Shop OBEX P1 Docs P2 Docs Learn Events
Fastest Serial Speed? — Parallax Forums

Fastest Serial Speed?

SteelSteel Posts: 313
edited 2007-07-04 07:14 in Propeller 1
I just came over to the Propeller from the SX controller.

On the SX Controller, I was able to run Serial data (uart) at 1MB/s.

On the propeller, It seems that the fastest normal baudrate that I am able to run is at 115.2kB/s.
I have tried the FullDuplexSerial Object, and I have tried just using ·pin toggles in SPIN, but I am not able to get close to the Serial speed of the SX.

Is there something I am missing?·

Shaun

Comments

  • Mike GreenMike Green Posts: 23,101
    edited 2007-07-03 17:46
    The fastest asynchronous serial in Spin has been reported as somewhat over 19.2KBaud half duplex. Full duplex Spin routines would come out under 9600 Baud although none have been written yet. The FullDuplexSerial routines have been tested around 230KBaud. A number of compromises were made on speed to get full duplex with only one cog.

    I have some assembly SPI routines that are part of FemtoBasic that could easily be modified to transmit or receive half duplex asynchronous serial data at well over 1MBaud, probably closer to 2MBaud. Two cogs would get you full duplex at that rate.

    Synchronous serial (SPI) can be done several times faster using one of the cog counters to generate the clock. Have a look at Rokicki's fast assembly low level driver for SD cards.

    Post Edited (Mike Green) : 7/3/2007 5:51:58 PM GMT
  • SteelSteel Posts: 313
    edited 2007-07-03 18:12
    I may be a bit confused. I would think that even when I am doing a 'bit-banged' UART command such as below when the clock speed is 80MHz, it should be running at a decent speed. (as the SX is running at 50MHz):

    I guess I was thinking that these instructions took the least amount of clock cycles. Are the cogs running at slower speeds than the system clock?

    Sorry if I am asking questions that seem wierd...I just want to see about replacing the SX in my current system with the propeller with minimal re-design...I am working with technology that requires 750k Baud speed.


    'Initialize line
    DIRA[noparse][[/noparse]30]~~
    OUTA[noparse][[/noparse]30]~~

    'Add Start Bit
    OUTA[noparse][[/noparse]30]~
    WAITCNT(CLKFREQ/ [noparse][[/noparse]bit-time] + CNT

    'Add Data Byte - $AA
    OUTA[noparse][[/noparse]30]~
    OUTA[noparse][[/noparse]30]~~
    OUTA[noparse][[/noparse]30]~
    OUTA[noparse][[/noparse]30]~~
    OUTA[noparse][[/noparse]30]~
    OUTA[noparse][[/noparse]30]~~
    OUTA[noparse][[/noparse]30]~
    OUTA[noparse][[/noparse]30]~~

    'Add Parity and stop Bit
    OUTA[noparse][[/noparse]30]~~
    WAITCNT(CLKFREQ/ [noparse][[/noparse]bit-time] + CNT
    OUTA[noparse][[/noparse]30]~~
    WAITCNT(CLKFREQ/ [noparse][[/noparse]bit-time] + CNT
  • rokickirokicki Posts: 1,000
    edited 2007-07-03 18:44
    Sending at any speed up to about 8MBaud should be no trouble at all (but remember you
    can only transition pins at 12.5ns points unless you use the video circuitry with a PLL
    which is very tricky). So 1MB sending should be easy; each bit is just two
    instructions, a shift of a PHSA register to set an output bit and a waitcnt to wait a
    bit period (you'd have to precompute the waitcnt values and they may not all be the
    same width so you could get maximum accuracy).

    Receiving is a *lot* trickier because you cannot afford to miss a start edge, and you
    only have the stop bit period (and half of the last data bit period) to save out the
    most recent byte somewhere and prepare to wait for the next start bit. 1.5 bit
    periods at 1MHz is 1.5us which is 30 instructions which should make it possible.

    For speeds that fast you'd need one cog for receiving and a separate cog for
    sending since during any period you're sending, you'd miss the start bit (except
    you *could* do tricks with counters to assess when the start bit actually occurred).

    Heck, as a matter of fact, you could probably do some pretty amazing hacks
    by just using a counter in increment-when-hi mode to monitor the stream and
    then interpret the counts appropriately to locate the edges. Hmm.

    Do you need fullduplex? Sending and receiving at the same time? It's the *async*
    that gives the problem (you need to be prepared for a certain amount of
    inaccuracy in the widths, and you need to be ready for that start bit at any time.)
  • Mike GreenMike Green Posts: 23,101
    edited 2007-07-03 18:51
    You have written Spin instructions which get compiled into byte codes that are interpreted. The interpreter is what is running in a cog. Although it is quite efficient, it only executes a byte code instruction perhaps once every 3-5us. The native instruction set is much faster. Most instructions execute in 50ns. Here, for example, are the low level SPI routines in FemtoBasic:
    '' Low level byte I/O
    
    spiSendByte      mov     i2cMask,#%10000000
    :sendBit            test    i2cMask,i2cData    wc
                            andn    outa,spiMaskClk         ' Send data bytes MSB first
                            muxc    outa,spiMaskDI
                            or      outa,spiMaskClk
                            shr     i2cMask,#1              ' When mask shifted out, we're done
                            tjnz    i2cMask,#:sendBit
                            or      outa,spiMaskDI          ' Leave DI in idle (high) state
    spiSendByte_ret         ret
    
    spiRecvByte      mov     i2cMask,#%10000000
    :recvBit            andn    outa,spiMaskClk         ' Receive data bytes MSB first
                            or      outa,spiMaskClk         ' Copy DO to data bit
                            test    spiMaskDO,ina      wc     
                            muxc    i2cData,i2cMask
                            shr     i2cMask,#1              ' When mask shifted out, we're done
                            tjnz    i2cMask,#:recvBit
                            and     i2cData,#%11111111      ' Eight bits received
    spiRecvByte_ret         ret
    
    


    The transmit routine takes about 350ns per bit for the 8 data bits and clock. There's a bit more overhead calling these routines, fetching or storing the data itself, including parity / start / stop bits, etc. The overhead per bit in doing the clock would probably be about the same in doing the bit timing for the desired Baud.
  • HannoHanno Posts: 1,130
    edited 2007-07-04 07:14
    Hi,
    Viewport v1.1, available here:
    http://mydancebot.com/products/viewport/11
    transfers data between pc host and propeller at 2Mbps using a single cog. The FTDI chip supports up to 3Mbps, but we were happy with 2, the next fastest setting. We are doing full duplex- data is typically sent from the Propeller to the PC for analysis, but data can also be sent the other direction (concurrently) to change memory values. It was not easy!
    Hanno
Sign In or Register to comment.