i.MXRT 1020 USB speed test

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

i.MXRT 1020 USB speed test

4,224 Views
hahuonga2
Contributor I

Hi all,

I want to run USB speed test on i.MXRT 1020 - EVK. 

I ran some MCUExpresso USB examples such as CDC vcom, HID generic, so PC will be host, and board will be device. I change the speed to configure USB to HIGH speed (480Mb/s) on source code. But I don't know how PC communicate with the board? What is the device type that board will be known by PC?

I assume PC recognize the board as com port, and has a device like /dev/ttyACM1, should I write a C program on PC to run speed test? anh how to wirte it?

Labels (2)
0 Kudos
25 Replies

3,190 Views
hahuonga2
Contributor I

Hi jeremyzhou,

Thanks for your reply.

Actually I want to transfer data between PC and board using C program on PC side. I just need a simple way so I think cdc vcom is suitable. After that, I'll run speed test with my own program.

Now, the problem is how to configure board's USB act as high speed mode?

0 Kudos

3,190 Views
jeremyzhou
NXP Employee
NXP Employee

Hi Huong Ha,

Thanks for your reply.
In the SDK library, for instance, the dev_cdc_vcom_bm demo project, it supports to reconfigure the speed as the below snippet of code shows and please check it.

    s_cdcVcom.speed = USB_SPEED_FULL;
    s_cdcVcom.attach = 0;
    s_cdcVcom.cdcAcmHandle = (class_handle_t)NULL;
    s_cdcVcom.deviceHandle = NULL;
‍‍‍‍


Have a great day,
TIC

-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!

- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

0 Kudos

3,190 Views
hahuonga2
Contributor I

Hi jeremyzhou

Thanks for replying.

At this moment, I think I should write code for transfer first, USB speed configuring should be done after.

So I change APPTask function as bellow:

int APPTask(char input)
{
 usb_status_t error = kStatus_USB_Error;
 if ((1 == s_cdcVcom.attach) && (1 == s_cdcVcom.startTransactions))
 {
  /* User Code */
  if ((0 != s_recvSize) && (0xFFFFFFFFU != s_recvSize))
  {
   /* speed test here */
   uint32_t trans_time = 0;
   while(1) {
    int32_t i;

    /* Init Send Buff */
    for (i = 0; i < DATA_BUFF_SIZE; i++)
    {
     s_currSendBuf[s_sendSize++] = input;
    }
    s_recvSize = 0;

    /* Send data */
    if (s_sendSize)
    {
     uint32_t size = s_sendSize;
     s_sendSize = 0;

     error = USB_DeviceCdcAcmSend(s_cdcVcom.cdcAcmHandle, USB_CDC_VCOM_BULK_IN_ENDPOINT, s_currSendBuf, size);

     if (error != kStatus_USB_Success)
     {
      /* Failure to send Data Handling code here */
      PRINTF("send failed\r\n");
      break;
     }
    }
#if defined(FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED) && (FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED > 0U) && \
 defined(USB_DEVICE_CONFIG_KEEP_ALIVE_MODE) && (USB_DEVICE_CONFIG_KEEP_ALIVE_MODE > 0U) &&             \
 defined(FSL_FEATURE_USB_KHCI_USB_RAM) && (FSL_FEATURE_USB_KHCI_USB_RAM > 0U)
    if ((s_waitForDataReceive))
    {
     if (s_comOpen == 1)
     {
      /* Wait for all the packets been sent during opening the com port. Otherwise these packets may
            * wake up the system.
      */
      usb_echo("Waiting to enter lowpower ...\r\n");
      for (uint32_t i = 0U; i < 16000000U; ++i)
      {
       __ASM("NOP"); /* delay */
      }

      s_comOpen = 0;
     }
     usb_echo("Enter lowpower\r\n");
     BOARD_DbgConsole_Deinit();
     USB0->INTEN &= ~USB_INTEN_TOKDNEEN_MASK;
     USB_EnterLowpowerMode();

     s_waitForDataReceive = 0;
     USB0->INTEN |= USB_INTEN_TOKDNEEN_MASK;
     BOARD_DbgConsole_Init();
     usb_echo("Exit  lowpower\r\n");
    }
#endif
    input++;
    trans_time++;

   }
  }
 }
}

So the scenario is:

- A com port is created. On PC open it via picocom (or something like that, tera term...)

- Board waiting for trigger from PC

- On picocom, type a character

- Board send data to PC

It should be sent over and over, but only 512 characters are sent. That means USB_DeviceCdcAcmSend() function is called only once.

I don't know why?

Note that DATA_BUFF_SIZE = 512.

