LPUART interrupt driven character transmission

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

LPUART interrupt driven character transmission

2,548 Views
jacconbastiaans
Contributor III

We are writing an interrupt driven driver for the LPUART on the KL17 and KL13 (note that for several reasons, we write our own driver instead of using the driver provided by MCUxpresso).

 

For the transmission part of the driver, we want to enable the transmit interrupt (the TIE bit in the CTRL register) when there is new data to transmit. When the transmit interrupt occurs and there is no more data to send, the driver should disable the transmit interrupt again. The problem is that the CTRL register description in the LPUART chapter of the Kinetis reference manual states that “This register should only be altered when the transmitter and receiver are both disabled”. The CTRL register description also states that after setting the TE and RE bits to zero, an ongoing character transmission and reception have to finish first before the transmitter and receiver are really disabled.

 

So in order to disable the transmit interrupt in an ISR, we should:

  • Set the TE and RE in the CTRL register to zero
  • Wait until TE and RE become zero
  • Set TIE in the CTRL register to zero

 

The waiting time (2nd step) can take the time for one character to be received/transmitted which is a long time (when using a low baud rate) to spend in an ISR.

 

When looking in the driver provided by MCUXpresso (see attachment), we see that the TE and RE bits are not cleared when disabling and enabling the TIE bit in the CTRL register.

 

So our question is: under which circumstances can we enable/disable the LPUART interrupt sources? Is the manual too strict when stating that all bits in the CTRL register can only be modified when the transmitter and receiver are both disabled?

Labels (1)
12 Replies

1,991 Views
jingpan
NXP TechSupport
NXP TechSupport

Hi jaccon,

Yes, you are right!

Regards

Jing

0 Kudos
Reply

1,991 Views
jingpan
NXP TechSupport
NXP TechSupport

Hi all,

I got a new explain from support team, he said that this is just for interrupt enable/disable, don't affect LPUART configuration, so don't need to disable transmitter and receiver, will share to doc team to refine it.

thanks a lot!

Jing

0 Kudos
Reply

1,991 Views
jacconbastiaans
Contributor III

Hello Jing Pan,

Just to be sure that we understand each other correctly: are you telling here that

1) we don't need to disable the receiver and transmitter when enabling/disabling the interrupts

2) we need to disable the transmitter and receiver when we want to change the LPUART configuration (for example, change the baudrate, parity, etc.)

Can tell us whether this summary is correct or not?

Regards,

  jaccon 

0 Kudos
Reply

1,991 Views
jingpan
NXP TechSupport
NXP TechSupport

Hi Jaccon,

I checked this issue again, the answer is if  you have no more data to send, disable the transmit function(TE) and then disable interrupt. So offically the result is uncertain if you disable interrupt before disable Transmit. I think you have to get around it by some way. You can mask LPUART interrupt at that time, or wait a certain time by a timer, or DMA.

Regards

Jing

0 Kudos
Reply

1,991 Views
mjbcswitzerland
Specialist V

Hello Jing

This is very worrying - the user's manual says that both Rx and Tx need to be disabled. In practice and also in NXP examples this is never respected (and there are no known issues with doing this). But now you state that 'only' the Tx needs to be disabled.

Basically a restriction to changing interrupts masks in a peripheral during operation would indicate a major blunder in the peripheral design since it requires nasty and complicated workarounds, some of which may also not be 100% safe/possible - especially if both Tx and Rx needed to be disabled when changing something to do only with a Tx interrupt, for example.

If this is a real issue it would be best to have an explanation of WHY it is so and maybe we can then find a 100% safe work-round. For example, would using bit-banding or bit-manipulation engine accesses help?

In DMA mode it is also sometimes necessary to still use an end of transmission interrupt for the final character (so that RS485 direction control can be achieved) and if an interrupt can't be enabled during the final byte transmission (or two bytes in the case of some DMA timing) the SW workaround  is indeed very ugly indeed!

Regards

Mark

0 Kudos
Reply

1,991 Views
bobpaddock
Senior Contributor III

"(and there are no known issues with doing this)."

I'm unconvinced of that point.  As that is what I'm doing, as all other UARTs in the universe work this way as you are aware.

As I've commented before I've had problems with the KL27 LPUART.
It strangely stops transmitting and/or receiving at times, mostly Tx.  Not enough consistency to track it down.

Using same Queue code and techniques that have worked on many other micros for a long time.

