Uart "translator" 1Mb to 921600b?

Go To Last Post
21 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Bit of a tricky one this!

 

I have two devices, and neither of them can be changed, modified or adjusted.

 

Device A puts out a TTL level UART at 1mbaud.

Device B is expecting a TTL 921600 baud UART.

 

See the problem!  ;-)

 

So bit length for device A is 1uS, and 1.085uS for device 2.  8.5% different, so too much for one baud setting to work with both.

 

How do i get device A to talk to device B?   Some buffering will be necessary, but the datastream is discontinuous and not timing critical (within reason)

 

Short of diving into an FPGA, can anyone think of a simple solution?   enlightened

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Half-duplex or full-duplex?

 

How long are "packets"?  If continuous streaming in both directions it might be to0ugh with an AVR8.

 

Xmega with fractional baud rate divisor, along with DMA?

 

CodeVision Wizard comes up with this, for an Xmega__E5 running at a 32MHz base clock:

// I/O Registers definitions
#include <io.h>

// USARTs initialization functions
#include "usarts_init.h"

// USARTC0 initialization
void usartc0_init(void)
{
// Note: The correct PORTC direction for the RxD, TxD and XCK signals
// is configured in the ports_init function.

// Transmitter is enabled
// Set TxD=1
PORTC.OUTSET=0x08;

// Communication mode: Asynchronous USART
// Data bits: 8
// Stop bits: 1
// Parity: Disabled
USARTC0.CTRLC=USART_CMODE_ASYNCHRONOUS_gc | USART_PMODE_DISABLED_gc | USART_CHSIZE_8BIT_gc;

// Receive complete interrupt: Disabled
// Transmit complete interrupt: Disabled
// Data register empty interrupt: Disabled
USARTC0.CTRLA=(USARTC0.CTRLA & (~(USART_RXCINTLVL_gm | USART_TXCINTLVL_gm | USART_DREINTLVL_gm))) |
	USART_RXCINTLVL_OFF_gc | USART_TXCINTLVL_OFF_gc | USART_DREINTLVL_OFF_gc;

// Required Baud rate: 921600
// Real Baud Rate: 920863.3 (x1 Mode), Error: 0.1 %
USARTC0.BAUDCTRLA=0x96;
USARTC0.BAUDCTRLB=((0x09 << USART_BSCALE_gp) & USART_BSCALE_gm) | 0x00;

// Receiver: On
// Transmitter: On
// Double transmission speed mode: Off
// Multi-processor communication mode: Off
USARTC0.CTRLB=(USARTC0.CTRLB & (~(USART_RXEN_bm | USART_TXEN_bm | USART_CLK2X_bm | USART_MPCM_bm | USART_TXB8_bm))) |
	USART_RXEN_bm | USART_TXEN_bm;
}

// Receive a character from USARTC0
// USARTC0 is used as the default input device by the 'getchar' function
// #define _ALTERNATE_GETCHAR_ is inserted for this purpose
// in the main program source file before #include <stdio.h>
#pragma used+
char getchar(void)
{
char data;
unsigned char status;

while (1)
      {
      while (((status=USARTC0.STATUS) & USART_RXCIF_bm) == 0);
      data=USARTC0.DATA;
      if ((status & (USART_FERR_bm | USART_PERR_bm | USART_BUFOVF_bm)) == 0) return data;
      }
}
#pragma used-

// Write a character to the USARTC0 Transmitter
// USARTC0 is used as the default output device by the 'putchar' function
// #define _ALTERNATE_PUTCHAR_ is inserted for this purpose
// in the main program source file before #include <stdio.h>
#pragma used+
void putchar(char c)
{
while ((USARTC0.STATUS & USART_DREIF_bm) == 0);
USARTC0.DATA=c;
}
#pragma used-

// USARTD0 initialization
void usartd0_init(void)
{
// Note: The correct PORTD direction for the RxD, TxD and XCK signals
// is configured in the ports_init function.

// Transmitter is enabled
// Set TxD=1
PORTD.OUTSET=0x08;

// Communication mode: Asynchronous USART
// Data bits: 8
// Stop bits: 1
// Parity: Disabled
USARTD0.CTRLC=USART_CMODE_ASYNCHRONOUS_gc | USART_PMODE_DISABLED_gc | USART_CHSIZE_8BIT_gc;

// Receive complete interrupt: Disabled
// Transmit complete interrupt: Disabled
// Data register empty interrupt: Disabled
USARTD0.CTRLA=(USARTD0.CTRLA & (~(USART_RXCINTLVL_gm | USART_TXCINTLVL_gm | USART_DREINTLVL_gm))) |
	USART_RXCINTLVL_OFF_gc | USART_TXCINTLVL_OFF_gc | USART_DREINTLVL_OFF_gc;

// Required Baud rate: 1000000
// Real Baud Rate: 1000000.0 (x1 Mode), Error: 0.0 %
USARTD0.BAUDCTRLA=0x80;
USARTD0.BAUDCTRLB=((0x09 << USART_BSCALE_gp) & USART_BSCALE_gm) | 0x00;

// Receiver: On
// Transmitter: On
// Double transmission speed mode: Off
// Multi-processor communication mode: Off
USARTD0.CTRLB=(USARTD0.CTRLB & (~(USART_RXEN_bm | USART_TXEN_bm | USART_CLK2X_bm | USART_MPCM_bm | USART_TXB8_bm))) |
	USART_RXEN_bm | USART_TXEN_bm;
}

