USB CDC - Force device mode

ChibiOS public support forum for topics related to the STMicroelectronics STM32 family of micro-controllers.

Moderator: RoccoMarco

Post Reply
User avatar
Tectu
Posts: 1225
Joined: Thu May 10, 2012 9:50 am

USB CDC - Force device mode

Post by Tectu »

Hello folks,

I've once extracted the USB part into a separate file so I'm able to simply include it and get a shell working over USB CDC quickly. I'd now need to force my STM32F407 to be in device mode. There's the FDMOD bit in the OTG_FS_GUSBCFG register. I'm hard finding out how I can force the MCU to be in device mode using ChibiOS/RT. Can anyone give me a pointer? This is the actual code I took from the testhal:

Code: Select all

#include "ch.h"
#include "hal.h"
#include "shell.h"
#include "usb_cdc.h"
#include "usb_shell.h"
#include "chprintf.h"

SerialUSBDriver SDU1;

static const uint8_t vcom_device_descriptor_data[18] = {
  USB_DESC_DEVICE       (0x0110,        /* bcdUSB (1.1).                    */
                         0x02,          /* bDeviceClass (CDC).              */
                         0x00,          /* bDeviceSubClass.                 */
                         0x00,          /* bDeviceProtocol.                 */
                         0x40,          /* bMaxPacketSize.                  */
                         0x0483,        /* idVendor (ST).                   */
                         0x5740,        /* idProduct.                       */
                         0x0200,        /* bcdDevice.                       */
                         1,             /* iManufacturer.                   */
                         2,             /* iProduct.                        */
                         3,             /* iSerialNumber.                   */
                         1)             /* bNumConfigurations.              */
};

/* Device Descriptor wrapper */
static const USBDescriptor vcom_device_descriptor = {
   sizeof vcom_device_descriptor_data,
   vcom_device_descriptor_data
};

/* Configuration Descriptor tree for a CDC */
static const uint8_t vcom_configuration_descriptor_data[67] = {
  /* Configuration Descriptor.*/
  USB_DESC_CONFIGURATION(67,            /* wTotalLength.                    */
                         0x02,          /* bNumInterfaces.                  */
                         0x01,          /* bConfigurationValue.             */
                         0,             /* iConfiguration.                  */
                         0xC0,          /* bmAttributes (self powered).     */
                         50),           /* bMaxPower (100mA).               */
  /* Interface Descriptor.*/
  USB_DESC_INTERFACE    (0x00,          /* bInterfaceNumber.                */
                         0x00,          /* bAlternateSetting.               */
                         0x01,          /* bNumEndpoints.                   */
                         0x02,          /* bInterfaceClass (Communications
                                           Interface Class, CDC section
                                           4.2).                            */
                         0x02,          /* bInterfaceSubClass (Abstract
                                         Control Model, CDC section 4.3).   */
                         0x01,          /* bInterfaceProtocol (AT commands,
                                           CDC section 4.4).                */
                         0),            /* iInterface.                      */
  /* Header Functional Descriptor (CDC section 5.2.3).*/
  USB_DESC_BYTE         (5),            /* bLength.                         */
  USB_DESC_BYTE         (0x24),         /* bDescriptorType (CS_INTERFACE).  */
  USB_DESC_BYTE         (0x00),         /* bDescriptorSubtype (Header
                                           Functional Descriptor.           */
  USB_DESC_BCD          (0x0110),       /* bcdCDC.                          */
  /* Call Management Functional Descriptor. */
  USB_DESC_BYTE         (5),            /* bFunctionLength.                 */
  USB_DESC_BYTE         (0x24),         /* bDescriptorType (CS_INTERFACE).  */
  USB_DESC_BYTE         (0x01),         /* bDescriptorSubtype (Call Management
                                           Functional Descriptor).          */
  USB_DESC_BYTE         (0x00),         /* bmCapabilities (D0+D1).          */
  USB_DESC_BYTE         (0x01),         /* bDataInterface.                  */
  /* ACM Functional Descriptor.*/
  USB_DESC_BYTE         (4),            /* bFunctionLength.                 */
  USB_DESC_BYTE         (0x24),         /* bDescriptorType (CS_INTERFACE).  */
  USB_DESC_BYTE         (0x02),         /* bDescriptorSubtype (Abstract
                                           Control Management Descriptor).  */
  USB_DESC_BYTE         (0x02),         /* bmCapabilities.                  */
  /* Union Functional Descriptor.*/
  USB_DESC_BYTE         (5),            /* bFunctionLength.                 */
  USB_DESC_BYTE         (0x24),         /* bDescriptorType (CS_INTERFACE).  */
  USB_DESC_BYTE         (0x06),         /* bDescriptorSubtype (Union
                                           Functional Descriptor).          */
  USB_DESC_BYTE         (0x00),         /* bMasterInterface (Communication
                                           Class Interface).                */
  USB_DESC_BYTE         (0x01),         /* bSlaveInterface0 (Data Class
                                           Interface).                      */
  /* Endpoint 2 Descriptor.*/
  USB_DESC_ENDPOINT     (USB_CDC_INTERRUPT_REQUEST_EP|0x80,
                         0x03,          /* bmAttributes (Interrupt).        */
                         0x0008,        /* wMaxPacketSize.                  */
                         0xFF),         /* bInterval.                       */
  /* Interface Descriptor.*/
  USB_DESC_INTERFACE    (0x01,          /* bInterfaceNumber.                */
                         0x00,          /* bAlternateSetting.               */
                         0x02,          /* bNumEndpoints.                   */
                         0x0A,          /* bInterfaceClass (Data Class
                                           Interface, CDC section 4.5).     */
                         0x00,          /* bInterfaceSubClass (CDC section
                                           4.6).                            */
                         0x00,          /* bInterfaceProtocol (CDC section
                                           4.7).                            */
                         0x00),         /* iInterface.                      */
  /* Endpoint 3 Descriptor.*/
  USB_DESC_ENDPOINT     (USB_CDC_DATA_AVAILABLE_EP,     /* bEndpointAddress.*/
                         0x02,          /* bmAttributes (Bulk).             */
                         0x0040,        /* wMaxPacketSize.                  */
                         0x00),         /* bInterval.                       */
  /* Endpoint 1 Descriptor.*/
  USB_DESC_ENDPOINT     (USB_CDC_DATA_REQUEST_EP|0x80,  /* bEndpointAddress.*/
                         0x02,          /* bmAttributes (Bulk).             */
                         0x0040,        /* wMaxPacketSize.                  */
                         0x00)          /* bInterval.                       */
};

