I'm writing code to support the Modbus RTU protocol with variable-length packets. One of its distinguishing features is that the end of a packet is indicated by a gap (3.5 byte periods) in received data.
I'm working with the FRDM KL27Z dev board. I'd like to receive Modbus packets via an LPUART DMA setup, perhaps by modifying the example given in:
{sdk2.2.1}/boards/frdmkl27z/driver_examples/lpuart/dma_transfer/
Since the length of a Modbus RTU packet isn't known ahead of time, I need a way to stop the DMA at the end of the packet. My thought is to enable the LPUARTx_STAT.IDLE interrupt (by setting LPUARTx_CTRL.ILIE). When I receive that interrupt, it signifies the end of the Modbus packet, so I can stop the DMA reception in progress.
So far, I've not gotten it to work -- any pointers or examples would be welcome.
What I've tried (and what doesn't work)
I have tried adding the following to the lpuart_dma_transfer.c example:
void DEMO_LPUART_IRQ_HANDLER(void) {
LPUART_Type *base = DEMO_LPUART;
base->STAT |= LPUART_STAT_IDLE_MASK;
rxBufferEmpty = false;
rxOnGoing = false;
}main() {
...
LPUART_EnableInterrupts(DEMO_LPUART, kLPUART_IdleLineInterruptEnable);
EnableIRQ(DEMO_LPUART_IRQn);
...
}What I observe is that it calls the IRQ_HANDER repeatedly, even though I disable the IDLE interrupt. Within the interrupt, I don't see what is causing the repeated interrupt:
base->BAUD = 0x1f20000d
base->STAT = 0x00c00000
In other words, BAUD has not enabled any interrupts, and STAT indicates TDRE and TC is true but no enabled interrupts.
What am I missing?