From EdWiki

Revision as of 11:07, 5 November 2018 by Jshankar (Talk | contribs) (Configuring interrupts from the UART)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

Configuring interrupts from the UART

Configuring interrupts from the UART

To have an event generate an interrupt, its interrupt source must be unmasked. This can be achieved with uart_enable_interrupts(). Interrupts which are no longer needed can be disabled through uart_disable_interrupts().

In order for the interrupt to generate an IRQ and a call to the interrupt service routine, the interrupt for the target UART must be routed through the NVIC with nvic_enable_irq(). For this last step, the nvic.h header is needed:

Enabling an interrupt is as simple as unmasking the desired interrupt, and routing the desired UART's interrupt through the NVIC.

// Unmask receive interrupt
// Make sure the interrupt is routed through the NVIC

If a more than one interrupt is to be enabled at one time, the interrupts can be enabled by a single call to uart_enable_interrupts(). For example:

// Unmask receive, CTS, and RI, interrupts
uart_enable_interrupts(UART0, UART_INT_RX | UART_INT_RI | UART_INT_CTS);

After interrupts are properly enabled and routed through the NVIC, when an event occurs, the appropriate IRQ flag is set by hardware, and execution jumps to the UART ISR. The ISR should query the IRQ flags to determine which event caused the interrupt. For this, use uart_is_interrupt_source(), with the desired UART_INT flag. After one or more interrupt sources are serviced, the IRQ flags must be cleared by the ISR. This can be done with uart_clear_interrupt_flag().

A typical UART ISR may look like the following:

  1. void uart0_isr(void)
  2. {
  3.      uint32_t serviced_irqs = 0;
  4.      // Process individual IRQs
  5.      if (uart_is_interrupt_source(UART0, UART_INT_RX)) {
  6.         process_rx_event();
  7.         serviced_irq |= UART_INT_RX;
  8.      }
  9.      if (uart_is_interrupt_source(UART0, UART_INT_CTS)) {
  10.         process_cts_event();
  11.         serviced_irq |= UART_INT_CTS;
  12.      }
  13.      // Clear the interrupt flag for the processed IRQs
  14.      uart_clear_interrupt_flag(UART0, serviced_irqs);
  15. }