So could you give me some suggestion for that?

0 Kudos

3,190 Views
jeremyzhou
NXP Employee
NXP Employee

Hi Huong Ha,

Thanks for your reply.

Whether you mean that the dev_cdc_vcom_bm demo project wouldn't echo more than 512th received characters, I hope you introduce the testing process in details.

Have a great day,

TIC

 

-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!

 

- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

0 Kudos

3,190 Views
hahuonga2
Contributor I

Hi jeremyzhou,

Sorry for responding lately.

The cdc_vcom_bm demo project can echo 512bytes more times, so I can perform testing for a long time.

I try transferring data from the board to PC in 10s and calculate the speed. The result is about 190KB/s with  

s_cdcVcom.speed = USB_SPEED_FULL;

When I change the above configuration to

s_cdcVcom.speed = USB_SPEED_HIGH;

the result is the same (still ~190KB/s).

So, is that change enough to configure USB speed as High speed? Or should I make some changes in other code to archive the maximum USB speed?

Following is my testing code:

int APPTask(char input)
{
 uint64_t tsc1, tsc2;
 double tg;

 usb_status_t error = kStatus_USB_Error;
 if ((1 == s_cdcVcom.attach) && (1 == s_cdcVcom.startTransactions))
 {
  /* User Code */
  if ((0 != s_recvSize) && (0xFFFFFFFFU != s_recvSize))
  {
   /* speed test here */
   uint32_t trans_time = 0;

   tsc1 = get_timing_hardclock();

   while(1) {

    int32_t i;

    /* Init Send Buff */
    for (i = 0; i < DATA_BUFF_SIZE; i++)
    {
     s_currSendBuf[s_sendSize++] = input;
    }
    s_recvSize = 0;

    /* Send data */
    if (s_sendSize)
    {
     uint32_t size = s_sendSize;
     s_sendSize = 0;

     error = USB_DeviceCdcAcmSend(s_cdcVcom.cdcAcmHandle, USB_CDC_VCOM_BULK_IN_ENDPOINT, s_currSendBuf, size);

     if (error != kStatus_USB_Success)
     {
      /* Failure to send Data Handling code here */
      PRINTF("send failed\r\n");
      break;
     } else {
      trans_time++;

      tsc2 = get_timing_hardclock();
      tg = (((float)(tsc2 - tsc1)) / CLOCK_GetCoreSysClkFreq());
      if(tg >= 10.0) {
       PRINTF("SPEED: %fkB/s\r\n", trans_time / 2.0 / tg);
       break;
      }
      PRINTF("send ok\r\n");
     }

    }
#if defined(FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED) && (FSL_FEATURE_USB_KHCI_KEEP_ALIVE_ENABLED > 0U) && \
 defined(USB_DEVICE_CONFIG_KEEP_ALIVE_MODE) && (USB_DEVICE_CONFIG_KEEP_ALIVE_MODE > 0U) &&             \
 defined(FSL_FEATURE_USB_KHCI_USB_RAM) && (FSL_FEATURE_USB_KHCI_USB_RAM > 0U)
    if ((s_waitForDataReceive))
    {
     if (s_comOpen == 1)
     {
      /* Wait for all the packets been sent during opening the com port. Otherwise these packets may
            * wake up the system.
      */
      usb_echo("Waiting to enter lowpower ...\r\n");
      for (uint32_t i = 0U; i < 16000000U; ++i)
      {
       __ASM("NOP"); /* delay */
      }

      s_comOpen = 0;
     }
     usb_echo("Enter lowpower\r\n");
     BOARD_DbgConsole_Deinit();
     USB0->INTEN &= ~USB_INTEN_TOKDNEEN_MASK;
     USB_EnterLowpowerMode();

     s_waitForDataReceive = 0;
     USB0->INTEN |= USB_INTEN_TOKDNEEN_MASK;
     BOARD_DbgConsole_Init();
     usb_echo("Exit  lowpower\r\n");
    }
#endif
    input++;

   }
  }
 }
}
0 Kudos

3,190 Views
jeremyzhou
NXP Employee
NXP Employee

Hi Huong Ha,

Thanks for your reply.

After reviewing the code you sharing, I‘m afraid it's incapable of evaluating the speed of USB Full and High mode, for the term of USB CDC class device, the transfer speed is determined by the 'baud rate' of the USB CDC class device, in the dev_cdc_vcom_bm demo, the 'baud rate' is 115200 bps.
Hope this is clear.

Have a great day,

TIC

 

-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!

 

- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

0 Kudos

3,190 Views
hahuonga2
Contributor I

