void lpc_sdmmc_on_isr(int vector, void* param) { CORE* core = (CORE*)param; if (LPC_SDMMC->IDSTS & SDMMC_IDSTS_NIS_Msk) { switch (core->sdmmc.state) { case SDMMC_STATE_READ: case SDMMC_STATE_WRITE: if (core->sdmmc.state == SDMMC_STATE_READ) core->sdmmc.io->data_size = core->sdmmc.total; iio_complete(core->sdmmc.process, HAL_IO_CMD(HAL_SDMMC, core->sdmmc.state == SDMMC_STATE_READ ? IPC_READ : IPC_WRITE), core->sdmmc.user, core->sdmmc.io); core->sdmmc.io = NULL; core->sdmmc.process = INVALID_HANDLE; core->sdmmc.state = SDMMC_STATE_IDLE; break; case SDMMC_STATE_VERIFY: case SDMMC_STATE_WRITE_VERIFY: //write is taking some also as hash, so it's better to switch to userspace for completion ipc_ipost_inline(process_iget_current(), HAL_CMD(HAL_SDMMC, LPC_SDMMC_VERIFY), 0, 0, 0); break; default: break; } LPC_SDMMC->IDSTS = SDMMC_IDSTS_RI_Msk | SDMMC_IDSTS_TI_Msk | SDMMC_IDSTS_NIS_Msk; } if (LPC_SDMMC->IDSTS & SDMMC_IDSTS_AIS_Msk) { if (LPC_SDMMC->IDSTS & SDMMC_IDSTS_FBE_Msk) { lpc_sdmmc_error(core, ERROR_HARDWARE); LPC_SDMMC->IDSTS = SDMMC_IDSTS_FBE_Msk; } if (LPC_SDMMC->IDSTS & SDMMC_IDSTS_CES_Msk) { if (LPC_SDMMC->RINTSTS & SDMMC_RINTSTS_DRTO_BDS_Msk) { lpc_sdmmc_error(core, ERROR_TIMEOUT); LPC_SDMMC->RINTSTS = SDMMC_RINTSTS_DRTO_BDS_Msk; } if (LPC_SDMMC->RINTSTS & SDMMC_RINTSTS_DCRC_Msk) { lpc_sdmmc_error(core, ERROR_CRC); LPC_SDMMC->RINTSTS = SDMMC_RINTSTS_DCRC_Msk; } if (LPC_SDMMC->RINTSTS & (SDMMC_RINTSTS_SBE_Msk | SDMMC_RINTSTS_EBE_Msk)) { lpc_sdmmc_error(core, ERROR_HARDWARE); LPC_SDMMC->RINTSTS = SDMMC_RINTSTS_SBE_Msk | SDMMC_RINTSTS_EBE_Msk; } LPC_SDMMC->IDSTS = SDMMC_IDSTS_CES_Msk; } LPC_SDMMC->IDSTS = SDMMC_IDSTS_AIS_Msk; } }
static inline void lpc_usb_out(CORE* core, int num) { EP* ep = core->usb.out[USB_EP_NUM(num)]; unsigned int cnt = ep->mps - (((*USB_EP_LISTSTS(num, 0)) & USB_EP_LISTST_NBYTES_MASK) >> USB_EP_LISTST_NBYTES_POS); io_data_append(ep->io, ep->fifo, cnt); if (ep->io->data_size >= ep->size || cnt < ep->mps) { ep->io_active = false; iio_complete(core->usb.device, HAL_IO_CMD(HAL_USB, IPC_READ), num, ep->io); ep->io = NULL; } else lpc_usb_rx_prepare(core, num); }
void usb_on_isr(int vector, void* param) { int i; EXO* exo = param; unsigned int sta = OTG_FS_GENERAL->INTSTS; //first two most often called if ((OTG_FS_GENERAL->INTMSK & OTG_FS_GENERAL_INTMSK_RXFLVLM) && (sta & OTG_FS_GENERAL_INTSTS_RXFLVL)) { //mask interrupts, will be umasked by process after FIFO read OTG_FS_GENERAL->INTMSK &= ~OTG_FS_GENERAL_INTMSK_RXFLVLM; stm32_otg_on_isr_rx(exo); return; } for (i = 0; i < USB_EP_COUNT_MAX; ++i) if (exo->usb.in[i] != NULL && exo->usb.in[i]->io_active && (OTG_FS_DEVICE->INEP[i].INT & OTG_FS_DEVICE_ENDPOINT_INT_XFRC)) { OTG_FS_DEVICE->INEP[i].INT = OTG_FS_DEVICE_ENDPOINT_INT_XFRC; if (exo->usb.in[i]->size >= exo->usb.in[i]->io->data_size) { exo->usb.in[i]->io_active = false; iio_complete(exo->usb.device, HAL_IO_CMD(HAL_USB, IPC_WRITE), USB_EP_IN | i, exo->usb.in[i]->io); exo->usb.in[i]->io = NULL; } else stm32_otg_tx(exo, USB_EP_IN | i); return; } //rarely called if (sta & OTG_FS_GENERAL_INTSTS_ENUMDNE) { usb_enumdne(exo); OTG_FS_GENERAL->INTSTS |= OTG_FS_GENERAL_INTSTS_ENUMDNE; return; } if ((sta & OTG_FS_GENERAL_INTSTS_USBSUSP) && (OTG_FS_GENERAL->INTMSK & OTG_FS_GENERAL_INTMSK_USBSUSPM)) { usb_suspend(exo); OTG_FS_GENERAL->INTSTS |= OTG_FS_GENERAL_INTSTS_USBSUSP; return; } if (sta & OTG_FS_GENERAL_INTSTS_WKUPINT) { usb_wakeup(exo); OTG_FS_GENERAL->INTSTS |= OTG_FS_GENERAL_INTSTS_WKUPINT | OTG_FS_GENERAL_INTSTS_USBSUSP; } OTG_FS_GENERAL->OTGINT = 0xFFFFFF;// clear other request }
static inline void lpc_usb_in(CORE* core, int num) { EP* ep = core->usb.in[USB_EP_NUM(num)]; //handle STATUS in for set address if (core->usb.addr && ep->size == 0) { LPC_USB->DEVCMDSTAT |= core->usb.addr; core->usb.addr = 0; } if (ep->size >= ep->io->data_size) { ep->io_active = false; iio_complete(core->usb.device, HAL_IO_CMD(HAL_USB, IPC_WRITE), USB_EP_IN | num, ep->io); ep->io = NULL; } else lpc_usb_tx(core, num); }
//------------------------------------------------------------------------ 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_eth_isr(int vector, void* param) { #if (ETH_DOUBLE_BUFFERING) int i; #endif //ETH_DOUBLE_BUFFERING uint32_t sta; EXO* exo = (EXO*)param; sta = LPC_ETHERNET->DMA_STAT; if (sta & ETHERNET_DMA_STAT_RI_Msk) { #if (ETH_DOUBLE_BUFFERING) for (i = 0; i < 2; ++i) { if ((exo->eth.rx[exo->eth.cur_rx] != NULL) && ((exo->eth.rx_des[exo->eth.cur_rx].ctl & ETH_RDES0_OWN) == 0)) { exo->eth.rx[exo->eth.cur_rx]->data_size = (exo->eth.rx_des[exo->eth.cur_rx].ctl & ETH_RDES0_FL_MASK) >> ETH_RDES0_FL_POS; iio_complete(exo->eth.tcpip, HAL_IO_CMD(HAL_ETH, IPC_READ), exo->eth.phy_addr, exo->eth.rx[exo->eth.cur_rx]); exo->eth.rx[exo->eth.cur_rx] = NULL; exo->eth.cur_rx = (exo->eth.cur_rx + 1) & 1; } else break; }