| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950 |
- /*
- * Copyright (C) 2022-2024, Xiaohua Semiconductor Co., Ltd.
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date Author Notes
- * 2023-02-14 CDT first version
- * 2025-07-25 CDT support HC32F4A8
- */
- /*******************************************************************************
- * Include files
- ******************************************************************************/
- #include <rtthread.h>
- #include <rtdevice.h>
- #if defined(BSP_USING_USBD)
- //#define DRV_DEBUG
- #define LOG_TAG "drv.usbd"
- #include <drv_log.h>
- #include "board_config.h"
- #include "irq_config.h"
- #include "drv_usbd.h"
- #if defined(HC32F472)
- #define USBFS_VBUS_INT_PIN (rt_base_t)(((rt_uint16_t)USBF_VBUS_PORT * 16) + __CLZ(__RBIT(USBF_VBUS_PIN)))
- #endif
- #if !defined(BSP_USING_USBD_HS)
- extern rt_err_t rt_hw_usbfs_board_init(void);
- #else
- extern rt_err_t rt_hw_usbhs_board_init(void);
- #endif
- extern void rt_hw_us_delay(rt_uint32_t us);
- static usb_core_instance _hc32_usbd;
- static struct udcd _hc32_udc;
- static struct ep_id _ep_pool[] =
- {
- {0x0, USB_EP_ATTR_CONTROL, USB_DIR_INOUT, 64, ID_ASSIGNED },
- {0x1, USB_EP_ATTR_BULK, USB_DIR_IN, 64, ID_UNASSIGNED},
- {0x1, USB_EP_ATTR_BULK, USB_DIR_OUT, 64, ID_UNASSIGNED},
- {0x2, USB_EP_ATTR_BULK, USB_DIR_IN, 64, ID_UNASSIGNED},
- {0x2, USB_EP_ATTR_BULK, USB_DIR_OUT, 64, ID_UNASSIGNED},
- {0x3, USB_EP_ATTR_BULK, USB_DIR_IN, 64, ID_UNASSIGNED},
- {0x3, USB_EP_ATTR_BULK, USB_DIR_OUT, 64, ID_UNASSIGNED},
- {0x4, USB_EP_ATTR_INT, USB_DIR_IN, 64, ID_UNASSIGNED},
- {0x4, USB_EP_ATTR_INT, USB_DIR_OUT, 64, ID_UNASSIGNED},
- {0x5, USB_EP_ATTR_ISOC, USB_DIR_IN, 64, ID_UNASSIGNED},
- {0x5, USB_EP_ATTR_ISOC, USB_DIR_OUT, 64, ID_UNASSIGNED},
- #if defined (HC32F4A0) || defined(HC32F4A8)
- {0x6, USB_EP_ATTR_BULK, USB_DIR_IN, 64, ID_UNASSIGNED},
- {0x6, USB_EP_ATTR_BULK, USB_DIR_OUT, 64, ID_UNASSIGNED},
- {0x7, USB_EP_ATTR_BULK, USB_DIR_IN, 64, ID_UNASSIGNED},
- {0x7, USB_EP_ATTR_BULK, USB_DIR_OUT, 64, ID_UNASSIGNED},
- {0x8, USB_EP_ATTR_BULK, USB_DIR_IN, 64, ID_UNASSIGNED},
- {0x8, USB_EP_ATTR_BULK, USB_DIR_OUT, 64, ID_UNASSIGNED},
- {0x9, USB_EP_ATTR_BULK, USB_DIR_IN, 64, ID_UNASSIGNED},
- {0x9, USB_EP_ATTR_BULK, USB_DIR_OUT, 64, ID_UNASSIGNED},
- {0xA, USB_EP_ATTR_BULK, USB_DIR_IN, 64, ID_UNASSIGNED},
- {0xA, USB_EP_ATTR_BULK, USB_DIR_OUT, 64, ID_UNASSIGNED},
- {0xB, USB_EP_ATTR_INT, USB_DIR_IN, 64, ID_UNASSIGNED},
- {0xB, USB_EP_ATTR_INT, USB_DIR_OUT, 64, ID_UNASSIGNED},
- {0xC, USB_EP_ATTR_INT, USB_DIR_IN, 64, ID_UNASSIGNED},
- {0xC, USB_EP_ATTR_INT, USB_DIR_OUT, 64, ID_UNASSIGNED},
- {0xD, USB_EP_ATTR_INT, USB_DIR_IN, 64, ID_UNASSIGNED},
- {0xD, USB_EP_ATTR_INT, USB_DIR_OUT, 64, ID_UNASSIGNED},
- {0xE, USB_EP_ATTR_ISOC, USB_DIR_IN, 64, ID_UNASSIGNED},
- {0xE, USB_EP_ATTR_ISOC, USB_DIR_OUT, 64, ID_UNASSIGNED},
- {0xF, USB_EP_ATTR_ISOC, USB_DIR_IN, 64, ID_UNASSIGNED},
- {0xF, USB_EP_ATTR_ISOC, USB_DIR_OUT, 64, ID_UNASSIGNED},
- #endif
- {0xFF, USB_EP_ATTR_TYPE_MASK, USB_DIR_MASK, 0, ID_ASSIGNED },
- };
- __WEAK void usb_udelay(const uint32_t usec)
- {
- rt_hw_us_delay(usec);
- }
- __WEAK void usb_mdelay(const uint32_t msec)
- {
- rt_thread_mdelay(msec);
- }
- static void usb_opendevep(usb_core_instance *pdev, uint8_t ep_addr, uint16_t ep_mps, uint8_t ep_type)
- {
- USB_DEV_EP *ep;
- __IO uint8_t tmp_1, tmp_2;
- tmp_1 = ep_addr >> 7; /* EP type, it is IN(=1) or OUT(=0) */
- tmp_2 = ep_addr & 0x7FU; /* EP number */
- if (tmp_1 == 1U)
- {
- ep = &pdev->dev.in_ep[tmp_2];
- }
- else
- {
- ep = &pdev->dev.out_ep[tmp_2];
- }
- ep->epidx = tmp_2;
- ep->ep_dir = tmp_1;
- ep->maxpacket = ep_mps;
- ep->trans_type = ep_type;
- if (tmp_1 == 1U)
- {
- /* Assign a Tx FIFO */
- ep->tx_fifo_num = tmp_2;
- }
- /* Set initial data PID. */
- if (ep_type == EP_TYPE_BULK)
- {
- ep->data_pid_start = 0U;
- }
- usb_epactive(&pdev->regs, ep);
- }
- static void usb_shutdevep(usb_core_instance *pdev, uint8_t ep_addr)
- {
- USB_DEV_EP *ep;
- __IO uint8_t tmp_1, tmp_2;
- tmp_1 = ep_addr >> 7; /* EP type, it is IN(=1) or OUT(=0) */
- tmp_2 = ep_addr & 0x7FU; /* EP number */
- if (tmp_1 == 1U)
- {
- ep = &pdev->dev.in_ep[tmp_2];
- }
- else
- {
- ep = &pdev->dev.out_ep[tmp_2];
- }
- ep->epidx = tmp_2;
- ep->ep_dir = tmp_1;
- usb_epdeactive(&pdev->regs, ep);
- }
- static void usb_readytorx(usb_core_instance *pdev, uint8_t ep_addr, uint8_t *pbuf, uint16_t buf_len)
- {
- USB_DEV_EP *ep;
- __IO uint8_t tmp_1;
- tmp_1 = ep_addr & 0x7FU; /* EP number */
- ep = &pdev->dev.out_ep[tmp_1];
- /* setup and start the Xfer */
- ep->xfer_buff = pbuf;
- ep->xfer_len = (uint32_t)buf_len;
- ep->xfer_count = 0UL;
- ep->ep_dir = 0U;
- ep->epidx = tmp_1;
- if (pdev->basic_cfgs.dmaen == 1U)
- {
- ep->dma_addr = (uint32_t)pbuf;
- }
- if (tmp_1 == 0U)
- {
- usb_ep0transbegin(&pdev->regs, ep, pdev->basic_cfgs.dmaen);
- }
- else
- {
- usb_epntransbegin(&pdev->regs, ep, pdev->basic_cfgs.dmaen);
- }
- }
- static void usb_deveptx(usb_core_instance *pdev, uint8_t ep_addr, uint8_t *pbuf, uint32_t buf_len)
- {
- USB_DEV_EP *ep;
- __IO uint8_t tmp_1;
- tmp_1 = ep_addr & 0x7FU; /* EP number */
- ep = &pdev->dev.in_ep[tmp_1];
- /* Setup and start the Transfer */
- ep->ep_dir = 1U;
- ep->epidx = tmp_1;
- ep->xfer_buff = pbuf;
- ep->dma_addr = (uint32_t)pbuf;
- ep->xfer_count = 0UL;
- ep->xfer_len = buf_len;
- if (tmp_1 == 0U)
- {
- usb_ep0transbegin(&pdev->regs, ep, pdev->basic_cfgs.dmaen);
- }
- else
- {
- usb_epntransbegin(&pdev->regs, ep, pdev->basic_cfgs.dmaen);
- }
- }
- static void usb_stalldevep(usb_core_instance *pdev, uint8_t epnum)
- {
- USB_DEV_EP *ep;
- __IO uint8_t tmp_1, tmp_2;
- tmp_1 = epnum >> 7; /* EP type, it is IN(=1) or OUT(=0) */
- tmp_2 = epnum & 0x7FU; /* EP number */
- if (tmp_1 != 0U)
- {
- ep = &pdev->dev.in_ep[tmp_2];
- }
- else
- {
- ep = &pdev->dev.out_ep[tmp_2];
- }
- ep->ep_stall = 1U;
- ep->epidx = tmp_2;
- if (tmp_1 != 0U)
- {
- ep->ep_dir = 1U;
- }
- else
- {
- ep->ep_dir = 0U;
- }
- usb_setepstall(&pdev->regs, ep);
- }
- static void usb_clrstall(usb_core_instance *pdev, uint8_t epnum)
- {
- USB_DEV_EP *ep;
- __IO uint8_t tmp_1, tmp_2;
- tmp_1 = epnum >> 7; /* EP type, it is IN(=1) or OUT(=0) */
- tmp_2 = epnum & 0x7FU; /* EP number */
- if (tmp_1 != 0U)
- {
- ep = &pdev->dev.in_ep[tmp_2];
- }
- else
- {
- ep = &pdev->dev.out_ep[tmp_2];
- }
- ep->ep_stall = 0U;
- ep->epidx = tmp_2;
- if (tmp_1 != 0U)
- {
- ep->ep_dir = 1U;
- }
- else
- {
- ep->ep_dir = 0U;
- }
- usb_clearepstall(&pdev->regs, ep);
- }
- static void usb_dev_rst(usb_core_instance *pdev)
- {
- usb_opendevep(pdev, 0x00U, USB_MAX_EP0_SIZE, EP_TYPE_CTRL);
- usb_opendevep(pdev, 0x80U, USB_MAX_EP0_SIZE, EP_TYPE_CTRL);
- rt_usbd_reset_handler(&_hc32_udc);
- LOG_D("USB Reset");
- }
- static void usb_ctrlconn(usb_core_instance *pdev, uint8_t conn)
- {
- __IO uint8_t tmp_1;
- tmp_1 = conn;
- if (tmp_1 != 0U)
- {
- rt_usbd_connect_handler(&_hc32_udc);
- LOG_D("USB Connect");
- }
- else
- {
- rt_usbd_disconnect_handler(&_hc32_udc);
- LOG_D("USB Disconnect");
- }
- }
- static void usb_dev_susp(usb_core_instance *pdev)
- {
- LOG_D("USB Suspend");
- }
- static void usb_dev_resume(usb_core_instance *pdev)
- {
- LOG_D("USB Resume");
- }
- static void usb_sof_process(usb_core_instance *pdev)
- {
- rt_usbd_sof_handler(&_hc32_udc);
- }
- static void usb_setup_process(usb_core_instance *pdev)
- {
- rt_usbd_ep0_setup_handler(&_hc32_udc, (struct urequest *)pdev->dev.setup_pkt_buf);
- }
- static void usb_dataout_process(usb_core_instance *pdev, uint8_t epnum)
- {
- if (epnum != 0)
- {
- rt_usbd_ep_out_handler(&_hc32_udc, epnum, pdev->dev.out_ep[epnum].xfer_count);
- }
- else
- {
- rt_usbd_ep0_out_handler(&_hc32_udc, pdev->dev.out_ep[0].xfer_count);
- }
- }
- static void usb_datain_process(usb_core_instance *pdev, uint8_t epnum)
- {
- if (epnum == 0)
- {
- rt_usbd_ep0_in_handler(&_hc32_udc);
- }
- else
- {
- rt_usbd_ep_in_handler(&_hc32_udc, 0x80 | epnum, pdev->dev.in_ep[epnum].xfer_count);
- }
- }
- static void usb_isoinincomplt_process(usb_core_instance *pdev)
- {
- /* reserved */
- }
- static void usb_isooutincomplt_process(usb_core_instance *pdev)
- {
- /* reserved */
- }
- static usb_dev_int_cbk_typedef dev_int_cbk =
- {
- &usb_dev_rst,
- &usb_ctrlconn,
- &usb_dev_susp,
- &usb_dev_resume,
- &usb_sof_process,
- &usb_setup_process,
- &usb_dataout_process,
- &usb_datain_process,
- &usb_isoinincomplt_process,
- &usb_isooutincomplt_process
- };
- static usb_dev_int_cbk_typedef *dev_int_cbkpr = &dev_int_cbk;
- static uint32_t usb_rddevinep(usb_core_instance *pdev, uint8_t epnum)
- {
- uint32_t u32diepmsk;
- uint32_t u32diepempmsk;
- u32diepmsk = READ_REG32(pdev->regs.DREGS->DIEPMSK);
- u32diepempmsk = READ_REG32(pdev->regs.DREGS->DIEPEMPMSK);
- u32diepmsk |= (((u32diepempmsk >> epnum) & 0x1UL) << 7U);
- return (READ_REG32(pdev->regs.INEP_REGS[epnum]->DIEPINT) & u32diepmsk);
- }
- static void usb_wrblanktxfifo(usb_core_instance *pdev, uint32_t epnum)
- {
- USB_DEV_EP *ep;
- uint32_t u32Len;
- uint32_t u32Len32b;
- uint16_t u16spclen;
- uint32_t u32diepempmsk;
- ep = &pdev->dev.in_ep[epnum];
- u32Len = ep->xfer_len - ep->xfer_count;
- if (u32Len > ep->maxpacket)
- {
- u32Len = ep->maxpacket;
- }
- u32Len32b = (u32Len + 3UL) >> 2;
- u16spclen = usb_rdineptxfspcavail(pdev, epnum);
- while ((u16spclen >= u32Len32b) && (ep->xfer_count < ep->xfer_len))
- {
- u32Len = ep->xfer_len - ep->xfer_count;
- if (u32Len > ep->maxpacket)
- {
- u32Len = ep->maxpacket;
- }
- u32Len32b = (u32Len + 3UL) >> 2;
- usb_wrpkt(&pdev->regs, ep->xfer_buff, (uint8_t)epnum, (uint16_t)u32Len, pdev->basic_cfgs.dmaen);
- ep->xfer_buff += u32Len;
- ep->xfer_count += u32Len;
- u16spclen = usb_rdineptxfspcavail(pdev, epnum);
- }
- if (u32Len == 0UL)
- {
- u32diepempmsk = 0x01UL << epnum;
- CLR_REG32_BIT(pdev->regs.DREGS->DIEPEMPMSK, u32diepempmsk);
- }
- }
- #if defined(HC32F4A0) || defined(HC32F460) || defined(HC32F4A8)
- #ifdef VBUS_SENSING_ENABLED
- static void usb_sessionrequest_isr(usb_core_instance *pdev)
- {
- dev_int_cbkpr->devctrlconnect(pdev, 1U);
- WRITE_REG32(pdev->regs.GREGS->GINTSTS, USBFS_GINTSTS_VBUSVINT);
- if (0U != pdev->basic_cfgs.low_power)
- {
- CLR_REG32_BIT(*pdev->regs.GCCTL, USBFS_GCCTL_STPPCLK | USBFS_GCCTL_GATEHCLK);
- }
- }
- #endif
- #endif
- static void usb_resume_isr(usb_core_instance *pdev)
- {
- if (0U != pdev->basic_cfgs.low_power)
- {
- CLR_REG32_BIT(*pdev->regs.GCCTL, USBFS_GCCTL_STPPCLK | USBFS_GCCTL_GATEHCLK);
- }
- CLR_REG32_BIT(pdev->regs.DREGS->DCTL, USBFS_DCTL_RWUSIG);
- dev_int_cbkpr->Resume(pdev);
- WRITE_REG32(pdev->regs.GREGS->GINTSTS, USBFS_GINTSTS_WKUINT);
- }
- static void usb_susp_isr(usb_core_instance *pdev)
- {
- uint32_t u32dsts;
- u32dsts = READ_REG32(pdev->regs.DREGS->DSTS);
- if ((u32dsts & 1UL) != 0UL)
- {
- dev_int_cbkpr->Suspend(pdev);
- }
- WRITE_REG32(pdev->regs.GREGS->GINTSTS, USBFS_GINTSTS_USBSUSP);
- }
- static void usb_inep_isr(usb_core_instance *pdev)
- {
- uint32_t u32diepint;
- uint32_t u32EpIntr;
- uint8_t u8epnum;
- uint32_t u32diepempmsk;
- u32EpIntr = usb_getalliepintr(&pdev->regs);
- u8epnum = 0U;
- while ((0U != u32EpIntr) && (u8epnum < USB_MAX_TX_FIFOS))
- {
- if ((u32EpIntr & 0x1UL) != 0UL)
- {
- u32diepint = usb_rddevinep(pdev, u8epnum);
- if ((u32diepint & XFER_COMPL) != 0UL)
- {
- u32diepempmsk = 1UL << u8epnum;
- CLR_REG32_BIT(pdev->regs.DREGS->DIEPEMPMSK, u32diepempmsk);
- WRITE_REG32(pdev->regs.INEP_REGS[u8epnum]->DIEPINT, XFER_COMPL);
- dev_int_cbkpr->DataInStage(pdev, u8epnum);
- if (pdev->basic_cfgs.dmaen == 1U)
- {
- if ((pdev->dev.device_state == USB_EP0_STATUS_IN) && (u8epnum == 0U))
- {
- pdev->dev.out_ep[0].xfer_len = 64U;
- pdev->dev.out_ep[0].rem_data_len = 64U;
- pdev->dev.out_ep[0].total_data_len = 64U;
- usb_ep0revcfg(&pdev->regs, pdev->basic_cfgs.dmaen, pdev->dev.setup_pkt_buf);
- pdev->dev.device_state = USB_EP0_IDLE;
- }
- }
- }
- if ((u32diepint & EPDISABLED) != 0UL)
- {
- WRITE_REG32(pdev->regs.INEP_REGS[u8epnum]->DIEPINT, EPDISABLED);
- }
- if ((u32diepint & TIME_OUT) != 0UL)
- {
- WRITE_REG32(pdev->regs.INEP_REGS[u8epnum]->DIEPINT, TIME_OUT);
- }
- if ((u32diepint & INTKNTXFEMP) != 0UL)
- {
- WRITE_REG32(pdev->regs.INEP_REGS[u8epnum]->DIEPINT, INTKNTXFEMP);
- }
- if ((u32diepint & INEPNAKEFF) != 0UL)
- {
- WRITE_REG32(pdev->regs.INEP_REGS[u8epnum]->DIEPINT, INEPNAKEFF);
- }
- if ((u32diepint & TXFEMP) != 0UL)
- {
- usb_wrblanktxfifo(pdev, u8epnum);
- }
- }
- u8epnum++;
- u32EpIntr >>= 1U;
- }
- }
- static void usb_outep_isr(usb_core_instance *pdev)
- {
- uint32_t u32EpIntr;
- uint32_t u32doepint;
- uint8_t u8epnum = 0U;
- uint32_t u32Xfer;
- uint32_t u32ReadEpSize;
- u32EpIntr = usb_getalloepintr(&pdev->regs);
- while ((u32EpIntr != 0UL) && (u8epnum < USB_MAX_TX_FIFOS))
- {
- if ((u32EpIntr & 0x1UL) != 0UL)
- {
- u32doepint = usb_getoepintbit(&pdev->regs, u8epnum);
- if ((u32doepint & XFER_COMPL) != 0UL)
- {
- WRITE_REG32(pdev->regs.OUTEP_REGS[u8epnum]->DOEPINT, XFER_COMPL);
- if (pdev->basic_cfgs.dmaen == 1U)
- {
- u32ReadEpSize = (READ_REG32(pdev->regs.OUTEP_REGS[u8epnum]->DOEPTSIZ) & USBFS_DOEPTSIZ_XFRSIZ);
- u32Xfer = LL_MIN(pdev->dev.out_ep[u8epnum].maxpacket, pdev->dev.out_ep[u8epnum].xfer_len);
- pdev->dev.out_ep[u8epnum].xfer_count = u32Xfer - u32ReadEpSize;
- if (u8epnum != 0U)
- {
- pdev->dev.out_ep[u8epnum].xfer_count = pdev->dev.out_ep[u8epnum].xfer_len - u32ReadEpSize;
- }
- }
- dev_int_cbkpr->DataOutStage(pdev, u8epnum);
- if (pdev->basic_cfgs.dmaen == 1U)
- {
- if ((pdev->dev.device_state == USB_EP0_STATUS_OUT) && (u8epnum == 0U))
- {
- pdev->dev.out_ep[0].xfer_len = 64U;
- pdev->dev.out_ep[0].rem_data_len = 64U;
- pdev->dev.out_ep[0].total_data_len = 64U;
- usb_ep0revcfg(&pdev->regs, pdev->basic_cfgs.dmaen, pdev->dev.setup_pkt_buf);
- pdev->dev.device_state = USB_EP0_IDLE;
- }
- }
- }
- if ((u32doepint & EPDISABLED) != 0UL)
- {
- WRITE_REG32(pdev->regs.OUTEP_REGS[u8epnum]->DOEPINT, EPDISABLED);
- }
- if (u8epnum == 0U)
- {
- u32doepint = usb_getoepintbit(&pdev->regs, u8epnum);
- if ((u32doepint & SETUP_BIT) != 0UL)
- {
- dev_int_cbkpr->SetupStage(pdev);
- WRITE_REG32(pdev->regs.OUTEP_REGS[u8epnum]->DOEPINT, SETUP_BIT);
- }
- }
- }
- u8epnum++;
- u32EpIntr >>= 1U;
- }
- }
- static void usb_sof_isr(usb_core_instance *pdev)
- {
- dev_int_cbkpr->SOF(pdev);
- WRITE_REG32(pdev->regs.GREGS->GINTSTS, USBFS_GINTSTS_SOF);
- }
- static void usb_rxstsqlvl_isr(usb_core_instance *pdev)
- {
- uint32_t u32grxsts;
- USB_DEV_EP *ep;
- uint8_t u8epnum;
- uint8_t u8PktStatus;
- uint16_t u16ByteCnt;
- CLR_REG32_BIT(pdev->regs.GREGS->GINTMSK, USBFS_GINTMSK_RXFNEM);
- u32grxsts = READ_REG32(pdev->regs.GREGS->GRXSTSP);
- u8epnum = (uint8_t)(u32grxsts & USBFS_GRXSTSP_CHNUM_EPNUM);
- u8PktStatus = (uint8_t)((u32grxsts & USBFS_GRXSTSP_PKTSTS) >> USBFS_GRXSTSP_PKTSTS_POS);
- u16ByteCnt = (uint16_t)((u32grxsts & USBFS_GRXSTSP_BCNT) >> USBFS_GRXSTSP_BCNT_POS);
- ep = &pdev->dev.out_ep[u8epnum];
- switch (u8PktStatus)
- {
- case STS_DATA_UPDT:
- if (0U != u16ByteCnt)
- {
- RT_ASSERT(RT_IS_ALIGN((uint32_t)ep->xfer_buff, 4UL));
- usb_rdpkt(&pdev->regs, ep->xfer_buff, u16ByteCnt);
- ep->xfer_buff += u16ByteCnt;
- ep->xfer_count += u16ByteCnt;
- }
- else
- {
- ;
- }
- break;
- case STS_SETUP_UPDT:
- /* Copy the setup packet received in FIFO into the setup buffer in RAM */
- usb_rdpkt(&pdev->regs, pdev->dev.setup_pkt_buf, 8U);
- ep->xfer_count += u16ByteCnt;
- break;
- case STS_GOUT_NAK:
- case STS_XFER_COMP:
- case STS_SETUP_COMP:
- break;
- default:
- break;
- }
- SET_REG32_BIT(pdev->regs.GREGS->GINTMSK, USBFS_GINTMSK_RXFNEM);
- }
- static void usb_reset_isr(usb_core_instance *pdev)
- {
- uint32_t i;
- CLR_REG32_BIT(pdev->regs.DREGS->DCTL, USBFS_DCTL_RWUSIG);
- usb_txfifoflush(&pdev->regs, 0UL);
- for (i = 0UL; i < pdev->basic_cfgs.dev_epnum ; i++)
- {
- WRITE_REG32(pdev->regs.INEP_REGS[i]->DIEPINT, 0xFFUL);
- WRITE_REG32(pdev->regs.OUTEP_REGS[i]->DOEPINT, 0xFFUL);
- }
- WRITE_REG32(pdev->regs.DREGS->DAINT, 0xFFFFFFFFUL);
- WRITE_REG32(pdev->regs.DREGS->DAINTMSK, 1UL | (1UL << USBFS_DAINTMSK_OEPINTM_POS));
- WRITE_REG32(pdev->regs.DREGS->DOEPMSK, USBFS_DOEPMSK_STUPM | USBFS_DOEPMSK_XFRCM | USBFS_DOEPMSK_EPDM);
- #ifdef USB_OTG_HS_DEDICATED_EP1_ENABLED
- WRITE_REG32(pdev->regs.DREGS->DOUTEP1MSK, USBFS_DOEPMSK_STUPM | USBFS_DOEPMSK_XFRCM | USBFS_DOEPMSK_EPDM);
- #endif
- WRITE_REG32(pdev->regs.DREGS->DIEPMSK, USBFS_DIEPMSK_XFRCM | USBFS_DIEPMSK_TOM | USBFS_DIEPMSK_EPDM);
- #ifdef USB_OTG_HS_DEDICATED_EP1_ENABLED
- WRITE_REG32(pdev->regs.DREGS->DINEP1MSK, USBFS_DIEPMSK_XFRCM | USBFS_DIEPMSK_TOM | USBFS_DIEPMSK_EPDM);
- #endif
- CLR_REG32_BIT(pdev->regs.DREGS->DCFG, USBFS_DCFG_DAD);
- pdev->dev.out_ep[0].xfer_len = 64U;
- pdev->dev.out_ep[0].rem_data_len = 64U;
- pdev->dev.out_ep[0].total_data_len = 64U;
- usb_ep0revcfg(&pdev->regs, pdev->basic_cfgs.dmaen, pdev->dev.setup_pkt_buf);
- WRITE_REG32(pdev->regs.GREGS->GINTSTS, USBFS_GINTSTS_USBRST);
- dev_int_cbkpr->Reset(pdev);
- }
- static void usb_enumfinish_isr(usb_core_instance *pdev)
- {
- usb_ep0activate(&pdev->regs);
- usb_setaroundtim(pdev);
- WRITE_REG32(pdev->regs.GREGS->GINTSTS, USBFS_GINTSTS_ENUMDNE);
- }
- static void usb_isoinincomplt_isr(usb_core_instance *pdev)
- {
- dev_int_cbkpr->IsoINIncomplete(pdev);
- WRITE_REG32(pdev->regs.GREGS->GINTSTS, USBFS_GINTSTS_IISOIXFR);
- }
- static void usb_isooutincomplt_isr(usb_core_instance *pdev)
- {
- dev_int_cbkpr->IsoOUTIncomplete(pdev);
- WRITE_REG32(pdev->regs.GREGS->GINTSTS, USBFS_GINTSTS_IPXFR_INCOMPISOOUT);
- }
- static void usb_isr_handler(usb_core_instance *pdev)
- {
- uint32_t u32gintsts;
- if (0U == usb_getcurmod(&pdev->regs))
- {
- u32gintsts = usb_getcoreintr(&pdev->regs);
- if (u32gintsts == 0UL)
- {
- return;
- }
- if ((u32gintsts & OUTEP_INT) != 0UL)
- {
- usb_outep_isr(pdev);
- }
- if ((u32gintsts & INEP_INT) != 0UL)
- {
- usb_inep_isr(pdev);
- }
- if ((u32gintsts & MODEMIS_INT) != 0UL)
- {
- WRITE_REG32(pdev->regs.GREGS->GINTSTS, MODEMIS_INT);
- }
- if ((u32gintsts & WAKEUP_INT) != 0UL)
- {
- usb_resume_isr(pdev);
- }
- if ((u32gintsts & USBSUSP_INT) != 0UL)
- {
- usb_susp_isr(pdev);
- }
- if ((u32gintsts & SOF_INT) != 0UL)
- {
- usb_sof_isr(pdev);
- }
- if ((u32gintsts & RXFLVL_INT) != 0UL)
- {
- usb_rxstsqlvl_isr(pdev);
- }
- if ((u32gintsts & USBRST_INT) != 0UL)
- {
- usb_reset_isr(pdev);
- }
- if ((u32gintsts & ENUMDONE_INT) != 0UL)
- {
- usb_enumfinish_isr(pdev);
- }
- if ((u32gintsts & INCOMPLSOIN) != 0UL)
- {
- usb_isoinincomplt_isr(pdev);
- }
- if ((u32gintsts & INCOMPLSOOUT) != 0UL)
- {
- usb_isooutincomplt_isr(pdev);
- }
- #if defined(HC32F4A0) || defined(HC32F460) || defined(HC32F4A8)
- #ifdef VBUS_SENSING_ENABLED
- if ((u32gintsts & VBUSV_INT) != 0UL)
- {
- usb_sessionrequest_isr(pdev);
- }
- #endif
- #endif
- }
- }
- static void usbd_irq_handler(void)
- {
- rt_interrupt_enter();
- usb_isr_handler(&_hc32_usbd);
- rt_interrupt_leave();
- }
- #if defined(HC32F472)
- void USBFS_Handler(void)
- {
- usbd_irq_handler();
- }
- #ifdef VBUS_SENSING_ENABLED
- static void vbus_irq_handler(void *args)
- {
- if (PIN_LOW == rt_pin_read(USBFS_VBUS_INT_PIN))
- {
- SET_REG32_BIT(_hc32_usbd.regs.DREGS->DCTL, USBFS_DCTL_SDIS);
- }
- else
- {
- CLR_REG32_BIT(_hc32_usbd.regs.DREGS->DCTL, USBFS_DCTL_SDIS);
- }
- }
- #endif
- #endif
- static rt_err_t _usbd_ep_set_stall(rt_uint8_t address)
- {
- usb_stalldevep(&_hc32_usbd, address);
- return RT_EOK;
- }
- static rt_err_t _usbd_ep_clear_stall(rt_uint8_t address)
- {
- usb_clrstall(&_hc32_usbd, address);
- return RT_EOK;
- }
- static rt_err_t _usbd_set_address(rt_uint8_t address)
- {
- usb_devaddrset(&_hc32_usbd.regs, address);
- return RT_EOK;
- }
- static rt_err_t _usbd_set_config(rt_uint8_t address)
- {
- return RT_EOK;
- }
- static rt_err_t _usbd_ep_enable(uep_t ep)
- {
- RT_ASSERT(ep != RT_NULL);
- RT_ASSERT(ep->ep_desc != RT_NULL);
- usb_opendevep(&_hc32_usbd, ep->ep_desc->bEndpointAddress,
- ep->ep_desc->wMaxPacketSize, ep->ep_desc->bmAttributes);
- return RT_EOK;
- }
- static rt_err_t _usbd_ep_disable(uep_t ep)
- {
- RT_ASSERT(ep != RT_NULL);
- RT_ASSERT(ep->ep_desc != RT_NULL);
- usb_shutdevep(&_hc32_usbd, ep->ep_desc->bEndpointAddress);
- return RT_EOK;
- }
- static rt_ssize_t _usbd_ep_read(rt_uint8_t address, void *buffer)
- {
- rt_size_t size = 0;
- RT_ASSERT(buffer != RT_NULL);
- return size;
- }
- static rt_ssize_t _usbd_ep_read_prepare(rt_uint8_t address, void *buffer, rt_size_t size)
- {
- usb_readytorx(&_hc32_usbd, address, buffer, size);
- return size;
- }
- static rt_ssize_t _usbd_ep_write(rt_uint8_t address, void *buffer, rt_size_t size)
- {
- usb_deveptx(&_hc32_usbd, address, buffer, size);
- return size;
- }
- static rt_err_t _usbd_ep0_send_status(void)
- {
- usb_deveptx(&_hc32_usbd, 0x00, NULL, 0);
- return RT_EOK;
- }
- static rt_err_t _usbd_suspend(void)
- {
- return RT_EOK;
- }
- static rt_err_t _usbd_wakeup(void)
- {
- return RT_EOK;
- }
- static rt_err_t _usbd_init(rt_device_t device)
- {
- usb_core_instance *pdev;
- stc_usb_port_identify stcPortIdentify;
- struct hc32_irq_config irq_config;
- pdev = (usb_core_instance *)device->user_data;
- #if !defined(BSP_USING_USBD_HS)
- rt_hw_usbfs_board_init();
- FCG_Fcg1PeriphClockCmd(FCG1_PERIPH_USBFS, ENABLE);
- #else
- rt_hw_usbhs_board_init();
- FCG_Fcg1PeriphClockCmd(FCG1_PERIPH_USBHS, ENABLE);
- #endif
- /* Parameters */
- #if !defined(BSP_USING_USBD_HS)
- stcPortIdentify.u8CoreID = USBFS_CORE_ID;
- #else
- stcPortIdentify.u8CoreID = USBHS_CORE_ID;
- #endif
- #if defined (HC32F4A0) || defined(HC32F4A8)
- #if !defined(BSP_USING_USBHS_PHY_EXTERN)
- stcPortIdentify.u8PhyType = USBHS_PHY_EMBED;
- #else
- stcPortIdentify.u8PhyType = USBHS_PHY_EXT;
- #endif
- #endif
- usb_setregaddr(&pdev->regs, &stcPortIdentify, &pdev->basic_cfgs);
- usb_gintdis(&pdev->regs);
- /*Init the Core (common init.) */
- usb_initusbcore(&pdev->regs, &pdev->basic_cfgs);
- /* Force Device Mode*/
- usb_modeset(&pdev->regs, DEVICE_MODE);
- /* Init Device */
- usb_devmodeinit(&pdev->regs, &pdev->basic_cfgs);
- /* Enable USB Global interrupt */
- usb_ginten(&pdev->regs);
- /* NVIC Config */
- #if !defined(BSP_USING_USBD_HS)
- irq_config.irq_num = BSP_USBFS_GLB_IRQ_NUM;
- irq_config.int_src = INT_SRC_USBFS_GLB;
- irq_config.irq_prio = BSP_USBFS_GLB_IRQ_PRIO;
- #else
- irq_config.irq_num = BSP_USBHS_GLB_IRQ_NUM;
- irq_config.int_src = INT_SRC_USBHS_GLB;
- irq_config.irq_prio = BSP_USBHS_GLB_IRQ_PRIO;
- #endif
- /* register interrupt */
- hc32_install_irq_handler(&irq_config,
- usbd_irq_handler,
- RT_TRUE);
- #if defined(HC32F472)
- #ifdef VBUS_SENSING_ENABLED
- /* VBUS Extint config */
- rt_pin_mode(USBFS_VBUS_INT_PIN, PIN_MODE_INPUT);
- rt_pin_attach_irq(USBFS_VBUS_INT_PIN, PIN_IRQ_MODE_RISING_FALLING, vbus_irq_handler, (void *)"callbackargs");
- rt_pin_irq_enable(USBFS_VBUS_INT_PIN, PIN_IRQ_ENABLE);
- #endif
- #endif
- return RT_EOK;
- }
- const static struct udcd_ops _udc_ops =
- {
- _usbd_set_address,
- _usbd_set_config,
- _usbd_ep_set_stall,
- _usbd_ep_clear_stall,
- _usbd_ep_enable,
- _usbd_ep_disable,
- _usbd_ep_read_prepare,
- _usbd_ep_read,
- _usbd_ep_write,
- _usbd_ep0_send_status,
- _usbd_suspend,
- _usbd_wakeup,
- };
- #ifdef RT_USING_DEVICE_OPS
- const static struct rt_device_ops _ops =
- {
- _usbd_init,
- RT_NULL,
- RT_NULL,
- RT_NULL,
- RT_NULL,
- RT_NULL,
- };
- #endif
- int rt_hw_usbd_init(void)
- {
- rt_memset((void *)&_hc32_udc, 0, sizeof(struct udcd));
- _hc32_udc.parent.type = RT_Device_Class_USBDevice;
- #ifdef RT_USING_DEVICE_OPS
- _hc32_udc.parent.ops = &_ops;
- #else
- _hc32_udc.parent.init = _usbd_init;
- #endif
- _hc32_udc.parent.user_data = &_hc32_usbd;
- _hc32_udc.ops = &_udc_ops;
- /* Register endpoint infomation */
- _hc32_udc.ep_pool = _ep_pool;
- _hc32_udc.ep0.id = &_ep_pool[0];
- #ifdef BSP_USBD_SPEED_HS
- _hc32_udc.device_is_hs = RT_TRUE;
- #endif
- rt_device_register((rt_device_t)&_hc32_udc, "usbd", 0);
- rt_usb_device_init();
- return RT_EOK;
- }
- INIT_DEVICE_EXPORT(rt_hw_usbd_init);
- #endif /* BSP_USING_USBD */
|