// Receive a character from USARTD0
#pragma used+
char getchar_usartd0(void)
{
char data;
unsigned char status;

while (1)
      {
      while (((status=USARTD0.STATUS) & USART_RXCIF_bm) == 0);
      data=USARTD0.DATA;
      if ((status & (USART_FERR_bm | USART_PERR_bm | USART_BUFOVF_bm)) == 0) return data;
      }
}
#pragma used-

// Write a character to the USARTD0 Transmitter
#pragma used+
void putchar_usartd0(char c)
{
while ((USARTD0.STATUS & USART_DREIF_bm) == 0);
USARTD0.DATA=c;
}
#pragma used-

You can noodle yourself for other clock speeds.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

Last Edited: Thu. Jul 6, 2017 - 08:11 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

Use an MCU with two or more UARTs. Each can have independent baud rate. Several AVRs have this.

 

You will want two buffers. One for A-receive to B-transmit and one for B-receive to A-transmit. Probably best to configure them as circular.

 

Jim

 

Until Black Lives Matter, we do not have "All Lives Matter"!

 

 

Last Edited: Thu. Jul 6, 2017 - 08:01 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

2 AVR with UART, one with 16MHz clock, second with 14.745 MHz and SPI or TWI in between.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

A single oscillator forces the use of fractional baud rate divisors, what's the simplest IC that has this?  Has to be an Xmega?

 

Two "back to back" AVRs with different rate xtals is possible, but feels like  bit of  a bodge to me  lol!

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I give up.  I proposed a $2-$3 solution (ATxmaga8E5).  I'm not an Xmega expert, but if feasible the experts in that forum could tell you how to set up the DMA so no code is needed for each character.

 

Even if you need to take the RX from one USART and dump it into the TX buffer for the other USART, I'd think you should be able to keep up in all but the most pathological of conditions.

 

I give up because you come back and talk of "back-to-back AVRs", without answering any of the questions about direction or "packet" size.  If you are doing AVR8 work now, I'd think you already had a toolchain that could do Xmega.  (I guess ISP could be a consideration.)  Otherwise, pick whatever solution you want.  921600 works well with magic clock frequencies but 1M doesn't.

 

 

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

MAX3107 SPI/I²C UART

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Did you read my response?

 

I suggested, it seems in line with your comments, that two "back to back" AVRs was a "bit of a bodge"!

 

 

My question was, is the ATxmega8E5 the simplest / cheapest option?  tbh, i'm not really up with the latest Atmel chips.  I tend to use "old skool" AVRS like Mega32 for simple stuff, then just jump up to ARMs for anything else!

 

 

Packet size is a max of 256 bytes (that's the size of the TX buffer i'm lead to believe in device A)  i think, broadcasting bursts every 50ms of so (not sure of this)

 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

max_torque_2008 wrote:
then just jump up to ARMs for anything else!

Then why not use an ARM?!?

 

Define "simplest" and "cheapest".  '8E5 is a few bucks in qty. 1.  Mega88Pa maybe a buck less.  Both much less than a Mega32; Mega32A is a buck more.  Mega32 only has a single USART.  Mega164A/PA has two, anc costa about 3 bucks.   [I don't know of any AVR that has separate baud rate registers for TX and RX]  Simplest?  Mega32 is a 40/44 pin chip.  Requires external clock above 8MHz.  '8E5 is 32 pins, and has internal 32MHz clock.

 

And is the communication in one direction or both?

 

The new Tiny family n14/n16/n17 has fractional baud generator, but only a single USART.

 

 

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

Last Edited: Thu. Jul 6, 2017 - 08:55 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Well to add another spanner in the works, both devices, being a bit old, are 5v TTL, so a 5v solution would be handy!

 

(i know i forgot to say that in my original post, sorry!)

 

Pretty sure i'm going to have to use an external xtal, as device will need to operate up to 85degC, which tends to run out internal Oscs, due to thermal drifts

 

