Esempio n. 1
0
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();
}
Esempio n. 4
0
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();
}