Статьи

USB CDC с FRDM-K64F, наконец-то!

Иногда я думаю, что проблема должна быть решена в течение нескольких минут, а потом оказывается, что она затягивается на месяцы. Очень, очень расстраивает! Так работает стек USB 4.1.1 на плате FRDM-K64F. У меня эта плата с апреля 2014 года, и мне потребовалось 7 месяцев, чтобы запустить на ней USB-стек FSL :-(.

FRDM-K64F Доска

FRDM-K64F Доска

Я успешно использую стек 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!

disablingMemoryProtectionUnitForK64F

disablingMemoryProtectionUnitForK64F

Исправление для K64F было зафиксировано на GitHub и будет доступно в следующей версии компонентов на SourceForge .

Чтобы использовать USB с FRDM-K64F, создайте проект Processor Expert, затем добавьте компонент FSL_USB_Stack в проект:

FSL_USB_CDC Компонент

FSL_USB_CDC Компонент

Выберите Init_USB_OTG_VAR0 (для Kinetis) и класс устройства USB CDC :

USB CDC устройство

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:

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 прерывает

USB Init Interrupts

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

Выбор устройства USB CDC

USB CDC Device Selection

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

USB CDC с кольцевыми буферами

USB CDC with RingBuffers

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

Размер кольцевого буфера USB CDC

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 :-).

Тестовая программа для USB CDC на 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 🙂