8 years, 5 months ago.

LPC1768 serial getc stuck when if received message longer?

Hi,

I am using LPC1768's uart p9, p10 to communication with zigbee. First of all, I need to initial zigbee with several commands sent from LPC1768 and got all response from zigbee are just expected. I have to point this out, those response message are not longer than 19 bytes in length. My problem is, when zigbee send a message(INCOMING_DATA) longer than 19 bytes, then the process will stuck on getc. Part of my program:

Serial zb1(p9, p10);
DigitalOut led1(LED1);
DigitalOut led2(LED2);

void callback(){
    while(zb1.readable()) {
    	led2 = !led2;
        printf("0x%02X \n", zb1.getc());    //<----stuck on reading 20th byte
    }
    led2 = 0;
}

int main() {
    zb1.format(8, Serial::None, 1);
    zb1.baud(115200);
    zb1.attach(&callback);
    
    while(1){
        led1 != led1;
        wait(1000);
    }
}

I also use logical analyzer to check the Rx of LPC1768, the message has no problem on format and it look like this, 0xFE 0x16 0x44 0x81 0x00 0x00 0x04 0x01 0x4E 0x88 0x03 0x03 0x00 0x00 0x00 0x48 0x9E 0x03 0x00 ,0x00 0x05 0x00 0x02 0x00 0x00 0x00 0xC2, but in callback, it will stuck on after got 19th byte. Can someone tell me why its happened? and how do I fix it?

Many thanks.

Patrick Shih

Never mind, I use MODSERIAL instead and has no problem.

posted by Patrick Shih 13 Nov 2015

2 Answers

8 years, 5 months ago.

Just to note your problem: You are using default printf to communicate with your PC, this runs at 9600 baudrate. Your zigbee is running at a much higher baudrate. In addition for every byte you receive, it needs to transmit about 6 bytes back.

So from this it is clear that you got a problem: the time it takes your interrupt routine to complete, which requires all data to be sent, is much longer than the time it takes a new character to arrive. And this makes it stop working (it shouldn't actually get stuck, just it will miss a large part of the message).

Why do you receive about 19 bytes? The LPC1768 has a 16-byte hardware FIFO for TX and RX. So you will always receive at least 16 bytes, they are placed in hardware buffers. The first 16 bytes it transmits back are handled instantaniously: They are just placed in the TX buffers. After this it needs to wait on space in the FIFO (and actually due to a not really handy UART it needs to wait until the TX buffer is completely empty). So this allows it to transmit a few responses back instantly. And now we are at the 20'th byte, which cannot fit in the RX buffer and the interrupt routine is stucking waiting on space in the TX buffer.

MODSERIAL (or BufferedSerial) immediatly upon reception places chars in a software buffer, which should remove your problems. Although depending on how you use them, you can also there get the same issue :).

Accepted Answer

Wow...I didn't notice that the problem I met is printf. Yes, its not really stuck and further messages will overlap. Thanks Erik

posted by Patrick Shih 16 Nov 2015
8 years, 5 months ago.

The interrupt processing time has to be very short. Never use a printf within a interrupt routine
Please read for instance https://developer.mbed.org/handbook/Ticker

Thanks for your recommend. :)

posted by Patrick Shih 16 Nov 2015