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