tbh, i think the Xmega8E5 is probably the best answer.  Not a chip ive used before, which always increases the chances of a first attempt messup of course!

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Are you going to answer my questions? [remaining is direction]

 

Xmega are not 5V parts.

 

If you have an ARM toolkit, then go for it.  ATSAMC20E are 5V parts, four USARTS, 32-pin, and cost a couple bucks.

 

 

 

 

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Full duplex coms

 

although around 90% more bytes going 1Mb -> 921kb  and just 10% going 921kB -> 1Mb

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

max_torque_2008 wrote:

Full duplex coms

 

although around 90% more bytes going 1Mb -> 921kb  and just 10% going 921kB -> 1Mb

 

That's still not enough info.

What block/burst size & gaps are there ? - as clearly continual 1Mb -> 921k will not work.

 

As mentioned, if you want one device, you need fractional baud, dual UART silicon.

 

If the 5V parts cannot tolerate 3v3 levels, (you can do 5V -> 3v3 direction with resistor divider), you need a 5V part, or level shifters.

 

5V ARMs come from Atmel, Cypress, NXP, Nuvoton, Infineon, Zilog....  Pick one you are most familiar with.

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

You can split the difference with an AVR running at 15.36MHz (which seems to be a standard crystal freq.)  That might be enough?

I designed this little "Serial Munger" board based on an ATtin1634 (two UARTS!) with applications like this in mind.  It hasn't been tested yet, so I haven't published the design files, but you're welcome to them if you're willing to take the risk...

~4Mbps worst-case burst rate is a lot to ask from an AVR, though.

https://hackaday.io/project/1976...

 

Other than that, there are the SAMD09 series - I think they can be set up with two fractional BRG USARTs...

 

 

2 AVR with UART, one with 16MHz clock, second with 14.745 MHz and SPI or TWI in between.

 Or some sort of parallel port(s)...  The bi-directional requirement makes these more complicated.  And note that TWI doesn't (at least in theory) do 1Mbps.

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Xmc2go - $7.18usd at digikey. Ecc on flash, parity on ram. 5V. arduino support although the Serial class might need some tweaking for dual uart.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Change of plan!  We are just going to replace the 921600 device!  (and make one that accepts the exisiting 1Mbaud stream......)

 

(ie no point putting loads of effort in to a custom bridge to make an obsolete device continue to work, when we can just design a new device for less effort that does what we want!  ;-)

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

How about keeping the old device but just putting an 8% faster crystal in it?

Doing magic with a USD 7 Logic Analyser: https://www.avrfreaks.net/comment/2421756#comment-2421756

Bunch of old projects with AVR's: http://www.hoevendesign.com

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

max_torque_2008 wrote:
Change of plan! We are just going to replace the 921600 device! (and make one that accepts the exisiting 1Mbaud stream......) (ie no point putting loads of effort in to a custom bridge to make an obsolete device continue to work, when we can just design a new device for less effort that does what we want! ;-)

As always, it depends.  For example, how many of the beasties are there?  how far into the future do you plan for (to keep these lecacy systems operational)?

 

From the symptoms, the two devices do NOT communicate now?

 

If only a few, like inhouse production equipment, say, then (as mentioned above) a handful of ready-made GP "demo" boards with a suitable processor can be quite attractive.  If you or someone there is familiar with the architecture and you have a toolchain, the app in the end will be nearly trivial.

 

 

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

westfw wrote:

You can split the difference with an AVR running at 15.36MHz (which seems to be a standard crystal freq.)  That might be enough?

I thought about that when noodling with clock speeds earlier.  Did you use a tool, or just trial-and-error to come up with 15.36?

 

~4% off on each side, indeed.  Will UARTs be comfortable with that?

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

What kind of data do you want to send, and how fast?

 

If you only use 4 bit (4 lsb) and let the rest be 1's , a 921000 UART can receive 1M baud correct.

 

add:

set the transmitter to 2 stop bit

Last Edited: Fri. Jul 7, 2017 - 08:38 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

 

>> You can split the difference with an AVR running at 15.36MHz

 

I thought about that when noodling with clock speeds earlier.  Did you use a tool, or just trial-and-error to come up with 15.36?

I used the wormfood calculator, and trial-and-errored it...

 

~4% off on each side, indeed.  Will UARTs be comfortable with that?

 It's hard to say, IIRC 5% is supposed to the the limit, for UARTS that sample in the exact middle of bit.  I think if both ends are exactly the described bitrate, and crystal controlled, and use moderately standard UARTs, then it will "probably" work.  If one of the sides is only "close", or is using an internal (low-accuracy) oscillator, I'd be pretty nervous.  In retrospect, I'm more concerned about being able to process that much data, even assuming no UART errors.