Giter Club home page Giter Club logo

Comments (18)

TravisJoe avatar TravisJoe commented on July 19, 2024

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().

screenshot_32

from mbed-os.

0xc0170 avatar 0xc0170 commented on July 19, 2024

Hello TravisJoe,

isn't this hw related issue?
Does it change if you lower baudrate? IF you suspect there can be framing error, does your target have a flag for it?

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,
0xc0170

from mbed-os.

mbednotifications avatar mbednotifications commented on July 19, 2024

I experienced same problem with Nucleo and CC2530 boards connected trough
UART.
I have tried UART loop on Nucleo board, and the same problem in interrupt
received only 1st byte.
But logic analyzer showed whole packet.

On Thu, Jun 5, 2014 at 10:32 AM, Martin Kojtal [email protected]
wrote:

Hello TravisJoe,

isn't this hw related issue?
Does it change if you lower baudrate? IF you suspect there can be framing
error, does your target have a flag for it?

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,
0xc0170


Reply to this email directly or view it on GitHub
#343 (comment).

You received this message because you are subscribed to the Google Groups
"mbed-devel" group.
To unsubscribe from this group and stop receiving emails from it, send an
email to [email protected].
For more options, visit https://groups.google.com/d/optout.

Best regards.
V.Golovanov

from mbed-os.

TravisJoe avatar TravisJoe commented on July 19, 2024

Thanks for both of your comments.

0xc0170,
I will look into using CMSIS, or at least another serial library, to read the port and see if the results change. Hopefully this can point to hardware or to the code. I will also try to jumper another micro to those pins and try to mimic the packet, maybe by bit banging.

mbednotifications??,
In some ways this is comforting to know others have seen my issue... however you did not say you found a solutions so that also makes me worry. Did you ever find a solution or work around?

Thanks

from mbed-os.

adamgreen avatar adamgreen commented on July 19, 2024

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.

from mbed-os.

TravisJoe avatar TravisJoe commented on July 19, 2024

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:

    if(channel == 2){
            sendADCSerialChar(ADC_CHANNEL2); 
    }

    //Wait for ADC conversion
    wait_ms(2);

    //Get bytes from ADC
    counter = 0;

    while(serialADC.readable()){
        valueCharArray[counter] = serialADC.getc();
        counter++;
    }

from mbed-os.

TravisJoe avatar TravisJoe commented on July 19, 2024

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.

from mbed-os.

TravisJoe avatar TravisJoe commented on July 19, 2024

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.

while(serialRS485.readable()){
    receive[counter] = serialRS485.getc();
    counter++;
    if(counter >= RS485_BUFFER_SIZE){
        break;
    }
}

from mbed-os.

fritzprix avatar fritzprix commented on July 19, 2024

Your code should be like
uint32_t idx = 0;
while(idx < buffersize){
while(!serial.readable()); // busy waiting for data available
rxbuf [idx++] = serial.getc();
}

from mbed-os.

fritzprix avatar fritzprix commented on July 19, 2024

it's more safe to insert timeout condition in busy wait loop for more stable system operation
but why serial HAL doesn't use DMA feature or receive buffer which guarantees more efficient io operation?

from mbed-os.

0xc0170 avatar 0xc0170 commented on July 19, 2024

@fritzprix that's what we would like to improve !

from mbed-os.

TravisJoe avatar TravisJoe commented on July 19, 2024

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
RXRDY - Receiver Ready flag. When 1, indicates that data is available to be read from the receiver buffer. Cleared after a read of the RXDAT or RXDATSTAT registers.

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;
}

from mbed-os.

fritzprix avatar fritzprix commented on July 19, 2024

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)

from mbed-os.

fritzprix avatar fritzprix commented on July 19, 2024

LPC84x's getc routine is blocking call. So you can simplify the snippet i suggested at first by removing busy waiting loop.

from mbed-os.

fritzprix avatar fritzprix commented on July 19, 2024

How many bytes to be read is depend on your decision.
I mean typically there are two largely used cases to communicate between host and its slave using serial.
first is packet size is fixed so you can assume specific size of packet after you send some command.
second is packet size is not fixed but packet has header in its front part so that you can get the size of packet ,type and so on.

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.

from mbed-os.

TravisJoe avatar TravisJoe commented on July 19, 2024

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;
    }
}

from mbed-os.

malay29 avatar malay29 commented on July 19, 2024

@TravisJoe

How you dealt with storing variable length packets in array without getting stuck at getc() ?
Because, in my case the getc() function waits for more data, when the data received is shorter then the buffer size, and hence resulting halt of program.

from mbed-os.

TravisJoe avatar TravisJoe commented on July 19, 2024

@malay29
It has been a couple years now so I am not sure how the API has changed, but hopefully it has improved. If you are using the main mbed platforms likely the readable() function correctly tells you if there is data in the buffer.

You could do a while loop based around what readable() returns and only use getc() when there is items in the buffer.

from mbed-os.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.