AT91 RS485

View: New views
8 Messages — Rating Filter:   Alert me  

AT91 RS485

by Ethernut :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi all,

while trying to figure out, why the configurator option "USE HW RS485 on
UARTx" is not working, I recognized, that the entry

file = "include/cfg/uart.h"

is missing for UART0 and UART1.

Anyone else using RS485 (or half duplex) on the AT91 platform (except
Ulrich, of whom I know that he uses a specific variant)?


Harald
_______________________________________________
http://lists.egnite.de/mailman/listinfo/en-nut-discussion

Re: AT91 RS485

by András Szemző :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi Harald,

count one for me.

Andras

On Sep 4, 2009, at 10:37 AM, Harald Kipp wrote:

> Hi all,
>
> while trying to figure out, why the configurator option "USE HW  
> RS485 on
> UARTx" is not working, I recognized, that the entry
>
> file = "include/cfg/uart.h"
>
> is missing for UART0 and UART1.
>
> Anyone else using RS485 (or half duplex) on the AT91 platform (except
> Ulrich, of whom I know that he uses a specific variant)?
>
>
> Harald
> _______________________________________________
> http://lists.egnite.de/mailman/listinfo/en-nut-discussion

_______________________________________________
http://lists.egnite.de/mailman/listinfo/en-nut-discussion

Re: AT91 RS485

by Ethernut :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

András Szemző wrote:

> count one for me.

Hi Andras,

nice to have you available. If I remember correctly, you're the one who
did the first implementation, right? Either someone (me?) did not
correctly commit your patch or you are using other tricky stuff to
overcome the missing file entries in the Lua script.

If you are using any other modifications locally, I'd like to get them
into the official distribution.

Harald

_______________________________________________
http://lists.egnite.de/mailman/listinfo/en-nut-discussion

Re: AT91 RS485

by Coleman Brumley-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Harald,

I am also using half duplex RS485 on the AT91 platform.  However, I
specifically set up the registers in the CPU to do this at startup -- I
don't rely on the "USE HW RS485 on UARTx" feature.  

- Coleman

> -----Original Message-----
> From: en-nut-discussion-bounces@... [mailto:en-nut-discussion-
> bounces@...] On Behalf Of Harald Kipp
> Sent: Friday, September 04, 2009 4:37 AM
> To: Ethernut User Chat (English)
> Subject: [En-Nut-Discussion] AT91 RS485
>
> Hi all,
>
> while trying to figure out, why the configurator option "USE HW RS485
> on
> UARTx" is not working, I recognized, that the entry
>
> file = "include/cfg/uart.h"
>
> is missing for UART0 and UART1.
>
> Anyone else using RS485 (or half duplex) on the AT91 platform (except
> Ulrich, of whom I know that he uses a specific variant)?
>
>
> Harald
> _______________________________________________
> http://lists.egnite.de/mailman/listinfo/en-nut-discussion

_______________________________________________
http://lists.egnite.de/mailman/listinfo/en-nut-discussion

Re: AT91 RS485

by Ethernut :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Coleman Brumley wrote:
> Harald,
>
> I am also using half duplex RS485 on the AT91 platform.  However, I
> specifically set up the registers in the CPU to do this at startup -- I
> don't rely on the "USE HW RS485 on UARTx" feature.  

I read about problems with some RS485 level translators taking too long
to switch from receive to transmit or vice versa. The AT91 offers a
timeguard value for the latter, but not for switching back to transmit mode.

It's a kind of academic question because the driver will support
switching a GPIO anyway. I'm just curious if this is a real world
problem or just an urban legend. And I'm wondering why Atmel implemented
this timeguard at all. In RS485 mode the RTS status is tied to TXEMPTY,
which ensures, that the last character had been completely shifted out.

Harald
_______________________________________________
http://lists.egnite.de/mailman/listinfo/en-nut-discussion

Re: AT91 RS485

by Coleman Brumley-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


