123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816 |
- /*
- * Copyright (c) 2022, sakumisu
- *
- * SPDX-License-Identifier: Apache-2.0
- */
- #include "usbd_core.h"
- #include "usb_musb_reg.h"
- #define HWREG(x) \
- (*((volatile uint32_t *)(x)))
- #define HWREGH(x) \
- (*((volatile uint16_t *)(x)))
- #define HWREGB(x) \
- (*((volatile uint8_t *)(x)))
- #define USB_BASE (g_usbdev_bus[0].reg_base)
- #if defined(CONFIG_USB_MUSB_SUNXI)
- #define MUSB_FADDR_OFFSET 0x98
- #define MUSB_POWER_OFFSET 0x40
- #define MUSB_TXIS_OFFSET 0x44
- #define MUSB_RXIS_OFFSET 0x46
- #define MUSB_TXIE_OFFSET 0x48
- #define MUSB_RXIE_OFFSET 0x4A
- #define MUSB_IS_OFFSET 0x4C
- #define MUSB_IE_OFFSET 0x50
- #define MUSB_EPIDX_OFFSET 0x42
- #define MUSB_IND_TXMAP_OFFSET 0x80
- #define MUSB_IND_TXCSRL_OFFSET 0x82
- #define MUSB_IND_TXCSRH_OFFSET 0x83
- #define MUSB_IND_RXMAP_OFFSET 0x84
- #define MUSB_IND_RXCSRL_OFFSET 0x86
- #define MUSB_IND_RXCSRH_OFFSET 0x87
- #define MUSB_IND_RXCOUNT_OFFSET 0x88
- #define MUSB_FIFO_OFFSET 0x00
- #define MUSB_DEVCTL_OFFSET 0x41
- #define MUSB_TXFIFOSZ_OFFSET 0x90
- #define MUSB_RXFIFOSZ_OFFSET 0x94
- #define MUSB_TXFIFOADD_OFFSET 0x92
- #define MUSB_RXFIFOADD_OFFSET 0x96
- #elif defined(CONFIG_USB_MUSB_CUSTOM)
- #include "musb_custom.h"
- #else
- #define MUSB_FADDR_OFFSET 0x00
- #define MUSB_POWER_OFFSET 0x01
- #define MUSB_TXIS_OFFSET 0x02
- #define MUSB_RXIS_OFFSET 0x04
- #define MUSB_TXIE_OFFSET 0x06
- #define MUSB_RXIE_OFFSET 0x08
- #define MUSB_IS_OFFSET 0x0A
- #define MUSB_IE_OFFSET 0x0B
- #define MUSB_EPIDX_OFFSET 0x0E
- #define MUSB_IND_TXMAP_OFFSET 0x10
- #define MUSB_IND_TXCSRL_OFFSET 0x12
- #define MUSB_IND_TXCSRH_OFFSET 0x13
- #define MUSB_IND_RXMAP_OFFSET 0x14
- #define MUSB_IND_RXCSRL_OFFSET 0x16
- #define MUSB_IND_RXCSRH_OFFSET 0x17
- #define MUSB_IND_RXCOUNT_OFFSET 0x18
- #define MUSB_FIFO_OFFSET 0x20
- #define MUSB_DEVCTL_OFFSET 0x60
- #define MUSB_TXFIFOSZ_OFFSET 0x62
- #define MUSB_RXFIFOSZ_OFFSET 0x63
- #define MUSB_TXFIFOADD_OFFSET 0x64
- #define MUSB_RXFIFOADD_OFFSET 0x66
- #endif // CONFIG_USB_MUSB_SUNXI
- #define USB_FIFO_BASE(ep_idx) (USB_BASE + MUSB_FIFO_OFFSET + 0x4 * ep_idx)
- typedef enum {
- USB_EP0_STATE_SETUP = 0x0, /**< SETUP DATA */
- USB_EP0_STATE_IN_DATA = 0x1, /**< IN DATA */
- USB_EP0_STATE_OUT_DATA = 0x3, /**< OUT DATA */
- USB_EP0_STATE_IN_STATUS = 0x4, /**< IN status */
- USB_EP0_STATE_OUT_STATUS = 0x5, /**< OUT status */
- USB_EP0_STATE_IN_ZLP = 0x6, /**< OUT status */
- USB_EP0_STATE_STALL = 0x7, /**< STALL status */
- } ep0_state_t;
- /* Endpoint state */
- struct musb_ep_state {
- uint16_t ep_mps; /* Endpoint max packet size */
- uint8_t ep_type; /* Endpoint type */
- uint8_t ep_stalled; /* Endpoint stall flag */
- uint8_t ep_enable; /* Endpoint enable */
- uint8_t *xfer_buf;
- uint32_t xfer_len;
- uint32_t actual_xfer_len;
- };
- /* Driver state */
- struct musb_udc {
- volatile uint8_t dev_addr;
- __attribute__((aligned(32))) struct usb_setup_packet setup;
- struct musb_ep_state in_ep[CONFIG_USBDEV_EP_NUM]; /*!< IN endpoint parameters*/
- struct musb_ep_state out_ep[CONFIG_USBDEV_EP_NUM]; /*!< OUT endpoint parameters */
- } g_musb_udc;
- static volatile uint8_t usb_ep0_state = USB_EP0_STATE_SETUP;
- /* get current active ep */
- static uint8_t musb_get_active_ep(void)
- {
- return HWREGB(USB_BASE + MUSB_EPIDX_OFFSET);
- }
- /* set the active ep */
- static void musb_set_active_ep(uint8_t ep_index)
- {
- HWREGB(USB_BASE + MUSB_EPIDX_OFFSET) = ep_index;
- }
- static void musb_write_packet(uint8_t ep_idx, uint8_t *buffer, uint16_t len)
- {
- uint32_t *buf32;
- uint8_t *buf8;
- uint32_t count32;
- uint32_t count8;
- int i;
- if ((uint32_t)buffer & 0x03) {
- buf8 = buffer;
- for (i = 0; i < len; i++) {
- HWREGB(USB_FIFO_BASE(ep_idx)) = *buf8++;
- }
- } else {
- count32 = len >> 2;
- count8 = len & 0x03;
- buf32 = (uint32_t *)buffer;
- while (count32--) {
- HWREG(USB_FIFO_BASE(ep_idx)) = *buf32++;
- }
- buf8 = (uint8_t *)buf32;
- while (count8--) {
- HWREGB(USB_FIFO_BASE(ep_idx)) = *buf8++;
- }
- }
- }
- static void musb_read_packet(uint8_t ep_idx, uint8_t *buffer, uint16_t len)
- {
- uint32_t *buf32;
- uint8_t *buf8;
- uint32_t count32;
- uint32_t count8;
- int i;
- if ((uint32_t)buffer & 0x03) {
- buf8 = buffer;
- for (i = 0; i < len; i++) {
- *buf8++ = HWREGB(USB_FIFO_BASE(ep_idx));
- }
- } else {
- count32 = len >> 2;
- count8 = len & 0x03;
- buf32 = (uint32_t *)buffer;
- while (count32--) {
- *buf32++ = HWREG(USB_FIFO_BASE(ep_idx));
- }
- buf8 = (uint8_t *)buf32;
- while (count8--) {
- *buf8++ = HWREGB(USB_FIFO_BASE(ep_idx));
- }
- }
- }
- static uint32_t musb_get_fifo_size(uint16_t mps, uint16_t *used)
- {
- uint32_t size;
- for (uint8_t i = USB_TXFIFOSZ_SIZE_8; i <= USB_TXFIFOSZ_SIZE_2048; i++) {
- size = (8 << i);
- if (mps <= size) {
- *used = size;
- return i;
- }
- }
- *used = 0;
- return USB_TXFIFOSZ_SIZE_8;
- }
- static uint32_t usbd_musb_fifo_config(struct musb_fifo_cfg *cfg, uint32_t offset)
- {
- uint16_t fifo_used;
- uint8_t c_size;
- uint16_t c_off;
- c_off = offset >> 3;
- c_size = musb_get_fifo_size(cfg->maxpacket, &fifo_used);
- musb_set_active_ep(cfg->ep_num);
- switch (cfg->style) {
- case FIFO_TX:
- HWREGB(USB_BASE + MUSB_TXFIFOSZ_OFFSET) = c_size & 0x0f;
- HWREGH(USB_BASE + MUSB_TXFIFOADD_OFFSET) = c_off;
- break;
- case FIFO_RX:
- HWREGB(USB_BASE + MUSB_RXFIFOSZ_OFFSET) = c_size & 0x0f;
- HWREGH(USB_BASE + MUSB_RXFIFOADD_OFFSET) = c_off;
- break;
- case FIFO_TXRX:
- HWREGB(USB_BASE + MUSB_TXFIFOSZ_OFFSET) = c_size & 0x0f;
- HWREGH(USB_BASE + MUSB_TXFIFOADD_OFFSET) = c_off;
- HWREGB(USB_BASE + MUSB_RXFIFOSZ_OFFSET) = c_size & 0x0f;
- HWREGH(USB_BASE + MUSB_RXFIFOADD_OFFSET) = c_off;
- break;
- default:
- break;
- }
- return (offset + fifo_used);
- }
- __WEAK void usb_dc_low_level_init(void)
- {
- }
- __WEAK void usb_dc_low_level_deinit(void)
- {
- }
- int usb_dc_init(uint8_t busid)
- {
- uint16_t offset = 0;
- uint8_t cfg_num;
- struct musb_fifo_cfg *cfg;
- usb_dc_low_level_init();
- #ifdef CONFIG_USB_HS
- HWREGB(USB_BASE + MUSB_POWER_OFFSET) |= USB_POWER_HSENAB;
- #else
- HWREGB(USB_BASE + MUSB_POWER_OFFSET) &= ~USB_POWER_HSENAB;
- #endif
- musb_set_active_ep(0);
- HWREGB(USB_BASE + MUSB_FADDR_OFFSET) = 0;
- HWREGB(USB_BASE + MUSB_DEVCTL_OFFSET) |= USB_DEVCTL_SESSION;
- cfg_num = usbd_get_musb_fifo_cfg(&cfg);
- for (uint8_t i = 0; i < cfg_num; i++) {
- offset = usbd_musb_fifo_config(&cfg[i], offset);
- }
- if (offset > usb_get_musb_ram_size()) {
- USB_LOG_ERR("offset:%d is overflow, please check your table\r\n", offset);
- while (1) {
- }
- }
- /* Enable USB interrupts */
- HWREGB(USB_BASE + MUSB_IE_OFFSET) = USB_IE_RESET | USB_IE_SUSPND | USB_IE_RESUME;
- HWREGH(USB_BASE + MUSB_TXIE_OFFSET) = USB_TXIE_EP0;
- HWREGH(USB_BASE + MUSB_RXIE_OFFSET) = 0;
- HWREGB(USB_BASE + MUSB_POWER_OFFSET) |= USB_POWER_SOFTCONN;
- return 0;
- }
- int usb_dc_deinit(uint8_t busid)
- {
- return 0;
- }
- int usbd_set_address(uint8_t busid, const uint8_t addr)
- {
- if (addr == 0) {
- HWREGB(USB_BASE + MUSB_FADDR_OFFSET) = 0;
- }
- g_musb_udc.dev_addr = addr;
- return 0;
- }
- int usbd_set_remote_wakeup(uint8_t busid)
- {
- HWREGB(USB_BASE + MUSB_POWER_OFFSET) |= USB_POWER_RESUME;
- usbd_musb_delay_ms(10);
- HWREGB(USB_BASE + MUSB_POWER_OFFSET) &= ~USB_POWER_RESUME;
- return 0;
- }
- uint8_t usbd_get_port_speed(uint8_t busid)
- {
- uint8_t speed = USB_SPEED_UNKNOWN;
- if (HWREGB(USB_BASE + MUSB_POWER_OFFSET) & USB_POWER_HSMODE)
- speed = USB_SPEED_HIGH;
- else if (HWREGB(USB_BASE + MUSB_DEVCTL_OFFSET) & USB_DEVCTL_FSDEV)
- speed = USB_SPEED_FULL;
- else if (HWREGB(USB_BASE + MUSB_DEVCTL_OFFSET) & USB_DEVCTL_LSDEV)
- speed = USB_SPEED_LOW;
- return speed;
- }
- int usbd_ep_open(uint8_t busid, const struct usb_endpoint_descriptor *ep)
- {
- uint8_t ep_idx = USB_EP_GET_IDX(ep->bEndpointAddress);
- uint8_t old_ep_idx;
- uint32_t ui32Flags = 0;
- uint16_t ui32Register = 0;
- if (ep_idx == 0) {
- g_musb_udc.out_ep[0].ep_mps = USB_CTRL_EP_MPS;
- g_musb_udc.out_ep[0].ep_type = 0x00;
- g_musb_udc.out_ep[0].ep_enable = true;
- g_musb_udc.in_ep[0].ep_mps = USB_CTRL_EP_MPS;
- g_musb_udc.in_ep[0].ep_type = 0x00;
- g_musb_udc.in_ep[0].ep_enable = true;
- return 0;
- }
- if (ep_idx > (CONFIG_USBDEV_EP_NUM - 1)) {
- USB_LOG_ERR("Ep addr %02x overflow\r\n", ep->bEndpointAddress);
- return -1;
- }
- old_ep_idx = musb_get_active_ep();
- musb_set_active_ep(ep_idx);
- if (USB_EP_DIR_IS_OUT(ep->bEndpointAddress)) {
- g_musb_udc.out_ep[ep_idx].ep_mps = USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize);
- g_musb_udc.out_ep[ep_idx].ep_type = USB_GET_ENDPOINT_TYPE(ep->bmAttributes);
- g_musb_udc.out_ep[ep_idx].ep_enable = true;
- if ((8 << HWREGB(USB_BASE + MUSB_RXFIFOSZ_OFFSET)) < g_musb_udc.out_ep[ep_idx].ep_mps) {
- USB_LOG_ERR("Ep %02x fifo is overflow\r\n", ep->bEndpointAddress);
- return -2;
- }
- HWREGH(USB_BASE + MUSB_IND_RXMAP_OFFSET) = USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize);
- //
- // Allow auto clearing of RxPktRdy when packet of size max packet
- // has been unloaded from the FIFO.
- //
- if (ui32Flags & USB_EP_AUTO_CLEAR) {
- ui32Register = USB_RXCSRH1_AUTOCL;
- }
- //
- // Configure the DMA mode.
- //
- if (ui32Flags & USB_EP_DMA_MODE_1) {
- ui32Register |= USB_RXCSRH1_DMAEN | USB_RXCSRH1_DMAMOD;
- } else if (ui32Flags & USB_EP_DMA_MODE_0) {
- ui32Register |= USB_RXCSRH1_DMAEN;
- }
- //
- // If requested, disable NYET responses for high-speed bulk and
- // interrupt endpoints.
- //
- if (ui32Flags & USB_EP_DIS_NYET) {
- ui32Register |= USB_RXCSRH1_DISNYET;
- }
- //
- // Enable isochronous mode if requested.
- //
- if (USB_GET_ENDPOINT_TYPE(ep->bmAttributes) == 0x01) {
- ui32Register |= USB_RXCSRH1_ISO;
- }
- HWREGB(USB_BASE + MUSB_IND_RXCSRH_OFFSET) = ui32Register;
- // Reset the Data toggle to zero.
- if (HWREGB(USB_BASE + MUSB_IND_RXCSRL_OFFSET) & USB_RXCSRL1_RXRDY)
- HWREGB(USB_BASE + MUSB_IND_RXCSRL_OFFSET) = (USB_RXCSRL1_CLRDT | USB_RXCSRL1_FLUSH);
- else
- HWREGB(USB_BASE + MUSB_IND_RXCSRL_OFFSET) = USB_RXCSRL1_CLRDT;
- } else {
- g_musb_udc.in_ep[ep_idx].ep_mps = USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize);
- g_musb_udc.in_ep[ep_idx].ep_type = USB_GET_ENDPOINT_TYPE(ep->bmAttributes);
- g_musb_udc.in_ep[ep_idx].ep_enable = true;
- if ((8 << HWREGB(USB_BASE + MUSB_TXFIFOSZ_OFFSET)) < g_musb_udc.in_ep[ep_idx].ep_mps) {
- USB_LOG_ERR("Ep %02x fifo is overflow\r\n", ep->bEndpointAddress);
- return -2;
- }
- HWREGH(USB_BASE + MUSB_IND_TXMAP_OFFSET) = USB_GET_MAXPACKETSIZE(ep->wMaxPacketSize);
- //
- // Allow auto setting of TxPktRdy when max packet size has been loaded
- // into the FIFO.
- //
- if (ui32Flags & USB_EP_AUTO_SET) {
- ui32Register |= USB_TXCSRH1_AUTOSET;
- }
- //
- // Configure the DMA mode.
- //
- if (ui32Flags & USB_EP_DMA_MODE_1) {
- ui32Register |= USB_TXCSRH1_DMAEN | USB_TXCSRH1_DMAMOD;
- } else if (ui32Flags & USB_EP_DMA_MODE_0) {
- ui32Register |= USB_TXCSRH1_DMAEN;
- }
- //
- // Enable isochronous mode if requested.
- //
- if (USB_GET_ENDPOINT_TYPE(ep->bmAttributes) == 0x01) {
- ui32Register |= USB_TXCSRH1_ISO;
- }
- HWREGB(USB_BASE + MUSB_IND_TXCSRH_OFFSET) = ui32Register;
- // Reset the Data toggle to zero.
- if (HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) & USB_TXCSRL1_TXRDY)
- HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) = (USB_TXCSRL1_CLRDT | USB_TXCSRL1_FLUSH);
- else
- HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) = USB_TXCSRL1_CLRDT;
- }
- musb_set_active_ep(old_ep_idx);
- return 0;
- }
- int usbd_ep_close(uint8_t busid, const uint8_t ep)
- {
- return 0;
- }
- int usbd_ep_set_stall(uint8_t busid, const uint8_t ep)
- {
- uint8_t ep_idx = USB_EP_GET_IDX(ep);
- uint8_t old_ep_idx;
- old_ep_idx = musb_get_active_ep();
- musb_set_active_ep(ep_idx);
- if (USB_EP_DIR_IS_OUT(ep)) {
- if (ep_idx == 0x00) {
- usb_ep0_state = USB_EP0_STATE_STALL;
- HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) |= (USB_CSRL0_STALL | USB_CSRL0_RXRDYC);
- } else {
- HWREGB(USB_BASE + MUSB_IND_RXCSRL_OFFSET) |= USB_RXCSRL1_STALL;
- }
- } else {
- if (ep_idx == 0x00) {
- usb_ep0_state = USB_EP0_STATE_STALL;
- HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) |= (USB_CSRL0_STALL | USB_CSRL0_RXRDYC);
- } else {
- HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) |= USB_TXCSRL1_STALL;
- }
- }
- musb_set_active_ep(old_ep_idx);
- return 0;
- }
- int usbd_ep_clear_stall(uint8_t busid, const uint8_t ep)
- {
- uint8_t ep_idx = USB_EP_GET_IDX(ep);
- uint8_t old_ep_idx;
- old_ep_idx = musb_get_active_ep();
- musb_set_active_ep(ep_idx);
- if (USB_EP_DIR_IS_OUT(ep)) {
- if (ep_idx == 0x00) {
- HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) &= ~USB_CSRL0_STALLED;
- } else {
- // Clear the stall on an OUT endpoint.
- HWREGB(USB_BASE + MUSB_IND_RXCSRL_OFFSET) &= ~(USB_RXCSRL1_STALL | USB_RXCSRL1_STALLED);
- // Reset the data toggle.
- HWREGB(USB_BASE + MUSB_IND_RXCSRL_OFFSET) |= USB_RXCSRL1_CLRDT;
- }
- } else {
- if (ep_idx == 0x00) {
- HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) &= ~USB_CSRL0_STALLED;
- } else {
- // Clear the stall on an IN endpoint.
- HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) &= ~(USB_TXCSRL1_STALL | USB_TXCSRL1_STALLED);
- // Reset the data toggle.
- HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) |= USB_TXCSRL1_CLRDT;
- }
- }
- musb_set_active_ep(old_ep_idx);
- return 0;
- }
- int usbd_ep_is_stalled(uint8_t busid, const uint8_t ep, uint8_t *stalled)
- {
- uint8_t ep_idx = USB_EP_GET_IDX(ep);
- uint8_t old_ep_idx;
- old_ep_idx = musb_get_active_ep();
- musb_set_active_ep(ep_idx);
- if (USB_EP_DIR_IS_OUT(ep)) {
- if(HWREGB(USB_BASE + MUSB_IND_RXCSRL_OFFSET) & USB_RXCSRL1_STALL) {
- *stalled = 1;
- } else {
- *stalled = 0;
- }
- } else {
- if(HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) & USB_TXCSRL1_STALL) {
- *stalled = 1;
- } else {
- *stalled = 0;
- }
- }
- musb_set_active_ep(old_ep_idx);
- return 0;
- }
- int usbd_ep_start_write(uint8_t busid, const uint8_t ep, const uint8_t *data, uint32_t data_len)
- {
- uint8_t ep_idx = USB_EP_GET_IDX(ep);
- uint8_t old_ep_idx;
- if (!data && data_len) {
- return -1;
- }
- if (!g_musb_udc.in_ep[ep_idx].ep_enable) {
- return -2;
- }
- old_ep_idx = musb_get_active_ep();
- musb_set_active_ep(ep_idx);
- if (HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) & USB_TXCSRL1_TXRDY) {
- musb_set_active_ep(old_ep_idx);
- return -3;
- }
- g_musb_udc.in_ep[ep_idx].xfer_buf = (uint8_t *)data;
- g_musb_udc.in_ep[ep_idx].xfer_len = data_len;
- g_musb_udc.in_ep[ep_idx].actual_xfer_len = 0;
- if (data_len == 0) {
- if (ep_idx == 0x00) {
- if (g_musb_udc.setup.wLength == 0) {
- usb_ep0_state = USB_EP0_STATE_IN_STATUS;
- } else {
- usb_ep0_state = USB_EP0_STATE_IN_ZLP;
- }
- HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) = (USB_CSRL0_TXRDY | USB_CSRL0_DATAEND);
- } else {
- HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) = USB_TXCSRL1_TXRDY;
- HWREGH(USB_BASE + MUSB_TXIE_OFFSET) |= (1 << ep_idx);
- }
- musb_set_active_ep(old_ep_idx);
- return 0;
- }
- data_len = MIN(data_len, g_musb_udc.in_ep[ep_idx].ep_mps);
- musb_write_packet(ep_idx, (uint8_t *)data, data_len);
- HWREGH(USB_BASE + MUSB_TXIE_OFFSET) |= (1 << ep_idx);
- if (ep_idx == 0x00) {
- usb_ep0_state = USB_EP0_STATE_IN_DATA;
- if (data_len < g_musb_udc.in_ep[ep_idx].ep_mps) {
- HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) = (USB_CSRL0_TXRDY | USB_CSRL0_DATAEND);
- } else {
- HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) = USB_CSRL0_TXRDY;
- }
- } else {
- HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) = USB_TXCSRL1_TXRDY;
- }
- musb_set_active_ep(old_ep_idx);
- return 0;
- }
- int usbd_ep_start_read(uint8_t busid, const uint8_t ep, uint8_t *data, uint32_t data_len)
- {
- uint8_t ep_idx = USB_EP_GET_IDX(ep);
- uint8_t old_ep_idx;
- if (!data && data_len) {
- return -1;
- }
- if (!g_musb_udc.out_ep[ep_idx].ep_enable) {
- return -2;
- }
- old_ep_idx = musb_get_active_ep();
- musb_set_active_ep(ep_idx);
- g_musb_udc.out_ep[ep_idx].xfer_buf = data;
- g_musb_udc.out_ep[ep_idx].xfer_len = data_len;
- g_musb_udc.out_ep[ep_idx].actual_xfer_len = 0;
- if (data_len == 0) {
- if (ep_idx == 0) {
- usb_ep0_state = USB_EP0_STATE_SETUP;
- }
- musb_set_active_ep(old_ep_idx);
- return 0;
- }
- if (ep_idx == 0) {
- usb_ep0_state = USB_EP0_STATE_OUT_DATA;
- } else {
- HWREGH(USB_BASE + MUSB_RXIE_OFFSET) |= (1 << ep_idx);
- }
- musb_set_active_ep(old_ep_idx);
- return 0;
- }
- static void handle_ep0(void)
- {
- uint8_t ep0_status = HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET);
- uint16_t read_count;
- if (ep0_status & USB_CSRL0_STALLED) {
- HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) &= ~USB_CSRL0_STALLED;
- usb_ep0_state = USB_EP0_STATE_SETUP;
- return;
- }
- if (ep0_status & USB_CSRL0_SETEND) {
- HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) = USB_CSRL0_SETENDC;
- }
- if (g_musb_udc.dev_addr > 0) {
- HWREGB(USB_BASE + MUSB_FADDR_OFFSET) = g_musb_udc.dev_addr;
- g_musb_udc.dev_addr = 0;
- }
- switch (usb_ep0_state) {
- case USB_EP0_STATE_SETUP:
- if (ep0_status & USB_CSRL0_RXRDY) {
- read_count = HWREGH(USB_BASE + MUSB_IND_RXCOUNT_OFFSET);
- if (read_count != 8) {
- return;
- }
- musb_read_packet(0, (uint8_t *)&g_musb_udc.setup, 8);
- if (g_musb_udc.setup.wLength) {
- HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) = USB_CSRL0_RXRDYC;
- } else {
- HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) = (USB_CSRL0_RXRDYC | USB_CSRL0_DATAEND);
- }
- usbd_event_ep0_setup_complete_handler(0, (uint8_t *)&g_musb_udc.setup);
- }
- break;
- case USB_EP0_STATE_IN_DATA:
- if (g_musb_udc.in_ep[0].xfer_len > g_musb_udc.in_ep[0].ep_mps) {
- g_musb_udc.in_ep[0].actual_xfer_len += g_musb_udc.in_ep[0].ep_mps;
- g_musb_udc.in_ep[0].xfer_len -= g_musb_udc.in_ep[0].ep_mps;
- } else {
- g_musb_udc.in_ep[0].actual_xfer_len += g_musb_udc.in_ep[0].xfer_len;
- g_musb_udc.in_ep[0].xfer_len = 0;
- }
- usbd_event_ep_in_complete_handler(0, 0x80, g_musb_udc.in_ep[0].actual_xfer_len);
- break;
- case USB_EP0_STATE_OUT_DATA:
- if (ep0_status & USB_CSRL0_RXRDY) {
- read_count = HWREGH(USB_BASE + MUSB_IND_RXCOUNT_OFFSET);
- musb_read_packet(0, g_musb_udc.out_ep[0].xfer_buf, read_count);
- g_musb_udc.out_ep[0].xfer_buf += read_count;
- g_musb_udc.out_ep[0].actual_xfer_len += read_count;
- if (read_count < g_musb_udc.out_ep[0].ep_mps) {
- usbd_event_ep_out_complete_handler(0, 0x00, g_musb_udc.out_ep[0].actual_xfer_len);
- HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) = (USB_CSRL0_RXRDYC | USB_CSRL0_DATAEND);
- usb_ep0_state = USB_EP0_STATE_IN_STATUS;
- } else {
- HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) = USB_CSRL0_RXRDYC;
- }
- }
- break;
- case USB_EP0_STATE_IN_STATUS:
- case USB_EP0_STATE_IN_ZLP:
- usb_ep0_state = USB_EP0_STATE_SETUP;
- usbd_event_ep_in_complete_handler(0, 0x80, 0);
- break;
- }
- }
- void USBD_IRQHandler(uint8_t busid)
- {
- uint32_t is;
- uint32_t txis;
- uint32_t rxis;
- uint8_t old_ep_idx;
- uint8_t ep_idx;
- uint16_t write_count, read_count;
- is = HWREGB(USB_BASE + MUSB_IS_OFFSET);
- txis = HWREGH(USB_BASE + MUSB_TXIS_OFFSET);
- rxis = HWREGH(USB_BASE + MUSB_RXIS_OFFSET);
- HWREGB(USB_BASE + MUSB_IS_OFFSET) = is;
- old_ep_idx = musb_get_active_ep();
- /* Receive a reset signal from the USB bus */
- if (is & USB_IS_RESET) {
- memset(&g_musb_udc, 0, sizeof(struct musb_udc));
- usbd_event_reset_handler(0);
- HWREGH(USB_BASE + MUSB_TXIE_OFFSET) = USB_TXIE_EP0;
- HWREGH(USB_BASE + MUSB_RXIE_OFFSET) = 0;
- usb_ep0_state = USB_EP0_STATE_SETUP;
- }
- if (is & USB_IS_SOF) {
- }
- if (is & USB_IS_RESUME) {
- usbd_event_resume_handler(0);
- }
- if (is & USB_IS_SUSPEND) {
- usbd_event_suspend_handler(0);
- }
- txis &= HWREGH(USB_BASE + MUSB_TXIE_OFFSET);
- /* Handle EP0 interrupt */
- if (txis & USB_TXIE_EP0) {
- HWREGH(USB_BASE + MUSB_TXIS_OFFSET) = USB_TXIE_EP0;
- musb_set_active_ep(0);
- handle_ep0();
- txis &= ~USB_TXIE_EP0;
- }
- ep_idx = 1;
- while (txis) {
- if (txis & (1 << ep_idx)) {
- musb_set_active_ep(ep_idx);
- HWREGH(USB_BASE + MUSB_TXIS_OFFSET) = (1 << ep_idx);
- if (HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) & USB_TXCSRL1_UNDRN) {
- HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) &= ~USB_TXCSRL1_UNDRN;
- }
- if (g_musb_udc.in_ep[ep_idx].xfer_len > g_musb_udc.in_ep[ep_idx].ep_mps) {
- g_musb_udc.in_ep[ep_idx].xfer_buf += g_musb_udc.in_ep[ep_idx].ep_mps;
- g_musb_udc.in_ep[ep_idx].actual_xfer_len += g_musb_udc.in_ep[ep_idx].ep_mps;
- g_musb_udc.in_ep[ep_idx].xfer_len -= g_musb_udc.in_ep[ep_idx].ep_mps;
- } else {
- g_musb_udc.in_ep[ep_idx].xfer_buf += g_musb_udc.in_ep[ep_idx].xfer_len;
- g_musb_udc.in_ep[ep_idx].actual_xfer_len += g_musb_udc.in_ep[ep_idx].xfer_len;
- g_musb_udc.in_ep[ep_idx].xfer_len = 0;
- }
- if (g_musb_udc.in_ep[ep_idx].xfer_len == 0) {
- HWREGH(USB_BASE + MUSB_TXIE_OFFSET) &= ~(1 << ep_idx);
- usbd_event_ep_in_complete_handler(0, ep_idx | 0x80, g_musb_udc.in_ep[ep_idx].actual_xfer_len);
- } else {
- write_count = MIN(g_musb_udc.in_ep[ep_idx].xfer_len, g_musb_udc.in_ep[ep_idx].ep_mps);
- musb_write_packet(ep_idx, g_musb_udc.in_ep[ep_idx].xfer_buf, write_count);
- HWREGB(USB_BASE + MUSB_IND_TXCSRL_OFFSET) = USB_TXCSRL1_TXRDY;
- }
- txis &= ~(1 << ep_idx);
- }
- ep_idx++;
- }
- rxis &= HWREGH(USB_BASE + MUSB_RXIE_OFFSET);
- ep_idx = 1;
- while (rxis) {
- if (rxis & (1 << ep_idx)) {
- musb_set_active_ep(ep_idx);
- HWREGH(USB_BASE + MUSB_RXIS_OFFSET) = (1 << ep_idx);
- if (HWREGB(USB_BASE + MUSB_IND_RXCSRL_OFFSET) & USB_RXCSRL1_RXRDY) {
- read_count = HWREGH(USB_BASE + MUSB_IND_RXCOUNT_OFFSET);
- musb_read_packet(ep_idx, g_musb_udc.out_ep[ep_idx].xfer_buf, read_count);
- HWREGB(USB_BASE + MUSB_IND_RXCSRL_OFFSET) &= ~(USB_RXCSRL1_RXRDY);
- g_musb_udc.out_ep[ep_idx].xfer_buf += read_count;
- g_musb_udc.out_ep[ep_idx].actual_xfer_len += read_count;
- g_musb_udc.out_ep[ep_idx].xfer_len -= read_count;
- if ((read_count < g_musb_udc.out_ep[ep_idx].ep_mps) || (g_musb_udc.out_ep[ep_idx].xfer_len == 0)) {
- HWREGH(USB_BASE + MUSB_RXIE_OFFSET) &= ~(1 << ep_idx);
- usbd_event_ep_out_complete_handler(0, ep_idx, g_musb_udc.out_ep[ep_idx].actual_xfer_len);
- } else {
- }
- }
- rxis &= ~(1 << ep_idx);
- }
- ep_idx++;
- }
- musb_set_active_ep(old_ep_idx);
- }
|