Jump to content
43oh

MSP430F550x based USB - UART bridge


Recommended Posts

I am working on SBW programmer, with 2 CDC ports. First port will be used for programmer itself, and second will be USB UART bridge without any relation to programmer. On this topic I will published also bridge as standalone solution without programmer.

Target is to come close with performance to bridge chips (PL/FT/CP) at higher baud rate (921600 bps) with big at-once transfer. Of course, performance with few-bytes transfer will be pore, because MSP430F550x bridge will rely on standard CDC OS drivers that can not compete with dedicated driver solutions from bridge chips producers.

MSP430F550x bridge will support:
- any baud rate (probably till 1 Mbps), for example 123456 bps, 654321 bps...
- 7/8 bit character length
- no/odd/even parity
- 1/2 stop bit

Anyway, bridge chips are working better, and they are cheaper than MSP430F550x, but just want to show that MSP430F550x can also be used for this purpose without problems.

Bridge example from original TI USB stack is not very useful, and form my point of view, it is showing the way how things not to be done.

Link to post
Share on other sites

Just to have some orientation to transfer speed, I used 2 bridge adapters based on PL2303HX chip connected with rs232 together.

adapter1  conn  adapter2
TXD ---------------- RXD
RXD --------------- TXD
CTS --------------- RTS
RTS --------------- CTS

Without RTS/CTS connection it will not work with standard Win32 API WriteFile/ReadFile commands.

Here are some PL2303HX benchmark results for big at-once transfer:

 64 KB @ 115200 bps  Time 5766 ms  Rate 11 KB/s
128 KB @ 460800 bps  Time 2922 ms  Rate 45 KB/s
256 KB @ 921600 bps  Time 3015 ms  Rate 87 KB/s

 

PL2303HX chips can work on much higher transfer speed, but one of adapters that I heave is limited with Sipex 323 chip and can not go higher than 1 Mbps. Anyway, reached results for higher rate: 1228800 bps 113 KB/s.

Link to post
Share on other sites

Haha!  Very accurate.  I assume you've implemented a timeout to flush the buffer.

 

Now, working on UART -> CDC side, and it will be hardest coded part in complete SBW programmer project. Making something like TI example, to exchange characters after pressed keyboard key between 2 terminal application is one thing, and making real bridge to work at 1228800 bps without any problems is something else.

Link to post
Share on other sites

Easier part, MSP430 CDC -> UART side is done, and it is working OK. It is used OEP without double buffering, but with toggling 2 address/pointers (USBOEPBBAX). Code is fast enough, without impact on requested baud rate.

Here are the results for MSP430 -> PL2303 uart transfer:

512 KB @  921600 bps  Time 5672 ms  Rate  92 KB/s
512 KB @ 1228800 bps  Time 4266 ms  Rate 123 KB/s
512 KB @ 1500000 bps  Time 3485 ms  Rate 150 KB/s


Even it is specified in datasheet, and can be found on web, that MSP430 maximum baud rate is around 1 Mbps, didn't have any problems with testing till 1.5 Mbps. Going over this value cause transfer failures.

Link to post
Share on other sites

Now, working on UART -> CDC side, and it will be hardest coded part in complete SBW programmer project. Making something like TI example, to exchange characters after pressed keyboard key between 2 terminal application is one thing, and making real bridge to work at 1228800 bps without any problems is something else.

If you have an architecture loosely based on TI's library, just set the RX timer for ~50us each time you service the X/Y buffer or get the data detection event.  If the timer expires, it means the stream has stopped before the Y/X buffer (respectively) has filled.  I can tell you for certain that this strategy works (I have no benchmarks, but for transfers that are multiples of 64 bytes, there is no overhead).  You'll need also to send a stall command while waiting for the UART to finish, but I'm sure you knew that already.

Link to post
Share on other sites

If you have an architecture loosely based on TI's library, just set the RX timer for ~50us each time you service the X/Y buffer or get the data detection event.  If the timer expires, it means the stream has stopped before the Y/X buffer (respectively) has filled.  I can tell you for certain that this strategy works (I have no benchmarks, but for transfers that are multiples of 64 bytes, there is no overhead).  You'll need also to send a stall command while waiting for the UART to finish, but I'm sure you knew that already.

 

