Learn MoreFAQsTutorials

4 posts / 0 new
Last post
Mario
Offline
Last seen:3 years 6 months ago
加入:2017-03-30 13:56
UART

Hi Dialog,
I’m trying to build up an UART communication with a periphal device. Later, I’d like to transmit the received data via BLE to another device - I’ve chosen the ble_multi_link Demo to build on.
How is it possible to read out data from UART more than once? Is there any possibility to receive an interrupt when there is data at the rx input?

I've tried the following code, but it leads to recurring resets.

ble_multi_link_task(void*params) {
.
.
for(;;) {
uart_device dev;
int rx_data;
dev = ad_uart_open(SERIAL2);
ad_uart_bus_acquire(dev);
rx_data = ad_uart_read(dev, buf, 4, OS_EVENT_FOREVER);
ad_uart_bus_release(dev);
}

}

Thank you!

Device:
MT_dialog
Offline
Last seen:5 days 3 hours ago
工作人员
加入:2015-06-08 11:34
Hi Mario,

Hi Mario,

A few comments regarding the code that you ve pasted, the multilink is allready using the UART2 module in order to retarget the printf() functionallity ( the CONFIG_RETARGET is the definition that configures and redirects the printf() functionallity to the UART2), also this re-targeting doesn't use the adapters but the LLD drivers so as far as i can tell, you are accessing the same periheral by the Low level drivers and by the adapter, this wont oppose an issue at the moment but if the device gets stressed with data this might cause you problems.

Also you have placed the initialization code for starting the UART adapter in the for(;;) loop of the task, that means that each time this for(;;) executes you execute the same functions (this is not happening though since you are blocking the execution of the task with the UART timeout). Additionally i suppose that you have placed the snippet that you have attached before the watchdog functions execute (sys_watchdog_notify() and sys_watchdog_suspend()). That means that the watchdog is running and you wait forever until 4 bytes of data come to your UART, the code will end up in a watchdog_Handler() before having the chance to do anything.

I dont get exactly what you mean "read data from UART more than once", the ad_uart_read() will block the task until either the time elapses (in your case with the
OS_EVENT_FOREVER这不会发生)或者4时代es are received, this function doesn't also uses any callback to notify you that the data have arrived since the function is blocking. You can also check the ad_uart_read_async() function which will not block the task and will wait for a specified number of bytes to be received (be aware that this function cannot be called consecutively before the previous transaction has been completed), this function is executing a callback when the predefined number of data arrive. Since the SDK is using adapters and not the LLD the interrupts are used by the adapters and it requires some effort in order not to use the adapters and implement code using the Low Level Drivers and therefore use the interrupts.

The task which will trigger the UART interaction could be either an allready implemented task or a new task that will handle your UART, that depends on your implementation. Also you will have to be aware that when the device is in sleep mode all the peripherals including the UART are powered down, so while in sleep mode you wont be able to have UART interaction unless the device is awake. So you can either have the device allways awake or implement a scheme where before the external device sends data it wakes up the 68x first, that implies that you will have to use hardware flow control in order for the external device to wake up the 68x via the RTS pin.

Lets assume that you would like to read data from the UART one byte at a time and print it back to your terminal, a simple implementation of using the UART on the multilink could be the following.

  • Set additional pins as RTS and CTS in order to prevent the device from going to sleep while the CTS is asserted by the external device.
  • Before entering the for(;;) loop of the task initiate the uart transaction dev = ad_uart_open(SERIAL2); ad_uart_read_async(dev, &buf, 1, (void*)uart_async_read_cb, NULL);.
  • The callback will send a notification to the main task in order to print the received data and will reset the reading by invoking the ad_uart_read_async() function.

Thanks MT_dialog

Mario
Offline
Last seen:3 years 6 months ago
加入:2017-03-30 13:56
Thanks!

Thanks!

mahmed106
Offline
Last seen:1 week 3 days ago
加入:2019-05-03所
Thanks alot for your detailed

Thanks alot for your detailed reply. After reusing ad_uart_read_async () , i was able to read data from uart just like interrupt. Thanks ,, your detailed answer really helped me. :)