Interrupt Driven LPUART Transmits Zeros

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Interrupt Driven LPUART Transmits Zeros

Jump to solution
959 Views
pcpro178
Contributor III

I'm using the MKL17Z256VLH4 with interrupt-driven LPUART0.  When transmitting more than one byte the following bytes are always zero, regardless of what is passed to the subsequent calls of LPUART_WriteByte(), which is in LPUART_TX_RX_IRQHandler().

Here is just the transmit portion of my ISR:

if(kLPUART_TxDataRegEmptyFlag & status && (((LPUART_Type*)UART_SEL[uart])->CTRL & LPUART_CTRL_TIE_MASK))

{
    if(TxMsg[uart].pos < TxMsg[uart].length && SCI_PAR_NONE2 != TxMsg[uart].parity) {
        LPUART_WriteByte(UART_SEL[uart], TxMsg[uart].data[TxMsg[uart].pos++]); // << breakpoint here
    } else {
        // Message is sent.
        LPUART_DisableInterrupts(UART_SEL[uart], kLPUART_TxDataRegEmptyInterruptEnable);
        LPUART_EnableInterrupts(UART_SEL[uart], kLPUART_TransmissionCompleteInterruptEnable);
    }
}

I noticed that when I set a breakpoint on the call to LPUART_WriteByte() the data bytes started transmitted correctly (most of the time), so I added a software delay to see what would happen:

for (int i = 100000; i > 0; i--);
LPUART_WriteByte(UART_SEL[uart], TxMsg[uart].data[TxMsg[uart].pos++]);

The data started coming through (monitored with RealTerm), but it's inconsistent.  Clearly there is something wrong here.  I've stepped through and verified, using the expressions and memory view windows in KDS, that the data being sent to LPUART_WriteByte() is correct.  I've also connected a logic analyzer to the LPUART0 transmit and receive lines and verified that the data coming out of the micro is not correct. 

There's clearly something wrong with either the LPUART0 or my use of it.  Any insight anyone can offer would be much appreciated.

Labels (1)
0 Kudos
1 Solution
728 Views
pcpro178
Contributor III

Thanks, Mark, for the good suggestions.  It turned out that a message buffer was being shared by both the transmit and receive sides of the application (inherited code from my predecessor), and they were stomping on each other.  Modifying the code to use separate buffers for transmit and receive resolved the problem.

View solution in original post

0 Kudos
2 Replies
728 Views
mjbcswitzerland
Specialist V

Jim

I don't see anything obvious - the following is the same LPUART interrupt handler in the uTasker project (used in many KL17/KL27 products and no problems experienced):

// Generic LPUART interrupt handler
//
static __interrupt void _LPUART_interrupt(KINETIS_LPUART_CONTROL *ptrLPUART, int LPUART_Reference) // generic LPUART interrupt handler
{
    unsigned long ulState = ptrLPUART->LPUART_STAT;                      // status register on entry to the interrupt routine
..
    if (((ulState & LPUART_STAT_TDRE) & ptrLPUART->LPUART_CTRL) != 0) {  // if transmit buffer is empty and the transmit interrupt is enabled
        fnSciTxByte((QUEUE_LIMIT)LPUART_Reference);                      // transmit data empty interrupt - write next byte, if waiting
    }
..
}

fnSCITxByte() does the same as yours (feeds the next byte or disables further interrupts).

However, when I look again I would review carefully the brackets in

if(kLPUART_TxDataRegEmptyFlag & status && (((LPUART_Type*)UART_SEL[uart])->CTRL & LPUART_CTRL_TIE_MASK))

It sounds as though your interrupt may be reentering faster than you expect and thus cause you to overrun the output buffer if this were not right (check the interrupt with a port toggle at each occurrence and maybe you will have surprised - it should reenter only once per character (somewhere around the last data bit transmission).

Regards

Mark


uTasker developer and supporter (+5'000 hours experience on +60 Kinetis derivatives in +80 product developments)
Kinetis: http://www.utasker.com/kinetis.html

uTasker - for more performance and faster, cheaper product development

0 Kudos
729 Views
pcpro178
Contributor III

Thanks, Mark, for the good suggestions.  It turned out that a message buffer was being shared by both the transmit and receive sides of the application (inherited code from my predecessor), and they were stomping on each other.  Modifying the code to use separate buffers for transmit and receive resolved the problem.

0 Kudos