> -----Original Message-----
> From: en-nut-discussion-bounces@... [mailto:en-nut-discussion-
> bounces@...] On Behalf Of Harald Kipp
> Sent: Friday, September 04, 2009 11:03 AM
> To: Ethernut User Chat (English)
> Subject: Re: [En-Nut-Discussion] AT91 RS485
>
> Coleman Brumley wrote:
> > Harald,
> >
> > I am also using half duplex RS485 on the AT91 platform.  However, I
> > specifically set up the registers in the CPU to do this at startup --
> I
> > don't rely on the "USE HW RS485 on UARTx" feature.
>
> I read about problems with some RS485 level translators taking too long
> to switch from receive to transmit or vice versa. The AT91 offers a
> timeguard value for the latter, but not for switching back to transmit
> mode.
>
> It's a kind of academic question because the driver will support
> switching a GPIO anyway. I'm just curious if this is a real world
> problem or just an urban legend. And I'm wondering why Atmel
> implemented
> this timeguard at all. In RS485 mode the RTS status is tied to TXEMPTY,
> which ensures, that the last character had been completely shifted out.

It's absolutely a real world problem.  The protocol I work with, BACnet
MS/TP, has a requirement that TX enable be dropped within x milliseconds
after the last byte of a packet has be TX'd.  This timeguard setting in the
AT91 chips does that automatically so there's no polling involved in
software.  It makes life much, much easier.

>
> Harald
> _______________________________________________
> http://lists.egnite.de/mailman/listinfo/en-nut-discussion

_______________________________________________
http://lists.egnite.de/mailman/listinfo/en-nut-discussion

Re: AT91 RS485

by Coleman Brumley-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On a similar note, has anyone ever modified the Nut/OS USART driver to work
with DMA?

Is this a possible solution for the USART issues folks are reporting?  I.e.
would a USART driver in DMA mode work "faster"?

- Coleman

> -----Original Message-----
> From: en-nut-discussion-bounces@... [mailto:en-nut-discussion-
> bounces@...] On Behalf Of Harald Kipp
> Sent: Friday, September 04, 2009 4:37 AM
> To: Ethernut User Chat (English)
> Subject: [En-Nut-Discussion] AT91 RS485
>
> Hi all,
>
> while trying to figure out, why the configurator option "USE HW RS485
> on
> UARTx" is not working, I recognized, that the entry
>
> file = "include/cfg/uart.h"
>
> is missing for UART0 and UART1.
>
> Anyone else using RS485 (or half duplex) on the AT91 platform (except
> Ulrich, of whom I know that he uses a specific variant)?
>
>
> Harald
> _______________________________________________
> http://lists.egnite.de/mailman/listinfo/en-nut-discussion

_______________________________________________
http://lists.egnite.de/mailman/listinfo/en-nut-discussion

Re: AT91 RS485

by uprinz :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi!

I may bore some of the experienced guys but let me get into some detail
about USART handling especially with handshake signals.

Coleman Brumley schrieb:
> On a similar note, has anyone ever modified the Nut/OS USART driver to work
> with DMA?
>
> Is this a possible solution for the USART issues folks are reporting?  I.e.
> would a USART driver in DMA mode work "faster"?
>
> - Coleman
>
I don't think, that the problem is the speed, it's more the timing. If
you control a signal like RS485 DE/RE, then you have to take care, that
the signal is not switched in the middle of a transmitted byte.

So AVRs and others give you two transmission interrupts. One is rised if
the transmission data register is empty, but that register is only a
buffer in front of the transmission register in the background. From the
last one the bits are sent out. So we need a second signal to show us,
when the last bit (Stop-Bit) has been sent out of the background
register. Therefore we have the second interrupt, the tx-complete-interrupt.

So, whenever a byte needs to be transmitted the usart-tx routine needs
to switch from receiving to sending of the RS485 driver. Then it throws
bytes at the tx buffer registrer on every buffer register empty
interrupt. As long es this is done fast enough, an because of the double
buffering, a tx-complete-interrupt is never rising until no new bytes
are put in the buffer. If then the txc-interrupt comes, it only switches
the RS485 driver back to listen mode.

Now there are two traps:
If the chain feeding new bytes in is on low priority, the stream may
break and a txc is rised cause tx-empty was not answered fast enough.

You can avoid:
Instead of having txc-interrupt constantly on enable it right after the
last character of the queue had been put into the buffer. The USART then
will finish the actual byte and continue with the last on from the buffer.

