2 Replies Latest reply on Feb 15, 2016 6:44 AM by content.librarian

    Looking for advice on using USBUART in an interrupt driven mannor on the PSoC5LP

    content.librarian

      I would like to "connect" a USBUART device to a regular UART device in the same PSoC5LP.  I have the added a UART and USBUART component to my existing design and have had success in interfacing them in software.  When a byte arrives on the CDC interface I queue it for delivery on the UART and when a byte arrives on the UART I write it to the USBUART.   

         

      At slow speeds everything works fine, however I have noticed that Windows seems to send data to the USBUART faster than the 115,200 baud rate that I configured the interface for, which overwhelms the PSoC with data.

         

      Also, I am implementing this in an interrupt driven framwork so I need to be interrupted when data arrives on the USBUART.  I assue that this is the common use model but I cannot find any reference or example code to do this.  

         

      I had some luck putting a callback function in the auto-generated function: USBUART_EP_3_ISR() to signal that data arrived, but I am not confident that this is a safe/efficient way to react to incomming data.

         

      I have read the USBUART and UART datasheets and I am pretty comfortable using them, however I am looking for some more information on the USBUART, specifically:

         

      1) Is it my imagination or does data transfer faster than the specified baud rate (i.e. 115,200 baud) when using a CDC driver like the one generated by PSoC Creator?  If so, is there a way in software (PSoC firmware or CDC inf file) to slow down the transfer?

         

      2) How do I use the USBUART, specifically the RX part, in an interrupt driven manor?  What should I tringger my ISR on?

         

      Thanks All!

        • 1. Re: Looking for advice on using USBUART in an interrupt driven mannor on the PSoC5LP
          user_116575504
              

          1) Is it my imagination or does data transfer faster than the specified baud rate (i.e. 115,200 baud) when using a CDC driver like the one generated by PSoC Creator?  If so, is there a way in software (PSoC firmware or CDC inf file) to slow down the transfer?

             
             

          This isn't your imagination - the USB host sends data down in blocks at the USB connection-speed. The baud rate for a USB serial port is a parameter the host sends to the USB device (the PSoC 5LP in this case) and the USB device may use this to set the baud rate of an actual serial port (in the case of a USB-to-serial adapter).

             

          I don't know of a way to slow the transfer of host data, but I believe it is flow-controlled; you'll get up to 64 bytes at a time and then the host will wait for the the USB device to consume it.

             
              

          2) How do I use the USBUART, specifically the RX part, in an interrupt driven manor?  What should I tringger my ISR on?

             
             

          I have the same question myself, which is why I saw your message.

             

          Dana

          • 2. Re: Looking for advice on using USBUART in an interrupt driven mannor on the PSoC5LP
            content.librarian

            I was able to get this working.  I added a custom callback in the file: Generated_Source/PSoC5/<instance>_episr.c in the EP3_ISR handler, like so:

               

                    /* `#START EP3_END_USER_CODE` Place your code here */
                    post_USB_DATA_IN();     
                    /* `#END` */

               

            Then in non-ISR land, the following code reads the data from the USB EP:

               

                    // Ignore the new data if there is already a TX in progress
                    if (ISR_txBuffer_numBytes == 0 || 
                        ISR_txBuffer_numBytes == ISR_txBuffer_index) {

               

                        if (HostSideUSB_DataIsReady()) {
                            // Found more data on the USB device endpoint, Now it has to be read
                            // Note that this read prepares the endpoint for more data, so it has to be done
                            // only after all the existing data has been processed.
                            ISR_txBuffer_numBytes = HostSideUSB_GetData(ISR_txBuffer, sizeof(ISR_txBuffer));
                            
                            // Start the TX transfer from the internal UART
                            // The send is non-blocking so USB_BYTE_SEND_COMPLETE_SIG is sent when the
                            // transfer is complete.
                            USB_UART_PutChar(ISR_txBuffer[0]);        // Send the first byte, the ISR will handle the rest
                            ISR_txBuffer_index = 1;
                        }        
                    }

               

            As far as how to slow down the data transfer, I agree that it is flow controlled, in other words, data will come in as fast as it is read.  So to slow it down, it is just a matter of slowing down the reads.  I was syncing with an 115200 baud serial RS232 type connection, so I just put a delay (using a hardware timer) on read such that it matched the slower 115200 baud speed and it worked fine.

               

            Hope this helps!