Hi,
I am trying to transfer data to a CC2540 device through the UART link and I observe data loss during the transfer.
My hardware setup is a CC2540EM plugged into a SmartRF05 rev 1.8.1 evaluation board. The evaluation board is connected to a PC through a serial cable.
I slightly modified the SimpleBLEPeripheral project (from the BLE-CC254x-1.2 software version) to include a UART test (see patch bellow). The test is very simple: it counts the number of bytes it received into the callback function gave to the HAL_UART component. The HAL_UART uses the underlying _hal_uart_dma component. Every 5 seconds it displays on the LCD display (line 1) the received amount of bytes. The test also checks for the HAL_UART_RX_FULL event. During the test, the cc2540 device remains in advertising mode.
Serial communication is set at 115200 bauds, 8 bits, no parity, no flow control. The serial speed and the flow control don’t matter. Whatever these values are, the issue remains.
On the PC side, I send through the serial connection the amount of 56 bytes every 10 ms at 115200 bauds. I am performing this operation 1000 times resulting in a transferred amount of 56000 bytes.
Once the transfer ends, the amount of received bytes displayed is different of 56000 and varies each time the test is run. Also no overflow in the receive buffer occurs, meaning that the problem resides in data acquisition from the hardware to the internal receive buffer.
I have tested DMA or IRQ methods and same results popped up. The problem is even worse when the POWER_SAVING option is defined.
Is here any way to ensure a correct transfer through the UART interface on the CC2540 device?
Marc
Patch file with UART modifications for the SimpleBLEPeripheral project.
*********************************************************************************
diff -rupN SimpleBLEPeripheral.org/CC2540DB/SimpleBLEPeripheral.ewp SimpleBLEPeripheral/CC2540DB/SimpleBLEPeripheral.ewp
--- SimpleBLEPeripheral.org/CC2540DB/SimpleBLEPeripheral.ewp 2012-01-11 11:40:18.000000000 +0100
+++ SimpleBLEPeripheral/CC2540DB/SimpleBLEPeripheral.ewp 2012-03-06 14:46:47.041232900 +0100
@@ -1326,10 +1326,11 @@
<state>OSAL_CBTIMER_NUM_TASKS=1</state>
<state>HAL_AES_DMA=TRUE</state>
<state>HAL_DMA=TRUE</state>
- <state>POWER_SAVING</state>
+ <state>xPOWER_SAVING</state>
<state>xPLUS_BROADCASTER</state>
<state>HAL_LCD=TRUE</state>
<state>HAL_LED=FALSE</state>
+ <state>HAL_UART=TRUE</state>
</option>
<option>
<name>CCPreprocFile</name>
diff -rupN SimpleBLEPeripheral.org/Source/simpleBLEPeripheral.c SimpleBLEPeripheral/Source/simpleBLEPeripheral.c
--- SimpleBLEPeripheral.org/Source/simpleBLEPeripheral.c 2012-02-01 10:05:42.000000000 +0100
+++ SimpleBLEPeripheral/Source/simpleBLEPeripheral.c 2012-03-06 15:51:00.409196600 +0100
@@ -50,6 +50,7 @@
#include "hal_led.h"
#include "hal_key.h"
#include "hal_lcd.h"
+#include "hal_uart.h"
#include "gatt.h"
@@ -252,6 +253,55 @@ static simpleProfileCBs_t simpleBLEPerip
simpleProfileChangeCB // Charactersitic value change callback
};
+/* UART test */
+static void uart0CB(uint8 port, uint8 event);
+static halUARTCfg_t com0 =
+{
+ FALSE,
+ HAL_UART_BR_115200,
+ FALSE,
+ 0,
+ 0,
+ { 0, 0, 0, NULL, },
+ { 0, 0, 0, NULL, },
+ 0,
+ 0,
+ uart0CB,
+};
+
+static uint32 uart0RXBytes = 0;
+static uint32 uart0ErrPort = 0;
+static uint32 uart0ErrFull = 0;
+
+static void uart0CB(uint8 port, uint8 event)
+{
+ uint8 dummy[256];
+ uint16 bLen;
+
+ // some error checking
+ if (port != HAL_UART_PORT_0) {
+ uart0ErrPort++;
+ return;
+ }
+
+ // filter and counters
+ switch (event) {
+ case HAL_UART_RX_FULL:
+ uart0ErrFull++;
+ break;
+ case HAL_UART_RX_ABOUT_FULL:
+ case HAL_UART_RX_TIMEOUT:
+ break;
+ default:
+ return;
+ }
+
+ // just read uart in order to empty the buffer
+ bLen = Hal_UART_RxBufLen(HAL_UART_PORT_0);
+ if (bLen > 256) bLen = 256;
+ uart0RXBytes += HalUARTRead(HAL_UART_PORT_0, dummy, bLen);
+}
+
/*********************************************************************
* PUBLIC FUNCTIONS
*/
@@ -407,7 +457,9 @@ void SimpleBLEPeripheral_Init( uint8 tas
HCI_EXT_MapPmIoPortCmd( HCI_EXT_PM_IO_PORT_P0, HCI_EXT_PM_IO_PORT_PIN7 );
#endif // defined ( DC_DC_P0_7 )
-
+
+ HalUARTOpen(HAL_UART_PORT_0, &com0);
+
// Setup a delayed profile startup
osal_set_event( simpleBLEPeripheral_TaskID, SBP_START_DEVICE_EVT );
@@ -712,6 +764,16 @@ static void performPeriodicTask( void )
*/
SimpleProfile_SetParameter( SIMPLEPROFILE_CHAR4, sizeof(uint8), &valueToCopy);
}
+
+#if (defined HAL_LCD) && (HAL_LCD == TRUE)
+ if (uart0ErrFull) {
+ HalLcdWriteStringValue("OF:", (uint16)(uart0RXBytes), 10, HAL_LCD_LINE_1);
+ } else if (uart0ErrPort) {
+ HalLcdWriteStringValue("PE:", (uint16)(uart0RXBytes), 10, HAL_LCD_LINE_1);
+ } else {
+ HalLcdWriteValue(uart0RXBytes, 10, HAL_LCD_LINE_1);
+ }
+#endif // (defined HAL_LCD) && (HAL_LCD == TRUE)
}
/*********************************************************************