static void set_error(uint8_t sra, SerialDriver *sdp) { sdflags_t sts = 0; if (sra & (1 << DOR)) sts |= SD_OVERRUN_ERROR; if (sra & (1 << UPE)) sts |= SD_PARITY_ERROR; if (sra & (1 << FE)) sts |= SD_FRAMING_ERROR; chSysLockFromIsr(); sdAddFlagsI(sdp, sts); chSysUnlockFromIsr(); }
/** * @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: chSysLockFromIsr(); if (chIQIsEmpty(&sdp->iqueue)) chEvtBroadcastI(&sdp->ievent); chSysUnlockFromIsr(); while (u->UART_LSR & LSR_RBR_FULL) { chSysLockFromIsr(); if (chIQPutI(&sdp->iqueue, u->UART_RBR) < Q_OK) sdAddFlagsI(sdp, SD_OVERRUN_ERROR); chSysUnlockFromIsr(); } break; case IIR_SRC_TX: { int i = LPC214x_UART_FIFO_PRELOAD; do { msg_t b; chSysLockFromIsr(); b = chOQGetI(&sdp->oqueue); chSysUnlockFromIsr(); if (b < Q_OK) { u->UART_IER &= ~IER_THRE; chSysLockFromIsr(); chEvtBroadcastI(&sdp->oevent); chSysUnlockFromIsr(); break; } u->UART_THR = b; } while (--i); } break; default: (void) u->UART_THR; (void) u->UART_RBR; } } }
/** * @brief Error handling routine. * * @param[in] sdp communication channel associated to the UART * @param[in] err UART LSR register value */ static void set_error(SerialDriver *sdp, IOREG32 err) { sdflags_t sts = 0; if (err & LSR_OVERRUN) sts |= SD_OVERRUN_ERROR; if (err & LSR_PARITY) sts |= SD_PARITY_ERROR; if (err & LSR_FRAMING) sts |= SD_FRAMING_ERROR; if (err & LSR_BREAK) sts |= SD_BREAK_DETECTED; chSysLockFromIsr(); sdAddFlagsI(sdp, sts); chSysUnlockFromIsr(); }
static void set_error(SerialDriver *sdp, uint8_t sr) { sdflags_t sts = 0; if (sr & 0x08) /* OR bit. */ sts |= SD_OVERRUN_ERROR; if (sr & 0x04) /* NF bit. */ sts |= SD_NOISE_ERROR; if (sr & 0x02) /* FE bit. */ sts |= SD_FRAMING_ERROR; if (sr & 0x01) /* PE bit. */ sts |= SD_PARITY_ERROR; chSysLockFromIsr(); sdAddFlagsI(sdp, sts); chSysUnlockFromIsr(); }