Dmitry пре 8 година
родитељ
комит
7918a4e3fd

+ 4 - 1
inc/usb.h

@@ -70,7 +70,10 @@
     #define usbd_hw usbd_otgfs
     #define usbd_hw usbd_otgfs
     #endif
     #endif
 
 
-#elif defined(STM32F429xx)
+#elif defined(STM32F405xx) || defined(STM32F415xx) || \
+      defined(STM32F407xx) || defined(STM32F417xx) || \
+      defined(STM32F427xx) || defined(STM32F437xx) || \
+      defined(STM32F429xx) || defined(STM32F439xx)
 
 
     #define USBD_STM32F429
     #define USBD_STM32F429
 
 

+ 21 - 12
inc/usbd_core.h

@@ -59,10 +59,19 @@
 #define usbd_lane_dcp       4   /**<\brief Lanes connected to dedicated charging port.*/
 #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_ADDRFST     (1 << 0)    /**<\brief Set address before STATUS_OUT.*/
 #define USBD_HW_BC          (1 << 1)    /**<\brief Battery charging detection supported.*/
 #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 enabled. */
+#define USBD_HW_ENUMSPEED   (2 << 4)    /**<\brief USB device enumeration speed mask.*/
+#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,15 +221,16 @@ typedef usbd_respond (*usbd_cfg_callback)(usbd_device *dev, uint8_t cfg);
 
 
 /**\addtogroup USBD_HW
 /**\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
 /**\brief Enables or disables USB hardware
  * \param enable Enables USB when TRUE disables otherwise.
  * \param enable Enables USB when TRUE disables otherwise.
  */
  */
 typedef void (*usbd_hw_enable)(bool enable);
 typedef void (*usbd_hw_enable)(bool enable);
 
 
