UART status and TEMT interrupt

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 

UART status and TEMT interrupt

4,655 次查看
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by rkiryanov on Tue Apr 20 06:07:18 MST 2010
Hello!

To reduce power consumption I want to turn off UART after last bit transmission. It seems, that UART cannot generate such interrupt. How can I detect that last bit was transmitted? I can't read UxLSR because it clears interrupts.

Any idea? Thanks.
0 项奖励
回复
17 回复数

4,492 次查看
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by graynomad on Tue Dec 11 17:34:32 MST 2012
OK, I just got back onto this and am happy to report that it works. I've documented the problem and process as I see it here

http://ardweenet.blogspot.com.au/2012/12/nxp-wtf.html
0 项奖励
回复

4,492 次查看
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by graynomad on Mon Aug 06 01:55:15 MST 2012
Are you happy this technique is working? It's certainly non-intuitive and a stupid design.
0 项奖励
回复

4,492 次查看
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by John Sinclair on Tue Jul 31 02:31:01 MST 2012
You have only write this byte if you want an TEMT interrupt alone when the FIFO was empty. For example you want send 13 bytes and want the TEMT int on 13th byte:

[LIST]
[*]so you write first 12 bytes in fifo
[*]you get an fifo empty interrupt there you write the 13th byte
[*]the next interrupt will occur if the 13th byte was sent (fifo and transmit register are empty)
[/LIST]
0 项奖励
回复

4,492 次查看
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by graynomad on Tue Jul 31 01:34:33 MST 2012
Yes I read that, the M0 is the same. I've read it about 5 times now and it makes my brain hurt.

It seems that it will work if you only have a single byte in the FIFO but most transmissions are for more than 1 byte and if you have to wait for the FIFO to empty then put one byte in you're back to square one.

I'll go back to the data sheet and try to make sense of that paragraph.
0 项奖励
回复

4,492 次查看
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by John Sinclair on Mon Jul 30 23:03:08 MST 2012
No Register. In the manual of my M3 I found following:

Quote:
The UARTn THRE interrupt (UnIIR[3:1] = 001) is a third level interrupt and is activated when the UARTn THR FIFO is empty provided certain initialization conditions have been met. These initialization conditions are intended to give the UARTn THR FIFO a chance to fill up with data to eliminate many THRE interrupts from occurring at system start-up. The initialization conditions implement a one character delay minus the stop bit whenever THRE = 1 and there have not been at least two characters in the UnTHR at one time since the last THRE = 1 event. This delay is provided to give the CPU time to write data to UnTHR without a THRE interrupt to decode and service. A THRE interrupt is set immediately if the UARTn THR FIFO has held two or more characters at one time and currently, the UnTHR is empty. The THRE interrupt is reset when a UnTHR write occurs or a read of the UnIIR occurs and the THRE is the highest interrupt (UnIIR[3:1] = 001).

I think there implement always the same UART IP in the M0 also.
So you have only write one byte in the fifo and the THRE interrupt will occur after this byte was sent.
0 项奖励
回复

4,492 次查看
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by graynomad on Mon Jul 30 07:24:14 MST 2012
Can you elaborate a bit and tell us what you set in what register?
0 项奖励
回复

4,492 次查看
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by John Sinclair on Mon Jul 30 06:59:00 MST 2012
I have found a solution:
The Uart Fifo have a initialization conditions with a character delay in  the interrupt. So you have write only one byte in  the fifo. Through the initialization  condition the THRE interrupt will occur one byte later. In my case it works fine :-)
0 项奖励
回复

4,492 次查看
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by graynomad on Mon Jul 30 04:34:54 MST 2012
Ooo that's a bad non-feature, surely there's a better work around than "poll until the last char has gone".
0 项奖励
回复

4,492 次查看
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by John Sinclair on Mon Jul 30 02:09:01 MST 2012
Hello,

I have the same problem on LPC1778. Only to illustrate the crap:
I have 5 RS485 buses on my 5 UARTs. On every Uart I have to send every 50ms a telegram. Every telegram I have to stick the parity and wait in a while loop until the transmit register is empty. With baud rate of 9600 so it will take about 1ms in the loop, timers I don't have free. So in 100ms I will wait 2ms in a loop for one bus. For 5 buses I will wait in 100ms 10ms! This is 10% of the computing power I loss only because there don't exist a TEMT interrupt!

So I wish a new UART design too!
0 项奖励
回复

4,492 次查看
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by rkiryanov on Tue Apr 27 01:04:47 MST 2010
I have looked to UART example code:

