4 Replies Latest reply on Aug 17, 2020 1:28 PM by TiSc_1146951

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

    TiSc_1146951

      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.

        • 1. Re: SCB UART GetNumInRingBuffer() returns very large (wrong) value
          BragadeeshV_41

          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

          • 2. Re: SCB UART GetNumInRingBuffer() returns very large (wrong) value
            TiSc_1146951

            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.

            • 3. Re: SCB UART GetNumInRingBuffer() returns very large (wrong) value
              BragadeeshV_41

              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

              1 of 1 people found this helpful
              • 4. Re: SCB UART GetNumInRingBuffer() returns very large (wrong) value
                TiSc_1146951

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