USB-UART - Low bit rate

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

cross mob
zvivered
Level 2
Level 2
10 replies posted 5 questions asked 10 sign-ins

Hello,

My host is connected to a PSOC that contains a USBUART. 

Upon PSOC boot completion, the PC has a new COM23. 

On the PSOC side I used the following code to initialize:

USBUART_1_Start(USBFS_DEVICE, USBUART_1_5V_OPERATION);    
while(USBUART_1_GetConfiguration() ==0);
USBUART_1_CDC_Init();

On the PC, COM23 is configured to 115200[baud], 8 (data bits), 1(stop bit). 

I succeeded to send a packet to the PSOC and get a reply from the PSOC. 

But it seems the rate is quite low. 

Example: I sent 28 bytes to the PSOC and got 36 bytes from PSOC. 
Expected: (28 + 36) * 8 = 64 bytes = 512 bits
The time required to send + receive should be: ~4.5msec
Actual: The elapsed time till I got a reply was much longer. 

Is it possible to improve the performance ?

Thank you,

Zvika 

0 Likes
1 Solution
Len_CONSULTRON
Level 9
Level 9
Beta tester 500 solutions authored 1000 replies posted

Zvika,

There are two RTOS-preferred methods to do what you want to do.

  • This method doesn't require an interrupt so is code-simple.   

    • Lower the UART task priority.  This allows other tasks to process more.
    • Get rid of CyDelay(100u).  It's not needed.  Replace it with TaskYIELD().  This task should be activated every so often if the other tasks are not blocking.  I see you only have one task scheduled.
    • Since UsbUartReadMsg() performs a non-blocking UsbUartRead() then the UsbUartHandleMsg() is executed when the rc == USBUART_TASK_OK and a message is available.
  • The second method is to create a RTOS_friendly ISR.  The ISR will be attached to the RX_FIFO_NOT_EMPTY.  When the ISR executes,
    • it sets a Notify to the UsbUartTask() using xTaskNotifyFromISR()
    • Replace CyDelay() in UsbUartTask() with xTaskNotifyWait().
Len
"Engineering is an Art. The Art of Compromise."

View solution in original post

8 Replies
odissey1
Level 9
Level 9
First comment on KBA 1000 replies posted 750 replies posted

Though COM23 was set to 115k,  the actual average transfer speed is several times faster. It is, actually, irrelevant for which speed COM23 is configured - USBUART will operate at its max speed, which is 1000 packets of 64 bytes each per second. This corresponds to the equivalent UART baud rate of  64×8×1000 = 512k. However, since those packets are scheduled at only 1kHz rate, actual round-trip will be over 2ms.

     Because of this  USBUART packeting, regular UART for small message length can, actually, be faster. But since nowadays computers don't have actual UART, using some USB-UART dongle, like FTDI, you can check how quick your software can ping such dongle with shorted Tx-Rx UART pins.

I recommend to post here your project (File->Create workspace bundle->Minimal), as well as your test results. 

0 Likes
lock attach
Attachments are accessible only for community members.
zvivered
Level 2
Level 2
10 replies posted 5 questions asked 10 sign-ins

Hello,

Thank you for your reply.

Attached an archived project. 

The project contains only one Free RTOS task that waits for requests coming from a host PC and then respond. 

Thank you,

Zvika 

0 Likes

zvivered,

Unfortunately, I am not familiar with RTOS. Hopefully, someone else, proficient in RTOS, can help you further. 

0 Likes
zvivered
Level 2
Level 2
10 replies posted 5 questions asked 10 sign-ins

Hello,

I'm quite sure RTOS is not the cause to the problem. 

UsbUartTask.c is a while loop that handles incoming requests. 

Can tell if it's written properly ?

Will it help if I send a project without RTOS  ?

Thank you in advance,

Zvika 

0 Likes

Zvika,

I cannot compile your project.

I'm missing the following:

  • FreeRTOSConfig.h
  • HostToPsoc.h
  • PsocToHost.h

Regardless, I noticed an issue:

  • In UsbUartTask.c line 105 you have CyDelay(100u);   
    In general you should avoid ALL blocking functions in RTOS design (of which CyDelay is a BIG ONE).   This CyDelay will eat up 100ms doing nothing and even not letting other tasks to run.  
    There are RTOS-equivalent calls that are safer to use and lets the RTOS run other tasks until the requested time.  An example of a CyDelay()-equivalent task-safe call is vTaskDelay().

Question:  Does the "slow-down" appear to occur in the UART Write or Read?

Len
"Engineering is an Art. The Art of Compromise."
0 Likes

Hi Len,

Thank you for your reply. 

I really appreciate it. 

Is it possible to block the task  till I get incoming message ?

Currently I can't tell if the "slow-down" appear in the UART Write or Read. 

Best regards,

Zvika 

0 Likes
Len_CONSULTRON
Level 9
Level 9
Beta tester 500 solutions authored 1000 replies posted

Zvika,

There are two RTOS-preferred methods to do what you want to do.

  • This method doesn't require an interrupt so is code-simple.   

    • Lower the UART task priority.  This allows other tasks to process more.
    • Get rid of CyDelay(100u).  It's not needed.  Replace it with TaskYIELD().  This task should be activated every so often if the other tasks are not blocking.  I see you only have one task scheduled.
    • Since UsbUartReadMsg() performs a non-blocking UsbUartRead() then the UsbUartHandleMsg() is executed when the rc == USBUART_TASK_OK and a message is available.
  • The second method is to create a RTOS_friendly ISR.  The ISR will be attached to the RX_FIFO_NOT_EMPTY.  When the ISR executes,
    • it sets a Notify to the UsbUartTask() using xTaskNotifyFromISR()
    • Replace CyDelay() in UsbUartTask() with xTaskNotifyWait().
Len
"Engineering is an Art. The Art of Compromise."

Thank you very much !

0 Likes