My way has nothing in common with TI example. I am not using double buffering and DMA, because this will not improve anything. Timeout is not the problem because it is automatically calculated based on baud rate. With 24 MHz SCLK, and serial transfer of 10 bits (1 start bit, 8 data bits, 1 stop bit) it is close to:

115200 bps  ~  (10 bit / 115200 bps) = 86.806 us  ~  TAxCCR0 = (24 MHz * 86.806 us) = 2083
921600 bps  ~  (10 bit / 921600 bps) = 10.851 us  ~  TAxCCR0 = (24 MHz * 10.851 us) = 260

 

First algorithm was based on collecting uart RX bytes in (circular) buffer (256 bytes). Than (part of) this buffer was copied to IEP buffer, and flushed with 64 bytes length or less bytes with timeout. Problem was on higher baud rate (1228800 bps), because it was not fast enough.

 

Second algorithm was based on writing RX bytes directly to IEP buffer. With this one, problem was not in speed, but in too short buffer lenght (2 * 64 bytes), and USB was not having enough time (on higher baud rate) to accelerate (starting of few first packets).

 

Now am I working on algorithm that is combination of this two, writing directly (with skipping) to big IEP buffer (1 KB), and flushing it with packets of 64 bytes, or less if timeout is reached.

Link to post
Share on other sites

I was playing few years ago with DS89C450 uart at high baud rate. Formula for baud rate was BR = SCLK / 16. With 32 MHz SCLK (8 MHz Quartz) it was able to transfer data at 2000000 bps, and overclocked to 40 MHz (10 Mhz Quartz) at 2500000 bps. It have only one common byte for TX/RX buffer (not two separate bytes like MSP430), but it was able to transfer data to/from PC (over PL2303HX bridge) at high rate without problems.

I was little disappointed when I found datasheet info about 1 Mbps limitation for MSP430. Fortunately, it can go much higher. Today I made uart ping-pong test for send/receive big data size at once. I used my 2 MSP430F550x based bridges. Both boards are diy p2p (one with MSP430F5508, and another with MSP430F5510), with same 24 Mhz Quartz (same batch). I connected UCA1RXD/UCA1TXD lines (crossed, from one to another board) with short wires over 100 Ohm resistor. Algorithm for calculating BR/MCTL dividers was same on both sides, with same results, so basically error for uart transfer was close to zero. Result is here:

2048 KB @ 2500000 bps  Time 8312 ms  Rate 252 KB/s

 

So, MSP430F550x uart can work at 2.5 Mbps like overclocked DS89C450, without problems. After going upper with baud rate, transfer was failing. Not sure if the reason for this is in USCI itself, or my bridge code limitation.

Link to post
Share on other sites

Maybe I'm getting confused with something else.  Anyway, most UARTs do a 16x oversample on the data, therefore the clock is expected to be 16x the data rate.

 

SCLK is directly sourced (/1) from 24 Mhz XT2. XT1 is not used. Don't know about MSP430F550x UART internals (and don't care), but it can work on higher baud rates (2.5 Mbps) than it is specified in datasheet (1 Mbps) without problems. I made benchmark for sending to/from UART 2 MB of non-dummy data, where receiver was checking received data. If even one received byte (from 2 MB block) was wrong (different than expected), benchmark program will display error info about this. Also if received size is different from sent size (2 MB), again error will be displayed.

 

When I completely finish bridge software, I will made final benchmark, and will put results here.

Link to post
Share on other sites

Didn't found much regarding topic, on web. There is USB UART bridge example from TI (CC1 from TI USB stack). Another one is from Atmel. Nothing special, but if somebody want to see it:

 

AVR272: USB CDC Demonstration: UART to USB Bridge, on megaAVR with USB

http://www.atmel.com/Images/doc7602.pdf

http://www.atmel.com/Images/AVR272_USB_CDC_Virtual_Com_Port.zip
 

Link to post
Share on other sites
  • 8 months later...

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...