void UARTSend(uint8_t *BufferPtr, uint32_t Length)
{
  while ( Length != 0 )
  {
      /* Below flag is set inside the interrupt handler when THRE occurs. */
      while ( !(UARTTxEmpty & 0x01) );
      LPC_UART->THR = *BufferPtr;
      UARTTxEmpty = 0;    /* not empty in the THR until it shifts out */

      BufferPtr++;
      Length--;
  }

  return;
}


compare to my code for LM3S UART:

bool UART0::PutImpl(uint_fast8_t const data)
{
    while (true)
    {
        uint8_t b;

        if (UART0FR & hw::UARTx::FR_TXFF)
        {
            return false;
        }
        else if (this->tx_.Pop(b))
        {
            UART0DR = b;
        }
        else
        {
            UART0DR = data;
            return true;
        }
    }
}


As you can see, there is no UART-feature workaround (UARTTxEmpty), program can access UART status without any affects.
0 项奖励
回复

4,492 次查看
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by rkiryanov on Fri Apr 23 22:29:21 MST 2010

Quote: simonbr
Calculating the timer period from the baudrate etc. should not be difficult.



Solution with timer looks like "first we create the problem, then heroically solve it"
0 项奖励
回复

4,492 次查看
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by simonbr on Fri Apr 23 15:20:51 MST 2010

Quote: rkiryanov
If program will put data to THR it should cancel timer.



Yes.


Quote: rkiryanov
Also, for timer period program needs free timer, remember baudrate, symbol width-format, frequency.



If you have already used up all the timers that would be a problem. Calculating the timer period from the baudrate etc. should not be difficult.
0 项奖励
回复

4,492 次查看
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by rkiryanov on Fri Apr 23 01:28:45 MST 2010

Quote: simonbr
it can setup a timer to generate an interrupt after that period has elapsed.



If program will put data to THR it should cancel timer. Also, for timer period program needs free timer, remember baudrate, symbol width-format, frequency.
0 项奖励
回复

4,492 次查看
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by simonbr on Fri Apr 23 00:40:39 MST 2010
When the THRE interrupt occurs it takes about one character period until the last character is transmitted completely. So the THRE interrupt handler can busy-wait until the TEMT bit becomes 1, or if busy-waiting is not acceptable for even this short period, it can setup a timer to generate an interrupt after that period has elapsed.
0 项奖励
回复

4,492 次查看
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by rkiryanov on Fri Apr 23 00:28:53 MST 2010
Additionally, with TEMT interrupt I can use any GPIO pin or even PCA9557 to control RS-485 direction. This is very useful on low pin count MCUs.
0 项奖励
回复

4,492 次查看
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by rkiryanov on Thu Apr 22 12:00:39 MST 2010

Quote: NXP_USA
The main code could poll the flag to determine when the last character has been sent.



Polling and WFI are not compatible.


Quote: NXP_USA
when TEMT was detected



There is [B]no TEMT interrupt[/B].


Quote: NXP_USA
A time delay dependent on the baud rate and the size of the FIFO could be used.



Too difficult and requires delays, timers... TEMT interrupt is ideal solution. Can you redesign UART?
0 项奖励
回复

4,492 次查看
lpcware
NXP Employee
NXP Employee
Content originally posted in LPCWare by NXP_USA on Thu Apr 22 10:04:17 MST 2010

Quote: rkiryanov
Hello!

To reduce power consumption I want to turn off UART after last bit transmission. It seems, that UART cannot generate such interrupt. How can I detect that last bit was transmitted? I can't read UxLSR because it clears interrupts.

Any idea? Thanks.



To save power, generally the main code should always go into WFI sleep mode whever it is not actively processing data. It will wake up with any new interrupts. If polling is needed, timer match interrupts can be set to wake the part.

Probably the safest way to go into deep sleep or deep powerdown mode is for the UART interrupt routine to set a global volatile variable when a TEMT interrupt is detected. The main code could poll the flag to determine when the last character has been sent.

Another method is: When it is time to save power, the UART interrupt routine could be responsible for putting the part into deep sleep mode when TEMT was detected. This could create re-entrancy headaches because it moves a little bit more code into an interrupt routine. For example there is probably a shutdown routine that would get called before the trip into sleep mode. That routine is likely to need to access several variables that are both read and written in the main loop. This is sometimes frowned upon as a software design style.

A time delay dependent on the baud rate and the size of the FIFO could be used.

If your application involves machine communication (instead of human interaction) then you could go to sleep after receiving an acknowledgement of your transmission through the UART from the other end.

Hope this helps!
-NXP USA Support
0 项奖励
回复