瀏覽代碼

update musb dc port

xieyangrun@rt-thread.com 3 年之前
父節點
當前提交
f7d90a4192
共有 2 個文件被更改,包括 251 次插入25 次删除
  1. 109 25
      port/musb/usb_dc_musb.c
  2. 142 0
      port/musb/usb_musb_reg.h

+ 109 - 25
port/musb/usb_dc_musb.c

@@ -1,6 +1,31 @@
 #include "usbd_core.h"
 #include "usb_musb_reg.h"
 
+#ifdef USB_MUSB_SUNXI
+#define SUNXI_SRAMC_BASE     0x01c00000
+#define SUNXI_USB0_BASE      0x01c13000
+
+#define USBC_REG_o_PHYCTL    0x0404
+
+#ifndef USB_BASE
+#define USB_BASE (SUNXI_USB0_BASE)
+#endif
+
+#ifndef USBD_IRQHandler
+#define USBD_IRQHandler USB_INT_Handler //use actual usb irq name instead
+
+void USBD_IRQHandler(int, void *);
+#endif
+
+#define USB_TXCSRLx_BASE(ep_idx)  (&USB->TXCSRL1)
+#define USB_RXCSRLx_BASE(ep_idx)  (&USB->RXCSRL1)
+#define USB_TXCSRHx_BASE(ep_idx)  (&USB->TXCSRH1)
+#define USB_RXCSRHx_BASE(ep_idx)  (&USB->RXCSRH1)
+#define USB_RXCOUNTx_BASE(ep_idx) ((uint8_t *)&USB->RXCOUNT1)
+#define USB_FIFO_BASE(ep_idx)     (&USB->FIFO0_BYTE + 0x4 * ep_idx)
+
+#else
+
 #ifndef USBD_IRQHandler
 #define USBD_IRQHandler USB_INT_Handler //use actual usb irq name instead
 #endif
@@ -9,11 +34,20 @@
 #define USB_BASE (0x40086400UL)
 #endif
 
+#define USB_TXCSRLx_BASE(ep_idx)  (&USB->TXCSRL1 + 0x10 * (ep_idx - 1))
+#define USB_RXCSRLx_BASE(ep_idx)  (&USB->RXCSRL1 + 0x10 * (ep_idx - 1))
+#define USB_TXCSRHx_BASE(ep_idx)  (&USB->TXCSRH1 + 0x10 * (ep_idx - 1))
+#define USB_RXCSRHx_BASE(ep_idx)  (&USB->RXCSRH1 + 0x10 * (ep_idx - 1))
+#define USB_RXCOUNTx_BASE(ep_idx) ((uint8_t *)&USB->RXCOUNT1 + 0x10 * (ep_idx - 1))
+#define USB_FIFO_BASE(ep_idx)     (&USB->FIFO0_BYTE + 0x4 * ep_idx)
+
+#endif // USB_MUSB_SUNXI
+
 #ifndef USB_NUM_BIDIR_ENDPOINTS
 #define USB_NUM_BIDIR_ENDPOINTS 8
 #endif
 
-#define USB ((USB0_Type *)USB_BASE)
+#define USB ((volatile USB0_Type *)USB_BASE)
 
 #define HWREG(x) \
     (*((volatile uint32_t *)(x)))
@@ -22,12 +56,6 @@
 #define HWREGB(x) \
     (*((volatile uint8_t *)(x)))
 