/* Configuration Descriptor wrapper */
static const USBDescriptor vcom_configuration_descriptor = {
   sizeof vcom_configuration_descriptor_data,
   vcom_configuration_descriptor_data
};

/* U.S. English language identifier */
static const uint8_t vcom_string0[] = {
   USB_DESC_BYTE(4),                     /* bLength.                         */
   USB_DESC_BYTE(USB_DESCRIPTOR_STRING), /* bDescriptorType.                 */
   USB_DESC_WORD(0x0409)                 /* wLANGID (U.S. English).          */
};

/* Vendor string */
static const uint8_t vcom_string1[] = {
   USB_DESC_BYTE(38),                    /* bLength.                         */
   USB_DESC_BYTE(USB_DESCRIPTOR_STRING), /* bDescriptorType.                 */
   'S', 0, 'T', 0, 'M', 0, 'i', 0, 'c', 0, 'r', 0, 'o', 0, 'e', 0,
   'l', 0, 'e', 0, 'c', 0, 't', 0, 'r', 0, 'o', 0, 'n', 0, 'i', 0,
   'c', 0, 's', 0
};

/* Device Description string */
static const uint8_t vcom_string2[] = {
   USB_DESC_BYTE(56),                    /* bLength.                         */
   USB_DESC_BYTE(USB_DESCRIPTOR_STRING), /* bDescriptorType.                 */
   'C', 0, 'h', 0, 'i', 0, 'b', 0, 'i', 0, 'O', 0, 'S', 0, '/', 0,
   'R', 0, 'T', 0, ' ', 0, 'V', 0, 'i', 0, 'r', 0, 't', 0, 'u', 0,
   'a', 0, 'l', 0, ' ', 0, 'C', 0, 'O', 0, 'M', 0, ' ', 0, 'P', 0,
   'o', 0, 'r', 0, 't', 0
};