I suspect LPUART problem has some connection to other unrelated things going on, on the part.
The project is doing complex sound generation via DMA with lots of timer IRQs going on, none of which are related to the LPUART.

I can say with certainty I'll never design this part into an other project because all the strange problems it has, many of which still have not been acknowledged with an errata, I2C as example.

0 Kudos
Reply

1,991 Views
mjbcswitzerland
Specialist V

Bob

This is why I am worried!

Since I support many product developments which are now using newer KL28, KL82, K66 etc., where effectively the original UARTs have been phased out and only the LPUARTs are available, I am questioning whether they all inherit a bug in a peripheral that is still used massively.


Up to now I haven't had any reports of issues but DMA based transmission is predominanty used, which may mask or reduce the effects - however there are quite a number of Modbus products that might use RS485 direction control and some DMX based (with break condition timing) where it is necessary to access the control register during the final byte transmission in order to achieve exact timing.

In all user manuals with LPUARTs this restriction is mentioned (I assumed it was just a doc error since it doesn't make sense to not be able to change an interrupt mask and all testing was OK) but now - based on latest information - it might be a doc error ("only" the Tx may need to be disabled) but it may be a truth. This is what needs to be cleared up - what exactly is the problem/effect with writing to this register during operation, which bits could still be changed without causing an effect, can it be worked around by using bit manipulation engine accesses (or bit-banding on M4 parts), etc?

Personally I don't mind if it is an errata or by design but we need to know what we are facing to ensure the quality and reliability of present and future products using these parts!

Regards

Mark

1,991 Views
bobpaddock
Senior Contributor III


Good that they are updating the docs. 

However I'm still unconvinced there is not a subtle unfound problem hiding away too bite us later in the LPUARTs.

Here is the code I use to shut down LPUART0.  Note the 'while( 0UL != LPUART0_CTRL )'. 

When I remove that my sound system using a complex mess of DMA and timers to generate sound stops working; Never let a Government Paper Pusher write technical requirements.  LPUART0 is not involved in timers nor DMA.

What is the connection?


void uart0_shutdown( void )
{
    if( 0U != ( SIM_SCGC5 & SIM_SCGC5_LPUART0_MASK ) ) /* Shutting uart off more than once will cause bus fault */
        {
            while( 0U == ( LPUART0_STAT & LPUART_STAT_TC_MASK ) ) /* Wait until transmit shift register is empty */
                {
                    nop();
                }
            LPUART0_CTRL = 0UL; /* Can only update baud when disabled */
            LPUART0_BAUD  = (
                                LPUART_BAUD_OSR( 0xFU ) | /* Reset to default value data sheet values */
                                LPUART_BAUD_SBR( 4U )
                            );
            while( 0UL != LPUART0_CTRL )
              {
                nop(); /* Read to synchronize time domains? Sound does not work if don't do this.  What is the connection to sound? */
              }
            NVIC_DisableIRQ( INT_LPUART0 );
            SIM_SCGC5 &=  ~SIM_SCGC5_LPUART0_MASK;
        }
    PORTA_PCR1 &= ~( PORT_PCR_PFE_MASK | PORT_PCR_PE_MASK | PORT_PCR_PS_MASK ); /* Clear out old setting */
    PORTA_PCR1 |=  ( PORT_PCR_PFE_MASK | PORT_PCR_PE_MASK );                    /* PullDown */
}
0 Kudos
Reply

1,991 Views
michaelheidinge
Contributor III

Like Mark I recommend to use DMA. Having good results here too.

0 Kudos
Reply

1,991 Views
jingpan
NXP TechSupport
NXP TechSupport

Hi Jaccon
Yes, I think so. Change interrupt enable/disable bit should be safty.
Regards

Jing

0 Kudos
Reply

1,991 Views
jacconbastiaans
Contributor III

Hello Jing Pan,

Just to be sure: I can change all the interrupt enable bits in the LPUART CTRL register without first having to disable the receiver and transmitter. Is this correct?

Regards,

  Jaccon

0 Kudos
Reply

1,991 Views
mjbcswitzerland
Specialist V

Hi Jaccon

I have used LPUART interrupt and DMA driven drivers (http://www.utasker.com/docs/uTasker/uTaskerUART.PDF) for a few years in many industrial products and never had a problem with adjusting the interrupt enable controls with active Tx and Rx.
It is likely that the user's manual is stating more that the mode control settings shouldn't be adjusted with enabled Rx/Tx to avoid transfer errors.

Regards

Mark

0 Kudos
Reply