SCB UART GetNumInRingBuffer() returns very large (wrong) value

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
Bit-Twiddler
Level 3
Level 3
5 questions asked 10 sign-ins First solution authored

I started with the "UART using high level APIs" example to implement an SCB UART [v2.0] on my CYBLE-416045-02. I modified the RX Ring Buffer to be 129[+1] bytes.

Once the FIFO is emptied into the Ring buffer due to FIFO Level Triggering, I use the Receive function to move the bytes out of the Ring Buffer. This works fine until the Ring Buffer wraps around the end of its array. Then when I call GetNumInRingBuffer()  I start getting returned values a little less than 2^32 due to a negative value being stored in the unsigned 32-bit integer. Delving a little into the underlying code:

Cy_SCB_UART_GetNumInRingBuffer() [cy_scb_uart.c]

if (locHead >= context->rxRingBufTail) {

     size = (locHead - context->rxRingBufTail);  // <-- Calculates the correct values

}

else {

     size = (locHead + (context->rxBufSize - context->rxRingBufTail));  // <-- Calculates "negative" values

}

During debugging I found that usually

rxBufSize == 0

and

rxRingBufSize == 129

If the rxBufSize in the formula were replaced with rxRingBufSize then the formula appears to work as expected.

cy_scb_uart.h:

rxRingBufSize;  /**< The ring buffer size */

rxBufSize;      /**< The receive buffer size */

Has anyone else encountered this problem when calling GetNumInRingBuffer() after the Ring Buffer wraps?

Why would a calculation for the Ring Buffer bytes-utilized-count need to reference the size of a completely different buffer?

Let me know if I can provide any additional information to help identify the source of this issue.

0 Likes
1 Solution

Hi TiSc_1146951​,

Yes, we were able to reproduce at our end as well. We have raised an internal request to fix this issue in the SCB drivers. However, please note that we will be fixing the PDL for ModusToolbox first before updating PDL for PSoC Creator. We highly recommend you to evaluate ModusToolBox for PSoC 6 development.

https://www.cypress.com/products/modustoolbox-software-environment

Regards,

Bragadeesh

Regards,
Bragadeesh

View solution in original post

4 Replies
BragadeeshV
Moderator
Moderator
Moderator
First question asked 1000 replies posted 750 replies posted

Hi TiSc_1146951​,

Can you please send your project to us so that we can reproduce the issue at our end as well?

Regards,

Bragadeesh

Regards,
Bragadeesh
0 Likes
lock attach
Attachments are accessible only for community members.

Hey there Bragadeesh,

I believe I've attached the archived workspace that contains the project. I've never gone through this packaging process before so let me know if I did it correctly or not.

This example project is used with the aforementioned PSoC 6 BLE module, and specifically on the CYBLE-416024-EVAL Arduino board since it has a built in USB-UART interface. The CM4 code sets up the SCB UART, sends an initial header over the UART TX, then about every second it will output to the TX:

  • Number of words in RX FIFO
  • Number of words in the RX Ring Buffer
  • Head & Tail Indices for the Ring Buffer

When bytes are sent to the UART's RX line then the above output will update faster.

For this example I've set the ring size to 65 bytes, and set the main loop to Receive the bytes from the Ring Buffer if there are more than 0, but less than or equal to the size of the Ring Buffer. If there are more words "in the Ring Buffer" than is possible, handle_error() is called.

When sending 1 character at a time through a serial terminal, the final output looks something like:

# in FIFO:   60        # in Ring:                     0       TailIdx:    0   HeadIdx:      0

# in FIFO:   61        # in Ring:                     0       TailIdx:    0   HeadIdx:      0

# in FIFO:   62        # in Ring:                     0       TailIdx:    0   HeadIdx:      0

# in FIFO:   63        # in Ring:                     0       TailIdx:    0   HeadIdx:      0

# in FIFO:     0        # in Ring:                   64       TailIdx:    0   HeadIdx:    64          <--- 64 bytes were in FIFO, which triggers transfer to Ring Buffer

# in FIFO:     0        # in Ring:                     0       TailIdx:   64   HeadIdx:   64          <--- Main loop detects data in Ring Buffer, transfers it out

# in FIFO:     0        # in Ring:   4294967232       TailIdx:   64   HeadIdx:     0          <--- Another byte comes into Ring Buffer, incrementing Head Index and wrapping

Breakpointing inside of Cy_SCB_UART_GetNumInRingBuffer(), the problem occurs when the formula on line 529 is used, when the Head Index is smaller than the Tail.

size = (locHead + (context->rxBufSize - context->rxRingBufTail));

locHead == context->rxRingBufHead  == 0

context->rxBufSize                               == 0

context->rxRingBufTail                         == 64

size = locHead + (rxBufSize - rxRingBufTail)

size = 0 + (0 - 64)

size = -64

(-64) as uint32_t --> 4294967232

Because rxBufSize == 0, this gives incorrect values. The issue is that rxRingBufTail needs to be subtracted from the size of the Ring Buffer size, not the size of the temporary buffer that Receive() is using.

If we correct the formula to:

size = locHead + (rxRingBufSize - rxRingBufTail)

and

context->rxRingBufSize == 65

we end up with

size = 0 + (65 - 64)

size = +1

Which is the correct value.

From what I can tell, the

     rxBufSize

should instead be

     rxRingBufSize

Let me know if you need any additional information to identify if this is the issue or not.

0 Likes

Hi TiSc_1146951​,

Yes, we were able to reproduce at our end as well. We have raised an internal request to fix this issue in the SCB drivers. However, please note that we will be fixing the PDL for ModusToolbox first before updating PDL for PSoC Creator. We highly recommend you to evaluate ModusToolBox for PSoC 6 development.

https://www.cypress.com/products/modustoolbox-software-environment

Regards,

Bragadeesh

Regards,
Bragadeesh

Thank you for the confirmation of the issue. In the meantime I'll edit the PDL libraries on my system to include my fix. That should hold me over until the fixed PDL library is distributed to PSoC Creator.

As for moving to ModusToolbox, according to what I've read this year and last, the software is still lacking important features that PSoC Creator already has implemented and working. Until Modus catches up to PSoC Creator then I likely will not be migrating.

And in case anyone else sees this before the PDL is patched, and they therefore need to patch the issue themselves:

cy_scb_uart.c, line 529 was changed to

size = (locHead + (context->rxRingBufSize - context->rxRingBufTail));