Shop OBEX P1 Docs P2 Docs Learn Events
BS2: SEROUT/SERIN at 38400 easy-peasy — Parallax Forums

BS2: SEROUT/SERIN at 38400 easy-peasy

There have been some discussions recently about (relatively) fast serial I/O with the BS2. I decided to experiment. I chose to use only "standard" baud rates.

1. SEROUT works just fine up to and including 38,400 with formatting.
' {$STAMP BS2}
' {$PBASIC 2.5}
TxOut PIN 1
RxIn  PIN 2               'receive data here
Baud CON 6                '38400 baud

ByteSize  VAR Byte
WordSize  VAR Word

main:
WordSize = 12345

DO
  SEROUT TxOut, baud, ["String", HEX4 Wordsize, DEC5 WordSize, CR]
  PAUSE 50
  LOOP

BS2OutComplete shows the complete output. The first six characters are the text string, then 4 characters of HEX4 formatting, and finally 5 characters of DEC5 formatting. There are plenty of extra STOP bits, but that is perfectly legal. Async is asynchronous.

BS2OutComplete.jpg

BS2OutDetail shows a single character. The bit time is 25.92, corresponding to 38,580 baud rate, less than 1% fast.
BS2OutDetail.jpg

2. SERIN works up to 38,400, but WITHOUT formatting. Here is a driver I wrote for propellor. I wrote my own because I wanted explicit control over the protocol including number of stop bits. It turns out that a single stop bit was adequate.
{Serial Character Stream Generator
Transmit test streams for formstted testing}
CON
        _clkmode = xtal1 + pll16x    'Standard clock mode 
        _xinfreq = 5_000_000         '* crystal frequency = 80 MHz

        TxOut = 17
        BaudRate = 38400           '   
        HalfStops = 0               '1 stop bit
                      
VAR    
  long  Command                        '<> 0 says => driveer busy
                                       '14..0 :  Address in hub memory
  long  MyParm[6]                      'passing addresses, etc to display driver
  byte  Cog
  byte TheString[10]
  word DecVal                   '

OBJ
  pst      : "parallax serial terminal"
  
PUB main
    pst.Start (115_200)                  'start up ser terminal
    pst.str(String("hello, world   "))   'runs in cog 1
    pst.NewLine
    waitcnt(clkfreq/10 + cnt)

    MyParm[0] := @Command             'address of string to send
    MyParm[1] := 80_000_000/BaudRate    'bit time in clock cycles
    MyParm[2] := HalfStops              'optional extra half stop bits                      
    cog := cognew(@PCog, @MyParm)       'start up the output cog
    pst.str(String("Transmit Cog: "))             '
    pst.hex(Cog,1)
    pst.NewLine
    waitcnt(clkfreq/10+cnt)

    repeat DecVal from 0 to 65_000
      Dec2ASC(DecVal, @TheString)
      Command := @TheString                'transmit dec
      repeat while (Command <> 0)      
      waitcnt(clkfreq/20 + cnt)                                             
      pst.char("*")

PUB Dec2ASC(InVal, Point)| Count         'convert word to 5 ascii digits
    byte[Point][0] := "0"+InVal / 10_000
    byte[Point][1] := "0"+(Inval//10_000) / 1_000
    Byte[Point][2] := "0"+(InVal//1_000) / 100
    Byte[Point][3] := "0"+(InVal//100) / 10
    Byte[Point][4] := "0"+(InVal//10) 
    byte[Point][5] := 13                 'terminator for BS2
    byte[Point][6] := 0                  'terminator for serial out          
    
          
DAT
PCog    org   0                  'This PASM driver is a serial driver
        mov AdPar,Par            'get the address of input parameters
        rdlong AdCommand, AdPar  'address of command long
        add AdPar, #4
        rdlong BitTime, AdPar   'clocks per bit
        mov HalfBT, BitTime
        shr HalfBT, #1           'clocks per half bit time
        add AdPar, #4
        rdlong HalfSB, AdPar    'number of half stop bits
        or outa, TxMask         'comes up high   
        or dira, TxMask         'transmitter is an output
       
'*********************wait here for something to do*************************                                                   
top     rdlong AdString, AdCommand wz  'wait for a command (address of string)
        if_Z jmp #top                   'just hang here
         
Cloop   rdbyte TheChar, AdString wz     'get the (first)(next) character
        if_Z jmp #done                  'zero terminated string
        add AdString, #1                'point to following char
        mov BitCount, #8                '8 bits per character
        mov time, BitTime
        add time, cnt                   'time at end of start bit
        andn outa, TxMask               'send start bit
        waitcnt time, BitTime           'time start bit
BLoop   shr TheChar, #1 wc              'next (first) bit into carry
        muxc outa, TXMask               'then onto pin 
        waitcnt time, BitTime           'one bit time
        djnz BitCount, #BLoop           'eight bits per character
        or outa, TXMask                 'stop bit
        waitcnt time, HalfBT            'one stop bit
        mov BitCount, HalfSB wz         'optional half stop bits
        if_Z jmp #CLoop                 'no optional stop bits
SLoop   waitcnt time, HalfBT            'at least one half stop bit
        djnz BitCount, #SLoop           'however many
        jmp #CLoop                      'on to next character        
done    wrlong zero, AdCommand          'tell boss cog done
        jmp #top                        'and wait for another   
                          '                  
zero        long     0               'constants
TxMask      long 1<<TxOut            'mask corresponding to transmit pin
BitTime     res                      'clocks per bit time
AdPar       res                      'address into parameter list
AdCommand   res                      'address in hub of command long
MyCommand   res                      'my copy of the command
BitCount    res                      'number of bits per character
time        res                      'time to wait
AdString    res                      'current address in string 
theChar     res                      'the character we are transmitting
HalfSB      res                      'number of optional half stop bits
HalfBT      res                      'half bit time (for optional 1/2 stops) 

and here is the BS2 program that received it.
' {$STAMP BS2}
' {$PBASIC 2.5}

RxIn  PIN 2              'receive data here
baud CON 6               '38400 Baud

SerString VAR Byte(10)    'buffer so as to use STR
Result    VAR Word        'decimal value from convert
CharCount VAR Byte        'number of characters to convert
Point     VAR Byte        'pointer into character string

main:

DO
  SERIN RXIn, baud, [STR serString\10\13]  'up to 10 chars, teerminated with CR
  DEBUG STR SerString, "  "                'display raw string for manual inspection
  CharCount = 5                            'convert 5 digits
  GOSUB Asc2Dec                            'convert ASCII decimal string to binary
  DEBUG DEC5 Result, CR                    'display result in decimal
  LOOP

Asc2Dec:                                   'convert ascii string
  Result = 0                               'remove previous result
  FOR Point = 0 TO CharCount - 1           'work way through string
    Result = (Result * 10) + (SerString(Point) - "0")  'shift and add
    NEXT
  RETURN

Note that SERIN uses only STR (capture a string). Formatting like HEXn and DECn do work only to 9600. So any conversion you need to do needs to be done by hand.
1219 x 632 - 69K
1219 x 632 - 68K
Sign In or Register to comment.