From 4e34687f65c0cf3dc839754391b268d9118a0937 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 17 Jun 2012 15:59:49 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@4291 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- demos/ARMCM4-STM32F407-LWIP-FATFS-USB/Makefile | 4 +- demos/ARMCM4-STM32F407-LWIP-FATFS-USB/halconf.h | 4 +- demos/ARMCM4-STM32F407-LWIP-FATFS-USB/main.c | 13 +- demos/ARMCM4-STM32F407-LWIP-FATFS-USB/usbshell.c | 432 +++++++++++++++++++++++ demos/ARMCM4-STM32F407-LWIP-FATFS-USB/usbshell.h | 33 ++ 5 files changed, 480 insertions(+), 6 deletions(-) create mode 100644 demos/ARMCM4-STM32F407-LWIP-FATFS-USB/usbshell.c create mode 100644 demos/ARMCM4-STM32F407-LWIP-FATFS-USB/usbshell.h (limited to 'demos/ARMCM4-STM32F407-LWIP-FATFS-USB') diff --git a/demos/ARMCM4-STM32F407-LWIP-FATFS-USB/Makefile b/demos/ARMCM4-STM32F407-LWIP-FATFS-USB/Makefile index 94a0c4096..43dd4ea46 100644 --- a/demos/ARMCM4-STM32F407-LWIP-FATFS-USB/Makefile +++ b/demos/ARMCM4-STM32F407-LWIP-FATFS-USB/Makefile @@ -87,7 +87,9 @@ CSRC = $(PORTSRC) \ $(BOARDSRC) \ $(LWSRC) \ $(CHIBIOS)/os/various/evtimer.c \ - web/web.c main.c + $(CHIBIOS)/os/various/chprintf.c \ + $(CHIBIOS)/os/various/shell.c \ + web/web.c usbshell.c main.c # C++ sources that can be compiled in ARM or THUMB mode depending on the global # setting. diff --git a/demos/ARMCM4-STM32F407-LWIP-FATFS-USB/halconf.h b/demos/ARMCM4-STM32F407-LWIP-FATFS-USB/halconf.h index ea8a906e9..507e35235 100644 --- a/demos/ARMCM4-STM32F407-LWIP-FATFS-USB/halconf.h +++ b/demos/ARMCM4-STM32F407-LWIP-FATFS-USB/halconf.h @@ -136,7 +136,7 @@ * @brief Enables the SERIAL over USB subsystem. */ #if !defined(HAL_USE_SERIAL_USB) || defined(__DOXYGEN__) -#define HAL_USE_SERIAL_USB FALSE +#define HAL_USE_SERIAL_USB TRUE #endif /** @@ -157,7 +157,7 @@ * @brief Enables the USB subsystem. */ #if !defined(HAL_USE_USB) || defined(__DOXYGEN__) -#define HAL_USE_USB FALSE +#define HAL_USE_USB TRUE #endif /*===========================================================================*/ diff --git a/demos/ARMCM4-STM32F407-LWIP-FATFS-USB/main.c b/demos/ARMCM4-STM32F407-LWIP-FATFS-USB/main.c index ce4745b6d..ed7833d2c 100644 --- a/demos/ARMCM4-STM32F407-LWIP-FATFS-USB/main.c +++ b/demos/ARMCM4-STM32F407-LWIP-FATFS-USB/main.c @@ -24,6 +24,7 @@ #include "lwipthread.h" +#include "usbshell.h" #include "web/web.h" /* @@ -58,7 +59,12 @@ int main(void) { chSysInit(); /* - * Activates the serial driver 3 using the driver default configuration. + * Activates the shell on the USB-CDC. + */ + usInit(); + + /* + * Activates the serial driver 6 using the driver default configuration. */ sdStart(&SD6, NULL); @@ -84,8 +90,9 @@ int main(void) { * sleeping in a loop and check the button state. */ while (TRUE) { - if (palReadPad(GPIOA, GPIOA_BUTTON_WKUP) == 0) - TestThread(&SD6); + usStateCheck(); + if (palReadPad(GPIOA, GPIOA_BUTTON_WKUP) != 0) { + } chThdSleepMilliseconds(500); } } diff --git a/demos/ARMCM4-STM32F407-LWIP-FATFS-USB/usbshell.c b/demos/ARMCM4-STM32F407-LWIP-FATFS-USB/usbshell.c new file mode 100644 index 000000000..278a530e2 --- /dev/null +++ b/demos/ARMCM4-STM32F407-LWIP-FATFS-USB/usbshell.c @@ -0,0 +1,432 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011,2012 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "ch.h" +#include "hal.h" +#include "test.h" + +#include "usb_cdc.h" +#include "chprintf.h" +#include "shell.h" + +/*===========================================================================*/ +/* USB related stuff. */ +/*===========================================================================*/ + +/* + * USB Driver structure. + */ +static SerialUSBDriver SDU1; + +/* + * 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. */ +}; + +/* + * 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} +}; + +/* + * Handles the GET_DESCRIPTOR callback. All required descriptors must be + * handled here. + */ +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; +} + +/** + * @brief IN EP1 state. + */ +static USBInEndpointState ep1instate; + +/** + * @brief EP1 initialization structure (IN only). + */ +static const USBEndpointConfig ep1config = { + USB_EP_MODE_TYPE_BULK, + NULL, + sduDataTransmitted, + NULL, + 0x0040, + 0x0000, + &ep1instate, + NULL, + NULL +}; + +/** + * @brief OUT EP2 state. + */ +USBOutEndpointState ep2outstate; + +/** + * @brief EP2 initialization structure (IN only). + */ +static const USBEndpointConfig ep2config = { + USB_EP_MODE_TYPE_INTR, + NULL, + sduInterruptTransmitted, + NULL, + 0x0010, + 0x0000, + NULL, + &ep2outstate, + NULL +}; + +/** + * @brief OUT EP2 state. + */ +USBOutEndpointState ep3outstate; + +/** + * @brief EP3 initialization structure (OUT only). + */ +static const USBEndpointConfig ep3config = { + USB_EP_MODE_TYPE_BULK, + NULL, + NULL, + sduDataReceived, + 0x0000, + 0x0040, + NULL, + &ep3outstate, + NULL +}; + +/* + * Handles the USB driver global events. + */ +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); + usbInitEndpointI(usbp, USB_CDC_DATA_AVAILABLE_EP, &ep3config); + + /* 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; +} + +/* + * Serial over USB driver configuration. + */ +static const SerialUSBConfig serusbcfg = { + &USBD1, + { + usb_event, + get_descriptor, + sduRequestsHook, + NULL + } +}; + +/*===========================================================================*/ +/* Command line related. */ +/*===========================================================================*/ + +#define SHELL_WA_SIZE THD_WA_SIZE(2048) +#define TEST_WA_SIZE THD_WA_SIZE(256) + +static void cmd_mem(BaseSequentialStream *chp, int argc, char *argv[]) { + size_t n, size; + + (void)argv; + if (argc > 0) { + chprintf(chp, "Usage: mem\r\n"); + return; + } + n = chHeapStatus(NULL, &size); + chprintf(chp, "core free memory : %u bytes\r\n", chCoreStatus()); + chprintf(chp, "heap fragments : %u\r\n", n); + chprintf(chp, "heap free total : %u bytes\r\n", size); +} + +static void cmd_threads(BaseSequentialStream *chp, int argc, char *argv[]) { + static const char *states[] = {THD_STATE_NAMES}; + Thread *tp; + + (void)argv; + if (argc > 0) { + chprintf(chp, "Usage: threads\r\n"); + return; + } + chprintf(chp, " addr stack prio refs state time\r\n"); + tp = chRegFirstThread(); + do { + chprintf(chp, "%.8lx %.8lx %4lu %4lu %9s %lu\r\n", + (uint32_t)tp, (uint32_t)tp->p_ctx.r13, + (uint32_t)tp->p_prio, (uint32_t)(tp->p_refs - 1), + states[tp->p_state], (uint32_t)tp->p_time); + tp = chRegNextThread(tp); + } while (tp != NULL); +} + +static void cmd_test(BaseSequentialStream *chp, int argc, char *argv[]) { + Thread *tp; + + (void)argv; + if (argc > 0) { + chprintf(chp, "Usage: test\r\n"); + return; + } + tp = chThdCreateFromHeap(NULL, TEST_WA_SIZE, chThdGetPriority(), + TestThread, chp); + if (tp == NULL) { + chprintf(chp, "out of memory\r\n"); + return; + } + chThdWait(tp); +} + +static const ShellCommand commands[] = { + {"mem", cmd_mem}, + {"threads", cmd_threads}, + {"test", cmd_test}, + {NULL, NULL} +}; + +static const ShellConfig shell_cfg1 = { + (BaseSequentialStream *)&SDU1, + commands +}; + +/*===========================================================================*/ +/* External Interface. */ +/*===========================================================================*/ + +static Thread *shelltp = NULL; + +/** + * @brief USB shell initialization. + */ +void usInit(void) { + + usbDisconnectBus(serusbcfg.usbp); + chThdSleepMilliseconds(1000); + sduObjectInit(&SDU1); + sduStart(&SDU1, &serusbcfg); + usbConnectBus(serusbcfg.usbp); +} + +/** + * @brief USB shell state check. + */ +void usStateCheck(void) { + + if (!shelltp && (SDU1.config->usbp->state == USB_ACTIVE)) + shelltp = shellCreate(&shell_cfg1, SHELL_WA_SIZE, NORMALPRIO); + else if (chThdTerminated(shelltp)) { + chThdRelease(shelltp); /* Recovers memory of the previous shell. */ + shelltp = NULL; /* Triggers spawning of a new shell. */ + } +} diff --git a/demos/ARMCM4-STM32F407-LWIP-FATFS-USB/usbshell.h b/demos/ARMCM4-STM32F407-LWIP-FATFS-USB/usbshell.h new file mode 100644 index 000000000..cee510e73 --- /dev/null +++ b/demos/ARMCM4-STM32F407-LWIP-FATFS-USB/usbshell.h @@ -0,0 +1,33 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011,2012 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifndef _USBSHELL_H_ +#define _USBSHELL_H_ + +#ifdef __cplusplus +extern "C" { +#endif + void usInit(void); + void usStateCheck(void); +#ifdef __cplusplus +} +#endif + +#endif /* _USBSHELL_H_ */ -- cgit v1.2.3