This tutorial was extracted from Erich Styger blog http://mcuoneclipse.wordpress.com with his agreement.
The Freedom boards FRDM-KL25Z RevE and FRDM-K20D50M make it easier to use it as USB Host device, as they come with a special jumper to provide 5V to the USB device, so my earlier ‘hack’ is not needed any more . After I had USB MSD Host working for the FRDM-KL25Z, it was much harder to get the USB stack working for the FRDM-K20D50MFRDM-K20D50M board, because somehow the example Freescale provided with their USB stack refused to work properly on my board. After debugging it for several nightly hours, I decided to take my working Processor Expert project for KL25Z and added support for the K20. And the good news is: since tonight this is working .
USB Host Jumper
By default, the FRDM boards do not supply 5V to the USB connector. But that 5V is required to attach a device like memory stick to power the MSD device from the host (the FRDM board). On the FRDM-KL25Z RevE I can set a jumper to provide the 5V to the bus:
A similar jumper is present on the FRDM-K20D50M board:
Example Application
The example application runs a command line shell over OpenSDA virtual COM (USB CDC):
USB enumeration is shown with a RGB LED which blinks either green or red. As file system the application runs FatFs. Below are some points to consider if you want to build your own application from scratch:
Clock Settings
The clock needs to provide 48 MHz to the USB peripheral. As the FRDM-K20D50M has an external 8 MHz crystal, I configure this in the CPU settings:
The clock is configured for PEE mode to produce an 48 MHz PLL output:
The System Clocks are configured as below:
Do not forget to set the PLL/FLL clock choice to ‘PLL clock’ with 48 MHz, otherwise USB will *not* work. I missed that myself, and have lost many hours of debugging .
Processor Expert USB Component
The FSL_USB_Stack Processor Expert component is configured as below:
The FSL_USB_MSD_Host component settings only needs to know for which CPU it is:
MSD Host Application
I’m using a FreeRTOS task to perform the USB processing with interrupts:
/*
* host.c
* Author: Erich Styger
*/
#include "host.h"
#include "msd_commands.h"
#include "CLS1.h"
#include "FRTOS1.h"
#include "FsMSD1.h"
static
void
print(unsigned
char
*str) {
CLS1_SendStr(str, CLS1_GetStdio()->stdOut);
}
static
void
CheckStatus(
void
) {
switch
(FsMSD1_GetDeviceStatus()) {
case
USB_DEVICE_IDLE:
break
;
case
USB_DEVICE_ATTACHED:
LEDR_Off();
LEDG_On();
print((unsigned
char
*)
"Mass Storage Device Attached\n"
);
break
;
case
USB_DEVICE_SET_INTERFACE_STARTED:
break
;
case
USB_DEVICE_INTERFACED:
break
;
case
USB_DEVICE_DETACHED:
LEDR_On();
LEDG_Off();
print((unsigned
char
*)
"\nMass Storage Device Detached\n"
);
break
;
case
USB_DEVICE_OTHER:
break
;
default
:
print((unsigned
char
*)
"Unknown Mass Storage Device State\n"
);
break
;
}
/* switch */
}
static
portTASK_FUNCTION(HostTask, pvParameters) {
(
void
)pvParameters;
/* not used */
for
(;;) {
FsMSD1_AppTask();
CheckStatus();
FRTOS1_taskYIELD();
}
}
void
HOST_Init(
void
) {
FsMSD1_HostInit();
if
(FRTOS1_xTaskCreate(HostTask, (
signed
portCHAR *)
"Host"
, configMINIMAL_STACK_SIZE+100, NULL, tskIDLE_PRIORITY+1, NULL) != pdPASS) {
for
(;;){}
/* error */
}
}
Summary
With this I have now USB MSD host working for the FRDM-K20D50M. The most complicated part is to set up the clock settings which are not that simple. But after knowing what needs to be done, this is pretty easy, especially with the help of Processor Expert. The example project is attached to this message.