static inline void lpc_usb_wakeup(CORE* core) { IPC ipc; ipc.process = core->usb.device; ipc.cmd = HAL_CMD(HAL_USB, USB_WAKEUP); ipc.param1 = USB_HANDLE_DEVICE; ipc_ipost(&ipc); }
static inline void lpc_usb_suspend(CORE* core) { IPC ipc; ipc.process = core->usb.device; ipc.cmd = HAL_CMD(HAL_USB, USB_SUSPEND); ipc.param1 = USB_HANDLE_DEVICE; ipc_ipost(&ipc); }
static inline void usb_wakeup(EXO* exo) { IPC ipc; OTG_FS_GENERAL->INTMSK |= OTG_FS_GENERAL_INTMSK_USBSUSPM; ipc.process = exo->usb.device; ipc.param1 = USB_HANDLE_DEVICE; ipc.cmd = HAL_CMD(HAL_USB, USB_WAKEUP); ipc_ipost(&ipc); }
static inline void usb_suspend(EXO* exo) { IPC ipc; OTG_FS_GENERAL->INTMSK &= ~OTG_FS_GENERAL_INTMSK_USBSUSPM; ipc.process = exo->usb.device; ipc.param1 = USB_HANDLE_DEVICE; ipc.cmd = HAL_CMD(HAL_USB, USB_SUSPEND); ipc_ipost(&ipc); }
static inline void lpc_usb_setup(CORE* core) { IPC ipc; ipc.process = core->usb.device; ipc.cmd = HAL_CMD(HAL_USB, USB_SETUP); ipc.param1 = 0; ipc.param2 = *((uint32_t*)(USB_SETUP_BUF_BASE)); ipc.param3 = *((uint32_t*)(USB_SETUP_BUF_BASE + 4)); ipc_ipost(&ipc); }
void ipc_ipost_inline(HANDLE process, unsigned int cmd, unsigned int param1, unsigned int param2, unsigned int param3) { IPC ipc; ipc.process = process; ipc.cmd = cmd; ipc.param1 = param1; ipc.param2 = param2; ipc.param3 = param3; ipc_ipost(&ipc); }
static inline void usb_enumdne(EXO* exo) { OTG_FS_GENERAL->INTMSK |= OTG_FS_GENERAL_INTMSK_USBSUSPM; IPC ipc; ipc.process = exo->usb.device; ipc.param1 = USB_HANDLE_DEVICE; ipc.param2 = stm32_otg_get_speed(exo); ipc.cmd = HAL_CMD(HAL_USB, USB_RESET); ipc_ipost(&ipc); }
static inline void lpc_usb_reset(CORE* core) { //enable device LPC_USB->DEVCMDSTAT |= USB_DEVCMDSTAT_DEV_EN; IPC ipc; ipc.process = core->usb.device; ipc.cmd = HAL_CMD(HAL_USB, USB_RESET); ipc.param1 = USB_HANDLE_DEVICE; ipc.param2 = lpc_usb_get_speed(core); ipc_ipost(&ipc); }
//------------------------------------------------------------------------ static inline void stm32_otg_on_isr_rx(EXO* exo) { IPC ipc; unsigned int sta = OTG_FS_GENERAL->RXSTSP; unsigned int pktsts = sta & OTG_FS_GENERAL_RXSTSR_PKTSTS; int bcnt = (sta & OTG_FS_GENERAL_RXSTSR_BCNT) >> OTG_FS_GENERAL_RXSTSR_BCNT_POS; unsigned int ep_num = (sta & OTG_FS_GENERAL_RXSTSR_EPNUM) >> OTG_FS_GENERAL_RXSTSR_EPNUM_POS; EP* ep = exo->usb.out[ep_num]; if (pktsts == OTG_FS_GENERAL_RXSTSR_PKTSTS_SETUP_RX) { //ignore all data on setup packet exo->usb.setup_lo = ((uint32_t*)(OTG_FS_FIFO_BASE + ep_num * 0x1000))[0]; exo->usb.setup_hi = ((uint32_t*)(OTG_FS_FIFO_BASE + ep_num * 0x1000))[1]; } else if ((pktsts == OTG_FS_GENERAL_RXSTSR_PKTSTS_SETUP_DONE)) { ipc.process = exo->usb.device; ipc.cmd = HAL_CMD(HAL_USB, USB_SETUP); ipc.param1 = USB_HANDLE(USB_0, 0); ipc.param2 = exo->usb.setup_lo; ipc.param3 = exo->usb.setup_hi; ipc_ipost(&ipc); } else if ((pktsts == OTG_FS_GENERAL_RXSTSR_PKTSTS_OUT_RX) && bcnt) { memcpy4(io_data(ep->io) + ep->io->data_size, (void*)(OTG_FS_FIFO_BASE + ep_num * 0x1000), bcnt); ep->io->data_size += bcnt; if (ep->io->data_size >= ep->size || bcnt < ep->mps ) { iio_complete(exo->usb.device, HAL_IO_CMD(HAL_USB, IPC_READ), ep_num, ep->io); ep->io_active = false; ep->io = NULL; } else stm32_otg_rx_prepare(exo, ep_num); } OTG_FS_GENERAL->INTMSK |= OTG_FS_GENERAL_INTMSK_RXFLVLM; }
void lpc_usb_on_isr(int vector, void* param) { int i; CORE* core = (SHARED_USB_DRV*)param; uint32_t sta = LPC_USB->INTSTAT; EP* ep; #if (USB_DEBUG_ERRORS) IPC ipc; switch (LPC_USB->INFO & USB_INFO_ERR_CODE_MASK) { case USB_INFO_ERR_CODE_NO_ERROR: case USB_INFO_ERR_CODE_IONAK: //no error break; default: ipc.process = process_iget_current(); ipc.cmd = HAL_CMD(HAL_USB, LPC_USB_ERROR); ipc.param1 = USB_HANDLE_DEVICE; ipc.param2 = (LPC_USB->INFO & USB_INFO_ERR_CODE_MASK) >> USB_INFO_ERR_CODE_POS; ipc_ipost(&ipc); LPC_USB->INFO &= ~USB_INFO_ERR_CODE_MASK; } #endif if (sta & USB_INTSTAT_DEV_INT) { sta = LPC_USB->DEVCMDSTAT; //Don't care on connection change, just clear pending bit if (sta & USB_DEVCMDSTAT_DCON_C) LPC_USB->DEVCMDSTAT |= USB_DEVCMDSTAT_DCON_C; if (sta & USB_DEVCMDSTAT_DSUS_C) { if (sta & USB_DEVCMDSTAT_DSUS) lpc_usb_suspend(core); else lpc_usb_wakeup(core); LPC_USB->DEVCMDSTAT |= USB_DEVCMDSTAT_DSUS_C; } if (sta & USB_DEVCMDSTAT_DRES_C) { lpc_usb_reset(core); LPC_USB->DEVCMDSTAT |= USB_DEVCMDSTAT_DRES_C; } LPC_USB->INTSTAT = USB_INTSTAT_DEV_INT; return; } if ((sta & USB_INTSTAT_EP0OUT) && (LPC_USB->DEVCMDSTAT & USB_DEVCMDSTAT_SETUP)) { lpc_usb_setup(core); LPC_USB->DEVCMDSTAT |= USB_DEVCMDSTAT_SETUP; LPC_USB->INTSTAT = USB_INTSTAT_EP0OUT; return; } for (i = 0; i < USB_EP_COUNT_MAX; ++i) { if (sta & USB_EP_INT_BIT(i)) { ep = core->usb.out[i]; if (ep && ep->io_active) lpc_usb_out(core, i); LPC_USB->INTSTAT = USB_EP_INT_BIT(i); } if (sta & USB_EP_INT_BIT(USB_EP_IN | i)) { ep = core->usb.in[i]; if (ep && ep->io_active) lpc_usb_in(core, i | USB_EP_IN); LPC_USB->INTSTAT = USB_EP_INT_BIT(USB_EP_IN | i); } } }