UART latency
Posted: Thu Nov 28, 2013 4:04 pm
Hey everyone,
using a BLE112 bluetooth low energy device at my STM32F0 Discovery UART@115000baud I have some trouble somtimes to capture the events if they come quickly each one after another.
I appended a saleae screen where you see a command sent from STM32 at first and the ack from the BLE device. Just 4ms after this the BLE event throws an event. Sometimes my UART handler gets that and sometimes not...
Here is my UART listening thread
Also one can see what else is running
What else you can see is, that I have a GPIO to serve a indicator function. My UART handler also pulls the line low, when it gets called.
First off I had a 10ms timeout in the charbuf = chnGetTimeout(&SD1, TIME_IMMEDIATE); routine which led to never see events thrown on the line within 10ms after an earlier UART RX activity. I was able to solve that but now I don't have a reliable and quick UART reading.
Did I overlook something crucial?
Thanks for the help, I appreciate it!
Greetings
Stefan
using a BLE112 bluetooth low energy device at my STM32F0 Discovery UART@115000baud I have some trouble somtimes to capture the events if they come quickly each one after another.
I appended a saleae screen where you see a command sent from STM32 at first and the ack from the BLE device. Just 4ms after this the BLE event throws an event. Sometimes my UART handler gets that and sometimes not...
Here is my UART listening thread
Code: Select all
static msg_t Thread4(void *arg)
{
(void)arg;
chRegSetThreadName("BLEData");
static unsigned char data[256];
static struct ble_header hdr;
static uint32_t payload_length = 0, cnt_received = 0;
EventListener elBLEData;
flagsmask_t flags;
chEvtRegisterMask((EventSource *)chnGetEventSource(&SD1), &elBLEData, EVENT_MASK(1));
while (TRUE)
{
chEvtWaitAllTimeout(EVENT_MASK(1), TIME_IMMEDIATE);
chSysLock();
flags = chEvtGetAndClearFlags(&elBLEData);
chSysUnlock();
if(flags & SD_PARITY_ERROR){ // Parity error happened.
gwinPrintf(GW1, "[UART] parity error\n");
gdispFlush();
}
if(flags & SD_FRAMING_ERROR){ // Framing error happened.
gwinPrintf(GW1, "[UART] framing error\n");
gdispFlush();
}
if(flags & SD_OVERRUN_ERROR){ // Overflow happened.
gwinPrintf(GW1, "[UART] Overflow\n");
gdispFlush();
}
if(flags & SD_NOISE_ERROR){ // Noise on the line.
gwinPrintf(GW1, "[UART] Noisy line\n");
gdispFlush();
}
if(flags & SD_BREAK_DETECTED){ // Break detected.
gwinPrintf(GW1, "[UART] Break!\n");
gdispFlush();
}
if(flags & CHN_INPUT_AVAILABLE)
{
ledFlash(); //Indicate: something has been received
msg_t charbuf;
do{ //Read all there is into buffer
charbuf = chnGetTimeout(&SD1, TIME_IMMEDIATE);
if(charbuf != Q_TIMEOUT){
if(cnt_received < sizeof(hdr)){
if(cnt_received == 0)
hdr.type_hilen = (uint8_t)charbuf;
if(cnt_received == 1)
hdr.lolen = (uint8_t)charbuf;
if(cnt_received == 2)
hdr.cls= (uint8_t)charbuf;
if(cnt_received == 3)
hdr.command= (uint8_t)charbuf;
}
else
data[cnt_received - sizeof(hdr)] = (uint8_t)charbuf;
cnt_received++;
}
}
while(charbuf != Q_TIMEOUT);
if(cnt_received >= sizeof(hdr)){ //Do we have at least the header bytes?
payload_length = ((uint32_t)(hdr.type_hilen & 0x07))<<8 | (uint32_t)hdr.lolen;
if(cnt_received >= sizeof(hdr)+payload_length){ //Have we gathered all payload bytes?
cnt_received = 0; //Reset receiver counter
const struct ble_msg *msg = ble_get_msg_hdr(hdr); //Process message header
if(!msg){
gwinPrintf(GW1, "[BLE] unknown message\n");
gdispFlush();
}
else
msg->handler(data); //Here message handler gets called
}
}
}
}
}
Also one can see what else is running
Code: Select all
int main(void) {
halInit();
chSysInit();
tpBlinkBlue = chThdCreateStatic(waThread_2, sizeof(waThread_2), NORMALPRIO, Thread2, NULL); //Blinker thread from STM32 demo code
tpButton = chThdCreateStatic(waThread_3, sizeof(waThread_3), NORMALPRIO, Thread3, NULL); //This sleeping reacts on button press events. IRQ wakes up this thread
tpBLEData = chThdCreateStatic(waThread_4, sizeof(waThread_4), NORMALPRIO, Thread4, NULL); //This is the UART listener
initDisplay();
initUART();
initBLE();
extStart(&EXTD1, &extcfg); // Activates the EXT driver 1.
while(TRUE){
}
}
What else you can see is, that I have a GPIO to serve a indicator function. My UART handler also pulls the line low, when it gets called.
First off I had a 10ms timeout in the charbuf = chnGetTimeout(&SD1, TIME_IMMEDIATE); routine which led to never see events thrown on the line within 10ms after an earlier UART RX activity. I was able to solve that but now I don't have a reliable and quick UART reading.
Did I overlook something crucial?
Thanks for the help, I appreciate it!
Greetings
Stefan