From f7d90a41927c64c7aadf7efd3a4c8887cd018ff8 Mon Sep 17 00:00:00 2001 From: "xieyangrun@rt-thread.com" Date: Sun, 20 Mar 2022 09:15:25 +0800 Subject: [PATCH] update musb dc port --- port/musb/usb_dc_musb.c | 134 +++++++++++++++++++++++++++++------- port/musb/usb_musb_reg.h | 142 +++++++++++++++++++++++++++++++++++++++ 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.