-
Notifications
You must be signed in to change notification settings - Fork 3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
mbed serial readable() seeing all bytes #343
Comments
Here is a better image showing timing of the sent package and the response. You can see there is almost no time between the two. Also the returning bytes are a continues stream and are barely separated by the start/stop bits. This is at 57600 baud. It is frustrating because I see the characters in the logic analyzer and on the scope, but it continues to read only the first byte when checking readable(). |
Hello TravisJoe, isn't this hw related issue? Would you eliminate the mbed library from the picture and use directly registers in the application to catch those 3 bytes? This might not have any impact as mbed API layer is thin and the code below in serial in this case, it's short, mostly 1/2 lines.. Regards, |
I experienced same problem with Nucleo and CC2530 boards connected trough On Thu, Jun 5, 2014 at 10:32 AM, Martin Kojtal notifications@github.com
Best regards. |
Thanks for both of your comments. 0xc0170, mbednotifications??, Thanks |
Where is your code? In the snippet above from your debugging session I see something like: while (serial.readable())
array[i++] = serial.getc(); If you are expecting 3 bytes, then I think you need to call getc() 3 times. There is nothing guaranteeing that readable() will return true right after you read the first byte since the UART may not have received the second byte yet. |
Thanks I will try this. I cannot remember if getc() is blocking until a byte shows up. Also here is more of my code for reference:
|
I am still having a lot of trouble with this. I have tried interrupts, timing and other adjustments and it just seems to not notice the 2nd and 3rd bytes. I have (and many others) used the simple readable() loop to read iterate through characters in the RX buffer. But for some reason I cannot figure out why this is not working. Because it has worked on other platforms I would think that the issue is in the LPC812 specific portions of the code. Does anybody have this same issue or could potentially help me look into this more? I will do what I can, but my knowledge of low level code especially on this newer processor is limited. |
I am back at this. I am using a different port and a different way of communicating, but getting the same results. It seems that readable() is cleared after reading one byte, but when looking at several example of using the serial port and past code I have used it seems that readable() should still return 1 unit the RX buffer is cleared. Has anybody tried this on their LPC812 devices? Here is my latest code. I am currently using RawSerial instead of standard serial.
|
Your code should be like |
it's more safe to insert timeout condition in busy wait loop for more stable system operation |
@fritzprix that's what we would like to improve ! |
First, thanks for helping with my issue. It seems to be an ongoing problem with what I am doing, and I appreciate the help. I looked over some mbed code and the manual and found this. From the LPC8xx manual RXDAT is called when getc() is called which seems to clear the readable() flag. I do not know if this is handled differently with the LPC176x library. What I am not sure of now is how to get more than one byte, without knowing the number of bytes in the buffer, after readable() is called. Even with using an interrupt how would I know how many times to call getc() if there was more than one byte that was in the buffer already. Code from LPC8xx mbed library int serial_getc(serial_t *obj) {
while (!serial_readable(obj));
return obj->uart->RXDATA;
} int serial_readable(serial_t *obj) {
return obj->uart->STAT & RXRDY;
} For reference here is the LPC176x library int serial_getc(serial_t *obj) {
while (!serial_readable(obj));
int data = obj->uart->RBR;
if (NC != uart_data[obj->index].sw_rts.pin) {
gpio_write(&uart_data[obj->index].sw_rts, 0);
obj->uart->IER |= 1 << RxIrq;
}
return data;
} int serial_readable(serial_t *obj) {
return obj->uart->LSR & 0x01;
} |
basically, you are right. so I think HAL Interface could be improved but if interface change happened, every Hal Port of other HW tree should be also changed accordingly. so I think it's better to keep the interface itself unchanged as possible and add just few functions to support buffered IO based on MsgQ (which is cmsis ipc feature) |
LPC84x's getc routine is blocking call. So you can simplify the snippet i suggested at first by removing busy waiting loop. |
How many bytes to be read is depend on your decision. first case is relatively more simple than second one. because second one usually needs implement packet parser top of the serial interface so actually, how many bytes to be read is rarely matter. but busy waiting is the real problem because it degrade over all performance because thread (or executing process) occupy cpu until io operation accomplished which is typically takes a few thousands of cpu clocks and I guess presumably that you seem to be confusing some point because you think there is internal receiving buffer which has more than one byte. but the fact is there is only one byte of buffer(RXD register) so if you don't read data in proper way, data might be lost. |
In my experiences I have always used variable length packets with indicators for start and finish like brackets. They usually have some for of CRC also. Modbus would be an example. I could be wrong but I thought, at the very least on the LPC1768/9, has a 16byte FIFO serial buffer as part of the MCU. So I managed to figure out a method that finally worked. It seems that I have not found a way to allow for simple polling of the RS485 buffer. I was able to get the this to work by making my own buffer instead of relying on buffering on the MCU and and interrupts to quickly dump the data into the buffer. I wish I would of done this much sooner instead of trying to figure out why readable() was not behaving as I expected. void RS485interrupt(void){
RS485buffer[RS485bufferCounter] = serialRS485.getc();
RS485bufferCounter++;
// Avoid overrun
if(RS485bufferCounter >= RS485_BUFFER_SIZE){
RS485bufferCounter = 0;
}
} |
How you dealt with storing variable length packets in array without getting stuck at getc() ? |
@malay29 You could do a while loop based around what readable() returns and only use getc() when there is items in the buffer. |
Hello,
I have used mbed on and off for several years without having any issues with the serial port. Recently I started using a IC that has a UART output (Silabs si8900).When powered has an auto baud function that happens were you send a single byte until it can match the baud and send a single byte response . I have no trouble receiving and reading the single character during auto baud, only when I try to read the 3 byte response during normal use does it appear to not read the 2nd and 3rd byte.
Below is an image showing what is going on.
The top section of code shows my read statement which picks bytes from the buffer while readable() returns 1. The 3 byte response comes after I send a request byte, which is not shown.
The middle section shows the values during debugging which shows I read the first byte but shows no values stored in the other bytes due to readable() returning 0.
The third section is the logic analyzer output showing the 3 byte response.
The only thing I can think of is there is no delay between bytes and the serial port might see it as a single byte with framing issues. I do not know enough about the serial port library to know what could be causing this issue. It would be helpful if somebody could take a look at this and see if they can find anything.
As a side note, I programmed simple software serial functions but due to how quickly the response is from the IC the timing does not work out well.
Any help would be appreciated.
The text was updated successfully, but these errors were encountered: