Got UART transmit working. But how to do receive? ASF4

Go To Last Post
5 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Adding the USART driver to START and configuring it as a UART3 and setting pins, baud rate and so on using the START page, and using the driver_examples.c code as a starting point I was able to transmit data out the UART pins just fine.  However there is no example code on how to read incoming UART data.  I see there is some commented out RX code in the example but I dont' know how to use this.

 

So, Can someone give me a jump start here on how to use the receive feature?  I have a callback function made called:

 

static void rx_cb(const struct usart_async_descriptor *const io_descr)

 

and I assume this function gets called whenever a byte comes into the receive buffer set up by START but I'm not sure.  Here are my specific questions:

 

Does this callback get called when data comes in?

How do I read the data (what is the buffer called that's set up by the HAL)?

how do I set the buffer size and use the buffer pointers

When I read the data does the buffer pointer automatically increment?

do I just manually set a flag or something so main knows I have data or do I just put a function into the main loop to monitor a flag or ?

.etc.

 

 

So far what I have is this:

(callback function)

 

static void rx_cb(const struct usart_async_descriptor *const io_descr)
{
(get the data from the buffer and return)
}

-----------------

void read_init(){

struct io_descriptor *io;

usart_async_register_callback(&USART_0, USART_ASYNC_RXC_CB, rx_cb);
//usart_async_register_callback(&USART_0, USART_ASYNC_ERROR_CB, err_cb);
usart_async_get_io_descriptor(&USART_0, &io);
usart_async_enable(&USART_0);

}

 

 

 

This topic has a solution.
Last Edited: Wed. Jul 17, 2019 - 06:39 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You've now managed to create three connected threads yet in onoly one did you identify the SAM chip being used. This is what happens when you grapeshot cross posts.

 

It helps to keep all the detail in one thread where possible - everything is simply about using the Start UART code.

 

PS Start will generate demo projects as well as just creating "empty projects" with added driver code. Surely there is a send/receive example for the UART ?

Last Edited: Tue. Jul 16, 2019 - 08:16 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:

You've now managed to create three connected threads yet in onoly one did you identify the SAM chip being used. This is what happens when you grapeshot cross posts.

 

It helps to keep all the detail in one thread where possible - everything is simply about using the Start UART code.

 

PS Start will generate demo projects as well as just creating "empty projects" with added driver code. Surely there is a send/receive example for the UART ?

 

Again, sorry about leaving out the chip.  It's an ATSAMS70Q21B (144 pin).

 

With regard to starting different threads.  The questions are quite different, which is why I did that.  If a thread is too long, it can be tedious for the reader leaving them to miss a question.  Just trying to be efficient and friendly to a search.

 

I'll try and keep it in one thread if the concensus is that is a better way. Don't want to be a pain.

 

With regard to the device_example.c  This is the entire code given as an example.  The transmit is clear enough, but I can't glean enough info from it to make a working receive.  Here is the whole code for the UART generated by START:

 

--------

/**
 * Example of using USART_0 to write "Hello World" using the IO abstraction.
 *
 * Since the driver is asynchronous we need to use statically allocated memory for string
 * because driver initiates transfer and then returns before the transmission is completed.
 *
 * Once transfer has been completed the tx_cb function will be called.
 */

static uint8_t example_USART_0[12] = "Hello World!";

static void tx_cb_USART_0(const struct usart_async_descriptor *const io_descr)
{
    /* Transfer completed */
}

void USART_0_example(void)
{
    struct io_descriptor *io;

    usart_async_register_callback(&USART_0, USART_ASYNC_TXC_CB, tx_cb_USART_0);
    /*usart_async_register_callback(&USART_0, USART_ASYNC_RXC_CB, rx_cb);
    usart_async_register_callback(&USART_0, USART_ASYNC_ERROR_CB, err_cb);*/
    usart_async_get_io_descriptor(&USART_0, &io);
    usart_async_enable(&USART_0);

    io_write(io, example_USART_0, 12);
}

 

Thanks for your time.

 

 

This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

 

Nafai wrote:
The questions are quite different,
No they aren't they are all about using Start UART support for a SAM chip ?!?
Nafai wrote:
If a thread is too long,
That can never be the case. A large thread collates all the important facts together. The fastidious reader will welcome this as they are not required to read N different threads to amass all the salient facts.

 

BTW the kind of UART example I was thinking of was something like this. It appears to be E70 compatible:

 

 

when you click through to the E70 version of the code the main() seems to be doing:

int main(void)
{
	uint8_t recv_char;

	atmel_start_init();

	usart_async_register_callback(&EDBG_COM, USART_ASYNC_TXC_CB, tx_cb_EDBG_COM);
	usart_async_register_callback(&EDBG_COM, USART_ASYNC_RXC_CB, rx_cb_EDBG_COM);
	usart_async_register_callback(&EDBG_COM, USART_ASYNC_ERROR_CB, err_cb_EDBG_COM);
	usart_async_enable(&EDBG_COM);

	io_write(&EDBG_COM.io, example_hello_world, 12);

	while (1) {
		if (data_arrived == 0) {
			continue;
		}

		while (io_read(&EDBG_COM.io, &recv_char, 1) == 1) {
			while (io_write(&EDBG_COM.io, &recv_char, 1) != 1) {
			}
		}
		data_arrived = 0;
	}
}

which looks like it exercises both io_write() and io_read().

Last Edited: Tue. Jul 16, 2019 - 05:00 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:

 

BTW the kind of UART example I was thinking of was something like this. It appears to be E70 compatible:

when you click through to the E70 version of the code the main() seems to be doing:

int main(void)
{
	uint8_t recv_char;

	atmel_start_init();

	usart_async_register_callback(&EDBG_COM, USART_ASYNC_TXC_CB, tx_cb_EDBG_COM);
	usart_async_register_callback(&EDBG_COM, USART_ASYNC_RXC_CB, rx_cb_EDBG_COM);
	usart_async_register_callback(&EDBG_COM, USART_ASYNC_ERROR_CB, err_cb_EDBG_COM);
	usart_async_enable(&EDBG_COM);

	io_write(&EDBG_COM.io, example_hello_world, 12);

	while (1) {
		if (data_arrived == 0) {
			continue;
		}

		while (io_read(&EDBG_COM.io, &recv_char, 1) == 1) {
			while (io_write(&EDBG_COM.io, &recv_char, 1) != 1) {
			}
		}
		data_arrived = 0;
	}
}

which looks like it exercises both io_write() and io_read().

 

Perfect!  That code did the trick.  I'm now writing and reading.  Thank you very much for taking the time to post that.