/** * @brief Default data received callback. * @details The application must use this function as callback for the OUT * data endpoint. * * @param[in] usbp pointer to the @p USBDriver object * @param[in] ep endpoint number */ void sduDataReceived(USBDriver *usbp, usbep_t ep) { size_t n, maxsize; SerialUSBDriver *sdup = usbp->out_params[ep - 1U]; if (sdup == NULL) { return; } osalSysLockFromISR(); chnAddFlagsI(sdup, CHN_INPUT_AVAILABLE); /* Writes to the input queue can only happen when there is enough space to hold at least one packet.*/ maxsize = usbp->epc[ep]->out_maxsize; if ((n = iqGetEmptyI(&sdup->iqueue)) >= maxsize) { /* The endpoint cannot be busy, we are in the context of the callback, so a packet is in the buffer for sure.*/ osalSysUnlockFromISR(); n = (n / maxsize) * maxsize; usbPrepareQueuedReceive(usbp, ep, &sdup->iqueue, n); osalSysLockFromISR(); (void) usbStartReceiveI(usbp, ep); } osalSysUnlockFromISR(); }
/** * @brief Default data transmitted callback. * @details The application must use this function as callback for the IN * data endpoint. * * @param[in] usbp pointer to the @p USBDriver object * @param[in] ep endpoint number */ void hidDebugDataTransmitted(USBDriver *usbp, usbep_t ep) { HIDDebugDriver *hiddp = usbp->in_params[ep - 1U]; size_t n; if(hiddp == NULL) { return; } osalSysLockFromISR(); /* rearm the flush timer */ chVTSetI(&hid_debug_flush_timer, MS2ST(DEBUG_TX_FLUSH_MS), hid_debug_flush_cb, hiddp); /* see if we've transmitted everything */ if((n = oqGetFullI(&hiddp->oqueue)) == 0) { chnAddFlagsI(hiddp, CHN_OUTPUT_EMPTY); } /* Check if there's enough data in the queue to send again */ if(n >= DEBUG_TX_SIZE) { /* The endpoint cannot be busy, we are in the context of the callback, * so it is safe to transmit without a check.*/ osalSysUnlockFromISR(); usbPrepareQueuedTransmit(usbp, ep, &hiddp->oqueue, DEBUG_TX_SIZE); osalSysLockFromISR(); (void)usbStartTransmitI(usbp, ep); } osalSysUnlockFromISR(); }
/** * @brief 1-wire read bit callback. * @note Must be called from PWM's ISR. * * @param[in] pwmp pointer to the @p PWMDriver object * @param[in] owp pointer to the @p onewireDriver object * * @notapi */ static void ow_read_bit_cb(PWMDriver *pwmp, onewireDriver *owp) { if (true == owp->reg.final_timeslot) { osalSysLockFromISR(); pwmDisableChannelI(pwmp, owp->config->sample_channel); osalThreadResumeI(&owp->thread, MSG_OK); osalSysUnlockFromISR(); return; } else { *owp->buf |= ow_read_bit(owp) << owp->reg.bit; owp->reg.bit++; if (8 == owp->reg.bit) { owp->reg.bit = 0; owp->buf++; owp->reg.bytes--; if (0 == owp->reg.bytes) { owp->reg.final_timeslot = true; osalSysLockFromISR(); /* Only master channel must be stopped here. Sample channel will be stopped in next ISR call. It is still needed to generate final interrupt. */ pwmDisableChannelI(pwmp, owp->config->master_channel); osalSysUnlockFromISR(); } } } }
/** * @brief Common IRQ handler. * @note Tries hard to clear all the pending interrupt sources, we don't * want to go through the whole ISR and have another interrupt soon * after. * * @param[in] u pointer to an UART I/O block * @param[in] sdp communication channel associated to the UART */ static void serve_interrupt(SerialDriver *sdp) { UART_TypeDef *u = sdp->uart; uint8_t s1 = u->S1; if (s1 & UARTx_S1_RDRF) { osalSysLockFromISR(); if (chIQIsEmptyI(&sdp->iqueue)) chnAddFlagsI(sdp, CHN_INPUT_AVAILABLE); if (chIQPutI(&sdp->iqueue, u->D) < Q_OK) chnAddFlagsI(sdp, SD_OVERRUN_ERROR); osalSysUnlockFromISR(); } if (s1 & UARTx_S1_TDRE) { msg_t b; osalSysLockFromISR(); b = chOQGetI(&sdp->oqueue); osalSysUnlockFromISR(); if (b < Q_OK) { osalSysLockFromISR(); chnAddFlagsI(sdp, CHN_OUTPUT_EMPTY); osalSysUnlockFromISR(); u->C2 &= ~UARTx_C2_TIE; } else { u->D = b; } } }
/** * @brief Common IRQ handler. * * @param[in] sdp pointer to a @p SerialDriver object */ static void serve_interrupt(SerialDriver *sdp) { volatile struct ESCI_tag *escip = sdp->escip; uint32_t sr = escip->SR.R; escip->SR.R = 0x3FFFFFFF; /* Does not clear TDRE | TC.*/ if (sr & 0x0F000000) /* OR | NF | FE | PF. */ set_error(sdp, sr); if (sr & 0x20000000) { /* RDRF. */ osalSysLockFromISR(); sdIncomingDataI(sdp, escip->DR.B.D); osalSysUnlockFromISR(); } if (escip->CR1.B.TIE && (sr & 0x80000000)) { /* TDRE. */ msg_t b; osalSysLockFromISR(); b = oqGetI(&sdp->oqueue); if (b < Q_OK) { chnAddFlagsI(sdp, CHN_OUTPUT_EMPTY); escip->CR1.B.TIE = 0; } else { ESCI_A.SR.B.TDRE = 1; escip->DR.R = (uint16_t)b; } osalSysUnlockFromISR(); } }
/** * @brief Default EP0 IN callback. * @details This function is used by the low level driver as default handler * for EP0 IN events. * * @param[in] usbp pointer to the @p USBDriver object * @param[in] ep endpoint number, always zero * * @notapi */ void _usb_ep0in(USBDriver *usbp, usbep_t ep) { size_t max; (void)ep; switch (usbp->ep0state) { case USB_EP0_TX: max = (size_t)get_hword(&usbp->setup[6]); /* If the transmitted size is less than the requested size and it is a multiple of the maximum packet size then a zero size packet must be transmitted.*/ if ((usbp->ep0n < max) && ((usbp->ep0n % usbp->epc[0]->in_maxsize) == 0U)) { usbPrepareTransmit(usbp, 0, NULL, 0); osalSysLockFromISR(); (void) usbStartTransmitI(usbp, 0); osalSysUnlockFromISR(); usbp->ep0state = USB_EP0_WAITING_TX0; return; } /* Falls into, it is intentional.*/ case USB_EP0_WAITING_TX0: /* Transmit phase over, receiving the zero sized status packet.*/ usbp->ep0state = USB_EP0_WAITING_STS; #if (USB_EP0_STATUS_STAGE == USB_EP0_STATUS_STAGE_SW) usbPrepareReceive(usbp, 0, NULL, 0); osalSysLockFromISR(); (void) usbStartReceiveI(usbp, 0); osalSysUnlockFromISR(); #else usb_lld_end_setup(usbp, ep); #endif return; case USB_EP0_SENDING_STS: /* Status packet sent, invoking the callback if defined.*/ if (usbp->ep0endcb != NULL) { usbp->ep0endcb(usbp); } usbp->ep0state = USB_EP0_WAITING_SETUP; return; case USB_EP0_WAITING_SETUP: case USB_EP0_WAITING_STS: case USB_EP0_RX: /* All the above are invalid states in the IN phase.*/ osalDbgAssert(false, "EP0 state machine error"); /* Falling through is intentional.*/ case USB_EP0_ERROR: /* Error response, the state machine goes into an error state, the low level layer will have to reset it to USB_EP0_WAITING_SETUP after receiving a SETUP packet.*/ usb_lld_stall_in(usbp, 0); usb_lld_stall_out(usbp, 0); _usb_isr_invoke_event_cb(usbp, USB_EVENT_STALLED); usbp->ep0state = USB_EP0_ERROR; return; default: osalDbgAssert(false, "EP0 state machine invalid state"); } }
/** * @brief Common IRQ handler. * * @param[in] sdp communication channel associated to the USART */ static void serve_interrupt(SerialDriver *sdp) { USART_TypeDef *u = sdp->usart; uint16_t cr1 = u->CR1; uint16_t sr = u->SR; /* Special case, LIN break detection.*/ if (sr & USART_SR_LBD) { osalSysLockFromISR(); chnAddFlagsI(sdp, SD_BREAK_DETECTED); u->SR = ~USART_SR_LBD; osalSysUnlockFromISR(); } /* Data available.*/ osalSysLockFromISR(); while (sr & (USART_SR_RXNE | USART_SR_ORE | USART_SR_NE | USART_SR_FE | USART_SR_PE)) { uint8_t b; /* Error condition detection.*/ if (sr & (USART_SR_ORE | USART_SR_NE | USART_SR_FE | USART_SR_PE)) set_error(sdp, sr); b = (uint8_t)u->DR & sdp->rxmask; if (sr & USART_SR_RXNE) sdIncomingDataI(sdp, b); sr = u->SR; } osalSysUnlockFromISR(); /* Transmission buffer empty.*/ if ((cr1 & USART_CR1_TXEIE) && (sr & USART_SR_TXE)) { msg_t b; osalSysLockFromISR(); b = oqGetI(&sdp->oqueue); if (b < MSG_OK) { chnAddFlagsI(sdp, CHN_OUTPUT_EMPTY); u->CR1 = (cr1 & ~USART_CR1_TXEIE) | USART_CR1_TCIE; } else u->DR = b; osalSysUnlockFromISR(); } /* Physical transmission end.*/ if ((cr1 & USART_CR1_TCIE) && (sr & USART_SR_TC)) { osalSysLockFromISR(); if (oqIsEmptyI(&sdp->oqueue)) { chnAddFlagsI(sdp, CHN_TRANSMISSION_END); u->CR1 = cr1 & ~USART_CR1_TCIE; } osalSysUnlockFromISR(); } }
/** * @brief Common IRQ handler. * * @param[in] sdp communication channel associated to the USART */ static void serve_interrupt(SerialDriver *sdp) { USART_TypeDef *u = sdp->usart; uint32_t cr1 = u->CR1; uint32_t isr; /* Reading and clearing status.*/ isr = u->ISR; u->ICR = isr; /* Error condition detection.*/ if (isr & (USART_ISR_ORE | USART_ISR_NE | USART_ISR_FE | USART_ISR_PE)) set_error(sdp, isr); /* Special case, LIN break detection.*/ if (isr & USART_ISR_LBDF) { osalSysLockFromISR(); chnAddFlagsI(sdp, SD_BREAK_DETECTED); osalSysUnlockFromISR(); } /* Data available.*/ if (isr & USART_ISR_RXNE) { osalSysLockFromISR(); sdIncomingDataI(sdp, (uint8_t)u->RDR); osalSysUnlockFromISR(); } /* Transmission buffer empty.*/ if ((cr1 & USART_CR1_TXEIE) && (isr & USART_ISR_TXE)) { msg_t b; osalSysLockFromISR(); b = oqGetI(&sdp->oqueue); if (b < Q_OK) { chnAddFlagsI(sdp, CHN_OUTPUT_EMPTY); u->CR1 = (cr1 & ~USART_CR1_TXEIE) | USART_CR1_TCIE; } else u->TDR = b; osalSysUnlockFromISR(); } /* Physical transmission end.*/ if (isr & USART_ISR_TC) { osalSysLockFromISR(); if (oqIsEmptyI(&sdp->oqueue)) chnAddFlagsI(sdp, CHN_TRANSMISSION_END); u->CR1 = cr1 & ~USART_CR1_TCIE; osalSysUnlockFromISR(); } }
/** * @brief Common IRQ handler. * @note Tries hard to clear all the pending interrupt sources, we dont want * to go through the whole ISR and have another interrupt soon after. * * @param[in] sdp communication channel associated to the UART */ static void serve_interrupt(SerialDriver *sdp) { UART *u = sdp->uart; while (TRUE) { switch (u->UART_IIR & IIR_SRC_MASK) { case IIR_SRC_NONE: return; case IIR_SRC_ERROR: set_error(sdp, u->UART_LSR); break; case IIR_SRC_TIMEOUT: case IIR_SRC_RX: osalSysLockFromISR(); if (chIQIsEmptyI(&sdp->iqueue)) chnAddFlagsI(sdp, CHN_INPUT_AVAILABLE); osalSysUnlockFromISR(); while (u->UART_LSR & LSR_RBR_FULL) { osalSysLockFromISR(); if (chIQPutI(&sdp->iqueue, u->UART_RBR) < Q_OK) chnAddFlagsI(sdp, SD_OVERRUN_ERROR); osalSysUnlockFromISR(); } break; case IIR_SRC_TX: { int i = LPC214x_UART_FIFO_PRELOAD; do { msg_t b; osalSysLockFromISR(); b = chOQGetI(&sdp->oqueue); osalSysUnlockFromISR(); if (b < Q_OK) { u->UART_IER &= ~IER_THRE; osalSysLockFromISR(); chnAddFlagsI(sdp, CHN_OUTPUT_EMPTY); osalSysUnlockFromISR(); break; } u->UART_THR = b; } while (--i); } break; default: (void) u->UART_THR; (void) u->UART_RBR; } } }
static void idle_rx_handler(UARTDriver *uart) { volatile uint16_t sr = uart->usart->SR; if (sr & (USART_SR_LBD | USART_SR_ORE | /* overrun error - packet was too big for DMA or DMA was too slow */ USART_SR_NE | /* noise error - we have lost a byte due to noise */ USART_SR_FE | USART_SR_PE)) { /* framing error - start/stop bit lost or line break */ /* send a line break - this will abort transmission/reception on the other end */ osalSysLockFromISR(); uart->usart->SR = ~USART_SR_LBD; uart->usart->CR1 |= USART_CR1_SBK; num_rx_error++; uart->usart->CR3 &= ~(USART_CR3_DMAT | USART_CR3_DMAR); (void)uart->usart->SR; (void)uart->usart->DR; (void)uart->usart->DR; dmaStreamDisable(uart->dmarx); dmaStreamDisable(uart->dmatx); dmaStreamSetMemory0(uart->dmarx, &iomcu.rx_io_packet); dmaStreamSetTransactionSize(uart->dmarx, sizeof(iomcu.rx_io_packet)); dmaStreamSetMode(uart->dmarx, uart->dmamode | STM32_DMA_CR_DIR_P2M | STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE); dmaStreamEnable(uart->dmarx); uart->usart->CR3 |= USART_CR3_DMAR; osalSysUnlockFromISR(); return; } if (sr & USART_SR_IDLE) { dma_rx_end_cb(uart); num_idle_rx++; } }
static void dma_rx_end_cb(UARTDriver *uart) { osalSysLockFromISR(); uart->usart->CR3 &= ~(USART_CR3_DMAT | USART_CR3_DMAR); (void)uart->usart->SR; (void)uart->usart->DR; (void)uart->usart->DR; dmaStreamDisable(uart->dmarx); dmaStreamDisable(uart->dmatx); iomcu.process_io_packet(); num_total_rx++; num_dma_complete_rx = num_total_rx - num_idle_rx; dmaStreamSetMemory0(uart->dmarx, &iomcu.rx_io_packet); dmaStreamSetTransactionSize(uart->dmarx, sizeof(iomcu.rx_io_packet)); dmaStreamSetMode(uart->dmarx, uart->dmamode | STM32_DMA_CR_DIR_P2M | STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE); dmaStreamEnable(uart->dmarx); uart->usart->CR3 |= USART_CR3_DMAR; dmaStreamSetMemory0(uart->dmatx, &iomcu.tx_io_packet); dmaStreamSetTransactionSize(uart->dmatx, iomcu.tx_io_packet.get_size()); dmaStreamSetMode(uart->dmatx, uart->dmamode | STM32_DMA_CR_DIR_M2P | STM32_DMA_CR_MINC | STM32_DMA_CR_TCIE); dmaStreamEnable(uart->dmatx); uart->usart->CR3 |= USART_CR3_DMAT; osalSysUnlockFromISR(); }
/** * @brief DMA RX end IRQ handler. * * @param[in] nandp pointer to the @p NANDDriver object * @param[in] flags pre-shifted content of the ISR register * * @notapi */ static void nand_lld_serve_transfer_end_irq(NANDDriver *nandp, uint32_t flags) { /* DMA errors handling.*/ #if defined(STM32_NAND_DMA_ERROR_HOOK) if ((flags & (STM32_DMA_ISR_TEIF | STM32_DMA_ISR_DMEIF)) != 0) { STM32_NAND_DMA_ERROR_HOOK(nandp); } #else (void)flags; #endif osalSysLockFromISR(); dmaStreamDisable(nandp->dma); switch (nandp->state){ case NAND_DMA_TX: nandp->state = NAND_PROGRAM; nandp->map_cmd[0] = NAND_CMD_PAGEPROG; /* thread will be woken from ready_isr() */ break; case NAND_DMA_RX: nandp->state = NAND_READY; nandp->rxdata = NULL; nandp->datalen = 0; wakeup_isr(nandp); break; default: osalSysHalt("Unhandled case"); break; } osalSysUnlockFromISR(); }
/** * @brief Reads from a dedicated packet buffer. * * @param[in] udp pointer to a @p stm32_usb_descriptor_t * @param[in] iqp pointer to an @p input_queue_t object * @param[in] n maximum number of bytes to copy. This value must * not exceed the maximum packet size for this endpoint. * * @notapi */ static void usb_packet_read_to_queue(stm32_usb_descriptor_t *udp, input_queue_t *iqp, size_t n) { size_t nhw; stm32_usb_pma_t *pmap= USB_ADDR2PTR(udp->RXADDR0); nhw = n / 2; while (nhw > 0) { stm32_usb_pma_t w; w = *pmap++; *iqp->q_wrptr++ = (uint8_t)w; if (iqp->q_wrptr >= iqp->q_top) iqp->q_wrptr = iqp->q_buffer; *iqp->q_wrptr++ = (uint8_t)(w >> 8); if (iqp->q_wrptr >= iqp->q_top) iqp->q_wrptr = iqp->q_buffer; nhw--; } /* Last byte for odd numbers.*/ if ((n & 1) != 0) { *iqp->q_wrptr++ = (uint8_t)*pmap; if (iqp->q_wrptr >= iqp->q_top) iqp->q_wrptr = iqp->q_buffer; } /* Updating queue.*/ osalSysLockFromISR(); iqp->q_counter += n; osalThreadDequeueAllI(&iqp->q_waiting, Q_OK); osalSysUnlockFromISR(); }
/** * @brief Default data received callback. * @details The application must use this function as callback for the OUT * data endpoint. * * @param[in] usbp pointer to the @p USBDriver object * @param[in] ep OUT endpoint number */ void sduDataReceived(USBDriver *usbp, usbep_t ep) { uint8_t *buf; SerialUSBDriver *sdup = usbp->out_params[ep - 1U]; if (sdup == NULL) { return; } osalSysLockFromISR(); /* Signaling that data is available in the input queue.*/ chnAddFlagsI(sdup, CHN_INPUT_AVAILABLE); /* Posting the filled buffer in the queue.*/ ibqPostFullBufferI(&sdup->ibqueue, usbGetReceiveTransactionSizeX(sdup->config->usbp, sdup->config->bulk_out)); /* The endpoint cannot be busy, we are in the context of the callback, so a packet is in the buffer for sure. Trying to get a free buffer for the next transaction.*/ buf = ibqGetEmptyBufferI(&sdup->ibqueue); if (buf != NULL) { /* Buffer found, starting a new transaction.*/ usbStartReceiveI(sdup->config->usbp, sdup->config->bulk_out, buf, SERIAL_USB_BUFFERS_SIZE); } osalSysUnlockFromISR(); }
/** * @brief Generic endpoint OUT handler. * * @param[in] usbp pointer to the @p USBDriver object * @param[in] ep endpoint number * * @notapi */ static void otg_epout_handler(USBDriver *usbp, usbep_t ep) { stm32_otg_t *otgp = usbp->otg; uint32_t epint = otgp->oe[ep].DOEPINT; /* Resets all EP IRQ sources.*/ otgp->oe[ep].DOEPINT = epint; if ((epint & DOEPINT_STUP) && (otgp->DOEPMSK & DOEPMSK_STUPM)) { /* Setup packets handling, setup packets are handled using a specific callback.*/ _usb_isr_invoke_setup_cb(usbp, ep); } if ((epint & DOEPINT_XFRC) && (otgp->DOEPMSK & DOEPMSK_XFRCM)) { /* Receive transfer complete.*/ USBOutEndpointState *osp = usbp->epc[ep]->out_state; if (osp->rxsize < osp->totsize) { /* In case the transaction covered only part of the total transfer then another transaction is immediately started in order to cover the remaining.*/ osp->rxsize = osp->totsize - osp->rxsize; osp->rxcnt = 0; usb_lld_prepare_receive(usbp, ep); osalSysLockFromISR(); usb_lld_start_out(usbp, ep); osalSysUnlockFromISR(); } else { /* End on OUT transfer.*/ _usb_isr_invoke_out_cb(usbp, ep); } } }
/* * GPT callback. */ static void gptcb(GPTDriver *gptp) { (void)gptp; osalSysLockFromISR(); unix_usec += RTC_TIMER_STEP + timer_skew; osalSysUnlockFromISR(); }
/** * @brief Ready interrupt handler * * @param[in] nandp pointer to the @p NANDDriver object * * @notapi */ static void nand_isr_handler (NANDDriver *nandp) { osalSysLockFromISR(); #if !STM32_NAND_USE_EXT_INT osalDbgCheck(nandp->nand->SR & FSMC_SR_IRS); /* spurious interrupt happened */ nandp->nand->SR &= ~FSMC_SR_IRS; #endif switch (nandp->state){ case NAND_READ: nandp->state = NAND_DMA_RX; dmaStartMemCopy(nandp->dma, nandp->dmamode, nandp->map_data, nandp->rxdata, nandp->datalen); /* thread will be waked up from DMA ISR */ break; case NAND_ERASE: /* NAND reports about erase finish */ nandp->state = NAND_READY; wakeup_isr(nandp); break; case NAND_PROGRAM: /* NAND reports about page programming finish */ nandp->state = NAND_READY; wakeup_isr(nandp); break; default: osalSysHalt("Unhandled case"); break; } osalSysUnlockFromISR(); }
/* Handles the USB driver global events */ static void usb_event_cb(USBDriver *usbp, usbevent_t event) { switch(event) { case USB_EVENT_RESET: return; case USB_EVENT_ADDRESS: return; case USB_EVENT_CONFIGURED: osalSysLockFromISR(); /* Enable the endpoints specified into the configuration. */ usbInitEndpointI(usbp, DEBUG_TX_ENDPOINT, &hid_debug_ep_config); hidDebugConfigureHookI(&HIDD); osalSysUnlockFromISR(); return; case USB_EVENT_SUSPEND: return; case USB_EVENT_WAKEUP: return; case USB_EVENT_STALLED: return; } }
/** * @brief USB suspend routine. * @details This function must be invoked when an USB bus suspend condition is * detected. * * @param[in] usbp pointer to the @p USBDriver object * * @notapi */ void _usb_suspend(USBDriver *usbp) { /* No state change, suspend always returns to previous state. */ /* State transition.*/ usbp->saved_state = usbp->state; usbp->state = USB_SUSPENDED; /* Notification of suspend event.*/ _usb_isr_invoke_event_cb(usbp, USB_EVENT_SUSPEND); /* Signaling the event to threads waiting on endpoints.*/ #if USB_USE_WAIT == TRUE { unsigned i; for (i = 0; i <= (unsigned)USB_MAX_ENDPOINTS; i++) { if (usbp->epc[i] != NULL) { osalSysLockFromISR(); if (usbp->epc[i]->in_state != NULL) { osalThreadResumeI(&usbp->epc[i]->in_state->thread, MSG_RESET); } if (usbp->epc[i]->out_state != NULL) { osalThreadResumeI(&usbp->epc[i]->out_state->thread, MSG_RESET); } osalSysUnlockFromISR(); } } } #endif }
/** * @brief Disables all the active endpoints. * @details This function disables all the active endpoints except the * endpoint zero. * @note This function must be invoked in response of a SET_CONFIGURATION * message with configuration number zero. * * @param[in] usbp pointer to the @p USBDriver object * * @iclass */ void usbDisableEndpointsI(USBDriver *usbp) { unsigned i; osalDbgCheckClassI(); osalDbgCheck(usbp != NULL); osalDbgAssert(usbp->state == USB_ACTIVE, "invalid state"); usbp->transmitting &= 1U; usbp->receiving &= 1U; for (i = 1; i <= (unsigned)USB_MAX_ENDPOINTS; i++) { #if USB_USE_WAIT == TRUE /* Signaling the event to threads waiting on endpoints.*/ if (usbp->epc[i] != NULL) { osalSysLockFromISR(); if (usbp->epc[i]->in_state != NULL) { osalThreadResumeI(&usbp->epc[i]->in_state->thread, MSG_RESET); } if (usbp->epc[i]->out_state != NULL) { osalThreadResumeI(&usbp->epc[i]->out_state->thread, MSG_RESET); } osalSysUnlockFromISR(); } #endif usbp->epc[i] = NULL; } /* Low level endpoints deactivation.*/ usb_lld_disable_endpoints(usbp); }
/* * Handles the USB driver global events. */ static void usb_event(USBDriver *usbp, usbevent_t event) { // (void)usbp; switch (event) { case USB_EVENT_RESET: return; case USB_EVENT_ADDRESS: return; case USB_EVENT_CONFIGURED: osalSysLockFromISR(); /* Enables the endpoints specified into the configuration. Note, this callback is invoked from an ISR so I-Class functions must be used.*/ usbInitEndpointI(usbp, USBD1_DATA_REQUEST_EP, &ep1config); /* Resetting the state of the CDC subsystem.*/ hidConfigureHookI(&UHD1); osalSysUnlockFromISR(); return; case USB_EVENT_SUSPEND: return; case USB_EVENT_WAKEUP: return; case USB_EVENT_STALLED: return; } return; }
/* * Handles the USB driver start of frame event. */ static void sof_handler(USBDriver *usbp) { (void)usbp; osalSysLockFromISR(); sduSOFHookI(&SDU1); osalSysUnlockFromISR(); }
/** * @brief Interrupt callback to be used in the EXT driver config * for sensor reads. Used with interrupt driven sensors. * * @param[in] extp Pointer to the EXTDriver object. * @param[in] channel Pointer the ext channel. * * */ void sensors_interrupt_callback(EXTDriver *extp, expchannel_t channel) { const interrupt_sensor_t *p; osalSysLockFromISR(); /* Check if the driver is in the correct state, else disable the interrupt */ if (SRD1.state == SRD_STARTED) { p = extchannel2interrupt_sensor(&SRD1, channel); if (p != NULL) { /* Tell the reading thread to read the sensor requested sensor */ if (queueReadI(&SRD1, &p->sensor) != MSG_OK) { #if SRD_DEBUG SRD1.dbg_mailbox_overflow = true; #endif } } else /* Something in the initial settings structures are faulty */ extChannelDisableI(extp, channel); } else extChannelDisableI(extp, channel); osalSysUnlockFromISR(); }
static void set_error(uint8_t sra, SerialDriver *sdp) { eventflags_t sts = 0; uint8_t dor = 0; uint8_t upe = 0; uint8_t fe = 0; #if AVR_SERIAL_USE_USART0 if (&SD1 == sdp) { dor = (1 << DOR0); upe = (1 << UPE0); fe = (1 << FE0); } #endif #if AVR_SERIAL_USE_USART1 if (&SD2 == sdp) { dor = (1 << DOR1); upe = (1 << UPE1); fe = (1 << FE1); } #endif if (sra & dor) sts |= SD_OVERRUN_ERROR; if (sra & upe) sts |= SD_PARITY_ERROR; if (sra & fe) sts |= SD_FRAMING_ERROR; osalSysLockFromISR(); chnAddFlagsI(sdp, sts); osalSysUnlockFromISR(); }
/* * Handles the Start of Frame event. */ static void sof_handler(USBDriver *usbp) { (void)usbp; osalSysLockFromISR(); sduSOFHookI(&OUTPUT_CHANNEL); osalSysUnlockFromISR(); }
/** * @brief Common IRQ handler. * @note Tries hard to clear all the pending interrupt sources, we don't * want to go through the whole ISR and have another interrupt soon * after. * * @param[in] u pointer to an UART I/O block * @param[in] sdp communication channel associated to the UART */ static void serial_serve_interrupt(SerialDriver *sdp) { uint32_t u = sdp->uart; uint16_t mis = HWREG(u + UART_O_MIS); HWREG(u + UART_O_ICR) = mis; /* clear interrupts */ if (mis & (UART_MIS_FEMIS | UART_MIS_PEMIS | UART_MIS_BEMIS | UART_MIS_OEMIS)) { set_error(sdp, mis); } if ((mis & UART_MIS_RXMIS) || (mis & UART_MIS_RTMIS)) { osalSysLockFromISR(); if (iqIsEmptyI(&sdp->iqueue)) { chnAddFlagsI(sdp, CHN_INPUT_AVAILABLE); } osalSysUnlockFromISR(); while ((HWREG(u + UART_O_FR) & UART_FR_RXFE) == 0) { osalSysLockFromISR(); if (iqPutI(&sdp->iqueue, HWREG(u + UART_O_DR)) < Q_OK) { chnAddFlagsI(sdp, SD_QUEUE_FULL_ERROR); } osalSysUnlockFromISR(); } } if (mis & UART_MIS_TXMIS) { while ((HWREG(u + UART_O_FR) & UART_FR_TXFF) == 0) { msg_t b; osalSysLockFromISR(); b = oqGetI(&sdp->oqueue); osalSysUnlockFromISR(); if (b < Q_OK) { HWREG(u + UART_O_IM) &= ~UART_IM_TXIM; osalSysLockFromISR(); chnAddFlagsI(sdp, CHN_OUTPUT_EMPTY); osalSysUnlockFromISR(); break; } HWREG(u + UART_O_DR) = b; } } /* TODO: Physical transmission end. */ }
/** * @brief 1-wire reset pulse callback. * @note Must be called from PWM's ISR. * * @param[in] pwmp pointer to the @p PWMDriver object * @param[in] owp pointer to the @p onewireDriver object * * @notapi */ static void ow_reset_cb(PWMDriver *pwmp, onewireDriver *owp) { owp->reg.slave_present = (PAL_LOW == ow_read_bit(owp)); osalSysLockFromISR(); pwmDisableChannelI(pwmp, owp->config->sample_channel); osalThreadResumeI(&owp->thread, MSG_OK); osalSysUnlockFromISR(); }
static void pps_cb(EXTDriver *extp, expchannel_t channel){ (void)extp; (void)channel; osalSysLockFromISR(); TimeKeeper::PPS_ISR_I(); gnss::GNSSReceiver::PPS_ISR_I(); osalSysUnlockFromISR(); }
/** * @brief Common IRQ handler. * @note Tries hard to clear all the pending interrupt sources, we don't * want to go through the whole ISR and have another interrupt soon * after. * * @param[in] u pointer to an UART I/O block * @param[in] sdp communication channel associated to the UART */ static void serial_serve_interrupt(SerialDriver *sdp) { UART_TypeDef *u = sdp->uart; uint16_t mis = u->MIS; u->ICR = mis; /* clear interrupts */ if (mis & (TIVA_MIS_FEMIS | TIVA_MIS_PEMIS | TIVA_MIS_BEMIS | TIVA_MIS_OEMIS)) { set_error(sdp, mis); } if ((mis & TIVA_MIS_RXMIS) || (mis & TIVA_MIS_RTMIS)) { osalSysLockFromISR(); if (iqIsEmptyI(&sdp->iqueue)) { chnAddFlagsI(sdp, CHN_INPUT_AVAILABLE); } osalSysUnlockFromISR(); while ((u->FR & TIVA_FR_RXFE) == 0) { osalSysLockFromISR(); if (iqPutI(&sdp->iqueue, u->DR) < Q_OK) { chnAddFlagsI(sdp, SD_OVERRUN_ERROR); } osalSysUnlockFromISR(); } } if (mis & TIVA_MIS_TXMIS) { while ((u->FR & TIVA_FR_TXFF) == 0) { msg_t b; osalSysLockFromISR(); b = oqGetI(&sdp->oqueue); osalSysUnlockFromISR(); if (b < Q_OK) { u->IM &= ~TIVA_IM_TXIM; osalSysLockFromISR(); chnAddFlagsI(sdp, CHN_OUTPUT_EMPTY); osalSysUnlockFromISR(); break; } u->DR = b; } } }
void systick_isr() { systick_millis_count++; if (sysTickEnabled) { OSAL_IRQ_PROLOGUE(); osalSysLockFromISR(); osalOsTimerHandlerI(); osalSysUnlockFromISR(); OSAL_IRQ_EPILOGUE(); } }