Repostiory containing DAPLink source code with Reset Pin workaround for HANI_IOT board.
Upstream: https://github.com/ARMmbed/DAPLink
Diff: source/hic_hal/freescale/k26f/usbd_MK26F.c
- Revision:
- 0:01f31e923fe2
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/source/hic_hal/freescale/k26f/usbd_MK26F.c Tue Apr 07 12:55:42 2020 +0200 @@ -0,0 +1,892 @@ +/** + * @file usbd_LPC43xx_USBD0.c + * @brief + * + * DAPLink Interface Firmware + * Copyright (c) 2009-2016, ARM Limited, All Rights Reserved + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "rl_usb.h" +#include "usb.h" +#include "fsl_device_registers.h" +#include "hic_init.h" + +#define __NO_USB_LIB_C +#include "usb_config.c" + +/* Endpoint queue head */ +typedef struct __EPQH { + uint32_t cap; + uint32_t curr_dTD; + uint32_t next_dTD; + uint32_t dTD_token; + uint32_t buf[5]; + uint32_t reserved; + uint32_t setup[2]; + uint32_t reserved1[4]; +} EPQH; + +/* Endpoint transfer descriptor */ +typedef struct __dTD { + uint32_t next_dTD; + uint32_t dTD_token; + uint32_t buf[5]; + uint32_t reserved; +} dTD; + +/* Endpoint */ +typedef struct __EP { + uint8_t *buf; + uint32_t maxPacket; +} EP; + +EPQH __align(2048) EPQHx[(USBD_EP_NUM + 1) * 2]; +dTD __align(32) dTDx[(USBD_EP_NUM + 1) * 2]; + +EP Ep[(USBD_EP_NUM + 1) * 2]; +uint32_t BufUsed; +uint32_t IsoEp; +uint32_t cmpl_pnd; + +#define ENDPTCTRL(EPNum) *(volatile uint32_t *)((uint32_t)(&USBHS->EPCR0) + 4 * EPNum) +#define EP_OUT_IDX(EPNum) (EPNum * 2 ) +#define EP_IN_IDX(EPNum) (EPNum * 2 + 1) +#define HS(en) (USBD_HS_ENABLE * en) + +/* reserve RAM for endpoint buffers */ +#if USBD_VENDOR_ENABLE +/* custom class: user defined buffer size */ +#define EP_BUF_POOL_SIZE 0x1000 +uint8_t __align(4096) EPBufPool[EP_BUF_POOL_SIZE] +#else +/* supported classes are used */ +uint8_t __align(4096) EPBufPool[ + USBD_MAX_PACKET0 * 2 + + USBD_HID_ENABLE * (HS(USBD_HID_HS_ENABLE) ? USBD_HID_HS_WMAXPACKETSIZE : USBD_HID_WMAXPACKETSIZE) * 2 + + USBD_MSC_ENABLE * (HS(USBD_MSC_HS_ENABLE) ? USBD_MSC_HS_WMAXPACKETSIZE : USBD_MSC_WMAXPACKETSIZE) * 2 + + USBD_ADC_ENABLE * (HS(USBD_ADC_HS_ENABLE) ? USBD_ADC_HS_WMAXPACKETSIZE : USBD_ADC_WMAXPACKETSIZE) + + USBD_CDC_ACM_ENABLE * ((HS(USBD_CDC_ACM_HS_ENABLE) ? USBD_CDC_ACM_HS_WMAXPACKETSIZE : USBD_CDC_ACM_WMAXPACKETSIZE) + + (HS(USBD_CDC_ACM_HS_ENABLE) ? USBD_CDC_ACM_HS_WMAXPACKETSIZE1 : USBD_CDC_ACM_WMAXPACKETSIZE1) * 2) + + USBD_BULK_ENABLE * (HS(USBD_BULK_HS_ENABLE) ? USBD_BULK_HS_WMAXPACKETSIZE : USBD_BULK_WMAXPACKETSIZE) * 2 +]; +#endif + +void USBD_PrimeEp(uint32_t EPNum, uint32_t cnt); + +/* + * Usb interrupt enable/disable + * Parameters: ena: enable/disable + * 0: disable interrupt + * 1: enable interrupt + */ + +#ifdef __RTX +void __svc(1) USBD_Intr(int ena); +void __SVC_1(int ena) +{ +#else +void USBD_Intr(int ena) +{ +#endif + + if (ena) { + NVIC_EnableIRQ(USBHS_IRQn); /* Enable USB interrupt */ + } else { + NVIC_DisableIRQ(USBHS_IRQn); /* Disable USB interrupt */ + } +} + + +/* + * USB Device Initialize Function + * Called by the User to initialize USB Device + * Return Value: None + */ + +void USBD_Init(void) +{ + USBD_Intr(0); + + hic_enable_usb_clocks(); + + USBHS->USBCMD |= (1UL << 1); /* usb reset */ + + while (USBHS->USBCMD & (1UL << 1)); + + USBHS->USBMODE = 2 | (1UL << 3);/* device mode */ +#if USBD_HS_ENABLE + USBHS->PORTSC1 &= ~(1UL << 24); +#else + USBHS->PORTSC1 |= (1UL << 24); +#endif + USBHS->OTGSC = 1 | (1UL << 3); + Ep[EP_OUT_IDX(0)].maxPacket = USBD_MAX_PACKET0; + USBHS->USBINTR = (1UL << 0) | /* usb int enable */ + (1UL << 2) | /* port change detect int enable */ + (1UL << 8) | /* suspend int enable */ + (1UL << 16) | /* nak int enable */ + (1UL << 6) | /* reset int enable */ +#ifdef __RTX + ((USBD_RTX_DevTask != 0) ? (1UL << 7) : 0) | /* SOF */ + ((USBD_RTX_DevTask != 0) ? (1UL << 1) : 0) ; /* Error */ +#else + ((USBD_P_SOF_Event != 0) ? (1UL << 7) : 0) | /* SOF */ + ((USBD_P_Error_Event != 0) ? (1UL << 1) : 0) ; /* Error */ +#endif + USBD_Reset(); + USBD_Intr(1); +} + + +/* + * USB Device Connect Function + * Called by the User to Connect/Disconnect USB Device + * Parameters: con: Connect/Disconnect + * Return Value: None + */ + +void USBD_Connect(uint32_t con) +{ + if (con) { + USBHS->USBCMD |= 1; /* run */ + } else { + USBHS->USBCMD &= ~1; /* stop */ + } +} + + +/* + * USB Device Reset Function + * Called automatically on USB Device Reset + * Return Value: None + */ + +void USBD_Reset(void) +{ + uint32_t i; + uint8_t *ptr; + cmpl_pnd = 0; + + for (i = 1; i < USBD_EP_NUM + 1; i++) { + ENDPTCTRL(i) &= ~((1UL << 7) | (1UL << 23)); + } + + /* clear interrupts */ + USBHS->ENDPTNAK = 0xFFFFFFFF; + USBHS->ENDPTNAKEN = 0; + USBHS->USBSTS = 0xFFFFFFFF; + USBHS->EPSETUPSR = USBHS->EPSETUPSR; + USBHS->EPCOMPLETE = USBHS->EPCOMPLETE; + + while (USBHS->EPPRIME); + + USBHS->EPFLUSH = 0xFFFFFFFF; + + while (USBHS->EPFLUSH); + + USBHS->USBCMD &= ~0x00FF0000; /* immediate intrrupt treshold */ + /* clear endpoint queue heads */ + ptr = (uint8_t *)EPQHx; + + for (i = 0; i < sizeof(EPQHx); i++) { + ptr[i] = 0; + } + + /* clear endpoint transfer descriptors */ + ptr = (uint8_t *)dTDx; + + for (i = 0; i < sizeof(dTDx); i++) { + ptr[i] = 0; + } + + Ep[EP_OUT_IDX(0)].maxPacket = USBD_MAX_PACKET0; + Ep[EP_OUT_IDX(0)].buf = EPBufPool; + BufUsed = USBD_MAX_PACKET0; + Ep[EP_IN_IDX(0)].maxPacket = USBD_MAX_PACKET0; + Ep[EP_IN_IDX(0)].buf = &(EPBufPool[BufUsed]); + BufUsed += USBD_MAX_PACKET0; + dTDx[EP_OUT_IDX(0)].next_dTD = 1; + dTDx[EP_IN_IDX(0)].next_dTD = 1; + dTDx[EP_OUT_IDX(0)].dTD_token = (USBD_MAX_PACKET0 << 16) | /* total bytes */ + (1UL << 15); /* int on compl */ + dTDx[EP_IN_IDX(0)].dTD_token = (USBD_MAX_PACKET0 << 16) | /* total bytes */ + (1UL << 15); /* int on compl */ + EPQHx[EP_OUT_IDX(0)].next_dTD = (uint32_t) &dTDx[EP_OUT_IDX(0)]; + EPQHx[EP_IN_IDX(0)].next_dTD = (uint32_t) &dTDx[EP_IN_IDX(0)]; + EPQHx[EP_OUT_IDX(0)].cap = ((USBD_MAX_PACKET0 & 0x0EFF) << 16) | + (1UL << 29) | + (1UL << 15); /* int on setup */ + EPQHx[EP_IN_IDX(0)].cap = (USBD_MAX_PACKET0 << 16) | + (1UL << 29) | + (1UL << 15); /* int on setup */ + USBHS->EPLISTADDR = (uint32_t)EPQHx; + USBHS->USBMODE |= (1UL << 3); /* Setup lockouts off */ + USBHS->EPCR0 = 0x00C000C0; + USBD_PrimeEp(0, Ep[EP_OUT_IDX(0)].maxPacket); +} + + +/* + * USB Device Suspend Function + * Called automatically on USB Device Suspend + * Return Value: None + */ + +void USBD_Suspend(void) +{ + /* Performed by Hardware */ +} + + +/* + * USB Device Resume Function + * Called automatically on USB Device Resume + * Return Value: None + */ + +void USBD_Resume(void) +{ + /* Performed by Hardware */ +} + + +/* + * USB Device Remote Wakeup Function + * Called automatically on USB Device Remote Wakeup + * Return Value: None + */ + +void USBD_WakeUp(void) +{ + USBHS->PORTSC1 |= (1UL << 6); +} + + +/* + * USB Device Remote Wakeup Configuration Function + * Parameters: cfg: Device Enable/Disable + * Return Value: None + */ + +void USBD_WakeUpCfg(uint32_t cfg) +{ + /* Not needed */ +} + + +/* + * USB Device Set Address Function + * Parameters: adr: USB Device Address + * Return Value: None + */ + +void USBD_SetAddress(uint32_t adr, uint32_t setup) +{ + if (setup == 0) { + USBHS->DEVICEADDR = (adr << 25); + USBHS->DEVICEADDR |= (1UL << 24); + } +} + + +/* + * USB Device Configure Function + * Parameters: cfg: Device Configure/Deconfigure + * Return Value: None + */ + +void USBD_Configure(uint32_t cfg) +{ + uint32_t i; + + if (!cfg) { + for (i = 2; i < (2 * (USBD_EP_NUM + 1)); i++) { + Ep[i].buf = 0; + Ep[i].maxPacket = 0; + } + + BufUsed = 2 * USBD_MAX_PACKET0; + } +} + + +/* + * Configure USB Device Endpoint according to Descriptor + * Parameters: pEPD: Pointer to Device Endpoint Descriptor + * Return Value: None + */ + +void USBD_ConfigEP(USB_ENDPOINT_DESCRIPTOR *pEPD) +{ + uint32_t num, val, type, idx; + + if ((pEPD->bEndpointAddress & USB_ENDPOINT_DIRECTION_MASK)) { + val = 16; + num = pEPD->bEndpointAddress & ~0x80; + idx = EP_IN_IDX(num); + + } else { + val = 0; + num = pEPD->bEndpointAddress; + idx = EP_OUT_IDX(num); + } + + type = pEPD->bmAttributes & USB_ENDPOINT_TYPE_MASK; + + if (!(Ep[idx].buf)) { + Ep[idx].buf = &(EPBufPool[BufUsed]); + Ep[idx].maxPacket = pEPD->wMaxPacketSize; + BufUsed += pEPD->wMaxPacketSize; + + /* Isochronous endpoint */ + if (type == USB_ENDPOINT_TYPE_ISOCHRONOUS) { + IsoEp |= (1UL << (num + val)); + } + } + + dTDx[idx].buf[0] = (uint32_t)(Ep[idx].buf); + dTDx[idx].next_dTD = 1; + EPQHx[idx].cap = (Ep[idx].maxPacket << 16) | + (1UL << 29); + ENDPTCTRL(num) &= ~(0xFFFF << val); + ENDPTCTRL(num) |= ((type << 2) << val) | + ((1UL << 6) << val); /* Data toogle reset */ +} + + +/* + * Set Direction for USB Device Control Endpoint + * Parameters: dir: Out (dir == 0), In (dir <> 0) + * Return Value: None + */ + +void USBD_DirCtrlEP(uint32_t dir) +{ + /* Not needed */ +} + + +/* + * Enable USB Device Endpoint + * Parameters: EPNum: Device Endpoint Number + * EPNum.0..3: Address + * EPNum.7: Dir + * Return Value: None + */ + +void USBD_EnableEP(uint32_t EPNum) +{ + if (EPNum & 0x80) { + EPNum &= 0x7F; + ENDPTCTRL(EPNum) |= (1UL << 23); /* EP enabled */ + } else { + ENDPTCTRL(EPNum) |= (1UL << 7); /* EP enabled */ + } +} + + +/* + * Disable USB Device Endpoint + * Parameters: EPNum: Device Endpoint Number + * EPNum.0..3: Address + * EPNum.7: Dir + * Return Value: None + */ + +void USBD_DisableEP(uint32_t EPNum) +{ + if (EPNum & 0x80) { + EPNum &= 0x7F; + ENDPTCTRL(EPNum) &= ~(1UL << 23); /* EP disabled */ + } else { + ENDPTCTRL(EPNum) &= ~(1UL << 7); /* EP disabled */ + } +} + + +/* + * Reset USB Device Endpoint + * Parameters: EPNum: Device Endpoint Number + * EPNum.0..3: Address + * EPNum.7: Dir + * Return Value: None + */ + +void USBD_ResetEP(uint32_t EPNum) +{ + if (EPNum & 0x80) { + EPNum &= 0x7F; + EPQHx[EP_IN_IDX(EPNum)].dTD_token &= 0xC0; + USBHS->EPFLUSH = (1UL << (EPNum + 16)); /* flush endpoint */ + + while (USBHS->EPFLUSH & (1UL << (EPNum + 16))); + + ENDPTCTRL(EPNum) |= (1UL << 22); /* data toggle reset */ + + } else { + EPQHx[EP_OUT_IDX(EPNum)].dTD_token &= 0xC0; + USBHS->EPFLUSH = (1UL << EPNum); /* flush endpoint */ + + while (USBHS->EPFLUSH & (1UL << EPNum)); + + ENDPTCTRL(EPNum) |= (1UL << 6); /* data toggle reset */ + USBD_PrimeEp(EPNum, Ep[EP_OUT_IDX(EPNum)].maxPacket); + } +} + + +/* + * Set Stall for USB Device Endpoint + * Parameters: EPNum: Device Endpoint Number + * EPNum.0..3: Address + * EPNum.7: Dir + * Return Value: None + */ + +void USBD_SetStallEP(uint32_t EPNum) +{ + if (EPNum & 0x80) { + EPNum &= 0x7F; + ENDPTCTRL(EPNum) |= (1UL << 16); /* IN endpoint stall */ + } else { + ENDPTCTRL(EPNum) |= (1UL << 0); /* OUT endpoint stall */ + } +} + + +/* + * Clear Stall for USB Device Endpoint + * Parameters: EPNum: Device Endpoint Number + * EPNum.0..3: Address + * EPNum.7: Dir + * Return Value: None + */ + +void USBD_ClrStallEP(uint32_t EPNum) +{ + if (EPNum & 0x80) { + EPNum &= 0x7F; + ENDPTCTRL(EPNum) &= ~(1UL << 16); /* clear stall */ + ENDPTCTRL(EPNum) |= (1UL << 22); /* data toggle reset */ + + while (ENDPTCTRL(EPNum) & (1UL << 16)); + + USBD_ResetEP(EPNum | 0x80); + + } else { + ENDPTCTRL(EPNum) &= ~(1UL << 0); /* clear stall */ + ENDPTCTRL(EPNum) |= (1UL << 6); /* data toggle reset */ + } +} + + +/* + * Clear USB Device Endpoint Buffer + * Parameters: EPNum: Device Endpoint Number + * EPNum.0..3: Address + * EPNum.7: Dir + * Return Value: None + */ + +void USBD_ClearEPBuf(uint32_t EPNum) +{ +} + + +/* + * USB Device Prime endpoint function + * Parameters: EPNum: Device Endpoint Number + * EPNum.0..3: Address + * EPNum.7: Dir + * cnt: Bytes to transfer/receive + * Return Value: None + */ + +void USBD_PrimeEp(uint32_t EPNum, uint32_t cnt) +{ + uint32_t idx, val; + + /* IN endpoint */ + if (EPNum & 0x80) { + EPNum &= 0x7F; + idx = EP_IN_IDX(EPNum); + val = (1UL << (EPNum + 16)); + } + + /* OUT endpoint */ + else { + val = (1UL << EPNum); + idx = EP_OUT_IDX(EPNum); + } + + dTDx[idx].buf[0] = (uint32_t)(Ep[idx].buf); + dTDx[idx].next_dTD = 1; + + if (IsoEp & val) { + if (Ep[idx].maxPacket <= cnt) { + dTDx[idx].dTD_token = (1 << 10); /* MultO = 1 */ + + } else if ((Ep[idx].maxPacket * 2) <= cnt) { + dTDx[idx].dTD_token = (2 << 10); /* MultO = 2 */ + + } else { + dTDx[idx].dTD_token = (3 << 10); /* MultO = 3 */ + } + + } else { + dTDx[idx].dTD_token = 0; + } + + dTDx[idx].dTD_token |= (cnt << 16) | /* bytes to transfer */ + (1UL << 15) | /* int on complete */ + 0x80; /* status - active */ + EPQHx[idx].next_dTD = (uint32_t)(&dTDx[idx]); + EPQHx[idx].dTD_token &= ~0xC0; + USBHS->EPPRIME = (val); + + while ((USBHS->EPPRIME & val)); +} + + +/* + * Read USB Device Endpoint Data + * Parameters: EPNum: Device Endpoint Number + * EPNum.0..3: Address + * EPNum.7: Dir + * pData: Pointer to Data Buffer + * Return Value: Number of bytes read + */ + +uint32_t USBD_ReadEP(uint32_t EPNum, uint8_t *pData, uint32_t size) +{ + uint32_t cnt = 0; + uint32_t i; + + /* Setup packet */ + if ((USBHS->EPSETUPSR & 1) && (!EPNum)) { + USBHS->EPSETUPSR = 1; + + while (USBHS->EPSETUPSR & 1); + + do { + *((__packed uint32_t *) pData) = EPQHx[EP_OUT_IDX(0)].setup[0]; + *((__packed uint32_t *)(pData + 4)) = EPQHx[EP_OUT_IDX(0)].setup[1]; + cnt = 8; + USBHS->USBCMD |= (1UL << 13); + } while (!(USBHS->USBCMD & (1UL << 13))); + + USBHS->USBCMD &= (~(1UL << 13)); + USBHS->EPFLUSH = (1UL << EPNum) | (1UL << (EPNum + 16)); + + while (USBHS->EPFLUSH & ((1UL << (EPNum + 16)) | (1UL << EPNum))); + + while (USBHS->EPSETUPSR & 1); + + USBD_PrimeEp(EPNum, Ep[EP_OUT_IDX(EPNum)].maxPacket); + } + + /* OUT Packet */ + else { + if (Ep[EP_OUT_IDX(EPNum)].buf) { + cnt = Ep[EP_OUT_IDX(EPNum)].maxPacket - + ((dTDx[EP_OUT_IDX(EPNum)].dTD_token >> 16) & 0x7FFF); + + for (i = 0; i < cnt; i++) { + pData[i] = Ep[EP_OUT_IDX(EPNum)].buf[i]; + } + } + + USBHS->EPCOMPLETE = (1UL << EPNum); + cmpl_pnd &= ~(1UL << EPNum); + USBD_PrimeEp(EPNum, Ep[EP_OUT_IDX(EPNum)].maxPacket); + } + + return (cnt); +} + + +/* + * Write USB Device Endpoint Data + * Parameters: EPNum: Endpoint Number + * EPNum.0..3: Address + * EPNum.7: Dir + * pData: Pointer to Data Buffer + * cnt: Number of bytes to write + * Return Value: Number of bytes written + */ + +uint32_t USBD_WriteEP(uint32_t EPNum, uint8_t *pData, uint32_t cnt) +{ + uint32_t i; + EPNum &= 0x7f; + + for (i = 0; i < cnt; i++) { + Ep[EP_IN_IDX(EPNum)].buf[i] = pData[i]; + } + + USBD_PrimeEp(EPNum | 0x80, cnt); + return (cnt); +} + + +/* + * Get USB Device Last Frame Number + * Parameters: None + * Return Value: Frame Number + */ + +uint32_t USBD_GetFrame(void) +{ + return ((USBHS->FRINDEX >> 3) & 0x0FFF); +} + + +#ifdef __RTX +uint32_t LastError; /* Last Error */ + +/* + * Get USB Device Last Error Code + * Parameters: None + * Return Value: Error Code + */ + +uint32_t USBD_GetError(void) +{ + return (LastError); +} +#endif + + +/* + * USB Device Interrupt Service Routine + */ +void USBHS_IRQHandler(void) +{ + NVIC_DisableIRQ(USBHS_IRQn); + USBD_SignalHandler(); +} + +/* + * USB Device Interrupt Service Routine + */ + +void USBD_Handler(void) +{ + uint32_t sts, cmpl, num; + sts = USBHS->USBSTS & USBHS->USBINTR; + cmpl = USBHS->EPCOMPLETE; + USBHS->USBSTS = sts; /* clear interupt flags */ + + /* reset interrupt */ + if (sts & (1UL << 6)) { + USBD_Reset(); + usbd_reset_core(); +#ifdef __RTX + + if (USBD_RTX_DevTask) { + isr_evt_set(USBD_EVT_RESET, USBD_RTX_DevTask); + } + +#else + + if (USBD_P_Reset_Event) { + USBD_P_Reset_Event(); + } + +#endif + } + + /* suspend interrupt */ + if (sts & (1UL << 8)) { + USBD_Suspend(); +#ifdef __RTX + + if (USBD_RTX_DevTask) { + isr_evt_set(USBD_EVT_SUSPEND, USBD_RTX_DevTask); + } + +#else + + if (USBD_P_Suspend_Event) { + USBD_P_Suspend_Event(); + } + +#endif + } + + /* SOF interrupt */ + if (sts & (1UL << 7)) { + if (IsoEp) { + for (num = 0; num < USBD_EP_NUM + 1; num++) { + if (IsoEp & (1UL << num)) { + USBD_PrimeEp(num, Ep[EP_OUT_IDX(num)].maxPacket); + } + } + + } else { +#ifdef __RTX + + if (USBD_RTX_DevTask) { + isr_evt_set(USBD_EVT_SOF, USBD_RTX_DevTask); + } + +#else + + if (USBD_P_SOF_Event) { + USBD_P_SOF_Event(); + } + +#endif + } + } + + /* port change detect interrupt */ + if (sts & (1UL << 2)) { + if (((USBHS->PORTSC1 >> 26) & 0x03) == 2) { + USBD_HighSpeed = __TRUE; + } + + USBD_Resume(); +#ifdef __RTX + + if (USBD_RTX_DevTask) { + isr_evt_set(USBD_EVT_RESUME, USBD_RTX_DevTask); + } + +#else + + if (USBD_P_Resume_Event) { + USBD_P_Resume_Event(); + } + +#endif + } + + /* USB interrupt - completed transfer */ + if (sts & 1) { + /* Setup Packet */ + if (USBHS->EPSETUPSR) { +#ifdef __RTX + + if (USBD_RTX_EPTask[0]) { + isr_evt_set(USBD_EVT_SETUP, USBD_RTX_EPTask[0]); + } + +#else + + if (USBD_P_EP[0]) { + USBD_P_EP[0](USBD_EVT_SETUP); + } + +#endif + } + + /* IN Packet */ + if (cmpl & (0x3F << 16)) { + for (num = 0; num < USBD_EP_NUM + 1; num++) { + if (((cmpl >> 16) & 0x3F) & (1UL << num)) { + USBHS->EPCOMPLETE = (1UL << (num + 16)); /* Clear completed */ +#ifdef __RTX + + if (USBD_RTX_EPTask[num]) { + isr_evt_set(USBD_EVT_IN, USBD_RTX_EPTask[num]); + } + +#else + + if (USBD_P_EP[num]) { + USBD_P_EP[num](USBD_EVT_IN); + } + +#endif + } + } + } + + /* OUT Packet */ + if (cmpl & 0x3F) { + for (num = 0; num < USBD_EP_NUM + 1; num++) { + if ((cmpl ^ cmpl_pnd) & cmpl & (1UL << num)) { + cmpl_pnd |= 1UL << num; +#ifdef __RTX + + if (USBD_RTX_EPTask[num]) { + isr_evt_set(USBD_EVT_OUT, USBD_RTX_EPTask[num]); + + } else if (IsoEp & (1UL << num)) { + if (USBD_RTX_DevTask) { + isr_evt_set(USBD_EVT_SOF, USBD_RTX_DevTask); + } + } + +#else + + if (USBD_P_EP[num]) { + USBD_P_EP[num](USBD_EVT_OUT); + + } else if (IsoEp & (1UL << num)) { + if (USBD_P_SOF_Event) { + USBD_P_SOF_Event(); + } + } + +#endif + } + } + } + } + + /* error interrupt */ + if (sts & (1UL << 1)) { + for (num = 0; num < USBD_EP_NUM + 1; num++) { + if (cmpl & (1UL << num)) { +#ifdef __RTX + + if (USBD_RTX_DevTask) { + LastError = dTDx[EP_OUT_IDX(num)].dTD_token & 0xE8; + isr_evt_set(USBD_EVT_ERROR, USBD_RTX_DevTask); + } + +#else + + if (USBD_P_Error_Event) { + USBD_P_Error_Event(dTDx[EP_OUT_IDX(num)].dTD_token & 0xE8); + } + +#endif + } + + if (cmpl & (1UL << (num + 16))) { +#ifdef __RTX + + if (USBD_RTX_DevTask) { + LastError = dTDx[EP_IN_IDX(num)].dTD_token & 0xE8; + isr_evt_set(USBD_EVT_ERROR, USBD_RTX_DevTask); + } + +#else + + if (USBD_P_Error_Event) { + USBD_P_Error_Event(dTDx[EP_IN_IDX(num)].dTD_token & 0xE8); + } + +#endif + } + } + } + + NVIC_EnableIRQ(USBHS_IRQn); +}