update musb dc port

This commit is contained in:
xieyangrun@rt-thread.com
2022-03-20 09:15:25 +08:00
committed by sakumisu
parent 66e15f381a
commit f7d90a4192
2 changed files with 251 additions and 25 deletions

View File

@@ -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);
}

View File

@@ -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.