USB with the Freescale FRDM-K22F Board

The FRDM-K22F is one of the latest members of the Freedom board families: 512 KByte Flash, 128 KB RAM and the usual Freedom board components on it. Unfortunately, Freescale decided not to populate the micro-SD card connector on the board, so from this perspective the FRDM-K64F is more value for the money. But the board has USB, so this makes it still interesting. And this is what this post is about: Adding USB to the FRDM-K22F board in a few minutes…

Freescale FRDM-K22F Board

Freescale FRDM-K22F Board

Software Update

I’m using Kinetis Design Studio in this post with Processor Expert components.

Components

Components

You need the “Processor Expert Support for Kinetis K22F/KV31F @120/100MHz Service Pack” installed. You get that update with the menu Help > Install New software and use the

http://nxp.com/lgfiles/updates/Eclipse/KDS

update site:

Installed K22F Service Pack

Installed K22F Service Pack

Additionally, you need the latest McuOnEclipse Processor Expert components from SourceForge (https://sourceforge.net/projects/mcuoneclipse/files/PEx%20Components/), see “McuOnEclipse Releases on SourceForge“.

Project Creation

Create a new project for Processor Expert in Eclipse and for the MK22FN512xxx12 device:

New Project for MK22FN512

New Project for MK22FN512

Do *not* select the Kinetis SDK option, only select Processor Expert:

Processor Expert Project

Processor Expert Project

Clock Configuration

The K22 can run up to 120 MHz. I configure it to maximum speed, similar to the K64F (see “FRDM-K64F at Maximum Speed of 120 MHz“). I have the 8 MHz external crystal enabled:

Enabled External 8 MHz Crystal

Enabled External 8 MHz Crystal

MCG is set to PEE with a PLL output clock of 120 MHz:

PEE with 120 MHz Clock

PEE with 120 MHz Clock

System clocks are set to the maximum possible values:

System Clocks

System Clocks

USB Configuration

Add the FSL_USB_Stack component to the project. I’m using here a USB CDC Device class. Configure it to use Init_USB_OTG_VAR0 and enable USB CDC Device class:

USB Component Configuration

USB Component Configuration

Enable the clock gate and have it to use the PLL/FLL clock with the clock divider output as clock source. To build the needed 48 MHz USB sampling clock from the 120 MHz PLL clock, use a multiplier of 2 with a divider of 5:

USB Init Configuration

USB Init Configuration

Finally, select the K22FN120 as CPU in the USB CDC sub component:

USB CPU Selected

USB CPU Selected

That’s it!

Application Code

What is missing is now the application code. It can be very simple as this:

#include <stdio.h>
static uint8_t cdc_buffer[USB1_DATA_BUFF_SIZE];
static uint8_t in_buffer[USB1_DATA_BUFF_SIZE];

static void CDC_Run(void) {
  int i, cnt = 0;
  uint32_t val = 0;
  unsigned char buf[16];

  for(;;) {
    while(CDC1_App_Task(cdc_buffer, sizeof(cdc_buffer))==ERR_BUSOFF) {
      /* device not enumerated */
      LED1_Neg(); LED2_Off();
      WAIT1_Waitms(10);
    }
    LED1_Off(); LED2_Neg();
    if (CDC1_GetCharsInRxBuf()!=0) {
      i = 0;
      while(   i<sizeof(in_buffer)-1
            && CDC1_GetChar(&in_buffer[i])==ERR_OK
           )
      {
        i++;
      }
      in_buffer[i] = '\0';
      (void)CDC1_SendString((unsigned char*)"echo: ");
      (void)CDC1_SendString(in_buffer);
      UTIL1_strcpy(buf, sizeof(buf), (unsigned char*)"val: ");
      UTIL1_strcatNum32u(buf, sizeof(buf), val);
      UTIL1_strcat(buf, sizeof(buf), (unsigned char*)"\r\n");
      (void)CDC1_SendString(buf);
      val++;
    } else {
      WAIT1_Waitms(10);
      cnt++;
      if ((cnt%1024)==0) { /* from time to time, write some text */
        (void)CDC1_SendString((unsigned char*)"Type some text and it will echo.\r\n");
        CDC1_SendBlock((unsigned char*)"hello?\r\n", sizeof("hello?\r\n")-1);
      }
    }
  }
}

Summary

The K22F is the latest addition to the list of supported USB microcontroller in the FSL_USB_Stack component. The example project featuring USB CDC is available on GitHub.

Happy USBing 🙂

Links:

90 thoughts on “USB with the Freescale FRDM-K22F Board

  1. Pingback: McuOnEclipse Components: 27-Dec-2014 Release | MCU on Eclipse

  2. Hi!

    Many thanks for your excellent tutorials.

    When should we use the mcuoneclipse FSL_USB_Stack component and when should we use the fsl_usb_descriptors, fsl_usb_framework and fsl_usb_device_* components?

    I’m trying to get a USB MSD device working on my custom K64-based board with an SD card for storage. It appears that the Freescale fsl_usb_device_msd_class component is the tool for the job. When I add it to my project, it brings with it a usb_descriptors component and a fsl_usb_framework component. I think everything is set up right (clocks, initialisation, etc), but when I plug in USB, nothing happens. The init code runs fine, and the code jumps correctly through all the error handling without printing (or trying to print) any errors out to the debug console (which is itself working fine). However, enumeration doesn’t seem to get anywhere at all. Perhaps I need to set up and handle some callbacks, or something?

    Before I get into a thorough debugging session, it would be good to have an overview of what components I’m actually supposed to use!

    It seems that the KDS 2.0.0 + KSDK 1.1.0 + Processor Expert combination is in a lot of flux at the moment, and almost completely undocumented! Am I right, or am I missing something? The built in “Help on Component” feature in KDS is woefully inadequate! There don’t seem to even be any KDS+Processor Expert examples formally supplied by Freescale.

    Since I’m new to the Kinetis tools, I would prefer to start with KDS rather than the deprecated CW stuff.

    Cheers
    Jeff

    Like

    • Hi Jeff,
      thanks 🙂
      the fsl_ (lower case) components are only working with the Kinetis SDK (http://www.freescale.com/ksdk) projects. I have not used them for my USB projects yet (I always used the FSL_USB_Stack components so far. For the reasons you mention in your comments. If enumeration does not work: check if USB interrupts are enabled and working (set a breakpoint in the interrupt service routine). And yes: use KDS, CW is depreciated.
      I hope this helps.
      Erich

      Like

      • Thanks for the quick reply, Erich! I will revisit this once I’ve got some of my basic parts to work. I’m using KSDK so I’ll try the lowercase variants.

        Currently crawling through fire to get the comparator output pin out of tristate so I can begin to find out why my comparator doesn’t work! Glacial progress with this toolchain. 3 days in and I’ve only got UART and an LED!

        Keep up the great work!

        Like

      • Hi Erich,
        I’m still stuck on this I’m afraid! The usb demo code works ok (dev_msd_disk_frdmk64f_bm_frdmk64f) but I want to build a standalone version that is not reliant on the precompiled libusbd_bm.a and libksdk_platform.a . I need a clean code tree that is all in one git repository.

        I’ve tried with the fsl_usb_ components, as well as by copying the KSDK-1.1.0/usb folder into my source tree and building it that way. Both produce the same outcome – the USB-MSD stack initialises ok (lots of USB_OK’s, and correct debug print statements) but when you plug in a USB cable it doesn’t enumerate. No interrupts fire.

        A little more background info here:
        freescale community thread/353811

        Do you have any ideas? The freescale forum is very quiet!

        Many thanks
        Jeff

        Like

        • Hi Jeff,
          I’m affraid that I cannot help you much here. So you are saying that it works with the library, but not if you build the files yourself? That sounds like the library is build with different set of options or settings?

          Erich

          Like

  3. Pingback: Proof of Concept: Open Source ARM SWD Debug and General Purpose Board | MCU on Eclipse

  4. Hi Erich,

    I have implemented this project and have seen that USB CDC implemented in this project is bus-powered but I couldn’t find any option to toggle between self-powered and bus-powered options inside FSL_USB_STACK component.

    Thanks,
    Saad

    Like

      • Hi Erich,

        Powering mechanism is catered inside configuration descriptors in USB 2.0 standard. In FSL USB Stack, this is implemented in g_config_descriptor() function inside usb_descriptor.c and is enabled for all three powering options (Bus-powered, Self-powered and Remote wake-up). There is no option available in processor expert to change it to any specific powering option.

        Like

        • Hi Muhammad,
          I have implemented an additional setting in the component, so you can enable/disable bus powered and self powered options.
          I’m going to commit the changes on GitHub, are you able to get it from there?
          I plan to release new *.PEupd files soon, but I don’t know when I can do this.

          Thanks,
          Erich

          Like

  5. Hi Please help me.
    I am trying the same on K22F board.
    1. Using KSDK1.2 latest version.
    2. KDS latest version 3.0
    3. Freescale K22F

    I follow all the steps as explained by you. But I get error. USB0: “Device not supported on selected processor”

    Please help me. I am stuck with this problem from many days.

    Like

    • Hi Vishal,
      have you cerated that project with the Kinetis SDK option enabled? With the Kinetis SDK, many Processor Expert components do *not* work, including my FSL_USB_CDC one. So if you create your own new project, make sure you select ‘none’ for Kinetis SDK.
      I hope this helps,
      Erich

      Like

  6. Pingback: tinyK20: New Board with micro-SD Card | MCU on Eclipse

  7. Hello Erich!
    Thanks for the nice post!
    I imported your project, and tried to run in my K22F board.
    I use the USB_CDC_SEGGER Debug.
    The code is stucked in this loop:
    while(CDC1_App_Task(cdc_buffer, sizeof(cdc_buffer))==ERR_BUSOFF)

    How can I run the code correctly?
    Can I open the com port with Putty and see the USB activity?
    Where did you configure the baud rate?
    I’m a little confused. hehe

    Thanks in advance.

    Like

    • Hi Guiherme,
      if you are stuck in this while loop, it means that the board was not able to enumerate (connect) with the host PC. Have you used as second USB cable to connect to the K22F port (USB)?
      And yes, you can use Putty or any other terminal program to connect to the board: open the COM port which has been installed/enumerated with that board.
      Baud: that’s a thing of UART, not of USB. USB CDC does not have a baud rate. So you can use any baud you like in the terminal (I prefer 38400).
      I hope this helps.

      Like

      • Yeah, I tried to connect with 2 cables, but I saw now… my driver is with some warning problem in windows device manager.
        I found another post in your site that you explain how to set the things on… hehehe
        Erich, I really aprecciate your help.
        In 10 lines you explained all my doubts about the usb connection problem.
        Thanks, my friend, and congratulations by your excelent work in the site!

        Like

  8. Pingback: Microchip DAC Module MCP49xx on FRDM-K22F using Software SPI | TechnoChronicle

  9. Hello.
    Is there any problem to use the FRDM-K22F running in 120 MHz, using SPI and USB at the same project? Because the SPI is not working, only the USB.

    Like

    • Hi,
      I am not using the combination of SPI and USB. I am only using SPI in my project. And for me, it works at 120 MHz. I am using following pins.

      PTC9 –SDCARD_DETECT
      PTD0 — SPI0_PCS0 SDCARD_CS
      PTD1 — SPI0_SCK SDCARD_SCK
      PTD2 — SPI0_MOSI SDCARD_MOSI
      PTD3 — SPI0_MISO SDCARD_MISO

      Like

      • Hi Vishal,
        are you using the SD card footprint/socket on the FRDM-K22F for this? I have put a socket on it (same as on the FRDM-K64F board), but somehow I do not get it to work :-(. I have a core clock of 120 MHz, maybe I see that problem with USB too?

        Like

        • Hi Vishal,
          It works now :-). I have sorted out my problem: I was sending LSB instead of MSB on the SPI bus 😦 So I have now both the SD card and USB working on the FRDM-K22F with 120 MHz core clock. Project is my ‘Kinetis Drone’ project on GitHub:

          Like

  10. Hi, Erich

    I want to use “K20DX256VLK10” in my project, and CDC, but I found the component FSL_USB_Stack doesn’t support this MCU, please let me know, how can I use CDC in this projetc? or, do you mind add this MCU to component, thank you very much

    Like

  11. Hi Erich,

    I have run into a strange problem in USB CDC using your component; since I updated KSDK 1.3.0 (which I am definitely not using in CDC project), I can not select USB Init as Init_USB_OTG_VAR0 in processor expert. This option is not available at all. Although I am not using OTG but this error doesn’t allow processor expert to generate the code. Can you please tell if there is any link between the KSDK and CDC component?

    Regards,
    Saad

    Like

    • Yes, I have seen such a problem in several of my projects, but did not think that it could have been caused by the SDK v1.3 update :-(. So thanks for that tip.
      Are you using my latest version of the components from SourceForge? Because in the most recent version I have added the ability that you can add the Init_USB_OTG_VAR0 *outside* the USB component. Set the ‘Inherited USB Init’ to disabled and have the Init component added outside of the USB component.
      I hope this helps.

      Like

      • No, I am using “Component_2015_03_22” which are quite old but I have built a big project with several other components as well so I assume I can not replace the FSL_USB_STACK component in the project with a new revision.

        If I update components in eclipse then will it update the FSL_USB_STACK already being used in the project or I’ll have to add the new component to project again?

        Like

        • It is always good to make a backup (just in case). The components are stored here: C:\ProgramData\Processor Expert
          If you update the components, it will overwrite the existing version. You don’t have to add new components to the project again. But you might need to add a few additional components (e.g. utility, or Kinetis SDK, or CriticalSection) as some of them have been referenced in addition. Should not be a big deal.

          Like

      • I have updated the 22.11.2015 components into PEx. I wanted to know that can I use KSDK 1.3.0 components and PEx components within the same project?

        Regards,
        Saad

        Like

        • Hi Saad,
          you can use the Freescale provided PEx components which names are starting with “fsl_”. You cannot use any components which end with “_LDD” and no other components provided by Freescale (ahem: NXP) which are using hardware. You can use many of the McuOnEclipse components especially the ones which do not depend on hardware. You can use the McuOnEclipse FreeRTOS component, but you cannot use the “FSL_USB_Stack” component as it depends on the USB hardware. In general: the Kinetis SDK is very different and you cannot use it with components created before the SDK area.
          I hope this helps?

          Like

  12. Pingback: USB CDC with the Raspberry Pi | MCU on Eclipse

  13. Hi Erich,

    Is there a way to set the required USB current in the configuration descriptor? Currently, I have to manually modify the usb_descriptor.c file to set maximum power to 500mA because my CDC device requires about 300mA to work.

    Are you planning to add the power setting feature in the next release of the PE components.

    Many thanks,
    Kevin Le

    Like

  14. Hi, I’m trying to get a USB CDC implementation working on a custom board using a 120 MHz K22FN processor, almost the same as on the Freedom board. Following the steps in this post, I was able to get the board enumerating as a USB device, but I would really like to be able to use the FSL_USB_STACK component in a KSDK 1.3 project. The KSDK fsl_dpsi peripheral is pretty essential for what I’m trying to do – reconfigure programatically from an SPI slave to SPI master, which the MCU on Eclipse SPI LDD components cannot do.

    Anyways, using a KSDK 1.3 project, I can add and configure the FSL_USB_STACK component, but the INIT_USB_OTG inherited component always throws errors, saying that “the component is incompatible with the selected processor”, and will not let me enable the clock gate or change other config parameters.

    I tried adding a non-inherited INIT_USB_OTG component with the same configuration as the one generated by FSL_USB_STACK, but using the non-inherited component, I cannot get the device to enumerate. It fails saying it cannot get descriptor info.

    Any ideas?

    Like

    • Hi Devin,
      yes, the problem is the INIT_USB_OTG component. In my latest component version, you could can disable the ‘Inherited USB Init’. But then do not add the INIT_USB_OTG component. Instead, you need to add code to your application which does the same (initializing the USB). I have not tried that, but if done properly, it should work.
      If it does not enumerate, it might be a problem with your clocking (make sure the USB is clocked with 48 MHz) plus that the interrupt vectors are configured properly.
      I hope this helps,
      Erich

      Like

      • Hi Erich,

        I tried using the enumerating, non-SDK project to generate code to the SDK, non-enumerating project, but even after resolving all of the dependencies calling USB0_Init just results in getting stuck inside DefaultISR.

        My clock config is fine, using a crystal-less, 120/60/48 MHz config for Core/Bus/USB respectively.

        Any advice on how to get USB initialized without using either the inherited or SDK verion of the USB_Init_OTG module? It would be awesome to get this working, as I personally find the SDK USB implementation (fsl_usb_framework) baffling, and would rather steer clear of it.

        Like

        • Hi Devin,
          I made some progress today on the same thing with a FRDM-K64F. I have it not fully working yet, but close I think. I hope I can put it up (working) on GitHub soon. If you end up the DefaultISR than this tells me that probaly the USB interrupt vector is not pointing to the USB interrupt service routine which is USB_ISR(). I added something like this as a quick wrapper:
          void USB0_IRQHandler(void) {
          USB_ISR(); /* call USB handler */
          }

          The other thing is I had to add the clock ungating to the USB0_Init() I have copied from the Processor Expert version (non-SDK):
          static void USB0_CommonInit(void) {
          /* SIM_SCGC4: USBOTG=1 */
          SIM_SCGC4 |= SIM_SCGC4_USBOTG_MASK;
          /* SIM_SOPT2: USBSRC=1 */
          SIM_SOPT2 |= SIM_SOPT2_USBSRC_MASK;
          /* NVICIP53: PRI53=0 */
          // NVICIP53 = NVIC_IP_PRI53(0x00);
          NVIC_SetPriority(USB0_IRQn, 0);
          }

          void USB0_Init(void) {
          USB0_CommonInit();

          /* Register ‘USB0_CTL’ initialization */
          ….
          }

          I hope this helps,
          Erich

          Like

      • Just saw the changes to FSL_USB_Stack.drv, what were you trying to do on line 273? USB0_IRQn just shows up as undefined. Is the ISR name meant to be a placeholder?

        Like

      • Nevermind, I got it. It’s defined by one of the SDK includes. I’ll try implementing your changes to the USB init and IRQ, let me know if you get it working on your freedom board.

        Like

  15. Pingback: First steps: ARM Cortex-M7 and FreeRTOS on NXP TWR-KV58F220M | MCU on Eclipse

  16. Hi! I am following this USB Stack example, however I need to access the USB port as: MSD_Host.

    I have the latest version of Kinetis and MCUOnEclipse. I re-created this example project above in Processor Expert and I have no application code yet. When the USB Stack is initializing, it enables the Interrupts and the CPU is always re-entering the “void USB_ISR(void)” in khci_kinetis.c. This behavior let me think the USB ISR Flag stay always raised and never get cleared. The CPU is then always looping within the “void USB_ISR(void)” function and the normal code never has a chance to be executed.

    If I configure the USB Stack Device Class as “CDC Device” (Like in this example) I don’t have any Interrupt issue. If I configure it to “CDC Host” or “MSD Host” I have this interrupt problem.

    Like

      • Hi, I am currently using an older processor: MK20DX256VLH7. Everything is working (including the USB) and we are in production with this processor right now. The problem is that my application need more RAM than expected and I am trying to port it to: MK22FN512VLH12. Both chips have the same pins configuration (this avoid PCB Layout changes) and this new chip has 128K RAM instead of only 64K.

        While porting my project (that include the application part of the MSD Host) to this new processor I found this USB Interrupt problem. My original project has been written with an older version of Kinetis and Processor Expert but I am now using the latest versions when working on the MK22FN512VLH12.

        While executing the “int main(void)” function It correctly enter into the “PE_low_level_init();” function. However it never returns from this function because when the USB interrupt is enabled, 100% of the CPU is dedicated to the “void USB_ISR(void)”. So even if I put the application part of the MSD Host, it will never be executed anyways. In the “FSL_USB_MSD_HOST” component, CPU setting is set to : “Kenitis K22FN120” as mentioned in this example.

        I am an experienced embedded developer and I am suspecting there might be a bug in processor expert with the FSL_USB_MSD component on the MK22FN512xxx12 processor. Would it be possible to test this scenario on your side to see if you have the same issue?

        Like

      • Hi! The Interrupts were disabled in my project but I saw that the were getting enabled by the initialization code, even if the option was set to disabled. I checked your project and I saw that all the interrupts were also masked.. The interrupts were unchecked in PE (Stall, Attach, Resume,…) By doing the same thing in my project, it fixed my problem. Thanks!

        Like

  17. Hi Erich,

    I’m trying to get the USB stack working on a K22 board at work.

    The problem i’m having with Kinetis Design Studio is that when I come to select the CPU in the “FSL_USB_CDC_Device”, the Kinetis device I’m using doesn’t appear in the list – even having applied the software update you suggested at the start of the tutorial yet the K22 doesn’t appear: K40, K60 and KL25 are my only options.

    Have I missed a step?

    Kind regards,
    Kevin

    Like

  18. Hi Erich,
    Your the most help that can be found on Kinetis …. Thanks again.

    Question for today:
    On my K22FN512 custom hardware I am dumping a ‘virtual debug screen’ through the USB CDC component.

    In my program I keep a memory mapped virtual screen (about 120×40 chars) that I have routines that do formatted prints to an row,col address. There is also a second frame buffer that just contains the color attribute data and keeps a ‘dirty’ bit so I can tell if that location needs redrawing.

    About 10 times a second I refresh the screen by building a output stream full of ANSI esc sequences for positioning the cursor and setting the color attribute, and the ascii chars.

    I then send this stream out using ‘CDC1_SendString(Buffer);’, and buffer could be hundreds or in the case of an entire screen refresh, 5000 or more characters.

    The terminal emulator program I am using is TeraTerm, and it usually nicely displays my screens, although there is a flakeyness when I am changing lots of info and if it loses some or all of an ANSI esc sequence my screen gets hashed.

    I am trying to figure out how to make it more solid – I have upped the endpoint sizes, and the RX and TX buffer sizes (2048 is the max I can get away with, if I try 4096 something breaks in the compile) , which seems like it helped a some, but I am wondering if there is something I can do to make the screens perfect.

    Clearly, possibly some (or all?) of the problem is that Tera Term is choking on the volume of characters (actually it might be the ansi esc sequences that give it more grief)

    Any thoughts?

    Like

      • it was an odd error, and it was the RTT system view module that didn’t compile. It didn’t say anything about ram or stack, but I assumed that was the problem. when I went back to 2048 for the RX and TX components, the error went away.

        Like

        • Hi Brynn,
          i quickly tried RTT and USB CDC with ring buffers of 4096 bytes, and have not seen any problem. If you see it again, please let me know.

          Like

    • I assume it works fine if you say send the data with 1 Hz? Then there should be nothing wrong with the escape sequences.
      Make sure your processor is running at max speed of 120 MHz.
      Make sure the USB interrupt has the highest interrupt level (0) in the system: that way USB transfers are not interrupted.
      Making the ring buffer largers helps that you can store more data in it until it needs to be sent. Have a look at CDC1_SendChar().
      When the buffer is full it calls CDC1_App_Task() which then will prepare the packet so it can be picked up by the polling host. This will only send 64 bytes (unless you increase that buffer).
      You should call CDC1_App_Task() frequently outside calling CDC1_SendStringBuffe(), I hope you are doing this? This will ensure that the Tx and Rx buffers are frequently processed.

      Last but not least: remember that the host is driving the USB CDC transfer: so if the host (PC) does not poll the USB bus frequently enough you will see problems too. So this all might depend on the libraries of your host too.

      Like

      • I tried at 2 hz instead of the 20hz that the update runs at, and while it was better it still had issues.

        My CPU was running at 96Mhz off my 16 Mhz external crystal, I figured out how to change it to 120Mhz and still have the USB at 48Mhz. That is going to help in general with it just being faster.

        USB interrupt priority seems to be at the default priority of ‘0’

        When I was checking that CDC1_app_task gets called alot (it is in a task that has a 10ms task delay at the end of the loop), I noticed that it is called with yet another buffer – cdc_buffer.

        Tracking the size of this, it was only set to 1024, and had the comment
        /*
        DATA_BUFF_SIZE should be greater than or equal to the endpoint buffer size,
        otherwise there will be data loss. For MC9S08JS16, maximum DATA_BUFF_SIZE
        supported is 16 Bytes
        */

        So, my endpoint was bigger than this. I cranked this size up ( it is in the USB1_FSL_USB_Stack component).

        Now I have that one set to 4096, the out_endpoint set to 4096, and the TX ring buffer set to 4096.
        (the in_endpoint is 512, and RX ring buffer is set to 512)

        It now works almost perfectly. The only time it fails is sometimes when the ‘refreshEntireScreen’ is called either periodically or with a manual command, often it mangles.
        As this routine was only created to try to redraw a mangled screen, I shouldn’t have to call it anymore.
        And actually, it’s likely that when I call that routine – which sets the dirty bit on every character in the frame buffer -it builds a character stream that is bigger than 4096.
        even with a screen of 100×40 it has to add the escape sequences everytime the color changes.

        A simple fix to the full screen refresh is to just split it into two half screen refreshes which should never be more than 3k chars (unless I did something dumb like change the color of every character)

        Thanks a bunch Erich!

        Brynn

        p.s. working on my next question already, but will try to stick it in the comment of the most appropriate thread…

        Like

        • Hi Brynn,
          There are different buffers for CDC1_app_task(), as the USB stack uses pointers to it and it is necessary to separate the data if multiple data transactions are started. Unfortunately this is the way how they have architected the USB stack. Another thought: make sure you are using only a single task sending data to the USB CDC: if you have multiple tasks using the USB, you need a mutex in place to guarantee reentrancy as the USB stack is using global variables.

          Like

  19. Hi Erich,
    It’s working perfectly now. Getting the buffer sizes happy, and then in my screenupdate routine that builds the stream of characters and ansi escape sequences, it checks to see that it is not overrunning the buffer by just finishing up the current line if it is getting near buffer full. Since it only streams out frame buffer locations that have the dirty bit set, this works perfect – it will just take two or more calls in the rare case where I set the dirty bit on every character in order to force a complete update. which at 20Hz you can’t hardly notice.

    Code was already only calling the CDC1_sendString in one task. However, CDC1_appTask does get called in several tasks, is that okay? ( I assume it must be, because of my perfect screen…)

    Thanks Erich!
    Brynn

    Like

    • Because CDC1_AppTask() is using its own buffer from outside, I think it *could* be ok to have it called just from one task. I have not checked if it really would be possible (the USB stack is not that easy to understand), but in my applications I have it called from one task only. If it works for you, great!

      Like

  20. Hi Erich,

    First, I would like to thank you for all the help you have provided for me and for my colleagues through your blog and through your components.

    I am running into some unexpected behaviour using the example code for this component: FRDM-K22F_USB_CDC. I have changed the code which sends data to the CDC to only the following:

    if (CDC1_GetCharsInRxBuf()!=0) {
    … // not relevant
    } else {
    CDC1_SendBlock((unsigned char*)test_buf, 64);
    }

    I have earlier initialised the buffer (once only), e.g.:

    char test_buf[65];
    for (int i = 0; i < 64; i++) { test_buf[i] = '0' + (i % 10); }
    test_buf[64] = 0;

    On sending the data to a consumer application on the PC, the consumer registers a throughput of about 3072 bytes per second, or about 24000 baud.

    I have also tested the performance with a FreeCntr at the source and sent the output to Putty running at a variety of baud rates. The result is the same: 3072 bytes per second.

    Does this level of performance surprise you? This compares with a throughput of about 480000 baud using the OpenSDA UART to send the same data to the same consumer. I was hoping for something up to 3 MBaud, rather than 24 kBaud.

    Thanks in advance for your thoughts on this,
    Bruce

    Like

    • Hi Bruce,
      thank you 🙂
      To increase performance: check your USB_CDC_Device component settings: Under Configuration, there is a setting for DATA_BUFF_SIZE (in the latest released component). By default this is set to 64 bytes. For a high performance USB application I have set this to 1024 bytes. This should help you getting a higher data rate.

      I hope this helps,
      Erich

      Like

      • Hi Erich,

        Thank you so much for your instant help!

        I have made the following changes, with no discernible impact on performance:

        USB1:FSL_USB_Stack – No changes
        USB0:Init_USB_OTG – No changes
        CDC1:FSL_USB_CDC_Device –
        DATA_BUFF_SIZE=1024,
        USB_EP0_SIZE=1024,
        USB_EP1_SIZE=1024,
        USB_EP2_SIZE=1024
        Tx1:RingBuffer – Buffer Elements=1024
        Rx1:RingBuffer – Buffer Elements=1024

        After saving changes, USB1_DATA_BUFF_SIZE is now defined as 1024.

        The throughput is still around 24 kBaud. Am I missing a setting?

        Thanks again,
        Bruce

        Like

        • Hi Bruce,
          I don’t have my board with me, so cannot verify the performance.
          My settings:
          CDC1:FSL_USB_CDC_Device –
          DATA_BUFF_SIZE=1024,
          USB_EP0_SIZE=1024,
          USB_EP1_SIZE=1024,
          USB_EP2_SIZE=1024
          Tx1:RingBuffer – Buffer Elements=1024
          Rx1:RingBuffer – Buffer Elements=64 (I’m mostly sending)
          SendDataBlock
          Use Timout: enabled
          App Task Timeout: 100 ms
          Waiting time: 50 ms

          Like

        • Hi Erich,
          Thanks once again.
          Unfortunately there is no change in the performance using these settings.
          Best regards,
          Bruce

          Like

        • Hi Erich,
          I’m going to try to use the KSDK USB CDC code provided with MCUXpresso (dev_cdc_vcom_bm), which we have clocked at 6 MBaud and above.
          Thank you for all your help. If at any time you – or any of your readers – find yourself speed-testing the PEx USB CDC components, I would be most interested in hearing the results.
          Thanks again.
          Bruce

          Like

  21. Pingback: FatFS, MinIni, Shell and FreeRTOS for the NXP K22FN512 | MCU on Eclipse

  22. Pingback: How to get Data off an Embedded System: FatFS with USB MSD Host and FreeRTOS Direct Task Notification | MCU on Eclipse

  23. Pingback: Visual Studio Code for C/C++ with ARM Cortex-M: Part 1 | MCU on Eclipse

Leave a reply to Raulmerlin Cancel reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.