From 2eb9d1cb124a33c6e48b4bc8c572d1beb9c42ca4 Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Wed, 4 Feb 2015 14:13:52 +0000 Subject: Dual CDC demo for the STM32F4, to be tested. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@7653 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- testhal/STM32/STM32F4xx/USB_CDC_DUAL/main.c | 56 +++--- testhal/STM32/STM32F4xx/USB_CDC_DUAL/usbcfg.c | 269 ++++++++++++++------------ testhal/STM32/STM32F4xx/USB_CDC_DUAL/usbcfg.h | 3 +- 3 files changed, 181 insertions(+), 147 deletions(-) (limited to 'testhal') diff --git a/testhal/STM32/STM32F4xx/USB_CDC_DUAL/main.c b/testhal/STM32/STM32F4xx/USB_CDC_DUAL/main.c index 00490f436..04d5148bc 100644 --- a/testhal/STM32/STM32F4xx/USB_CDC_DUAL/main.c +++ b/testhal/STM32/STM32F4xx/USB_CDC_DUAL/main.c @@ -26,8 +26,11 @@ #include "usbcfg.h" -/* Virtual serial port over USB.*/ +/* + * Virtual serial ports over USB. + */ SerialUSBDriver SDU1; +SerialUSBDriver SDU2; /*===========================================================================*/ /* Command line related. */ @@ -131,6 +134,11 @@ static const ShellConfig shell_cfg1 = { commands }; +static const ShellConfig shell_cfg2 = { + (BaseSequentialStream *)&SDU2, + commands +}; + /*===========================================================================*/ /* Generic code. */ /*===========================================================================*/ @@ -146,7 +154,7 @@ static msg_t Thread1(void *arg) { while (true) { systime_t time; - time = serusbcfg.usbp->state == USB_ACTIVE ? 250 : 500; + time = serusbcfg1.usbp->state == USB_ACTIVE ? 250 : 500; palClearPad(GPIOD, GPIOD_LED4); chThdSleepMilliseconds(time); palSetPad(GPIOD, GPIOD_LED4); @@ -158,7 +166,8 @@ static msg_t Thread1(void *arg) { * Application entry point. */ int main(void) { - thread_t *shelltp = NULL; + thread_t *shelltp1 = NULL; + thread_t *shelltp2 = NULL; /* * System initializations. @@ -171,31 +180,22 @@ int main(void) { chSysInit(); /* - * Initializes a serial-over-USB CDC driver. + * Initializes two serial-over-USB CDC drivers. */ sduObjectInit(&SDU1); - sduStart(&SDU1, &serusbcfg); + sduStart(&SDU1, &serusbcfg1); + sduObjectInit(&SDU2); + sduStart(&SDU2, &serusbcfg2); /* * Activates the USB driver and then the USB bus pull-up on D+. * Note, a delay is inserted in order to not have to disconnect the cable * after a reset. */ - usbDisconnectBus(serusbcfg.usbp); + usbDisconnectBus(serusbcfg1.usbp); chThdSleepMilliseconds(1500); - usbStart(serusbcfg.usbp, &usbcfg); - usbConnectBus(serusbcfg.usbp); - - /* - * Stopping and restarting the USB in order to test the stop procedure. The - * following lines are not usually required. - */ - chThdSleepMilliseconds(3000); - usbDisconnectBus(serusbcfg.usbp); - usbStop(serusbcfg.usbp); - chThdSleepMilliseconds(1500); - usbStart(serusbcfg.usbp, &usbcfg); - usbConnectBus(serusbcfg.usbp); + usbStart(serusbcfg1.usbp, &usbcfg); + usbConnectBus(serusbcfg1.usbp); /* * Shell manager initialization. @@ -203,7 +203,7 @@ int main(void) { shellInit(); /* - * Creates the blinker thread. + * Creates the blinker threads. */ chThdCreateStatic(waThread1, sizeof(waThread1), NORMALPRIO, Thread1, NULL); @@ -212,11 +212,17 @@ int main(void) { * sleeping in a loop and check the button state. */ while (TRUE) { - if (!shelltp && (SDU1.config->usbp->state == USB_ACTIVE)) - shelltp = shellCreate(&shell_cfg1, SHELL_WA_SIZE, NORMALPRIO); - else if (chThdTerminatedX(shelltp)) { - chThdRelease(shelltp); /* Recovers memory of the previous shell. */ - shelltp = NULL; /* Triggers spawning of a new shell. */ + if (!shelltp1 && (SDU1.config->usbp->state == USB_ACTIVE)) + shelltp1 = shellCreate(&shell_cfg1, SHELL_WA_SIZE, NORMALPRIO); + else if (chThdTerminatedX(shelltp1)) { + chThdRelease(shelltp1); /* Recovers memory of the previous shell. */ + shelltp1 = NULL; /* Triggers spawning of a new shell. */ + } + if (!shelltp2 && (SDU2.config->usbp->state == USB_ACTIVE)) + shelltp2 = shellCreate(&shell_cfg2, SHELL_WA_SIZE, NORMALPRIO); + else if (chThdTerminatedX(shelltp2)) { + chThdRelease(shelltp2); /* Recovers memory of the previous shell. */ + shelltp2 = NULL; /* Triggers spawning of a new shell. */ } chThdSleepMilliseconds(1000); } diff --git a/testhal/STM32/STM32F4xx/USB_CDC_DUAL/usbcfg.c b/testhal/STM32/STM32F4xx/USB_CDC_DUAL/usbcfg.c index 260ffbfb6..b1d2b307b 100644 --- a/testhal/STM32/STM32F4xx/USB_CDC_DUAL/usbcfg.c +++ b/testhal/STM32/STM32F4xx/USB_CDC_DUAL/usbcfg.c @@ -14,35 +14,44 @@ limitations under the License. */ -#include "ch.h" #include "hal.h" /* - * Endpoints to be used for USBD1. + * Endpoints. */ -#define USBD1_DATA_REQUEST_EP_A 1 -#define USBD1_DATA_AVAILABLE_EP_A 1 -#define USBD1_INTERRUPT_REQUEST_EP_A 2 -#define USBD1_DATA_REQUEST_EP_B 3 -#define USBD1_DATA_AVAILABLE_EP_B 3 -#define USBD1_INTERRUPT_REQUEST_EP_B 4 +#define USB_INTERRUPT_REQUEST_EP_A 1 +#define USB_DATA_AVAILABLE_EP_A 2 +#define USB_DATA_REQUEST_EP_A 2 +#define USB_INTERRUPT_REQUEST_EP_B 3 +#define USB_DATA_AVAILABLE_EP_B 4 +#define USB_DATA_REQUEST_EP_B 4 + +/* + * Interfaces + */ +#define USB_NUM_INTERFACES 4 +#define USB_CDC_CIF_NUM0 0 +#define USB_CDC_DIF_NUM0 1 +#define USB_CDC_CIF_NUM1 2 +#define USB_CDC_DIF_NUM1 3 /* * USB Device Descriptor. */ 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. */ + USB_DESC_DEVICE( + 0x0110, /* bcdUSB (1.1). */ + 0xEF, /* bDeviceClass (misc). */ + 0x02, /* bDeviceSubClass (common). */ + 0x01, /* bDeviceProtocol (IAD). */ + 0x40, /* bMaxPacketSize. */ + 0x0483, /* idVendor (ST). */ + 0x5740, /* idProduct. */ + 0x0200, /* bcdDevice. */ + 1, /* iManufacturer. */ + 2, /* iProduct. */ + 3, /* iSerialNumber. */ + 1) /* bNumConfigurations. */ }; /* @@ -53,6 +62,10 @@ static const USBDescriptor vcom_device_descriptor = { vcom_device_descriptor_data }; +#define CDC_IF_DESC_SET_SIZE \ + (USB_DESC_INTERFACE_SIZE + 5 + 5 + 4 + 5 + USB_DESC_ENDPOINT_SIZE + \ + USB_DESC_INTERFACE_SIZE + (USB_DESC_ENDPOINT_SIZE *2)) + #define CDC_IF_DESC_SET(comIfNum, datIfNum, comInEp, datOutEp, datInEp) \ /* Interface Descriptor.*/ \ USB_DESC_INTERFACE( \ @@ -61,7 +74,7 @@ static const USBDescriptor vcom_device_descriptor = { 0x01, /* bNumEndpoints. */ \ CDC_COMMUNICATION_INTERFACE_CLASS, /* bInterfaceClass. */ \ CDC_ABSTRACT_CONTROL_MODEL, /* bInterfaceSubClass. */ \ - 0x01, /* bInterfaceProtocol (AT \ + 0x01, /* bInterfaceProtocol (AT commands, CDC section 4.4). */ \ 0), /* iInterface. */ \ @@ -87,11 +100,11 @@ static const USBDescriptor vcom_device_descriptor = { USB_DESC_BYTE (CDC_UNION), /* bDescriptorSubtype. */ \ USB_DESC_BYTE (comIfNum), /* bMasterInterface. */ \ USB_DESC_BYTE (datIfNum), /* bSlaveInterface. */ \ -/* Endpoint, Interrupt IN.*/ \ + /* Endpoint, Interrupt IN.*/ \ USB_DESC_ENDPOINT ( \ - comInEp | 0x80, \ - USB_ENDPOINT_TYPE_INTERRUPT, /* bmAttributes. */ \ - 0x000A, /*ZZZZZ*/ /* wMaxPacketSize. */ \ + comInEp, \ + USB_EP_MODE_TYPE_INTR, /* bmAttributes. */ \ + 0x0010, /* wMaxPacketSize. */ \ 0x01), /*******/ /* bInterval. */ \ \ /* CDC Data Interface Descriptor.*/ \ @@ -100,24 +113,26 @@ static const USBDescriptor vcom_device_descriptor = { 0x00, /* bAlternateSetting. */ \ 0x02, /* bNumEndpoints. */ \ CDC_DATA_INTERFACE_CLASS, /* bInterfaceClass. */ \ - 0x00, /* bInterfaceSubClass (CDC \ + 0x00, /* bInterfaceSubClass (CDC section 4.6). */ \ - 0x00, /* bInterfaceProtocol (CDC \ + 0x00, /* bInterfaceProtocol (CDC section 4.7). */ \ 0x00), /* iInterface. */ \ /* Endpoint, Bulk OUT.*/ \ USB_DESC_ENDPOINT( \ datOutEp, /* bEndpointAddress. */ \ - USB_ENDPOINT_TYPE_BULK, /* bmAttributes. */ \ + USB_EP_MODE_TYPE_BULK, /* bmAttributes. */ \ 0x0040, /*ZZZZZ*/ /* wMaxPacketSize. */ \ 0x00), /* bInterval. */ \ /* Endpoint, Bulk IN.*/ \ USB_DESC_ENDPOINT( \ - datInEp | 0x80, /* bEndpointAddress. */ \ - USB_ENDPOINT_TYPE_BULK, /* bmAttributes. */ \ + datInEp, /* bEndpointAddress. */ \ + USB_EP_MODE_TYPE_BULK, /* bmAttributes. */ \ 0x0040, /*ZZZZZ*/ /* wMaxPacketSize. */ \ 0x00) /* bInterval. */ +#define IAD_CDC_IF_DESC_SET_SIZE (8 + CDC_IF_DESC_SET_SIZE) + #define IAD_CDC_IF_DESC_SET(comIfNum, datIfNum, comInEp, datOutEp, datInEp) \ /* Interface Association Descriptor.*/ \ USB_DESC_BYTE (0x08), /* bLength. */ \ @@ -133,80 +148,31 @@ static const USBDescriptor vcom_device_descriptor = { /* Configuration Descriptor tree for a CDC.*/ -static const uint8_t vcom_configuration_descriptor_data[67] = { +static const uint8_t vcom_configuration_descriptor_data[] = { /* 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 (USBD1_INTERRUPT_REQUEST_EP_A|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 (USBD1_DATA_AVAILABLE_EP_A, /* bEndpointAddress.*/ - 0x02, /* bmAttributes (Bulk). */ - 0x0040, /* wMaxPacketSize. */ - 0x00), /* bInterval. */ - /* Endpoint 1 Descriptor.*/ - USB_DESC_ENDPOINT (USBD1_DATA_REQUEST_EP_A|0x80, /* bEndpointAddress.*/ - 0x02, /* bmAttributes (Bulk). */ - 0x0040, /* wMaxPacketSize. */ - 0x00) /* bInterval. */ + USB_DESC_CONFIGURATION( + USB_DESC_CONFIGURATION_SIZE + + (IAD_CDC_IF_DESC_SET_SIZE * 2), /* wTotalLength. */ + USB_NUM_INTERFACES, /* bNumInterfaces. */ + 0x01, /* bConfigurationValue. */ + 0, /* iConfiguration. */ + 0xC0, /* bmAttributes (self powered). */ + 50 /* bMaxPower (100mA). */ + ), + IAD_CDC_IF_DESC_SET( + USB_CDC_CIF_NUM0, + USB_CDC_DIF_NUM0, + USB_ENDPOINT_IN(USB_INTERRUPT_REQUEST_EP_A), + USB_ENDPOINT_OUT(USB_DATA_AVAILABLE_EP_A), + USB_ENDPOINT_IN(USB_DATA_REQUEST_EP_A) + ), + IAD_CDC_IF_DESC_SET( + USB_CDC_CIF_NUM1, + USB_CDC_DIF_NUM1, + USB_ENDPOINT_IN(USB_INTERRUPT_REQUEST_EP_B), + USB_ENDPOINT_OUT(USB_DATA_AVAILABLE_EP_B), + USB_ENDPOINT_IN(USB_DATA_REQUEST_EP_B) + ), }; /* @@ -299,52 +265,100 @@ static const USBDescriptor *get_descriptor(USBDriver *usbp, static USBInEndpointState ep1instate; /** - * @brief OUT EP1 state. + * @brief EP1 initialization structure (IN only). + */ +static const USBEndpointConfig ep1config = { + USB_EP_MODE_TYPE_INTR, + NULL, + sduInterruptTransmitted, + NULL, + 0x0010, + 0x0000, + &ep1instate, + NULL, + 1, + NULL +}; + +/** + * @brief IN EP2 state. + */ +static USBInEndpointState ep2instate; + +/** + * @brief OUT EP2 state. */ -static USBOutEndpointState ep1outstate; +static USBOutEndpointState ep2outstate; /** - * @brief EP1 initialization structure (both IN and OUT). + * @brief EP2 initialization structure (both IN and OUT). */ -static const USBEndpointConfig ep1config = { +static const USBEndpointConfig ep2config = { USB_EP_MODE_TYPE_BULK, NULL, sduDataTransmitted, sduDataReceived, 0x0040, 0x0040, - &ep1instate, - &ep1outstate, + &ep2instate, + &ep2outstate, 2, NULL }; /** - * @brief IN EP2 state. + * @brief IN EP3 state. */ -static USBInEndpointState ep2instate; +static USBInEndpointState ep3instate; /** - * @brief EP2 initialization structure (IN only). + * @brief EP3 initialization structure (IN only). */ -static const USBEndpointConfig ep2config = { +static const USBEndpointConfig ep3config = { USB_EP_MODE_TYPE_INTR, NULL, sduInterruptTransmitted, NULL, 0x0010, 0x0000, - &ep2instate, + &ep3instate, NULL, 1, NULL }; +/** + * @brief IN EP4 state. + */ +static USBInEndpointState ep4instate; + +/** + * @brief OUT EP4 state. + */ +static USBOutEndpointState ep4outstate; + +/** + * @brief EP4 initialization structure (both IN and OUT). + */ +static const USBEndpointConfig ep4config = { + USB_EP_MODE_TYPE_BULK, + NULL, + sduDataTransmitted, + sduDataReceived, + 0x0040, + 0x0040, + &ep4instate, + &ep4outstate, + 2, + NULL +}; + /* * Handles the USB driver global events. */ static void usb_event(USBDriver *usbp, usbevent_t event) { extern SerialUSBDriver SDU1; + extern SerialUSBDriver SDU2; switch (event) { case USB_EVENT_RESET: @@ -357,11 +371,14 @@ static void usb_event(USBDriver *usbp, usbevent_t event) { /* Enables the endpoints specified into the configuration. Note, this callback is invoked from an ISR so I-Class functions must be used.*/ - usbInitEndpointI(usbp, USBD1_DATA_REQUEST_EP_A, &ep1config); - usbInitEndpointI(usbp, USBD1_INTERRUPT_REQUEST_EP_A, &ep2config); + usbInitEndpointI(usbp, USB_DATA_REQUEST_EP_A, &ep1config); + usbInitEndpointI(usbp, USB_INTERRUPT_REQUEST_EP_A, &ep2config); + usbInitEndpointI(usbp, USB_DATA_REQUEST_EP_B, &ep3config); + usbInitEndpointI(usbp, USB_INTERRUPT_REQUEST_EP_B, &ep4config); /* Resetting the state of the CDC subsystem.*/ sduConfigureHookI(&SDU1); + sduConfigureHookI(&SDU2); chSysUnlockFromISR(); return; @@ -386,11 +403,21 @@ const USBConfig usbcfg = { }; /* - * Serial over USB driver configuration. + * Serial over USB driver configuration 1. + */ +const SerialUSBConfig serusbcfg1 = { + &USBD1, + USB_DATA_REQUEST_EP_A, + USB_DATA_AVAILABLE_EP_A, + USB_INTERRUPT_REQUEST_EP_A +}; + +/* + * Serial over USB driver configuration 2. */ -const SerialUSBConfig serusbcfg = { +const SerialUSBConfig serusbcfg2 = { &USBD1, - USBD1_DATA_REQUEST_EP_A, - USBD1_DATA_AVAILABLE_EP_A, - USBD1_INTERRUPT_REQUEST_EP_A + USB_DATA_REQUEST_EP_B, + USB_DATA_AVAILABLE_EP_B, + USB_INTERRUPT_REQUEST_EP_B }; diff --git a/testhal/STM32/STM32F4xx/USB_CDC_DUAL/usbcfg.h b/testhal/STM32/STM32F4xx/USB_CDC_DUAL/usbcfg.h index 2ffaa17f9..a97780b09 100644 --- a/testhal/STM32/STM32F4xx/USB_CDC_DUAL/usbcfg.h +++ b/testhal/STM32/STM32F4xx/USB_CDC_DUAL/usbcfg.h @@ -18,7 +18,8 @@ #define _USBCFG_H_ extern const USBConfig usbcfg; -extern SerialUSBConfig serusbcfg; +extern SerialUSBConfig serusbcfg1; +extern SerialUSBConfig serusbcfg2; #endif /* _USBCFG_H_ */ -- cgit v1.2.3