AnsweredAssumed Answered

Terminating LPUART Rx DMA with IDLE/ILIE (for variable length packets)

Question asked by Robert Poor on Jan 5, 2018
Latest reply on Jan 16, 2018 by Jing Pan

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?

Outcomes