The UART/USART peripheral usually available in many microcontrollers
triggers a few interrupts. Two of them are DRE (data register empty, as
named in AVR documentation) and TXC (transmitter complete).
The first can be used to feed the TX FIFO even during shifting out the
last pushed data.
Documentation usually lacks details on these interrupts, for example
exactly WHEN they are triggered.
I made some tests on SAMD20 (from Atmel/Microchip) and LPC54628 (from
NXP) and found a difference.
When the UART isn't transmitting, the DRE flag is set because it is
possible to push some data on TX FIFO that is empty. When you enable DRE interrupt, the relevant ISR is triggered immediately because the flag is already set.
In the ISR you usually push the first data to write and return.
The first data is immediately moved to the shift register so the TX FIFO
is again empty in a very short time, so the DRE interrupt is triggered
again.
There's a subtle difference between the two MCUs above.
On SAMD21 the second DRE interrupt is triggered immediately after the
first ISR returns.
On LPC54628 the second DRE interrupt is triggered AFTER a start bit
delay. It seems the first outgoing data stays in the TX FIFO during transmission of the start bit and moved out only after that period.
LPC54628 USART has an hardware TX FIFO, but I'm not using it because I configured the peripheral to trigger DRE interrupt when TX FIFO is empty.
The behaviour of LPC54628 is interesting. It can be used to enable an external transceiver after a few dummy bytes to have a short delay in replying on the bus, allowing the sender (that could be slower) to
change its direction.
If dummy bytes are 0xFF (that appears on the wire as a start bit only),
I can enable the driver in DRE ISR when I'm ready to push the first
useful data. In this way, all the dummy bytes will not appear really on
the wire.
On SAMD20 devices this can't be done, because you would enable the
driver before the start bit of the last dummy byte, so really
transmitting it on the wire.
You need to disable DRE interrupt in the DRE ISR of the last dummy byte,
wait for TXC interrupt to enable the driver and enable again DRE
interrupt. Push all useful data in DRE ISR and, at the last, disable
again DRE and wait for TXC ISR to change again the direction of the transceiver.
pozz <pozzugno@gmail.com> wrote:
The UART/USART peripheral usually available in many microcontrollers
triggers a few interrupts. Two of them are DRE (data register empty, as
named in AVR documentation) and TXC (transmitter complete).
The first can be used to feed the TX FIFO even during shifting out the
last pushed data.
Documentation usually lacks details on these interrupts, for example
exactly WHEN they are triggered.
I made some tests on SAMD20 (from Atmel/Microchip) and LPC54628 (from
NXP) and found a difference.
When the UART isn't transmitting, the DRE flag is set because it is
possible to push some data on TX FIFO that is empty. When you enable DRE
interrupt, the relevant ISR is triggered immediately because the flag is
already set.
In the ISR you usually push the first data to write and return.
The first data is immediately moved to the shift register so the TX FIFO
is again empty in a very short time, so the DRE interrupt is triggered
again.
There's a subtle difference between the two MCUs above.
On SAMD21 the second DRE interrupt is triggered immediately after the
first ISR returns.
On LPC54628 the second DRE interrupt is triggered AFTER a start bit
delay. It seems the first outgoing data stays in the TX FIFO during
transmission of the start bit and moved out only after that period.
LPC54628 USART has an hardware TX FIFO, but I'm not using it because I
configured the peripheral to trigger DRE interrupt when TX FIFO is empty.
The behaviour of LPC54628 is interesting. It can be used to enable an
external transceiver after a few dummy bytes to have a short delay in
replying on the bus, allowing the sender (that could be slower) to
change its direction.
If dummy bytes are 0xFF (that appears on the wire as a start bit only),
I can enable the driver in DRE ISR when I'm ready to push the first
useful data. In this way, all the dummy bytes will not appear really on
the wire.
On SAMD20 devices this can't be done, because you would enable the
driver before the start bit of the last dummy byte, so really
transmitting it on the wire.
You need to disable DRE interrupt in the DRE ISR of the last dummy byte,
wait for TXC interrupt to enable the driver and enable again DRE
interrupt. Push all useful data in DRE ISR and, at the last, disable
again DRE and wait for TXC ISR to change again the direction of the
transceiver.
Thanks for interesting info. However, it is not clear why do
you want to sent dummy bytes? AFACS all you need is a little
delay and for delay I would use timer.
Il 28/03/2022 16:57, antispam@math.uni.wroc.pl ha scritto:
pozz <pozzugno@gmail.com> wrote:
The UART/USART peripheral usually available in many microcontrollers
triggers a few interrupts. Two of them are DRE (data register empty, as
named in AVR documentation) and TXC (transmitter complete).
The first can be used to feed the TX FIFO even during shifting out the
last pushed data.
Documentation usually lacks details on these interrupts, for example
exactly WHEN they are triggered.
I made some tests on SAMD20 (from Atmel/Microchip) and LPC54628 (from
NXP) and found a difference.
When the UART isn't transmitting, the DRE flag is set because it is
possible to push some data on TX FIFO that is empty. When you enable DRE >> interrupt, the relevant ISR is triggered immediately because the flag is >> already set.
In the ISR you usually push the first data to write and return.
The first data is immediately moved to the shift register so the TX FIFO >> is again empty in a very short time, so the DRE interrupt is triggered
again.
There's a subtle difference between the two MCUs above.
On SAMD21 the second DRE interrupt is triggered immediately after the
first ISR returns.
On LPC54628 the second DRE interrupt is triggered AFTER a start bit
delay. It seems the first outgoing data stays in the TX FIFO during
transmission of the start bit and moved out only after that period.
LPC54628 USART has an hardware TX FIFO, but I'm not using it because I
configured the peripheral to trigger DRE interrupt when TX FIFO is empty. >>
The behaviour of LPC54628 is interesting. It can be used to enable an
external transceiver after a few dummy bytes to have a short delay in
replying on the bus, allowing the sender (that could be slower) to
change its direction.
If dummy bytes are 0xFF (that appears on the wire as a start bit only),
I can enable the driver in DRE ISR when I'm ready to push the first
useful data. In this way, all the dummy bytes will not appear really on
the wire.
On SAMD20 devices this can't be done, because you would enable the
driver before the start bit of the last dummy byte, so really
transmitting it on the wire.
You need to disable DRE interrupt in the DRE ISR of the last dummy byte, >> wait for TXC interrupt to enable the driver and enable again DRE
interrupt. Push all useful data in DRE ISR and, at the last, disable
again DRE and wait for TXC ISR to change again the direction of the
transceiver.
Thanks for interesting info. However, it is not clear why do
you want to sent dummy bytes? AFACS all you need is a little
delay and for delay I would use timer.
Some years ago, I read the idea to use the same UART peripheral as a
"timer" to have a short delay in the reply. It is sufficient to send
some dummy bytes, but not really.
The delay must be short (otherwise bus throughput would decrease too
much), so you need a timer peripheral. Why you want to waste a timer for
this if we can use the UART?
pozz <pozzugno@gmail.com> wrote:
Some years ago, I read the idea to use the same UART peripheral as a
"timer" to have a short delay in the reply. It is sufficient to send
some dummy bytes, but not really.
Well, if there is availible hardware timer, than arguably _not_
using it is a waste. If there is shortage of timers, then
multi-purposing single timer looks like better solution.
AFAICS main disadvantage of using UART is lack of portablity
and flexibility. You are tied to specific behaviour of UART,
changing to different mode (like enabling FIFO) can break
your code. And you only get multiple of character transmit
time as delay.
Sysop: | Keyop |
---|---|
Location: | Huddersfield, West Yorkshire, UK |
Users: | 491 |
Nodes: | 16 (2 / 14) |
Uptime: | 128:04:10 |
Calls: | 9,688 |
Calls today: | 4 |
Files: | 13,728 |
Messages: | 6,177,345 |