USB CDC with the FRDM-K64F, finally!
Join the DZone community and get the full member experience.
Join For FreeSometimes 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 :-(.
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.
:idea: 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!
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:
Select the Init_USB_OTG_VAR0 (for Kinetis) and the USB CDC Device Class:
In the Init_USB_OTG component, have the clock gate enabled and make sure that you have a 48 MHz USB module clock:
:idea: 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:
In the USB CDC component, I need to select my device:
The USB CDC device uses two ring buffers for the data:
Set both the Rx and Tx buffers to a reasonable size (I use 64 bytes):
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 :-).
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 :-)
Published at DZone with permission of Erich Styger, DZone MVB. See the original article here.
Opinions expressed by DZone contributors are their own.
Trending
-
10 Traits That Separate the Best Devs From the Crowd
-
Strategies for Reducing Total Cost of Ownership (TCO) For Integration Solutions
-
Manifold vs. Lombok: Enhancing Java With Property Support
-
Front-End: Cache Strategies You Should Know
Comments