diff options
author | Nikolay Minaylov <nm29719@gmail.com> | 2021-10-06 12:24:09 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-10-06 12:24:09 +0300 |
commit | e0c1928fde94387f0fc819eda16004c68ce164a6 (patch) | |
tree | cd8dbf3e37d3fffa5d06c3f2108a9914004b4620 /firmware | |
parent | 42e553bad525a0ae159a4c4814267d5cca3ae5d8 (diff) |
[FL-1857] New USB stack (#735)
* libusb_stm32 USB stack test
* USB: Add dual CDC mode
* USB HID demo, added libusb_stm32 as submodule
* Target F6/F7: remomve unused ll_usb
Co-authored-by: n.minaylov <n.minaylov@flipperdevices.com>
Co-authored-by: Aleksandr Kutuzov <alleteam@gmail.com>
Diffstat (limited to 'firmware')
43 files changed, 2263 insertions, 2120 deletions
diff --git a/firmware/targets/f6/Inc/stm32.h b/firmware/targets/f6/Inc/stm32.h new file mode 100644 index 00000000..45344fe3 --- /dev/null +++ b/firmware/targets/f6/Inc/stm32.h @@ -0,0 +1,52 @@ +#ifndef _STM32_H_ +#define _STM32_H_ + +/* modify bitfield */ +#define _BMD(reg, msk, val) (reg) = (((reg) & ~(msk)) | (val)) +/* set bitfield */ +#define _BST(reg, bits) (reg) = ((reg) | (bits)) +/* clear bitfield */ +#define _BCL(reg, bits) (reg) = ((reg) & ~(bits)) +/* wait until bitfield set */ +#define _WBS(reg, bits) while(((reg) & (bits)) == 0) +/* wait until bitfield clear */ +#define _WBC(reg, bits) while(((reg) & (bits)) != 0) +/* wait for bitfield value */ +#define _WVL(reg, msk, val) while(((reg) & (msk)) != (val)) +/* bit value */ +#define _BV(bit) (0x01 << (bit)) + +#if defined(STM32F0) + #include "STM32F0xx/Include/stm32f0xx.h" +#elif defined(STM32F1) + #include "STM32F1xx/Include/stm32f1xx.h" +#elif defined(STM32F2) + #include "STM32F2xx/Include/stm32f2xx.h" +#elif defined(STM32F3) + #include "STM32F3xx/Include/stm32f3xx.h" +#elif defined(STM32F4) + #include "STM32F4xx/Include/stm32f4xx.h" +#elif defined(STM32F7) + #include "STM32F7xx/Include/stm32f7xx.h" +#elif defined(STM32H7) + #include "STM32H7xx/Include/stm32h7xx.h" +#elif defined(STM32L0) + #include "STM32L0xx/Include/stm32l0xx.h" +#elif defined(STM32L1) + #include "STM32L1xx/Include/stm32l1xx.h" +#elif defined(STM32L4) + #include "STM32L4xx/Include/stm32l4xx.h" +#elif defined(STM32L5) + #include "STM32L5xx/Include/stm32l5xx.h" +#elif defined(STM32G0) + #include "STM32G0xx/Include/stm32g0xx.h" +#elif defined(STM32G4) + #include "STM32G4xx/Include/stm32g4xx.h" +#elif defined(STM32WB) + #include "STM32WBxx/Include/stm32wbxx.h" +#else + #error "STM32 family not defined" +#endif + + +#endif // _STM32_H_ diff --git a/firmware/targets/f6/Src/stm32wbxx_it.c b/firmware/targets/f6/Src/stm32wbxx_it.c index 01fbdc1d..6f70fb5e 100644 --- a/firmware/targets/f6/Src/stm32wbxx_it.c +++ b/firmware/targets/f6/Src/stm32wbxx_it.c @@ -2,8 +2,9 @@ #include "stm32wbxx_it.h"
#include "FreeRTOS.h"
#include "task.h"
+#include "usbd_core.h"
-extern PCD_HandleTypeDef hpcd_USB_FS;
+extern usbd_device udev;
extern COMP_HandleTypeDef hcomp1;
extern RTC_HandleTypeDef hrtc;
extern TIM_HandleTypeDef htim1;
@@ -20,7 +21,7 @@ void SysTick_Handler(void) { }
void USB_LP_IRQHandler(void) {
- HAL_PCD_IRQHandler(&hpcd_USB_FS);
+ usbd_poll(&udev);
}
void COMP_IRQHandler(void) {
diff --git a/firmware/targets/f6/furi-hal/furi-hal-usb-cdc.c b/firmware/targets/f6/furi-hal/furi-hal-usb-cdc.c new file mode 100644 index 00000000..09efbec3 --- /dev/null +++ b/firmware/targets/f6/furi-hal/furi-hal-usb-cdc.c @@ -0,0 +1,555 @@ +#include "furi-hal-version.h" +#include "furi-hal-usb_i.h" +#include "furi-hal-vcp_i.h" +#include "furi-hal-usb-cdc_i.h" +#include <furi.h> + +#include "usb.h" +#include "usb_cdc.h" + +#define CDC0_RXD_EP 0x01 +#define CDC0_TXD_EP 0x82 +#define CDC0_NTF_EP 0x83 + +#define CDC1_RXD_EP 0x04 +#define CDC1_TXD_EP 0x85 +#define CDC1_NTF_EP 0x86 + +#define CDC_NTF_SZ 0x08 + +struct CdcIadDescriptor { + struct usb_iad_descriptor comm_iad; + struct usb_interface_descriptor comm; + struct usb_cdc_header_desc cdc_hdr; + struct usb_cdc_call_mgmt_desc cdc_mgmt; + struct usb_cdc_acm_desc cdc_acm; + struct usb_cdc_union_desc cdc_union; + struct usb_endpoint_descriptor comm_ep; + struct usb_interface_descriptor data; + struct usb_endpoint_descriptor data_eprx; + struct usb_endpoint_descriptor data_eptx; +}; + +struct CdcConfigDescriptorSingle { + struct usb_config_descriptor config; + struct CdcIadDescriptor iad_0; +} __attribute__((packed)); + +struct CdcConfigDescriptorDual { + struct usb_config_descriptor config; + struct CdcIadDescriptor iad_0; + struct CdcIadDescriptor iad_1; +} __attribute__((packed)); + +static const struct usb_string_descriptor dev_manuf_desc = USB_STRING_DESC("Flipper Devices Inc."); + +/* Device descriptor */ +static const struct usb_device_descriptor cdc_device_desc = { + .bLength = sizeof(struct usb_device_descriptor), + .bDescriptorType = USB_DTYPE_DEVICE, + .bcdUSB = VERSION_BCD(2,0,0), + .bDeviceClass = USB_CLASS_IAD, + .bDeviceSubClass = USB_SUBCLASS_IAD, + .bDeviceProtocol = USB_PROTO_IAD, + .bMaxPacketSize0 = USB_EP0_SIZE, + .idVendor = 0x0483, + .idProduct = 0x5740, + .bcdDevice = VERSION_BCD(1,0,0), + .iManufacturer = UsbDevManuf, + .iProduct = UsbDevProduct, + .iSerialNumber = UsbDevSerial, + .bNumConfigurations = 1, +}; + +/* Device configuration descriptor - single mode*/ +static const struct CdcConfigDescriptorSingle cdc_cfg_desc_single = { + .config = { + .bLength = sizeof(struct usb_config_descriptor), + .bDescriptorType = USB_DTYPE_CONFIGURATION, + .wTotalLength = sizeof(struct CdcConfigDescriptorSingle), + .bNumInterfaces = 2, + + .bConfigurationValue = 1, + .iConfiguration = NO_DESCRIPTOR, + .bmAttributes = USB_CFG_ATTR_RESERVED | USB_CFG_ATTR_SELFPOWERED, + .bMaxPower = USB_CFG_POWER_MA(100), + }, + .iad_0 = { + .comm_iad = { + .bLength = sizeof(struct usb_iad_descriptor), + .bDescriptorType = USB_DTYPE_INTERFASEASSOC, + .bFirstInterface = 0, + .bInterfaceCount = 2, + .bFunctionClass = USB_CLASS_CDC, + .bFunctionSubClass = USB_CDC_SUBCLASS_ACM, + .bFunctionProtocol = USB_PROTO_NONE, + .iFunction = NO_DESCRIPTOR, + }, + .comm = { + .bLength = sizeof(struct usb_interface_descriptor), + .bDescriptorType = USB_DTYPE_INTERFACE, + .bInterfaceNumber = 0, + .bAlternateSetting = 0, + .bNumEndpoints = 1, + .bInterfaceClass = USB_CLASS_CDC, + .bInterfaceSubClass = USB_CDC_SUBCLASS_ACM, + .bInterfaceProtocol = USB_PROTO_NONE, + .iInterface = NO_DESCRIPTOR, + }, + .cdc_hdr = { + .bFunctionLength = sizeof(struct usb_cdc_header_desc), + .bDescriptorType = USB_DTYPE_CS_INTERFACE, + .bDescriptorSubType = USB_DTYPE_CDC_HEADER, + .bcdCDC = VERSION_BCD(1,1,0), + }, + .cdc_mgmt = { + .bFunctionLength = sizeof(struct usb_cdc_call_mgmt_desc), + .bDescriptorType = USB_DTYPE_CS_INTERFACE, + .bDescriptorSubType = USB_DTYPE_CDC_CALL_MANAGEMENT, + .bmCapabilities = 0, + .bDataInterface = 1, + }, + .cdc_acm = { + .bFunctionLength = sizeof(struct usb_cdc_acm_desc), + .bDescriptorType = USB_DTYPE_CS_INTERFACE, + .bDescriptorSubType = USB_DTYPE_CDC_ACM, + .bmCapabilities = 0, + }, + .cdc_union = { + .bFunctionLength = sizeof(struct usb_cdc_union_desc), + .bDescriptorType = USB_DTYPE_CS_INTERFACE, + .bDescriptorSubType = USB_DTYPE_CDC_UNION, + .bMasterInterface0 = 0, + .bSlaveInterface0 = 1, + }, + .comm_ep = { + .bLength = sizeof(struct usb_endpoint_descriptor), + .bDescriptorType = USB_DTYPE_ENDPOINT, + .bEndpointAddress = CDC0_NTF_EP, + .bmAttributes = USB_EPTYPE_INTERRUPT, + .wMaxPacketSize = CDC_NTF_SZ, + .bInterval = 0xFF, + }, + .data = { + .bLength = sizeof(struct usb_interface_descriptor), + .bDescriptorType = USB_DTYPE_INTERFACE, + .bInterfaceNumber = 1, + .bAlternateSetting = 0, + .bNumEndpoints = 2, + .bInterfaceClass = USB_CLASS_CDC_DATA, + .bInterfaceSubClass = USB_SUBCLASS_NONE, + .bInterfaceProtocol = USB_PROTO_NONE, + .iInterface = NO_DESCRIPTOR, + }, + .data_eprx = { + .bLength = sizeof(struct usb_endpoint_descriptor), + .bDescriptorType = USB_DTYPE_ENDPOINT, + .bEndpointAddress = CDC0_RXD_EP, + .bmAttributes = USB_EPTYPE_BULK, + .wMaxPacketSize = CDC_DATA_SZ, + .bInterval = 0x01, + }, + .data_eptx = { + .bLength = sizeof(struct usb_endpoint_descriptor), + .bDescriptorType = USB_DTYPE_ENDPOINT, + .bEndpointAddress = CDC0_TXD_EP, + .bmAttributes = USB_EPTYPE_BULK, + .wMaxPacketSize = CDC_DATA_SZ, + .bInterval = 0x01, + }, + }, +}; + +/* Device configuration descriptor - dual mode*/ +static const struct CdcConfigDescriptorDual cdc_cfg_desc_dual = { + .config = { + .bLength = sizeof(struct usb_config_descriptor), + .bDescriptorType = USB_DTYPE_CONFIGURATION, + .wTotalLength = sizeof(struct CdcConfigDescriptorDual), + .bNumInterfaces = 4, + + .bConfigurationValue = 1, + .iConfiguration = NO_DESCRIPTOR, + .bmAttributes = USB_CFG_ATTR_RESERVED | USB_CFG_ATTR_SELFPOWERED, + .bMaxPower = USB_CFG_POWER_MA(100), + }, + .iad_0 = { + .comm_iad = { + .bLength = sizeof(struct usb_iad_descriptor), + .bDescriptorType = USB_DTYPE_INTERFASEASSOC, + .bFirstInterface = 0, + .bInterfaceCount = 2, + .bFunctionClass = USB_CLASS_CDC, + .bFunctionSubClass = USB_CDC_SUBCLASS_ACM, + .bFunctionProtocol = USB_PROTO_NONE, + .iFunction = NO_DESCRIPTOR, + }, + .comm = { + .bLength = sizeof(struct usb_interface_descriptor), + .bDescriptorType = USB_DTYPE_INTERFACE, + .bInterfaceNumber = 0, + .bAlternateSetting = 0, + .bNumEndpoints = 1, + .bInterfaceClass = USB_CLASS_CDC, + .bInterfaceSubClass = USB_CDC_SUBCLASS_ACM, + .bInterfaceProtocol = USB_PROTO_NONE, + .iInterface = NO_DESCRIPTOR, + }, + .cdc_hdr = { + .bFunctionLength = sizeof(struct usb_cdc_header_desc), + .bDescriptorType = USB_DTYPE_CS_INTERFACE, + .bDescriptorSubType = USB_DTYPE_CDC_HEADER, + .bcdCDC = VERSION_BCD(1,1,0), + }, + .cdc_mgmt = { + .bFunctionLength = sizeof(struct usb_cdc_call_mgmt_desc), + .bDescriptorType = USB_DTYPE_CS_INTERFACE, + .bDescriptorSubType = USB_DTYPE_CDC_CALL_MANAGEMENT, + .bmCapabilities = 0, + .bDataInterface = 1, + }, + .cdc_acm = { + .bFunctionLength = sizeof(struct usb_cdc_acm_desc), + .bDescriptorType = USB_DTYPE_CS_INTERFACE, + .bDescriptorSubType = USB_DTYPE_CDC_ACM, + .bmCapabilities = 0, + }, + .cdc_union = { + .bFunctionLength = sizeof(struct usb_cdc_union_desc), + .bDescriptorType = USB_DTYPE_CS_INTERFACE, + .bDescriptorSubType = USB_DTYPE_CDC_UNION, + .bMasterInterface0 = 0, + .bSlaveInterface0 = 1, + }, + .comm_ep = { + .bLength = sizeof(struct usb_endpoint_descriptor), + .bDescriptorType = USB_DTYPE_ENDPOINT, + .bEndpointAddress = CDC0_NTF_EP, + .bmAttributes = USB_EPTYPE_INTERRUPT, + .wMaxPacketSize = CDC_NTF_SZ, + .bInterval = 0xFF, + }, + .data = { + .bLength = sizeof(struct usb_interface_descriptor), + .bDescriptorType = USB_DTYPE_INTERFACE, + .bInterfaceNumber = 1, + .bAlternateSetting = 0, + .bNumEndpoints = 2, + .bInterfaceClass = USB_CLASS_CDC_DATA, + .bInterfaceSubClass = USB_SUBCLASS_NONE, + .bInterfaceProtocol = USB_PROTO_NONE, + .iInterface = NO_DESCRIPTOR, + }, + .data_eprx = { + .bLength = sizeof(struct usb_endpoint_descriptor), + .bDescriptorType = USB_DTYPE_ENDPOINT, + .bEndpointAddress = CDC0_RXD_EP, + .bmAttributes = USB_EPTYPE_BULK, + .wMaxPacketSize = CDC_DATA_SZ, + .bInterval = 0x01, + }, + .data_eptx = { + .bLength = sizeof(struct usb_endpoint_descriptor), + .bDescriptorType = USB_DTYPE_ENDPOINT, + .bEndpointAddress = CDC0_TXD_EP, + .bmAttributes = USB_EPTYPE_BULK, + .wMaxPacketSize = CDC_DATA_SZ, + .bInterval = 0x01, + }, + }, + .iad_1 = { + .comm_iad = { + .bLength = sizeof(struct usb_iad_descriptor), + .bDescriptorType = USB_DTYPE_INTERFASEASSOC, + .bFirstInterface = 2, + .bInterfaceCount = 2, + .bFunctionClass = USB_CLASS_CDC, + .bFunctionSubClass = USB_CDC_SUBCLASS_ACM, + .bFunctionProtocol = USB_PROTO_NONE, + .iFunction = NO_DESCRIPTOR, + }, + .comm = { + .bLength = sizeof(struct usb_interface_descriptor), + .bDescriptorType = USB_DTYPE_INTERFACE, + .bInterfaceNumber = 2+0, + .bAlternateSetting = 0, + .bNumEndpoints = 1, + .bInterfaceClass = USB_CLASS_CDC, + .bInterfaceSubClass = USB_CDC_SUBCLASS_ACM, + .bInterfaceProtocol = USB_PROTO_NONE, + .iInterface = NO_DESCRIPTOR, + }, + .cdc_hdr = { + .bFunctionLength = sizeof(struct usb_cdc_header_desc), + .bDescriptorType = USB_DTYPE_CS_INTERFACE, + .bDescriptorSubType = USB_DTYPE_CDC_HEADER, + .bcdCDC = VERSION_BCD(1,1,0), + }, + .cdc_mgmt = { + .bFunctionLength = sizeof(struct usb_cdc_call_mgmt_desc), + .bDescriptorType = USB_DTYPE_CS_INTERFACE, + .bDescriptorSubType = USB_DTYPE_CDC_CALL_MANAGEMENT, + .bmCapabilities = 0, + .bDataInterface = 2+1, + }, + .cdc_acm = { + .bFunctionLength = sizeof(struct usb_cdc_acm_desc), + .bDescriptorType = USB_DTYPE_CS_INTERFACE, + .bDescriptorSubType = USB_DTYPE_CDC_ACM, + .bmCapabilities = 0, + }, + .cdc_union = { + .bFunctionLength = sizeof(struct usb_cdc_union_desc), + .bDescriptorType = USB_DTYPE_CS_INTERFACE, + .bDescriptorSubType = USB_DTYPE_CDC_UNION, + .bMasterInterface0 = 2+0, + .bSlaveInterface0 = 2+1, + }, + .comm_ep = { + .bLength = sizeof(struct usb_endpoint_descriptor), + .bDescriptorType = USB_DTYPE_ENDPOINT, + .bEndpointAddress = CDC1_NTF_EP, + .bmAttributes = USB_EPTYPE_INTERRUPT, + .wMaxPacketSize = CDC_NTF_SZ, + .bInterval = 0xFF, + }, + .data = { + .bLength = sizeof(struct usb_interface_descriptor), + .bDescriptorType = USB_DTYPE_INTERFACE, + .bInterfaceNumber = 2+1, + .bAlternateSetting = 0, + .bNumEndpoints = 2, + .bInterfaceClass = USB_CLASS_CDC_DATA, + .bInterfaceSubClass = USB_SUBCLASS_NONE, + .bInterfaceProtocol = USB_PROTO_NONE, + .iInterface = NO_DESCRIPTOR, + }, + .data_eprx = { + .bLength = sizeof(struct usb_endpoint_descriptor), + .bDescriptorType = USB_DTYPE_ENDPOINT, + .bEndpointAddress = CDC1_RXD_EP, + .bmAttributes = USB_EPTYPE_BULK, + .wMaxPacketSize = CDC_DATA_SZ, + .bInterval = 0x01, + }, + .data_eptx = { + .bLength = sizeof(struct usb_endpoint_descriptor), + .bDescriptorType = USB_DTYPE_ENDPOINT, + .bEndpointAddress = CDC1_TXD_EP, + .bmAttributes = USB_EPTYPE_BULK, + .wMaxPacketSize = CDC_DATA_SZ, + .bInterval = 0x01, + }, + }, +}; + +static struct usb_cdc_line_coding cdc_line = { + .dwDTERate = 38400, + .bCharFormat = USB_CDC_1_STOP_BITS, + .bParityType = USB_CDC_NO_PARITY, + .bDataBits = 8, +}; +static void cdc_init(usbd_device* dev, struct UsbInterface* intf); +static void cdc_deinit(usbd_device *dev); +static void cdc_on_wakeup(usbd_device *dev); +static void cdc_on_suspend(usbd_device *dev); + +static usbd_respond cdc_ep_config (usbd_device *dev, uint8_t cfg); +static usbd_respond cdc_control (usbd_device *dev, usbd_ctlreq *req, usbd_rqc_callback *callback); +static usbd_device* usb_dev; +static struct UsbInterface* cdc_if_cur = NULL; + +struct UsbInterface usb_cdc_single = { + .init = cdc_init, + .deinit = cdc_deinit, + .wakeup = cdc_on_wakeup, + .suspend = cdc_on_suspend, + + .dev_descr = (struct usb_device_descriptor*)&cdc_device_desc, + + .str_manuf_descr = (void*)&dev_manuf_desc, + .str_prod_descr = NULL, + .str_serial_descr = NULL, + + .cfg_descr = (void*)&cdc_cfg_desc_single, +}; + +struct UsbInterface usb_cdc_dual = { + .init = cdc_init, + .deinit = cdc_deinit, + .wakeup = cdc_on_wakeup, + .suspend = cdc_on_suspend, + + .dev_descr = (struct usb_device_descriptor*)&cdc_device_desc, + + .str_manuf_descr = (void*)&dev_manuf_desc, + .str_prod_descr = NULL, + .str_serial_descr = NULL, + + .cfg_descr = (void*)&cdc_cfg_desc_dual, +}; + +static void cdc_init(usbd_device* dev, struct UsbInterface* intf) { + usb_dev = dev; + cdc_if_cur = intf; + + char* name = (char*)furi_hal_version_get_device_name_ptr(); + uint8_t len = (name == NULL) ? (0) : (strlen(name)); + struct usb_string_descriptor* dev_prod_desc = furi_alloc(len * 2 + 2); + dev_prod_desc->bLength = len * 2 + 2; + dev_prod_desc->bDescriptorType = USB_DTYPE_STRING; + for (uint8_t i = 0; i < len; i++) + dev_prod_desc->wString[i] = name[i]; + + name = (char*)furi_hal_version_get_name_ptr(); + len = (name == NULL) ? (0) : (strlen(name)); + struct usb_string_descriptor* dev_serial_desc = furi_alloc((len + 5) * 2 + 2); + dev_serial_desc->bLength = (len + 5) * 2 + 2; + dev_serial_desc->bDescriptorType = USB_DTYPE_STRING; + memcpy(dev_serial_desc->wString, "f\0l\0i\0p\0_\0", 5*2); + for (uint8_t i = 0; i < len; i++) + dev_serial_desc->wString[i+5] = name[i]; + + cdc_if_cur->str_prod_descr = dev_prod_desc; + cdc_if_cur->str_serial_descr = dev_serial_desc; + + usbd_reg_config(dev, cdc_ep_config); + usbd_reg_control(dev, cdc_control); + + usbd_connect(dev, true); +} + +static void cdc_deinit(usbd_device *dev) { + usbd_reg_config(dev, NULL); + usbd_reg_control(dev, NULL); + + free(cdc_if_cur->str_prod_descr); + free(cdc_if_cur->str_serial_descr); + + cdc_if_cur = NULL; +} + +void furi_hal_cdc_send(uint8_t if_num, uint8_t* buf, uint16_t len) { + if (if_num == 0) + usbd_ep_write(usb_dev, CDC0_TXD_EP, buf, len); + else + usbd_ep_write(usb_dev, CDC1_TXD_EP, buf, len); +} + +int32_t furi_hal_cdc_receive(uint8_t if_num, uint8_t* buf, uint16_t max_len) { + if (if_num == 0) + return usbd_ep_read(usb_dev, CDC0_RXD_EP, buf, max_len); + else + return usbd_ep_read(usb_dev, CDC1_RXD_EP, buf, max_len); +} + +static void cdc_on_wakeup(usbd_device *dev) { + furi_hal_vcp_on_usb_resume(); +} + +static void cdc_on_suspend(usbd_device *dev) { + furi_hal_vcp_on_usb_suspend(); +} + +static void cdc_rx_ep_callback (usbd_device *dev, uint8_t event, uint8_t ep) { + if (ep == CDC0_RXD_EP) + furi_hal_vcp_on_cdc_rx(0); + else + furi_hal_vcp_on_cdc_rx(1); +} + +static void cdc_tx_ep_callback (usbd_device *dev, uint8_t event, uint8_t ep) { + if (ep == CDC0_TXD_EP) + furi_hal_vcp_on_cdc_tx_complete(0); + else + furi_hal_vcp_on_cdc_tx_complete(1); +} + +static void cdc_txrx_ep_callback (usbd_device *dev, uint8_t event, uint8_t ep) { + if (event == usbd_evt_eptx) { + cdc_tx_ep_callback(dev, event, ep); + } else { + cdc_rx_ep_callback(dev, event, ep); + } +} + +/* Configure endpoints */ +static usbd_respond cdc_ep_config (usbd_device *dev, uint8_t cfg) { + uint8_t if_cnt = ((struct usb_config_descriptor*)(cdc_if_cur->cfg_descr))->bNumInterfaces; + switch (cfg) { + case 0: + /* deconfiguring device */ + usbd_ep_deconfig(dev, CDC0_NTF_EP); + usbd_ep_deconfig(dev, CDC0_TXD_EP); + usbd_ep_deconfig(dev, CDC0_RXD_EP); + usbd_reg_endpoint(dev, CDC0_RXD_EP, 0); + usbd_reg_endpoint(dev, CDC0_TXD_EP, 0); + if (if_cnt == 4) { + usbd_ep_deconfig(dev, CDC1_NTF_EP); + usbd_ep_deconfig(dev, CDC1_TXD_EP); + usbd_ep_deconfig(dev, CDC1_RXD_EP); + usbd_reg_endpoint(dev, CDC1_RXD_EP, 0); + usbd_reg_endpoint(dev, CDC1_TXD_EP, 0); + } + return usbd_ack; + case 1: + /* configuring device */ + if ((CDC0_TXD_EP & 0x7F) != (CDC0_RXD_EP & 0x7F)) { + usbd_ep_config(dev, CDC0_RXD_EP, USB_EPTYPE_BULK | USB_EPTYPE_DBLBUF, CDC_DATA_SZ); + usbd_ep_config(dev, CDC0_TXD_EP, USB_EPTYPE_BULK | USB_EPTYPE_DBLBUF, CDC_DATA_SZ); + usbd_ep_config(dev, CDC0_NTF_EP, USB_EPTYPE_INTERRUPT, CDC_NTF_SZ); + usbd_reg_endpoint(dev, CDC0_RXD_EP, cdc_rx_ep_callback); + usbd_reg_endpoint(dev, CDC0_TXD_EP, cdc_tx_ep_callback); + } else { + usbd_ep_config(dev, CDC0_RXD_EP, USB_EPTYPE_BULK, CDC_DATA_SZ); + usbd_ep_config(dev, CDC0_TXD_EP, USB_EPTYPE_BULK, CDC_DATA_SZ); + usbd_ep_config(dev, CDC0_NTF_EP, USB_EPTYPE_INTERRUPT, CDC_NTF_SZ); + usbd_reg_endpoint(dev, CDC0_RXD_EP, cdc_txrx_ep_callback); + usbd_reg_endpoint(dev, CDC0_TXD_EP, cdc_txrx_ep_callback); + } + usbd_ep_write(dev, CDC0_TXD_EP, 0, 0); + + if (if_cnt == 4) { + if ((CDC1_TXD_EP & 0x7F) != (CDC1_RXD_EP & 0x7F)) { + usbd_ep_config(dev, CDC1_RXD_EP, USB_EPTYPE_BULK | USB_EPTYPE_DBLBUF, CDC_DATA_SZ); + usbd_ep_config(dev, CDC1_TXD_EP, USB_EPTYPE_BULK | USB_EPTYPE_DBLBUF, CDC_DATA_SZ); + usbd_ep_config(dev, CDC1_NTF_EP, USB_EPTYPE_INTERRUPT, CDC_NTF_SZ); + usbd_reg_endpoint(dev, CDC1_RXD_EP, cdc_rx_ep_callback); + usbd_reg_endpoint(dev, CDC1_TXD_EP, cdc_tx_ep_callback); + } else { + usbd_ep_config(dev, CDC1_RXD_EP, USB_EPTYPE_BULK, CDC_DATA_SZ); + usbd_ep_config(dev, CDC1_TXD_EP, USB_EPTYPE_BULK, CDC_DATA_SZ); + usbd_ep_config(dev, CDC1_NTF_EP, USB_EPTYPE_INTERRUPT, CDC_NTF_SZ); + usbd_reg_endpoint(dev, CDC1_RXD_EP, cdc_txrx_ep_callback); + usbd_reg_endpoint(dev, CDC1_TXD_EP, cdc_txrx_ep_callback); + } + usbd_ep_write(dev, CDC1_TXD_EP, 0, 0); + } + return usbd_ack; + default: + return usbd_fail; + } +} + +/* Control requests handler */ +static usbd_respond cdc_control (usbd_device *dev, usbd_ctlreq *req, usbd_rqc_callback *callback) { + /* CDC control requests */ + if (((USB_REQ_RECIPIENT | USB_REQ_TYPE) & req->bmRequestType) == (USB_REQ_INTERFACE | USB_REQ_CLASS) + && req->wIndex == 0 ) { + switch (req->bRequest) { + case USB_CDC_SET_CONTROL_LINE_STATE: + furi_hal_vcp_on_cdc_control_line(req->wValue); + return usbd_ack; + case USB_CDC_SET_LINE_CODING: + memcpy(&cdc_line, req->data, sizeof(cdc_line)); + return usbd_ack; + case USB_CDC_GET_LINE_CODING: + dev->status.data_ptr = &cdc_line; + dev->status.data_count = sizeof(cdc_line); + return usbd_ack; + default: + return usbd_fail; + } + } + return usbd_fail; +} diff --git a/firmware/targets/f6/furi-hal/furi-hal-usb-cdc_i.h b/firmware/targets/f6/furi-hal/furi-hal-usb-cdc_i.h new file mode 100644 index 00000000..636b3c04 --- /dev/null +++ b/firmware/targets/f6/furi-hal/furi-hal-usb-cdc_i.h @@ -0,0 +1,7 @@ +#pragma once + +#define CDC_DATA_SZ 0x40 + +void furi_hal_cdc_send(uint8_t if_num, uint8_t* buf, uint16_t len); + +int32_t furi_hal_cdc_receive(uint8_t if_num, uint8_t* buf, uint16_t max_len); diff --git a/firmware/targets/f6/furi-hal/furi-hal-usb-hid.c b/firmware/targets/f6/furi-hal/furi-hal-usb-hid.c new file mode 100644 index 00000000..38423610 --- /dev/null +++ b/firmware/targets/f6/furi-hal/furi-hal-usb-hid.c @@ -0,0 +1,264 @@ +#include "furi-hal-version.h" +#include "furi-hal-usb_i.h" +#include <furi.h> + +#include "usb.h" +#include "usb_hid.h" +#include "hid_usage_desktop.h" +#include "hid_usage_button.h" + +#define HID_RIN_EP 0x81 +#define HID_RIN_SZ 0x10 + +struct HidIadDescriptor { + struct usb_iad_descriptor hid_iad; + struct usb_interface_descriptor hid; + struct usb_hid_descriptor hid_desc; + struct usb_endpoint_descriptor hid_ep; +}; + +struct HidConfigDescriptor { + struct usb_config_descriptor config; + struct HidIadDescriptor iad_0; +} __attribute__((packed)); + +/* HID mouse report desscriptor. 2 axis 5 buttons */ +static const uint8_t hid_report_desc[] = { + HID_USAGE_PAGE(HID_PAGE_DESKTOP), + HID_USAGE(HID_DESKTOP_MOUSE), + HID_COLLECTION(HID_APPLICATION_COLLECTION), + HID_USAGE(HID_DESKTOP_POINTER), + HID_COLLECTION(HID_PHYSICAL_COLLECTION), + HID_USAGE(HID_DESKTOP_X), + HID_USAGE(HID_DESKTOP_Y), + HID_LOGICAL_MINIMUM(-127), + HID_LOGICAL_MAXIMUM(127), + HID_REPORT_SIZE(8), + HID_REPORT_COUNT(2), + HID_INPUT(HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_RELATIVE ), + HID_USAGE_PAGE(HID_PAGE_BUTTON), + HID_USAGE_MINIMUM(1), + HID_USAGE_MAXIMUM(5), + HID_LOGICAL_MINIMUM(0), + HID_LOGICAL_MAXIMUM(1), + HID_REPORT_SIZE(1), + HID_REPORT_COUNT(5), + HID_INPUT(HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE ), + HID_REPORT_SIZE(1), + HID_REPORT_COUNT(3), + HID_INPUT(HID_IOF_CONSTANT), + HID_END_COLLECTION, + HID_END_COLLECTION, +}; + +static const struct usb_string_descriptor dev_manuf_desc = USB_STRING_DESC("Logitech"); +static const struct usb_string_descriptor dev_prod_desc = USB_STRING_DESC("USB Receiver"); +static const struct usb_string_descriptor dev_serial_desc = USB_STRING_DESC("1234567890"); + +/* Device descriptor */ +static const struct usb_device_descriptor hid_device_desc = { + .bLength = sizeof(struct usb_device_descriptor), + .bDescriptorType = USB_DTYPE_DEVICE, + .bcdUSB = VERSION_BCD(2,0,0), + .bDeviceClass = USB_CLASS_IAD, + .bDeviceSubClass = USB_SUBCLASS_IAD, + .bDeviceProtocol = USB_PROTO_IAD, + .bMaxPacketSize0 = USB_EP0_SIZE, + .idVendor = 0x046d, + .idProduct = 0xc529, + .bcdDevice = VERSION_BCD(1,0,0), + .iManufacturer = UsbDevManuf, + .iProduct = UsbDevProduct, + .iSerialNumber = UsbDevSerial, + .bNumConfigurations = 1, +}; + +/* Device configuration descriptor */ +static const struct HidConfigDescriptor hid_cfg_desc = { + .config = { + .bLength = sizeof(struct usb_config_descriptor), + .bDescriptorType = USB_DTYPE_CONFIGURATION, + .wTotalLength = sizeof(struct HidConfigDescriptor), + .bNumInterfaces = 1, + .bConfigurationValue = 1, + .iConfiguration = NO_DESCRIPTOR, + .bmAttributes = USB_CFG_ATTR_RESERVED | USB_CFG_ATTR_SELFPOWERED, + .bMaxPower = USB_CFG_POWER_MA(100), + }, + .iad_0 = { + .hid_iad = { + .bLength = sizeof(struct usb_iad_descriptor), + .bDescriptorType = USB_DTYPE_INTERFASEASSOC, + .bFirstInterface = 0, + .bInterfaceCount = 1, + .bFunctionClass = USB_CLASS_PER_INTERFACE, + .bFunctionSubClass = USB_SUBCLASS_NONE, + .bFunctionProtocol = USB_PROTO_NONE, + .iFunction = NO_DESCRIPTOR, + }, + .hid = { + .bLength = sizeof(struct usb_interface_descriptor), + .bDescriptorType = USB_DTYPE_INTERFACE, + .bInterfaceNumber = 0, + .bAlternateSetting = 0, + .bNumEndpoints = 1, + .bInterfaceClass = USB_CLASS_HID, + .bInterfaceSubClass = USB_HID_SUBCLASS_NONBOOT, + .bInterfaceProtocol = USB_HID_PROTO_NONBOOT, + .iInterface = NO_DESCRIPTOR, + }, + .hid_desc = { + .bLength = sizeof(struct usb_hid_descriptor), + .bDescriptorType = USB_DTYPE_HID, + .bcdHID = VERSION_BCD(1,0,0), + .bCountryCode = USB_HID_COUNTRY_NONE, + .bNumDescriptors = 1, + .bDescriptorType0 = USB_DTYPE_HID_REPORT, + .wDescriptorLength0 = sizeof(hid_report_desc), + }, + .hid_ep = { + .bLength = sizeof(struct usb_endpoint_descriptor), + .bDescriptorType = USB_DTYPE_ENDPOINT, + .bEndpointAddress = HID_RIN_EP, + .bmAttributes = USB_EPTYPE_INTERRUPT, + .wMaxPacketSize = HID_RIN_SZ, + .bInterval = 50, + }, + }, +}; + +static struct { + int8_t x; + int8_t y; + uint8_t buttons; +} __attribute__((packed)) hid_report_data; + +static void hid_init(usbd_device* dev, struct UsbInterface* intf); +static void hid_deinit(usbd_device *dev); +static void hid_on_wakeup(usbd_device *dev); +static void hid_on_suspend(usbd_device *dev); + +static usbd_respond hid_ep_config (usbd_device *dev, uint8_t cfg); +static usbd_respond hid_control (usbd_device *dev, usbd_ctlreq *req, usbd_rqc_callback *callback); +static usbd_device* usb_dev; + +struct UsbInterface usb_hid = { + .init = hid_init, + .deinit = hid_deinit, + .wakeup = hid_on_wakeup, + .suspend = hid_on_suspend, + + .dev_descr = (struct usb_device_descriptor*)&hid_device_desc, + + .str_manuf_descr = (void*)&dev_manuf_desc, + .str_prod_descr = (void*)&dev_prod_desc, + .str_serial_descr = (void*)&dev_serial_desc, + + .cfg_descr = (void*)&hid_cfg_desc, +}; + +static void hid_init(usbd_device* dev, struct UsbInterface* intf) { + usb_dev = dev; + + usbd_reg_config(dev, hid_ep_config); + usbd_reg_control(dev, hid_control); + + usbd_connect(dev, true); +} + +static void hid_deinit(usbd_device *dev) { + usbd_reg_config(dev, NULL); + usbd_reg_control(dev, NULL); +} + +static void hid_on_wakeup(usbd_device *dev) { +} + +static void hid_on_suspend(usbd_device *dev) { +} + +/* HID mouse IN endpoint callback */ +static void hid_mouse_move(usbd_device *dev, uint8_t event, uint8_t ep) { + static uint8_t t = 0; + if (t < 0x10) { + hid_report_data.x = 1; + hid_report_data.y = 0; + } else if (t < 0x20) { + hid_report_data.x = 1; + hid_report_data.y = 1; + } else if (t < 0x30) { + hid_report_data.x = 0; + hid_report_data.y = 1; + } else if (t < 0x40) { + hid_report_data.x = -1; + hid_report_data.y = 1; + } else if (t < 0x50) { + hid_report_data.x = -1; + hid_report_data.y = 0; + } else if (t < 0x60) { + hid_report_data.x = -1; + hid_report_data.y = -1; + } else if (t < 0x70) { + hid_report_data.x = 0; + hid_report_data.y = -1; + } else { + hid_report_data.x = 1; + hid_report_data.y = -1; + } + t = (t + 1) & 0x7F; + usbd_ep_write(dev, ep, &hid_report_data, sizeof(hid_report_data)); +} + +/* Configure endpoints */ +static usbd_respond hid_ep_config (usbd_device *dev, uint8_t cfg) { + switch (cfg) { + case 0: + /* deconfiguring device */ + usbd_ep_deconfig(dev, HID_RIN_EP); + usbd_reg_endpoint(dev, HID_RIN_EP, 0); + return usbd_ack; + case 1: + /* configuring device */ + usbd_ep_config(dev, HID_RIN_EP, USB_EPTYPE_INTERRUPT, HID_RIN_SZ); + usbd_reg_endpoint(dev, HID_RIN_EP, hid_mouse_move); + usbd_ep_write(dev, HID_RIN_EP, 0, 0); + return usbd_ack; + default: + return usbd_fail; + } +} + +/* Control requests handler */ +static usbd_respond hid_control (usbd_device *dev, usbd_ctlreq *req, usbd_rqc_callback *callback) { + /* HID control requests */ + if (((USB_REQ_RECIPIENT | USB_REQ_TYPE) & req->bmRequestType) == (USB_REQ_INTERFACE | USB_REQ_CLASS) + && req->wIndex == 0 ) { + switch (req->bRequest) { + case USB_HID_SETIDLE: + return usbd_ack; + case USB_HID_GETREPORT: + dev->status.data_ptr = &hid_report_data; + dev->status.data_count = sizeof(hid_report_data); + return usbd_ack; + default: + return usbd_fail; + } + } + if (((USB_REQ_RECIPIENT | USB_REQ_TYPE) & req->bmRequestType) == (USB_REQ_INTERFACE | USB_REQ_STANDARD) + && req->wIndex == 0 + && req->bRequest == USB_STD_GET_DESCRIPTOR) { + switch (req->wValue >> 8) { + case USB_DTYPE_HID: + dev->status.data_ptr = (uint8_t*)&(hid_cfg_desc.iad_0.hid_desc); + dev->status.data_count = sizeof(hid_cfg_desc.iad_0.hid_desc); + return usbd_ack; + case USB_DTYPE_HID_REPORT: + dev->status.data_ptr = (uint8_t*)hid_report_desc; + dev->status.data_count = sizeof(hid_report_desc); + return usbd_ack; + default: + return usbd_fail; + } + } + return usbd_fail; +} diff --git a/firmware/targets/f6/furi-hal/furi-hal-usb.c b/firmware/targets/f6/furi-hal/furi-hal-usb.c new file mode 100644 index 00000000..fc5add2e --- /dev/null +++ b/firmware/targets/f6/furi-hal/furi-hal-usb.c @@ -0,0 +1,164 @@ +#include "furi-hal-version.h" +#include "furi-hal-usb_i.h" +#include "furi-hal-usb.h" +#include "furi-hal-vcp_i.h" +#include <furi.h> + +#include "usb.h" + +#define USB_RECONNECT_DELAY 500 + +extern struct UsbInterface usb_cdc_single; +extern struct UsbInterface usb_cdc_dual; +extern struct UsbInterface usb_hid; + +static struct UsbInterface* const usb_if_modes[UsbModesNum] = { + NULL, + &usb_cdc_single, + &usb_cdc_dual, + &usb_hid, + NULL,//&usb_hid_u2f, +}; + +static const struct usb_string_descriptor dev_lang_desc = USB_ARRAY_DESC(USB_LANGID_ENG_US); + +static uint32_t ubuf[0x20]; +usbd_device udev; + +static usbd_respond usb_descriptor_get (usbd_ctlreq *req, void **address, uint16_t *length); +static void susp_evt(usbd_device *dev, uint8_t event, uint8_t ep); +static void wkup_evt(usbd_device *dev, uint8_t event, uint8_t ep); + +struct UsbCfg{ + osTimerId_t reconnect_tmr; + UsbMode mode_cur; + UsbMode mode_next; + bool enabled; +} usb_config; + +static void furi_hal_usb_tmr_cb(void* context); + +/* Low-level init */ +void furi_hal_usb_init(void) { + + LL_GPIO_InitTypeDef GPIO_InitStruct = {0}; + LL_PWR_EnableVddUSB(); + + GPIO_InitStruct.Pin = LL_GPIO_PIN_11 | LL_GPIO_PIN_12; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + GPIO_InitStruct.Alternate = LL_GPIO_AF_10; + LL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + usbd_init(&udev, &usbd_hw, USB_EP0_SIZE, ubuf, sizeof(ubuf)); + usbd_enable(&udev, true); + + usbd_reg_descr(&udev, usb_descriptor_get); + usbd_reg_event(&udev, usbd_evt_susp, susp_evt); + usbd_reg_event(&udev, usbd_evt_wkup, wkup_evt); + + usb_config.enabled = false; + usb_config.reconnect_tmr = NULL; + HAL_NVIC_SetPriority(USB_LP_IRQn, 5, 0); + NVIC_EnableIRQ(USB_LP_IRQn); + + FURI_LOG_I("FuriHalUsb", "Init OK"); +} + +void furi_hal_usb_set_config(UsbMode new_mode) { + if (new_mode != usb_config.mode_cur) { + if (usb_config.enabled) { + usb_config.mode_next = new_mode; + if (usb_config.reconnect_tmr == NULL) + usb_config.reconnect_tmr = osTimerNew(furi_hal_usb_tmr_cb, osTimerOnce, NULL, NULL); + furi_hal_usb_disable(); + osTimerStart(usb_config.reconnect_tmr, USB_RECONNECT_DELAY); + } + else { + if (usb_if_modes[usb_config.mode_cur] != NULL) + usb_if_modes[usb_config.mode_cur]->deinit(&udev); + if (usb_if_modes[new_mode] != NULL) { + usb_if_modes[new_mode]->init(&udev, usb_if_modes[new_mode]); + FURI_LOG_I("FuriHalUsb", "USB mode change %u -> %u", usb_config.mode_cur, new_mode); + usb_config.enabled = true; + usb_config.mode_cur = new_mode; + } + } + } +} + +void furi_hal_usb_disable() { + if (usb_config.enabled) { + susp_evt(&udev, 0, 0); + usbd_connect(&udev, false); + usb_config.enabled = false; + FURI_LOG_I("FuriHalUsb", "USB Disable"); + } +} + +void furi_hal_usb_enable() { + if ((!usb_config.enabled) && (usb_if_modes[usb_config.mode_cur] != NULL)) { + usbd_connect(&udev, true); + usb_config.enabled = true; + FURI_LOG_I("FuriHalUsb", "USB Enable"); + } +} + +static void furi_hal_usb_tmr_cb(void* context) { + furi_hal_usb_set_config(usb_config.mode_next); +} + +/* Get device / configuration descriptors */ +static usbd_respond usb_descriptor_get (usbd_ctlreq *req, void **address, uint16_t *length) { + const uint8_t dtype = req->wValue >> 8; + const uint8_t dnumber = req->wValue & 0xFF; + const void* desc; + uint16_t len = 0; + if (usb_if_modes[usb_config.mode_cur] == NULL) + return usbd_fail; + + switch (dtype) { + case USB_DTYPE_DEVICE: + desc = usb_if_modes[usb_config.mode_cur]->dev_descr; + break; + case USB_DTYPE_CONFIGURATION: + desc = usb_if_modes[usb_config.mode_cur]->cfg_descr; + len = ((struct usb_string_descriptor*)(usb_if_modes[usb_config.mode_cur]->cfg_descr))->wString[0]; + break; + case USB_DTYPE_STRING: + if (dnumber == UsbDevLang) { + desc = &dev_lang_desc; + } else if (dnumber == UsbDevManuf) { + desc = usb_if_modes[usb_config.mode_cur]->str_manuf_descr; + } else if (dnumber == UsbDevProduct) { + desc = usb_if_modes[usb_config.mode_cur]->str_prod_descr; + } else if (dnumber == UsbDevSerial) { + desc = usb_if_modes[usb_config.mode_cur]->str_serial_descr; + } else + return usbd_fail; + break; + default: + return usbd_fail; + } + if (desc == NULL) + return usbd_fail; + + if (len == 0) { + len = ((struct usb_header_descriptor*)desc)->bLength; + } + *address = (void*)desc; + *length = len; + return usbd_ack; +} + +static void susp_evt(usbd_device *dev, uint8_t event, uint8_t ep) { + if (usb_if_modes[usb_config.mode_cur] != NULL) + usb_if_modes[usb_config.mode_cur]->suspend(&udev); +} + +static void wkup_evt(usbd_device *dev, uint8_t event, uint8_t ep) { + if (usb_if_modes[usb_config.mode_cur] != NULL) + usb_if_modes[usb_config.mode_cur]->wakeup(&udev); +} diff --git a/firmware/targets/f6/furi-hal/furi-hal-usb_i.h b/firmware/targets/f6/furi-hal/furi-hal-usb_i.h new file mode 100644 index 00000000..b329c51f --- /dev/null +++ b/firmware/targets/f6/furi-hal/furi-hal-usb_i.h @@ -0,0 +1,28 @@ +#pragma once + +#include "usb.h" + +#define USB_EP0_SIZE 8 + +/* String descriptors */ +enum UsbDevDescStr{ + UsbDevLang = 0, + UsbDevManuf = 1, + UsbDevProduct = 2, + UsbDevSerial = 3, +}; + +struct UsbInterface { + void (*init)(usbd_device *dev, struct UsbInterface* intf); + void (*deinit)(usbd_device *dev); + void (*wakeup)(usbd_device *dev); + void (*suspend)(usbd_device *dev); + + struct usb_device_descriptor* dev_descr; + + void* str_manuf_descr; + void* str_prod_descr; + void* str_serial_descr; + + void* cfg_descr; +}; diff --git a/firmware/targets/f6/furi-hal/furi-hal-vcp.c b/firmware/targets/f6/furi-hal/furi-hal-vcp.c index 88de32b5..e276c4a3 100644 --- a/firmware/targets/f6/furi-hal/furi-hal-vcp.c +++ b/firmware/targets/f6/furi-hal/furi-hal-vcp.c @@ -1,12 +1,12 @@ #include <furi-hal-vcp_i.h> +#include <furi-hal-usb-cdc_i.h> #include <furi.h> -#include <usbd_cdc_if.h> #include <stream_buffer.h> -#define FURI_HAL_VCP_RX_BUFFER_SIZE (APP_RX_DATA_SIZE * 5) - -extern USBD_HandleTypeDef hUsbDeviceFS; +#define APP_RX_DATA_SIZE CDC_DATA_SZ +#define APP_TX_DATA_SIZE CDC_DATA_SZ +#define FURI_HAL_VCP_RX_BUFFER_SIZE (APP_RX_DATA_SIZE * 16) typedef struct { volatile bool connected; @@ -22,8 +22,11 @@ static FuriHalVcp* furi_hal_vcp = NULL; static const uint8_t ascii_soh = 0x01; static const uint8_t ascii_eot = 0x04; +static uint8_t* vcp_rx_buf; + void furi_hal_vcp_init() { furi_hal_vcp = furi_alloc(sizeof(FuriHalVcp)); + vcp_rx_buf = furi_alloc(APP_RX_DATA_SIZE); furi_hal_vcp->connected = false; furi_hal_vcp->rx_stream = xStreamBufferCreate(FURI_HAL_VCP_RX_BUFFER_SIZE, 1); @@ -40,10 +43,8 @@ size_t furi_hal_vcp_rx(uint8_t* buffer, size_t size) { size_t received = xStreamBufferReceive(furi_hal_vcp->rx_stream, buffer, size, portMAX_DELAY); if(furi_hal_vcp->rx_stream_full - &&xStreamBufferSpacesAvailable(furi_hal_vcp->rx_stream) >= APP_RX_DATA_SIZE) { + && xStreamBufferSpacesAvailable(furi_hal_vcp->rx_stream) >= APP_RX_DATA_SIZE) { furi_hal_vcp->rx_stream_full = false; - // data accepted, start waiting for next packet - USBD_CDC_ReceivePacket(&hUsbDeviceFS); } return received; @@ -67,13 +68,9 @@ void furi_hal_vcp_tx(const uint8_t* buffer, size_t size) { batch_size = APP_TX_DATA_SIZE; } - if (CDC_Transmit_FS((uint8_t*)buffer, batch_size) == USBD_OK) { - size -= batch_size; - buffer += batch_size; - } else { - FURI_LOG_E("FuriHalVcp", "CDC_Transmit_FS failed"); - osDelay(50); - } + furi_hal_cdc_send(0, (uint8_t*)buffer, batch_size); + size -= batch_size; + buffer += batch_size; } } @@ -89,6 +86,8 @@ void furi_hal_vcp_on_usb_suspend() { } void furi_hal_vcp_on_cdc_control_line(uint8_t state) { + + BaseType_t xHigherPriorityTaskWoken = pdFALSE; // bit 0: DTR state, bit 1: RTS state // bool dtr = state & 0b01; bool dtr = state & 0b1; @@ -96,33 +95,45 @@ void furi_hal_vcp_on_cdc_control_line(uint8_t state) { if (dtr) { if (!furi_hal_vcp->connected) { furi_hal_vcp->connected = true; - furi_hal_vcp_on_cdc_rx(&ascii_soh, 1); // SOH + xStreamBufferSendFromISR(furi_hal_vcp->rx_stream, &ascii_soh, 1, &xHigherPriorityTaskWoken); // SOH + } } else { if (furi_hal_vcp->connected) { - furi_hal_vcp_on_cdc_rx(&ascii_eot, 1); // EOT + xStreamBufferSendFromISR(furi_hal_vcp->rx_stream, &ascii_eot, 1, &xHigherPriorityTaskWoken); // EOT furi_hal_vcp->connected = false; } } osSemaphoreRelease(furi_hal_vcp->tx_semaphore); + + portYIELD_FROM_ISR(xHigherPriorityTaskWoken); } -void furi_hal_vcp_on_cdc_rx(const uint8_t* buffer, size_t size) { +void furi_hal_vcp_on_cdc_rx(uint8_t if_num) { BaseType_t xHigherPriorityTaskWoken = pdFALSE; - size_t ret = xStreamBufferSendFromISR(furi_hal_vcp->rx_stream, buffer, size, &xHigherPriorityTaskWoken); - furi_check(ret == size); - - if (xStreamBufferSpacesAvailable(furi_hal_vcp->rx_stream) >= APP_RX_DATA_SIZE) { - USBD_CDC_ReceivePacket(&hUsbDeviceFS); - } else { - furi_hal_vcp->rx_stream_full = true; + + if (if_num == 0) { + uint16_t max_len = xStreamBufferSpacesAvailable(furi_hal_vcp->rx_stream); + if (max_len > 0) { + if (max_len > APP_RX_DATA_SIZE) + max_len = APP_RX_DATA_SIZE; + int32_t size = furi_hal_cdc_receive(0, vcp_rx_buf, max_len); + + if (size > 0) { + size_t ret = xStreamBufferSendFromISR(furi_hal_vcp->rx_stream, vcp_rx_buf, size, &xHigherPriorityTaskWoken); + furi_check(ret == size); + } + } else { + furi_hal_vcp->rx_stream_full = true; + }; } portYIELD_FROM_ISR(xHigherPriorityTaskWoken); } -void furi_hal_vcp_on_cdc_tx_complete(size_t size) { - osSemaphoreRelease(furi_hal_vcp->tx_semaphore); +void furi_hal_vcp_on_cdc_tx_complete(uint8_t if_num) { + if (if_num == 0) + osSemaphoreRelease(furi_hal_vcp->tx_semaphore); } diff --git a/firmware/targets/f6/furi-hal/furi-hal-vcp_i.h b/firmware/targets/f6/furi-hal/furi-hal-vcp_i.h index 05ddc6ad..9c8ccd73 100644 --- a/firmware/targets/f6/furi-hal/furi-hal-vcp_i.h +++ b/firmware/targets/f6/furi-hal/furi-hal-vcp_i.h @@ -8,6 +8,6 @@ void furi_hal_vcp_on_usb_suspend(); void furi_hal_vcp_on_cdc_control_line(uint8_t state); -void furi_hal_vcp_on_cdc_rx(const uint8_t* buffer, size_t size); +void furi_hal_vcp_on_cdc_rx(uint8_t if_num); -void furi_hal_vcp_on_cdc_tx_complete(size_t size); +void furi_hal_vcp_on_cdc_tx_complete(uint8_t if_num); diff --git a/firmware/targets/f6/furi-hal/furi-hal-version.c b/firmware/targets/f6/furi-hal/furi-hal-version.c index 90a3d6c2..93166b16 100644 --- a/firmware/targets/f6/furi-hal/furi-hal-version.c +++ b/firmware/targets/f6/furi-hal/furi-hal-version.c @@ -8,10 +8,6 @@ #include "ble.h" #define FURI_HAL_VERSION_OTP_HEADER_MAGIC 0xBABE -#define FURI_HAL_VERSION_NAME_LENGTH 8 -#define FURI_HAL_VERSION_ARRAY_NAME_LENGTH (FURI_HAL_VERSION_NAME_LENGTH + 1) -/** BLE symbol + "Flipper " + name */ -#define FURI_HAL_VERSION_DEVICE_NAME_LENGTH (1 + 8 + FURI_HAL_VERSION_ARRAY_NAME_LENGTH) #define FURI_HAL_VERSION_OTP_ADDRESS OTP_AREA_BASE /** OTP Versions enum */ diff --git a/firmware/targets/f6/furi-hal/furi-hal.c b/firmware/targets/f6/furi-hal/furi-hal.c index 2ec06dd4..64b29ba7 100644 --- a/firmware/targets/f6/furi-hal/furi-hal.c +++ b/firmware/targets/f6/furi-hal/furi-hal.c @@ -3,7 +3,6 @@ #include <comp.h> #include <rtc.h> #include <tim.h> -#include <usb_device.h> #include <gpio.h> void furi_hal_init() { @@ -35,7 +34,8 @@ void furi_hal_init() { // VCP + USB furi_hal_vcp_init(); - MX_USB_Device_Init(); + furi_hal_usb_init(); + furi_hal_usb_set_config(UsbModeVcpSingle); FURI_LOG_I("HAL", "USB OK"); furi_hal_i2c_init(); diff --git a/firmware/targets/f6/target.mk b/firmware/targets/f6/target.mk index fe950149..d8ab0d5d 100644 --- a/firmware/targets/f6/target.mk +++ b/firmware/targets/f6/target.mk @@ -38,6 +38,7 @@ CFLAGS += \ CFLAGS += \ -I$(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Inc \ -I$(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Inc/Legacy \ + -I$(CUBE_DIR)/Drivers/CMSIS/Device/ST \ -I$(CUBE_DIR)/Drivers/CMSIS/Device/ST/STM32WBxx/Include \ -I$(CUBE_DIR)/Drivers/CMSIS/Include C_SOURCES += \ @@ -69,7 +70,6 @@ C_SOURCES += \ $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_spi.c \ $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_tim.c \ $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_usart.c \ - $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_usb.c \ $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_utils.c # FreeRTOS @@ -116,17 +116,10 @@ C_SOURCES += \ $(CUBE_DIR)/Middlewares/ST/STM32_WPAN/interface/patterns/ble_thread/tl/shci_tl_if.c \ $(CUBE_DIR)/Middlewares/ST/STM32_WPAN/interface/patterns/ble_thread/shci/shci.c -# USB glue +# USB stack CFLAGS += \ - -I$(TARGET_DIR)/usb-glue \ - -I$(CUBE_DIR)/Middlewares/ST/STM32_USB_Device_Library/Core/Inc \ - -I$(CUBE_DIR)/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -C_SOURCES += \ - $(wildcard $(TARGET_DIR)/usb-glue/*.c) \ - $(CUBE_DIR)/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_core.c \ - $(CUBE_DIR)/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ctlreq.c \ - $(CUBE_DIR)/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ioreq.c \ - $(CUBE_DIR)/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c + -DSTM32WB \ + -DUSB_PMASIZE=0x400 # Furi HAL FURI_HAL_OS_DEBUG ?= 0 diff --git a/firmware/targets/f6/usb-glue/usb_device.c b/firmware/targets/f6/usb-glue/usb_device.c deleted file mode 100644 index 84e9143d..00000000 --- a/firmware/targets/f6/usb-glue/usb_device.c +++ /dev/null @@ -1,34 +0,0 @@ -#include "usb_device.h"
-
-#include "stm32wbxx.h"
-#include "stm32wbxx_hal.h"
-
-#include "usbd_def.h"
-#include "usbd_core.h"
-#include "usbd_desc.h"
-#include "usbd_cdc.h"
-#include "usbd_cdc_if.h"
-
-extern void Error_Handler(void);
-
-/* USB Device Core handle declaration. */
-USBD_HandleTypeDef hUsbDeviceFS;
-
-extern USBD_DescriptorsTypeDef CDC_Desc;
-
-/** Init USB device Library, add supported class and start the library */
-void MX_USB_Device_Init(void) {
- /* Init Device Library, add supported class and start the library. */
- if (USBD_Init(&hUsbDeviceFS, &CDC_Desc, DEVICE_FS) != USBD_OK) {
- Error_Handler();
- }
- if (USBD_RegisterClass(&hUsbDeviceFS, &USBD_CDC) != USBD_OK) {
- Error_Handler();
- }
- if (USBD_CDC_RegisterInterface(&hUsbDeviceFS, &USBD_Interface_fops_FS) != USBD_OK) {
- Error_Handler();
- }
- if (USBD_Start(&hUsbDeviceFS) != USBD_OK) {
- Error_Handler();
- }
-}
diff --git a/firmware/targets/f6/usb-glue/usb_device.h b/firmware/targets/f6/usb-glue/usb_device.h deleted file mode 100644 index 7d80e348..00000000 --- a/firmware/targets/f6/usb-glue/usb_device.h +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once
-
-#ifdef __cplusplus
- extern "C" {
-#endif
-
-void MX_USB_Device_Init();
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/firmware/targets/f6/usb-glue/usbd_cdc_if.c b/firmware/targets/f6/usb-glue/usbd_cdc_if.c deleted file mode 100644 index 6b905c84..00000000 --- a/firmware/targets/f6/usb-glue/usbd_cdc_if.c +++ /dev/null @@ -1,142 +0,0 @@ -#include "usbd_cdc_if.h"
-#include <furi-hal-vcp_i.h>
-
-extern USBD_HandleTypeDef hUsbDeviceFS;
-
-static int8_t CDC_Init_FS(void);
-static int8_t CDC_DeInit_FS(void);
-static int8_t CDC_Control_FS(uint8_t cmd, uint8_t* pbuf, uint16_t length);
-static int8_t CDC_Receive_FS(uint8_t* pbuf, uint32_t *Len);
-static int8_t CDC_TransmitCplt_FS(uint8_t *pbuf, uint32_t *Len, uint8_t epnum);
-
-USBD_CDC_ItfTypeDef USBD_Interface_fops_FS =
-{
- CDC_Init_FS,
- CDC_DeInit_FS,
- CDC_Control_FS,
- CDC_Receive_FS,
- CDC_TransmitCplt_FS
-};
-
-uint8_t UserRxBufferFS[APP_RX_DATA_SIZE];
-uint8_t UserTxBufferFS[APP_TX_DATA_SIZE];
-
-/** Initializes the CDC media low layer over the FS USB IP
- * @retval USBD_OK if all operations are OK else USBD_FAIL
- */
-static int8_t CDC_Init_FS(void) {
- /* Set Application Buffers */
- USBD_CDC_SetTxBuffer(&hUsbDeviceFS, UserTxBufferFS, 0);
- USBD_CDC_SetRxBuffer(&hUsbDeviceFS, UserRxBufferFS);
- return (USBD_OK);
-}
-
-/**
- * @brief DeInitializes the CDC media low layer
- * @retval USBD_OK if all operations are OK else USBD_FAIL
- */
-static int8_t CDC_DeInit_FS(void) {
- return (USBD_OK);
-}
-
-/** Manage the CDC class requests
- * @param cmd: Command code
- * @param pbuf: Buffer containing command data (request parameters)
- * @param length: Number of data to be sent (in bytes)
- * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
- */
-static int8_t CDC_Control_FS(uint8_t cmd, uint8_t* pbuf, uint16_t length) {
- if (cmd == CDC_SEND_ENCAPSULATED_COMMAND) {
- } else if (cmd == CDC_GET_ENCAPSULATED_RESPONSE) {
- } else if (cmd == CDC_SET_COMM_FEATURE) {
- } else if (cmd == CDC_GET_COMM_FEATURE) {
- } else if (cmd == CDC_CLEAR_COMM_FEATURE) {
- } else if (cmd == CDC_SET_LINE_CODING) {
- /*******************************************************************************/
- /* Line Coding Structure */
- /*-----------------------------------------------------------------------------*/
- /* Offset | Field | Size | Value | Description */
- /* 0 | dwDTERate | 4 | Number |Data terminal rate, in bits per second*/
- /* 4 | bCharFormat | 1 | Number | Stop bits */
- /* 0 - 1 Stop bit */
- /* 1 - 1.5 Stop bits */
- /* 2 - 2 Stop bits */
- /* 5 | bParityType | 1 | Number | Parity */
- /* 0 - None */
- /* 1 - Odd */
- /* 2 - Even */
- /* 3 - Mark */
- /* 4 - Space */
- /* 6 | bDataBits | 1 | Number Data bits (5, 6, 7, 8 or 16). */
- /*******************************************************************************/
- } else if (cmd == CDC_GET_LINE_CODING) {
- } else if (cmd == CDC_SET_CONTROL_LINE_STATE) {
- furi_hal_vcp_on_cdc_control_line(((USBD_SetupReqTypedef*)pbuf)->wValue);
- } else if (cmd == CDC_SEND_BREAK) {
- } else {
- }
-
- return (USBD_OK);
-}
-
-/** Data received over USB OUT endpoint are sent over CDC interface through this function.
- *
- * @note
- * This function will issue a NAK packet on any OUT packet received on
- * USB endpoint until exiting this function. If you exit this function
- * before transfer is complete on CDC interface (ie. using DMA controller)
- * it will result in receiving more data while previous ones are still
- * not sent.
- *
- * @param Buf: Buffer of data to be received
- * @param Len: Number of data received (in bytes)
- * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
- */
-static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len) {
- if (*Len) {
- furi_hal_vcp_on_cdc_rx(Buf, *Len);
- } else {
- USBD_CDC_ReceivePacket(&hUsbDeviceFS);
- }
-
- return (USBD_OK);
-}
-
-/** CDC_Transmit_FS Data to send over USB IN endpoint are sent over CDC interface
- * through this function.
- * @param Buf: Buffer of data to be sent
- * @param Len: Number of data to be sent (in bytes)
- * @retval USBD_OK if all operations are OK else USBD_FAIL or USBD_BUSY
- */
-uint8_t CDC_Transmit_FS(uint8_t* Buf, uint16_t Len)
-{
- uint8_t result = USBD_OK;
-
- USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*)hUsbDeviceFS.pClassData;
- if (hcdc->TxState != 0){
- return USBD_BUSY;
- }
- memcpy(UserTxBufferFS, Buf, Len);
- USBD_CDC_SetTxBuffer(&hUsbDeviceFS, UserTxBufferFS, Len);
- result = USBD_CDC_TransmitPacket(&hUsbDeviceFS);
-
- return result;
-}
-
-/** CDC_TransmitCplt_FS Data transmited callback
- *
- * @note
- * This function is IN transfer complete callback used to inform user that
- * the submitted Data is successfully sent over USB.
- *
- * @param Buf: Buffer of data to be received
- * @param Len: Number of data received (in bytes)
- * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
- */
-static int8_t CDC_TransmitCplt_FS(uint8_t *Buf, uint32_t *Len, uint8_t epnum) {
- uint8_t result = USBD_OK;
-
- furi_hal_vcp_on_cdc_tx_complete(*Len);
-
- return result;
-}
diff --git a/firmware/targets/f6/usb-glue/usbd_cdc_if.h b/firmware/targets/f6/usb-glue/usbd_cdc_if.h deleted file mode 100644 index fc0aefbe..00000000 --- a/firmware/targets/f6/usb-glue/usbd_cdc_if.h +++ /dev/null @@ -1,22 +0,0 @@ -#pragma once
-
-#ifdef __cplusplus
- extern "C" {
-#endif
-
-/* Includes ------------------------------------------------------------------*/
-#include "usbd_cdc.h"
-
-/* Define size for the receive and transmit buffer over CDC */
-/* It's up to user to redefine and/or remove those define */
-#define APP_RX_DATA_SIZE CDC_DATA_FS_MAX_PACKET_SIZE
-#define APP_TX_DATA_SIZE CDC_DATA_FS_MAX_PACKET_SIZE
-
-/** CDC Interface callback. */
-extern USBD_CDC_ItfTypeDef USBD_Interface_fops_FS;
-
-uint8_t CDC_Transmit_FS(uint8_t* Buf, uint16_t Len);
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/firmware/targets/f6/usb-glue/usbd_conf.c b/firmware/targets/f6/usb-glue/usbd_conf.c deleted file mode 100644 index cbc137e5..00000000 --- a/firmware/targets/f6/usb-glue/usbd_conf.c +++ /dev/null @@ -1,506 +0,0 @@ -#include "stm32wbxx.h"
-#include "stm32wbxx_hal.h"
-
-#include <furi-hal-vcp_i.h>
-
-#include "usbd_def.h"
-#include "usbd_core.h"
-#include "usbd_cdc.h"
-
-PCD_HandleTypeDef hpcd_USB_FS;
-void Error_Handler(void);
-
-static USBD_StatusTypeDef USBD_Get_USB_Status(HAL_StatusTypeDef hal_status);
-
-static void SystemClockConfig_Resume(void);
-
-void HAL_PCD_MspInit(PCD_HandleTypeDef* pcdHandle) {
- GPIO_InitTypeDef GPIO_InitStruct = {0};
- if(pcdHandle->Instance==USB) {
- __HAL_RCC_GPIOA_CLK_ENABLE();
- /**USB GPIO Configuration
- PA11 ------> USB_DM
- PA12 ------> USB_DP
- */
- GPIO_InitStruct.Pin = GPIO_PIN_11|GPIO_PIN_12;
- GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
- GPIO_InitStruct.Pull = GPIO_NOPULL;
- GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
- GPIO_InitStruct.Alternate = GPIO_AF10_USB;
- HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
-
- /* Peripheral clock enable */
- __HAL_RCC_USB_CLK_ENABLE();
-
- /* Peripheral interrupt init */
- HAL_NVIC_SetPriority(USB_LP_IRQn, 5, 0);
- HAL_NVIC_EnableIRQ(USB_LP_IRQn);
- }
-}
-
-void HAL_PCD_MspDeInit(PCD_HandleTypeDef* pcdHandle) {
- if(pcdHandle->Instance==USB) {
- /* Peripheral clock disable */
- __HAL_RCC_USB_CLK_DISABLE();
-
- /**USB GPIO Configuration
- PA11 ------> USB_DM
- PA12 ------> USB_DP
- */
- HAL_GPIO_DeInit(GPIOA, GPIO_PIN_11|GPIO_PIN_12);
-
- /* Peripheral interrupt Deinit*/
- HAL_NVIC_DisableIRQ(USB_LP_IRQn);
- }
-}
-
-/** Setup stage callback
- * @param hpcd: PCD handle
- * @retval None
- */
-void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd) {
- USBD_LL_SetupStage((USBD_HandleTypeDef*)hpcd->pData, (uint8_t *)hpcd->Setup);
-}
-
-/** Data Out stage callback.
- * @param hpcd: PCD handle
- * @param epnum: Endpoint number
- * @retval None
- */
-void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) {
- USBD_LL_DataOutStage((USBD_HandleTypeDef*)hpcd->pData, epnum, hpcd->OUT_ep[epnum].xfer_buff);
-}
-
-/** Data In stage callback.
- * @param hpcd: PCD handle
- * @param epnum: Endpoint number
- * @retval None
- */
-void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) {
- USBD_LL_DataInStage((USBD_HandleTypeDef*)hpcd->pData, epnum, hpcd->IN_ep[epnum].xfer_buff);
-}
-
-/** SOF callback.
- * @param hpcd: PCD handle
- * @retval None
- */
-void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd) {
- USBD_LL_SOF((USBD_HandleTypeDef*)hpcd->pData);
-}
-
-/** Reset callback.
- * @param hpcd: PCD handle
- * @retval None
- */
-void HAL_PCD_ResetCallback(PCD_HandleTypeDef *hpcd) {
- USBD_SpeedTypeDef speed = USBD_SPEED_FULL;
-
- if ( hpcd->Init.speed != PCD_SPEED_FULL) {
- Error_Handler();
- }
-
- /* Set Speed. */
- USBD_LL_SetSpeed((USBD_HandleTypeDef*)hpcd->pData, speed);
-
- /* Reset Device. */
- USBD_LL_Reset((USBD_HandleTypeDef*)hpcd->pData);
-}
-
-/** Suspend callback.
- * When Low power mode is enabled the debug cannot be used (IAR, Keil doesn't support it)
- * @param hpcd: PCD handle
- * @retval None
- */
-void HAL_PCD_SuspendCallback(PCD_HandleTypeDef *hpcd) {
- USBD_LL_Suspend((USBD_HandleTypeDef*)hpcd->pData);
-
- furi_hal_vcp_on_usb_suspend();
-
- if (hpcd->Init.low_power_enable) {
- /* Set SLEEPDEEP bit and SleepOnExit of Cortex System Control Register. */
- SCB->SCR |= (uint32_t)((uint32_t)(SCB_SCR_SLEEPDEEP_Msk | SCB_SCR_SLEEPONEXIT_Msk));
- }
-}
-
-/** Resume callback.
- * When Low power mode is enabled the debug cannot be used (IAR, Keil doesn't support it)
- * @param hpcd: PCD handle
- * @retval None
- */
-void HAL_PCD_ResumeCallback(PCD_HandleTypeDef *hpcd) {
- if (hpcd->Init.low_power_enable) {
- /* Reset SLEEPDEEP bit of Cortex System Control Register. */
- SCB->SCR &= (uint32_t)~((uint32_t)(SCB_SCR_SLEEPDEEP_Msk | SCB_SCR_SLEEPONEXIT_Msk));
- SystemClockConfig_Resume();
- }
-
- furi_hal_vcp_on_usb_resume();
-
- USBD_LL_Resume((USBD_HandleTypeDef*)hpcd->pData);
-}
-
-/** ISOOUTIncomplete callback.
- * @param hpcd: PCD handle
- * @param epnum: Endpoint number
- * @retval None
- */
-void HAL_PCD_ISOOUTIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) {
- USBD_LL_IsoOUTIncomplete((USBD_HandleTypeDef*)hpcd->pData, epnum);
-}
-
-/** ISOINIncomplete callback.
- * @param hpcd: PCD handle
- * @param epnum: Endpoint number
- * @retval None
- */
-void HAL_PCD_ISOINIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) {
- USBD_LL_IsoINIncomplete((USBD_HandleTypeDef*)hpcd->pData, epnum);
-}
-
-/** Connect callback.
- * @param hpcd: PCD handle
- * @retval None
- */
-void HAL_PCD_ConnectCallback(PCD_HandleTypeDef *hpcd) {
- USBD_LL_DevConnected((USBD_HandleTypeDef*)hpcd->pData);
-}
-
-/** Disconnect callback.
- * @param hpcd: PCD handle
- * @retval None
- */
-void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd) {
- USBD_LL_DevDisconnected((USBD_HandleTypeDef*)hpcd->pData);
-}
-
-/** Initializes the low level portion of the device driver.
- * @param pdev: Device handle
- * @retval USBD status
- */
-USBD_StatusTypeDef USBD_LL_Init(USBD_HandleTypeDef *pdev) {
- /* Init USB Ip. */
- hpcd_USB_FS.pData = pdev;
-
- /* Link the driver to the stack. */
- pdev->pData = &hpcd_USB_FS;
-
- /* Enable USB power on Pwrctrl CR2 register. */
- HAL_PWREx_EnableVddUSB();
-
- hpcd_USB_FS.Instance = USB;
- hpcd_USB_FS.Init.dev_endpoints = 8;
- hpcd_USB_FS.Init.speed = PCD_SPEED_FULL;
- hpcd_USB_FS.Init.phy_itface = PCD_PHY_EMBEDDED;
- hpcd_USB_FS.Init.Sof_enable = DISABLE;
- hpcd_USB_FS.Init.low_power_enable = DISABLE;
- hpcd_USB_FS.Init.lpm_enable = DISABLE;
- hpcd_USB_FS.Init.battery_charging_enable = DISABLE;
-
- if (HAL_PCD_Init(&hpcd_USB_FS) != HAL_OK) {
- Error_Handler();
- }
-
- HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , 0x00 , PCD_SNG_BUF, 0x18);
- HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , 0x80 , PCD_SNG_BUF, 0x58);
-
- HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , 0x81 , PCD_SNG_BUF, 0xC0);
- HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , 0x01 , PCD_SNG_BUF, 0x110);
- HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , 0x82 , PCD_SNG_BUF, 0x100);
-
- return USBD_OK;
-}
-
-/** De-Initializes the low level portion of the device driver.
- * @param pdev: Device handle
- * @retval USBD status
- */
-USBD_StatusTypeDef USBD_LL_DeInit(USBD_HandleTypeDef *pdev)
-{
- HAL_StatusTypeDef hal_status = HAL_OK;
- USBD_StatusTypeDef usb_status = USBD_OK;
-
- hal_status = HAL_PCD_DeInit(pdev->pData);
-
- usb_status = USBD_Get_USB_Status(hal_status);
-
- return usb_status;
-}
-
-/** Starts the low level portion of the device driver.
- * @param pdev: Device handle
- * @retval USBD status
- */
-USBD_StatusTypeDef USBD_LL_Start(USBD_HandleTypeDef *pdev) {
- HAL_StatusTypeDef hal_status = HAL_OK;
- USBD_StatusTypeDef usb_status = USBD_OK;
-
- hal_status = HAL_PCD_Start(pdev->pData);
-
- usb_status = USBD_Get_USB_Status(hal_status);
-
- return usb_status;
-}
-
-/** Stops the low level portion of the device driver.
- * @param pdev: Device handle
- * @retval USBD status
- */
-USBD_StatusTypeDef USBD_LL_Stop(USBD_HandleTypeDef *pdev) {
- HAL_StatusTypeDef hal_status = HAL_OK;
- USBD_StatusTypeDef usb_status = USBD_OK;
-
- hal_status = HAL_PCD_Stop(pdev->pData);
-
- usb_status = USBD_Get_USB_Status(hal_status);
-
- return usb_status;
-}
-
-/** Opens an endpoint of the low level driver.
- * @param pdev: Device handle
- * @param ep_addr: Endpoint number
- * @param ep_type: Endpoint type
- * @param ep_mps: Endpoint max packet size
- * @retval USBD status
- */
-USBD_StatusTypeDef USBD_LL_OpenEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr, uint8_t ep_type, uint16_t ep_mps) {
- HAL_StatusTypeDef hal_status = HAL_OK;
- USBD_StatusTypeDef usb_status = USBD_OK;
-
- hal_status = HAL_PCD_EP_Open(pdev->pData, ep_addr, ep_mps, ep_type);
-
- usb_status = USBD_Get_USB_Status(hal_status);
-
- return usb_status;
-}
-
-/** Closes an endpoint of the low level driver.
- * @param pdev: Device handle
- * @param ep_addr: Endpoint number
- * @retval USBD status
- */
-USBD_StatusTypeDef USBD_LL_CloseEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr) {
- HAL_StatusTypeDef hal_status = HAL_OK;
- USBD_StatusTypeDef usb_status = USBD_OK;
-
- hal_status = HAL_PCD_EP_Close(pdev->pData, ep_addr);
-
- usb_status = USBD_Get_USB_Status(hal_status);
-
- return usb_status;
-}
-
-/**
- * @brief Flushes an endpoint of the Low Level Driver.
- * @param pdev: Device handle
- * @param ep_addr: Endpoint number
- * @retval USBD status
- */
-USBD_StatusTypeDef USBD_LL_FlushEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr) {
- HAL_StatusTypeDef hal_status = HAL_OK;
- USBD_StatusTypeDef usb_status = USBD_OK;
-
- hal_status = HAL_PCD_EP_Flush(pdev->pData, ep_addr);
-
- usb_status = USBD_Get_USB_Status(hal_status);
-
- return usb_status;
-}
-
-/** Sets a Stall condition on an endpoint of the Low Level Driver.
- * @param pdev: Device handle
- * @param ep_addr: Endpoint number
- * @retval USBD status
- */
-USBD_StatusTypeDef USBD_LL_StallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr) {
- HAL_StatusTypeDef hal_status = HAL_OK;
- USBD_StatusTypeDef usb_status = USBD_OK;
-
- hal_status = HAL_PCD_EP_SetStall(pdev->pData, ep_addr);
-
- usb_status = USBD_Get_USB_Status(hal_status);
-
- return usb_status;
-}
-
-/** Clears a Stall condition on an endpoint of the Low Level Driver.
- * @param pdev: Device handle
- * @param ep_addr: Endpoint number
- * @retval USBD status
- */
-USBD_StatusTypeDef USBD_LL_ClearStallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr) {
- HAL_StatusTypeDef hal_status = HAL_OK;
- USBD_StatusTypeDef usb_status = USBD_OK;
-
- hal_status = HAL_PCD_EP_ClrStall(pdev->pData, ep_addr);
-
- usb_status = USBD_Get_USB_Status(hal_status);
-
- return usb_status;
-}
-
-/** Returns Stall condition.
- * @param pdev: Device handle
- * @param ep_addr: Endpoint number
- * @retval Stall (1: Yes, 0: No)
- */
-uint8_t USBD_LL_IsStallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr) {
- PCD_HandleTypeDef *hpcd = (PCD_HandleTypeDef*) pdev->pData;
-
- if((ep_addr & 0x80) == 0x80)
- {
- return hpcd->IN_ep[ep_addr & 0x7F].is_stall;
- }
- else
- {
- return hpcd->OUT_ep[ep_addr & 0x7F].is_stall;
- }
-}
-
-/** Assigns a USB address to the device.
- * @param pdev: Device handle
- * @param dev_addr: Device address
- * @retval USBD status
- */
-USBD_StatusTypeDef USBD_LL_SetUSBAddress(USBD_HandleTypeDef *pdev, uint8_t dev_addr) {
- HAL_StatusTypeDef hal_status = HAL_OK;
- USBD_StatusTypeDef usb_status = USBD_OK;
-
- hal_status = HAL_PCD_SetAddress(pdev->pData, dev_addr);
-
- usb_status = USBD_Get_USB_Status(hal_status);
-
- return usb_status;
-}
-
-/** Transmits data over an endpoint.
- * @param pdev: Device handle
- * @param ep_addr: Endpoint number
- * @param pbuf: Pointer to data to be sent
- * @param size: Data size
- * @retval USBD status
- */
-USBD_StatusTypeDef USBD_LL_Transmit(USBD_HandleTypeDef *pdev, uint8_t ep_addr, uint8_t *pbuf, uint32_t size) {
- HAL_StatusTypeDef hal_status = HAL_OK;
- USBD_StatusTypeDef usb_status = USBD_OK;
-
- hal_status = HAL_PCD_EP_Transmit(pdev->pData, ep_addr, pbuf, size);
-
- usb_status = USBD_Get_USB_Status(hal_status);
-
- return usb_status;
-}
-
-/** Prepares an endpoint for reception.
- * @param pdev: Device handle
- * @param ep_addr: Endpoint number
- * @param pbuf: Pointer to data to be received
- * @param size: Data size
- * @retval USBD status
- */
-USBD_StatusTypeDef USBD_LL_PrepareReceive(USBD_HandleTypeDef *pdev, uint8_t ep_addr, uint8_t *pbuf, uint32_t size) {
- HAL_StatusTypeDef hal_status = HAL_OK;
- USBD_StatusTypeDef usb_status = USBD_OK;
-
- hal_status = HAL_PCD_EP_Receive(pdev->pData, ep_addr, pbuf, size);
-
- usb_status = USBD_Get_USB_Status(hal_status);
-
- return usb_status;
-}
-
-/** Returns the last transfered packet size.
- * @param pdev: Device handle
- * @param ep_addr: Endpoint number
- * @retval Recived Data Size
- */
-uint32_t USBD_LL_GetRxDataSize(USBD_HandleTypeDef *pdev, uint8_t ep_addr) {
- return HAL_PCD_EP_GetRxCount((PCD_HandleTypeDef*) pdev->pData, ep_addr);
-}
-
-/** Send LPM message to user layer
- * @param hpcd: PCD handle
- * @param msg: LPM message
- * @retval None
- */
-void HAL_PCDEx_LPM_Callback(PCD_HandleTypeDef *hpcd, PCD_LPM_MsgTypeDef msg) {
- switch (msg) {
- case PCD_LPM_L0_ACTIVE:
- if (hpcd->Init.low_power_enable) {
- SystemClockConfig_Resume();
- /* Reset SLEEPDEEP bit of Cortex System Control Register. */
- SCB->SCR &= (uint32_t)~((uint32_t)(SCB_SCR_SLEEPDEEP_Msk | SCB_SCR_SLEEPONEXIT_Msk));
- }
- USBD_LL_Resume(hpcd->pData);
- break;
-
- case PCD_LPM_L1_ACTIVE:
- USBD_LL_Suspend(hpcd->pData);
-
- /* Enter in STOP mode. */
- if (hpcd->Init.low_power_enable) {
- /* Set SLEEPDEEP bit and SleepOnExit of Cortex System Control Register. */
- SCB->SCR |= (uint32_t)((uint32_t)(SCB_SCR_SLEEPDEEP_Msk | SCB_SCR_SLEEPONEXIT_Msk));
- }
- break;
- }
-}
-
-/** Delays routine for the USB Device Library.
- * @param Delay: Delay in ms
- * @retval None
- */
-void USBD_LL_Delay(uint32_t Delay) {
- HAL_Delay(Delay);
-}
-
-/** Static single allocation.
- * @param size: Size of allocated memory
- * @retval None
- */
-void *USBD_static_malloc(uint32_t size) {
- static uint32_t mem[(sizeof(USBD_CDC_HandleTypeDef)/4)+1];/* On 32-bit boundary */
- return mem;
-}
-
-/** Dummy memory free
- * @param p: Pointer to allocated memory address
- * @retval None
- */
-void USBD_static_free(void *p) {
-}
-
-/** Configures system clock after wake-up from USB resume callBack:
- * enable HSI, PLL and select PLL as system clock source.
- * @retval None
- */
-static void SystemClockConfig_Resume(void) {
-}
-
-/** Retuns the USB status depending on the HAL status:
- * @param hal_status: HAL status
- * @retval USB status
- */
-USBD_StatusTypeDef USBD_Get_USB_Status(HAL_StatusTypeDef hal_status) {
- USBD_StatusTypeDef usb_status = USBD_OK;
-
- switch (hal_status)
- {
- case HAL_OK :
- usb_status = USBD_OK;
- break;
- case HAL_ERROR :
- usb_status = USBD_FAIL;
- break;
- case HAL_BUSY :
- usb_status = USBD_BUSY;
- break;
- case HAL_TIMEOUT :
- usb_status = USBD_FAIL;
- break;
- default :
- usb_status = USBD_FAIL;
- break;
- }
- return usb_status;
-}
diff --git a/firmware/targets/f6/usb-glue/usbd_conf.h b/firmware/targets/f6/usb-glue/usbd_conf.h deleted file mode 100644 index 9e2a86f2..00000000 --- a/firmware/targets/f6/usb-glue/usbd_conf.h +++ /dev/null @@ -1,73 +0,0 @@ -#pragma once
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "stm32wbxx.h"
-#include "stm32wbxx_hal.h"
-
-#ifdef __cplusplus
- extern "C" {
-#endif
-
-#define USBD_MAX_NUM_INTERFACES 1U
-#define USBD_MAX_NUM_CONFIGURATION 1U
-#define USBD_MAX_STR_DESC_SIZ 512U
-#define USBD_DEBUG_LEVEL 0U
-#define USBD_LPM_ENABLED 0U
-#define USBD_SELF_POWERED 0U
-
-/****************************************/
-/* #define for FS and HS identification */
-#define DEVICE_FS 0
-
-/* Memory management macros */
-
-/** Alias for memory allocation. */
-#define USBD_malloc (void *)USBD_static_malloc
-
-/** Alias for memory release. */
-#define USBD_free USBD_static_free
-
-/** Alias for memory set. */
-#define USBD_memset memset
-
-/** Alias for memory copy. */
-#define USBD_memcpy memcpy
-
-/** Alias for delay. */
-#define USBD_Delay HAL_Delay
-
-/* DEBUG macros */
-
-#if (USBD_DEBUG_LEVEL > 0)
-#define USBD_UsrLog(...) printf(__VA_ARGS__);\
- printf("\n");
-#else
-#define USBD_UsrLog(...)
-#endif
-
-#if (USBD_DEBUG_LEVEL > 1)
-
-#define USBD_ErrLog(...) printf("ERROR: ") ;\
- printf(__VA_ARGS__);\
- printf("\n");
-#else
-#define USBD_ErrLog(...)
-#endif
-
-#if (USBD_DEBUG_LEVEL > 2)
-#define USBD_DbgLog(...) printf("DEBUG : ") ;\
- printf(__VA_ARGS__);\
- printf("\n");
-#else
-#define USBD_DbgLog(...)
-#endif
-
-void *USBD_static_malloc(uint32_t size);
-void USBD_static_free(void *p);
-
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/firmware/targets/f6/usb-glue/usbd_desc.c b/firmware/targets/f6/usb-glue/usbd_desc.c deleted file mode 100644 index 96cc2cda..00000000 --- a/firmware/targets/f6/usb-glue/usbd_desc.c +++ /dev/null @@ -1,206 +0,0 @@ -#include "usbd_core.h"
-#include "usbd_desc.h"
-#include "usbd_conf.h"
-#include "furi-hal-version.h"
-
-#define USBD_VID 1155
-#define USBD_LANGID_STRING 1033
-#define USBD_MANUFACTURER_STRING "Flipper Devices Inc."
-#define USBD_PID 22336
-#define USBD_CONFIGURATION_STRING "CDC Config"
-#define USBD_INTERFACE_STRING "CDC Interface"
-
-static void Get_SerialNum(void);
-static void IntToUnicode(uint32_t value, uint8_t * pbuf, uint8_t len);
-
-uint8_t* USBD_CDC_DeviceDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
-uint8_t* USBD_CDC_LangIDStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
-uint8_t* USBD_CDC_ManufacturerStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
-uint8_t* USBD_CDC_ProductStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
-uint8_t* USBD_CDC_SerialStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
-uint8_t* USBD_CDC_ConfigStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
-uint8_t* USBD_CDC_InterfaceStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
-
-USBD_DescriptorsTypeDef CDC_Desc = {
- USBD_CDC_DeviceDescriptor,
- USBD_CDC_LangIDStrDescriptor,
- USBD_CDC_ManufacturerStrDescriptor,
- USBD_CDC_ProductStrDescriptor,
- USBD_CDC_SerialStrDescriptor,
- USBD_CDC_ConfigStrDescriptor,
- USBD_CDC_InterfaceStrDescriptor
-};
-
-/** USB standard device descriptor. */
-__ALIGN_BEGIN uint8_t USBD_CDC_DeviceDesc[USB_LEN_DEV_DESC] __ALIGN_END = {
- 0x12, /*bLength */
- USB_DESC_TYPE_DEVICE, /*bDescriptorType*/
- 0x00, /*bcdUSB */
- 0x02,
- 0x02, /*bDeviceClass*/
- 0x02, /*bDeviceSubClass*/
- 0x00, /*bDeviceProtocol*/
- USB_MAX_EP0_SIZE, /*bMaxPacketSize*/
- LOBYTE(USBD_VID), /*idVendor*/
- HIBYTE(USBD_VID), /*idVendor*/
- LOBYTE(USBD_PID), /*idProduct*/
- HIBYTE(USBD_PID), /*idProduct*/
- 0x00, /*bcdDevice rel. 2.00*/
- 0x02,
- USBD_IDX_MFC_STR, /*Index of manufacturer string*/
- USBD_IDX_PRODUCT_STR, /*Index of product string*/
- USBD_IDX_SERIAL_STR, /*Index of serial number string*/
- USBD_MAX_NUM_CONFIGURATION /*bNumConfigurations*/
-};
-
-/* USB_DeviceDescriptor */
-
-/** USB lang indentifier descriptor. */
-__ALIGN_BEGIN uint8_t USBD_LangIDDesc[USB_LEN_LANGID_STR_DESC] __ALIGN_END = {
- USB_LEN_LANGID_STR_DESC,
- USB_DESC_TYPE_STRING,
- LOBYTE(USBD_LANGID_STRING),
- HIBYTE(USBD_LANGID_STRING)
-};
-
-/* Internal string descriptor. */
-__ALIGN_BEGIN uint8_t USBD_StrDesc[USBD_MAX_STR_DESC_SIZ] __ALIGN_END;
-
-__ALIGN_BEGIN uint8_t USBD_StringSerial[USB_SIZ_STRING_SERIAL] __ALIGN_END = {
- USB_SIZ_STRING_SERIAL,
- USB_DESC_TYPE_STRING,
-};
-
-/** Return the device descriptor
- * @param speed : Current device speed
- * @param length : Pointer to data length variable
- * @retval Pointer to descriptor buffer
- */
-uint8_t * USBD_CDC_DeviceDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) {
- UNUSED(speed);
- *length = sizeof(USBD_CDC_DeviceDesc);
- return USBD_CDC_DeviceDesc;
-}
-
-/** Return the LangID string descriptor
- * @param speed : Current device speed
- * @param length : Pointer to data length variable
- * @retval Pointer to descriptor buffer
- */
-uint8_t * USBD_CDC_LangIDStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) {
- UNUSED(speed);
- *length = sizeof(USBD_LangIDDesc);
- return USBD_LangIDDesc;
-}
-
-/** Return the product string descriptor
- * @param speed : Current device speed
- * @param length : Pointer to data length variable
- * @retval Pointer to descriptor buffer
- */
-uint8_t * USBD_CDC_ProductStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) {
- USBD_GetString((uint8_t*)furi_hal_version_get_device_name_ptr(), USBD_StrDesc, length);
- return USBD_StrDesc;
-}
-
-/** Return the manufacturer string descriptor
- * @param speed : Current device speed
- * @param length : Pointer to data length variable
- * @retval Pointer to descriptor buffer
- */
-uint8_t * USBD_CDC_ManufacturerStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) {
- UNUSED(speed);
- USBD_GetString((uint8_t *)USBD_MANUFACTURER_STRING, USBD_StrDesc, length);
- return USBD_StrDesc;
-}
-
-/** Return the serial number string descriptor
- * @param speed : Current device speed
- * @param length : Pointer to data length variable
- * @retval Pointer to descriptor buffer
- */
-uint8_t * USBD_CDC_SerialStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) {
- UNUSED(speed);
- *length = USB_SIZ_STRING_SERIAL;
-
- /* Update the serial number string descriptor with the data from the unique
- * ID */
- if(furi_hal_version_get_name_ptr()){
- char buffer[14] = "flip_";
- strncat(buffer, furi_hal_version_get_name_ptr(), 8);
- USBD_GetString((uint8_t*) buffer, USBD_StringSerial, length);
- } else {
- Get_SerialNum();
- }
-
- return (uint8_t *) USBD_StringSerial;
-}
-
-/** Return the configuration string descriptor
- * @param speed : Current device speed
- * @param length : Pointer to data length variable
- * @retval Pointer to descriptor buffer
- */
-uint8_t * USBD_CDC_ConfigStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) {
- if(speed == USBD_SPEED_HIGH) {
- USBD_GetString((uint8_t *)USBD_CONFIGURATION_STRING, USBD_StrDesc, length);
- } else {
- USBD_GetString((uint8_t *)USBD_CONFIGURATION_STRING, USBD_StrDesc, length);
- }
- return USBD_StrDesc;
-}
-
-/** Return the interface string descriptor
- * @param speed : Current device speed
- * @param length : Pointer to data length variable
- * @retval Pointer to descriptor buffer
- */
-uint8_t * USBD_CDC_InterfaceStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) {
- if(speed == 0) {
- USBD_GetString((uint8_t *)USBD_INTERFACE_STRING, USBD_StrDesc, length);
- } else {
- USBD_GetString((uint8_t *)USBD_INTERFACE_STRING, USBD_StrDesc, length);
- }
- return USBD_StrDesc;
-}
-
-/** Create the serial number string descriptor
- * @param None
- * @retval None
- */
-static void Get_SerialNum(void) {
- uint32_t deviceserial0, deviceserial1, deviceserial2;
-
- deviceserial0 = *(uint32_t *) DEVICE_ID1;
- deviceserial1 = *(uint32_t *) DEVICE_ID2;
- deviceserial2 = *(uint32_t *) DEVICE_ID3;
-
- deviceserial0 += deviceserial2;
-
- if (deviceserial0 != 0) {
- IntToUnicode(deviceserial0, &USBD_StringSerial[2], 8);
- IntToUnicode(deviceserial1, &USBD_StringSerial[18], 4);
- }
-}
-
-/** Convert Hex 32Bits value into char
- * @param value: value to convert
- * @param pbuf: pointer to the buffer
- * @param len: buffer length
- * @retval None
- */
-static void IntToUnicode(uint32_t value, uint8_t * pbuf, uint8_t len) {
- uint8_t idx = 0;
-
- for (idx = 0; idx < len; idx++) {
- if (((value >> 28)) < 0xA) {
- pbuf[2 * idx] = (value >> 28) + '0';
- } else {
- pbuf[2 * idx] = (value >> 28) + 'A' - 10;
- }
-
- value = value << 4;
-
- pbuf[2 * idx + 1] = 0;
- }
-}
diff --git a/firmware/targets/f6/usb-glue/usbd_desc.h b/firmware/targets/f6/usb-glue/usbd_desc.h deleted file mode 100644 index 795b33e4..00000000 --- a/firmware/targets/f6/usb-glue/usbd_desc.h +++ /dev/null @@ -1,19 +0,0 @@ -#pragma once
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include "usbd_def.h"
-
-#define DEVICE_ID1 (UID_BASE)
-#define DEVICE_ID2 (UID_BASE + 0x4)
-#define DEVICE_ID3 (UID_BASE + 0x8)
-
-#define USB_SIZ_STRING_SERIAL 0x1E
-
-extern USBD_DescriptorsTypeDef CDC_Desc;
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/firmware/targets/f7/Inc/stm32.h b/firmware/targets/f7/Inc/stm32.h new file mode 100644 index 00000000..45344fe3 --- /dev/null +++ b/firmware/targets/f7/Inc/stm32.h @@ -0,0 +1,52 @@ +#ifndef _STM32_H_ +#define _STM32_H_ + +/* modify bitfield */ +#define _BMD(reg, msk, val) (reg) = (((reg) & ~(msk)) | (val)) +/* set bitfield */ +#define _BST(reg, bits) (reg) = ((reg) | (bits)) +/* clear bitfield */ +#define _BCL(reg, bits) (reg) = ((reg) & ~(bits)) +/* wait until bitfield set */ +#define _WBS(reg, bits) while(((reg) & (bits)) == 0) +/* wait until bitfield clear */ +#define _WBC(reg, bits) while(((reg) & (bits)) != 0) +/* wait for bitfield value */ +#define _WVL(reg, msk, val) while(((reg) & (msk)) != (val)) +/* bit value */ +#define _BV(bit) (0x01 << (bit)) + +#if defined(STM32F0) + #include "STM32F0xx/Include/stm32f0xx.h" +#elif defined(STM32F1) + #include "STM32F1xx/Include/stm32f1xx.h" +#elif defined(STM32F2) + #include "STM32F2xx/Include/stm32f2xx.h" +#elif defined(STM32F3) + #include "STM32F3xx/Include/stm32f3xx.h" +#elif defined(STM32F4) + #include "STM32F4xx/Include/stm32f4xx.h" +#elif defined(STM32F7) + #include "STM32F7xx/Include/stm32f7xx.h" +#elif defined(STM32H7) + #include "STM32H7xx/Include/stm32h7xx.h" +#elif defined(STM32L0) + #include "STM32L0xx/Include/stm32l0xx.h" +#elif defined(STM32L1) + #include "STM32L1xx/Include/stm32l1xx.h" +#elif defined(STM32L4) + #include "STM32L4xx/Include/stm32l4xx.h" +#elif defined(STM32L5) + #include "STM32L5xx/Include/stm32l5xx.h" +#elif defined(STM32G0) + #include "STM32G0xx/Include/stm32g0xx.h" +#elif defined(STM32G4) + #include "STM32G4xx/Include/stm32g4xx.h" +#elif defined(STM32WB) + #include "STM32WBxx/Include/stm32wbxx.h" +#else + #error "STM32 family not defined" +#endif + + +#endif // _STM32_H_ diff --git a/firmware/targets/f7/Src/stm32wbxx_it.c b/firmware/targets/f7/Src/stm32wbxx_it.c index 01fbdc1d..6f70fb5e 100644 --- a/firmware/targets/f7/Src/stm32wbxx_it.c +++ b/firmware/targets/f7/Src/stm32wbxx_it.c @@ -2,8 +2,9 @@ #include "stm32wbxx_it.h"
#include "FreeRTOS.h"
#include "task.h"
+#include "usbd_core.h"
-extern PCD_HandleTypeDef hpcd_USB_FS;
+extern usbd_device udev;
extern COMP_HandleTypeDef hcomp1;
extern RTC_HandleTypeDef hrtc;
extern TIM_HandleTypeDef htim1;
@@ -20,7 +21,7 @@ void SysTick_Handler(void) { }
void USB_LP_IRQHandler(void) {
- HAL_PCD_IRQHandler(&hpcd_USB_FS);
+ usbd_poll(&udev);
}
void COMP_IRQHandler(void) {
diff --git a/firmware/targets/f7/furi-hal/furi-hal-usb-cdc.c b/firmware/targets/f7/furi-hal/furi-hal-usb-cdc.c new file mode 100644 index 00000000..09efbec3 --- /dev/null +++ b/firmware/targets/f7/furi-hal/furi-hal-usb-cdc.c @@ -0,0 +1,555 @@ +#include "furi-hal-version.h" +#include "furi-hal-usb_i.h" +#include "furi-hal-vcp_i.h" +#include "furi-hal-usb-cdc_i.h" +#include <furi.h> + +#include "usb.h" +#include "usb_cdc.h" + +#define CDC0_RXD_EP 0x01 +#define CDC0_TXD_EP 0x82 +#define CDC0_NTF_EP 0x83 + +#define CDC1_RXD_EP 0x04 +#define CDC1_TXD_EP 0x85 +#define CDC1_NTF_EP 0x86 + +#define CDC_NTF_SZ 0x08 + +struct CdcIadDescriptor { + struct usb_iad_descriptor comm_iad; + struct usb_interface_descriptor comm; + struct usb_cdc_header_desc cdc_hdr; + struct usb_cdc_call_mgmt_desc cdc_mgmt; + struct usb_cdc_acm_desc cdc_acm; + struct usb_cdc_union_desc cdc_union; + struct usb_endpoint_descriptor comm_ep; + struct usb_interface_descriptor data; + struct usb_endpoint_descriptor data_eprx; + struct usb_endpoint_descriptor data_eptx; +}; + +struct CdcConfigDescriptorSingle { + struct usb_config_descriptor config; + struct CdcIadDescriptor iad_0; +} __attribute__((packed)); + +struct CdcConfigDescriptorDual { + struct usb_config_descriptor config; + struct CdcIadDescriptor iad_0; + struct CdcIadDescriptor iad_1; +} __attribute__((packed)); + +static const struct usb_string_descriptor dev_manuf_desc = USB_STRING_DESC("Flipper Devices Inc."); + +/* Device descriptor */ +static const struct usb_device_descriptor cdc_device_desc = { + .bLength = sizeof(struct usb_device_descriptor), + .bDescriptorType = USB_DTYPE_DEVICE, + .bcdUSB = VERSION_BCD(2,0,0), + .bDeviceClass = USB_CLASS_IAD, + .bDeviceSubClass = USB_SUBCLASS_IAD, + .bDeviceProtocol = USB_PROTO_IAD, + .bMaxPacketSize0 = USB_EP0_SIZE, + .idVendor = 0x0483, + .idProduct = 0x5740, + .bcdDevice = VERSION_BCD(1,0,0), + .iManufacturer = UsbDevManuf, + .iProduct = UsbDevProduct, + .iSerialNumber = UsbDevSerial, + .bNumConfigurations = 1, +}; + +/* Device configuration descriptor - single mode*/ +static const struct CdcConfigDescriptorSingle cdc_cfg_desc_single = { + .config = { + .bLength = sizeof(struct usb_config_descriptor), + .bDescriptorType = USB_DTYPE_CONFIGURATION, + .wTotalLength = sizeof(struct CdcConfigDescriptorSingle), + .bNumInterfaces = 2, + + .bConfigurationValue = 1, + .iConfiguration = NO_DESCRIPTOR, + .bmAttributes = USB_CFG_ATTR_RESERVED | USB_CFG_ATTR_SELFPOWERED, + .bMaxPower = USB_CFG_POWER_MA(100), + }, + .iad_0 = { + .comm_iad = { + .bLength = sizeof(struct usb_iad_descriptor), + .bDescriptorType = USB_DTYPE_INTERFASEASSOC, + .bFirstInterface = 0, + .bInterfaceCount = 2, + .bFunctionClass = USB_CLASS_CDC, + .bFunctionSubClass = USB_CDC_SUBCLASS_ACM, + .bFunctionProtocol = USB_PROTO_NONE, + .iFunction = NO_DESCRIPTOR, + }, + .comm = { + .bLength = sizeof(struct usb_interface_descriptor), + .bDescriptorType = USB_DTYPE_INTERFACE, + .bInterfaceNumber = 0, + .bAlternateSetting = 0, + .bNumEndpoints = 1, + .bInterfaceClass = USB_CLASS_CDC, + .bInterfaceSubClass = USB_CDC_SUBCLASS_ACM, + .bInterfaceProtocol = USB_PROTO_NONE, + .iInterface = NO_DESCRIPTOR, + }, + .cdc_hdr = { + .bFunctionLength = sizeof(struct usb_cdc_header_desc), + .bDescriptorType = USB_DTYPE_CS_INTERFACE, + .bDescriptorSubType = USB_DTYPE_CDC_HEADER, + .bcdCDC = VERSION_BCD(1,1,0), + }, + .cdc_mgmt = { + .bFunctionLength = sizeof(struct usb_cdc_call_mgmt_desc), + .bDescriptorType = USB_DTYPE_CS_INTERFACE, + .bDescriptorSubType = USB_DTYPE_CDC_CALL_MANAGEMENT, + .bmCapabilities = 0, + .bDataInterface = 1, + }, + .cdc_acm = { + .bFunctionLength = sizeof(struct usb_cdc_acm_desc), + .bDescriptorType = USB_DTYPE_CS_INTERFACE, + .bDescriptorSubType = USB_DTYPE_CDC_ACM, + .bmCapabilities = 0, + }, + .cdc_union = { + .bFunctionLength = sizeof(struct usb_cdc_union_desc), + .bDescriptorType = USB_DTYPE_CS_INTERFACE, + .bDescriptorSubType = USB_DTYPE_CDC_UNION, + .bMasterInterface0 = 0, + .bSlaveInterface0 = 1, + }, + .comm_ep = { + .bLength = sizeof(struct usb_endpoint_descriptor), + .bDescriptorType = USB_DTYPE_ENDPOINT, + .bEndpointAddress = CDC0_NTF_EP, + .bmAttributes = USB_EPTYPE_INTERRUPT, + .wMaxPacketSize = CDC_NTF_SZ, + .bInterval = 0xFF, + }, + .data = { + .bLength = sizeof(struct usb_interface_descriptor), + .bDescriptorType = USB_DTYPE_INTERFACE, + .bInterfaceNumber = 1, + .bAlternateSetting = 0, + .bNumEndpoints = 2, + .bInterfaceClass = USB_CLASS_CDC_DATA, + .bInterfaceSubClass = USB_SUBCLASS_NONE, + .bInterfaceProtocol = USB_PROTO_NONE, + .iInterface = NO_DESCRIPTOR, + }, + .data_eprx = { + .bLength = sizeof(struct usb_endpoint_descriptor), + .bDescriptorType = USB_DTYPE_ENDPOINT, + .bEndpointAddress = CDC0_RXD_EP, + .bmAttributes = USB_EPTYPE_BULK, + .wMaxPacketSize = CDC_DATA_SZ, + .bInterval = 0x01, + }, + .data_eptx = { + .bLength = sizeof(struct usb_endpoint_descriptor), + .bDescriptorType = USB_DTYPE_ENDPOINT, + .bEndpointAddress = CDC0_TXD_EP, + .bmAttributes = USB_EPTYPE_BULK, + .wMaxPacketSize = CDC_DATA_SZ, + .bInterval = 0x01, + }, + }, +}; + +/* Device configuration descriptor - dual mode*/ +static const struct CdcConfigDescriptorDual cdc_cfg_desc_dual = { + .config = { + .bLength = sizeof(struct usb_config_descriptor), + .bDescriptorType = USB_DTYPE_CONFIGURATION, + .wTotalLength = sizeof(struct CdcConfigDescriptorDual), + .bNumInterfaces = 4, + + .bConfigurationValue = 1, + .iConfiguration = NO_DESCRIPTOR, + .bmAttributes = USB_CFG_ATTR_RESERVED | USB_CFG_ATTR_SELFPOWERED, + .bMaxPower = USB_CFG_POWER_MA(100), + }, + .iad_0 = { + .comm_iad = { + .bLength = sizeof(struct usb_iad_descriptor), + .bDescriptorType = USB_DTYPE_INTERFASEASSOC, + .bFirstInterface = 0, + .bInterfaceCount = 2, + .bFunctionClass = USB_CLASS_CDC, + .bFunctionSubClass = USB_CDC_SUBCLASS_ACM, + .bFunctionProtocol = USB_PROTO_NONE, + .iFunction = NO_DESCRIPTOR, + }, + .comm = { + .bLength = sizeof(struct usb_interface_descriptor), + .bDescriptorType = USB_DTYPE_INTERFACE, + .bInterfaceNumber = 0, + .bAlternateSetting = 0, + .bNumEndpoints = 1, + .bInterfaceClass = USB_CLASS_CDC, + .bInterfaceSubClass = USB_CDC_SUBCLASS_ACM, + .bInterfaceProtocol = USB_PROTO_NONE, + .iInterface = NO_DESCRIPTOR, + }, + .cdc_hdr = { + .bFunctionLength = sizeof(struct usb_cdc_header_desc), + .bDescriptorType = USB_DTYPE_CS_INTERFACE, + .bDescriptorSubType = USB_DTYPE_CDC_HEADER, + .bcdCDC = VERSION_BCD(1,1,0), + }, + .cdc_mgmt = { + .bFunctionLength = sizeof(struct usb_cdc_call_mgmt_desc), + .bDescriptorType = USB_DTYPE_CS_INTERFACE, + .bDescriptorSubType = USB_DTYPE_CDC_CALL_MANAGEMENT, + .bmCapabilities = 0, + .bDataInterface = 1, + }, + .cdc_acm = { + .bFunctionLength = sizeof(struct usb_cdc_acm_desc), + .bDescriptorType = USB_DTYPE_CS_INTERFACE, + .bDescriptorSubType = USB_DTYPE_CDC_ACM, + .bmCapabilities = 0, + }, + .cdc_union = { + .bFunctionLength = sizeof(struct usb_cdc_union_desc), + .bDescriptorType = USB_DTYPE_CS_INTERFACE, + .bDescriptorSubType = USB_DTYPE_CDC_UNION, + .bMasterInterface0 = 0, + .bSlaveInterface0 = 1, + }, + .comm_ep = { + .bLength = sizeof(struct usb_endpoint_descriptor), + .bDescriptorType = USB_DTYPE_ENDPOINT, + .bEndpointAddress = CDC0_NTF_EP, + .bmAttributes = USB_EPTYPE_INTERRUPT, + .wMaxPacketSize = CDC_NTF_SZ, + .bInterval = 0xFF, + }, + .data = { + .bLength = sizeof(struct usb_interface_descriptor), + .bDescriptorType = USB_DTYPE_INTERFACE, + .bInterfaceNumber = 1, + .bAlternateSetting = 0, + .bNumEndpoints = 2, + .bInterfaceClass = USB_CLASS_CDC_DATA, + .bInterfaceSubClass = USB_SUBCLASS_NONE, + .bInterfaceProtocol = USB_PROTO_NONE, + .iInterface = NO_DESCRIPTOR, + }, + .data_eprx = { + .bLength = sizeof(struct usb_endpoint_descriptor), + .bDescriptorType = USB_DTYPE_ENDPOINT, + .bEndpointAddress = CDC0_RXD_EP, + .bmAttributes = USB_EPTYPE_BULK, + .wMaxPacketSize = CDC_DATA_SZ, + .bInterval = 0x01, + }, + .data_eptx = { + .bLength = sizeof(struct usb_endpoint_descriptor), + .bDescriptorType = USB_DTYPE_ENDPOINT, + .bEndpointAddress = CDC0_TXD_EP, + .bmAttributes = USB_EPTYPE_BULK, + .wMaxPacketSize = CDC_DATA_SZ, + .bInterval = 0x01, + }, + }, + .iad_1 = { + .comm_iad = { + .bLength = sizeof(struct usb_iad_descriptor), + .bDescriptorType = USB_DTYPE_INTERFASEASSOC, + .bFirstInterface = 2, + .bInterfaceCount = 2, + .bFunctionClass = USB_CLASS_CDC, + .bFunctionSubClass = USB_CDC_SUBCLASS_ACM, + .bFunctionProtocol = USB_PROTO_NONE, + .iFunction = NO_DESCRIPTOR, + }, + .comm = { + .bLength = sizeof(struct usb_interface_descriptor), + .bDescriptorType = USB_DTYPE_INTERFACE, + .bInterfaceNumber = 2+0, + .bAlternateSetting = 0, + .bNumEndpoints = 1, + .bInterfaceClass = USB_CLASS_CDC, + .bInterfaceSubClass = USB_CDC_SUBCLASS_ACM, + .bInterfaceProtocol = USB_PROTO_NONE, + .iInterface = NO_DESCRIPTOR, + }, + .cdc_hdr = { + .bFunctionLength = sizeof(struct usb_cdc_header_desc), + .bDescriptorType = USB_DTYPE_CS_INTERFACE, + .bDescriptorSubType = USB_DTYPE_CDC_HEADER, + .bcdCDC = VERSION_BCD(1,1,0), + }, + .cdc_mgmt = { + .bFunctionLength = sizeof(struct usb_cdc_call_mgmt_desc), + .bDescriptorType = USB_DTYPE_CS_INTERFACE, + .bDescriptorSubType = USB_DTYPE_CDC_CALL_MANAGEMENT, + .bmCapabilities = 0, + .bDataInterface = 2+1, + }, + .cdc_acm = { + .bFunctionLength = sizeof(struct usb_cdc_acm_desc), + .bDescriptorType = USB_DTYPE_CS_INTERFACE, + .bDescriptorSubType = USB_DTYPE_CDC_ACM, + .bmCapabilities = 0, + }, + .cdc_union = { + .bFunctionLength = sizeof(struct usb_cdc_union_desc), + .bDescriptorType = USB_DTYPE_CS_INTERFACE, + .bDescriptorSubType = USB_DTYPE_CDC_UNION, + .bMasterInterface0 = 2+0, + .bSlaveInterface0 = 2+1, + }, + .comm_ep = { + .bLength = sizeof(struct usb_endpoint_descriptor), + .bDescriptorType = USB_DTYPE_ENDPOINT, + .bEndpointAddress = CDC1_NTF_EP, + .bmAttributes = USB_EPTYPE_INTERRUPT, + .wMaxPacketSize = CDC_NTF_SZ, + .bInterval = 0xFF, + }, + .data = { + .bLength = sizeof(struct usb_interface_descriptor), + .bDescriptorType = USB_DTYPE_INTERFACE, + .bInterfaceNumber = 2+1, + .bAlternateSetting = 0, + .bNumEndpoints = 2, + .bInterfaceClass = USB_CLASS_CDC_DATA, + .bInterfaceSubClass = USB_SUBCLASS_NONE, + .bInterfaceProtocol = USB_PROTO_NONE, + .iInterface = NO_DESCRIPTOR, + }, + .data_eprx = { + .bLength = sizeof(struct usb_endpoint_descriptor), + .bDescriptorType = USB_DTYPE_ENDPOINT, + .bEndpointAddress = CDC1_RXD_EP, + .bmAttributes = USB_EPTYPE_BULK, + .wMaxPacketSize = CDC_DATA_SZ, + .bInterval = 0x01, + }, + .data_eptx = { + .bLength = sizeof(struct usb_endpoint_descriptor), + .bDescriptorType = USB_DTYPE_ENDPOINT, + .bEndpointAddress = CDC1_TXD_EP, + .bmAttributes = USB_EPTYPE_BULK, + .wMaxPacketSize = CDC_DATA_SZ, + .bInterval = 0x01, + }, + }, +}; + +static struct usb_cdc_line_coding cdc_line = { + .dwDTERate = 38400, + .bCharFormat = USB_CDC_1_STOP_BITS, + .bParityType = USB_CDC_NO_PARITY, + .bDataBits = 8, +}; +static void cdc_init(usbd_device* dev, struct UsbInterface* intf); +static void cdc_deinit(usbd_device *dev); +static void cdc_on_wakeup(usbd_device *dev); +static void cdc_on_suspend(usbd_device *dev); + +static usbd_respond cdc_ep_config (usbd_device *dev, uint8_t cfg); +static usbd_respond cdc_control (usbd_device *dev, usbd_ctlreq *req, usbd_rqc_callback *callback); +static usbd_device* usb_dev; +static struct UsbInterface* cdc_if_cur = NULL; + +struct UsbInterface usb_cdc_single = { + .init = cdc_init, + .deinit = cdc_deinit, + .wakeup = cdc_on_wakeup, + .suspend = cdc_on_suspend, + + .dev_descr = (struct usb_device_descriptor*)&cdc_device_desc, + + .str_manuf_descr = (void*)&dev_manuf_desc, + .str_prod_descr = NULL, + .str_serial_descr = NULL, + + .cfg_descr = (void*)&cdc_cfg_desc_single, +}; + +struct UsbInterface usb_cdc_dual = { + .init = cdc_init, + .deinit = cdc_deinit, + .wakeup = cdc_on_wakeup, + .suspend = cdc_on_suspend, + + .dev_descr = (struct usb_device_descriptor*)&cdc_device_desc, + + .str_manuf_descr = (void*)&dev_manuf_desc, + .str_prod_descr = NULL, + .str_serial_descr = NULL, + + .cfg_descr = (void*)&cdc_cfg_desc_dual, +}; + +static void cdc_init(usbd_device* dev, struct UsbInterface* intf) { + usb_dev = dev; + cdc_if_cur = intf; + + char* name = (char*)furi_hal_version_get_device_name_ptr(); + uint8_t len = (name == NULL) ? (0) : (strlen(name)); + struct usb_string_descriptor* dev_prod_desc = furi_alloc(len * 2 + 2); + dev_prod_desc->bLength = len * 2 + 2; + dev_prod_desc->bDescriptorType = USB_DTYPE_STRING; + for (uint8_t i = 0; i < len; i++) + dev_prod_desc->wString[i] = name[i]; + + name = (char*)furi_hal_version_get_name_ptr(); + len = (name == NULL) ? (0) : (strlen(name)); + struct usb_string_descriptor* dev_serial_desc = furi_alloc((len + 5) * 2 + 2); + dev_serial_desc->bLength = (len + 5) * 2 + 2; + dev_serial_desc->bDescriptorType = USB_DTYPE_STRING; + memcpy(dev_serial_desc->wString, "f\0l\0i\0p\0_\0", 5*2); + for (uint8_t i = 0; i < len; i++) + dev_serial_desc->wString[i+5] = name[i]; + + cdc_if_cur->str_prod_descr = dev_prod_desc; + cdc_if_cur->str_serial_descr = dev_serial_desc; + + usbd_reg_config(dev, cdc_ep_config); + usbd_reg_control(dev, cdc_control); + + usbd_connect(dev, true); +} + +static void cdc_deinit(usbd_device *dev) { + usbd_reg_config(dev, NULL); + usbd_reg_control(dev, NULL); + + free(cdc_if_cur->str_prod_descr); + free(cdc_if_cur->str_serial_descr); + + cdc_if_cur = NULL; +} + +void furi_hal_cdc_send(uint8_t if_num, uint8_t* buf, uint16_t len) { + if (if_num == 0) + usbd_ep_write(usb_dev, CDC0_TXD_EP, buf, len); + else + usbd_ep_write(usb_dev, CDC1_TXD_EP, buf, len); +} + +int32_t furi_hal_cdc_receive(uint8_t if_num, uint8_t* buf, uint16_t max_len) { + if (if_num == 0) + return usbd_ep_read(usb_dev, CDC0_RXD_EP, buf, max_len); + else + return usbd_ep_read(usb_dev, CDC1_RXD_EP, buf, max_len); +} + +static void cdc_on_wakeup(usbd_device *dev) { + furi_hal_vcp_on_usb_resume(); +} + +static void cdc_on_suspend(usbd_device *dev) { + furi_hal_vcp_on_usb_suspend(); +} + +static void cdc_rx_ep_callback (usbd_device *dev, uint8_t event, uint8_t ep) { + if (ep == CDC0_RXD_EP) + furi_hal_vcp_on_cdc_rx(0); + else + furi_hal_vcp_on_cdc_rx(1); +} + +static void cdc_tx_ep_callback (usbd_device *dev, uint8_t event, uint8_t ep) { + if (ep == CDC0_TXD_EP) + furi_hal_vcp_on_cdc_tx_complete(0); + else + furi_hal_vcp_on_cdc_tx_complete(1); +} + +static void cdc_txrx_ep_callback (usbd_device *dev, uint8_t event, uint8_t ep) { + if (event == usbd_evt_eptx) { + cdc_tx_ep_callback(dev, event, ep); + } else { + cdc_rx_ep_callback(dev, event, ep); + } +} + +/* Configure endpoints */ +static usbd_respond cdc_ep_config (usbd_device *dev, uint8_t cfg) { + uint8_t if_cnt = ((struct usb_config_descriptor*)(cdc_if_cur->cfg_descr))->bNumInterfaces; + switch (cfg) { + case 0: + /* deconfiguring device */ + usbd_ep_deconfig(dev, CDC0_NTF_EP); + usbd_ep_deconfig(dev, CDC0_TXD_EP); + usbd_ep_deconfig(dev, CDC0_RXD_EP); + usbd_reg_endpoint(dev, CDC0_RXD_EP, 0); + usbd_reg_endpoint(dev, CDC0_TXD_EP, 0); + if (if_cnt == 4) { + usbd_ep_deconfig(dev, CDC1_NTF_EP); + usbd_ep_deconfig(dev, CDC1_TXD_EP); + usbd_ep_deconfig(dev, CDC1_RXD_EP); + usbd_reg_endpoint(dev, CDC1_RXD_EP, 0); + usbd_reg_endpoint(dev, CDC1_TXD_EP, 0); + } + return usbd_ack; + case 1: + /* configuring device */ + if ((CDC0_TXD_EP & 0x7F) != (CDC0_RXD_EP & 0x7F)) { + usbd_ep_config(dev, CDC0_RXD_EP, USB_EPTYPE_BULK | USB_EPTYPE_DBLBUF, CDC_DATA_SZ); + usbd_ep_config(dev, CDC0_TXD_EP, USB_EPTYPE_BULK | USB_EPTYPE_DBLBUF, CDC_DATA_SZ); + usbd_ep_config(dev, CDC0_NTF_EP, USB_EPTYPE_INTERRUPT, CDC_NTF_SZ); + usbd_reg_endpoint(dev, CDC0_RXD_EP, cdc_rx_ep_callback); + usbd_reg_endpoint(dev, CDC0_TXD_EP, cdc_tx_ep_callback); + } else { + usbd_ep_config(dev, CDC0_RXD_EP, USB_EPTYPE_BULK, CDC_DATA_SZ); + usbd_ep_config(dev, CDC0_TXD_EP, USB_EPTYPE_BULK, CDC_DATA_SZ); + usbd_ep_config(dev, CDC0_NTF_EP, USB_EPTYPE_INTERRUPT, CDC_NTF_SZ); + usbd_reg_endpoint(dev, CDC0_RXD_EP, cdc_txrx_ep_callback); + usbd_reg_endpoint(dev, CDC0_TXD_EP, cdc_txrx_ep_callback); + } + usbd_ep_write(dev, CDC0_TXD_EP, 0, 0); + + if (if_cnt == 4) { + if ((CDC1_TXD_EP & 0x7F) != (CDC1_RXD_EP & 0x7F)) { + usbd_ep_config(dev, CDC1_RXD_EP, USB_EPTYPE_BULK | USB_EPTYPE_DBLBUF, CDC_DATA_SZ); + usbd_ep_config(dev, CDC1_TXD_EP, USB_EPTYPE_BULK | USB_EPTYPE_DBLBUF, CDC_DATA_SZ); + usbd_ep_config(dev, CDC1_NTF_EP, USB_EPTYPE_INTERRUPT, CDC_NTF_SZ); + usbd_reg_endpoint(dev, CDC1_RXD_EP, cdc_rx_ep_callback); + usbd_reg_endpoint(dev, CDC1_TXD_EP, cdc_tx_ep_callback); + } else { + usbd_ep_config(dev, CDC1_RXD_EP, USB_EPTYPE_BULK, CDC_DATA_SZ); + usbd_ep_config(dev, CDC1_TXD_EP, USB_EPTYPE_BULK, CDC_DATA_SZ); + usbd_ep_config(dev, CDC1_NTF_EP, USB_EPTYPE_INTERRUPT, CDC_NTF_SZ); + usbd_reg_endpoint(dev, CDC1_RXD_EP, cdc_txrx_ep_callback); + usbd_reg_endpoint(dev, CDC1_TXD_EP, cdc_txrx_ep_callback); + } + usbd_ep_write(dev, CDC1_TXD_EP, 0, 0); + } + return usbd_ack; + default: + return usbd_fail; + } +} + +/* Control requests handler */ +static usbd_respond cdc_control (usbd_device *dev, usbd_ctlreq *req, usbd_rqc_callback *callback) { + /* CDC control requests */ + if (((USB_REQ_RECIPIENT | USB_REQ_TYPE) & req->bmRequestType) == (USB_REQ_INTERFACE | USB_REQ_CLASS) + && req->wIndex == 0 ) { + switch (req->bRequest) { + case USB_CDC_SET_CONTROL_LINE_STATE: + furi_hal_vcp_on_cdc_control_line(req->wValue); + return usbd_ack; + case USB_CDC_SET_LINE_CODING: + memcpy(&cdc_line, req->data, sizeof(cdc_line)); + return usbd_ack; + case USB_CDC_GET_LINE_CODING: + dev->status.data_ptr = &cdc_line; + dev->status.data_count = sizeof(cdc_line); + return usbd_ack; + default: + return usbd_fail; + } + } + return usbd_fail; +} diff --git a/firmware/targets/f7/furi-hal/furi-hal-usb-cdc_i.h b/firmware/targets/f7/furi-hal/furi-hal-usb-cdc_i.h new file mode 100644 index 00000000..636b3c04 --- /dev/null +++ b/firmware/targets/f7/furi-hal/furi-hal-usb-cdc_i.h @@ -0,0 +1,7 @@ +#pragma once + +#define CDC_DATA_SZ 0x40 + +void furi_hal_cdc_send(uint8_t if_num, uint8_t* buf, uint16_t len); + +int32_t furi_hal_cdc_receive(uint8_t if_num, uint8_t* buf, uint16_t max_len); diff --git a/firmware/targets/f7/furi-hal/furi-hal-usb-hid.c b/firmware/targets/f7/furi-hal/furi-hal-usb-hid.c new file mode 100644 index 00000000..38423610 --- /dev/null +++ b/firmware/targets/f7/furi-hal/furi-hal-usb-hid.c @@ -0,0 +1,264 @@ +#include "furi-hal-version.h" +#include "furi-hal-usb_i.h" +#include <furi.h> + +#include "usb.h" +#include "usb_hid.h" +#include "hid_usage_desktop.h" +#include "hid_usage_button.h" + +#define HID_RIN_EP 0x81 +#define HID_RIN_SZ 0x10 + +struct HidIadDescriptor { + struct usb_iad_descriptor hid_iad; + struct usb_interface_descriptor hid; + struct usb_hid_descriptor hid_desc; + struct usb_endpoint_descriptor hid_ep; +}; + +struct HidConfigDescriptor { + struct usb_config_descriptor config; + struct HidIadDescriptor iad_0; +} __attribute__((packed)); + +/* HID mouse report desscriptor. 2 axis 5 buttons */ +static const uint8_t hid_report_desc[] = { + HID_USAGE_PAGE(HID_PAGE_DESKTOP), + HID_USAGE(HID_DESKTOP_MOUSE), + HID_COLLECTION(HID_APPLICATION_COLLECTION), + HID_USAGE(HID_DESKTOP_POINTER), + HID_COLLECTION(HID_PHYSICAL_COLLECTION), + HID_USAGE(HID_DESKTOP_X), + HID_USAGE(HID_DESKTOP_Y), + HID_LOGICAL_MINIMUM(-127), + HID_LOGICAL_MAXIMUM(127), + HID_REPORT_SIZE(8), + HID_REPORT_COUNT(2), + HID_INPUT(HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_RELATIVE ), + HID_USAGE_PAGE(HID_PAGE_BUTTON), + HID_USAGE_MINIMUM(1), + HID_USAGE_MAXIMUM(5), + HID_LOGICAL_MINIMUM(0), + HID_LOGICAL_MAXIMUM(1), + HID_REPORT_SIZE(1), + HID_REPORT_COUNT(5), + HID_INPUT(HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE ), + HID_REPORT_SIZE(1), + HID_REPORT_COUNT(3), + HID_INPUT(HID_IOF_CONSTANT), + HID_END_COLLECTION, + HID_END_COLLECTION, +}; + +static const struct usb_string_descriptor dev_manuf_desc = USB_STRING_DESC("Logitech"); +static const struct usb_string_descriptor dev_prod_desc = USB_STRING_DESC("USB Receiver"); +static const struct usb_string_descriptor dev_serial_desc = USB_STRING_DESC("1234567890"); + +/* Device descriptor */ +static const struct usb_device_descriptor hid_device_desc = { + .bLength = sizeof(struct usb_device_descriptor), + .bDescriptorType = USB_DTYPE_DEVICE, + .bcdUSB = VERSION_BCD(2,0,0), + .bDeviceClass = USB_CLASS_IAD, + .bDeviceSubClass = USB_SUBCLASS_IAD, + .bDeviceProtocol = USB_PROTO_IAD, + .bMaxPacketSize0 = USB_EP0_SIZE, + .idVendor = 0x046d, + .idProduct = 0xc529, + .bcdDevice = VERSION_BCD(1,0,0), + .iManufacturer = UsbDevManuf, + .iProduct = UsbDevProduct, + .iSerialNumber = UsbDevSerial, + .bNumConfigurations = 1, +}; + +/* Device configuration descriptor */ +static const struct HidConfigDescriptor hid_cfg_desc = { + .config = { + .bLength = sizeof(struct usb_config_descriptor), + .bDescriptorType = USB_DTYPE_CONFIGURATION, + .wTotalLength = sizeof(struct HidConfigDescriptor), + .bNumInterfaces = 1, + .bConfigurationValue = 1, + .iConfiguration = NO_DESCRIPTOR, + .bmAttributes = USB_CFG_ATTR_RESERVED | USB_CFG_ATTR_SELFPOWERED, + .bMaxPower = USB_CFG_POWER_MA(100), + }, + .iad_0 = { + .hid_iad = { + .bLength = sizeof(struct usb_iad_descriptor), + .bDescriptorType = USB_DTYPE_INTERFASEASSOC, + .bFirstInterface = 0, + .bInterfaceCount = 1, + .bFunctionClass = USB_CLASS_PER_INTERFACE, + .bFunctionSubClass = USB_SUBCLASS_NONE, + .bFunctionProtocol = USB_PROTO_NONE, + .iFunction = NO_DESCRIPTOR, + }, + .hid = { + .bLength = sizeof(struct usb_interface_descriptor), + .bDescriptorType = USB_DTYPE_INTERFACE, + .bInterfaceNumber = 0, + .bAlternateSetting = 0, + .bNumEndpoints = 1, + .bInterfaceClass = USB_CLASS_HID, + .bInterfaceSubClass = USB_HID_SUBCLASS_NONBOOT, + .bInterfaceProtocol = USB_HID_PROTO_NONBOOT, + .iInterface = NO_DESCRIPTOR, + }, + .hid_desc = { + .bLength = sizeof(struct usb_hid_descriptor), + .bDescriptorType = USB_DTYPE_HID, + .bcdHID = VERSION_BCD(1,0,0), + .bCountryCode = USB_HID_COUNTRY_NONE, + .bNumDescriptors = 1, + .bDescriptorType0 = USB_DTYPE_HID_REPORT, + .wDescriptorLength0 = sizeof(hid_report_desc), + }, + .hid_ep = { + .bLength = sizeof(struct usb_endpoint_descriptor), + .bDescriptorType = USB_DTYPE_ENDPOINT, + .bEndpointAddress = HID_RIN_EP, + .bmAttributes = USB_EPTYPE_INTERRUPT, + .wMaxPacketSize = HID_RIN_SZ, + .bInterval = 50, + }, + }, +}; + +static struct { + int8_t x; + int8_t y; + uint8_t buttons; +} __attribute__((packed)) hid_report_data; + +static void hid_init(usbd_device* dev, struct UsbInterface* intf); +static void hid_deinit(usbd_device *dev); +static void hid_on_wakeup(usbd_device *dev); +static void hid_on_suspend(usbd_device *dev); + +static usbd_respond hid_ep_config (usbd_device *dev, uint8_t cfg); +static usbd_respond hid_control (usbd_device *dev, usbd_ctlreq *req, usbd_rqc_callback *callback); +static usbd_device* usb_dev; + +struct UsbInterface usb_hid = { + .init = hid_init, + .deinit = hid_deinit, + .wakeup = hid_on_wakeup, + .suspend = hid_on_suspend, + + .dev_descr = (struct usb_device_descriptor*)&hid_device_desc, + + .str_manuf_descr = (void*)&dev_manuf_desc, + .str_prod_descr = (void*)&dev_prod_desc, + .str_serial_descr = (void*)&dev_serial_desc, + + .cfg_descr = (void*)&hid_cfg_desc, +}; + +static void hid_init(usbd_device* dev, struct UsbInterface* intf) { + usb_dev = dev; + + usbd_reg_config(dev, hid_ep_config); + usbd_reg_control(dev, hid_control); + + usbd_connect(dev, true); +} + +static void hid_deinit(usbd_device *dev) { + usbd_reg_config(dev, NULL); + usbd_reg_control(dev, NULL); +} + +static void hid_on_wakeup(usbd_device *dev) { +} + +static void hid_on_suspend(usbd_device *dev) { +} + +/* HID mouse IN endpoint callback */ +static void hid_mouse_move(usbd_device *dev, uint8_t event, uint8_t ep) { + static uint8_t t = 0; + if (t < 0x10) { + hid_report_data.x = 1; + hid_report_data.y = 0; + } else if (t < 0x20) { + hid_report_data.x = 1; + hid_report_data.y = 1; + } else if (t < 0x30) { + hid_report_data.x = 0; + hid_report_data.y = 1; + } else if (t < 0x40) { + hid_report_data.x = -1; + hid_report_data.y = 1; + } else if (t < 0x50) { + hid_report_data.x = -1; + hid_report_data.y = 0; + } else if (t < 0x60) { + hid_report_data.x = -1; + hid_report_data.y = -1; + } else if (t < 0x70) { + hid_report_data.x = 0; + hid_report_data.y = -1; + } else { + hid_report_data.x = 1; + hid_report_data.y = -1; + } + t = (t + 1) & 0x7F; + usbd_ep_write(dev, ep, &hid_report_data, sizeof(hid_report_data)); +} + +/* Configure endpoints */ +static usbd_respond hid_ep_config (usbd_device *dev, uint8_t cfg) { + switch (cfg) { + case 0: + /* deconfiguring device */ + usbd_ep_deconfig(dev, HID_RIN_EP); + usbd_reg_endpoint(dev, HID_RIN_EP, 0); + return usbd_ack; + case 1: + /* configuring device */ + usbd_ep_config(dev, HID_RIN_EP, USB_EPTYPE_INTERRUPT, HID_RIN_SZ); + usbd_reg_endpoint(dev, HID_RIN_EP, hid_mouse_move); + usbd_ep_write(dev, HID_RIN_EP, 0, 0); + return usbd_ack; + default: + return usbd_fail; + } +} + +/* Control requests handler */ +static usbd_respond hid_control (usbd_device *dev, usbd_ctlreq *req, usbd_rqc_callback *callback) { + /* HID control requests */ + if (((USB_REQ_RECIPIENT | USB_REQ_TYPE) & req->bmRequestType) == (USB_REQ_INTERFACE | USB_REQ_CLASS) + && req->wIndex == 0 ) { + switch (req->bRequest) { + case USB_HID_SETIDLE: + return usbd_ack; + case USB_HID_GETREPORT: + dev->status.data_ptr = &hid_report_data; + dev->status.data_count = sizeof(hid_report_data); + return usbd_ack; + default: + return usbd_fail; + } + } + if (((USB_REQ_RECIPIENT | USB_REQ_TYPE) & req->bmRequestType) == (USB_REQ_INTERFACE | USB_REQ_STANDARD) + && req->wIndex == 0 + && req->bRequest == USB_STD_GET_DESCRIPTOR) { + switch (req->wValue >> 8) { + case USB_DTYPE_HID: + dev->status.data_ptr = (uint8_t*)&(hid_cfg_desc.iad_0.hid_desc); + dev->status.data_count = sizeof(hid_cfg_desc.iad_0.hid_desc); + return usbd_ack; + case USB_DTYPE_HID_REPORT: + dev->status.data_ptr = (uint8_t*)hid_report_desc; + dev->status.data_count = sizeof(hid_report_desc); + return usbd_ack; + default: + return usbd_fail; + } + } + return usbd_fail; +} diff --git a/firmware/targets/f7/furi-hal/furi-hal-usb.c b/firmware/targets/f7/furi-hal/furi-hal-usb.c new file mode 100644 index 00000000..fc5add2e --- /dev/null +++ b/firmware/targets/f7/furi-hal/furi-hal-usb.c @@ -0,0 +1,164 @@ +#include "furi-hal-version.h" +#include "furi-hal-usb_i.h" +#include "furi-hal-usb.h" +#include "furi-hal-vcp_i.h" +#include <furi.h> + +#include "usb.h" + +#define USB_RECONNECT_DELAY 500 + +extern struct UsbInterface usb_cdc_single; +extern struct UsbInterface usb_cdc_dual; +extern struct UsbInterface usb_hid; + +static struct UsbInterface* const usb_if_modes[UsbModesNum] = { + NULL, + &usb_cdc_single, + &usb_cdc_dual, + &usb_hid, + NULL,//&usb_hid_u2f, +}; + +static const struct usb_string_descriptor dev_lang_desc = USB_ARRAY_DESC(USB_LANGID_ENG_US); + +static uint32_t ubuf[0x20]; +usbd_device udev; + +static usbd_respond usb_descriptor_get (usbd_ctlreq *req, void **address, uint16_t *length); +static void susp_evt(usbd_device *dev, uint8_t event, uint8_t ep); +static void wkup_evt(usbd_device *dev, uint8_t event, uint8_t ep); + +struct UsbCfg{ + osTimerId_t reconnect_tmr; + UsbMode mode_cur; + UsbMode mode_next; + bool enabled; +} usb_config; + +static void furi_hal_usb_tmr_cb(void* context); + +/* Low-level init */ +void furi_hal_usb_init(void) { + + LL_GPIO_InitTypeDef GPIO_InitStruct = {0}; + LL_PWR_EnableVddUSB(); + + GPIO_InitStruct.Pin = LL_GPIO_PIN_11 | LL_GPIO_PIN_12; + GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE; + GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + GPIO_InitStruct.Pull = LL_GPIO_PULL_NO; + GPIO_InitStruct.Alternate = LL_GPIO_AF_10; + LL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + usbd_init(&udev, &usbd_hw, USB_EP0_SIZE, ubuf, sizeof(ubuf)); + usbd_enable(&udev, true); + + usbd_reg_descr(&udev, usb_descriptor_get); + usbd_reg_event(&udev, usbd_evt_susp, susp_evt); + usbd_reg_event(&udev, usbd_evt_wkup, wkup_evt); + + usb_config.enabled = false; + usb_config.reconnect_tmr = NULL; + HAL_NVIC_SetPriority(USB_LP_IRQn, 5, 0); + NVIC_EnableIRQ(USB_LP_IRQn); + + FURI_LOG_I("FuriHalUsb", "Init OK"); +} + +void furi_hal_usb_set_config(UsbMode new_mode) { + if (new_mode != usb_config.mode_cur) { + if (usb_config.enabled) { + usb_config.mode_next = new_mode; + if (usb_config.reconnect_tmr == NULL) + usb_config.reconnect_tmr = osTimerNew(furi_hal_usb_tmr_cb, osTimerOnce, NULL, NULL); + furi_hal_usb_disable(); + osTimerStart(usb_config.reconnect_tmr, USB_RECONNECT_DELAY); + } + else { + if (usb_if_modes[usb_config.mode_cur] != NULL) + usb_if_modes[usb_config.mode_cur]->deinit(&udev); + if (usb_if_modes[new_mode] != NULL) { + usb_if_modes[new_mode]->init(&udev, usb_if_modes[new_mode]); + FURI_LOG_I("FuriHalUsb", "USB mode change %u -> %u", usb_config.mode_cur, new_mode); + usb_config.enabled = true; + usb_config.mode_cur = new_mode; + } + } + } +} + +void furi_hal_usb_disable() { + if (usb_config.enabled) { + susp_evt(&udev, 0, 0); + usbd_connect(&udev, false); + usb_config.enabled = false; + FURI_LOG_I("FuriHalUsb", "USB Disable"); + } +} + +void furi_hal_usb_enable() { + if ((!usb_config.enabled) && (usb_if_modes[usb_config.mode_cur] != NULL)) { + usbd_connect(&udev, true); + usb_config.enabled = true; + FURI_LOG_I("FuriHalUsb", "USB Enable"); + } +} + +static void furi_hal_usb_tmr_cb(void* context) { + furi_hal_usb_set_config(usb_config.mode_next); +} + +/* Get device / configuration descriptors */ +static usbd_respond usb_descriptor_get (usbd_ctlreq *req, void **address, uint16_t *length) { + const uint8_t dtype = req->wValue >> 8; + const uint8_t dnumber = req->wValue & 0xFF; + const void* desc; + uint16_t len = 0; + if (usb_if_modes[usb_config.mode_cur] == NULL) + return usbd_fail; + + switch (dtype) { + case USB_DTYPE_DEVICE: + desc = usb_if_modes[usb_config.mode_cur]->dev_descr; + break; + case USB_DTYPE_CONFIGURATION: + desc = usb_if_modes[usb_config.mode_cur]->cfg_descr; + len = ((struct usb_string_descriptor*)(usb_if_modes[usb_config.mode_cur]->cfg_descr))->wString[0]; + break; + case USB_DTYPE_STRING: + if (dnumber == UsbDevLang) { + desc = &dev_lang_desc; + } else if (dnumber == UsbDevManuf) { + desc = usb_if_modes[usb_config.mode_cur]->str_manuf_descr; + } else if (dnumber == UsbDevProduct) { + desc = usb_if_modes[usb_config.mode_cur]->str_prod_descr; + } else if (dnumber == UsbDevSerial) { + desc = usb_if_modes[usb_config.mode_cur]->str_serial_descr; + } else + return usbd_fail; + break; + default: + return usbd_fail; + } + if (desc == NULL) + return usbd_fail; + + if (len == 0) { + len = ((struct usb_header_descriptor*)desc)->bLength; + } + *address = (void*)desc; + *length = len; + return usbd_ack; +} + +static void susp_evt(usbd_device *dev, uint8_t event, uint8_t ep) { + if (usb_if_modes[usb_config.mode_cur] != NULL) + usb_if_modes[usb_config.mode_cur]->suspend(&udev); +} + +static void wkup_evt(usbd_device *dev, uint8_t event, uint8_t ep) { + if (usb_if_modes[usb_config.mode_cur] != NULL) + usb_if_modes[usb_config.mode_cur]->wakeup(&udev); +} diff --git a/firmware/targets/f7/furi-hal/furi-hal-usb_i.h b/firmware/targets/f7/furi-hal/furi-hal-usb_i.h new file mode 100644 index 00000000..b329c51f --- /dev/null +++ b/firmware/targets/f7/furi-hal/furi-hal-usb_i.h @@ -0,0 +1,28 @@ +#pragma once + +#include "usb.h" + +#define USB_EP0_SIZE 8 + +/* String descriptors */ +enum UsbDevDescStr{ + UsbDevLang = 0, + UsbDevManuf = 1, + UsbDevProduct = 2, + UsbDevSerial = 3, +}; + +struct UsbInterface { + void (*init)(usbd_device *dev, struct UsbInterface* intf); + void (*deinit)(usbd_device *dev); + void (*wakeup)(usbd_device *dev); + void (*suspend)(usbd_device *dev); + + struct usb_device_descriptor* dev_descr; + + void* str_manuf_descr; + void* str_prod_descr; + void* str_serial_descr; + + void* cfg_descr; +}; diff --git a/firmware/targets/f7/furi-hal/furi-hal-vcp.c b/firmware/targets/f7/furi-hal/furi-hal-vcp.c index 88de32b5..e276c4a3 100644 --- a/firmware/targets/f7/furi-hal/furi-hal-vcp.c +++ b/firmware/targets/f7/furi-hal/furi-hal-vcp.c @@ -1,12 +1,12 @@ #include <furi-hal-vcp_i.h> +#include <furi-hal-usb-cdc_i.h> #include <furi.h> -#include <usbd_cdc_if.h> #include <stream_buffer.h> -#define FURI_HAL_VCP_RX_BUFFER_SIZE (APP_RX_DATA_SIZE * 5) - -extern USBD_HandleTypeDef hUsbDeviceFS; +#define APP_RX_DATA_SIZE CDC_DATA_SZ +#define APP_TX_DATA_SIZE CDC_DATA_SZ +#define FURI_HAL_VCP_RX_BUFFER_SIZE (APP_RX_DATA_SIZE * 16) typedef struct { volatile bool connected; @@ -22,8 +22,11 @@ static FuriHalVcp* furi_hal_vcp = NULL; static const uint8_t ascii_soh = 0x01; static const uint8_t ascii_eot = 0x04; +static uint8_t* vcp_rx_buf; + void furi_hal_vcp_init() { furi_hal_vcp = furi_alloc(sizeof(FuriHalVcp)); + vcp_rx_buf = furi_alloc(APP_RX_DATA_SIZE); furi_hal_vcp->connected = false; furi_hal_vcp->rx_stream = xStreamBufferCreate(FURI_HAL_VCP_RX_BUFFER_SIZE, 1); @@ -40,10 +43,8 @@ size_t furi_hal_vcp_rx(uint8_t* buffer, size_t size) { size_t received = xStreamBufferReceive(furi_hal_vcp->rx_stream, buffer, size, portMAX_DELAY); if(furi_hal_vcp->rx_stream_full - &&xStreamBufferSpacesAvailable(furi_hal_vcp->rx_stream) >= APP_RX_DATA_SIZE) { + && xStreamBufferSpacesAvailable(furi_hal_vcp->rx_stream) >= APP_RX_DATA_SIZE) { furi_hal_vcp->rx_stream_full = false; - // data accepted, start waiting for next packet - USBD_CDC_ReceivePacket(&hUsbDeviceFS); } return received; @@ -67,13 +68,9 @@ void furi_hal_vcp_tx(const uint8_t* buffer, size_t size) { batch_size = APP_TX_DATA_SIZE; } - if (CDC_Transmit_FS((uint8_t*)buffer, batch_size) == USBD_OK) { - size -= batch_size; - buffer += batch_size; - } else { - FURI_LOG_E("FuriHalVcp", "CDC_Transmit_FS failed"); - osDelay(50); - } + furi_hal_cdc_send(0, (uint8_t*)buffer, batch_size); + size -= batch_size; + buffer += batch_size; } } @@ -89,6 +86,8 @@ void furi_hal_vcp_on_usb_suspend() { } void furi_hal_vcp_on_cdc_control_line(uint8_t state) { + + BaseType_t xHigherPriorityTaskWoken = pdFALSE; // bit 0: DTR state, bit 1: RTS state // bool dtr = state & 0b01; bool dtr = state & 0b1; @@ -96,33 +95,45 @@ void furi_hal_vcp_on_cdc_control_line(uint8_t state) { if (dtr) { if (!furi_hal_vcp->connected) { furi_hal_vcp->connected = true; - furi_hal_vcp_on_cdc_rx(&ascii_soh, 1); // SOH + xStreamBufferSendFromISR(furi_hal_vcp->rx_stream, &ascii_soh, 1, &xHigherPriorityTaskWoken); // SOH + } } else { if (furi_hal_vcp->connected) { - furi_hal_vcp_on_cdc_rx(&ascii_eot, 1); // EOT + xStreamBufferSendFromISR(furi_hal_vcp->rx_stream, &ascii_eot, 1, &xHigherPriorityTaskWoken); // EOT furi_hal_vcp->connected = false; } } osSemaphoreRelease(furi_hal_vcp->tx_semaphore); + + portYIELD_FROM_ISR(xHigherPriorityTaskWoken); } -void furi_hal_vcp_on_cdc_rx(const uint8_t* buffer, size_t size) { +void furi_hal_vcp_on_cdc_rx(uint8_t if_num) { BaseType_t xHigherPriorityTaskWoken = pdFALSE; - size_t ret = xStreamBufferSendFromISR(furi_hal_vcp->rx_stream, buffer, size, &xHigherPriorityTaskWoken); - furi_check(ret == size); - - if (xStreamBufferSpacesAvailable(furi_hal_vcp->rx_stream) >= APP_RX_DATA_SIZE) { - USBD_CDC_ReceivePacket(&hUsbDeviceFS); - } else { - furi_hal_vcp->rx_stream_full = true; + + if (if_num == 0) { + uint16_t max_len = xStreamBufferSpacesAvailable(furi_hal_vcp->rx_stream); + if (max_len > 0) { + if (max_len > APP_RX_DATA_SIZE) + max_len = APP_RX_DATA_SIZE; + int32_t size = furi_hal_cdc_receive(0, vcp_rx_buf, max_len); + + if (size > 0) { + size_t ret = xStreamBufferSendFromISR(furi_hal_vcp->rx_stream, vcp_rx_buf, size, &xHigherPriorityTaskWoken); + furi_check(ret == size); + } + } else { + furi_hal_vcp->rx_stream_full = true; + }; } portYIELD_FROM_ISR(xHigherPriorityTaskWoken); } -void furi_hal_vcp_on_cdc_tx_complete(size_t size) { - osSemaphoreRelease(furi_hal_vcp->tx_semaphore); +void furi_hal_vcp_on_cdc_tx_complete(uint8_t if_num) { + if (if_num == 0) + osSemaphoreRelease(furi_hal_vcp->tx_semaphore); } diff --git a/firmware/targets/f7/furi-hal/furi-hal-vcp_i.h b/firmware/targets/f7/furi-hal/furi-hal-vcp_i.h index 05ddc6ad..9c8ccd73 100644 --- a/firmware/targets/f7/furi-hal/furi-hal-vcp_i.h +++ b/firmware/targets/f7/furi-hal/furi-hal-vcp_i.h @@ -8,6 +8,6 @@ void furi_hal_vcp_on_usb_suspend(); void furi_hal_vcp_on_cdc_control_line(uint8_t state); -void furi_hal_vcp_on_cdc_rx(const uint8_t* buffer, size_t size); +void furi_hal_vcp_on_cdc_rx(uint8_t if_num); -void furi_hal_vcp_on_cdc_tx_complete(size_t size); +void furi_hal_vcp_on_cdc_tx_complete(uint8_t if_num); diff --git a/firmware/targets/f7/furi-hal/furi-hal-version.c b/firmware/targets/f7/furi-hal/furi-hal-version.c index b0c3c350..5a98ab5e 100644 --- a/firmware/targets/f7/furi-hal/furi-hal-version.c +++ b/firmware/targets/f7/furi-hal/furi-hal-version.c @@ -8,10 +8,6 @@ #include "ble.h" #define FURI_HAL_VERSION_OTP_HEADER_MAGIC 0xBABE -#define FURI_HAL_VERSION_NAME_LENGTH 8 -#define FURI_HAL_VERSION_ARRAY_NAME_LENGTH (FURI_HAL_VERSION_NAME_LENGTH + 1) -/** BLE symbol + "Flipper " + name */ -#define FURI_HAL_VERSION_DEVICE_NAME_LENGTH (1 + 8 + FURI_HAL_VERSION_ARRAY_NAME_LENGTH) #define FURI_HAL_VERSION_OTP_ADDRESS OTP_AREA_BASE /** OTP Versions enum */ diff --git a/firmware/targets/f7/furi-hal/furi-hal.c b/firmware/targets/f7/furi-hal/furi-hal.c index 2ec06dd4..64b29ba7 100644 --- a/firmware/targets/f7/furi-hal/furi-hal.c +++ b/firmware/targets/f7/furi-hal/furi-hal.c @@ -3,7 +3,6 @@ #include <comp.h> #include <rtc.h> #include <tim.h> -#include <usb_device.h> #include <gpio.h> void furi_hal_init() { @@ -35,7 +34,8 @@ void furi_hal_init() { // VCP + USB furi_hal_vcp_init(); - MX_USB_Device_Init(); + furi_hal_usb_init(); + furi_hal_usb_set_config(UsbModeVcpSingle); FURI_LOG_I("HAL", "USB OK"); furi_hal_i2c_init(); diff --git a/firmware/targets/f7/target.mk b/firmware/targets/f7/target.mk index fe950149..d8ab0d5d 100644 --- a/firmware/targets/f7/target.mk +++ b/firmware/targets/f7/target.mk @@ -38,6 +38,7 @@ CFLAGS += \ CFLAGS += \ -I$(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Inc \ -I$(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Inc/Legacy \ + -I$(CUBE_DIR)/Drivers/CMSIS/Device/ST \ -I$(CUBE_DIR)/Drivers/CMSIS/Device/ST/STM32WBxx/Include \ -I$(CUBE_DIR)/Drivers/CMSIS/Include C_SOURCES += \ @@ -69,7 +70,6 @@ C_SOURCES += \ $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_spi.c \ $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_tim.c \ $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_usart.c \ - $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_usb.c \ $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_utils.c # FreeRTOS @@ -116,17 +116,10 @@ C_SOURCES += \ $(CUBE_DIR)/Middlewares/ST/STM32_WPAN/interface/patterns/ble_thread/tl/shci_tl_if.c \ $(CUBE_DIR)/Middlewares/ST/STM32_WPAN/interface/patterns/ble_thread/shci/shci.c -# USB glue +# USB stack CFLAGS += \ - -I$(TARGET_DIR)/usb-glue \ - -I$(CUBE_DIR)/Middlewares/ST/STM32_USB_Device_Library/Core/Inc \ - -I$(CUBE_DIR)/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc -C_SOURCES += \ - $(wildcard $(TARGET_DIR)/usb-glue/*.c) \ - $(CUBE_DIR)/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_core.c \ - $(CUBE_DIR)/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ctlreq.c \ - $(CUBE_DIR)/Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ioreq.c \ - $(CUBE_DIR)/Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c + -DSTM32WB \ + -DUSB_PMASIZE=0x400 # Furi HAL FURI_HAL_OS_DEBUG ?= 0 diff --git a/firmware/targets/f7/usb-glue/usb_device.c b/firmware/targets/f7/usb-glue/usb_device.c deleted file mode 100644 index 84e9143d..00000000 --- a/firmware/targets/f7/usb-glue/usb_device.c +++ /dev/null @@ -1,34 +0,0 @@ -#include "usb_device.h"
-
-#include "stm32wbxx.h"
-#include "stm32wbxx_hal.h"
-
-#include "usbd_def.h"
-#include "usbd_core.h"
-#include "usbd_desc.h"
-#include "usbd_cdc.h"
-#include "usbd_cdc_if.h"
-
-extern void Error_Handler(void);
-
-/* USB Device Core handle declaration. */
-USBD_HandleTypeDef hUsbDeviceFS;
-
-extern USBD_DescriptorsTypeDef CDC_Desc;
-
-/** Init USB device Library, add supported class and start the library */
-void MX_USB_Device_Init(void) {
- /* Init Device Library, add supported class and start the library. */
- if (USBD_Init(&hUsbDeviceFS, &CDC_Desc, DEVICE_FS) != USBD_OK) {
- Error_Handler();
- }
- if (USBD_RegisterClass(&hUsbDeviceFS, &USBD_CDC) != USBD_OK) {
- Error_Handler();
- }
- if (USBD_CDC_RegisterInterface(&hUsbDeviceFS, &USBD_Interface_fops_FS) != USBD_OK) {
- Error_Handler();
- }
- if (USBD_Start(&hUsbDeviceFS) != USBD_OK) {
- Error_Handler();
- }
-}
diff --git a/firmware/targets/f7/usb-glue/usb_device.h b/firmware/targets/f7/usb-glue/usb_device.h deleted file mode 100644 index 7d80e348..00000000 --- a/firmware/targets/f7/usb-glue/usb_device.h +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once
-
-#ifdef __cplusplus
- extern "C" {
-#endif
-
-void MX_USB_Device_Init();
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/firmware/targets/f7/usb-glue/usbd_cdc_if.c b/firmware/targets/f7/usb-glue/usbd_cdc_if.c deleted file mode 100644 index 6b905c84..00000000 --- a/firmware/targets/f7/usb-glue/usbd_cdc_if.c +++ /dev/null @@ -1,142 +0,0 @@ -#include "usbd_cdc_if.h"
-#include <furi-hal-vcp_i.h>
-
-extern USBD_HandleTypeDef hUsbDeviceFS;
-
-static int8_t CDC_Init_FS(void);
-static int8_t CDC_DeInit_FS(void);
-static int8_t CDC_Control_FS(uint8_t cmd, uint8_t* pbuf, uint16_t length);
-static int8_t CDC_Receive_FS(uint8_t* pbuf, uint32_t *Len);
-static int8_t CDC_TransmitCplt_FS(uint8_t *pbuf, uint32_t *Len, uint8_t epnum);
-
-USBD_CDC_ItfTypeDef USBD_Interface_fops_FS =
-{
- CDC_Init_FS,
- CDC_DeInit_FS,
- CDC_Control_FS,
- CDC_Receive_FS,
- CDC_TransmitCplt_FS
-};
-
-uint8_t UserRxBufferFS[APP_RX_DATA_SIZE];
-uint8_t UserTxBufferFS[APP_TX_DATA_SIZE];
-
-/** Initializes the CDC media low layer over the FS USB IP
- * @retval USBD_OK if all operations are OK else USBD_FAIL
- */
-static int8_t CDC_Init_FS(void) {
- /* Set Application Buffers */
- USBD_CDC_SetTxBuffer(&hUsbDeviceFS, UserTxBufferFS, 0);
- USBD_CDC_SetRxBuffer(&hUsbDeviceFS, UserRxBufferFS);
- return (USBD_OK);
-}
-
-/**
- * @brief DeInitializes the CDC media low layer
- * @retval USBD_OK if all operations are OK else USBD_FAIL
- */
-static int8_t CDC_DeInit_FS(void) {
- return (USBD_OK);
-}
-
-/** Manage the CDC class requests
- * @param cmd: Command code
- * @param pbuf: Buffer containing command data (request parameters)
- * @param length: Number of data to be sent (in bytes)
- * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
- */
-static int8_t CDC_Control_FS(uint8_t cmd, uint8_t* pbuf, uint16_t length) {
- if (cmd == CDC_SEND_ENCAPSULATED_COMMAND) {
- } else if (cmd == CDC_GET_ENCAPSULATED_RESPONSE) {
- } else if (cmd == CDC_SET_COMM_FEATURE) {
- } else if (cmd == CDC_GET_COMM_FEATURE) {
- } else if (cmd == CDC_CLEAR_COMM_FEATURE) {
- } else if (cmd == CDC_SET_LINE_CODING) {
- /*******************************************************************************/
- /* Line Coding Structure */
- /*-----------------------------------------------------------------------------*/
- /* Offset | Field | Size | Value | Description */
- /* 0 | dwDTERate | 4 | Number |Data terminal rate, in bits per second*/
- /* 4 | bCharFormat | 1 | Number | Stop bits */
- /* 0 - 1 Stop bit */
- /* 1 - 1.5 Stop bits */
- /* 2 - 2 Stop bits */
- /* 5 | bParityType | 1 | Number | Parity */
- /* 0 - None */
- /* 1 - Odd */
- /* 2 - Even */
- /* 3 - Mark */
- /* 4 - Space */
- /* 6 | bDataBits | 1 | Number Data bits (5, 6, 7, 8 or 16). */
- /*******************************************************************************/
- } else if (cmd == CDC_GET_LINE_CODING) {
- } else if (cmd == CDC_SET_CONTROL_LINE_STATE) {
- furi_hal_vcp_on_cdc_control_line(((USBD_SetupReqTypedef*)pbuf)->wValue);
- } else if (cmd == CDC_SEND_BREAK) {
- } else {
- }
-
- return (USBD_OK);
-}
-
-/** Data received over USB OUT endpoint are sent over CDC interface through this function.
- *
- * @note
- * This function will issue a NAK packet on any OUT packet received on
- * USB endpoint until exiting this function. If you exit this function
- * before transfer is complete on CDC interface (ie. using DMA controller)
- * it will result in receiving more data while previous ones are still
- * not sent.
- *
- * @param Buf: Buffer of data to be received
- * @param Len: Number of data received (in bytes)
- * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
- */
-static int8_t CDC_Receive_FS(uint8_t* Buf, uint32_t *Len) {
- if (*Len) {
- furi_hal_vcp_on_cdc_rx(Buf, *Len);
- } else {
- USBD_CDC_ReceivePacket(&hUsbDeviceFS);
- }
-
- return (USBD_OK);
-}
-
-/** CDC_Transmit_FS Data to send over USB IN endpoint are sent over CDC interface
- * through this function.
- * @param Buf: Buffer of data to be sent
- * @param Len: Number of data to be sent (in bytes)
- * @retval USBD_OK if all operations are OK else USBD_FAIL or USBD_BUSY
- */
-uint8_t CDC_Transmit_FS(uint8_t* Buf, uint16_t Len)
-{
- uint8_t result = USBD_OK;
-
- USBD_CDC_HandleTypeDef *hcdc = (USBD_CDC_HandleTypeDef*)hUsbDeviceFS.pClassData;
- if (hcdc->TxState != 0){
- return USBD_BUSY;
- }
- memcpy(UserTxBufferFS, Buf, Len);
- USBD_CDC_SetTxBuffer(&hUsbDeviceFS, UserTxBufferFS, Len);
- result = USBD_CDC_TransmitPacket(&hUsbDeviceFS);
-
- return result;
-}
-
-/** CDC_TransmitCplt_FS Data transmited callback
- *
- * @note
- * This function is IN transfer complete callback used to inform user that
- * the submitted Data is successfully sent over USB.
- *
- * @param Buf: Buffer of data to be received
- * @param Len: Number of data received (in bytes)
- * @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
- */
-static int8_t CDC_TransmitCplt_FS(uint8_t *Buf, uint32_t *Len, uint8_t epnum) {
- uint8_t result = USBD_OK;
-
- furi_hal_vcp_on_cdc_tx_complete(*Len);
-
- return result;
-}
diff --git a/firmware/targets/f7/usb-glue/usbd_cdc_if.h b/firmware/targets/f7/usb-glue/usbd_cdc_if.h deleted file mode 100644 index fc0aefbe..00000000 --- a/firmware/targets/f7/usb-glue/usbd_cdc_if.h +++ /dev/null @@ -1,22 +0,0 @@ -#pragma once
-
-#ifdef __cplusplus
- extern "C" {
-#endif
-
-/* Includes ------------------------------------------------------------------*/
-#include "usbd_cdc.h"
-
-/* Define size for the receive and transmit buffer over CDC */
-/* It's up to user to redefine and/or remove those define */
-#define APP_RX_DATA_SIZE CDC_DATA_FS_MAX_PACKET_SIZE
-#define APP_TX_DATA_SIZE CDC_DATA_FS_MAX_PACKET_SIZE
-
-/** CDC Interface callback. */
-extern USBD_CDC_ItfTypeDef USBD_Interface_fops_FS;
-
-uint8_t CDC_Transmit_FS(uint8_t* Buf, uint16_t Len);
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/firmware/targets/f7/usb-glue/usbd_conf.c b/firmware/targets/f7/usb-glue/usbd_conf.c deleted file mode 100644 index cbc137e5..00000000 --- a/firmware/targets/f7/usb-glue/usbd_conf.c +++ /dev/null @@ -1,506 +0,0 @@ -#include "stm32wbxx.h"
-#include "stm32wbxx_hal.h"
-
-#include <furi-hal-vcp_i.h>
-
-#include "usbd_def.h"
-#include "usbd_core.h"
-#include "usbd_cdc.h"
-
-PCD_HandleTypeDef hpcd_USB_FS;
-void Error_Handler(void);
-
-static USBD_StatusTypeDef USBD_Get_USB_Status(HAL_StatusTypeDef hal_status);
-
-static void SystemClockConfig_Resume(void);
-
-void HAL_PCD_MspInit(PCD_HandleTypeDef* pcdHandle) {
- GPIO_InitTypeDef GPIO_InitStruct = {0};
- if(pcdHandle->Instance==USB) {
- __HAL_RCC_GPIOA_CLK_ENABLE();
- /**USB GPIO Configuration
- PA11 ------> USB_DM
- PA12 ------> USB_DP
- */
- GPIO_InitStruct.Pin = GPIO_PIN_11|GPIO_PIN_12;
- GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
- GPIO_InitStruct.Pull = GPIO_NOPULL;
- GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
- GPIO_InitStruct.Alternate = GPIO_AF10_USB;
- HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
-
- /* Peripheral clock enable */
- __HAL_RCC_USB_CLK_ENABLE();
-
- /* Peripheral interrupt init */
- HAL_NVIC_SetPriority(USB_LP_IRQn, 5, 0);
- HAL_NVIC_EnableIRQ(USB_LP_IRQn);
- }
-}
-
-void HAL_PCD_MspDeInit(PCD_HandleTypeDef* pcdHandle) {
- if(pcdHandle->Instance==USB) {
- /* Peripheral clock disable */
- __HAL_RCC_USB_CLK_DISABLE();
-
- /**USB GPIO Configuration
- PA11 ------> USB_DM
- PA12 ------> USB_DP
- */
- HAL_GPIO_DeInit(GPIOA, GPIO_PIN_11|GPIO_PIN_12);
-
- /* Peripheral interrupt Deinit*/
- HAL_NVIC_DisableIRQ(USB_LP_IRQn);
- }
-}
-
-/** Setup stage callback
- * @param hpcd: PCD handle
- * @retval None
- */
-void HAL_PCD_SetupStageCallback(PCD_HandleTypeDef *hpcd) {
- USBD_LL_SetupStage((USBD_HandleTypeDef*)hpcd->pData, (uint8_t *)hpcd->Setup);
-}
-
-/** Data Out stage callback.
- * @param hpcd: PCD handle
- * @param epnum: Endpoint number
- * @retval None
- */
-void HAL_PCD_DataOutStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) {
- USBD_LL_DataOutStage((USBD_HandleTypeDef*)hpcd->pData, epnum, hpcd->OUT_ep[epnum].xfer_buff);
-}
-
-/** Data In stage callback.
- * @param hpcd: PCD handle
- * @param epnum: Endpoint number
- * @retval None
- */
-void HAL_PCD_DataInStageCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) {
- USBD_LL_DataInStage((USBD_HandleTypeDef*)hpcd->pData, epnum, hpcd->IN_ep[epnum].xfer_buff);
-}
-
-/** SOF callback.
- * @param hpcd: PCD handle
- * @retval None
- */
-void HAL_PCD_SOFCallback(PCD_HandleTypeDef *hpcd) {
- USBD_LL_SOF((USBD_HandleTypeDef*)hpcd->pData);
-}
-
-/** Reset callback.
- * @param hpcd: PCD handle
- * @retval None
- */
-void HAL_PCD_ResetCallback(PCD_HandleTypeDef *hpcd) {
- USBD_SpeedTypeDef speed = USBD_SPEED_FULL;
-
- if ( hpcd->Init.speed != PCD_SPEED_FULL) {
- Error_Handler();
- }
-
- /* Set Speed. */
- USBD_LL_SetSpeed((USBD_HandleTypeDef*)hpcd->pData, speed);
-
- /* Reset Device. */
- USBD_LL_Reset((USBD_HandleTypeDef*)hpcd->pData);
-}
-
-/** Suspend callback.
- * When Low power mode is enabled the debug cannot be used (IAR, Keil doesn't support it)
- * @param hpcd: PCD handle
- * @retval None
- */
-void HAL_PCD_SuspendCallback(PCD_HandleTypeDef *hpcd) {
- USBD_LL_Suspend((USBD_HandleTypeDef*)hpcd->pData);
-
- furi_hal_vcp_on_usb_suspend();
-
- if (hpcd->Init.low_power_enable) {
- /* Set SLEEPDEEP bit and SleepOnExit of Cortex System Control Register. */
- SCB->SCR |= (uint32_t)((uint32_t)(SCB_SCR_SLEEPDEEP_Msk | SCB_SCR_SLEEPONEXIT_Msk));
- }
-}
-
-/** Resume callback.
- * When Low power mode is enabled the debug cannot be used (IAR, Keil doesn't support it)
- * @param hpcd: PCD handle
- * @retval None
- */
-void HAL_PCD_ResumeCallback(PCD_HandleTypeDef *hpcd) {
- if (hpcd->Init.low_power_enable) {
- /* Reset SLEEPDEEP bit of Cortex System Control Register. */
- SCB->SCR &= (uint32_t)~((uint32_t)(SCB_SCR_SLEEPDEEP_Msk | SCB_SCR_SLEEPONEXIT_Msk));
- SystemClockConfig_Resume();
- }
-
- furi_hal_vcp_on_usb_resume();
-
- USBD_LL_Resume((USBD_HandleTypeDef*)hpcd->pData);
-}
-
-/** ISOOUTIncomplete callback.
- * @param hpcd: PCD handle
- * @param epnum: Endpoint number
- * @retval None
- */
-void HAL_PCD_ISOOUTIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) {
- USBD_LL_IsoOUTIncomplete((USBD_HandleTypeDef*)hpcd->pData, epnum);
-}
-
-/** ISOINIncomplete callback.
- * @param hpcd: PCD handle
- * @param epnum: Endpoint number
- * @retval None
- */
-void HAL_PCD_ISOINIncompleteCallback(PCD_HandleTypeDef *hpcd, uint8_t epnum) {
- USBD_LL_IsoINIncomplete((USBD_HandleTypeDef*)hpcd->pData, epnum);
-}
-
-/** Connect callback.
- * @param hpcd: PCD handle
- * @retval None
- */
-void HAL_PCD_ConnectCallback(PCD_HandleTypeDef *hpcd) {
- USBD_LL_DevConnected((USBD_HandleTypeDef*)hpcd->pData);
-}
-
-/** Disconnect callback.
- * @param hpcd: PCD handle
- * @retval None
- */
-void HAL_PCD_DisconnectCallback(PCD_HandleTypeDef *hpcd) {
- USBD_LL_DevDisconnected((USBD_HandleTypeDef*)hpcd->pData);
-}
-
-/** Initializes the low level portion of the device driver.
- * @param pdev: Device handle
- * @retval USBD status
- */
-USBD_StatusTypeDef USBD_LL_Init(USBD_HandleTypeDef *pdev) {
- /* Init USB Ip. */
- hpcd_USB_FS.pData = pdev;
-
- /* Link the driver to the stack. */
- pdev->pData = &hpcd_USB_FS;
-
- /* Enable USB power on Pwrctrl CR2 register. */
- HAL_PWREx_EnableVddUSB();
-
- hpcd_USB_FS.Instance = USB;
- hpcd_USB_FS.Init.dev_endpoints = 8;
- hpcd_USB_FS.Init.speed = PCD_SPEED_FULL;
- hpcd_USB_FS.Init.phy_itface = PCD_PHY_EMBEDDED;
- hpcd_USB_FS.Init.Sof_enable = DISABLE;
- hpcd_USB_FS.Init.low_power_enable = DISABLE;
- hpcd_USB_FS.Init.lpm_enable = DISABLE;
- hpcd_USB_FS.Init.battery_charging_enable = DISABLE;
-
- if (HAL_PCD_Init(&hpcd_USB_FS) != HAL_OK) {
- Error_Handler();
- }
-
- HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , 0x00 , PCD_SNG_BUF, 0x18);
- HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , 0x80 , PCD_SNG_BUF, 0x58);
-
- HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , 0x81 , PCD_SNG_BUF, 0xC0);
- HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , 0x01 , PCD_SNG_BUF, 0x110);
- HAL_PCDEx_PMAConfig((PCD_HandleTypeDef*)pdev->pData , 0x82 , PCD_SNG_BUF, 0x100);
-
- return USBD_OK;
-}
-
-/** De-Initializes the low level portion of the device driver.
- * @param pdev: Device handle
- * @retval USBD status
- */
-USBD_StatusTypeDef USBD_LL_DeInit(USBD_HandleTypeDef *pdev)
-{
- HAL_StatusTypeDef hal_status = HAL_OK;
- USBD_StatusTypeDef usb_status = USBD_OK;
-
- hal_status = HAL_PCD_DeInit(pdev->pData);
-
- usb_status = USBD_Get_USB_Status(hal_status);
-
- return usb_status;
-}
-
-/** Starts the low level portion of the device driver.
- * @param pdev: Device handle
- * @retval USBD status
- */
-USBD_StatusTypeDef USBD_LL_Start(USBD_HandleTypeDef *pdev) {
- HAL_StatusTypeDef hal_status = HAL_OK;
- USBD_StatusTypeDef usb_status = USBD_OK;
-
- hal_status = HAL_PCD_Start(pdev->pData);
-
- usb_status = USBD_Get_USB_Status(hal_status);
-
- return usb_status;
-}
-
-/** Stops the low level portion of the device driver.
- * @param pdev: Device handle
- * @retval USBD status
- */
-USBD_StatusTypeDef USBD_LL_Stop(USBD_HandleTypeDef *pdev) {
- HAL_StatusTypeDef hal_status = HAL_OK;
- USBD_StatusTypeDef usb_status = USBD_OK;
-
- hal_status = HAL_PCD_Stop(pdev->pData);
-
- usb_status = USBD_Get_USB_Status(hal_status);
-
- return usb_status;
-}
-
-/** Opens an endpoint of the low level driver.
- * @param pdev: Device handle
- * @param ep_addr: Endpoint number
- * @param ep_type: Endpoint type
- * @param ep_mps: Endpoint max packet size
- * @retval USBD status
- */
-USBD_StatusTypeDef USBD_LL_OpenEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr, uint8_t ep_type, uint16_t ep_mps) {
- HAL_StatusTypeDef hal_status = HAL_OK;
- USBD_StatusTypeDef usb_status = USBD_OK;
-
- hal_status = HAL_PCD_EP_Open(pdev->pData, ep_addr, ep_mps, ep_type);
-
- usb_status = USBD_Get_USB_Status(hal_status);
-
- return usb_status;
-}
-
-/** Closes an endpoint of the low level driver.
- * @param pdev: Device handle
- * @param ep_addr: Endpoint number
- * @retval USBD status
- */
-USBD_StatusTypeDef USBD_LL_CloseEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr) {
- HAL_StatusTypeDef hal_status = HAL_OK;
- USBD_StatusTypeDef usb_status = USBD_OK;
-
- hal_status = HAL_PCD_EP_Close(pdev->pData, ep_addr);
-
- usb_status = USBD_Get_USB_Status(hal_status);
-
- return usb_status;
-}
-
-/**
- * @brief Flushes an endpoint of the Low Level Driver.
- * @param pdev: Device handle
- * @param ep_addr: Endpoint number
- * @retval USBD status
- */
-USBD_StatusTypeDef USBD_LL_FlushEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr) {
- HAL_StatusTypeDef hal_status = HAL_OK;
- USBD_StatusTypeDef usb_status = USBD_OK;
-
- hal_status = HAL_PCD_EP_Flush(pdev->pData, ep_addr);
-
- usb_status = USBD_Get_USB_Status(hal_status);
-
- return usb_status;
-}
-
-/** Sets a Stall condition on an endpoint of the Low Level Driver.
- * @param pdev: Device handle
- * @param ep_addr: Endpoint number
- * @retval USBD status
- */
-USBD_StatusTypeDef USBD_LL_StallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr) {
- HAL_StatusTypeDef hal_status = HAL_OK;
- USBD_StatusTypeDef usb_status = USBD_OK;
-
- hal_status = HAL_PCD_EP_SetStall(pdev->pData, ep_addr);
-
- usb_status = USBD_Get_USB_Status(hal_status);
-
- return usb_status;
-}
-
-/** Clears a Stall condition on an endpoint of the Low Level Driver.
- * @param pdev: Device handle
- * @param ep_addr: Endpoint number
- * @retval USBD status
- */
-USBD_StatusTypeDef USBD_LL_ClearStallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr) {
- HAL_StatusTypeDef hal_status = HAL_OK;
- USBD_StatusTypeDef usb_status = USBD_OK;
-
- hal_status = HAL_PCD_EP_ClrStall(pdev->pData, ep_addr);
-
- usb_status = USBD_Get_USB_Status(hal_status);
-
- return usb_status;
-}
-
-/** Returns Stall condition.
- * @param pdev: Device handle
- * @param ep_addr: Endpoint number
- * @retval Stall (1: Yes, 0: No)
- */
-uint8_t USBD_LL_IsStallEP(USBD_HandleTypeDef *pdev, uint8_t ep_addr) {
- PCD_HandleTypeDef *hpcd = (PCD_HandleTypeDef*) pdev->pData;
-
- if((ep_addr & 0x80) == 0x80)
- {
- return hpcd->IN_ep[ep_addr & 0x7F].is_stall;
- }
- else
- {
- return hpcd->OUT_ep[ep_addr & 0x7F].is_stall;
- }
-}
-
-/** Assigns a USB address to the device.
- * @param pdev: Device handle
- * @param dev_addr: Device address
- * @retval USBD status
- */
-USBD_StatusTypeDef USBD_LL_SetUSBAddress(USBD_HandleTypeDef *pdev, uint8_t dev_addr) {
- HAL_StatusTypeDef hal_status = HAL_OK;
- USBD_StatusTypeDef usb_status = USBD_OK;
-
- hal_status = HAL_PCD_SetAddress(pdev->pData, dev_addr);
-
- usb_status = USBD_Get_USB_Status(hal_status);
-
- return usb_status;
-}
-
-/** Transmits data over an endpoint.
- * @param pdev: Device handle
- * @param ep_addr: Endpoint number
- * @param pbuf: Pointer to data to be sent
- * @param size: Data size
- * @retval USBD status
- */
-USBD_StatusTypeDef USBD_LL_Transmit(USBD_HandleTypeDef *pdev, uint8_t ep_addr, uint8_t *pbuf, uint32_t size) {
- HAL_StatusTypeDef hal_status = HAL_OK;
- USBD_StatusTypeDef usb_status = USBD_OK;
-
- hal_status = HAL_PCD_EP_Transmit(pdev->pData, ep_addr, pbuf, size);
-
- usb_status = USBD_Get_USB_Status(hal_status);
-
- return usb_status;
-}
-
-/** Prepares an endpoint for reception.
- * @param pdev: Device handle
- * @param ep_addr: Endpoint number
- * @param pbuf: Pointer to data to be received
- * @param size: Data size
- * @retval USBD status
- */
-USBD_StatusTypeDef USBD_LL_PrepareReceive(USBD_HandleTypeDef *pdev, uint8_t ep_addr, uint8_t *pbuf, uint32_t size) {
- HAL_StatusTypeDef hal_status = HAL_OK;
- USBD_StatusTypeDef usb_status = USBD_OK;
-
- hal_status = HAL_PCD_EP_Receive(pdev->pData, ep_addr, pbuf, size);
-
- usb_status = USBD_Get_USB_Status(hal_status);
-
- return usb_status;
-}
-
-/** Returns the last transfered packet size.
- * @param pdev: Device handle
- * @param ep_addr: Endpoint number
- * @retval Recived Data Size
- */
-uint32_t USBD_LL_GetRxDataSize(USBD_HandleTypeDef *pdev, uint8_t ep_addr) {
- return HAL_PCD_EP_GetRxCount((PCD_HandleTypeDef*) pdev->pData, ep_addr);
-}
-
-/** Send LPM message to user layer
- * @param hpcd: PCD handle
- * @param msg: LPM message
- * @retval None
- */
-void HAL_PCDEx_LPM_Callback(PCD_HandleTypeDef *hpcd, PCD_LPM_MsgTypeDef msg) {
- switch (msg) {
- case PCD_LPM_L0_ACTIVE:
- if (hpcd->Init.low_power_enable) {
- SystemClockConfig_Resume();
- /* Reset SLEEPDEEP bit of Cortex System Control Register. */
- SCB->SCR &= (uint32_t)~((uint32_t)(SCB_SCR_SLEEPDEEP_Msk | SCB_SCR_SLEEPONEXIT_Msk));
- }
- USBD_LL_Resume(hpcd->pData);
- break;
-
- case PCD_LPM_L1_ACTIVE:
- USBD_LL_Suspend(hpcd->pData);
-
- /* Enter in STOP mode. */
- if (hpcd->Init.low_power_enable) {
- /* Set SLEEPDEEP bit and SleepOnExit of Cortex System Control Register. */
- SCB->SCR |= (uint32_t)((uint32_t)(SCB_SCR_SLEEPDEEP_Msk | SCB_SCR_SLEEPONEXIT_Msk));
- }
- break;
- }
-}
-
-/** Delays routine for the USB Device Library.
- * @param Delay: Delay in ms
- * @retval None
- */
-void USBD_LL_Delay(uint32_t Delay) {
- HAL_Delay(Delay);
-}
-
-/** Static single allocation.
- * @param size: Size of allocated memory
- * @retval None
- */
-void *USBD_static_malloc(uint32_t size) {
- static uint32_t mem[(sizeof(USBD_CDC_HandleTypeDef)/4)+1];/* On 32-bit boundary */
- return mem;
-}
-
-/** Dummy memory free
- * @param p: Pointer to allocated memory address
- * @retval None
- */
-void USBD_static_free(void *p) {
-}
-
-/** Configures system clock after wake-up from USB resume callBack:
- * enable HSI, PLL and select PLL as system clock source.
- * @retval None
- */
-static void SystemClockConfig_Resume(void) {
-}
-
-/** Retuns the USB status depending on the HAL status:
- * @param hal_status: HAL status
- * @retval USB status
- */
-USBD_StatusTypeDef USBD_Get_USB_Status(HAL_StatusTypeDef hal_status) {
- USBD_StatusTypeDef usb_status = USBD_OK;
-
- switch (hal_status)
- {
- case HAL_OK :
- usb_status = USBD_OK;
- break;
- case HAL_ERROR :
- usb_status = USBD_FAIL;
- break;
- case HAL_BUSY :
- usb_status = USBD_BUSY;
- break;
- case HAL_TIMEOUT :
- usb_status = USBD_FAIL;
- break;
- default :
- usb_status = USBD_FAIL;
- break;
- }
- return usb_status;
-}
diff --git a/firmware/targets/f7/usb-glue/usbd_conf.h b/firmware/targets/f7/usb-glue/usbd_conf.h deleted file mode 100644 index 9e2a86f2..00000000 --- a/firmware/targets/f7/usb-glue/usbd_conf.h +++ /dev/null @@ -1,73 +0,0 @@ -#pragma once
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include "stm32wbxx.h"
-#include "stm32wbxx_hal.h"
-
-#ifdef __cplusplus
- extern "C" {
-#endif
-
-#define USBD_MAX_NUM_INTERFACES 1U
-#define USBD_MAX_NUM_CONFIGURATION 1U
-#define USBD_MAX_STR_DESC_SIZ 512U
-#define USBD_DEBUG_LEVEL 0U
-#define USBD_LPM_ENABLED 0U
-#define USBD_SELF_POWERED 0U
-
-/****************************************/
-/* #define for FS and HS identification */
-#define DEVICE_FS 0
-
-/* Memory management macros */
-
-/** Alias for memory allocation. */
-#define USBD_malloc (void *)USBD_static_malloc
-
-/** Alias for memory release. */
-#define USBD_free USBD_static_free
-
-/** Alias for memory set. */
-#define USBD_memset memset
-
-/** Alias for memory copy. */
-#define USBD_memcpy memcpy
-
-/** Alias for delay. */
-#define USBD_Delay HAL_Delay
-
-/* DEBUG macros */
-
-#if (USBD_DEBUG_LEVEL > 0)
-#define USBD_UsrLog(...) printf(__VA_ARGS__);\
- printf("\n");
-#else
-#define USBD_UsrLog(...)
-#endif
-
-#if (USBD_DEBUG_LEVEL > 1)
-
-#define USBD_ErrLog(...) printf("ERROR: ") ;\
- printf(__VA_ARGS__);\
- printf("\n");
-#else
-#define USBD_ErrLog(...)
-#endif
-
-#if (USBD_DEBUG_LEVEL > 2)
-#define USBD_DbgLog(...) printf("DEBUG : ") ;\
- printf(__VA_ARGS__);\
- printf("\n");
-#else
-#define USBD_DbgLog(...)
-#endif
-
-void *USBD_static_malloc(uint32_t size);
-void USBD_static_free(void *p);
-
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/firmware/targets/f7/usb-glue/usbd_desc.c b/firmware/targets/f7/usb-glue/usbd_desc.c deleted file mode 100644 index 96cc2cda..00000000 --- a/firmware/targets/f7/usb-glue/usbd_desc.c +++ /dev/null @@ -1,206 +0,0 @@ -#include "usbd_core.h"
-#include "usbd_desc.h"
-#include "usbd_conf.h"
-#include "furi-hal-version.h"
-
-#define USBD_VID 1155
-#define USBD_LANGID_STRING 1033
-#define USBD_MANUFACTURER_STRING "Flipper Devices Inc."
-#define USBD_PID 22336
-#define USBD_CONFIGURATION_STRING "CDC Config"
-#define USBD_INTERFACE_STRING "CDC Interface"
-
-static void Get_SerialNum(void);
-static void IntToUnicode(uint32_t value, uint8_t * pbuf, uint8_t len);
-
-uint8_t* USBD_CDC_DeviceDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
-uint8_t* USBD_CDC_LangIDStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
-uint8_t* USBD_CDC_ManufacturerStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
-uint8_t* USBD_CDC_ProductStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
-uint8_t* USBD_CDC_SerialStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
-uint8_t* USBD_CDC_ConfigStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
-uint8_t* USBD_CDC_InterfaceStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length);
-
-USBD_DescriptorsTypeDef CDC_Desc = {
- USBD_CDC_DeviceDescriptor,
- USBD_CDC_LangIDStrDescriptor,
- USBD_CDC_ManufacturerStrDescriptor,
- USBD_CDC_ProductStrDescriptor,
- USBD_CDC_SerialStrDescriptor,
- USBD_CDC_ConfigStrDescriptor,
- USBD_CDC_InterfaceStrDescriptor
-};
-
-/** USB standard device descriptor. */
-__ALIGN_BEGIN uint8_t USBD_CDC_DeviceDesc[USB_LEN_DEV_DESC] __ALIGN_END = {
- 0x12, /*bLength */
- USB_DESC_TYPE_DEVICE, /*bDescriptorType*/
- 0x00, /*bcdUSB */
- 0x02,
- 0x02, /*bDeviceClass*/
- 0x02, /*bDeviceSubClass*/
- 0x00, /*bDeviceProtocol*/
- USB_MAX_EP0_SIZE, /*bMaxPacketSize*/
- LOBYTE(USBD_VID), /*idVendor*/
- HIBYTE(USBD_VID), /*idVendor*/
- LOBYTE(USBD_PID), /*idProduct*/
- HIBYTE(USBD_PID), /*idProduct*/
- 0x00, /*bcdDevice rel. 2.00*/
- 0x02,
- USBD_IDX_MFC_STR, /*Index of manufacturer string*/
- USBD_IDX_PRODUCT_STR, /*Index of product string*/
- USBD_IDX_SERIAL_STR, /*Index of serial number string*/
- USBD_MAX_NUM_CONFIGURATION /*bNumConfigurations*/
-};
-
-/* USB_DeviceDescriptor */
-
-/** USB lang indentifier descriptor. */
-__ALIGN_BEGIN uint8_t USBD_LangIDDesc[USB_LEN_LANGID_STR_DESC] __ALIGN_END = {
- USB_LEN_LANGID_STR_DESC,
- USB_DESC_TYPE_STRING,
- LOBYTE(USBD_LANGID_STRING),
- HIBYTE(USBD_LANGID_STRING)
-};
-
-/* Internal string descriptor. */
-__ALIGN_BEGIN uint8_t USBD_StrDesc[USBD_MAX_STR_DESC_SIZ] __ALIGN_END;
-
-__ALIGN_BEGIN uint8_t USBD_StringSerial[USB_SIZ_STRING_SERIAL] __ALIGN_END = {
- USB_SIZ_STRING_SERIAL,
- USB_DESC_TYPE_STRING,
-};
-
-/** Return the device descriptor
- * @param speed : Current device speed
- * @param length : Pointer to data length variable
- * @retval Pointer to descriptor buffer
- */
-uint8_t * USBD_CDC_DeviceDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) {
- UNUSED(speed);
- *length = sizeof(USBD_CDC_DeviceDesc);
- return USBD_CDC_DeviceDesc;
-}
-
-/** Return the LangID string descriptor
- * @param speed : Current device speed
- * @param length : Pointer to data length variable
- * @retval Pointer to descriptor buffer
- */
-uint8_t * USBD_CDC_LangIDStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) {
- UNUSED(speed);
- *length = sizeof(USBD_LangIDDesc);
- return USBD_LangIDDesc;
-}
-
-/** Return the product string descriptor
- * @param speed : Current device speed
- * @param length : Pointer to data length variable
- * @retval Pointer to descriptor buffer
- */
-uint8_t * USBD_CDC_ProductStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) {
- USBD_GetString((uint8_t*)furi_hal_version_get_device_name_ptr(), USBD_StrDesc, length);
- return USBD_StrDesc;
-}
-
-/** Return the manufacturer string descriptor
- * @param speed : Current device speed
- * @param length : Pointer to data length variable
- * @retval Pointer to descriptor buffer
- */
-uint8_t * USBD_CDC_ManufacturerStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) {
- UNUSED(speed);
- USBD_GetString((uint8_t *)USBD_MANUFACTURER_STRING, USBD_StrDesc, length);
- return USBD_StrDesc;
-}
-
-/** Return the serial number string descriptor
- * @param speed : Current device speed
- * @param length : Pointer to data length variable
- * @retval Pointer to descriptor buffer
- */
-uint8_t * USBD_CDC_SerialStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) {
- UNUSED(speed);
- *length = USB_SIZ_STRING_SERIAL;
-
- /* Update the serial number string descriptor with the data from the unique
- * ID */
- if(furi_hal_version_get_name_ptr()){
- char buffer[14] = "flip_";
- strncat(buffer, furi_hal_version_get_name_ptr(), 8);
- USBD_GetString((uint8_t*) buffer, USBD_StringSerial, length);
- } else {
- Get_SerialNum();
- }
-
- return (uint8_t *) USBD_StringSerial;
-}
-
-/** Return the configuration string descriptor
- * @param speed : Current device speed
- * @param length : Pointer to data length variable
- * @retval Pointer to descriptor buffer
- */
-uint8_t * USBD_CDC_ConfigStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) {
- if(speed == USBD_SPEED_HIGH) {
- USBD_GetString((uint8_t *)USBD_CONFIGURATION_STRING, USBD_StrDesc, length);
- } else {
- USBD_GetString((uint8_t *)USBD_CONFIGURATION_STRING, USBD_StrDesc, length);
- }
- return USBD_StrDesc;
-}
-
-/** Return the interface string descriptor
- * @param speed : Current device speed
- * @param length : Pointer to data length variable
- * @retval Pointer to descriptor buffer
- */
-uint8_t * USBD_CDC_InterfaceStrDescriptor(USBD_SpeedTypeDef speed, uint16_t *length) {
- if(speed == 0) {
- USBD_GetString((uint8_t *)USBD_INTERFACE_STRING, USBD_StrDesc, length);
- } else {
- USBD_GetString((uint8_t *)USBD_INTERFACE_STRING, USBD_StrDesc, length);
- }
- return USBD_StrDesc;
-}
-
-/** Create the serial number string descriptor
- * @param None
- * @retval None
- */
-static void Get_SerialNum(void) {
- uint32_t deviceserial0, deviceserial1, deviceserial2;
-
- deviceserial0 = *(uint32_t *) DEVICE_ID1;
- deviceserial1 = *(uint32_t *) DEVICE_ID2;
- deviceserial2 = *(uint32_t *) DEVICE_ID3;
-
- deviceserial0 += deviceserial2;
-
- if (deviceserial0 != 0) {
- IntToUnicode(deviceserial0, &USBD_StringSerial[2], 8);
- IntToUnicode(deviceserial1, &USBD_StringSerial[18], 4);
- }
-}
-
-/** Convert Hex 32Bits value into char
- * @param value: value to convert
- * @param pbuf: pointer to the buffer
- * @param len: buffer length
- * @retval None
- */
-static void IntToUnicode(uint32_t value, uint8_t * pbuf, uint8_t len) {
- uint8_t idx = 0;
-
- for (idx = 0; idx < len; idx++) {
- if (((value >> 28)) < 0xA) {
- pbuf[2 * idx] = (value >> 28) + '0';
- } else {
- pbuf[2 * idx] = (value >> 28) + 'A' - 10;
- }
-
- value = value << 4;
-
- pbuf[2 * idx + 1] = 0;
- }
-}
diff --git a/firmware/targets/f7/usb-glue/usbd_desc.h b/firmware/targets/f7/usb-glue/usbd_desc.h deleted file mode 100644 index 795b33e4..00000000 --- a/firmware/targets/f7/usb-glue/usbd_desc.h +++ /dev/null @@ -1,19 +0,0 @@ -#pragma once
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include "usbd_def.h"
-
-#define DEVICE_ID1 (UID_BASE)
-#define DEVICE_ID2 (UID_BASE + 0x4)
-#define DEVICE_ID3 (UID_BASE + 0x8)
-
-#define USB_SIZ_STRING_SERIAL 0x1E
-
-extern USBD_DescriptorsTypeDef CDC_Desc;
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/firmware/targets/furi-hal-include/furi-hal-usb.h b/firmware/targets/furi-hal-include/furi-hal-usb.h new file mode 100644 index 00000000..8e70a597 --- /dev/null +++ b/firmware/targets/furi-hal-include/furi-hal-usb.h @@ -0,0 +1,21 @@ +#pragma once + +#include "usb.h" + +typedef enum { + UsbModeNone, + UsbModeVcpSingle, + UsbModeVcpDual, + UsbModeHid, + UsbModeU2F, + + UsbModesNum, +} UsbMode; + +void furi_hal_usb_init(); + +void furi_hal_usb_set_config(UsbMode mode); + +void furi_hal_usb_disable(); + +void furi_hal_usb_enable(); diff --git a/firmware/targets/furi-hal-include/furi-hal-version.h b/firmware/targets/furi-hal-include/furi-hal-version.h index 12b2e63c..ac28188e 100644 --- a/firmware/targets/furi-hal-include/furi-hal-version.h +++ b/firmware/targets/furi-hal-include/furi-hal-version.h @@ -14,6 +14,11 @@ extern "C" { #endif +#define FURI_HAL_VERSION_NAME_LENGTH 8 +#define FURI_HAL_VERSION_ARRAY_NAME_LENGTH (FURI_HAL_VERSION_NAME_LENGTH + 1) +/** BLE symbol + "Flipper " + name */ +#define FURI_HAL_VERSION_DEVICE_NAME_LENGTH (1 + 8 + FURI_HAL_VERSION_ARRAY_NAME_LENGTH) + /** Device Colors */ typedef enum { FuriHalVersionColorUnknown=0x00, diff --git a/firmware/targets/furi-hal-include/furi-hal.h b/firmware/targets/furi-hal-include/furi-hal.h index 1318c614..7f344f87 100644 --- a/firmware/targets/furi-hal-include/furi-hal.h +++ b/firmware/targets/furi-hal-include/furi-hal.h @@ -33,6 +33,7 @@ template <unsigned int N> struct STOP_EXTERNING_ME {}; #include "furi-hal-ibutton.h" #include "furi-hal-rfid.h" #include "furi-hal-nfc.h" +#include "furi-hal-usb.h" /** Init furi-hal */ void furi_hal_init(); |