Second trap:
Some people do driver switching if the last byte had been sent out and
the tx-empty interrupt is rised again, but no new bytes are in the
queue. This doesn't work, as no one can know, if the last bit of the
byte still in the transmission shift register has been shifted out.
Polling is a waste of time.

Another half trap is:
If you leave the tx-empty interrupt on, you'll get another interrupt if
the last byte is put from the buffer to the shift register. So you need
to detect that interrupt and handle it even you cannot do anything with it.

I am pretty sure that I saw at least one of these traps in the NutO/S
USART system. But I cannot remember in which code ( AVR, ARM, Debug).
I will stumble upon that as soon, as I have to get RS422 and RS485
working on my system until end of September.

Ok, to make it easy: Do the driver like this:
(Its pseudo code but I hope you get the idea)

SendFunction:
- sets direction of (RS4xx) driver
- puts Character to Queue
- enables TX-Empty-Interrupt (should rise directly as UDR is empty)

SendInterrupt:
- fetches character from queue
- if queue is empty then switch off TX-Empty-Irq and switch on
TX-Complete-Interrupt

TxCompleteInterrupt:
- switch direction of driver
- disable TX-Complete-Interrupt

Thats for all systems using GPIO for control of serial driver chips.

------------------------
More intelligent USARTs...
There is another thing about those chips, having hardware support for
external drivers. Here only a modified setup of the USART part of the
chip is needed. TxComplete-Interrupt handling is not needed in that
case. (It could be interesting for special bus systems requiring certain
timings though)

------------------------
HALF-DUPLEX
That's the thing what I implemented earlier for the at91. I found some
of the things mentioned above where messed up in the half duplex option
of the at91. I didn't check for AVR. Especially one thing was a problem
for me, the half duplex was mixed with the hardware handshake. The
original implementor might have thought that only someone who uses RS485
needs half duplex. I need half duplex for a flawless one-wire interface
so I had to split of hardware handshake from half duplex.

Normally you'd just send without any handshake signal. That's fine, but
you get the echo as on a one-wire bus TX and RX are coupled. That is a
fine thing, if you want to check, that your bus is not broken. But it
needs buffers for these echos and code to decide if there is something
echoed or if there is a message from another bus client. And a broken
bus can be detected by a simple timeout function.
So you'd probably like to switch the echo off.

If you followed my ideas above, you see that half duplex is exactly the
same thing like direction switching of an RS485 with out the switching.
Instead of toggling the GPIO you simply toggle the TXE and RXE control
bits of the USART. On sending out the first byte, you switch off the RX
part of the USART. After sending out the last byte you enable
TX-Complete Interrupt and that interrupt enables RX again.

-----------------------
And now there is a thing called DMA...
This is not available for ATmega but it will be for ATxmega and it is
available for other ARM based CPUs. But you have to calculate carefully.
The setup of an DMA transfer needs some code and time. I didn't do DMA
with ARM but with TI-DSP. As far as I remember you need to setup at
least six registers before the stream starts flowing.
Source Address, Destination Address, Source Incrementation Type, Target
Incrementation Type, Length and some other things.

That is a lot of code for often pushing out only one character over an
USART.
It might make sense if uart related functions can early announce their
final data length. I am not sure if puc can detect how much data the
above printf will pass on. So you might have to implement a full new
standard library function set including DMA handling.

If you have your own protocol running over an USART, then it is
something else. But then there is mostly no way to implement that in a
way that can be used by anybody. In that case, I would appreciate if
someone writes an example and passes it over to the wiki or as code into
the app/ tree.

DMA is interesting if long data fields have to be transmittet over and
over to another place. So if you wrote a display driver with a frame
buffer in RAM, it really makes sense to refresh the screen by using DMA
as this will not block the system every few milliseconds.

I know Harald is working on a new code for RS485 handling as he reverted
my addition for the no-GPIO half duplex as it is thought to be in the
normal half-duplex code. There are some other bugs in the USART code
mentioned in the mailing list so we see what he/we find.

Sorry for the long description, hope someone can use it :)

Best regards
Ulrich
_______________________________________________
http://lists.egnite.de/mailman/listinfo/en-nut-discussion