diff --git a/conf/modules/telemetry_transparent.xml b/conf/modules/telemetry_transparent.xml index 7e7a452d03..14c82691da 100644 --- a/conf/modules/telemetry_transparent.xml +++ b/conf/modules/telemetry_transparent.xml @@ -3,11 +3,13 @@ - Telemetry using PPRZ protocol over UART + Telemetry using PPRZ protocol over UART or USB serial. + Can be used with a UART (uart1, uart2 ...), or a serial over USB: usb_serial, usb_serial_debug. + usb_serial_debug is available only for some MCUs (STM32F7, STM32H7) Currently used as a makefile wrapper over the telemetry_transparent modules - + diff --git a/conf/modules/telemetry_transparent_usb.xml b/conf/modules/telemetry_transparent_usb.xml index 57ebf8cc19..b0999833a1 100644 --- a/conf/modules/telemetry_transparent_usb.xml +++ b/conf/modules/telemetry_transparent_usb.xml @@ -3,29 +3,18 @@ + DEPRECATED: Use telemetry_transparent with configure MODEM_PORT=usb_serial instead. Telemetry using PPRZ protocol over serial USB (e.g. /dev/ttyACM0) - datalink_common - datalink,telemetry + telemetry_transparent - - -
- -
- - - - - - - - - - + + + $(warning Warning: telemetry_transparent_usb is deprecated. Use telemetry_transparent with configure MODEM_PORT=usb_serial instead.) +
diff --git a/conf/modules/usb_serial_stm32_example1.xml b/conf/modules/usb_serial_stm32_example1.xml index 2c7dd7fe8f..a8db66d3e1 100644 --- a/conf/modules/usb_serial_stm32_example1.xml +++ b/conf/modules/usb_serial_stm32_example1.xml @@ -9,7 +9,9 @@ To be used with Lisa M/MX 2.1 - + + uart +
@@ -18,7 +20,6 @@ - diff --git a/conf/system/udev/rules/50-paparazzi.rules b/conf/system/udev/rules/50-paparazzi.rules index 2c0335db72..50854fa916 100644 --- a/conf/system/udev/rules/50-paparazzi.rules +++ b/conf/system/udev/rules/50-paparazzi.rules @@ -11,6 +11,9 @@ SUBSYSTEM=="tty", ATTRS{interface}=="FLOSS-JTAG", ATTRS{bInterfaceNumber}=="01", SUBSYSTEM=="tty", ATTRS{interface}=="Black Magic GDB Server", SYMLINK+="bmp-gdb" SUBSYSTEM=="tty", ATTRS{interface}=="Black Magic UART Port", SYMLINK+="bmp-serial" +SUBSYSTEM=="tty", ATTRS{interface}=="Paparazzi UAV debug Port", SYMLINK+="pprz-dbg" +SUBSYSTEM=="tty", ATTRS{interface}=="Paparazzi UAV telemetry Port", SYMLINK+="pprz-tlm" + # FTDI 3.3V serial cable SUBSYSTEM=="tty", ATTRS{interface}=="TTL232R-3V3", SYMLINK+="ftdi-serial" diff --git a/sw/airborne/arch/chibios/halconf.h b/sw/airborne/arch/chibios/halconf.h index 55e01e790e..b80a11f99a 100644 --- a/sw/airborne/arch/chibios/halconf.h +++ b/sw/airborne/arch/chibios/halconf.h @@ -173,7 +173,7 @@ * @brief Enables the SERIAL over USB subsystem. */ #if !defined(HAL_USE_SERIAL_USB) || defined(__DOXYGEN__) -#if USE_USB_SERIAL +#if USE_USB_SERIAL || USE_USB_SERIAL_DEBUG #define HAL_USE_SERIAL_USB TRUE #else #define HAL_USE_SERIAL_USB FALSE @@ -216,7 +216,7 @@ * @brief Enables the USB subsystem. */ #if !defined(HAL_USE_USB) || defined(__DOXYGEN__) -#if USE_USB_SERIAL +#if USE_USB_SERIAL || USE_USB_SERIAL_DEBUG #define HAL_USE_USB TRUE #else #define HAL_USE_USB FALSE diff --git a/sw/airborne/arch/chibios/mcu_arch.h b/sw/airborne/arch/chibios/mcu_arch.h index b34bb3e9b3..eec8bc36f9 100644 --- a/sw/airborne/arch/chibios/mcu_arch.h +++ b/sw/airborne/arch/chibios/mcu_arch.h @@ -32,6 +32,7 @@ #define CHIBIOS_MCU_ARCH_H #include "std.h" +#include extern void mcu_arch_init(void); diff --git a/sw/airborne/arch/chibios/usb_ser_hw.c b/sw/airborne/arch/chibios/usb_ser_hw.c index 86985e405f..c701a43914 100644 --- a/sw/airborne/arch/chibios/usb_ser_hw.c +++ b/sw/airborne/arch/chibios/usb_ser_hw.c @@ -33,6 +33,9 @@ #define SERIAL_USB USBD1 #endif +/** + * Endpoints +*/ #ifndef USBD1_DATA_REQUEST_EP #define USBD1_DATA_REQUEST_EP 1 #endif @@ -43,6 +46,37 @@ #define USBD1_INTERRUPT_REQUEST_EP 2 #endif +/** + * Interfaces +*/ +#define USB_NUM_INTERFACES 2 +#define USB_CDC_CIF_NUM0 0 +#define USB_CDC_DIF_NUM0 1 + + +//------------------------------ 2 serial USB -------------------------- +#if USBD_NUMBER >= 2 +#ifndef USBD2_DATA_REQUEST_EP +#define USBD2_DATA_REQUEST_EP 3 +#endif +#ifndef USBD2_DATA_AVAILABLE_EP +#define USBD2_DATA_AVAILABLE_EP 3 +#endif +#ifndef USBD2_INTERRUPT_REQUEST_EP +#define USBD2_INTERRUPT_REQUEST_EP 4 +#endif +#undef USB_NUM_INTERFACES +#define USB_NUM_INTERFACES 4 +#define USB_CDC_CIF_NUM1 2 +#define USB_CDC_DIF_NUM1 3 +#endif + + +#define USB_INTERRUPT_REQUEST_SIZE 0x10 +#define USB_DATA_SIZE 0x40 + + + #if (CH_KERNEL_MAJOR == 2) static EventListener inputAvailEL = {NULL, NULL, 0, 0}; #else @@ -58,11 +92,11 @@ * 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. */ + USB_DESC_DEVICE (0x0200, /* bcdUSB (1.1). */ + 0xEF, /* bDeviceClass (misc). */ + 0x02, /* bDeviceSubClass (common). */ + 0x01, /* bDeviceProtocol (IAD). */ + USB_DATA_SIZE, /* bMaxPacketSize. */ 0x0483, /* idVendor (ST). */ 0x5740, /* idProduct. */ 0x0200, /* bcdDevice. */ @@ -72,6 +106,7 @@ static const uint8_t vcom_device_descriptor_data[18] = { 1) /* bNumConfigurations. */ }; + /* * Device Descriptor wrapper. */ @@ -80,81 +115,148 @@ 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 IAD_CDC_IF_DESC_SET_SIZE \ + (USB_DESC_INTERFACE_ASSOCIATION_SIZE + CDC_IF_DESC_SET_SIZE) + +#define CONFIG_DESC_DATA_SIZE (USB_DESC_CONFIGURATION_SIZE + (IAD_CDC_IF_DESC_SET_SIZE*USBD_NUMBER)) + /* Configuration Descriptor tree for a CDC.*/ -static const uint8_t vcom_configuration_descriptor_data[67] = { +static const uint8_t vcom_configuration_descriptor_data[CONFIG_DESC_DATA_SIZE] = { /* 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. */ + USB_DESC_CONFIGURATION( + CONFIG_DESC_DATA_SIZE, /* wTotalLength. */ + USB_NUM_INTERFACES, /* bNumInterfaces. */ + 0x01, /* bConfigurationValue. */ + 0, /* iConfiguration. */ + 0x80, /* bmAttributes (self powered). */ + 50), /* bMaxPower (100mA). */ + + + /* Interface Descriptor. USB serial 1.*/ + USB_DESC_INTERFACE( + USB_CDC_CIF_NUM0, /* bInterfaceNumber. */ + 0x00, /* bAlternateSetting. */ + 0x01, /* bNumEndpoints. */ + CDC_COMMUNICATION_INTERFACE_CLASS, /* bInterfaceClass */ + CDC_ABSTRACT_CONTROL_MODEL, /* bInterfaceSubClass */ + 0x00, /* bInterfaceProtocol (CDC section 4.4)*/ + 4), /* iInterface: Descriptor index */ /* 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. */ + USB_DESC_BYTE (5), /* bLength. */ + USB_DESC_BYTE (CDC_CS_INTERFACE), /* bDescriptorType (CS_INTERFACE). */ + USB_DESC_BYTE (CDC_HEADER), /* bDescriptorSubtype */ + 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. */ + USB_DESC_BYTE (5), /* bFunctionLength. */ + USB_DESC_BYTE (CDC_CS_INTERFACE), /* bDescriptorType (CS_INTERFACE). */ + USB_DESC_BYTE (CDC_CALL_MANAGEMENT), /* bDescriptorSubtype */ + USB_DESC_BYTE (0x00), /* bmCapabilities (D0+D1). */ + USB_DESC_BYTE (USB_CDC_DIF_NUM0), /* 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|0x80, - 0x03, /* bmAttributes (Interrupt). */ - 0x0008, /* wMaxPacketSize. */ - 0xFF), /* bInterval. */ + USB_DESC_BYTE (4), /* bFunctionLength. */ + USB_DESC_BYTE (CDC_CS_INTERFACE), /* bDescriptorType (CS_INTERFACE). */ + USB_DESC_BYTE (CDC_ABSTRACT_CONTROL_MANAGEMENT), /* bDescriptorSubtype */ + USB_DESC_BYTE (0x02), /* bmCapabilities. */ + /* Union Functional Descriptor.*/ + USB_DESC_BYTE (5), /* bFunctionLength. */ + USB_DESC_BYTE (CDC_CS_INTERFACE), /* bDescriptorType (CS_INTERFACE). */ + USB_DESC_BYTE (CDC_UNION), /* bDescriptorSubtype */ + USB_DESC_BYTE (USB_CDC_CIF_NUM0), /* bMasterInterface */ + USB_DESC_BYTE (USB_CDC_DIF_NUM0), /* bSlaveInterface0 */ + /* Endpoint, Interrupt IN.*/ + USB_DESC_ENDPOINT( + USB_ENDPOINT_IN(USBD1_INTERRUPT_REQUEST_EP), + USB_EP_MODE_TYPE_INTR, /* bmAttributes (Interrupt). */ + USB_INTERRUPT_REQUEST_SIZE, /* 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, /* bEndpointAddress.*/ - 0x02, /* bmAttributes (Bulk). */ - 0x0040, /* wMaxPacketSize. */ - 0x00), /* bInterval. */ - /* Endpoint 1 Descriptor.*/ - USB_DESC_ENDPOINT (USBD1_DATA_REQUEST_EP|0x80, /* bEndpointAddress.*/ - 0x02, /* bmAttributes (Bulk). */ - 0x0040, /* wMaxPacketSize. */ - 0x00) /* bInterval. */ + USB_DESC_INTERFACE( + USB_CDC_DIF_NUM0, /* bInterfaceNumber. */ + 0x00, /* bAlternateSetting. */ + 0x02, /* bNumEndpoints. */ + CDC_DATA_INTERFACE_CLASS, /* bInterfaceClass */ + 0x00, /* bInterfaceSubClass (CDC sec. 4.6)*/ + 0x00, /* bInterfaceProtocol (CDC sec. 4.7)*/ + 0x00), /* iInterface. */ + /* Endpoint, Bulk OUT.*/ + USB_DESC_ENDPOINT( + USB_ENDPOINT_OUT(USBD1_DATA_AVAILABLE_EP), /* bEndpointAddress. */ + USB_EP_MODE_TYPE_BULK, /* bmAttributes (Bulk). */ + USB_DATA_SIZE, /* wMaxPacketSize. */ + 0x00), /* bInterval. */ + /* Endpoint, Bulk IN*/ + USB_DESC_ENDPOINT( + USB_ENDPOINT_IN(USBD1_DATA_REQUEST_EP), /* bEndpointAddress. */ + USB_EP_MODE_TYPE_BULK, /* bmAttributes (Bulk). */ + USB_DATA_SIZE, /* wMaxPacketSize. */ + 0x00), /* bInterval. */ + + + +#if USBD_NUMBER >= 2 + /* Interface Descriptor. USB serial 2.*/ + USB_DESC_INTERFACE( + USB_CDC_CIF_NUM1, /* bInterfaceNumber. */ + 0x00, /* bAlternateSetting. */ + 0x01, /* bNumEndpoints. */ + CDC_COMMUNICATION_INTERFACE_CLASS, /* bInterfaceClass */ + CDC_ABSTRACT_CONTROL_MODEL, /* bInterfaceSubClass */ + 0x00, /* bInterfaceProtocol (CDC section 4.4)*/ + 5), /* iInterface: Descriptor index */ + /* Header Functional Descriptor (CDC section 5.2.3).*/ + USB_DESC_BYTE (5), /* bLength. */ + USB_DESC_BYTE (CDC_CS_INTERFACE), /* bDescriptorType (CS_INTERFACE). */ + USB_DESC_BYTE (CDC_HEADER), /* bDescriptorSubtype */ + USB_DESC_BCD (0x0110), /* bcdCDC. */ + /* Call Management Functional Descriptor. */ + USB_DESC_BYTE (5), /* bFunctionLength. */ + USB_DESC_BYTE (CDC_CS_INTERFACE), /* bDescriptorType (CS_INTERFACE). */ + USB_DESC_BYTE (CDC_CALL_MANAGEMENT), /* bDescriptorSubtype */ + USB_DESC_BYTE (0x00), /* bmCapabilities (D0+D1). */ + USB_DESC_BYTE (USB_CDC_DIF_NUM1), /* bDataInterface. */ + /* ACM Functional Descriptor.*/ + USB_DESC_BYTE (4), /* bFunctionLength. */ + USB_DESC_BYTE (CDC_CS_INTERFACE), /* bDescriptorType (CS_INTERFACE). */ + USB_DESC_BYTE (CDC_ABSTRACT_CONTROL_MANAGEMENT), /* bDescriptorSubtype */ + USB_DESC_BYTE (0x02), /* bmCapabilities. */ + /* Union Functional Descriptor.*/ + USB_DESC_BYTE (5), /* bFunctionLength. */ + USB_DESC_BYTE (CDC_CS_INTERFACE), /* bDescriptorType (CS_INTERFACE). */ + USB_DESC_BYTE (CDC_UNION), /* bDescriptorSubtype */ + USB_DESC_BYTE (USB_CDC_CIF_NUM1), /* bMasterInterface */ + USB_DESC_BYTE (USB_CDC_DIF_NUM1), /* bSlaveInterface0 */ + /* Endpoint, Interrupt IN.*/ + USB_DESC_ENDPOINT( + USB_ENDPOINT_IN(USBD2_INTERRUPT_REQUEST_EP), + USB_EP_MODE_TYPE_INTR, /* bmAttributes (Interrupt). */ + USB_INTERRUPT_REQUEST_SIZE, /* wMaxPacketSize. */ + 0xFF), /* bInterval. */ + /* Interface Descriptor.*/ + USB_DESC_INTERFACE( + USB_CDC_DIF_NUM1, /* bInterfaceNumber. */ + 0x00, /* bAlternateSetting. */ + 0x02, /* bNumEndpoints. */ + CDC_DATA_INTERFACE_CLASS, /* bInterfaceClass */ + 0x00, /* bInterfaceSubClass (CDC sec. 4.6)*/ + 0x00, /* bInterfaceProtocol (CDC sec. 4.7)*/ + 0x00), /* iInterface. */ + /* Endpoint, Bulk OUT.*/ + USB_DESC_ENDPOINT( + USB_ENDPOINT_OUT(USBD2_DATA_AVAILABLE_EP), /* bEndpointAddress. */ + USB_EP_MODE_TYPE_BULK, /* bmAttributes (Bulk). */ + USB_DATA_SIZE, /* wMaxPacketSize. */ + 0x00), /* bInterval. */ + /* Endpoint, Bulk IN*/ + USB_DESC_ENDPOINT( + USB_ENDPOINT_IN(USBD2_DATA_REQUEST_EP), /* bEndpointAddress. */ + USB_EP_MODE_TYPE_BULK, /* bmAttributes (Bulk). */ + USB_DATA_SIZE, /* wMaxPacketSize. */ + 0x00) /* bInterval. */ +#endif }; /* @@ -205,6 +307,31 @@ static const uint8_t vcom_string3[] = { '0' + CH_KERNEL_PATCH, 0 }; +/** + * interface ID ? +*/ +static const uint8_t vcom_string4[] = { + USB_DESC_BYTE(58), /* bLength. */ + USB_DESC_BYTE(USB_DESCRIPTOR_STRING), /* bDescriptorType. */ + 'P', 0, 'a', 0, 'p', 0, 'a', 0, 'r', 0, 'a', 0, 'z', 0, 'z', 0, + 'i', 0, ' ', 0, 'U', 0, 'A', 0, 'V', 0, ' ', 0, 't', 0, 'e', 0, + 'l', 0, 'e', 0, 'm', 0, 'e', 0, 't', 0, 'r', 0, 'y', 0, ' ', 0, + 'P', 0, 'o', 0, 'r', 0, 't', 0 +}; + +#if USBD_NUMBER >= 2 +/** + * interface ID ? +*/ +static const uint8_t vcom_string5[] = { + USB_DESC_BYTE(54), /* bLength. */ + USB_DESC_BYTE(USB_DESCRIPTOR_STRING), /* bDescriptorType. */ + 'P', 0, 'a', 0, 'p', 0, 'a', 0, 'r', 0, 'a', 0, 'z', 0, 'z', 0, + 'i', 0, ' ', 0, 'U', 0, 'A', 0, 'V', 0, ' ', 0, 'd', 0, 'e', 0, + 'b', 0, 'u', 0, 'g', 0, ' ', 0, 'P', 0, 'o', 0, 'r', 0, 't', 0 +}; +#endif + /* * Strings wrappers array. */ @@ -212,11 +339,18 @@ 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} + {sizeof vcom_string3, vcom_string3}, + {sizeof vcom_string4, vcom_string4}, +#if USBD_NUMBER >= 2 + {sizeof vcom_string5, vcom_string5} +#endif }; -static SerialUSBDriver SDU; +static SerialUSBDriver SDU1; +#if USBD_NUMBER >= 2 +static SerialUSBDriver SDU2; +#endif /* * Handles the GET_DESCRIPTOR callback. All required descriptors must be @@ -235,7 +369,7 @@ static const USBDescriptor *get_descriptor(USBDriver *usbp, case USB_DESCRIPTOR_CONFIGURATION: return &vcom_configuration_descriptor; case USB_DESCRIPTOR_STRING: - if (dindex < 4) + if (dindex < 6) return &vcom_strings[dindex]; } return NULL; @@ -260,8 +394,8 @@ static const USBEndpointConfig ep1config = { NULL, sduDataTransmitted, sduDataReceived, - 0x0040, - 0x0040, + USB_DATA_SIZE, + USB_DATA_SIZE, &ep1instate, &ep1outstate, 2, @@ -281,7 +415,7 @@ static const USBEndpointConfig ep2config = { NULL, sduInterruptTransmitted, NULL, - 0x0010, + USB_INTERRUPT_REQUEST_SIZE, 0x0000, &ep2instate, NULL, @@ -289,6 +423,55 @@ static const USBEndpointConfig ep2config = { NULL }; +#if USBD_NUMBER >= 2 +/** + * @brief IN EP3 state. + */ +static USBInEndpointState ep3instate; + +/** + * @brief OUT EP3 state. + */ +static USBOutEndpointState ep3outstate; + +/** + * @brief EP3 initialization structure (IN only). + */ +static const USBEndpointConfig ep3config = { + USB_EP_MODE_TYPE_BULK, + NULL, + sduDataTransmitted, + sduDataReceived, + USB_DATA_SIZE, + USB_DATA_SIZE, + &ep3instate, + &ep3outstate, + 2, + NULL +}; + +/** + * @brief IN EP4 state. + */ +static USBInEndpointState ep4instate; + +/** + * @brief EP4 initialization structure (IN only). + */ +static const USBEndpointConfig ep4config = { + USB_EP_MODE_TYPE_INTR, + NULL, + sduInterruptTransmitted, + NULL, + USB_INTERRUPT_REQUEST_SIZE, + 0x0000, + &ep4instate, + NULL, + 1, + NULL +}; +#endif + /* @@ -304,14 +487,26 @@ static void usb_event(USBDriver *usbp, usbevent_t event) { 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, USBD1_DATA_REQUEST_EP, &ep1config); - usbInitEndpointI(usbp, USBD1_INTERRUPT_REQUEST_EP, &ep2config); - - /* Resetting the state of the CDC subsystem.*/ - sduConfigureHookI(&SDU); + + if (usbp->state == USB_ACTIVE) { + /* 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, &ep1config); + usbInitEndpointI(usbp, USBD1_INTERRUPT_REQUEST_EP, &ep2config); +#if USBD_NUMBER >= 2 + usbInitEndpointI(usbp, USBD2_DATA_REQUEST_EP, &ep3config); + usbInitEndpointI(usbp, USBD2_INTERRUPT_REQUEST_EP, &ep4config); +#endif + /* Resetting the state of the CDC subsystem.*/ + sduConfigureHookI(&SDU1); +#if USBD_NUMBER >= 2 + sduConfigureHookI(&SDU2); +#endif + } + else if (usbp->state == USB_SELECTED) { + usbDisableEndpointsI(usbp); + } chSysUnlockFromISR(); return; @@ -321,8 +516,10 @@ static void usb_event(USBDriver *usbp, usbevent_t event) { chSysLockFromISR(); /* Disconnection event on suspend.*/ - sduSuspendHookI(&SDU); - + sduSuspendHookI(&SDU1); +#if USBD_NUMBER >= 2 + sduSuspendHookI(&SDU2); +#endif chSysUnlockFromISR(); return; case USB_EVENT_WAKEUP: @@ -341,7 +538,10 @@ static void sof_handler(USBDriver *usbp) (void)usbp; chSysLockFromISR(); - sduSOFHookI(&SDU); + sduSOFHookI(&SDU1); +#if USBD_NUMBER >= 2 + sduSOFHookI(&SDU2); +#endif chSysUnlockFromISR(); } @@ -355,11 +555,14 @@ static const USBConfig usbcfg = { sof_handler }; -static SerialUSBConfig serusbcfg ; +static SerialUSBConfig serusbcfg1; +#if USBD_NUMBER >= 2 +static SerialUSBConfig serusbcfg2; +#endif USBDriver *usbGetDriver (void) { - return serusbcfg.usbp; + return serusbcfg1.usbp; } @@ -386,16 +589,16 @@ bool isUsbConnected(void) void usbSerialReset(SerialUSBDriver *sdu) { - usbStop(serusbcfg.usbp); - usbDisconnectBus(serusbcfg.usbp); + usbStop(serusbcfg1.usbp); + usbDisconnectBus(serusbcfg1.usbp); sduStop (sdu); chThdSleepMilliseconds(10); - sduStart(sdu, &serusbcfg); - usbDisconnectBus(serusbcfg.usbp); + sduStart(sdu, &serusbcfg1); + usbDisconnectBus(serusbcfg1.usbp); chThdSleepMilliseconds(900); - usbStart(serusbcfg.usbp, &usbcfg); - usbConnectBus(serusbcfg.usbp); + usbStart(serusbcfg1.usbp, &usbcfg); + usbConnectBus(serusbcfg1.usbp); } @@ -404,6 +607,9 @@ void usbSerialReset(SerialUSBDriver *sdu) */ // Periph with generic device API struct usb_serial_periph usb_serial; +#if USBD_NUMBER >= 2 +struct usb_serial_periph usb_serial_debug; +#endif // Functions for the generic device API static int usb_serial_check_free_space(struct usb_serial_periph *p __attribute__((unused)), @@ -417,14 +623,14 @@ static void usb_serial_transmit(struct usb_serial_periph *p __attribute__((unuse long fd __attribute__((unused)), uint8_t byte) { - streamPut(&SDU, byte); + obqPutTimeout(&((SerialUSBDriver *)p->reg_addr)->obqueue, byte, TIME_IMMEDIATE); } static void usb_serial_transmit_buffer(struct usb_serial_periph *p __attribute__((unused)), long fd __attribute__((unused)), uint8_t *data, uint16_t len) { - streamWrite(&SDU, data, len); + obqWriteTimeout(&((SerialUSBDriver *)p->reg_addr)->obqueue, data, len, TIME_IMMEDIATE); } static void usb_serial_send(struct usb_serial_periph *p __attribute__((unused)), long fd __attribute__((unused))) @@ -442,7 +648,7 @@ static int usb_serial_char_available(struct usb_serial_periph *p __attribute__(( uint16_t write_idx = (p->rx_read_idx + p->nb_bytes) % USB_RX_BUFFER_SIZE; // no bytes in the buffer, try to get one - msg_t res = ibqGetTimeout(&SDU.ibqueue, TIME_IMMEDIATE); + msg_t res = ibqGetTimeout(&(((SerialUSBDriver*)(p->reg_addr))->ibqueue), TIME_IMMEDIATE); if(res >= 0) { // got a byte. put it in the buffer. p->rx_buf[write_idx] = (uint8_t) res; @@ -462,8 +668,7 @@ static uint8_t usb_serial_getch(struct usb_serial_periph *p __attribute__((unuse p->nb_bytes--; return ret; } else { - // blocking get - return streamGet(&SDU); + return ibqGetTimeout(&((SerialUSBDriver *)p->reg_addr)->ibqueue, TIME_IMMEDIATE); } } @@ -475,26 +680,36 @@ static uint8_t usb_serial_getch(struct usb_serial_periph *p __attribute__((unuse */ void VCOM_init() { - serusbcfg.usbp = &SERIAL_USB; - serusbcfg.bulk_in = USBD1_DATA_REQUEST_EP; - serusbcfg.bulk_out = USBD1_DATA_AVAILABLE_EP; - serusbcfg.int_in = USBD1_INTERRUPT_REQUEST_EP; + serusbcfg1.usbp = &SERIAL_USB; + serusbcfg1.bulk_in = USBD1_DATA_REQUEST_EP; + serusbcfg1.bulk_out = USBD1_DATA_AVAILABLE_EP; + serusbcfg1.int_in = USBD1_INTERRUPT_REQUEST_EP; +#if USBD_NUMBER >= 2 + serusbcfg2.usbp = &SERIAL_USB; + serusbcfg2.bulk_in = USBD2_DATA_REQUEST_EP; + serusbcfg2.bulk_out = USBD2_DATA_AVAILABLE_EP; + serusbcfg2.int_in = USBD2_INTERRUPT_REQUEST_EP; +#endif - sduObjectInit(&SDU); - sduStart(&SDU, &serusbcfg); + sduObjectInit(&SDU1); + sduStart(&SDU1, &serusbcfg1); +#if USBD_NUMBER >= 2 + sduObjectInit(&SDU2); + sduStart(&SDU2, &serusbcfg2); +#endif - usbDisconnectBus(serusbcfg.usbp); + usbDisconnectBus(serusbcfg1.usbp); chThdSleepMilliseconds(1000); - usbStart(serusbcfg.usbp, &usbcfg); - usbConnectBus(serusbcfg.usbp); + usbStart(serusbcfg1.usbp, &usbcfg); + usbConnectBus(serusbcfg1.usbp); - chEvtRegisterMask(chnGetEventSource(&SDU), &inputAvailEL, CHN_INPUT_AVAILABLE); + chEvtRegisterMask(chnGetEventSource(&SDU1), &inputAvailEL, CHN_INPUT_AVAILABLE); usb_serial.nb_bytes = 0; usb_serial.rx_read_idx = 0; - usb_serial.reg_addr = &SDU; + usb_serial.reg_addr = &SDU1; // Configure generic device usb_serial.device.periph = (void *)(&usb_serial); usb_serial.device.check_free_space = (check_free_space_t) usb_serial_check_free_space; @@ -504,6 +719,20 @@ void VCOM_init() usb_serial.device.char_available = (char_available_t) usb_serial_char_available; usb_serial.device.get_byte = (get_byte_t) usb_serial_getch; + +#if USBD_NUMBER >= 2 + usb_serial_debug.nb_bytes = 0; + usb_serial_debug.rx_read_idx = 0; + usb_serial_debug.reg_addr = &SDU2; + // Configure generic device + usb_serial_debug.device.periph = (void *)(&usb_serial_debug); + usb_serial_debug.device.check_free_space = (check_free_space_t) usb_serial_check_free_space; + usb_serial_debug.device.put_byte = (put_byte_t) usb_serial_transmit; + usb_serial_debug.device.put_buffer = (put_buffer_t) usb_serial_transmit_buffer; + usb_serial_debug.device.send_message = (send_message_t) usb_serial_send; + usb_serial_debug.device.char_available = (char_available_t) usb_serial_char_available; + usb_serial_debug.device.get_byte = (get_byte_t) usb_serial_getch; +#endif } @@ -511,7 +740,7 @@ int VCOM_putchar(int c) { if(!isUsbConnected()) { return -1; } - streamPut(&SDU, c); + streamPut((SerialUSBDriver*)(usb_serial.reg_addr), c); return c; } diff --git a/sw/airborne/boards/lia/chibios/v1.1/mcuconf.h b/sw/airborne/boards/lia/chibios/v1.1/mcuconf.h index 98957d8d5a..42e603ecd3 100644 --- a/sw/airborne/boards/lia/chibios/v1.1/mcuconf.h +++ b/sw/airborne/boards/lia/chibios/v1.1/mcuconf.h @@ -262,7 +262,7 @@ /* * USB driver system settings. */ -#if USE_USB_SERIAL +#if USE_USB_SERIAL || USE_USB_SERIAL_DEBUG #define STM32_USB_USE_OTG1 TRUE #else #define STM32_USB_USE_OTG1 FALSE diff --git a/sw/airborne/boards/lisa_mx/chibios/v2.1/mcuconf.h b/sw/airborne/boards/lisa_mx/chibios/v2.1/mcuconf.h index dcf313a4aa..04a384b491 100644 --- a/sw/airborne/boards/lisa_mx/chibios/v2.1/mcuconf.h +++ b/sw/airborne/boards/lisa_mx/chibios/v2.1/mcuconf.h @@ -427,7 +427,7 @@ /* * USB driver system settings. */ -#if USE_USB_SERIAL +#if USE_USB_SERIAL || USE_USB_SERIAL_DEBUG #define STM32_USB_USE_OTG1 TRUE #else #define STM32_USB_USE_OTG1 FALSE diff --git a/sw/airborne/boards/lisa_mxs/chibios/v1.0/mcuconf.h b/sw/airborne/boards/lisa_mxs/chibios/v1.0/mcuconf.h index dcf313a4aa..04a384b491 100644 --- a/sw/airborne/boards/lisa_mxs/chibios/v1.0/mcuconf.h +++ b/sw/airborne/boards/lisa_mxs/chibios/v1.0/mcuconf.h @@ -427,7 +427,7 @@ /* * USB driver system settings. */ -#if USE_USB_SERIAL +#if USE_USB_SERIAL || USE_USB_SERIAL_DEBUG #define STM32_USB_USE_OTG1 TRUE #else #define STM32_USB_USE_OTG1 FALSE diff --git a/sw/airborne/mcu.c b/sw/airborne/mcu.c index ed25973034..34b2bbce13 100644 --- a/sw/airborne/mcu.c +++ b/sw/airborne/mcu.c @@ -54,7 +54,8 @@ #if USE_ADC #include "mcu_periph/adc.h" #endif -#if USE_USB_SERIAL +#if USE_USB_SERIAL || USE_USB_SERIAL_DEBUG +#define USING_USB_SERIAL 1 #include "mcu_periph/usb_serial.h" #endif #ifdef USE_UDP @@ -197,7 +198,7 @@ void mcu_init(void) #if USE_ADC adc_init(); #endif -#if USE_USB_SERIAL +#if USING_USB_SERIAL VCOM_init(); #endif @@ -272,7 +273,7 @@ void mcu_event(void) softi2c_event(); #endif -#if USE_USB_SERIAL +#if USING_USB_SERIAL VCOM_event(); #endif } diff --git a/sw/airborne/mcu_periph/usb_serial.h b/sw/airborne/mcu_periph/usb_serial.h index 8ca12a5755..e0ff8b8113 100644 --- a/sw/airborne/mcu_periph/usb_serial.h +++ b/sw/airborne/mcu_periph/usb_serial.h @@ -32,11 +32,22 @@ #include "std.h" #include "pprzlink/pprzlink_device.h" #include "mcu_periph/uart.h" +#include "mcu_arch.h" #ifndef USB_RX_BUFFER_SIZE #define USB_RX_BUFFER_SIZE UART_RX_BUFFER_SIZE #endif +#ifdef USB_MAX_ENDPOINTS +#if USB_MAX_ENDPOINTS < 4 +#define USBD_NUMBER 1 +#else +#define USBD_NUMBER 2 +#endif +#else +#define USBD_NUMBER 1 +#endif + struct usb_serial_periph { /** Receive buffer */ uint8_t rx_buf[USB_RX_BUFFER_SIZE]; @@ -49,6 +60,9 @@ struct usb_serial_periph { }; extern struct usb_serial_periph usb_serial; +#if USBD_NUMBER >= 2 +extern struct usb_serial_periph usb_serial_debug; +#endif void VCOM_init(void); int VCOM_putchar(int c); diff --git a/sw/airborne/modules/datalink/extra_pprz_dl.h b/sw/airborne/modules/datalink/extra_pprz_dl.h index ce26c3fe5e..98addce048 100644 --- a/sw/airborne/modules/datalink/extra_pprz_dl.h +++ b/sw/airborne/modules/datalink/extra_pprz_dl.h @@ -34,7 +34,7 @@ #include "mcu_periph/udp.h" #endif -#if USE_USB_SERIAL +#if USE_USB_SERIAL || USE_USB_SERIAL_DEBUG #include "mcu_periph/usb_serial.h" #endif diff --git a/sw/airborne/modules/datalink/gec_dl.h b/sw/airborne/modules/datalink/gec_dl.h index 257167216d..b8cf43790c 100644 --- a/sw/airborne/modules/datalink/gec_dl.h +++ b/sw/airborne/modules/datalink/gec_dl.h @@ -32,7 +32,7 @@ #include "pprz_mutex.h" #include "mcu_periph/uart.h" -#if USE_USB_SERIAL +#if USE_USB_SERIAL || USE_USB_SERIAL_DEBUG #include "mcu_periph/usb_serial.h" #endif #if USE_UDP diff --git a/sw/airborne/modules/datalink/mavlink.h b/sw/airborne/modules/datalink/mavlink.h index 257db8b6a7..23495458e5 100644 --- a/sw/airborne/modules/datalink/mavlink.h +++ b/sw/airborne/modules/datalink/mavlink.h @@ -35,7 +35,7 @@ #if USE_UDP #include "mcu_periph/udp.h" #endif -#if USE_USB_SERIAL +#if USE_USB_SERIAL || USE_USB_SERIAL_DEBUG #include "mcu_periph/usb_serial.h" #endif #include "mcu_periph/uart.h" diff --git a/sw/airborne/modules/datalink/pprz_dl.h b/sw/airborne/modules/datalink/pprz_dl.h index 40a8f2f60c..b3ea8bf8a7 100644 --- a/sw/airborne/modules/datalink/pprz_dl.h +++ b/sw/airborne/modules/datalink/pprz_dl.h @@ -29,7 +29,7 @@ #include "pprzlink/pprz_transport.h" #include "mcu_periph/uart.h" -#if USE_USB_SERIAL +#if USE_USB_SERIAL || USE_USB_SERIAL_DEBUG #include "mcu_periph/usb_serial.h" #endif #if USE_FRSKY_X_SERIAL diff --git a/sw/airborne/modules/loggers/sdlog_chibios/usbStorage.c b/sw/airborne/modules/loggers/sdlog_chibios/usbStorage.c index 57bfca53b7..a6f33f510d 100644 --- a/sw/airborne/modules/loggers/sdlog_chibios/usbStorage.c +++ b/sw/airborne/modules/loggers/sdlog_chibios/usbStorage.c @@ -165,8 +165,13 @@ bool usbStorageIsItRunning(void) return isRunning; } +/* + * Enable USB storage only if USB is plugged. + */ void usbStorage_enable_usb_storage(float e) { - if(e > 0.5) { + if(e > 0.5 && palReadPad(SDLOG_USB_VBUS_PORT, SDLOG_USB_VBUS_PIN) == PAL_HIGH) { chBSemSignal(&bs_start_msd); + } else { + usb_storage_status = 0; } } diff --git a/sw/airborne/modules/loggers/sdlog_chibios/usb_msd.c b/sw/airborne/modules/loggers/sdlog_chibios/usb_msd.c index 350b4ff679..98790ceae2 100644 --- a/sw/airborne/modules/loggers/sdlog_chibios/usb_msd.c +++ b/sw/airborne/modules/loggers/sdlog_chibios/usb_msd.c @@ -1125,6 +1125,9 @@ void deinit_msd_driver(void) void init_msd_driver(void *dbgThreadPtr, USBMassStorageConfig *msdConfig) { + usbStop(&USBD); + usbDisconnectBus(&USBD); + msdInit(&UMSD); /* start the USB mass storage service */ msdStart(&UMSD, msdConfig); @@ -1134,7 +1137,6 @@ void init_msd_driver(void *dbgThreadPtr, USBMassStorageConfig *msdConfig) /* start the USB driver */ usbDisconnectBus(&USBD); chThdSleepMilliseconds(1000); - usbStop(&USBD); usbStart(&USBD, &usbConfig); usbConnectBus(&USBD); }