Subversion Repositories chibiosIgnition

Rev

Rev 18 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. /*
  2.     ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio
  3.  
  4.     Licensed under the Apache License, Version 2.0 (the "License");
  5.     you may not use this file except in compliance with the License.
  6.     You may obtain a copy of the License at
  7.  
  8.         http://www.apache.org/licenses/LICENSE-2.0
  9.  
  10.     Unless required by applicable law or agreed to in writing, software
  11.     distributed under the License is distributed on an "AS IS" BASIS,
  12.     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13.     See the License for the specific language governing permissions and
  14.     limitations under the License.
  15. */
  16.  
  17. #include "hal.h"
  18.  
  19.  
  20.  
  21. /* Virtual serial port over USB.*/
  22. SerialUSBDriver SDU1;
  23.  
  24. #if HAL_USE_USB_DUAL_CDC == TRUE
  25. SerialUSBDriver SDU2;
  26. #endif
  27.  
  28.  
  29.  
  30. #if  HAL_USE_USB_DUAL_CDC==TRUE
  31. #define USB_EP_BULK_DATASIZE 0x0020
  32. #define USB_EP_INTR_DATASIZE 0x0010
  33. #define USB_MAX_PACKETSIZE 0x0008
  34. #else
  35. #define USB_EP_BULK_DATASIZE 0x0040
  36. #define USB_EP_INTR_DATASIZE 0x0010
  37. #define USB_MAX_PACKETSIZE 0x0040
  38. #endif
  39.  
  40.  
  41. /*
  42.  * Endpoints to be used for USBD1/SDU1.
  43.  */
  44. #define USBD1_DATA_REQUEST_EP           1
  45. #define USBD1_DATA_AVAILABLE_EP         1
  46. #define USBD1_INTERRUPT_REQUEST_EP      2
  47.  
  48. /*
  49.  * Endpoints to be used for USBD1/SDU2
  50.  */
  51. #if HAL_USE_USB_DUAL_CDC == TRUE
  52. #define USBD1_DATA2_REQUEST_EP           3
  53. #define USBD1_DATA2_AVAILABLE_EP         3
  54. #define USBD1_INTERRUPT2_REQUEST_EP      4
  55. #endif
  56. /*
  57.  * USB Device Descriptor.
  58.  */
  59. static const uint8_t vcom_device_descriptor_data[18] = {
  60.   USB_DESC_DEVICE       (0x0110,        /* bcdUSB (1.1).                    */
  61.                          0x02,          /* bDeviceClass (CDC).              */
  62.                          0x00,          /* bDeviceSubClass.                 */
  63.                          0x00,          /* bDeviceProtocol.                 */
  64.                          USB_MAX_PACKETSIZE,          /* bMaxPacketSize.                  */
  65.                          0x0483,        /* idVendor (ST).                   */
  66.                          0x5740,        /* idProduct.                       */
  67.                          0x0200,        /* bcdDevice.                       */
  68.                          1,             /* iManufacturer.                   */
  69.                          2,             /* iProduct.                        */
  70.                          4,             /* iSerialNumber. */
  71.                          1)             /* bNumConfigurations.              */
  72. };
  73.  
  74. /*
  75.  * Device Descriptor wrapper.
  76.  */
  77. static const USBDescriptor vcom_device_descriptor = {
  78.   sizeof vcom_device_descriptor_data,
  79.   vcom_device_descriptor_data
  80. };
  81.  
  82.  
  83.  
  84.  
  85.  
  86. /* Configuration Descriptor tree for a CDC.*/
  87.  
  88. static const uint8_t vcom_configuration_descriptor_data[] = {
  89.   /* Configuration Descriptor.*/
  90. #if HAL_USE_USB_DUAL_CDC == FALSE
  91.                                  /* the header is 9 bytes long, total has 2 EPs in use = 67 bytes */
  92.   USB_DESC_CONFIGURATION(67,            /* wTotalLength.                    */
  93.                          0x02,          /* bNumInterfaces.                  */
  94.                          0x01,          /* bConfigurationValue.             */
  95.                          0,             /* iConfiguration.                  */
  96.                          0x80,          /* bmAttributes (bus  powered).     */
  97.                          50),           /* bMaxPower (100mA).               */
  98. #else
  99.                                                  /* the header is 9 bytes long, total has 4 EP in use = 67 * 2 -9 bytes */
  100.   USB_DESC_CONFIGURATION(125,           /* wTotalLength.                    */
  101.                                              0x04,          /* bNumInterfaces.                  */
  102.                                                  0x01,          /* bConfigurationValue.             */
  103.                                                  0,             /* iConfiguration.                  */
  104.                                                  0x80,          /* bmAttributes (bus powered).     */
  105.                                                  50),           /* bMaxPower (100mA).               */
  106. #endif
  107.                                                                                                  /* Interface Descriptor.*/
  108.   USB_DESC_INTERFACE    (0x00,          /* bInterfaceNumber.                */
  109.                          0x00,          /* bAlternateSetting.               */
  110.                          0x01,          /* bNumEndpoints.                   */
  111.                          0x02,          /* bInterfaceClass (Communications
  112.                                            Interface Class, CDC section
  113.                                            4.2).                            */
  114.                          0x02,          /* bInterfaceSubClass (Abstract
  115.                                          Control Model, CDC section 4.3).   */
  116.                          0x01,          /* bInterfaceProtocol (AT commands,
  117.                                            CDC section 4.4).                */
  118.                          0),            /* iInterface.                      */
  119.  
  120.                                                  /* Header Functional Descriptor (CDC section 5.2.3).*/
  121.   USB_DESC_BYTE         (5),            /* bLength.                         */
  122.   USB_DESC_BYTE         (0x24),         /* bDescriptorType (CS_INTERFACE).  */
  123.   USB_DESC_BYTE         (0x00),         /* bDescriptorSubtype (Header
  124.                                            Functional Descriptor.           */
  125.   USB_DESC_BCD          (0x0110),       /* bcdCDC.                          */
  126.   /* Call Management Functional Descriptor. */
  127.   USB_DESC_BYTE         (5),            /* bFunctionLength.                 */
  128.   USB_DESC_BYTE         (0x24),         /* bDescriptorType (CS_INTERFACE).  */
  129.   USB_DESC_BYTE         (0x01),         /* bDescriptorSubtype (Call Management
  130.                                            Functional Descriptor).          */
  131.   USB_DESC_BYTE         (0x00),         /* bmCapabilities (D0+D1).          */
  132.   USB_DESC_BYTE         (0x01),         /* bDataInterface.                  */
  133.   /* ACM Functional Descriptor.*/
  134.   USB_DESC_BYTE         (4),            /* bFunctionLength.                 */
  135.   USB_DESC_BYTE         (0x24),         /* bDescriptorType (CS_INTERFACE).  */
  136.   USB_DESC_BYTE         (0x02),         /* bDescriptorSubtype (Abstract
  137.                                            Control Management Descriptor).  */
  138.   USB_DESC_BYTE         (0x02),         /* bmCapabilities.                  */
  139.   /* Union Functional Descriptor.*/
  140.   USB_DESC_BYTE         (5),            /* bFunctionLength.                 */
  141.   USB_DESC_BYTE         (0x24),         /* bDescriptorType (CS_INTERFACE).  */
  142.   USB_DESC_BYTE         (0x06),         /* bDescriptorSubtype (Union
  143.                                            Functional Descriptor).          */
  144.   USB_DESC_BYTE         (0x00),         /* bMasterInterface (Communication
  145.                                            Class Interface).                */
  146.   USB_DESC_BYTE         (0x01),         /* bSlaveInterface0 (Data Class
  147.                                            Interface).                      */
  148.   /* Endpoint 2 Descriptor.*/
  149.   USB_DESC_ENDPOINT     (USBD1_INTERRUPT_REQUEST_EP|0x80,
  150.                          0x03,          /* bmAttributes (Interrupt).        */
  151.                          0x0008,        /* wMaxPacketSize.                  */
  152.                          0xFF),         /* bInterval.                       */
  153.   /* Interface Descriptor.*/
  154.   USB_DESC_INTERFACE    (0x01,          /* bInterfaceNumber.                */
  155.                          0x00,          /* bAlternateSetting.               */
  156.                          0x02,          /* bNumEndpoints.                   */
  157.                          0x0A,          /* bInterfaceClass (Data Class
  158.                                            Interface, CDC section 4.5).     */
  159.                          0x00,          /* bInterfaceSubClass (CDC section
  160.                                            4.6).                            */
  161.                          0x00,          /* bInterfaceProtocol (CDC section
  162.                                            4.7).                            */
  163.                          0x00),         /* iInterface.                      */
  164.   /* Endpoint 3 Descriptor.*/
  165.   USB_DESC_ENDPOINT     (USBD1_DATA_AVAILABLE_EP,       /* bEndpointAddress.*/
  166.                          0x02,          /* bmAttributes (Bulk).             */
  167.                                                  0x0040,        /* wMaxPacketSize.                  */
  168.                          0x00),         /* bInterval.                       */
  169.   /* Endpoint 1 Descriptor.*/
  170.   USB_DESC_ENDPOINT     (USBD1_DATA_REQUEST_EP|0x80,    /* bEndpointAddress.*/
  171.                          0x02,          /* bmAttributes (Bulk).             */
  172.                          0x0040,        /* wMaxPacketSize.                  */
  173.                          0x00),          /* bInterval.                       */
  174. #if HAL_USE_USB_DUAL_CDC ==TRUE
  175. /* Configuration Descriptor tree for a CDC.*/
  176. USB_DESC_INTERFACE    (0x02,          /* bInterfaceNumber.                */
  177.                        0x00,          /* bAlternateSetting.               */
  178.                        0x01,          /* bNumEndpoints.                   */
  179.                        0x02,          /* bInterfaceClass (Communications
  180.                                          Interface Class, CDC section
  181.                                          4.2).                            */
  182.                        0x02,          /* bInterfaceSubClass (Abstract
  183.                                        Control Model, CDC section 4.3).   */
  184.                        0x01,          /* bInterfaceProtocol (AT commands,
  185.                                          CDC section 4.4).                */
  186.                        0),            /* iInterface.                      */
  187.  
  188.                                                  /* Header Functional Descriptor (CDC section 5.2.3).*/
  189. USB_DESC_BYTE         (5),            /* bLength.                         */
  190. USB_DESC_BYTE         (0x24),         /* bDescriptorType (CS_INTERFACE).  */
  191. USB_DESC_BYTE         (0x00),         /* bDescriptorSubtype (Header
  192.                                          Functional Descriptor.           */
  193. USB_DESC_BCD          (0x0110),       /* bcdCDC.                          */
  194. /* Call Management Functional Descriptor. */
  195. USB_DESC_BYTE         (5),            /* bFunctionLength.                 */
  196. USB_DESC_BYTE         (0x24),         /* bDescriptorType (CS_INTERFACE).  */
  197. USB_DESC_BYTE         (0x01),         /* bDescriptorSubtype (Call Management
  198.                                          Functional Descriptor).          */
  199. USB_DESC_BYTE         (0x00),         /* bmCapabilities (D0+D1).          */
  200. USB_DESC_BYTE         (0x01),         /* bDataInterface.                  */
  201. /* ACM Functional Descriptor.*/
  202. USB_DESC_BYTE         (4),            /* bFunctionLength.                 */
  203. USB_DESC_BYTE         (0x24),         /* bDescriptorType (CS_INTERFACE).  */
  204. USB_DESC_BYTE         (0x02),         /* bDescriptorSubtype (Abstract
  205.                                          Control Management Descriptor).  */
  206. USB_DESC_BYTE         (0x02),         /* bmCapabilities.                  */
  207. /* Union Functional Descriptor.*/
  208. USB_DESC_BYTE         (5),            /* bFunctionLength.                 */
  209. USB_DESC_BYTE         (0x24),         /* bDescriptorType (CS_INTERFACE).  */
  210. USB_DESC_BYTE         (0x06),         /* bDescriptorSubtype (Union
  211.                                          Functional Descriptor).          */
  212. USB_DESC_BYTE         (0x00),         /* bMasterInterface (Communication
  213.                                          Class Interface).                */
  214. USB_DESC_BYTE         (0x01),         /* bSlaveInterface0 (Data Class
  215.                                          Interface).                      */
  216. /* Endpoint 2 Descriptor.*/
  217. USB_DESC_ENDPOINT     (USBD1_INTERRUPT2_REQUEST_EP|0x80,
  218.                        0x03,          /* bmAttributes (Interrupt).        */
  219.                        0x0008,        /* wMaxPacketSize.                  */
  220.                        0xFF),         /* bInterval.                       */
  221. /* Interface Descriptor.*/
  222. USB_DESC_INTERFACE    (0x03,          /* bInterfaceNumber.                */
  223.                        0x00,          /* bAlternateSetting.               */
  224.                        0x02,          /* bNumEndpoints.                   */
  225.                        0x0A,          /* bInterfaceClass (Data Class
  226.                                          Interface, CDC section 4.5).     */
  227.                        0x00,          /* bInterfaceSubClass (CDC section
  228.                                          4.6).                            */
  229.                        0x00,          /* bInterfaceProtocol (CDC section
  230.                                          4.7).                            */
  231.                        0x00),         /* iInterface.                      */
  232. /* Endpoint 3 Descriptor.*/
  233. USB_DESC_ENDPOINT     (USBD1_DATA2_AVAILABLE_EP,       /* bEndpointAddress.*/
  234.                        0x02,          /* bmAttributes (Bulk).             */
  235.                        0x0040,        /* wMaxPacketSize.                  */
  236.                        0x00),         /* bInterval.                       */
  237. /* Endpoint 1 Descriptor.*/
  238. USB_DESC_ENDPOINT     (USBD1_DATA2_REQUEST_EP|0x80,    /* bEndpointAddress.*/
  239.                        0x02,          /* bmAttributes (Bulk).             */
  240.                        0x0040,        /* wMaxPacketSize.                  */
  241.                        0x00)          /* bInterval.                       */
  242. #endif
  243. };
  244.  
  245.  
  246. /*
  247.  * Configuration Descriptor wrapper.
  248.  */
  249. static const USBDescriptor vcom_configuration_descriptor = {
  250.   sizeof vcom_configuration_descriptor_data,
  251.   vcom_configuration_descriptor_data
  252. };
  253.  
  254. /*
  255.  * U.S. English language identifier.
  256.  */
  257. static const uint8_t vcom_string0[] = {
  258.   USB_DESC_BYTE(4),                     /* bLength.                         */
  259.   USB_DESC_BYTE(USB_DESCRIPTOR_STRING), /* bDescriptorType.                 */
  260.   USB_DESC_WORD(0x0409)                 /* wLANGID (U.S. English).          */
  261. };
  262.  
  263. /*
  264.  * Vendor string.
  265.  */
  266. static const uint8_t vcom_string1[] = {
  267.   USB_DESC_BYTE(38),                    /* bLength.                         */
  268.   USB_DESC_BYTE(USB_DESCRIPTOR_STRING), /* bDescriptorType.                 */
  269.   'S', 0, 'T', 0, 'M', 0, 'i', 0, 'c', 0, 'r', 0, 'o', 0, 'e', 0,
  270.   'l', 0, 'e', 0, 'c', 0, 't', 0, 'r', 0, 'o', 0, 'n', 0, 'i', 0,
  271.   'c', 0, 's', 0
  272. };
  273.  
  274. /*
  275.  * Device Description string.
  276.  */
  277. static const uint8_t vcom_string2[] = {
  278.   USB_DESC_BYTE(56),                    /* bLength.                         */
  279.   USB_DESC_BYTE(USB_DESCRIPTOR_STRING), /* bDescriptorType.                 */
  280.   'C', 0, 'h', 0, 'i', 0, 'b', 0, 'i', 0, 'O', 0, 'S', 0, '/', 0,
  281.   'R', 0, 'T', 0, ' ', 0, 'V', 0, 'i', 0, 'r', 0, 't', 0, 'u', 0,
  282.   'a', 0, 'l', 0, ' ', 0, 'C', 0, 'O', 0, 'M', 0, ' ', 0, 'P', 0,
  283.   'o', 0, 'r', 0, 't', 0
  284. };
  285.  
  286. /*
  287.  * Serial Number string.
  288.  */
  289. static const uint8_t vcom_string3[] = {
  290.   USB_DESC_BYTE(8),                     /* bLength.                         */
  291.   USB_DESC_BYTE(USB_DESCRIPTOR_STRING), /* bDescriptorType.                 */
  292.   '0' + CH_KERNEL_MAJOR, 0,
  293.   '0' + CH_KERNEL_MINOR, 0,
  294.   '0' + CH_KERNEL_PATCH, 0
  295. };
  296.  
  297. /*
  298.  * Strings wrappers array.
  299.  */
  300. static const USBDescriptor vcom_strings[] = {
  301.   {sizeof vcom_string0, vcom_string0},
  302.   {sizeof vcom_string1, vcom_string1},
  303.   {sizeof vcom_string2, vcom_string2},
  304.   {sizeof vcom_string3, vcom_string3}
  305. };
  306.  
  307. /*
  308.  * Handles the GET_DESCRIPTOR callback. All required descriptors must be
  309.  * handled here.
  310.  */
  311. static const USBDescriptor *get_descriptor(USBDriver *usbp,
  312.                                            uint8_t dtype,
  313.                                            uint8_t dindex,
  314.                                            uint16_t lang) {
  315.  
  316.   (void)usbp;
  317.   (void)lang;
  318.   switch (dtype) {
  319.   case USB_DESCRIPTOR_DEVICE:
  320.     return &vcom_device_descriptor;
  321.   case USB_DESCRIPTOR_CONFIGURATION:
  322.     return &vcom_configuration_descriptor;
  323.   case USB_DESCRIPTOR_STRING:
  324.     if (dindex < 4)
  325.       return &vcom_strings[dindex];
  326.   }
  327.   return NULL;
  328. }
  329.  
  330. /**
  331.  * @brief   IN EP1 state.
  332.  */
  333. static USBInEndpointState ep1instate;
  334.  
  335. /**
  336.  * @brief   OUT EP1 state.
  337.  */
  338. static USBOutEndpointState ep1outstate;
  339.  
  340. /**
  341.  * @brief   EP1 initialization structure (both IN and OUT).
  342.  */
  343.  
  344. static const USBEndpointConfig ep1config = {
  345.   USB_EP_MODE_TYPE_BULK,
  346.   NULL,
  347.   sduDataTransmitted,
  348.   sduDataReceived,
  349.   USB_EP_BULK_DATASIZE,
  350.   USB_EP_BULK_DATASIZE,
  351.   &ep1instate,
  352.   &ep1outstate,
  353.   2,
  354.   NULL
  355. };
  356.  
  357. /**
  358.  * @brief   IN EP2 state.
  359.  */
  360. static USBInEndpointState ep2instate;
  361.  
  362. /**
  363.  * @brief   EP2 initialization structure (IN only).
  364.  */
  365. static const USBEndpointConfig ep2config = {
  366.   USB_EP_MODE_TYPE_INTR,
  367.   NULL,
  368.   sduInterruptTransmitted,
  369.   NULL,
  370.   USB_EP_INTR_DATASIZE,
  371.   0x0000,
  372.   &ep2instate,
  373.   NULL,
  374.   1,
  375.   NULL
  376. };
  377.  
  378.  
  379. #if  HAL_USE_USB_DUAL_CDC==TRUE
  380. /**
  381.  * @brief   IN EP3 state.
  382.  */
  383. static USBInEndpointState ep3instate;
  384.  
  385. /**
  386.  * @brief   OUT EP3 state.
  387.  */
  388. static USBOutEndpointState ep3outstate;
  389.  
  390. /**
  391.  * @brief   EP3 initialization structure (both IN and OUT).
  392.  */
  393. static const USBEndpointConfig ep3config = {
  394.   USB_EP_MODE_TYPE_BULK,
  395.   NULL,
  396.   sduDataTransmitted,
  397.   sduDataReceived,
  398.   USB_EP_BULK_DATASIZE,
  399.   USB_EP_BULK_DATASIZE,
  400.   &ep3instate,
  401.   &ep3outstate,
  402.   2,
  403.   NULL
  404. };
  405.  
  406. /**
  407.  * @brief   IN EP4 state.
  408.  */
  409. static USBInEndpointState ep4instate;
  410.  
  411. /**
  412.  * @brief   EP4 initialization structure (IN only).
  413.  */
  414. static const USBEndpointConfig ep4config = {
  415.   USB_EP_MODE_TYPE_INTR,
  416.   NULL,
  417.   sduInterruptTransmitted,
  418.   NULL,
  419.   USB_EP_INTR_DATASIZE,
  420.   0x0000,
  421.   &ep4instate,
  422.   NULL,
  423.   1,
  424.   NULL
  425. };
  426.  
  427.  
  428. #endif
  429. /*
  430.  * Handles the USB driver global events.
  431.  */
  432. static void usb_event(USBDriver *usbp, usbevent_t event) {
  433.   extern SerialUSBDriver SDU1;
  434.  
  435.   switch (event) {
  436.   case USB_EVENT_ADDRESS:
  437.     return;
  438.   case USB_EVENT_CONFIGURED:
  439.     chSysLockFromISR();
  440.  
  441.     /* Enables the endpoints specified into the configuration.
  442.        Note, this callback is invoked from an ISR so I-Class functions
  443.        must be used.*/
  444.     usbInitEndpointI(usbp, USBD1_DATA_REQUEST_EP, &ep1config);
  445.     usbInitEndpointI(usbp, USBD1_INTERRUPT_REQUEST_EP, &ep2config);
  446. #if  HAL_USE_USB_DUAL_CDC == TRUE
  447.     usbInitEndpointI(usbp, USBD1_DATA2_REQUEST_EP, &ep3config);
  448.     usbInitEndpointI(usbp, USBD1_INTERRUPT2_REQUEST_EP, &ep4config);
  449. #endif
  450.     /* Resetting the state of the CDC subsystem.*/
  451.     sduConfigureHookI(&SDU1);
  452.  
  453.     chSysUnlockFromISR();
  454.     return;
  455.   case USB_EVENT_RESET:
  456.     /* Falls into.*/
  457.   case USB_EVENT_UNCONFIGURED:
  458.     /* Falls into.*/
  459.   case USB_EVENT_SUSPEND:
  460.     chSysLockFromISR();
  461.  
  462.     /* Disconnection event on suspend.*/
  463.     sduSuspendHookI(&SDU1);
  464.  
  465.     chSysUnlockFromISR();
  466.     return;
  467.   case USB_EVENT_WAKEUP:
  468.     chSysLockFromISR();
  469.  
  470.     /* Disconnection event on suspend.*/
  471.     sduWakeupHookI(&SDU1);
  472.  
  473.     chSysUnlockFromISR();
  474.     return;
  475.   case USB_EVENT_STALLED:
  476.     return;
  477.   }
  478.   return;
  479. }
  480.  
  481. /*
  482.  * Handles the USB driver global events.
  483.  */
  484. static void sof_handler(USBDriver *usbp) {
  485.  
  486.   (void)usbp;
  487.  
  488.   osalSysLockFromISR();
  489.   sduSOFHookI(&SDU1);
  490.   osalSysUnlockFromISR();
  491. }
  492.  
  493. /*
  494.  * USB driver configuration.
  495.  */
  496. const USBConfig usbcfg = {
  497.   usb_event,
  498.   get_descriptor,
  499.   sduRequestsHook,
  500.   sof_handler
  501. };
  502.  
  503. /*
  504.  * Serial over USB driver configuration.
  505.  */
  506. const SerialUSBConfig serusbcfg = {
  507.   &USBD1,
  508.   USBD1_DATA_REQUEST_EP,
  509.   USBD1_DATA_AVAILABLE_EP,
  510.   USBD1_INTERRUPT_REQUEST_EP
  511. };
  512.  
  513. #if HAL_USE_USB_DUAL_CDC == TRUE
  514. const SerialUSBConfig serusbcfg2 = {
  515.   &USBD1,
  516.   USBD1_DATA2_REQUEST_EP,
  517.   USBD1_DATA2_AVAILABLE_EP,
  518.   USBD1_INTERRUPT2_REQUEST_EP
  519. };
  520. #endif
  521.