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;
}