uint32_t USBD_ReadEP (uint32_t EPNum, uint8_t *pData) { uint32_t cnt = 0; uint32_t i; /* Setup packet */ if ((LPC_USB0->ENDPTSETUPSTAT & 1) && (!EPNum)) { LPC_USB0->ENDPTSETUPSTAT = 1; while (LPC_USB0->ENDPTSETUPSTAT & 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; LPC_USB0->USBCMD_D |= (1UL << 13); } while (!(LPC_USB0->USBCMD_D & (1UL << 13))); LPC_USB0->USBCMD_D &= (~(1UL << 13)); LPC_USB0->ENDPTFLUSH = (1UL << EPNum) | (1UL << (EPNum + 16)); while (LPC_USB0->ENDPTFLUSH & ((1UL << (EPNum + 16)) | (1UL << EPNum))); while (LPC_USB0->ENDPTSETUPSTAT & 1); } /* 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]; } } LPC_USB0->ENDPTCOMPLETE = (1UL << EPNum); }
void USBD_ResetEP (uint32_t EPNum) { if (EPNum & 0x80) { EPNum &= 0x7F; EPQHx[EP_IN_IDX(EPNum)].dTD_token &= 0xC0; LPC_USBx->ENDPTFLUSH = (1UL << (EPNum + 16)); /* flush endpoint */ while (LPC_USBx->ENDPTFLUSH & (1UL << (EPNum + 16))); ENDPTCTRL(EPNum) |= (1UL << 22); /* data toggle reset */ } else { EPQHx[EP_OUT_IDX(EPNum)].dTD_token &= 0xC0; LPC_USBx->ENDPTFLUSH = (1UL << EPNum); /* flush endpoint */ while (LPC_USBx->ENDPTFLUSH & (1UL << EPNum)); ENDPTCTRL(EPNum) |= (1UL << 6 ); /* data toggle reset */ USBD_PrimeEp(EPNum, Ep[EP_OUT_IDX(EPNum)].maxPacket); } }
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; LPC_USBx->ENDPTPRIME = (val); while ((LPC_USBx->ENDPTPRIME & val)); }
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 */ }
void __SVC_1(int ena) { #else void USBD_Intr(int ena) { #endif if (ena) { NVIC_EnableIRQ(USB0_IRQn); /* Enable USB interrupt */ } else { NVIC_DisableIRQ(USB0_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); /* BASE_USB0_CLK */ LPC_CGU->BASE_USB0_CLK = (0x01 << 11) | /* Autoblock En */ (0x07 << 24) ; /* Clock source: PLL0 */ LPC_CCU1->CLK_M4_USB0_CFG |= 1; while (!(LPC_CCU1->CLK_M4_USB0_STAT & 1)); LPC_SCU->SFSP6_3 = 1; /* pwr en */ LPC_SCU->SFSP6_6 = 3; /* pwr fault */ LPC_SCU->SFSP8_1 = 1; /* port indicator LED control out 1 */ LPC_SCU->SFSP8_2 = 1; /* port indicator LED control out 0 */ LPC_USBx->USBCMD_D |= (1UL << 1); /* usb reset */ while (LPC_USBx->USBCMD_D & (1UL << 1)); LPC_CREG->CREG0 &= ~(1 << 5); LPC_USBx->USBMODE_D = 2 | (1UL << 3);/* device mode */ #if USBD_HS_ENABLE LPC_USBx->PORTSC1_D &= ~(1UL << 24); #else LPC_USBx->PORTSC1_D |= (1UL << 24); #endif LPC_USBx->OTGSC = 1 | (1UL << 3); Ep[EP_OUT_IDX(0)].maxPacket = USBD_MAX_PACKET0; LPC_USBx->USBINTR_D = (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); }
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 */ LPC_USBx->ENDPTNAK = 0xFFFFFFFF; LPC_USBx->ENDPTNAKEN = 0; LPC_USBx->USBSTS_D = 0xFFFFFFFF; LPC_USBx->ENDPTSETUPSTAT = LPC_USBx->ENDPTSETUPSTAT; LPC_USBx->ENDPTCOMPLETE = LPC_USBx->ENDPTCOMPLETE; while (LPC_USBx->ENDPTPRIME); LPC_USBx->ENDPTFLUSH = 0xFFFFFFFF; while (LPC_USBx->ENDPTFLUSH); LPC_USBx->USBCMD_D &= ~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 */ LPC_USBx->ENDPOINTLISTADDR = (uint32_t)EPQHx; LPC_USBx->USBMODE_D |= (1UL << 3); /* Setup lockouts off */ LPC_USBx->ENDPTCTRL0 = 0x00C000C0; USBD_PrimeEp(0, Ep[EP_OUT_IDX(0)].maxPacket); }
void __SVC_1 (int ena) { #else void USBD_Intr (int ena) { #endif if (ena) { NVIC_EnableIRQ (USB1_IRQn); /* Enable USB interrupt */ } else { NVIC_DisableIRQ (USB1_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); /* BASE_USB1_CLK */ LPC_CGU->BASE_USB1_CLK = (0x01 << 11) | /* Autoblock En */ (0x0C << 24) ; /* Clock source: IDIVA */ LPC_CCU1->CLK_M3_USB1_CFG |= 1; while (!(LPC_CCU1->CLK_M3_USB1_STAT & 1)); LPC_CCU1->CLK_USB1_CFG |= 1; while (!(LPC_CCU1->CLK_USB1_STAT & 1)); LPC_SCU->SFSP9_4 = 2; /* USB1_IND0 function */ LPC_SCU->SFSP9_3 = 2; /* USB1_IND1 function */ LPC_SCU->SFSP2_5 = (2UL << 0 ) | /* USB1_VBUS function */ (1UL << 3 ) | /* enable pull down, repeater mode */ (1UL << 6 ); /* input buffer enable */ LPC_USBx->USBCMD_D = (1UL << 1 ); /* usb reset */ while (LPC_USBx->USBCMD_D & 3); LPC_USBx->USBMODE_D = (2UL << 0 ) | /* device mode */ (1UL << 3 ); /* Setup lockout off */ LPC_USBx->PORTSC1_D |= (1UL << 24) | /* force full speed */ (3UL << 30); /* 1.1 PHy (Full speed only) */ Ep[EP_OUT_IDX(0)].maxPacket = USBD_MAX_PACKET0; LPC_USBx->USBINTR_D = (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(); LPC_SCU->SFSUSB = (1UL << 1 ) | /* enable USB1 */ (1UL << 4 ); USBD_Intr(1); }