/* Serial Number string */
static const uint8_t vcom_string3[] = {
   USB_DESC_BYTE(8),                     /* bLength.                         */
   USB_DESC_BYTE(USB_DESCRIPTOR_STRING), /* bDescriptorType.                 */
   '0' + CH_KERNEL_MAJOR, 0,
   '0' + CH_KERNEL_MINOR, 0,
   '0' + CH_KERNEL_PATCH, 0
};

/* Strings wrappers array */
static const USBDescriptor vcom_strings[] = {
   {sizeof vcom_string0, vcom_string0},
   {sizeof vcom_string1, vcom_string1},
   {sizeof vcom_string2, vcom_string2},
   {sizeof vcom_string3, vcom_string3}
};

static const USBDescriptor *get_descriptor(USBDriver *usbp, uint8_t dtype, uint8_t dindex, uint16_t lang) {
   (void)usbp;
   (void)lang;

   switch (dtype) {
      case USB_DESCRIPTOR_DEVICE:
         return &vcom_device_descriptor;

      case USB_DESCRIPTOR_CONFIGURATION:
         return &vcom_configuration_descriptor;

      case USB_DESCRIPTOR_STRING:
         if(dindex < 4)
         return &vcom_strings[dindex];
   }

   return NULL;
}

static USBInEndpointState ep1instate;
static USBOutEndpointState ep1outstate;
static const USBEndpointConfig ep1config = {
   USB_EP_MODE_TYPE_BULK,
   NULL,
   sduDataTransmitted,
   sduDataReceived,
   0x0040,
   0x0040,
   &ep1instate,
   &ep1outstate,
   2,
   NULL
};

static USBInEndpointState ep2instate;
static const USBEndpointConfig ep2config = {
   USB_EP_MODE_TYPE_INTR,
   NULL,
   sduInterruptTransmitted,
   NULL,
   0x0010,
   0x0000,
   &ep2instate,
   NULL,
   1,
   NULL
};

static void usb_event(USBDriver *usbp, usbevent_t event) {
   switch (event) {
      case USB_EVENT_RESET:
         return;

      case USB_EVENT_ADDRESS:
         return;

      case USB_EVENT_CONFIGURED:
         chSysLockFromIsr();

         /* Enables the endpoints specified into the configuration.
          * Note, this callback is invoked from an ISR so I-Class functions
          * must be used.
          */
         usbInitEndpointI(usbp, USB_CDC_DATA_REQUEST_EP, &ep1config);
         usbInitEndpointI(usbp, USB_CDC_INTERRUPT_REQUEST_EP, &ep2config);

         /* Resetting the state of the CDC subsystem.*/
         sduConfigureHookI(usbp);

         chSysUnlockFromIsr();
         return;

      case USB_EVENT_SUSPEND:
         return;

      case USB_EVENT_WAKEUP:
         return;

      case USB_EVENT_STALLED:
         return;
   }

   return;
}

const USBConfig usbcfg = {
   usb_event,
   get_descriptor,
   sduRequestsHook,
   NULL
};

const SerialUSBConfig serusbcfg = {
   &USBD1
};

BaseSequentialStream* usbShellInit(void) {
   sduObjectInit(&SDU1);
   sduStart(&SDU1, &serusbcfg);
   usbDisconnectBus(serusbcfg.usbp);

   chThdSleepMilliseconds(1000);

   usbStart(serusbcfg.usbp, &usbcfg);
   usbConnectBus(serusbcfg.usbp);
   
   return (BaseSequentialStream*)&SDU1;
}



Thanks in advance,

~ Tectu
User avatar
Giovanni
Site Admin
Posts: 14891
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: USB CDC - Force device mode

Post by Giovanni »

You don't need to force anything, it is done inside the driver.

Giovanni
User avatar
Tectu
Posts: 1225
Joined: Thu May 10, 2012 9:50 am

Re: USB CDC - Force device mode

Post by Tectu »

The reason I need to force it is because I don't have any ID line connected.
By "it's done inside the driver" you don't mean the code I showed, or do you try to tell me that I'm already forcing it into device mode?


~ Tectu
User avatar
Giovanni
Site Admin
Posts: 14891
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: USB CDC - Force device mode

Post by Giovanni »

It is already forced in device mode.

Giovanni
User avatar
Tectu
Posts: 1225
Joined: Thu May 10, 2012 9:50 am

Re: USB CDC - Force device mode

Post by Tectu »

Jep, it's definitely working. Thank you very much for your help!


~ Tectu
Post Reply