Hi jeremyzhou‌. Thanks for your reply.

So is that any example in MCUExpresso that USB port (of i.MXRT1020) working in HIGH speed mode or possible to configure USB port woking in that mode?

0 Kudos

3,190 Views
jeremyzhou
NXP Employee
NXP Employee

Hi Huong Ha,

Thanks for your reply.
1) So is that any example in MCUExpresso that USB port (of i.MXRT1020) working in HIGH-speed mode or possible to configure USB port working in that mode?
-- In the SDK library, the default USB demos work with Full-speed mode, however,  they're available to be configured to High-speed mode. Just like I mentioned in the previous reply.
In my opinion, what kind of USB class device to create is the most priority for you currently.
Have a great day,
TIC

-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!

- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

0 Kudos

3,190 Views
hahuonga2
Contributor I

Hi jeremyzhou

Actually, I don't know which USB class device should I use. I just want to transfer block of data between PC and the board via USB in max speed.

0 Kudos

3,190 Views
jeremyzhou
NXP Employee
NXP Employee

Hi Huong Ha,
Thanks for your reply.
Maybe you can consider using the HID class device, in the SDK library, it also provides some demo for referring to.

Have a great day,
TIC

 

-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!

 

- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

0 Kudos

3,190 Views
hahuonga2
Contributor I

Hi jeremyzhou

Thanks for replying.

As I know, USB HID class device just supports control and interrupt transfer type. In my case, I want to transfer data from PC to board, then from board to PC (after data processing) - like streaming. So I think isochronous is suitable.

Anyway, have you test the USB speed with HID class device on imxrt 1020 board? if yes, what is the max speed that you reached?

On MCUExpresso SDK USB Stack User's Guide, I find USB device ramdisk throughput as following picture:

Screenshot from 2019-09-03 22-53-03.png

So, could you give me the test process (for RT1050 EHCI) to archive that?

And, are there other examples worth to try (not include HID example) for my case?

0 Kudos

3,190 Views
jeremyzhou
NXP Employee
NXP Employee

Hi Huong Ha,
Thanks for your reply.

1) Have you tested the USB speed with HID class device on i.MX RT 1020 board? if yes, what is the max speed that you reached?
-- No.
2) Could you give me the test process (for RT1050 EHCI) to archive that?
-- The USB protocol tool is recommended to measure the transfer speed of the USB device, BTW, the USB MSD class is base on Bulk transfer.
3) Are there other examples worth to try (not include HID example) for my case?
-- The USB DFU class is worth to try.

Have a great day,
TIC

 

-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!

 

- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

0 Kudos

3,190 Views
hahuonga2
Contributor I

Oh, in DFU example, only endpoint 0 is used.

0 Kudos

3,190 Views
hahuonga2
Contributor I

Hi jeremyzhou

Changing LINE_CODING_DTERATE seems doesn't work. I open the vcom port in different baud rate and still communicate with the board. Btw, the usb speeds are same when changing the baud rate. So have you tried this before?

Additional question: Current clock rate is 24M. How can I change the clock rate (operating clock)? 

0 Kudos

3,190 Views
jeremyzhou
NXP Employee
NXP Employee

Hi Huong Ha,
Thanks for your reply.
1. So have you tried this before?
-- Yes, of course.
2. How can I change the clock rate (operating clock)?
-- Please use the MCUXpresso Config Tools to reconfigure the clocks.

Have a great day,
TIC

 

-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!

 

- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

0 Kudos

3,190 Views
hahuonga2
Contributor I

Hello jeremyzhou

Regarding the previous question: Could you give me the test process (for RT1050 EHCI) to archive that? (When iMX board is configured as ramdisk):
Your answer: The USB protocol tool is recommended to measure the transfer speed of the USB 

=> So could you tell me the USB tool is used?

0 Kudos

3,183 Views
jeremyzhou
NXP Employee
NXP Employee

Hi Huong Ha,
Thanks for your reply.
In our lab, we use the protocol analyzer of TELEDYE LECROY.

https://store.teledynelecroy.com/collections/usb-solutions/products/usb-t0s2-a01-x-advisor-t3-usb-2-...

Have a great day,
TIC

 

-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!

 

- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

0 Kudos

3,178 Views
hahuonga2
Contributor I

Ok jeremyzhou

I'm investigating usb ramdisk and usb ramdisk lite examples. I have an C program in PC and it writes data to the device.

Writing is successful but I can't read from the device. Below is my C program:

