summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author[email protected] <[email protected]>2022-03-20 09:15:25 +0800
committersakumisu <[email protected]>2022-03-20 13:10:30 +0800
commitf7d90a41927c64c7aadf7efd3a4c8887cd018ff8 (patch)
tree782035505a5b8edb415118adcd84c60f86624ed1
parent66e15f381ac49c98038cee00034dbf905f00323b (diff)
update musb dc port
-rw-r--r--port/musb/usb_dc_musb.c134
-rw-r--r--port/musb/usb_musb_reg.h142
2 files changed, 251 insertions, 25 deletions
diff --git a/port/musb/usb_dc_musb.c b/port/musb/usb_dc_musb.c
index 6bf54060..ef1467ab 100644
--- a/port/musb/usb_dc_musb.c
+++ b/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);
}
diff --git a/port/musb/usb_musb_reg.h b/port/musb/usb_musb_reg.h
index 2f3621b6..60b194de 100644
--- a/port/musb/usb_musb_reg.h
+++ b/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.