-#define USB_TXCSRLx_BASE(ep_idx)  (&USB->TXCSRL1 + 0x10 * (ep_idx - 1))
-#define USB_RXCSRLx_BASE(ep_idx)  (&USB->RXCSRL1 + 0x10 * (ep_idx - 1))
-#define USB_TXCSRHx_BASE(ep_idx)  (&USB->TXCSRH1 + 0x10 * (ep_idx - 1))
-#define USB_RXCSRHx_BASE(ep_idx)  (&USB->RXCSRH1 + 0x10 * (ep_idx - 1))
-#define USB_RXCOUNTx_BASE(ep_idx) ((uint8_t *)&USB->RXCOUNT1 + 0x10 * (ep_idx - 1))
-#define USB_FIFO_BASE(ep_idx)     (&USB->FIFO0_BYTE + 0x4 * ep_idx)
 
 typedef enum {
     USB_EP0_STATE_SETUP = 0x0,      /**< SETUP DATA */
@@ -60,6 +88,18 @@ struct usb_dc_config_priv {
 volatile uint8_t usb_ep0_state = USB_EP0_STATE_SETUP;
 volatile uint16_t ep0_last_size = 0;
 
+/* get current active ep */
+static uint8_t USBC_GetActiveEp(void)
+{
+    return USB->EPIDX;
+}
+
+/* set the active ep */
+static void USBC_SelectActiveEp(uint8_t ep_index)
+{
+    USB->EPIDX = ep_index;
+}
+
 static void usb_musb_data_ack(uint8_t ep_idx, bool bIsLastPacket)
 {
     if (ep_idx == 0) {
@@ -88,7 +128,7 @@ static void usb_musb_write_packet(uint8_t ep_idx, uint8_t *buffer, uint16_t len)
     uint32_t count8;
     int i;
 
-    if ((uint32_t)buffer & 0x03) {
+    if ((size_t)buffer & 0x03) {
         buf8 = buffer;
         for (i = 0; i < len; i++) {
             HWREGB(USB_FIFO_BASE(ep_idx)) = *buf8++;
@@ -119,7 +159,7 @@ static void usb_musb_read_packet(uint8_t ep_idx, uint8_t *buffer, uint16_t len)
     uint32_t count8;
     int i;
 
-    if ((uint32_t)buffer & 0x03) {
+    if ((size_t)buffer & 0x03) {
         buf8 = buffer;
         for (i = 0; i < len; i++) {
             *buf8++ = HWREGB(USB_FIFO_BASE(ep_idx));
@@ -218,6 +258,7 @@ int usbd_ep_open(const struct usbd_endpoint_cfg *ep_cfg)
     uint16_t used = 0;
     uint16_t fifo_size = 0;
     uint8_t ep_idx = USB_EP_GET_IDX(ep_cfg->ep_addr);
+    uint8_t old_ep_idx;
     uint32_t ui32Flags = 0;
     uint16_t ui32Register = 0;
 
@@ -225,9 +266,8 @@ int usbd_ep_open(const struct usbd_endpoint_cfg *ep_cfg)
         return 0;
     }
 
-    uint32_t old_ep_idx = USB->EPIDX;
-
-    USB->EPIDX = ep_idx;
+    old_ep_idx = USBC_GetActiveEp();
+    USBC_SelectActiveEp(ep_idx);
 
     if (USB_EP_DIR_IS_OUT(ep_cfg->ep_addr)) {
         usb_dc_cfg.out_ep[ep_idx].ep_mps = ep_cfg->ep_mps;
@@ -328,7 +368,7 @@ int usbd_ep_open(const struct usbd_endpoint_cfg *ep_cfg)
         usb_dc_cfg.fifo_size_offset += used;
     }
 
-    USB->EPIDX = old_ep_idx;
+    USBC_SelectActiveEp(old_ep_idx);
 
     return 0;
 }
@@ -341,6 +381,10 @@ int usbd_ep_close(const uint8_t ep)
 int usbd_ep_set_stall(const uint8_t ep)
 {
     uint8_t ep_idx = USB_EP_GET_IDX(ep);
+    uint8_t old_ep_idx;
+
+    old_ep_idx = USBC_GetActiveEp();
+    USBC_SelectActiveEp(ep_idx);
 
     if (USB_EP_DIR_IS_OUT(ep)) {
         if (ep_idx == 0x00) {
@@ -356,12 +400,17 @@ int usbd_ep_set_stall(const uint8_t ep)
         }
     }
 
+    USBC_SelectActiveEp(old_ep_idx);
     return 0;
 }
 
 int usbd_ep_clear_stall(const uint8_t ep)
 {
     uint8_t ep_idx = USB_EP_GET_IDX(ep);
+    uint8_t old_ep_idx;
+
+    old_ep_idx = USBC_GetActiveEp();
+    USBC_SelectActiveEp(ep_idx);
 
     if (USB_EP_DIR_IS_OUT(ep)) {
         if (ep_idx == 0x00) {
@@ -382,6 +431,8 @@ int usbd_ep_clear_stall(const uint8_t ep)
             HWREGB(USB_TXCSRLx_BASE(ep_idx)) |= USB_TXCSRL1_CLRDT;
         }
     }
+
+    USBC_SelectActiveEp(old_ep_idx);
     return 0;
 }
 
@@ -392,35 +443,46 @@ int usbd_ep_is_stalled(const uint8_t ep, uint8_t *stalled)
 
 int usbd_ep_write(const uint8_t ep, const uint8_t *data, uint32_t data_len, uint32_t *ret_bytes)
 {
+    int ret = 0;
     uint8_t ep_idx = USB_EP_GET_IDX(ep);
     uint32_t timeout = 0xffffff;
+    uint8_t old_ep_idx;
+
+    old_ep_idx = USBC_GetActiveEp();
+    USBC_SelectActiveEp(ep_idx);
 
     if (!data && data_len) {
-        return -1;
+        ret = -1;
+        goto _RET;
     }
 
     if (ep_idx == 0x00) {
         while (USB->CSRL0 & USB_CSRL0_TXRDY) {
             if (USB->CSRL0 & USB_CSRL0_ERROR) {
-                return -2;
+                ret = -2;
+                goto _RET;
             }
             if (!(timeout--)) {
-                return -3;
+                ret = -3;
+                goto _RET;
             }
         }
     } else {
         while (HWREGB(USB_TXCSRLx_BASE(ep_idx)) & USB_TXCSRL1_TXRDY) {
             if ((HWREGB(USB_TXCSRLx_BASE(ep_idx)) & USB_TXCSRL1_ERROR) || (HWREGB(USB_TXCSRLx_BASE(ep_idx)) & USB_TXCSRL1_UNDRN)) {
-                return -2;
+                ret = -2;
+                goto _RET;
             }
             if (!(timeout--)) {
-                return -3;
+                ret = -3;
+                goto _RET;
             }
         }
     }
 
     if (!data_len) {
-        return 0;
+        ret = 0;
+        goto _RET;
     }
 
     ep0_last_size = data_len;
@@ -438,24 +500,31 @@ int usbd_ep_write(const uint8_t ep, const uint8_t *data, uint32_t data_len, uint
         *ret_bytes = data_len;
     }
 
-    return 0;
+_RET:
+    USBC_SelectActiveEp(old_ep_idx);
+    return ret;
 }
 
 int usbd_ep_read(const uint8_t ep, uint8_t *data, uint32_t max_data_len, uint32_t *read_bytes)
 {
+    int ret = 0;
     uint8_t ep_idx = USB_EP_GET_IDX(ep);
     uint32_t read_count;
-    uint8_t *buf8 = data;
+    uint8_t old_ep_idx;
 
+    old_ep_idx = USBC_GetActiveEp();
+    USBC_SelectActiveEp(ep_idx);
     if (!data && max_data_len) {
-        return -1;
+        ret = -1;
+        goto _RET;
     }
 
     if (!max_data_len) {
         if (ep_idx != 0x00) {
             usb_musb_data_ack(ep_idx, false);
         }
-        return 0;
+        ret = 0;
+        goto _RET;
     }
 
     if (ep_idx == 0x00) {
@@ -476,7 +545,9 @@ int usbd_ep_read(const uint8_t ep, uint8_t *data, uint32_t max_data_len, uint32_
         *read_bytes = read_count;
     }
 
-    return 0;
+_RET:
+    USBC_SelectActiveEp(old_ep_idx);
+    return ret;
 }
 
 static void handle_ep0(void)
@@ -563,11 +634,16 @@ static void handle_ep0(void)
     }
 }
 
+#ifdef USB_MUSB_SUNXI
+void USBD_IRQHandler(int irq, void * args)
+#else
 void USBD_IRQHandler(void)
+#endif
 {
     uint32_t is;
     uint32_t txis;
     uint32_t rxis;
+    uint8_t old_ep_idx;
 
     is = USB->IS;
     txis = USB->TXIS;
@@ -598,28 +674,36 @@ void USBD_IRQHandler(void)
     if (is & USB_IS_SUSPEND) {
     }
 
+    USB->IS = is; // clear isr flag
     txis &= USB->TXIE;
     /* Handle EP0 interrupt */
     if (txis & USB_TXIE_EP0) {
+        USBC_SelectActiveEp(0);
         handle_ep0();
         txis &= ~USB_TXIE_EP0;
+        USB->TXIS = USB_TXIE_EP0; // clear isr flag
     }
 
     while (txis) {
         uint8_t ep_idx = __builtin_ctz(txis);
-
+        USBC_SelectActiveEp(ep_idx);
         if (HWREGB(USB_TXCSRLx_BASE(ep_idx)) & USB_TXCSRL1_UNDRN) {
             HWREGB(USB_TXCSRLx_BASE(ep_idx)) &= ~USB_TXCSRL1_UNDRN;
         }
         usbd_event_notify_handler(USBD_EVENT_EP_IN_NOTIFY, (void *)(0x80 | ep_idx));
         txis &= ~(1 << ep_idx);
+        USB->TXIS = (1 << ep_idx); // clear isr flag
     }
 
     rxis &= USB->RXIE;
     while (rxis) {
         uint8_t ep_idx = __builtin_ctz(rxis);
+        USBC_SelectActiveEp(ep_idx);
         if (HWREGB(USB_RXCSRLx_BASE(ep_idx)) & USB_RXCSRL1_RXRDY)
             usbd_event_notify_handler(USBD_EVENT_EP_OUT_NOTIFY, (void *)(ep_idx & 0x7f));
         rxis &= ~(1 << ep_idx);
+        USB->RXIS = (1 << ep_idx); // clear isr flag
     }
+
+    USBC_SelectActiveEp(old_ep_idx);
 }

+ 142 - 0
port/musb/usb_musb_reg.h

@@ -8,6 +8,146 @@
 /**
   * @brief Register map for USB0 peripheral (USB0)
   */
+#ifdef USB_MUSB_SUNXI
+
+typedef __PACKED_STRUCT {                                    /*!< USB0 Structure                                                        */
+  union {
+    __IO uint8_t   FIFO0_BYTE;                      /*!< USB FIFO Endpoint 0                                                   */
+    __IO uint16_t  FIFO0_HALF;                      /*!< USB FIFO Endpoint 0                                                   */
+    __IO uint32_t  FIFO0_WORD;                      /*!< USB FIFO Endpoint 0                                                   */
+  };
+  union {
+    __IO uint8_t   FIFO1_BYTE;                      /*!< USB FIFO Endpoint 1                                                   */
+    __IO uint16_t  FIFO1_HALF;                      /*!< USB FIFO Endpoint 1                                                   */
+    __IO uint32_t  FIFO1_WORD;                      /*!< USB FIFO Endpoint 1                                                   */
+  };
+  union {
+    __IO uint8_t   FIFO2_BYTE;                      /*!< USB FIFO Endpoint 2                                                   */
+    __IO uint16_t  FIFO2_HALF;                      /*!< USB FIFO Endpoint 2                                                   */
+    __IO uint32_t  FIFO2_WORD;                      /*!< USB FIFO Endpoint 2                                                   */
+  };
+  union {
+    __IO uint8_t   FIFO3_BYTE;                      /*!< USB FIFO Endpoint 3                                                   */
+    __IO uint16_t  FIFO3_HALF;                      /*!< USB FIFO Endpoint 3                                                   */
+    __IO uint32_t  FIFO3_WORD;                      /*!< USB FIFO Endpoint 3                                                   */
+  };
+  union {
+    __IO uint8_t   FIFO4_BYTE;                      /*!< USB FIFO Endpoint 4                                                   */
+    __IO uint16_t  FIFO4_HALF;                      /*!< USB FIFO Endpoint 4                                                   */
+    __IO uint32_t  FIFO4_WORD;                      /*!< USB FIFO Endpoint 4                                                   */
+  };
+  union {
+    __IO uint8_t   FIFO5_BYTE;                      /*!< USB FIFO Endpoint 5                                                   */
+    __IO uint16_t  FIFO5_HALF;                      /*!< USB FIFO Endpoint 5                                                   */
+    __IO uint32_t  FIFO5_WORD;                      /*!< USB FIFO Endpoint 5                                                   */
+  };
+  union {
+    __IO uint8_t   FIFO6_BYTE;                      /*!< USB FIFO Endpoint 6                                                   */
+    __IO uint16_t  FIFO6_HALF;                      /*!< USB FIFO Endpoint 6                                                   */
+    __IO uint32_t  FIFO6_WORD;                      /*!< USB FIFO Endpoint 6                                                   */
+  };
+  union {
+    __IO uint8_t   FIFO7_BYTE;                      /*!< USB FIFO Endpoint 7                                                   */
+    __IO uint16_t  FIFO7_HALF;                      /*!< USB FIFO Endpoint 7                                                   */
+    __IO uint32_t  FIFO7_WORD;                      /*!< USB FIFO Endpoint 7                                                   */
+  };
+  union {
+    __IO uint8_t   FIFO_BYTE;                      /*!< USB FIFO Endpoint 7                                                   */
+    __IO uint16_t  FIFO_HALF;                      /*!< USB FIFO Endpoint 7                                                   */
+    __IO uint32_t  FIFO_WORD;                      /*!< USB FIFO Endpoint 7                                                   */
+  } FIFO_RESERVED[8];
+
+    // 0x40
+  __IO uint8_t   POWER;                             /*!< USB Power                                                             */
+  __IO uint8_t   DEVCTL;                            /*!< USB Device Control                                                    */
+  __IO uint8_t   EPIDX;                             /*!< USB Endpoint Index                                                    */
+  __IO uint8_t   VEND0;
+// 0x44
+  __IO uint16_t  TXIS;                              /*!< USB Transmit Interrupt Status                                         */
+  __IO uint16_t  RXIS;                              /*!< USB Receive Interrupt Status                                          */
+  // 0x48
+  __IO uint16_t  TXIE;                              /*!< USB Transmit Interrupt Enable                                         */
+  __IO uint16_t  RXIE;                              /*!< USB Receive Interrupt Enable                                          */
+// 0x4c
+  __IO uint8_t   IS;                                /*!< USB General Interrupt Status                                          */
+  __I uint8_t   IS_RESERVED[3];
+
+  __IO  uint8_t   IE;                                /*!< USB Interrupt Enable                                                  */
+  __I  uint8_t   IE_RESERVED[3];
+
+  __IO uint16_t  FRAME;                             /*!< USB Frame Value                                                       */
+  __I  uint8_t   FRAME_RESERVED[34];
+
+  __IO uint8_t   EPINFO;                            /*!< USB Endpoint Information                                              */
+  __IO uint8_t   RAMINFO;                           /*!< USB RAM Information                                                   */
+  __IO uint8_t   LINKINFO;
+  __IO uint8_t   VPLEN;                             /*!< USB OTG VBUS Pulse Timing                                             */
+// 0x7c
+  __IO uint8_t   HSEOF;                             /*!< USB High-Speed Last Transaction to End of Frame Timing                */
+  __IO uint8_t   FSEOF;                             /*!< USB Full-Speed Last Transaction to End of Frame Timing                */
+  __IO uint8_t   LSEOF;                             /*!< USB Low-Speed Last Transaction to End of Frame Timing                 */
+  __I  uint8_t   RESERVED7F;
+
+// 0x80
+  __IO uint16_t  TXMAXP1;                           /*!< USB Maximum Transmit Data Endpoint 1                                  */
+  __PACKED_UNION
+  {
+    __IO uint8_t   CSRL0;
+    __IO uint8_t   TXCSRL1;                           /*!< USB Transmit Control and Status Endpoint 1 Low                        */
+  } ;
+
+  __PACKED_UNION
+  {
+    __O  uint8_t   CSRH0;                             /*!< USB Control and Status Endpoint 0 High                                */
+    __IO uint8_t   TXCSRH1;                           /*!< USB Transmit Control and Status Endpoint 1 High                       */
+  } ;
+// 0x84
+  __IO uint16_t  RXMAXP1;                           /*!< USB Maximum Receive Data Endpoint 1                                   */
+  __IO uint8_t   RXCSRL1;                           /*!< USB Receive Control and Status Endpoint 1 Low                         */
+  __IO uint8_t   RXCSRH1;                           /*!< USB Receive Control and Status Endpoint 1 High                        */
+
+  __PACKED_UNION
+  {
+    __IO uint16_t  COUNT0;
+    __IO uint16_t  RXCOUNT1;                          /*!< USB Receive Byte Count Endpoint 1                                     */
+  } ;
+  // 0x8A
+  __IO uint8_t   TYPE0;                             /*!< USB Type Endpoint 0                                                   */
+  __IO uint8_t   NAKLMT;                            /*!< USB NAK Limit                                                         */
+  // 0x8C
+  __IO uint8_t   TXTYPE1;                           /*!< USB Host Transmit Configure Type Endpoint 1                           */
+  __IO uint8_t   TXINTERVAL1;                       /*!< USB Host Transmit Interval Endpoint 1                                 */
+  __IO uint8_t   RXTYPE1;                           /*!< USB Host Configure Receive Type Endpoint 1                            */
+  __IO uint8_t   RXINTERVAL1;                       /*!< USB Host Receive Polling Interval Endpoint 1                          */
+// 0x90
+  __IO uint8_t   TXFIFOSZ;                          /*!< USB Transmit Dynamic FIFO Sizing                                      */
+  __I  uint8_t   RESERVED91;
+  __IO uint16_t  TXFIFOADD;                         /*!< USB Transmit FIFO Start Address                                       */
+// 0x94
+  __IO uint8_t   RXFIFOSZ;                          /*!< USB Receive Dynamic FIFO Sizing                                       */
+  __I  uint8_t   RESERVED95;
+  __IO uint16_t  RXFIFOADD;                         /*!< USB Receive FIFO Start Address                                        */
+
+/* "bus control"/target registers, for host side multipoint (external hubs) */
+// 0x98
+  __PACKED_UNION
+  {
+    __IO  uint8_t   FADDR;
+    __IO  uint8_t   TXFUNCADDR0;
+  };
+
+  __I uint8_t    RESERVERD99;
+// 0x9A
+  __IO uint8_t TXHUBADDR0;
+  __IO uint8_t TXHUBPORT0;
+// 0x9c
+  __IO uint8_t RXFUNCADDR0;
+  __I uint8_t RESERVED9d;
+  __IO uint8_t RXHUBADDR0;
+  __IO uint8_t RXHUBPORT0;
+} USB0_Type;
+
+#else
 
 typedef struct {                                    /*!< USB0 Structure                                                        */
   __IO uint8_t   FADDR;                             /*!< USB Device Functional Address                                         */
@@ -326,6 +466,8 @@ typedef struct {                                    /*!< USB0 Structure
   __IO uint32_t  CC;                                /*!< USB Clock Configuration                                               */
 } USB0_Type;
 
+#endif // USB_MUSB_SUNXI
+
 //*****************************************************************************
 //
 // The following are defines for the Univeral Serial Bus register offsets.