EmbeddedRelated.com
Forums
Memfault State of IoT Report

USART and Interrupt nesting

Started by Eric Pasquier January 24, 2007
I am using an AT91SAM7S256.
I do have some dificulties in reading the documentation about USART
and interrupts :

1) what is the difference between TXRDY and TXEMPTY interrupt/status ?

2) the documentation is very clear about nested interrupt in AIC, but
not about what is happening in this case :

- I have a bidirectional comunication in progress with TX and RX
interrupts enabled.
- RXRDY interrupt occurs meaning that a new character is available to
read.
- As the interrupt routine is the same, I have to check the bit in
US_CSR to determine the interrupt case. The reading of this register
should be done once, as it resets the RXRDY status.
- Then, the Transmitter just finished, and I supposed, is setting
TXRDY bit in US_CSR

In this case, does the USART is going to place a new Interrupt Request
after the end of the RXRDY interrupt ?

Thks,
Eric
Hi Eric
> 1) what is the difference between TXRDY and TXEMPTY interrupt/status ?

AFAIK, TXEMPTY means the shifter register is empty. TXRDY means, the
FIFO is empty (and the shifter is still sending).

If you wait for TXEMPTY, you'll get a gap between bytes on the line.

--
42Bastian
Does anybody have an idea of the behavior in this case (nested interrupt from the same peripheral) ?
Eric.

I am using an AT91SAM7S256.

The documentation is very clear about nested interrupt in AIC, but
not about what is happening in this case :

- I have a bidirectional comunication in progress with TX and RX
interrupts enabled.
- RXRDY interrupt occurs meaning that a new character is available to
read.
- As the interrupt routine is the same, I have to check the bit in
US_CSR to determine the interrupt case. The reading of this register
should be done once, as it resets the RXRDY status.
- Then, the Transmitter just finished, and I supposed, is setting
TXRDY bit in US_CSR

In this case, does the USART is going to place a new Interrupt Request
after the end of the RXRDY interrupt ?

Thks,
Eric
On Wednesday 24 January 2007 22:46, 42Bastian Schick wrote:
> Hi Eric
>
> > 1) what is the difference between TXRDY and TXEMPTY interrupt/status ?
>
> AFAIK, TXEMPTY means the shifter register is empty. TXRDY means, the
> FIFO is empty (and the shifter is still sending).

Correct.

>
> If you wait for TXEMPTY, you'll get a gap between bytes on the line.

In general:
you'd use the TXRDY as a way to feed more data into the UART since this
maintains full speed transfer.
you typically only use TXEMPTY when you want to do something after all the
data has been sent down the wire. eg. this is often used with RS485 to flip
from TX to RX mode after a transfer.
Eric

> Does anybody have an idea of the behavior in this case (nested interrupt
> from the same peripheral) ?

Unless you do not write the EOICR AIC will not allow an interrupt of
the same peripheral, only of a higher priority if you clear the I bit in
PSR.
Though it might of coure be pending, and as soon as you leave your
interrupt it'll re-enter, but this is normal behaviour.

--
42Bastian
I thought a lot about it and I think I found the answer.
I personally think that the Interrupt signal from the peripheral is an OR of
the status bits.
As long as you program the AIC in level sensitive mode, it will place a new
IRQ after serving the first one.
That's why it is very important to read the Status field only once, treat
all the cases, and "resets" the corresponding bits to clear the Interrupt
Signal.

I would apreciate a confirmation from some one from Atmel.

Thanks all about your comment about the 2 TX interrupts.
It's now clear for me which one to use.

Eric.
----- Original Message -----
From: "42Bastian Schick"
To:
Sent: Thursday, January 25, 2007 7:33 AM
Subject: Re: [AT91SAM] USART and Interrupt nesting
> Eric
>
>> Does anybody have an idea of the behavior in this case (nested interrupt
>> from the same peripheral) ?
>
> Unless you do not write the EOICR AIC will not allow an interrupt of
> the same peripheral, only of a higher priority if you clear the I bit in
> PSR.
> Though it might of coure be pending, and as soon as you leave your
> interrupt it'll re-enter, but this is normal behaviour.
>
> --
> 42Bastian
2007/1/24, Eric Pasquier :
>
> 1) what is the difference between TXRDY and TXEMPTY interrupt/status ?
>
TXRDY report that THR is empty (but shift register is working),
TXEMPTY report that even the shidt register is empty.
Usually you use the first interrupt to refill the THR register till
you have chars to send and then you fall in the TXEMPTY condition and
close the tx (for ex. you disable tx interrupt).

> 2) the documentation is very clear about nested interrupt in AIC, but
> not about what is happening in this case :
>
> - I have a bidirectional comunication in progress with TX and RX
> interrupts enabled.
> - RXRDY interrupt occurs meaning that a new character is available to
> read.
> - As the interrupt routine is the same, I have to check the bit in
> US_CSR to determine the interrupt case. The reading of this register
> should be done once, as it resets the RXRDY status.
> - Then, the Transmitter just finished, and I supposed, is setting
> TXRDY bit in US_CSR
>
> In this case, does the USART is going to place a new Interrupt Request
> after the end of the RXRDY interrupt ?
>
What I do (copied from others forum posting) is to read the CSR value
in a variable and test TXRDY and RXRDY bits on this variable because
your isr routine can be called with both bit set...

