static void USART_IRQHandler()

in lib/cmsis/CMSIS/Pack/Example/CMSIS_Driver/USART_LPC18xx.c [1759:1896]


static void USART_IRQHandler (USART_RESOURCES *usart) {
  uint32_t iir, event, val;

  event = 0;
  iir   = usart->reg->IIR;

  if ((iir & USART_IIR_INTSTATUS) == 0) {

    // Transmit holding register empty
    if ((iir & USART_IIR_INTID_MSK) == USART_IIR_INTID_THRE) {
      val = 16;
      while ((val --) && (usart->info->xfer.tx_num != usart->info->xfer.tx_cnt)) {
        if (((usart->info->mode == ARM_USART_MODE_SYNCHRONOUS_MASTER)  ||
             (usart->info->mode == ARM_USART_MODE_SYNCHRONOUS_SLAVE )) &&
             (usart->info->xfer.sync_mode == USART_SYNC_MODE_RX)) {
          // Dummy write in synchronous receive only mode
          usart->reg->THR = usart->info->xfer.tx_def_val;
        } else {
          // Write data to Tx FIFO      
          usart->reg->THR = usart->info->xfer.tx_buf[usart->info->xfer.tx_cnt];
        }
        usart->info->xfer.tx_cnt++;
      }

      // Check if all data is transmitted
      if (usart->info->xfer.tx_num == usart->info->xfer.tx_cnt) {
        // Disable THRE interrupt
        usart->reg->IER &= ~USART_IER_THREIE;

        // Clear TX busy flag
        usart->info->flags &= ~USART_FLAG_SEND_ACTIVE;

        // Set send complete event
        if ((usart->info->mode == ARM_USART_MODE_SYNCHRONOUS_MASTER) ||
            (usart->info->mode == ARM_USART_MODE_SYNCHRONOUS_SLAVE )) {
          if ((usart->info->xfer.sync_mode == USART_SYNC_MODE_TX)    &&
              ((usart->info->flags & USART_FLAG_RX_ENABLED) == 0)) {
            event |= ARM_USART_EVENT_SEND_COMPLETE;
          }
        } else {
          event |= ARM_USART_EVENT_SEND_COMPLETE;
        }       
      }
    }

    // Receive line status
    if ((iir & USART_IIR_INTID_MSK) == USART_IIR_INTID_RLS) {
      event |= USART_RxLineIntHandler(usart);
    }

    // Receive data available and Character time-out indicator interrupt
    if (((iir & USART_IIR_INTID_MSK) == USART_IIR_INTID_RDA)  |
        ((iir & USART_IIR_INTID_MSK) == USART_IIR_INTID_CTI)) {

      // Get all available data from RX FIFO
      while (usart->reg->LSR & USART_LSR_RDR) {
        // Check RX line interrupt for errors
        event |= USART_RxLineIntHandler (usart);

        if (((usart->info->mode == ARM_USART_MODE_SYNCHRONOUS_MASTER)  ||
             (usart->info->mode == ARM_USART_MODE_SYNCHRONOUS_SLAVE )) &&
             (usart->info->xfer.sync_mode == USART_SYNC_MODE_TX)) {
          // Dummy read in synchronous transmit only mode
          usart->reg->RBR;
        } else {
          // Read data from RX FIFO into receive buffer
          usart->info->xfer.rx_buf[usart->info->xfer.rx_cnt] = usart->reg->RBR;
        }

        usart->info->xfer.rx_cnt++;

        // Check if requested amount of data is received
        if (usart->info->xfer.rx_cnt == usart->info->xfer.rx_num) {
          // Disable RDA interrupt
          usart->reg->IER &= ~USART_IER_RBRIE;

          // Clear RX busy flag and set receive transfer complete event
          usart->info->status.rx_busy = 0;
          if ((usart->info->mode == ARM_USART_MODE_SYNCHRONOUS_MASTER) ||
              (usart->info->mode == ARM_USART_MODE_SYNCHRONOUS_SLAVE )) {
            val = usart->info->xfer.sync_mode;
            usart->info->xfer.sync_mode = 0;
            switch (val) {
              case USART_SYNC_MODE_TX:
                event |= ARM_USART_EVENT_SEND_COMPLETE;
                break;
              case USART_SYNC_MODE_RX:
                event |= ARM_USART_EVENT_RECEIVE_COMPLETE;
                break;
              case USART_SYNC_MODE_TX_RX:
                event |= ARM_USART_EVENT_TRANSFER_COMPLETE;
                break;
            }
          } else {
            event |= ARM_USART_EVENT_RECEIVE_COMPLETE;
          }
          break;
        }
      }
    }

    // Character time-out indicator
    if ((iir & USART_IIR_INTID_MSK) == USART_IIR_INTID_CTI) {
      if ((usart->info->mode != ARM_USART_MODE_SYNCHRONOUS_MASTER) &&
          (usart->info->mode != ARM_USART_MODE_SYNCHRONOUS_SLAVE )) {
        // Signal RX Time-out event, if not all requested data received
        if (usart->info->xfer.rx_cnt != usart->info->xfer.rx_num) {
          event |= ARM_USART_EVENT_RX_TIMEOUT;
        }
      }
    }

    // Modem interrupt (UART1 only)
#if (RTE_UART1)
    if (usart->uart_reg) {
      if ((iir & USART_IIR_INTID_MSK) == UART_IIR_INTID_MS) {
        // Save modem status register
        val = usart->uart_reg->MSR;
      
        // CTS state changed
        if ((usart->capabilities.cts) && (val & UART_MSR_DCTS))
          event |= ARM_USART_EVENT_CTS;
        // DSR state changed
        if ((usart->capabilities.dsr) && (val & UART_MSR_DDSR))
          event |= ARM_USART_EVENT_DSR;
        // Ring indicator
        if ((usart->capabilities.ri)  && (val & UART_MSR_TERI))
          event |= ARM_USART_EVENT_RI;
        // DCD state changed
        if ((usart->capabilities.dcd) && (val & UART_MSR_DDCD))
          event |= ARM_USART_EVENT_DCD;
      }
    }
#endif
  }
  if (usart->info->cb_event && event)
    usart->info->cb_event (event);
}