static inline void lpc_usb_open_ep(CORE* core, int num, USB_EP_TYPE type, unsigned int size) { unsigned int i; if (ep_data(core, num) != NULL) { error(ERROR_ALREADY_CONFIGURED); return; } EP* ep = malloc(sizeof(EP)); if (ep == NULL) return; ep->io = NULL; ep->fifo = (void*)USB_FREE_BUF_BASE; ep->io_active = false; ep->mps = size; //find free addr in FIFO for (i = 0; i < USB_EP_COUNT_MAX; ++i) { if (core->usb.in[i]) ep->fifo += ((core->usb.in[i]->mps + 63) & ~63); if (core->usb.out[i]) ep->fifo += ((core->usb.out[i]->mps + 63) & ~63); } num & USB_EP_IN ? (core->usb.in[USB_EP_NUM(num)] = ep) : (core->usb.out[USB_EP_NUM(num)] = ep); if (type == USB_EP_ISOCHRON) *USB_EP_LISTSTS(num, 0) |= USB_EP_LISTST_T; if (USB_EP_NUM(num)) *USB_EP_LISTSTS(num, 0) &= ~USB_EP_LISTST_D; LPC_USB->INTEN |= USB_EP_INT_BIT(num); }
static inline void lpc_usb_close_ep(CORE* core, int num) { if (!lpc_usb_ep_flush(core, num)) return; *USB_EP_LISTSTS(num, 0) |= USB_EP_LISTST_D; LPC_USB->INTEN &= ~USB_EP_INT_BIT(num); EP* ep = ep_data(core, num); free(ep); num & USB_EP_IN ? (core->usb.in[USB_EP_NUM(num)] = NULL) : (core->usb.out[USB_EP_NUM(num)] = NULL); }
static inline void stm32_otg_close_ep(EXO* exo, int num) { if (!stm32_otg_ep_flush(exo, num)) return; ep_reg_data(num)->CTL &= ~OTG_FS_DEVICE_ENDPOINT_CTL_USBAEP; EP* ep = ep_data(exo, num); ep->mps = 0; if (num & USB_EP_IN) { OTG_FS_DEVICE->AINTMSK &= ~(1 << USB_EP_NUM(num)); OTG_FS_DEVICE->EIPEMPMSK &= ~(1 << USB_EP_NUM(num)); } kfree(ep); num & USB_EP_IN ? (exo->usb.in[USB_EP_NUM(num)] = NULL) : (exo->usb.out[USB_EP_NUM(num)] = NULL); }
static bool lpc_usb_io_prepare(CORE* core, IPC* ipc) { EP* ep = ep_data(core, ipc->param1); if (ep == NULL) { error(ERROR_NOT_CONFIGURED); return false; } if (ep->io_active) { error(ERROR_IN_PROGRESS); return false; } ep->io = (IO*)ipc->param2; error(ERROR_SYNC); return true; }
bool stm32_otg_ep_flush(EXO* exo, int num) { EP* ep = ep_data(exo, num); if (ep == NULL) { kerror(ERROR_NOT_CONFIGURED); return false; } if (ep->io != NULL) { kexo_io_ex(exo->usb.device, HAL_IO_CMD(HAL_USB, (num & USB_EP_IN) ? IPC_WRITE : IPC_READ), num, ep->io, ERROR_IO_CANCELLED); ep->io = NULL; ep_reg_data(num)->CTL |= OTG_FS_DEVICE_ENDPOINT_CTL_SNAK; } ep->io_active = false; return true; }
bool lpc_usb_ep_flush(CORE* core, int num) { EP* ep = ep_data(core, num); if (ep == NULL) { error(ERROR_NOT_CONFIGURED); return false; } ep->io_active = false; lpc_usb_ep_reset(core, num); if (ep->io != NULL) { io_complete_ex(core->usb.device, HAL_IO_CMD(HAL_USB, (num & USB_EP_IN) ? IPC_WRITE : IPC_READ), num, ep->io, ERROR_IO_CANCELLED); ep->io = NULL; } return true; }
static bool stm32_usb_io_prepare(EXO* exo, IPC* ipc) { EP* ep = ep_data(exo, ipc->param1); if (ep == NULL) { printk("ep==null"); kerror(ERROR_NOT_CONFIGURED); return false; } if (ep->io_active) { printk("ep->io_active"); kerror(ERROR_IN_PROGRESS); return false; } ep->io = (IO*)ipc->param2; kerror(ERROR_SYNC); return true; }
static inline void stm32_otg_open_ep(EXO* exo, int num, USB_EP_TYPE type, unsigned int size) { if (ep_data(exo, num) != NULL) { kerror(ERROR_ALREADY_CONFIGURED); return; } EP* ep = kmalloc(sizeof(EP)); if (ep == NULL) return; num & USB_EP_IN ? (exo->usb.in[USB_EP_NUM(num)] = ep) : (exo->usb.out[USB_EP_NUM(num)] = ep); ep->io = NULL; ep->mps = 0; ep->io_active = false; int fifo_used, i; //enable, NAK uint32_t ctl = OTG_FS_DEVICE_ENDPOINT_CTL_USBAEP | OTG_FS_DEVICE_ENDPOINT_CTL_SNAK; //setup ep type, DATA0 for bulk/interrupt, EVEN frame for isochronous endpoint switch (type) { case USB_EP_CONTROL: ctl |= OTG_FS_DEVICE_ENDPOINT_CTL_EPTYP_CONTROL; break; case USB_EP_BULK: ctl |= OTG_FS_DEVICE_ENDPOINT_CTL_EPTYP_BULK | OTG_FS_DEVICE_ENDPOINT_CTL_DPID; break; case USB_EP_INTERRUPT: ctl |= OTG_FS_DEVICE_ENDPOINT_CTL_EPTYP_INTERRUPT | OTG_FS_DEVICE_ENDPOINT_CTL_DPID; break; case USB_EP_ISOCHRON: ctl |= OTG_FS_DEVICE_ENDPOINT_CTL_EPTYP_ISOCHRONOUS | OTG_FS_DEVICE_ENDPOINT_CTL_SEVNFRM; break; } if (num & USB_EP_IN) { //setup TX FIFO num for IN endpoint fifo_used = OTG_FS_GENERAL->RXFSIZ & 0xffff; for (i = 0; i < USB_EP_NUM(num); ++i) fifo_used += exo->usb.in[i]->mps / 4; if (USB_EP_NUM(num)) OTG_FS_GENERAL->DIEPTXF[USB_EP_NUM(num) - 1] = ((size / 4) << OTG_FS_GENERAL_TX0FSIZ_TX0FD_POS) | ((fifo_used * 4) | OTG_FS_GENERAL_TX0FSIZ_TX0FSA_POS); else OTG_FS_GENERAL->TX0FSIZ = ((size / 4) << OTG_FS_GENERAL_TX0FSIZ_TX0FD_POS) | ((fifo_used * 4) | OTG_FS_GENERAL_TX0FSIZ_TX0FSA_POS); ctl |= USB_EP_NUM(num) << OTG_FS_DEVICE_ENDPOINT_CTL_TXFNUM_POS; //enable interrupts for XFRCM OTG_FS_DEVICE->AINTMSK |= 1 << USB_EP_NUM(num); } //EP_OUT0 has differrent mps structure if (USB_EP_NUM(num) == 0) { switch (size) { case 8: ctl |= OTG_FS_DEVICE_ENDPOINT_CTL_MPSIZ0_8; break; case 16: ctl |= OTG_FS_DEVICE_ENDPOINT_CTL_MPSIZ0_16; break; case 32: ctl |= OTG_FS_DEVICE_ENDPOINT_CTL_MPSIZ0_32; break; default: ctl |= OTG_FS_DEVICE_ENDPOINT_CTL_MPSIZ0_64; } } else ctl |= size; ep->mps = size; ep_reg_data(num)->CTL = ctl; }