#include <stdio.h>
#include <string.h>
#include <sys/time.h>
#include <fcntl.h>              // Flags for open()
#include <sys/stat.h>           // Open() system call
#include <sys/types.h>          // Types for open()
#include <unistd.h>             // Close() system call
#include <stdbool.h>
#include <errno.h>

#define USB_NAME "/dev/sdc"
#define BUF_SIZE 128

unsigned char tx_buf[BUF_SIZE], rx_buf[BUF_SIZE];

unsigned long get_time() {
 struct timeval tv;
 gettimeofday(&tv, NULL);
 unsigned long ret = tv.tv_usec;
 ret /= 1000;
 ret += (tv.tv_sec * 1000);
 return ret;
}


int write_func(int fd) {
 int ret;
 
 tx_buf[0] += 1;
 tx_buf[1] += 1;
 tx_buf[2] += 2;
 tx_buf[BUF_SIZE - 1] += 2;

 printf("%u - %u\n", tx_buf[0], tx_buf[BUF_SIZE - 1]);
 ret = write(fd, tx_buf, BUF_SIZE);
 fdatasync(fd);

 return ret;
}

int read_func(int fd) {
 int ret;
 memset(rx_buf, 0, BUF_SIZE * sizeof(rx_buf[0]));

 ret = read(fd, rx_buf, BUF_SIZE);
 // fdatasync(fd);
 printf("%u - %u - %u - %u\n", rx_buf[0], rx_buf[1], rx_buf[2], rx_buf[BUF_SIZE - 1]);

 return ret;
}

int main(int argc, char ** argv)
{
 int usb_fd;
 int iCount, i;
 long w_times = 10;
 long start_time, end_time, count = 0;

 usb_fd = open(USB_NAME, O_CREAT | O_APPEND | O_RDWR | O_DSYNC, S_IRUSR | S_IWUSR);
 // usb_fd = open(USB_NAME, O_CREAT | O_APPEND | O_RDWR, S_IRUSR | S_IWUSR);

 if(usb_fd < 0) {
  printf("Open %s failed\n", USB_NAME);
  return -1;
 }

 memset(tx_buf, 0, BUF_SIZE * sizeof(tx_buf[0]));

 start_time = get_time();
  
 if(argc == 2) {
  if(!strcmp(argv[1], "-w")) {
   printf("W: argc = 2 - infinite\n");

   while(1) {
    end_time = get_time();
    if((end_time - start_time) <= 5000) {
     lseek(usb_fd, 0, SEEK_SET);
     iCount = write_func(usb_fd);

     if(iCount != BUF_SIZE) {
      printf("W: %d, %ld\n", iCount, count);
      break;
     }

     if((count % 30) == 0)
      lseek(usb_fd, 0, SEEK_SET);

     count++;
    } else {
     break;
    }
   }
   printf("write Speed = %f KB/s, count = %ld\n", (BUF_SIZE * count / 1024.0 * 1000 / (end_time - start_time) / 5.0), count);
  } else if(!strcmp(argv[1], "-r")) {
   printf("R: argc = 2 - infinite\n");

   while(1) {
    end_time = get_time();
    if((end_time - start_time) <= 5000) {
     lseek(usb_fd, 0, SEEK_SET);
     iCount = read_func(usb_fd);

     if(iCount != BUF_SIZE) {
      printf("R: %d, %ld\n", iCount, count);
      break;
     }

     if((count % 30) == 0)
      lseek(usb_fd, 0, SEEK_SET);

     count++;
    } else {
     break;
    }
   }
   printf("Read Speed = %f KB/s, count = %ld\n", (BUF_SIZE * count / 1024.0 * 1000 / (end_time - start_time) / 5.0), count);
  }
 }

 lseek(usb_fd, 0, SEEK_SET);
 close(usb_fd);

 return 0;
}
0 Kudos

3,178 Views
jeremyzhou
NXP Employee
NXP Employee

Hi Huong Ha,

How is going on now?
I'd like to suggest you use a protocol analyzer to visualize the USB transmit, it will help you to locate the cause efficiently.

Have a great day,
TIC

 

-------------------------------------------------------------------------------
Note:
- If this post answers your question, please click the "Mark Correct" button. Thank you!

 

- We are following threads for 7 weeks after the last post, later replies are ignored
Please open a new thread and refer to the closed one, if you have a related question at a later point in time.
-------------------------------------------------------------------------------

0 Kudos

3,178 Views
hahuonga2
Contributor I

Hi jeremyzhou‌,

I followed this guide: Modifying USB Generic HID Example Code for Cust... | NXP Community  and reached the speed at ~200KB/s (don't remember exactly) and this cover my spec.

Thank you very much for supporting me. 

0 Kudos