static bool_t inint(SerialDriver *sdp) { if (sdp->com_data != INVALID_SOCKET) { int i; uint8_t data[32]; /* * Input. */ int n = recv(sdp->com_data, data, sizeof(data), 0); switch (n) { case 0: close(sdp->com_data); sdp->com_data = INVALID_SOCKET; chSysLockFromIsr(); chnAddFlagsI(sdp, CHN_DISCONNECTED); chSysUnlockFromIsr(); return FALSE; case INVALID_SOCKET: if (errno == EWOULDBLOCK) return FALSE; close(sdp->com_data); sdp->com_data = INVALID_SOCKET; return FALSE; } for (i = 0; i < n; i++) { chSysLockFromIsr(); sdIncomingDataI(sdp, data[i]); chSysUnlockFromIsr(); } return TRUE; } return FALSE; }
/** * @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(); } }
static bool inint(SerialDriver *sdp) { if (sdp->com_data != INVALID_SOCKET) { int i; uint8_t data[32]; /* * Input. */ int n = recv(sdp->com_data, (char *)data, sizeof(data), 0); switch (n) { case 0: closesocket(sdp->com_data); sdp->com_data = INVALID_SOCKET; chSysLockFromISR(); chnAddFlagsI(sdp, CHN_DISCONNECTED); chSysUnlockFromISR(); return false; case SOCKET_ERROR: if (WSAGetLastError() == WSAEWOULDBLOCK) return false; closesocket(sdp->com_data); sdp->com_data = INVALID_SOCKET; return false; } for (i = 0; i < n; i++) { chSysLockFromISR(); sdIncomingDataI(sdp, data[i]); chSysUnlockFromISR(); } return true; } return false; }
/** * @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. * * @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; /* SR reset step 1.*/ uint16_t dr = u->DR; /* SR reset step 2.*/ /* Error condition detection.*/ if (sr & (USART_SR_ORE | USART_SR_NE | USART_SR_FE | USART_SR_PE)) set_error(sdp, sr); /* Special case, LIN break detection.*/ if (sr & USART_SR_LBD) { chSysLockFromIsr(); chnAddFlagsI(sdp, SD_BREAK_DETECTED); chSysUnlockFromIsr(); u->SR &= ~USART_SR_LBD; } /* Data available.*/ if (sr & USART_SR_RXNE) { chSysLockFromIsr(); sdIncomingDataI(sdp, (uint8_t)dr); chSysUnlockFromIsr(); } /* Transmission buffer empty.*/ if ((cr1 & USART_CR1_TXEIE) && (sr & USART_SR_TXE)) { msg_t b; chSysLockFromIsr(); b = chOQGetI(&sdp->oqueue); if (b < Q_OK) { chnAddFlagsI(sdp, CHN_OUTPUT_EMPTY); u->CR1 = (cr1 & ~USART_CR1_TXEIE) | USART_CR1_TCIE; } else u->DR = b; chSysUnlockFromIsr(); } /* Physical transmission end.*/ if (sr & USART_SR_TC) { chSysLockFromIsr(); chnAddFlagsI(sdp, CHN_TRANSMISSION_END); chSysUnlockFromIsr(); u->CR1 = cr1 & ~USART_CR1_TCIE; u->SR &= ~USART_SR_TC; } }
/** * @brief Common RXI IRQ handler. * * @param[in] sdp pointer to a @p SerialDriver object */ static void spc5xx_serve_rxi_interrupt(SerialDriver *sdp) { flagsmask_t sts = 0; uint16_t sr = sdp->linflexp->UARTSR.R; sdp->linflexp->UARTSR.R = SPC5_UARTSR_NF | SPC5_UARTSR_DRF | SPC5_UARTSR_PE0; if (sr & SPC5_UARTSR_NF) sts |= SD_NOISE_ERROR; if (sr & SPC5_UARTSR_PE0) sts |= SD_PARITY_ERROR; chSysLockFromIsr(); if (sts) chnAddFlagsI(sdp, sts); if (sr & SPC5_UARTSR_DRF) { sdIncomingDataI(sdp, sdp->linflexp->BDRM.B.DATA4); sdp->linflexp->UARTSR.R = SPC5_UARTSR_RMB; } chSysUnlockFromIsr(); }
static #endif /** * @brief Common IRQ handler. * * @param[in] sdp communication channel associated to the USART */ void sd_lld_serve_interrupt(SerialDriver *sdp) { uint32_t csr; AT91PS_USART u = sdp->usart; csr = u->US_CSR; if (csr & AT91C_US_RXRDY) { chSysLockFromIsr(); sdIncomingDataI(sdp, u->US_RHR); chSysUnlockFromIsr(); } if ((u->US_IMR & AT91C_US_TXRDY) && (csr & AT91C_US_TXRDY)) { msg_t b; chSysLockFromIsr(); b = chOQGetI(&sdp->oqueue); if (b < Q_OK) { chIOAddFlagsI(sdp, IO_OUTPUT_EMPTY); u->US_IDR = AT91C_US_TXRDY; } else u->US_THR = b; chSysUnlockFromIsr(); } csr &= (AT91C_US_OVRE | AT91C_US_FRAME | AT91C_US_PARE | AT91C_US_RXBRK); if (csr != 0) { set_error(sdp, csr); u->US_CR = AT91C_US_RSTSTA; } AT91C_BASE_AIC->AIC_EOICR = 0; }
void sd_lld_serve_interrupt( SerialDriver *sdp ) { if (AUX_MU_IIR_RX_IRQ) { chSysLockFromIsr(); while(!AUX_MU_LSR_RX_RDY); do { sdIncomingDataI(sdp, AUX_MU_IO_REG & 0xFF); } while (AUX_MU_LSR_RX_RDY); chSysUnlockFromIsr(); } if (AUX_MU_IIR_TX_IRQ) { chSysLockFromIsr(); while(!AUX_MU_LSR_TX_RDY); msg_t data = sdRequestDataI(sdp); if (data < Q_OK) { /* Disable tx interrupts.*/ AUX_MU_IER_REG &= ~AUX_MU_IER_TX_IRQEN; } else { mini_uart_send((uint32_t)data); } chSysUnlockFromIsr(); } }