Bladeren bron

refactor: replace HW capabilities bitmapped field to getinfo() function call.

Dmitry 8 jaren geleden
bovenliggende
commit
f2755360aa

+ 21 - 2
inc/usbd_core.h

@@ -59,10 +59,19 @@
 #define usbd_lane_dcp       4   /**<\brief Lanes connected to dedicated charging port.*/
 /** @} */
 
-/** \name USB HW capabilities
+/**\anchor USBD_HW_CAPS
+ * \name USB HW capabilities and status
  * @{ */
 #define USBD_HW_ADDRFST     (1 << 0)    /**<\brief Set address before STATUS_OUT.*/
 #define USBD_HW_BC          (1 << 1)    /**<\brief Battery charging detection supported.*/
+#define USND_HW_HS          (1 << 2)    /**<\brief High speed supported.*/
+#define USBD_HW_ENABLED     (1 << 3)    /**<\brief USB device emabled. */
+#define USBD_HW_ENUMSPEED   (2 << 4)    /**<\brief USB device enumerated speed*/
+#define USBD_HW_SPEED_NC    (0 << 4)    /**<\brief Not connected */
+#define USBD_HW_SPEED_LS    (1 << 4)    /**<\brief Low speed */
+#define USBD_HW_SPEED_FS    (2 << 4)    /**<\brief Full speed */
+#define USBD_HW_SPEED_HS    (3 << 4)    /**<\brief High speed */
+
 /** @} */
 /** @} */
 
@@ -212,6 +221,10 @@ typedef usbd_respond (*usbd_cfg_callback)(usbd_device *dev, uint8_t cfg);
 
 /**\addtogroup USBD_HW
  * @{ */
