AnsweredAssumed Answered

LPTMR0 stops working when using LPUART1?

Question asked by Ammar Bazzaz on Oct 16, 2019
Latest reply on Oct 22, 2019 by Ammar Bazzaz

I am having trouble with the LPTMR0 when I use LPUART1 to transmit a small buffer of data (8 bytes). When I use LPUART0 everything works fine. The code structure is identical between the two (UART0 vs UART1), except for the modifications required to use one instance the LPUART peripheral vs the other. When I use UART1 the LPTMR0 stops generating interrupts after (or possibly during) the time that 8 bytes of data in the buffer are transmitted. More detail below.

 

MCU is an MKE16F512VLH16

 

The 30,000 ft view goes like this:

LPTMR0 is set up for a 1ms interrupt.

A flag is set in the LPTMR0 IRQ Handler that calls tick() which resides in main().

Inside tick() there is a static counter that counts to 1000 and then calls uart1_send().

Inside uart1_send() 8 bytes of data are sent (one by one) using the UART1_TX IRQ Handler.

Flags and the counters are cleared accordingly and this process repeats every 1000ms.

Using UART0 everything works fine.

Using UART1 the 8 bytes of data are transmitted once and then LPTMR0 IRQ Handler is never called again.

 

I am stomped, any assistance would be helpful. Relevant code snippets below:

 

void lpuart_iz (void) {

   NVIC->ICPR[1] |= (1 << 0); // clear pending register for LPUART0 RX
   NVIC->ISER[1] |= (1 << 0); // set enable register for LPUART0 RX

   LPUART0->BAUD = 0xF00001A; // set SBR for 115,200 (115,385 actual), OSR for 16, 8.7us/bit, 87us/byte
   LPUART0->CTRL |= 0xAC0000; // enable TX/RX interrupts, enable TX/RX

   NVIC->ICPR[1] |= (1 << 2); // clear pending register for LPUART1 RX
   NVIC->ISER[1] |= (1 << 2); // set enable register for LPUART1 RX

   LPUART1->BAUD = 0xF00001A; // set SBR for 115,200 (115,385 actual), OSR for 16, 8.7us/bit, 87us/byte
   LPUART1->CTRL |= 0xAC0000; // enable TX/RX interrupts, enable TX/RX

}

 

void lptmr_iz (void) {

   NVIC->ICPR[1] |= (1 << 26); // clear pending register for LPTMR0
   NVIC->ISER[1] |= (1 << 26); // set enable register for LPTMR0

   LPTMR0->CSR = 0x40; // timer mode, interrupts enabled, counter rests on match
   LPTMR0->CMR = LPTMR0_TICK; // 1ms period
   LPTMR0->CSR |= 0x01; // enable and start LPTMR0

   if (!tick_flag) {tick_flag = 1;} // perform tick tasks immediately

}

 

int main(void) {

   clock_iz(); // initialize clocks and turn on peripheral gates
   port_iz(); // initialize ports and output states
   lpuart_iz(); // initialize lpuarts
   lptmr_iz(); // initialize and start lptrm0

   while (1) {

      if (tick_flag) tick(); // call tick tasks
      if (uart_send_flag) uart1_send();

   }

   return 0;

}

 

void tick (void) { // tick tasks

   static uint16_t supertick = 0;
   static uint8_t state = 0;

   if (supertick < 1000) supertick++;
   else {

      if (state) {RED_OFF; state = 0;}
      else {RED_ON; state = 1;}

      uart_send_flag = TRUE;
   supertick = 0;

   }

   tick_flag = 0; // clear tick_flag for next call

}

 

void LPTMR0_IRQHandler (void) {

   if (!tick_flag) {tick_flag = 1;}
   LPTMR0->CSR |= 0x80; // clear interrupt flag

}

 

void uart1_send (void) {

   static uint8_t i = 0;

   if (i < UART_TX_BUFFER_SIZE) {

      LPUART1->DATA = buffer[i];
      i++;

      NVIC->ICPR[1] |= (1 << 1); // clear pending register for LPUART1 TX
      NVIC->ISER[1] |= (1 << 1); // set enable register for LPUART1 TX

   }
   else i = 0;

   uart_send_flag = FALSE;

}

 

void LPUART1_TX_IRQHandler(void) {

   NVIC->ICER[1] |= (1 << 1); // clear enable register for LPUART1 TX
   uart_send_flag = TRUE;

}

Outcomes