BSOM Serial1 Peek/Read Mismatch

I am working on 4.2.0 with a B402 and have found that Serial1.peek() does not always match Serial1.read(). The logic I am using to check this is:

            if(Serial1.available() > 0) {
                int peek = Serial1.peek();
                int read = Serial1.read();
                if(read != peek) {
                    Log.info("Serial 1 mismatch");
                    Log.info("%02X %02X", peek, read);
                    return;
                }
            }

A call to peek before read should result in the same value, should it not? I have tested this on 2 units.

Hi @radek!

I'm Alberto, from the TAM team.
I don't have a B402 at hand but I will try to replicate your issue. If you print all the results, not only the mismatch, does it appear any pattern?

Hey Alberto,

The issue appears to be with the first byte received on every message I send to Serial1. For instance, if I send 16 bytes, values 0-15, The first peeked byte is -1, but the read is 0. Then every byte after matches. If I send the bytes multiple bytes, the first 1st received byte is always -1 according to peek. Additionally, if I instead send 1-16, then peek will also report the first byte as -1, whereas read reports 1. -1 is supposed to indicate no data available, but I check if there are bytes available with the available function before peeking and reading.

I think this can also be replicated by B524s, since we are seeing this issue in the field on some modules.

If you exceed the size of the serial read FIFO, the data can be discarded between the peek and read. The default size is 64 bytes. You can make it larger using acquireSerial1Buffer.

This is happening even with acquireSerial1Buffer.

Here's my implementation for B402:

hal_usart_buffer_config_t acquireSerial1Buffer() {
    const size_t bufferSize = 4096;
    hal_usart_buffer_config_t config = {
        .size = sizeof(hal_usart_buffer_config_t),
        .rx_buffer = new (std::nothrow) uint8_t[bufferSize],
        .rx_buffer_size = bufferSize,
        .tx_buffer = new (std::nothrow) uint8_t[bufferSize],
        .tx_buffer_size = bufferSize};

    return config;
}

Additionally, this happens every time I send small messages, such as 16 bytes. Even if I wait until available() returns 16 bytes and then start peeking/reading, the first byte peek() returns -1, whereas read returns the byte.