+/**\brief Get USB device status and capabilities.
+ * \return Hardware status and capabilities \ref USBD_HW_CAPS */
+
+typedef uint32_t (*usbd_hw_getinfo)(void);
 
 /**\brief Enables or disables USB hardware
  * \param enable Enables USB when TRUE disables otherwise.
@@ -291,7 +304,7 @@ typedef uint16_t (*usbd_hw_get_serialno)(void *buffer);
 
 /**\brief Represents a hardware USB driver call table.*/
 struct usbd_driver {
-    uint32_t                caps;               /**<\brief HW capabilities */
+    usbd_hw_getinfo         getinfo;            /**<\copybrief usbd_hw_getinfo */
     usbd_hw_enable          enable;             /**<\copybrief usbd_hw_enable */
     usbd_hw_connect         connect;            /**<\copybrief usbd_hw_connect */
     usbd_hw_setaddr         setaddr;            /**<\copybrief usbd_hw_setaddr */
@@ -452,6 +465,12 @@ inline static uint8_t usbd_connect(usbd_device *dev, bool connect) {
     return dev->driver->connect(connect);
 }
 
+/**<\brief Retrieves status and capabilities.
+ * \return current HW status, enumeration speed and capabilities /ref USBD_HW_CAPS */
+inline static uint32_t usbd_getinfo(usbd_device *dev) {
+    return dev->driver->getinfo();
+}
+
 #endif //(__ASSEMBLER__)
 /** @} */
 /** @} */

+ 1 - 0
src/memmap.inc

@@ -93,6 +93,7 @@
     #define GPIOG           0x40012000
     #define GPIO_CRL        0x00
     #define GPIO_CRH        0x04
+    #define GPIO_IDR        0x08
     #define GPIO_BSRR       0x10
 
 

+ 1 - 1
src/usbd_core.c

@@ -101,7 +101,7 @@ static usbd_respond usbd_process_devrq (usbd_device *dev, usbd_ctlreq *req) {
         req->data[1] = 0;
         return usbd_ack;
     case USB_STD_SET_ADDRESS:
-        if (dev->driver->caps & USBD_HW_ADDRFST) {
+        if (usbd_getinfo(dev) & USBD_HW_ADDRFST) {
             usbd_set_address(dev, req);
         } else {
             dev->complete_callback = usbd_set_address;

+ 13 - 1
src/usbd_stm32f103_devfs.c

@@ -35,6 +35,8 @@
 #define EP_TX_VALID(epr)    EP_TOGGLE_SET((epr), USB_EP_TX_VALID,                   USB_EPTX_STAT)
 #define EP_RX_VALID(epr)    EP_TOGGLE_SET((epr), USB_EP_RX_VALID,                   USB_EPRX_STAT)
 
+#define STATUS_VAL(x)       (x)
+
 typedef union _pma_table pma_table;
 
 #if defined(STM32F302x8) || defined(STM32F302xE) || defined(STM32F303xE)
@@ -158,6 +160,16 @@ static uint16_t get_next_pma(uint16_t sz) {
     }
 }
 
+uint32_t getinfo(void) {
+    if (!(RCC->APB1ENR & RCC_APB1ENR_USBEN)) return STATUS_VAL(0);
+#if defined(USBD_DP_PORT) && defined(USBD_DP_PIN)
+    if (USBD_DP_PORT->IDR && _BV(USBD_DP_PIN)) return STATUS_VAL(USBD_HW_ENABLED | USBD_HW_SPEED_FS);
+    return STATUS_VAL(USBD_HW_ENABLED);
+#else
+    return STATUS_VAL(USBD_HW_ENABLED | USBD_HW_SPEED_FS);
+#endif
+}
+
 void ep_setstall(uint8_t ep, bool stall) {
     volatile uint16_t *reg = EPR(ep);
     /* ISOCHRONOUS endpoint can't be stalled or unstalled */
@@ -524,7 +536,7 @@ uint16_t get_serialno_desc(void *buffer) {
 }
 
 const struct usbd_driver usbd_devfs = {
-    0,
+    getinfo,
     enable,
     connect,
     setaddr,

+ 21 - 2
src/usbd_stm32f103_devfs_asm.S

@@ -136,7 +136,7 @@
     .globl  usbd_devfs_asm
     .align  2
 usbd_devfs_asm:
-    .long   0
+    .long   _getinfo
     .long   _enable
     .long   _connect
     .long   _setaddr
@@ -323,8 +323,27 @@ _enable:
     .size   _enable, . - _enable
 
     .thumb_func
-    .type   _ep_setstall, %function
+    .type   _getinfo, %function
+_getinfo:
+    movs    r0, #0
+    ldr     r2, =#RCC_BASE
+    ldr     r1, [r2, #RCC_APB1ENR]
+    lsrs    r1, #24                     //USBEN -> CF
+    bcc     .L_getinfo_end
+    adds    r0, #USBD_HW_ENABLED
+#if defined(USBD_DP_PORT) && defined(USBD_DP_PIN)
+    ldr     r2, =#USBD_DP_PORT
+    ldr     r1, [r2, #GPIO_IDR]
+    lsrs    r1, #USBD_DP_PIN            //USBD_DP_PIN -> CF
+    bcc     .L_getinfo_end
+#endif
+    adds    r0, #USBD_HW_SPEED_FS
+.L_getinfo_end:
+    bx      lr
+    .size   _getinfo, . - _getinfo
 
+    .thumb_func
+    .type   _ep_setstall, %function
 /*void ep_settall(uint8_t ep, bool stall)
  * in  R0 <- endpoint number
  * in  R1 <- 0 if unstall, !0 if stall

+ 9 - 1
src/usbd_stm32f429_otgfs.c

@@ -27,6 +27,8 @@
 
 #define RX_FIFO_SZ      ((4 * MAX_CONTROL_EP + 6) + ((MAX_RX_PACKET / 4) + 1) + (MAX_EP * 2) + 1)
 
+#define STATUS_VAL(x)   (USBD_HW_ADDRFST | (x))
+
 USB_OTG_GlobalTypeDef * const OTG  = (void*)(USB_OTG_FS_PERIPH_BASE + USB_OTG_GLOBAL_BASE);
 USB_OTG_DeviceTypeDef * const OTGD = (void*)(USB_OTG_FS_PERIPH_BASE + USB_OTG_DEVICE_BASE);
 volatile uint32_t * const OTGPCTL  = (void*)(USB_OTG_FS_PERIPH_BASE + USB_OTG_PCGCCTL_BASE);
@@ -55,6 +57,12 @@ inline static void Flush_TX(uint8_t ep) {
     _WBC(OTG->GRSTCTL, USB_OTG_GRSTCTL_TXFFLSH);
 }
 
+uint32_t getinfo(void) {
+    if (!(RCC->AHB2ENR & RCC_AHB2ENR_OTGFSEN)) return STATUS_VAL(0);
+    if (!(OTGD->DCTL & USB_OTG_DCTL_SDIS)) return STATUS_VAL(USBD_HW_ENABLED | USBD_HW_SPEED_FS);
+    return STATUS_VAL(USBD_HW_ENABLED);
+}
+
 void ep_setstall(uint8_t ep, bool stall) {
     if (ep & 0x80) {
         ep &= 0x7F;
@@ -456,7 +464,7 @@ uint16_t get_serialno_desc(void *buffer) {
 }
 
 const struct usbd_driver usbd_otgfs = {
-    USBD_HW_ADDRFST,
+    getinfo,
     enable,
     connect,
     setaddr,

+ 9 - 2
src/usbd_stm32l052_devfs.c

@@ -28,7 +28,6 @@
 #define USB_EP_SWBUF_TX     USB_EP_DTOG_RX
 #define USB_EP_SWBUF_RX     USB_EP_DTOG_TX
 
-
 #define EP_TOGGLE_SET(epr, bits, mask) *(epr) = (*(epr) ^ (bits)) & (USB_EPREG_MASK | (mask))
 
 #define EP_TX_STALL(epr)    EP_TOGGLE_SET((epr), USB_EP_TX_STALL,                   USB_EPTX_STAT)
@@ -40,6 +39,8 @@
 #define EP_TX_VALID(epr)    EP_TOGGLE_SET((epr), USB_EP_TX_VALID,                   USB_EPTX_STAT)
 #define EP_RX_VALID(epr)    EP_TOGGLE_SET((epr), USB_EP_RX_VALID,                   USB_EPRX_STAT)
 
+#define STATUS_VAL(x)   (USBD_HW_BC | (x))
+
 typedef struct {
     uint16_t    addr;
     uint16_t    cnt;
@@ -95,6 +96,12 @@ static uint16_t get_next_pma(uint16_t sz) {
     }
 }
 
+uint32_t getinfo(void) {
+    if (!(RCC->APB1ENR & RCC_APB1ENR_USBEN)) return STATUS_VAL(0);
+    if (USB->BCDR & USB_BCDR_DPPU) return STATUS_VAL(USBD_HW_ENABLED | USBD_HW_SPEED_FS);
+    return STATUS_VAL(USBD_HW_ENABLED);
+}
+
 void ep_setstall(uint8_t ep, bool stall) {
     volatile uint16_t *reg = EPR(ep);
     /* ISOCHRONOUS endpoint can't be stalled or unstalled */
@@ -450,7 +457,7 @@ uint16_t get_serialno_desc(void *buffer) {
 }
 
 const struct usbd_driver usbd_devfs = {
-    USBD_HW_BC,
+    getinfo,
     enable,
     connect,
     setaddr,

+ 19 - 2
src/usbd_stm32l052_devfs_asm.S

@@ -83,7 +83,7 @@
     .globl  usbd_devfs_asm
     .align  2
 usbd_devfs_asm:
-    .long   USBD_HW_BC
+    .long   _getinfo
     .long   _enable
     .long   _connect
     .long   _setaddr
@@ -256,8 +256,25 @@ _enable:
     .size   _enable, . - _enable
 
     .thumb_func
-    .type   _ep_setstall, %function
+    .type   _getinfo, %function
+_getinfo:
+    movs    r0, #USBD_HW_BC
+    ldr     r2, =#RCC_BASE
+    ldr     r1, [r2, #RCC_APB1ENR]
+    lsrs    r1, #24                     //USBEN -> CF
+    bcc     .L_getinfo_end
+    adds    r0, #USBD_HW_ENABLED
+    ldr     r2, =#USB_REGBASE
+    ldr     r1, [r2, #USB_BCDR]
+    lsrs    r1, #15                     //DPPU -> CF
+    bcc     .L_getinfo_end
+    adds    r0, #USBD_HW_SPEED_FS
+.L_getinfo_end:
+    bx      lr
+    .size   _getinfo, . - _getinfo
 
+    .thumb_func
+    .type   _ep_setstall, %function
 /*void ep_settall(uint8_t ep, bool stall)
  * in  R0 <- endpoint number
  * in  R1 <- 0 if unstall, !0 if stall

+ 9 - 2
src/usbd_stm32l100_devfs.c

@@ -28,7 +28,6 @@
 #define USB_EP_SWBUF_TX     USB_EP_DTOG_RX
 #define USB_EP_SWBUF_RX     USB_EP_DTOG_TX
 
-
 #define EP_TOGGLE_SET(epr, bits, mask) *(epr) = (*(epr) ^ (bits)) & (USB_EPREG_MASK | (mask))
 
 #define EP_TX_STALL(epr)    EP_TOGGLE_SET((epr), USB_EP_TX_STALL,                   USB_EPTX_STAT)
@@ -40,6 +39,8 @@
 #define EP_TX_VALID(epr)    EP_TOGGLE_SET((epr), USB_EP_TX_VALID,                   USB_EPTX_STAT)
 #define EP_RX_VALID(epr)    EP_TOGGLE_SET((epr), USB_EP_RX_VALID,                   USB_EPRX_STAT)
 
+#define STATUS_VAL(x)       (x)
+
 typedef struct {
     uint16_t    addr;
     uint16_t    :16;
@@ -96,6 +97,12 @@ static uint16_t get_next_pma(uint16_t sz) {
     }
 }
 
+uint32_t getinfo(void) {
+    if (!(RCC->APB1ENR & RCC_APB1ENR_USBEN)) return STATUS_VAL(0);
+    if (SYSCFG->PMC & SYSCFG_PMC_USB_PU) return STATUS_VAL(USBD_HW_ENABLED | USBD_HW_SPEED_FS);
+    return STATUS_VAL(USBD_HW_ENABLED);
+}
+
 void ep_setstall(uint8_t ep, bool stall) {
     volatile uint16_t *reg = EPR(ep);
     /* ISOCHRONOUS endpoint can't be stalled or unstalled */
@@ -439,7 +446,7 @@ uint16_t get_serialno_desc(void *buffer) {
 }
 
 const struct usbd_driver usbd_devfs = {
-    0,
+    getinfo,
     enable,
     connect,
     setaddr,

+ 18 - 1
src/usbd_stm32l100_devfs_asm.S

@@ -84,7 +84,7 @@
     .globl  usbd_devfs_asm
     .align  2
 usbd_devfs_asm:
-    .long   0
+    .long   _getinfo
     .long   _enable
     .long   _connect
     .long   _setaddr
@@ -173,6 +173,23 @@ _connect:
     bx      lr
     .size   _connect, . - _connect
 
+    .thumb_func
+    .type   _getinfo, %function
+_getinfo:
+    movs    r0, 0
+    ldr     r2, =#RCC_BASE
+    ldr     r1, [r2, #RCC_APB1ENR]
+    lsrs    r1, #24                     //USBEN -> CF
+    bcc     .L_getinfo_end
+    adds    r0, #USBD_HW_ENABLED
+    ldr     r2, =#SYSCFG_BASE
+    ldr     r1, [r2, #SYSCFG_PMC]
+    lsrs    r1, #1                      //PU -> CF
+    bcc     .L_getinfo_end
+    adds    r0, #USBD_HW_SPEED_FS
+.L_getinfo_end:
+    bx      lr
+    .size   _getinfo, . - _getinfo
 
     .thumb_func
     .type   _setaddr, %function

+ 9 - 1
src/usbd_stm32l476_otgfs.c

@@ -27,6 +27,8 @@
 
 #define RX_FIFO_SZ      ((4 * MAX_CONTROL_EP + 6) + ((MAX_RX_PACKET / 4) + 1) + (MAX_EP * 2) + 1)
 
+#define STATUS_VAL(x)   (USBD_HW_BC | USBD_HW_ADDRFST | (x))
+
 USB_OTG_GlobalTypeDef * const OTG  = (void*)(USB_OTG_FS_PERIPH_BASE + USB_OTG_GLOBAL_BASE);
 USB_OTG_DeviceTypeDef * const OTGD = (void*)(USB_OTG_FS_PERIPH_BASE + USB_OTG_DEVICE_BASE);
 volatile uint32_t * const OTGPCTL  = (void*)(USB_OTG_FS_PERIPH_BASE + USB_OTG_PCGCCTL_BASE);
@@ -55,6 +57,12 @@ inline static void Flush_TX(uint8_t ep) {
     _WBC(OTG->GRSTCTL, USB_OTG_GRSTCTL_TXFFLSH);
 }
 
+uint32_t getinfo(void) {
+    if (!(RCC->AHB2ENR & RCC_AHB2ENR_OTGFSEN)) return STATUS_VAL(0);
+    if (!(OTGD->DCTL & USB_OTG_DCTL_SDIS)) return STATUS_VAL(USBD_HW_ENABLED | USBD_HW_SPEED_FS);
+    return STATUS_VAL(USBD_HW_ENABLED);
+}
+
 void ep_setstall(uint8_t ep, bool stall) {
     if (ep & 0x80) {
         ep &= 0x7F;
@@ -473,7 +481,7 @@ uint16_t get_serialno_desc(void *buffer) {
 }
 
 const struct usbd_driver usbd_otgfs = {
-    USBD_HW_ADDRFST | USBD_HW_BC,
+    getinfo,
     enable,
     connect,
     setaddr,