Good news for everyone owning the FRDM-K20D50M board: I have extended the FSL_USB_Stack with USB CDC device class support for the K20D50M :-).
Demo Application
The demo projects is made with Processor Expert components so it can be easily copied or ported to another board:
I have created a demo application which echoes the entered text back on the console, with incrementing a counter:
FSL_USB_Stack with FSL_USB_CDC_Device
With just two additional Processor Expert components, it is possible to add USB CDC functionality to an existing projects in just a few minutes. See “USB Component Splitted and Updated” for architectural information. The component has now added a Kinetis K20D50 option:
💡 The FSL_USB_CDC_Device component features now an optional timeout feature. With this, it is easer to use the component in a bare-metal environment. It is using the extra ‘Timeout’ component which implements a timer based timeout to avoid stalling of the stack.
USB Clock Configuration
The most difficult part is the clock configuration. The USB block needs a 48 MHz clock to sample the 24 MHz USB signal. In the CPU component properties, I configured the System oscillator 0 to use the external 8 MHz crystal in Low power mode:
The MCG Is set to PEE and 48 MHz PLL output clock:
❗ It should be possible to use a 96 MHz PLL clock and then divide it down in the USB peripheral to a clock of 48 MHz. This is what I did first, and lost a lot of time, because this did not work :-(. I have not investigated it further, but this is either a bug in the silicon or in Processor Expert? 48 MHz without prescaler in the USB worked.
Derived from this, the system clocks are set up like this:
❗ IMPORTANT: Do not forget to set the PLL/FLL clock choice to ‘PLL clock’ as shown as last item in above screenshot.
In the Init_USB_OTG, the clock gate has to be enabled and the PLL/FLL clock to be used with 48 MHz:
❗ From the settings it would be possible to use a 96 MHz PLL clock and then to scale it down ot 48 MHz. However, with this my device did *not* enumerate 😦
That’s it! The rest is just writing a small test application.
Sources
The above project and sources are available on GitHub here. The same repository hosts the updated FSL_USB_Stack and FSL_USB_CDC_Device Processor Expert components.
Happy CDCing 🙂
Erich,
Thanks a lot or the nice USB CDC PEx component! I could easily port your K20 project to the Kwikstik K40 and it seems to work 🙂 BTW, I had no problems to set the CPU clock to 96 MHz on the Kwikstik. Just noticed that the USB clock must be set twice to 48 MHz – I set it once in the CPU and again in the Init_USB_OTG – there the 96 MHz have to be divided by two to get 48 MHz.
Best regards,
Anguel
LikeLike
Hi Anguel,
good to hear that things are useful for you. I have not tried it with my Kwikstik K40: I had issues with the USB to get up and running. It looks I had an early version of it with either a hardware or silicon bug.
LikeLike
BTW, it looks like advanced settings like packet sizes or self- vs bus-powered options cannot be set in properties. Are these hardcoded somewhere and is there an easy way to see them? Thanks a lot!
LikeLike
Some settings can be changed in the ‘Init’ subcomponent (like device vs host). Other things are hardcoded in the USB stack. You might have a look at USB1_Init() and the functions it calls.
LikeLike
Thanks a lot, I will have a look. Are there actually other special benefits of your stack besides ease of use (e.g. better speed or bug fixes) vs. the original Freescale USB stack? As far as I understand your stack is based on the Freescale stack.
LikeLike
The main difference is: it integrates support for an RTOS (it is using the RTOS malloc() and free() routines, and as it is using Processor Expert, it is easier to integrate into the rest of a system (if using Processor Expert). Additionally I have removed many warnings detected by gcc, and made sure it works with higher optimizations. I have passed my fixes and extensions to Freescale, so their next stack should incorporate those fixes too.
LikeLike
Thank you once again for the clarification, for the nice stack and all the invaluable tutorials! I hope that Freescale is aware of the fact that what you are doing is much better than any marketing work.
LikeLike
Hi Eric,
Have you run the FSL_USB_STACK with MQX Lite? I have a bare metal project that runs with the stack, and another project that uses MQX Lite. When I add the stack to the MQX Lite project, I get a lot of script errors when the PE components are compiled. All of the components are error free before the compile. Any ideas?
Best Regards,
George
LikeLike
Hi George,
no, I have not used it yet with MQX-Lite. What comes to my mind is for sure the memory interface (malloc() and heap()) which would need to be adopted. I would need to check this (and to try it out).
LikeLike
Hi George,
I have created a MQXLite project for the KL25Z (FRDM-KL25Z) and added the FSL USB stack (CDC). So far I’m running into the problem that both the USB Stack and MQXLite generate a file ‘user_config.h’ which gives a name conflict. I’m going to change the file name in the USB stack, and hopfully this is the only problem? Or what error message are you seeing?
LikeLike
Hi George,
I have fixed this user_config.h file conflict: the USB stack on GitHub is using usb_user_config.h instead. I have created an MQX-Lite project with the USB stack, and it compiles fine. I have published it on https://github.com/ErichStyger/mcuoneclipse/tree/master/Examples. But there is one problem: as soon as I plugin the USB cable, the MQX RTOS causes a hard_fault, because Processor Expert is adding the USB interrupt directly to the vector table, and this causes to overwrite the kernel data structure. I’m hitting right now a wall, because that USB_Init component is not something I can change. Looks like using MQX-Lite is a lot harder than I thought 😦 Or do you have any suggestion?
LikeLike
Hi Eric,
Thanks for getting the config.h conflict resolved. It looks like Freescale needs to make some adjustments in the USB_Init component.
LikeLike
Yes, I have created a ticket on this. the Init component directly installs the interrupt vector, and then it crashes on my machine. So this hopefully can be addressed sometimes in the future. But as of right now, it looks that MQX lite does not work with the init components if they install an interrupt.
LikeLike
Hi Eric,
did freescale provide any solution for this Hard fault for USB plugin
I am having same issue.
thanks
Niranjan
LikeLike
Hi Niranjan,
I don’t know if they have changed that for MQXLite. Soon after I have found that issue, I have decided to switch to FreeRTOS anyway. I’m not using MQX or MQXLite for a long time any more. I’m sorry, I won’t be able to help you much for anything around MQX or MQXlite as this is a world of the past for me.
LikeLike
ok, Thanks for the response Erich
LikeLike
Eric,
Could you give a quick tutorial on how to download the example projects and libraries that you put on your GIT site?
Thanks, Greg
LikeLike
Hi Greg,
it took me while to get to that, but here is a tutorial how to use MCUonEclipse GitHub site without git: https://mcuoneclipse.com/2013/05/20/how-to-use-mcuoneclipse-github-without-git/
LikeLike
Hi Erich ,
I’m using KL25Z and USB CDC , i’m sending data continuously to terminal , but if terminal isn’t connected to KL25Z USB , then the card stalls , after it stalls i open terminal , it exits from stall but Tera Term can’t read received data .
LikeLike
Hi Erdem,
you would need to handle this on the application side I believe. In my implementation I’m not covering such a case (yet?).
LikeLike
Hi Eric,
Is there a way to adapt the FSL_USB_Stack PE component such that two FSL_USB_Stacks (one configured for a MSD host , and the other configured for a CDC device) can coexist on the same USB port, and be compiled in the same PE project? A soft switch (i.e. nonvolatile memory location or GPIO bit hard wired to a switch) could be used to select one of the two stack configurations to run when the processor boots. Currently there are expected pin and timer conflicts.
Regards,
George
LikeLike
Hi Georg,
interesting idea, especially switching between host and device mode. For sure the current stack/component does not support this at run time. But you say that it would be ok to switch this at boot time? That sounds like a bootloader implementation: so the ‘bootloader’ runs in MSD host mode, and the application runs in CDC device mode. This would be supported today. Is this what you have in mind? Using the MSD host to bootload your application?
LikeLike
Hi Eric,
The application (not the boot loader) needs the capability to switch between the host and device modes. Since the reboot time on an embedded system is usually fast, selecting the mode at boot time eliminates a lot of issues associated with trying to dynamically switch modes. There are other applications where the board could run as a device or host based on a selector at boot time.
George
LikeLike
Hi George,
so then I think this should be very doable. It is some work, but technically possible.
Erich
LikeLike
Pingback: Tutorial: FreeMASTER Visualization and Run-Time Debugging | MCU on Eclipse
Pingback: USB for the Freescale ARM Kinetis KL46Z and K21D50M | MCU on Eclipse
I don’t see K20F120 on there… can I use the K40 or K60 setting?
LikeLike
Hard to say, as it is really hard to tell which silicon Freescale is using: inside the same family (e.g. K20) there can be different dies, with different behaviour :-(. The differences are in some settings for the clocks and the USB module. You might give it try. I assume you are saying that the K20D50 did not work for you?
LikeLike
The K20D72 setting seems to work with the K20F120 (K20D50 didn’t)… at least it’s recognized and shows up as a Com port… still trying to get characters through.
LikeLike
Hi Marc,
yes, I think the K20D50 is a different version/die of the ARM processor.
LikeLike
the K20D72 is working with a K20F120 processor, FYI. But I noticed when I run my program (which also has FreeRTOS, so the shell and command interpreter are hooked to USB_CDC), it seems it doesn’t fully start up (thread running the interpreter flashes an LED, lifted from one of your projects) until the USB port is plugged in and recognized by the computer. Problem is it’s a diagnostic port, it won’t be hooked up in the field, so is there a way to deal with that, or is it not a problem and just need to make sure threads blocking on USB_CDC don’t do anything unrelated that still needs to run regardless? (hope I’m making sense)
LikeLike
Thanks for the confirmation that it works on the K20D72.
Where is your application blocked? While checking CDC1_App_Task()? It does not have to be blocked there (if you are using my example code. You need to periodically call it to empty the buffers once the cable is connected, but you the call to CDC1_App_Task() is non blocking. Does this make sense?
LikeLike
it’s stuck trying to print the help stuff before the task starts it’s infinite parsing loop. the call stack looks like this:
9 CDC1_RunUsbEngine() CDC1.c:358 0x000163de
8 CDC1_App_Task() CDC1.c:423 0x0001648e
7 CDC1_SendChar() CDC1.c:196 0x00016248
6 CLS1_SendChar() CLS1.c:678 0x000160e0
5 CLS1_SendStr() CLS1.c:93 0x00015a36
4 CLS1_ParseCommand() CLS1.c:244 0x00015b1a
3 CLS1_IterateTable() CLS1.c:397 0x00015dfc
2 CLS1_ParseWithCommandTable() CLS1.c:437 0x00015e7c
1 ShellTask() Shell.c:60 0x00018682
Stack levels 7, 8 & 9 var but it’s always in CLS1_SendChar() when I stop it…
I guess that’s no big deal I just have to make sure the threads with this comm stuff don’t need to do anything else important (like, in this case, blinking an LED every second).
LikeLike
Hi Marc,
have a look at the Shell (CLS1) properties: there is a property ‘Blocking Send’. I asssume it is set to ‘yes’ for you. This means it tries to send the string until it succeeds. Change that to ‘no’. Then it will try to send it, but if the buffer is blocked/full, it will return and not wait. This should solve your problem. Let me know if this works (or not).
LikeLike
yes I did have block on send set, and clearing that solved the problem, thanks. Still, when I re-run the program, I find I have to close the terminal connection (I’m using the terminal inside eclipse), and physically unplug the usb, then plug it back in, to get a good connection to the terminal. I suspect it’s the OS holding the device descriptor open. windows. gotta love it.
LikeLike
Yes, the OS keeps the device descriptors open which is a pain. Additionally, if you plug in the OpenSDA, then the USB bus gets reset. So this is the usual sequence I have to do:
– I have COM port open, and then power-up or disconnec the cable.
– I need first to close the COM port in the terminal program, then plugin the board
– After that, I can open the COM port again.
Failing that sequence means that the COM port will not work.
LikeLike
I have difficulty to develop a MSC device bootloader on FRDM-K20D50M. There are many random errors there. Do you think it is possible related to the PLL/FLL to 50MHz, instead of 48MHz? The situation is the MSC bootloader can be enumerated on Windows XP, but reprots I/O error during copying file and programming.
I can share my source if necessary.
LikeLike
I don’t think it is because of the clock. If the clock is wrong, then your USB device will not enumerate.
LikeLike
Hi, Erich
I’m trying to follow you to add a USB CDC function to my FRDM-K20D50M board. But I have some problems with the Freescale CDC Device driver now. Please help me.
I did like this,
I connected the USB cable, then after a short while, the board showed up as “Unknown Device” in the “USB controller” section of the Device Manager. I tried to update its driver, by doing “Browse my computer…” -> “let me pick from a list…” -> “have disk”, and finally I pointed to the “cdc.inf” file in Documents folder. But when I clicked OK, it popped up a window saying that there’s no driver for the device in this folder.
So I changed another way to install it. What I did is,
I chose “Add legacy hardware” in Device Manager. Then, “pick up from a list” -> “show all device” -> “have disk”. Finally I browsed the same driver file “cdc.inf”. This time, the installation started, and in the COM section, the device shows up as a serial port device named “Freescale CDC Device”, but with a yellow exclamation point. I connect the USB cable again, then for this “Freescale CDC Device”, nothing changes. And the board still shows up as “Unknown device”.
I tried to disconnect, connect the board, uninstall, reinstall many times. But it always doesn’t work. Note that on another PC, with the same board, there’s no problem. Do you know how to fix this problem?
Please help me! Many thanks!
LikeLike
I just can think about that the problem must be your PC (if the board is fine otherwise). Are you using USB3 ports maybe? That could cause problems. Have you tried different USB cables and different USB ports on your PC?
LikeLike
Hi,
I solved this problem yesterday. I just copy the generated .inf file from another PC on which the K20D50M works well to my own laptop. This time the driver installation is successful, so USB CDC is OK now:)
My laptop is a mac with win7 installed using bootcamp. There is no USB3 port and I’m using CW10.6.
LikeLike
Hi Eric,
I have been using the FSL_USB_Stack with the CDC Device property without any problems (K20). I just updated the components for an existing project, and I am getting a number of compile errors associated with %substring out of string {“FREESCALE INC.”,15,1} (file: Drivers\FSL_USB_Stack\Device\app\cdc\usb_descriptor.c). The component inspector indicates there is an error on the FSL_USB_CDC_Device, but does not show anything in the properties or methods.This happens on CW10.5 and 10.6. Is this a known issue?
Regards,
George
LikeLike
Hi George,
I have updated/changed that area recently to overcome a bug in Processor Expert. Are you using the latest components from GitHub? I just commit my latest version to be sure we have the same.
LikeLike
Hi Eric,
I have the latest components from GitHub (used the beans & drivers). This is when the problem started.
George
LikeLike
Strange. Can you share your project? See my email address on the About page of this blog.
LikeLike
I E-Mailed a project on your address.
Thanks
LikeLike
got it! I have made some modificiations and emailed it back to you. Hopefully this will make it work for you.
LikeLike
This bean is compatible with 9s08jm16 ?
LikeLike
Yes. I had it working on a FLEXIS (DEMOJM) board.
LikeLike
see https://github.com/ErichStyger/mcuoneclipse/tree/master/Examples
LikeLike
Hi Eric, I’m trying to make a USB CDC HOST application, using Processor Expert , CW10 and FRDM-k20DM board. Is it possible, because I’m stuck with device enumeration . I want to connect ACM USB device, but it is detected as DATA device.
LikeLike
Hi George, I only have used it as CDC device (not host), but CDC host should be possible.
LikeLike
Can I send you the code , to try give me some hint about it?
LikeLike
Got it. I see that you are using the Freescale provided components for USB CDC host. I was never able to get them working, so I decided to create my own components. They do not support USB CDC host, but now it looks I should have a look at it if time permits.
LikeLike
As an upate, I worked on the last couple of week-ends on the USB CDC Host stack. I have it compile and running on the target.
It is just that it does not enumerate (yet) properly. So I guess I still need to do some debugging….
LikeLike
Hi Erich, I have also worked on this and now my device enumerates properly. Later I will send you my code.
LikeLike
Here is my latest project. Device enumerate as ACM device and I think it works fine. The problem still left is in reading bytes from device. Sometimes I get 1 byte, sometimes 49. Just in few words my device is crypto module. After initialization I must send ping command and read the response. Initialization is done outside this project – its a Arch Linux custom Board , running my other firmware. After power down on my main CPU and board, K20 detects it and sends to main CPU command to shut down( I have battery pack and I need to save power) . Here is the challenge. Now instead of just being a pipe from main CPU to Crypto Module, K20 should simulate continuous work – in simple words just pinging the device and receive its answer( void CDC_Battery_Task()) . The answer is important for me, because device may initiate other command ( not just ping pong ). In this case I need to wake up my main CPU and do some other work. So I’m in state that my simple PING PONG won’t work because of not receiving proper count of bytes. 10x a lot again.
P.S. I’m sorry to waste your time, but this is area that I feel so “not in my place”. I’m working mostly on Linux environment – U-boot, kernel and writing on custom boards.
2014-08-10 7:44 GMT+03:00 MCU on Eclipse :
> Erich Styger commented: “As an upate, I worked on the last couple of > week-ends on the USB CDC Host stack. I have it compile and running on the > target. It is just that it does not enumerate (yet) properly. So I guess I > still need to do some debugging….” >
LikeLike
Hi George,
where have you posted your latest project? I cannot see a link in your comment, or did I miss it?
Erich
LikeLike
I am looking to do this as well with a Teensy 3.1 board (Kinetis MX20DX256) that’s in the mail.
Can you share your in-progress ACM startup code?
I am hoping to make the Teensy host an e-ink tablet for use as a ultra-low-power GPS map. Reversing the host/device roles would be easier, but most tablets’ USB-OTG-Host IC’s and kernel drivers are simply not well implemented and leak excessive power.
LikeLike
Hello,
what ACM startup code do you mean? As a reference, the project sources and files are on GitHub (see the link at the end of the article).
I hope this helps?
LikeLike
Pingback: USB with the Freescale FRDM-K22F Board | MCU on Eclipse
Hello Erick,
I want to add USB CDC to my custom board with MK60DX256.
I follow your guide but I have a trouble in USB0:Init_USB_OTG.
The problem is into USB_Init in the Module Clock Frequency that remains STOPPED (not 48 MHz).
Could you help me?
Thanks
LikeLike
Hi Frederico,
this means that probably a clock setting in the CPU component is wrong. Usually on the bottom of the properties in the CPU component there is a setting for the USB clock. Is it configured properly?
Erich
LikeLike
Hi Erick,
thanks for your reply.
In my project, if I open Component Inspector – Cpu, at the bottom I can’t find USB CLOCK SECTION (into PLL/FLL CLOCK SECTION). But if I open your CDC_TWR-K60N512, that settings appears.
What was wrong?
Thanks Federico
P.S.: Before open this thred I posted the same question on Freescale Community: freescale community thread/341639
LikeLike
Hi Frederico,
I posted an answer in that thread. It looks you have an older CodeWarrior (not 10.6 with Update 4) from your screenshots. And you are in Basic, not in Advanced mode, then some settings are hidden.
Erich
LikeLike
Hi Erick,
I reply on the thread.
Thanks
LikeLike
Hello, Erich
Do you have any example of USB-CDC on Kinetis using your Processor Expert beans like this, but for KDS 3.0.0?
Thanks!
LikeLike
Hi Marco,
yes, I have KDS projects here:
https://github.com/ErichStyger/mcuoneclipse/tree/master/Examples/KDS
but not a CDC one for the FRDM-K20, but for other boards. Some of the projects have not been moved to KDS v3.0.0 yet (you have to replace the linker options from “-nanolibc” to “–specs=nano.specs –specs=nosys.specs” for KDS v3.0.0.
But the setup in KDS is really the same as for CodeWarrior.
I hope this helps?
LikeLike
Hi Eric,
I have been working from your example code and components from SourceForge (Components 2016-06-25.zip). Thank you for providing the example and components. I’m new to the Freescale/NXP devices and this is all helpful. I can get the example working to the point of the USB device being recognized and enumerated. I’m using PuTTY for the terminal and I get no response when sending to the Freedom board. I added a CDC1_SendString operation after WAIT1_Waitms(10) to see if transmitting would works and it does send a character with every cycle. By doing this I found that if I send a string amidst the incoming characters, I would get the correct response from the device – the echo with the variable value. I can’t find out why the CDC1 Rx buffer won’t receive without having preceding transmission. Any ideas?
Thanks!
LikeLike
Hi John,
are you using one of my examples or did you build your own? One common pitfall is the size of the Rx and Tx buffers (subcomponent of the CDC component): make sure that it is at least 32 bytes or more. I have made a change in the most recent components that it allocates a default buffer of 32bytes or more, but can you check this (search for ‘ring buffer’ in https://mcuoneclipse.com/2014/10/25/usb-cdc-with-the-frdm-k64f-finally/).
The CDC1 Rx buffer can receive without the need to first send something. The Rx part works through interrupts: when the interrupt hapens for the incoming packet, the bytes get stored in to the Rx ringbuffer. But you still have to call CDC1_App_Task() frequently to keep the USB engine going on.
I hope this helps,
Erich
LikeLike
Thanks for the prompt reply Erich,
I am using the example code from https://www.element14.com/community/docs/DOC-54694/l/codewarrior-tutorial-for-frdm-k20d50m-usb-cdc-driver. The Freescale USB stack is v4.1.1 (from NXP site). I did have to fill the SDK property for a number of the beans (LEDs, Wait, USB1..) Other than that everything matches the properties outlined in your tutorial. Tx and Tx RingBuffers are 64. I added updated code code to match the example on https://mcuoneclipse.com/2014/10/25/usb-cdc-with-the-frdm-k64f-finally, which was the addition of the cnt statements on lines 5, 34-38. Interestingly, if I type nothing every ~10s “Type some text…& hello?” comes up in the terminal. If I type and send in the terminal nothing happens until the next “Type some text..& hello?” comes up and whay I entered will echo. I need to debug this thoug; if I send “XYZ”, the next “Type some text..& hello?” should be followed by “echo: XYZ” (LF) “val: 1”, but it is coming out “echo: XYZval: 1” (LF) “val: 2”.
Regards,
LikeLike
Hi John,
oh, that tutorial was some time back, and yes, there has been several improvements and changes after that. The original NXP/Freescale USB Stack v4.1.1 has a few bugs and issues which I have corrected in the Processor Expert component version, so maybe this is one of them, not sure. Are you using the FRDM-K20D50M with KDS V3.2.0? If so, I could recheck that example on GitHub.
The other advice is that you could try with another terminal program than putty (putty has a lot of settings, and can lead to strange things). I recommend Termite (http://www.compuphase.com/software_termite.htm).
LikeLike
Hi John,
so we are on the same page: I have updated and tested the CodeWarrior project on GitHub (https://github.com/ErichStyger/mcuoneclipse/tree/master/Examples/CodeWarrior/FRDM-K20D50M/FRDM-K20_CDC), because it did not use the latest components, and it works fine for me.
Additionally I have pushed on GitHub (https://github.com/ErichStyger/mcuoneclipse/tree/master/Examples/KDS/FRDM-K20D50M/FRDM-K20_USB_CDC) the same project for Kinetis Design Studio V3.2.0, as well using the latest components. Again works fine.
I hope this helps,
Erich
LikeLike