5 Replies Latest reply on Jun 1, 2020 1:44 PM by LePo_1062026

    PSOC to PSOC UART Comm

    CaDu_3933941

      Hi all,

       

      I am working on developing an RC car for which I need a controller and a receiver. This of course means the communication is through radio. The way it works is by sending multiple packets of data between each radio device.

       

      I am sending a total of 10 bytes of data, the first 3 being start bytes being three chars: 's', 't', 'r' which signal the start of the message. The following bytes are anything from the steering angle to the motor speed of the rc car (along with a few other commands).

       

      The problem I am having is the following: I a, sending 10 bytes of data and on the receiver side, everything seems fine, however, sometimes wrong bytes will begin to be written to the wrong byte on the receiver side. For the transmitter, I am using the UART_PutArray() command in order to send multiple bytes, and on the receiver side, I am using an interrupt on each byte received using the handler to unpack the bytes and assign them to the right index o the receiver buffer. Any help on this is appreciated.

       

      I am attaching both projects to this comment..

        • 1. Re: PSOC to PSOC UART Comm
          NoriakiT_91

          I assumed that your are saying about the "UART" instance in the "RC_receiver" project.

           

          You are setting the RX buffer size to 10 as following snapshot.

          GS004763.png

           

          In this case, an internal ISR is defined, a software FIFO is configured, and the received data will be consumed in the internal ISR.

          Please try to set the RX buffer size to "4" not to use the internal ISR with the software FIFO.

           

          Regards,

          Noriaki

          • 2. Re: PSOC to PSOC UART Comm
            CaDu_3933941

            I figured the buffer size had to be bigger than the expected number of bytes.

            • 3. Re: PSOC to PSOC UART Comm
              CaDu_3933941

              I still seem to be getting the same error. I made two new test projects with a transmitter sending a basic message and a receiver unpacking the data.

               

              Transmitter:

               

              /* ========================================

              *

              * Copyright YOUR COMPANY, THE YEAR

              * All Rights Reserved

              * UNPUBLISHED, LICENSED SOFTWARE.

              *

              * CONFIDENTIAL AND PROPRIETARY INFORMATION

              * WHICH IS THE PROPERTY OF your company.

              *

              * ========================================

              */

              #include "project.h"

               

               

              #define MSG_LENGTH 8

               

               

              volatile uint8_t Data_In=0;

              uint8_t i=0;

               

               

               

               

              const uint8_t MSG_STR[MSG_LENGTH]={'a', 'b', 'c','d', 'e', 'f', 'g', 'h'};

               

               

               

               

              //CY_ISR(TX_Handler){

              //   

              //    UART_WriteTxData(MSG_STR[i]);

              //    i++;

              //    if (i>=MSG_LENGTH) i = 0;

              //   

              //   

              //    TX_ISR_ClearPending();

              //   

              //   

              //}

               

               

               

               

              int main(void)

              {

                  CyGlobalIntEnable; /* Enable global interrupts. */

               

               

                  UART_Start();

                  UART_Terminal_Start();

                  TX_ISR_Start();

              //    TX_ISR_StartEx(TX_Handler);

                  for(;;)

                  {

                     

                      //UART_WriteTxData(3);

                      //UART_WriteTxData(4);

              //        if(UART_TX_STS_FIFO_EMPTY){

              //            UART_PutArray(MSG_STR,4);

              //        }

              //        if(UART_TX_STS_COMPLETE){

              //            UART_WriteTxData(MSG_STR[i]);

              //            i++;

              //            if (i>=MSG_LENGTH) i = 0;

              //            TX_ISR_ClearPending();   

              //        }

                      UART_PutArray(MSG_STR,4);

                      Data_In=UART_ReadRxData();

                      UART_Terminal_WriteTxData(Data_In);

               

               

               

               

                  }

              }

               

               

              /* [] END OF FILE */

               

               

              Receiver:

              /* ========================================

              *

              * Copyright YOUR COMPANY, THE YEAR

              * All Rights Reserved

              * UNPUBLISHED, LICENSED SOFTWARE.

              *

              * CONFIDENTIAL AND PROPRIETARY INFORMATION

              * WHICH IS THE PROPERTY OF your company.

              *

              * ========================================

              */

              #include "project.h"

               

               

              #define MSG_LENGTH 8

              #define LED_ADDR 0x20

               

               

              uint8_t a=0;

              uint8_t b=0;

              uint8_t c=0;

              uint8_t d=0;

              uint8_t e,f,g,h;

              uint8_t I2C_DataWrite[2];

              char MSG_In[MSG_LENGTH];

              char dummy;

              uint8_t buffer;

               

              int i =0;

               

               

              CY_ISR(RX_Handler){

                 

                  MSG_In[i]=UART_Radio_GetByte();

                  i++;

              //    if(MSG_In[i]==a){

              //        i=0;

              //    }

               

               

                 

                  if(i>= MSG_LENGTH) i = 0;

                  RX_ISR_ClearPending();

              }

               

               

              int main(void)

              {

                  CyGlobalIntEnable; /* Enable global interrupts. */

               

               

                  UART_Radio_Start();

                  RX_ISR_Start();

                  I2C_Start();

                  I2C_EnableInt();

                 

                  I2C_DataWrite[0]=0x00;

                  I2C_DataWrite[1]=0x00;

                 

                  I2C_MasterWriteBuf(LED_ADDR, I2C_DataWrite, 2, I2C_MODE_COMPLETE_XFER);

                  while(I2C_MasterStatus()!=I2C_MSTAT_WR_CMPLT);

                 

                  I2C_DataWrite[0]=0x0c;

                  I2C_DataWrite[1]=0xFF;

                 

                  I2C_MasterWriteBuf(LED_ADDR, I2C_DataWrite, 2, I2C_MODE_COMPLETE_XFER);

                  while(I2C_MasterStatus()!=I2C_MSTAT_WR_CMPLT);

                 

                  I2C_DataWrite[0]=0x0d;

                  I2C_DataWrite[1]=0xFF;

                 

                 

                

                  RX_ISR_StartEx(RX_Handler);

               

               

                  for(;;)

                  {

                     

                      a=MSG_In[0];

                      b=MSG_In[1];

                      c=MSG_In[2];

                      d=MSG_In[3];

                      e=MSG_In[4];

                      f=MSG_In[5];

                      g=MSG_In[6];

                      h=MSG_In[7];

                      if(a=='a'){

                          I2C_DataWrite[0]=0x02;

                          I2C_DataWrite[1]=0xFF;

                         

                          I2C_MasterWriteBuf(LED_ADDR, I2C_DataWrite, 2, I2C_MODE_COMPLETE_XFER);

                          while(I2C_MasterStatus()!=I2C_MSTAT_WR_CMPLT);

                      } 

                     

                      else{

                          I2C_DataWrite[0]=0x02;

                          I2C_DataWrite[1]=0x00;

                         

                          I2C_MasterWriteBuf(LED_ADDR, I2C_DataWrite, 2, I2C_MODE_COMPLETE_XFER);

                          while(I2C_MasterStatus()!=I2C_MSTAT_WR_CMPLT);

                      }

                      if(b=='b'){

                          I2C_DataWrite[0]=0x03;

                          I2C_DataWrite[1]=0xFF;

                         

                          I2C_MasterWriteBuf(LED_ADDR, I2C_DataWrite, 2, I2C_MODE_COMPLETE_XFER);

                          while(I2C_MasterStatus()!=I2C_MSTAT_WR_CMPLT);

                      }

                      else{

                          I2C_DataWrite[0]=0x0;

                          I2C_DataWrite[1]=0x00;

                         

                          I2C_MasterWriteBuf(LED_ADDR, I2C_DataWrite, 2, I2C_MODE_COMPLETE_XFER);

                          while(I2C_MasterStatus()!=I2C_MSTAT_WR_CMPLT);

                      }

                      if(c=='c'){

                          I2C_DataWrite[0]=0x04;

                          I2C_DataWrite[1]=0xFF;

                         

                          I2C_MasterWriteBuf(LED_ADDR, I2C_DataWrite, 2, I2C_MODE_COMPLETE_XFER);

                          while(I2C_MasterStatus()!=I2C_MSTAT_WR_CMPLT);

                      }

                      else{

                          I2C_DataWrite[0]=0x04;

                          I2C_DataWrite[1]=0x00;

                         

                          I2C_MasterWriteBuf(LED_ADDR, I2C_DataWrite, 2, I2C_MODE_COMPLETE_XFER);

                          while(I2C_MasterStatus()!=I2C_MSTAT_WR_CMPLT);

                      }

                      if(c=='c'){

                          I2C_DataWrite[0]=0x05;

                          I2C_DataWrite[1]=0xFF;

                         

                          I2C_MasterWriteBuf(LED_ADDR, I2C_DataWrite, 2, I2C_MODE_COMPLETE_XFER);

                          while(I2C_MasterStatus()!=I2C_MSTAT_WR_CMPLT);

                      }

                      else{

                          I2C_DataWrite[0]=0x05;

                          I2C_DataWrite[1]=0x00;

                         

                          I2C_MasterWriteBuf(LED_ADDR, I2C_DataWrite, 2, I2C_MODE_COMPLETE_XFER);

                          while(I2C_MasterStatus()!=I2C_MSTAT_WR_CMPLT);

                      }

                     

                      if(UART_Radio_RX_STS_OVERRUN){

                          I2C_DataWrite[0]=0x06;

                          I2C_DataWrite[1]=0xFF;

                             

                          I2C_MasterWriteBuf(LED_ADDR, I2C_DataWrite, 2, I2C_MODE_COMPLETE_XFER);

                          while(I2C_MasterStatus()!=I2C_MSTAT_WR_CMPLT);

                         

                         

                      }

                     

                      else{

                          I2C_DataWrite[0]=0x06;

                          I2C_DataWrite[1]=0x00;

                         

                          I2C_MasterWriteBuf(LED_ADDR, I2C_DataWrite, 2, I2C_MODE_COMPLETE_XFER);

                          while(I2C_MasterStatus()!=I2C_MSTAT_WR_CMPLT);

                      }

                      UART_Radio_WriteTxData(a);

                      buffer = UART_Radio_GetRxBufferSize();

                          

                  }

              }

               

               

              /* [] END OF FILE */

              • 4. Re: PSOC to PSOC UART Comm
                BoTa_264741

                CaDu,

                There might be issue with communication protocol.  In your case, Rx port is waiting for the prefix "str", and then it has to count exact number of bytes to elapse (10) or wait for a timeout (if not enough bytes received). This is not very robust and may lead to potential data loss. For example, consider that one byte in the packet has been lost so Rx counts next "str" prefix as a valid byte "s". As a result, the first message will be corrupted, and the second one will get lost (only "tr" remains, which is not valid prefix).

                 

                Typically with UART communication, the Rx port waits for a termination character, which indicates the end of the message (typ. 0x0A or 0x0D - 'line feed' or 'carriage return', or both). This immediately signals that some complete command is received and needs to be processed immediately (no timeout or byte count needed). Anything received afterward the termination character belongs to the next message. So the good way for UART control would be to send a packet (does not have to be a fixed length), which looks like this:

                 

                prefix, byte1,....byteN, checksum, termination char

                 

                You can find example of such UART_Rx here:

                Re: UART string reception garbage value

                 

                The demo project uses custom circular buffer to receive the data. Once the Termination character is received, it fires the interrupt and starts processing accumulated message. The command prefix is optional, it is indicates that the valid message is received and can carry additional information. I recommend adding a checksum to the message for higher reliability (no checksum used in the demo). Typically a simple sum of all bytes in the message is used as quick check, trimmed to one (least significant) byte.

                 

                /odissey1

                1 of 1 people found this helpful
                • 5. Re: PSOC to PSOC UART Comm
                  LePo_1062026

                  CaDu,

                   

                  You indicated that you are waiting for the 's', 't', 'r' sequence to start the data gathering of 7 bytes of data sequence.

                   

                  What would happen if any of your 7 bytes f data are 's', 't', or 'r'?   Would that force your UART sequence to restart?

                   

                  Len