USB CDC with the FRDM-K64F, finally!

Sometimes I think that a problem should be solvable in a few minutes, and then it turns out that it lingers around for months. Very, very frustrating! Such a thing is getting the USB 4.1.1 stack running on the FRDM-K64F board. I have that board since April 2014, and it took me 7 months to get the FSL USB stack running on it :-(.

FRDM-K64F Board

FRDM-K64F Board

I’m using the Freescale USB V4.1.1 stack and Processor Expert McuOnEclipse FSL_USB_Stack component successfully in many projects (ColdFire, S08 and Kinetis). But despite all my trials and debugging, the USB on the K64F failed to enumerate on the host.

💡 Freescale discontinued the USB V4.1.1 stack, and newer Kinetis devices are only supported with the USB stack in the Kinetis SDK. That Kinetis SDK stack is very different from the V4.1.1 stack, and only supports newer Kinetis Devices. So using that SDK stack was not an option.

Of course I have not working on that problem full-time, but nearly every week-end I thought that this problem should be solvable. Usually to port the stack to another Kinetis device is very easy: make sure the USB peripheral gets clocked at 48 MHz, check the USB interrupt vector location, and it simply works. But not for the K64F on the FRDM-K64F Board :-(.

I was already close to give up on that topic, until I reader ‘Obi’ (thank you, thank you, thank you!) posted a tip in a previous blog post: The problem is that the K64F has a memory protection unit, and this needs to be disabled before using the USB!

disablingMemoryProtectionUnitForK64F

disablingMemoryProtectionUnitForK64F

The fix for K64F has been committed on GitHub, and will be available with the next release of the components on SourceForge.

To use USB with the FRDM-K64F, create a Processor Expert project, then add the FSL_USB_Stack component to the project:

FSL_USB_CDC Component

FSL_USB_CDC Component

Select the Init_USB_OTG_VAR0 (for Kinetis) and the USB CDC Device Class:

USB CDC Device

USB CDC Device

In the Init_USB_OTG component, have the clock gate enabled and make sure that you have a 48 MHz USB module clock:

USB Init Clock

USB Init Clock

💡 The Clock divider input depends on how you have configured your CPU clock, see FRDM-K64F at Maximum Speed of 120 MHz.

The USB interrupts are disabled on startup, the interrupt will be enabled later in the USB stack initialization:

USB Init Interrupts

USB Init Interrupts

In the USB CDC component, I need to select my device:

USB CDC Device Selection

USB CDC Device Selection

The USB CDC device uses two ring buffers for the data:

USB CDC with RingBuffers

USB CDC with RingBuffers

Set both the Rx and Tx buffers to a reasonable size (I use 64 bytes):

USB CDC Ring Buffer Size

USB CDC Ring Buffer Size

With this I’m ready to use the USB CDC. Below is an example code using it:

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);
      }
    }
  }
}

With this, USB CDC enumerates and runs with the K64F :-).

Test Program for USB CDC on FRDM-K64F

Test Program for USB CDC on FRDM-K64F

Summary

Sometimes it takes a long time for a break through, as in this case. And as in this case, the right hint can come from somebody else. A big “thank you” to ‘Obi’!!!! I’m sure many other users of the FRDM-K64F board have waiting for that USB working.

An example project for KDS V1.1.1 is available on GitHub.

Happy USBing 🙂

Advertisements

