Иногда я думаю, что проблема должна быть решена в течение нескольких минут, а потом оказывается, что она затягивается на месяцы. Очень, очень расстраивает! Так работает стек USB 4.1.1 на плате FRDM-K64F. У меня эта плата с апреля 2014 года, и мне потребовалось 7 месяцев, чтобы запустить на ней USB-стек FSL :-(.
Я успешно использую стек Freescale USB V4.1.1 и компонент Processor Expert McuOnEclipse FSL_USB_Stack во многих проектах (ColdFire, S08 и Kinetis). Но, несмотря на все мои испытания и отладку, USB на K64F не смог перечислить на хосте.
: idea: Freescale прекратила использование стека USB V4.1.1, и новые устройства Kinetis поддерживаются только стеком USB в Kinetis SDK. Этот стек Kinetis SDK сильно отличается от стека V4.1.1 и поддерживает только новые устройства Kinetis. Поэтому использовать этот стек SDK было невозможно.
Конечно, я не работаю над этой проблемой полный рабочий день, но почти каждый уик-энд я думал, что эта проблема должна быть решаемой. Обычно портировать стек на другое устройство Kinetis очень просто: убедитесь, что периферийное устройство USB работает на частоте 48 МГц, проверьте расположение вектора прерывания USB и оно просто работает. Но не для K64F на плате FRDM-K64F :-(.
Я уже был близок к тому, чтобы отказаться от этой темы, пока я не прочитал «Оби» (спасибо, спасибо, спасибо!) В предыдущем посте в блоге : Проблема в том, что у K64F есть блок защиты памяти, и это необходимо отключить перед использованием USB!
Исправление для K64F было зафиксировано на GitHub и будет доступно в следующей версии компонентов на SourceForge .
Чтобы использовать USB с FRDM-K64F, создайте проект Processor Expert, затем добавьте компонент FSL_USB_Stack в проект:
Выберите Init_USB_OTG_VAR0 (для Kinetis) и класс устройства USB CDC :
In the Init_USB_OTG component, have the clock gate enabled and make sure that you have a 48 MHz USB module 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:
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 ?