void USBD_ResetEP (uint32_t EPNum) { if (EPNum & 0x80) { EPNum &= 0x7F; EPQHx[EP_IN_IDX(EPNum)].dTD_token &= 0xC0; LPC_USB0->ENDPTFLUSH = (1UL << (EPNum + 16)); /* flush endpoint */ while (LPC_USB0->ENDPTFLUSH & (1UL << (EPNum + 16))); ENDPTCTRL(EPNum) |= (1UL << 22); /* data toggle reset */ } else { EPQHx[EP_OUT_IDX(EPNum)].dTD_token &= 0xC0; LPC_USB0->ENDPTFLUSH = (1UL << EPNum); /* flush endpoint */ while (LPC_USB0->ENDPTFLUSH & (1UL << EPNum)); ENDPTCTRL(EPNum) |= (1UL << 6 ); /* data toggle reset */ } }
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 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); }