83 thoughts on “USB CDC with the FRDM-K64F, finally!

  1. is this why I can’t get a zigbee module to communicate? Like you I have been trying for months!
    So using the mbed compiler how do I turn off the MPU?

    PS I still cant get any sense out of the KDS too many stupid hurdles to jump, and I dont know where to start, especially as the NON beta version is so different in many ways that no tutorials are applicable!

    Like

    • How is your zigbee module connected to the microcontroller? SPI? I think that you might see a different problem. But maybe as for my problem, it is just a silly setting somewhere. I don’t use mbed any more, as too complicated and not usable for real development, or to solve problems like this.

      PS: What is so different? Start with the menu File > New > Kinetis Design Studio Project.

      Like

  2. Hello, Erich! Thanks for Your Job! what about USB-MSD component for FRDM-k64F? i am trying this for a week, and wait for your tutorial :))

    Like

    • Hi Oleg,
      yes, whith this the MSD class should work as well. I will probabably not have the time for a tutorial the coming weeks (I have a backlog of several weeks now). But if you use the existing MSD tutorials/projects, you should be able to get it working?

      Like

  3. Hi Eric, can you clarify between the FSL_USB_Stack and the LDD_USB and which you would recommend for different processors. I’m not clear from your discussion.
    I have KDS1.1 with your latest PE and FRDM-K20D50 for prototyping and target custom board with MK20DX128VLH7
    My objective is to test the stability of the USB Host MSC with a USB stick like some of your example projects. This is to do ADC readings and then write them to the USB stick.
    In the final application I’m looking to have USB OTG, with the capability of writing to a USB stick when plugged in, or using a USB HOST CDC if plugged in (Android Device or plain modem), and also USB Device if computer plugged in.
    Many thanks

    Like

    • Hi neilh20,
      There are three different USB stacks from Freescale: the USB (aka medical) V4.1.1 stack (which builds the foundation of my FSL_USB_Stack component, the MQX USB stack (in MQX), and the Kinetis SDK USB stack.
      The LDD_USB stack has been orphaned/discontinued by Freescale, and is yet again a different implementation of the V4.1.1 stack from Freescale. Yes, it is still there for older devices, but is not provided any more for new devices. The new way is to use the USB stack in the Kinetis SDK. I have created my own FSL_USB_Stack because the USB_LDD was a) not easy to use and b) had many issues. The V4.1.1 stack at least was working for me, so I created a component for it.
      Going forward, you probably have to look at the FSL Kinetis SDK USB stack, as this is maintained by Freescale.
      Good luck!

      Liked by 1 person

  4. Eric
    I didn’t realise that you had difficulties with the USB for this time – the problem was however discussed here at the beginning of the year:
    https://community.freescale.com/message/379572#379572
    Note also that if you want to work with descriptors, strings etc. directly from Flash for efficiency (I think the FSL stack copies everything to RAM) the K64 needs the USB controller’s access rights to be set to FMC_PFAPR – K64 USB is bus master 4 but other devices have different numbering – eg. K60 USB is 3).
    Regards
    Mark

    Like

    • Hi Mark,
      yes, when I found the problem with the memory controller, I remembered something having seen in the forums (thanks for the link!). Yes, by default for Kinetis the stack puts the descriptor into RAM.

      Like

  5. Hello Eric, do you think this component in KDS1.1 should work with the FRDM-M20D50.
    When added FSL_USB_Stack(& configuring) and then FatFsMem_USB_MSD and FAT_FileSystem to the project has some problems that look like a code cleanup.
    On compiling Expecting
    Event.c: delay_counter – 1mS up counter (can do that)
    host_ch9.c:624 USB_lock() –> asm() – more esoteric issues

    Also requires GenericTimeDate TmDr1.c – (eventhough got RTC_LDD) I guess it wants a tick – but this is now supplied to the FreeRTOS

    Anyway just checking before I dig deeper, I think I have your Components 2014-10-17 Beans installed. Thanks for any insights.

    Like

  6. Hi Erich,

    What about the Freescale Medical stack v5.0 beta? Is that the future for the KL25Z and KL46Z MCUs? It was released in May 2014. The Kinetis SDK doesn’t seem to support the KL25Z and KL46Z even though they belong to the Kinetis family. I’m basing my assumptions on the content provided by these two links:

    http://cache.freescale.com/files/microcontrollers/doc/user_guide/USBBMV50RN.pdf?fpsp=1
    http://www.freescale.com/webapp/sps/site/prod_summary.jsp?code=KINETIS_SDK

    Like

  7. Hi Erich,

    What about Freescale’s Medical USB stack v5.0 beta? Is that also discontinued? It just came out in May 2014. I looked at the Kinetis SDK and it doesn’t explicitly support for the KL25 and KL46 MCUs.

    Also, what is the purpose of the new “Use USB stack initialization” feature on the FSL_USB_CDC_Device component? Before this change, only the “Call Init Method” option was available. I see that you have both of these options set to “yes” on this post. I just updated to the most recent PEupd files and I’m confused by this change.

    Thanks,
    Carlos

    Like

  8. Hi Eric, I feel like I’m asking a lot of qu .. hope you don’t mind.:)
    To get a working toolchain I’ve switched to a FRDM-K64 brd, and upgrade to a fresh KDS1.1.1. Then I’ve imported your above project from my local updated copy of GitHub\mcuoneclipse\Examples\KDS\FRDM-K64F120M\FRDM-K64F_USB_CDC
    and it came in, I checked all the options you mention, and it built cleanly.
    I couldn’t find MPU_CESR in the init anywhere (I’m guess I’m working off your PE beans_17.10.2014.PEupd and not the newer downloaded
    GitHub\mcuoneclipse\Drivers\FSL_USB_Stack.drv which is updated)
    So I’ve added it my init before PE_low_level_init();
    I can download the built .elf over the configured debugger Segger ./USB SDA.
    However in the “Device Manager” I can’t find any PE CDC OSBD port as you describe in virtual-comusb-cdc-for-osbdmosjtag.
    I’ve downloaded http://www.pemicro.com/osbdm and installed it – I’m on Win8.1 so hope that isn’t causing an issue.
    I’ve rebooted my Win8.1 to ensure the drivers got in- but nothing showing inder Ports (COM & LPT) except for my segger JLINK CDC UART Port (I’m guessing from USB Controller J-Link OB CDC)
    Any suggestions gratefully accepted. 🙂
    Neil

    Like

    • Hi Neil,
      MPU_CESR change has been commited on GitHub, but not released as *.PEupd files on SourcForge yet. You did the right thing adding this as a workaround before PE_Low_Level_Init() (I did the same initially). You need to update your FRDM board to the latest firmware (but you need a non-win8.1 machine for this), see https://mcuoneclipse.com/2013/10/12/frdm-board-bootloader-fails-with-windows-8-1-preview/ and https://mcuoneclipse.com/2013/12/14/new-pe-opensda-firmware-v114/

      Like

      • Thanks for the quick answ. . seems like I’m getting into USB CDC hole with all the USB drivers- and Win8.1 .
        I’ve tried switching to a Linux Ubuntu 14.04 and installed the PE driver there – and then used lsusb to list connections, but no luck there.
        It doesn’t come up with USB SDA either I guess the K64F uUSB is OpenSDA Segger so also has to have matching drivers installed on Ubuntu . Bit of bummer.
        The other alternative – maybe an ignorant qu as I don’t get the USB architecture – I wonder are there other VID: PID combinations for another serial port on the segger J-Link OB CDC?

        Like

        • No issues to report on USB CDC on Win 8.1. On the K64F, it depends what USB CDC you are using (depends if you are using P&E, Segger or OpenOCD/CMSIS-DAP firmware). If you are using the OpenOCD/CMSIS-DAP, then it is the mbed serial driver. If you are using the P&E firmware, it is the P&E CDC driver, if it is the Segger firmware/application, then it is the Segger Driver. All use a different PID/VID.

          Like

  9. Well I finally got some communications -but not all good news.
    On my Win8.1 machine I installed VisualStudioExpress2013 and wdksetupe_driver.exe – to be able to use usbView.exe
    On plugging in the user uUSB connector cold into the FRDM-K64 board finally something happened on my Win8.1 Driver Manager and it showed “Other Devices” “FSL CDC Device” – which is of course the name it is given in
    FRDM-K64F120M\FRDM-K64F_USB_CDC\Documentation\cdc.inf
    I followed the rest of the install instructions – however the upgrade Win8.1 security jumped in stopped the installation with
    “The third-party INF does not contain digital signature information”
    The only way round it seems is to disable all signature checking for all drivers, not just USB drivers. I also found this
    http://www.davidegrayson.com/signing/ go to “Installing a driver package”
    However I switched the USB Host to Ubuntu 14.04. I had installed PEmicro for Ubuntu yesterday – but no effect.
    Then I installed Wireshark and a few other utilities – and suddenly I was seeing a usb show up with
    lsusb
    and “dmesg” confirmed it
    and further “ls /dev” showed a ttyACM0 appearing/dissappearing
    finally with “sudo minicom -s” setting the serial to ttyACM0 / 115Kbaurd- and then saving as ‘dfl’ (default I guess) – I had comms over CDC/USB to FRDM-K64 – and proving the basic software connection 🙂

    Like

  10. Pingback: USB with the Freescale FRDM-K22F Board | MCU on Eclipse

  11. Thank you for this much needed project, but I can’t build it.
    I have KDS 2.0.0 and KDSK 1.1.0.
    -I import the first of the identically called projects “FRDM-K64F_USB_CDC (FRDM-K64F_USB_CDC” into an empty workspace.
    – I clean project
    – I run the “Project/Generate Processor Expert Code” command
    – I build
    I get 4 errors:
    – fatal error: LED1.h: No such file or directory. (in fact ~17 .h files are missing if I look at events.h)
    – Make: *** [Static_Code/System/CPU_Init.o] Error 1
    – Make: *** [Static_Code/System/Vectors.o] Error 1
    – Make: *** Waiting for unfinished jobs….

    I’m new with KDS. Maybe something is wrong with my processor expert or what not…

    Can you please help?

    Thanks,
    Cat

    Like

      • Thank you Erich,
        Indeed, I think you’re right; I found this project searching for CDC on FRDM-K64F so I didn’t know there are pre-requisites; you might want to mention that 🙂
        Can you please tell me the origin of these files?
        Is there some blog entry that describes them, so I get what I’m doing when installing them?
        Also their license?
        I may want to use it at work as a starting point, if that’s OK with you.
        Thanks,
        Cat

        Like

        • Hi Cat,
          actually pretty much all of my projects have that pre-requisite, so I usually forget about it…
          The files have been developed as part of university research projects, student projects and many have been originated from my own work, some have been contributed by readers of this blog. The license of the files are in general LGPL, and it is mentioned in the header of the generated code. Some or from different LGPL licenses (FreeRTOS, FatFS) or from Freescale (e.g. the USB stack).
          The sources of the components are on GitHub here:
          https://github.com/ErichStyger/McuOnEclipse_PEx
          You will find on top of this repository as well the license information files.
          I hope this helps you, and is useful for you.
          Erich

          Like

        • I missed to answer the questions about blog entries about them: the answer is not an easy one, as this depends about the component. But if you google for ‘mcuoneclipse’ with the component name, you should get several hits. Otherwise there is a compendium which can help you to go through the growing number of articles: https://mcuoneclipse.com/compendium/

          Like

  12. Where specifically do I get the Windows driver for the PC side of this USB connection? I’m using Windows 7.
    I downloaded the Processor Expert components from sourceforge and the other project files from github, and built the project in KDS without a problem. When I run the code on the FRDM-K64F board my computer sees a new USB device named “FSL CDC DEVICE” but does not find a driver for it, so it does not install successfully.

    Like

    • Hi Doug,
      the driver files are already present on Windows. All what you need is to point to the right .inf file for it (text file). That .inf file is generated inside the project, in the Documentation folder. It has as well a readme in it, and you need to follow that instructions by the letter (do *not* let Windows pick the drivers for you!). See as well https://mcuoneclipse.com/2012/10/07/tutorial-usb-cdc-with-the-kl25z-freedom-board/

      I hope this helps!

      Like

      • Hi Erich
        Today I tried to install the CDC driver on Windows 10 (Brazilian Portuguese version). A generic “Serial USB device” was installed and worked well with Termite – I was able to send and receive data over USB. My board is based on MKL25Z128. However, when I tried to communicate using a software that uses the MSCOMM component, that COM port was not recognized. After that I have forced Windows to install the cdc.inf from KDS2.0. It was necessary disable driver signature verification, as related above. The COM string id on Windows Device Manager changed from “Serial USB Device” to “FSL CDC Device” as expected, but the enumerated COM didn’t work either through that MSCOMM software. Your thoughts about will be very welcome, thank you!
        Mauricio

        Like

        • Hi Erich. I was suspicious of the Freescale CDC driver on Windows 10 but I did some more tests and the problem is really in the MSCOMM. I’m studying an alternative. The generic Serial USB driver from Windows 10 is working great, as well as the Freescale driver. Thank you for your reply and keep doing this great job on your blog!

          Like

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

  14. Hi Erich,
    the FSL_USB component operates with a MK20DN512 mcu, in my case, only setting the CPU component properties “MPU settings Enabled and MPU module Disabled”. I read in this post about the K64 (neilh20) and I suppose that by chance the cpu component enforces the CESR register state.
    Is it possible to read USB keys with capacity over 4GB, regularly formatted with FAT32 and 4kB sectors?
    Thanks a lot, Michael

    Like

    • Hi Michael,
      the FSL_USB_Stack component has an option to select the K64F, and will configure the registers accordingly. As for >4 GB cards: I have used cards up to 16 GB, but I admit that I never wrote more than 2 GB Data on it. I have seen reports for older FatFS stack that there might be a problem if you write data beyond 4 GB or so, but I cannot confirm that.
      I hope this helps,
      Erich

      Like

      • Selecting the K64F option as you suggest is perfect.
        Reading 4GB USB flash keys is straightforward, however we are in no way able to read keys with greater capacity: the “opendir” FAT_filesystem component response is always “FR_NO_FILESYSTEM, /* (13) There is no valid FAT volume */”
        We’ll look for that in a second time when all the other pieces of the puzzle are in place.
        Thanks again for your help Erich

        Like

        • Hi Michael,
          what do you mean with “to read keys with greater capacity”? Do you mean to read you have a memory stick with more than 4 GB?

          Erich

          Like

  15. This program uses the components FSL_USB_Stack, FatFsmem_USB_MSD, FAT_FileSystem and FreeRTOS. The USB memory stick gives the user the possibility to update the application data (only read). The limit of 4GB sticks (sorry for “key” that comes from Italian) in this case is not very friendly, and it will be more and more difficult to find as time goes by. There is also a separate bootloader program residing in lower flash space used for user application update. The lower layers of the application are globally debugged and we are finalizing the user I/F (based on TSS and D4D).
    Thanks, Michael

    Like

    • Hi Michael,
      I had no issues to use FatFS with memory devices > 4 GB (the largest one I used was 32 GB). I have not written more than a few hundreds MByte of data, so I might be just below that 4 GB area. Or are you saying that you even cannot mount a device > 4 GB?

      Like

        • Hi Michael,
          sorry that it took so long to check this. But I’m able to work with say 8 GByte (FAT32) memory stick:
          CMD> FAT1 dir
          Directory of /
          D—- 2015-06-23 16:56 0 F1148
          0 File(s), 0 bytes total
          1 Dir(s), 7845128 KBytes free

          I have seen however sometimes some kind of problems (not reproducible): memory sticks with <= 2GB seemed to work somehow better.

          Like

        • Hello Erich, time of holidays for all 😉
          This question is not very important as our application operates without any problem with 4GB sticks… I take however due note to try again from the beginning some day with a FRDM board.
          Thanks again, Michael

          Like

  16. Hi, Erich,

    I try to use “FSL_USB_stack” for CDC in KDS 3.0 with KSDK1.3 (MK22FN512), but I got error
    “NO inherited component assigned”, it can’t find USB_Init,
    please help me, let me know, how can I solve this problem

    Thanks very much

    Like

  17. Hi Erich.

    I have a question concerning a hardware issue related to USB on Kinetis devices. I’m just wondering if the internal K64 USB module includes any buffer of voltage regulator to ensure 5V on trensfer lines DN and DP? I presume that USB standard requires 5V while the K64 operates on 3.3V. I read about USB Voltage Regulator in K64 datasheet but it’s only mentioned about the adjustment of 5V external supply voltage from USB cable to 3.3V operating voltage for the chip. Not the other way (anyway maybe it would even be a little bit stupid since we already have 5V from the cable…). So maybe the 5V for DN and DP is simply supplied directly without any regulator?

    Regards,
    Marcin

    Like

  18. Hi Erich,
    I am using K22FN120 MCU. I am confused right now. I have to optimize my RAM memory (decrease variables etc). I want to use either USBCDC or UART for debugging purposes so that I can connect to the computer and look at the logs. Which option do you suggest?

    I know that UART has problems with USB-Serial converter to be used to connect to today’s laprops etx, but I am worried if i will run out of RAM. I still have lot of code space on ROM. So code space should not be problem for me.

    Like

  19. Hi Eric,
    I am using the ksdk 1.2 for my application and prefer to use processor expert. Do you have any tutorial about usb cdc application using the sdk?
    thanks
    Hung

    Like

  20. Hi Erich,
    I am developing a project with the MK22FN1M0AVlQ12 using your FSL_USB_STACK with processor expert. I have realized that message greater than 16 bytes are splitted and i have data loss. Do you have any idea how to make grater the buffer of the fsl_usb_stack?.
    Thanks

    Like

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

  22. In usb_driver.c on linux I need to change this, case sensitivity really sucks

    #ifndef MULTIPLE_DEVICES
    //#include “USB_Config.h”
    #include “usb_config.h”
    #endif

    Like

  23. Pingback: Tutorial: Using Single Wire Output SWO with ARM Cortex-M and Eclipse | MCU on Eclipse

  24. Hello!
    Please, tell me where I can find an example as do the MSD device on FRDM-K64F that an onboard SD card it was visible in case of connection to the computer through USB as a Flash-disk.
    Thanks

    Like

  25. Hi, Erich, I tried to build this example, but I think that I forgot to disable memory protection, and now when I try to debug my K64F, it says that the gbd failed to reset/halt target mcu. Did you ever see this happen? Thanks for your attention!

    Like

    • My code/components automatically disable the memory protection. If you see the gdb failing to halt/reset the CPU, then:
      – CPU is in deep low power mode
      – FLASH is protected
      – You are using the wrong CPU in the launch configuration.
      Does it work for other applications?

      Like

      • I tried do debug this example last semester. I thought that the bootloader was bricked so I restored it using ULink2, but no success when trying to debug or even drag`n and drop`n a .bin pre-compiled application like `Hello World`. But last month I do use the .bin file again and suddenly it worked! So, I tried to debug the USB CDC example again in order to discover what is wrong, no success again! =/

        Like

        • I would check if the USB CDC device has really enumerated. Otherwise there are possible known problems with virtual COM ports on the host, so the problem could be your PC, not the board.

          Like

      • Anyway, I`m going to buy a J-Link or P&E Multilink, as you posted before, use only USB OpenSDA as debug interface can be painful!! haha

        Like

What do you think?

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

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