-/**\brief Resets USB hardware.*/
-typedef void (*usbd_hw_reset)(void);
-
 /** Connects or disconnects USB hardware to/from usb host
 /** Connects or disconnects USB hardware to/from usb host
  * \param connect Connects USB to host if TRUE, disconnects otherwise
  * \param connect Connects USB to host if TRUE, disconnects otherwise
  * \return lanes connection status.
  * \return lanes connection status.
@@ -294,9 +304,8 @@ typedef uint16_t (*usbd_hw_get_serialno)(void *buffer);
 
 
 /**\brief Represents a hardware USB driver call table.*/
 /**\brief Represents a hardware USB driver call table.*/
 struct usbd_driver {
 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_enable          enable;             /**<\copybrief usbd_hw_enable */
-    usbd_hw_reset           reset;              /**<\copybrief usbd_hw_reset */
     usbd_hw_connect         connect;            /**<\copybrief usbd_hw_connect */
     usbd_hw_connect         connect;            /**<\copybrief usbd_hw_connect */
     usbd_hw_setaddr         setaddr;            /**<\copybrief usbd_hw_setaddr */
     usbd_hw_setaddr         setaddr;            /**<\copybrief usbd_hw_setaddr */
     usbd_hw_ep_config       ep_config;          /**<\copybrief usbd_hw_ep_config */
     usbd_hw_ep_config       ep_config;          /**<\copybrief usbd_hw_ep_config */
@@ -349,12 +358,6 @@ inline static void usbd_init(usbd_device *dev, const struct usbd_driver *drv,
  */
  */
 void usbd_poll(usbd_device *dev);
 void usbd_poll(usbd_device *dev);
 
 
-/**\brief Asynchronous device control
- * \param dev dev usb device \ref _usbd_device
- * \param cmd Asynchronous control command
- */
-void usbd_control(usbd_device *dev, enum usbd_commands cmd) __attribute__((deprecated));
-
 /**\brief Register callback for all control requests
 /**\brief Register callback for all control requests
  * \param dev usb device \ref _usbd_device
  * \param dev usb device \ref _usbd_device
  * \param callback user control callback \ref usbd_ctl_callback
  * \param callback user control callback \ref usbd_ctl_callback
@@ -462,6 +465,12 @@ inline static uint8_t usbd_connect(usbd_device *dev, bool connect) {
     return dev->driver->connect(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__)
 #endif //(__ASSEMBLER__)
 /** @} */
 /** @} */
 /** @} */
 /** @} */

+ 7 - 2
readme.md

@@ -51,7 +51,12 @@
         <td>usbd_otgfs</td>
         <td>usbd_otgfs</td>
         <td>usbd_stm32l476_otgfs.c</td>
         <td>usbd_stm32l476_otgfs.c</td>
     </tr>
     </tr>
-
+    <tr>
+        <td>STM32F4x5 STM32F4x7 STM32F4x9</td>
+        <td nowrap>Doublebuffered<br/>6 endpoints<br/>VBUS detection<br/>SOF output</td>
+        <td>usbd_otgfs</td>
+        <td>usbd_stm32l429_otgfs.c</td>
+    </tr>
 </table>
 </table>
 
 
 1. Single physical endpoint can be used to implement
 1. Single physical endpoint can be used to implement
@@ -61,7 +66,7 @@
 
 
 2. At this moment BULK IN endpoint can use both buffers, but it is not **real** doublebuffered.
 2. At this moment BULK IN endpoint can use both buffers, but it is not **real** doublebuffered.
 
 
-3. Tested with STM32L052K8, STM32L100RC, STM32L476RG, STM32F072C8, STM32F103C8, STM32F103CB, STM32F303CC, STM32F303RE
+3. Tested with STM32L052K8, STM32L100RC, STM32L476RG, STM32F072C8, STM32F103C8, STM32F103CB, STM32F303CC, STM32F303RE, STM32F429ZI
 
 
 ### Implemented definitions for classes ###
 ### Implemented definitions for classes ###
 1. USB HID based on [Device Class Definition for Human Interface Devices (HID) Version 1.11](http://www.usb.org/developers/hidpage/HID1_11.pdf)
 1. USB HID based on [Device Class Definition for Human Interface Devices (HID) Version 1.11](http://www.usb.org/developers/hidpage/HID1_11.pdf)

+ 1 - 0
src/memmap.inc

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

+ 1 - 26
src/usbd_core.c

@@ -101,7 +101,7 @@ static usbd_respond usbd_process_devrq (usbd_device *dev, usbd_ctlreq *req) {
         req->data[1] = 0;
         req->data[1] = 0;
         return usbd_ack;
         return usbd_ack;
     case USB_STD_SET_ADDRESS:
     case USB_STD_SET_ADDRESS:
-        if (dev->driver->caps & USBD_HW_ADDRFST) {
+        if (usbd_getinfo(dev) & USBD_HW_ADDRFST) {
             usbd_set_address(dev, req);
             usbd_set_address(dev, req);
         } else {
         } else {
             dev->complete_callback = usbd_set_address;
             dev->complete_callback = usbd_set_address;
@@ -355,28 +355,3 @@ static void usbd_process_evt(usbd_device *dev, uint8_t evt, uint8_t ep) {
 void usbd_poll(usbd_device *dev) {
 void usbd_poll(usbd_device *dev) {
     return dev->driver->poll(dev, usbd_process_evt);
     return dev->driver->poll(dev, usbd_process_evt);
 }
 }
-
-void usbd_control(usbd_device *dev, enum usbd_commands cmd) {
-    switch (cmd) {
-    case usbd_cmd_enable:
-        dev->driver->enable(true);
-        dev->status.device_state = usbd_state_disconnected;
-        break;
-    case usbd_cmd_disable:
-        dev->driver->enable(false);
-        dev->status.device_state = usbd_state_disabled;
-        break;
-    case usbd_cmd_connect:
-        dev->driver->connect(true);
-        break;
-    case usbd_cmd_disconnect:
-        dev->driver->connect(false);
-        dev->status.device_state = usbd_state_disconnected;
-        break;
-    case usbd_cmd_reset:
-        dev->driver->reset();
-        break;
-    default:
-        break;
-    }
-}

+ 14 - 12
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_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 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;
 typedef union _pma_table pma_table;
 
 
 #if defined(STM32F302x8) || defined(STM32F302xE) || defined(STM32F303xE)
 #if defined(STM32F302x8) || defined(STM32F302xE) || defined(STM32F303xE)
@@ -151,11 +153,17 @@ static uint16_t get_next_pma(uint16_t sz) {
         if ((tbl->tx.addr) && (tbl->tx.addr < _result)) _result = tbl->tx.addr;
         if ((tbl->tx.addr) && (tbl->tx.addr < _result)) _result = tbl->tx.addr;
         if ((tbl->rx.addr) && (tbl->rx.addr < _result)) _result = tbl->rx.addr;
         if ((tbl->rx.addr) && (tbl->rx.addr < _result)) _result = tbl->rx.addr;
     }
     }
-    if ( _result < (4 * sizeof(pma_table) + sz)) {
-        return 0;
-    } else {
-        return _result - sz;
-    }
+    return (_result < (0x020 + sz)) ? 0 : (_result - 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) {
 void ep_setstall(uint8_t ep, bool stall) {
@@ -203,11 +211,6 @@ bool ep_isstalled(uint8_t ep) {
     }
     }
 }
 }
 
 
-void reset (void) {
-    USB->CNTR |= USB_CNTR_FRES;
-    USB->CNTR &= ~USB_CNTR_FRES;
-}
-
 uint8_t connect(bool connect) {
 uint8_t connect(bool connect) {
 #if defined(USBD_DP_PORT) && defined(USBD_DP_PIN) && defined(STM32F3)
 #if defined(USBD_DP_PORT) && defined(USBD_DP_PIN) && defined(STM32F3)
     uint32_t _t = USBD_DP_PORT->MODER & ~(0x03 << (2 * USBD_DP_PIN));
     uint32_t _t = USBD_DP_PORT->MODER & ~(0x03 << (2 * USBD_DP_PIN));
@@ -529,9 +532,8 @@ uint16_t get_serialno_desc(void *buffer) {
 }
 }
 
 
 const struct usbd_driver usbd_devfs = {
 const struct usbd_driver usbd_devfs = {
-    0,
+    getinfo,
     enable,
     enable,
-    reset,
     connect,
     connect,
     setaddr,
     setaddr,
     ep_config,
     ep_config,

+ 22 - 17
src/usbd_stm32f103_devfs_asm.S

@@ -136,9 +136,8 @@
     .globl  usbd_devfs_asm
     .globl  usbd_devfs_asm
     .align  2
     .align  2
 usbd_devfs_asm:
 usbd_devfs_asm:
-    .long   0
+    .long   _getinfo
     .long   _enable
     .long   _enable
-    .long   _reset
     .long   _connect
     .long   _connect
     .long   _setaddr
     .long   _setaddr
     .long   _ep_config
     .long   _ep_config
@@ -262,19 +261,6 @@ _setaddr:
     .size   _setaddr, . - _setaddr
     .size   _setaddr, . - _setaddr
 
 
     .thumb_func
     .thumb_func
-    .type   _reset, %function
-_reset:
-    ldr     r2, =#USB_REGBASE
-    movs    r0, #0x01           //FRES
-    ldrh    r1, [r2, #USB_CNTR]
-    orrs    r1, r0
-    strh    r1, [r2, #USB_CNTR]  // set FRES
-    bics    r1, r0
-    strh    r1, [r2, #USB_CNTR]  // clr FRES
-    bx      lr
-    .size   _reset, . - _reset
-
-    .thumb_func
     .type   _get_frame, %function
     .type   _get_frame, %function
 _get_frame:
 _get_frame:
     ldr     r0, =#USB_REGBASE
     ldr     r0, =#USB_REGBASE
@@ -337,8 +323,27 @@ _enable:
     .size   _enable, . - _enable
     .size   _enable, . - _enable
 
 
     .thumb_func
     .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)
 /*void ep_settall(uint8_t ep, bool stall)
  * in  R0 <- endpoint number
  * in  R0 <- endpoint number
  * in  R1 <- 0 if unstall, !0 if stall
  * in  R1 <- 0 if unstall, !0 if stall
@@ -605,7 +610,7 @@ _get_next_pma:
     bne     .L_gnp_chkaddr
     bne     .L_gnp_chkaddr
     subs    r0, r3, r2
     subs    r0, r3, r2
     blo     .L_gnp_exit
     blo     .L_gnp_exit
-    cmp     r0, #0x40       //check for the pma table overlap
+    cmp     r0, #0x20       //check for the pma table overlap
 .L_gnp_exit:
 .L_gnp_exit:
     pop     {r1, r3, r4, pc}
     pop     {r1, r3, r4, pc}
 
 

+ 9 - 7
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 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_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);
 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);
 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);
     _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) {
 void ep_setstall(uint8_t ep, bool stall) {
     if (ep & 0x80) {
     if (ep & 0x80) {
         ep &= 0x7F;
         ep &= 0x7F;
@@ -145,11 +153,6 @@ void enable(bool enable) {
     }
     }
 }
 }
 
 
-void reset (void) {
-   // _BST(OTG->GRSTCTL, USB_OTG_GRSTCTL_CSRST);
-   // _WBC(OTG->GRSTCTL, USB_OTG_GRSTCTL_CSRST);
-}
-
 uint8_t connect(bool connect) {
 uint8_t connect(bool connect) {
     if (connect) {
     if (connect) {
 /* The ST made a strange thing again. Really i dont'understand what is the reason to name
 /* The ST made a strange thing again. Really i dont'understand what is the reason to name
@@ -461,9 +464,8 @@ uint16_t get_serialno_desc(void *buffer) {
 }
 }
 
 
 const struct usbd_driver usbd_otgfs = {
 const struct usbd_driver usbd_otgfs = {
-    USBD_HW_ADDRFST,
+    getinfo,
     enable,
     enable,
-    reset,
     connect,
     connect,
     setaddr,
     setaddr,
     ep_config,
     ep_config,

+ 10 - 13
src/usbd_stm32l052_devfs.c

@@ -28,7 +28,6 @@
 #define USB_EP_SWBUF_TX     USB_EP_DTOG_RX
 #define USB_EP_SWBUF_TX     USB_EP_DTOG_RX
 #define USB_EP_SWBUF_RX     USB_EP_DTOG_TX
 #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_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)
 #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_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 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 {
 typedef struct {
     uint16_t    addr;
     uint16_t    addr;
     uint16_t    cnt;
     uint16_t    cnt;
@@ -88,11 +89,13 @@ static uint16_t get_next_pma(uint16_t sz) {
         if ((tbl->rx.addr) && (tbl->rx.addr < _result)) _result = tbl->rx.addr;
         if ((tbl->rx.addr) && (tbl->rx.addr < _result)) _result = tbl->rx.addr;
         if ((tbl->tx.addr) && (tbl->tx.addr < _result)) _result = tbl->tx.addr;
         if ((tbl->tx.addr) && (tbl->tx.addr < _result)) _result = tbl->tx.addr;
     }
     }
-    if ( _result < (8 * sizeof(pma_table) + sz)) {
-        return 0;
-    } else {
-        return _result - sz;
-    }
+    return (_result < (0x020 + sz)) ? 0 : (_result - 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) {
 void ep_setstall(uint8_t ep, bool stall) {
@@ -157,11 +160,6 @@ void enable(bool enable) {
     }
     }
 }
 }
 
 
-void reset (void) {
-    USB->CNTR |= USB_CNTR_FRES;
-    USB->CNTR &= ~USB_CNTR_FRES;
-}
-
 uint8_t connect(bool connect) {
 uint8_t connect(bool connect) {
     uint8_t res;
     uint8_t res;
     USB->BCDR = USB_BCDR_BCDEN | USB_BCDR_DCDEN;
     USB->BCDR = USB_BCDR_BCDEN | USB_BCDR_DCDEN;
@@ -455,9 +453,8 @@ uint16_t get_serialno_desc(void *buffer) {
 }
 }
 
 
 const struct usbd_driver usbd_devfs = {
 const struct usbd_driver usbd_devfs = {
-    USBD_HW_BC,
+    getinfo,
     enable,
     enable,
-    reset,
     connect,
     connect,
     setaddr,
     setaddr,
     ep_config,
     ep_config,

+ 20 - 17
src/usbd_stm32l052_devfs_asm.S

@@ -83,9 +83,8 @@
     .globl  usbd_devfs_asm
     .globl  usbd_devfs_asm
     .align  2
     .align  2
 usbd_devfs_asm:
 usbd_devfs_asm:
-    .long   USBD_HW_BC
+    .long   _getinfo
     .long   _enable
     .long   _enable
-    .long   _reset
     .long   _connect
     .long   _connect
     .long   _setaddr
     .long   _setaddr
     .long   _ep_config
     .long   _ep_config
@@ -205,19 +204,6 @@ _setaddr:
     .size   _setaddr, . - _setaddr
     .size   _setaddr, . - _setaddr
 
 
     .thumb_func
     .thumb_func
-    .type   _reset, %function
-_reset:
-    ldr     r2, =#USB_REGBASE
-    movs    r0, #0x01           //FRES
-    ldrh    r1, [r2, #USB_CNTR] //USB->CNTR
-    orrs    r1, r0
-    strh    r1, [r2, #USB_CNTR] // set FRES
-    bics    r1, r0
-    strh    r1, [r2, #USB_CNTR] // clr FRES
-    bx      lr
-    .size   _reset, . - _reset
-
-    .thumb_func
     .type   _get_frame, %function
     .type   _get_frame, %function
 _get_frame:
 _get_frame:
     ldr     r0, =#USB_REGBASE
     ldr     r0, =#USB_REGBASE
@@ -270,8 +256,25 @@ _enable:
     .size   _enable, . - _enable
     .size   _enable, . - _enable
 
 
     .thumb_func
     .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)
 /*void ep_settall(uint8_t ep, bool stall)
  * in  R0 <- endpoint number
  * in  R0 <- endpoint number
  * in  R1 <- 0 if unstall, !0 if stall
  * in  R1 <- 0 if unstall, !0 if stall
@@ -550,7 +553,7 @@ _get_next_pma:
     bhs     .L_gnp_chkaddr
     bhs     .L_gnp_chkaddr
     subs    r0, r3, r2
     subs    r0, r3, r2
     blo     .L_gnp_exit
     blo     .L_gnp_exit
-    cmp     r0, #0x40       //check for the pma table overlap
+    cmp     r0, #0x20       //check for the pma table overlap
 .L_gnp_exit:
 .L_gnp_exit:
     pop     {r1, r3, r4, pc}
     pop     {r1, r3, r4, pc}
     .size   _get_next_pma, . - _get_next_pma
     .size   _get_next_pma, . - _get_next_pma

+ 10 - 13
src/usbd_stm32l100_devfs.c

@@ -28,7 +28,6 @@
 #define USB_EP_SWBUF_TX     USB_EP_DTOG_RX
 #define USB_EP_SWBUF_TX     USB_EP_DTOG_RX
 #define USB_EP_SWBUF_RX     USB_EP_DTOG_TX
 #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_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)
 #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_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 EP_RX_VALID(epr)    EP_TOGGLE_SET((epr), USB_EP_RX_VALID,                   USB_EPRX_STAT)
 
 
+#define STATUS_VAL(x)       (x)
+
 typedef struct {
 typedef struct {
     uint16_t    addr;
     uint16_t    addr;
     uint16_t    :16;
     uint16_t    :16;
@@ -89,11 +90,13 @@ static uint16_t get_next_pma(uint16_t sz) {
         if ((tbl->tx.addr) && (tbl->tx.addr < _result)) _result = tbl->tx.addr;
         if ((tbl->tx.addr) && (tbl->tx.addr < _result)) _result = tbl->tx.addr;
         if ((tbl->rx.addr) && (tbl->rx.addr < _result)) _result = tbl->rx.addr;
         if ((tbl->rx.addr) && (tbl->rx.addr < _result)) _result = tbl->rx.addr;
     }
     }
-    if ( _result < (4 * sizeof(pma_table) + sz)) {
-        return 0;
-    } else {
-        return _result - sz;
-    }
+    return (_result < (0x020 + sz)) ? 0 : (_result - 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) {
 void ep_setstall(uint8_t ep, bool stall) {
@@ -159,11 +162,6 @@ void enable(bool enable) {
     }
     }
 }
 }
 
 
-void reset (void) {
-    USB->CNTR |= USB_CNTR_FRES;
-    USB->CNTR &= ~USB_CNTR_FRES;
-}
-
 uint8_t connect(bool connect) {
 uint8_t connect(bool connect) {
     if (connect) {
     if (connect) {
         SYSCFG->PMC |= SYSCFG_PMC_USB_PU;
         SYSCFG->PMC |= SYSCFG_PMC_USB_PU;
@@ -444,9 +442,8 @@ uint16_t get_serialno_desc(void *buffer) {
 }
 }
 
 
 const struct usbd_driver usbd_devfs = {
 const struct usbd_driver usbd_devfs = {
-    0,
+    getinfo,
     enable,
     enable,
-    reset,
     connect,
     connect,
     setaddr,
     setaddr,
     ep_config,
     ep_config,

+ 19 - 16
src/usbd_stm32l100_devfs_asm.S

@@ -84,9 +84,8 @@
     .globl  usbd_devfs_asm
     .globl  usbd_devfs_asm
     .align  2
     .align  2
 usbd_devfs_asm:
 usbd_devfs_asm:
-    .long   0
+    .long   _getinfo
     .long   _enable
     .long   _enable
-    .long   _reset
     .long   _connect
     .long   _connect
     .long   _setaddr
     .long   _setaddr
     .long   _ep_config
     .long   _ep_config
@@ -174,6 +173,23 @@ _connect:
     bx      lr
     bx      lr
     .size   _connect, . - _connect
     .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
     .thumb_func
     .type   _setaddr, %function
     .type   _setaddr, %function
@@ -185,19 +201,6 @@ _setaddr:
     .size   _setaddr, . - _setaddr
     .size   _setaddr, . - _setaddr
 
 
     .thumb_func
     .thumb_func
-    .type   _reset, %function
-_reset:
-    ldr     r2, =#USB_REGBASE
-    movs    r0, #0x01           //FRES
-    ldrh    r1, [r2, #USB_CNTR]
-    orrs    r1, r0
-    strh    r1, [r2, #USB_CNTR]  // set FRES
-    bics    r1, r0
-    strh    r1, [r2, #USB_CNTR]  // clr FRES
-    bx      lr
-    .size   _reset, . - _reset
-
-    .thumb_func
     .type   _get_frame, %function
     .type   _get_frame, %function
 _get_frame:
 _get_frame:
     ldr     r0, =#USB_REGBASE
     ldr     r0, =#USB_REGBASE
@@ -542,7 +545,7 @@ _get_next_pma:
     bne     .L_gnp_chkaddr
     bne     .L_gnp_chkaddr
     subs    r0, r3, r2
     subs    r0, r3, r2
     blo     .L_gnp_exit
     blo     .L_gnp_exit
-    cmp     r0, #0x40       //check for the pma table overlap
+    cmp     r0, #0x20       //check for the pma table overlap
 .L_gnp_exit:
 .L_gnp_exit:
     pop     {r1, r3, r4, pc}
     pop     {r1, r3, r4, pc}
 
 

+ 9 - 8
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 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_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);
 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);
 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);
     _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) {
 void ep_setstall(uint8_t ep, bool stall) {
     if (ep & 0x80) {
     if (ep & 0x80) {
         ep &= 0x7F;
         ep &= 0x7F;
@@ -147,12 +155,6 @@ void enable(bool enable) {
     }
     }
 }
 }
 
 
-void reset (void) {
-   // _BST(OTG->GRSTCTL, USB_OTG_GRSTCTL_CSRST);
-   // _WBC(OTG->GRSTCTL, USB_OTG_GRSTCTL_CSRST);
-}
-
-
 uint8_t connect(bool connect) {
 uint8_t connect(bool connect) {
     uint8_t res;
     uint8_t res;
 #if defined(USBD_VBUS_DETECT)
 #if defined(USBD_VBUS_DETECT)
@@ -479,9 +481,8 @@ uint16_t get_serialno_desc(void *buffer) {
 }
 }
 
 
 const struct usbd_driver usbd_otgfs = {
 const struct usbd_driver usbd_otgfs = {
-    USBD_HW_ADDRFST | USBD_HW_BC,
+    getinfo,
     enable,
     enable,
-    reset,
     connect,
     connect,
     setaddr,
     setaddr,
     ep_config,
     ep_config,