volatile INT32U u32UsartStatus;
volatile AT91PS_USART pUsart = AT91C_BASE_US0;

u32UsartStatus= pUsart->US_CSR & pCryptoUart->US_IMR;

if (u32UsartStatus& AT91C_US_TXRDY) {
...
}

if (u32UsartStatus& AT91C_US_RXRDY) {
...
}

best regards
Pietro
On Thursday 25 January 2007 22:23, Eric Pasquier wrote:
> I thought a lot about it and I think I found the answer.
> I personally think that the Interrupt signal from the peripheral is an OR
> of the status bits.
> As long as you program the AIC in level sensitive mode, it will place a new
> IRQ after serving the first one.
> That's why it is very important to read the Status field only once, treat
> all the cases, and "resets" the corresponding bits to clear the Interrupt
> Signal.
>
> I would apreciate a confirmation from some one from Atmel.
>
> Thanks all about your comment about the 2 TX interrupts.
> It's now clear for me which one to use.

I am not from Atmel, but I can confirm a few points, having used these devices
in many products:

1) You **must** issue the EOICR cclearing command to confirm that you have
done with this interrupt. If you don't then interrupts of the same or a lower
interrupt will not proceed.

2) If you use interrupt nesting, then the interrupt handling sequence is
different. Because of the way interrupts are handled in ARM, you can only
have one thread of execution in the interrupt context. Therefore, for any
nesting to work, you need to switch to system context, then back again later.
For an example, look at how irq_wrapper_nested is used in
http://lejos.svn.sourceforge.net/viewvc/lejos/trunk/nxtvm/platform/nxt/irq.s?revisionh&view=markup

3) The way you treat varius peri[pherals is dependent on the peripheral. In
some cases when you read the status register it clears all bits. In some
cases the status register just reflects a current hardware state.

For the last 20 or so years, using many different devices, I have handles
UARTs in pretty much the same way and, except on a few devices with broken
UARTs, I have not had to change the way I do things. See:
http://lejos.svn.sourceforge.net/viewvc/lejos/trunk/nxtvm/platform/nxt/uart.c?revision#7&view=markup

I just use a while loop that keeps going while there are bits I am interested
in.

In most cases level sensitive interrupts are the way to go, and definitely are
for UARTs. If you use edge sensitive processing for a UART you are likely to
miss an edge and then the UART will just get "stuck" and not do any more
processing.

The only time I recommend using edges is when you're using an external
interrupt pin and truely are looking for edges.

>
> Eric.
> ----- Original Message -----
> From: "42Bastian Schick"
> To:
> Sent: Thursday, January 25, 2007 7:33 AM
> Subject: Re: [AT91SAM] USART and Interrupt nesting
>
> > Eric
> >
> >> Does anybody have an idea of the behavior in this case (nested interrupt
> >> from the same peripheral) ?
> >
> > Unless you do not write the EOICR AIC will not allow an interrupt of
> > the same peripheral, only of a higher priority if you clear the I bit in
> > PSR.
> > Though it might of coure be pending, and as soon as you leave your
> > interrupt it'll re-enter, but this is normal behaviour.
> >
> > --
> > 42Bastian
> >
> >
> >
> >
Hi

We're finding our code sometimes in the abort handlers pabort_handler and
dabort_handler and can't work out what is going on.

We're using CrossWorks (based on GCC) and a AT91SAM7S256. Looking at the
ARM7TDMI technical reference manual, these look like a prefetch abort and
data abort.

Does anyone have any tips for working out why they occur? Is it
possible/easy to find out what caused the abort (other than single-stepping
through the code)? Ie inspecting something afterwards to work out why.

Regards
Peter
On Thursday 01 February 2007 18:23, Peter McConaghy wrote:
> Hi
>
> We're finding our code sometimes in the abort handlers pabort_handler and
> dabort_handler and can't work out what is going on.
>
> We're using CrossWorks (based on GCC) and a AT91SAM7S256. Looking at the
> ARM7TDMI technical reference manual, these look like a prefetch abort and
> data abort.
>
> Does anyone have any tips for working out why they occur? Is it
> possible/easy to find out what caused the abort (other than single-stepping
> through the code)? Ie inspecting something afterwards to work out why.

As Eric has answered. a pabt happens when you are attempting to fetch code
from an illegal address and a dabt happens when you are trying to fetch/write
data from an illegal address.

In both cases, you get this problem due to having a bad pointer of some sort,
typically caused by:
1) Overrun etc trashing pointers.
2) Uninitialised pointers.
3) Stack trashing. Then return addresses etc can be trashed.

Finding dabts is quite often pretty simple because you tend to have a valid pc
and address.

Finding pabts is often a bit more challenging because you often have already
driven over the edge.
You can write a full data/prefix abort handler, but the AT91SAM provides some
help.

I suggest you have a look at the data abort handler in data_abort.c and init.s
in http://lejos.svn.sourceforge.net/viewvc/lejos/trunk/nxtvm/platform/nxt/

Once you have a PC you can find the offending code with adr2line or whatever.

-- Charles

>
> Regards
> Peter

Memfault State of IoT Report