Shop OBEX P1 Docs P2 Docs Learn Events
Smart Pins for Async Serial for P2 v27 — Parallax Forums

Smart Pins for Async Serial for P2 v27

Is the following code the best way to use smart pins?

Are either of the commented out line pairs required (enable DIRn) ?
CON
' constants for serial driver
  _rxpin   = 63                                 ' P63=SI
  _txpin   = 62                                 ' P62=SO
  _baud    = 115_200
  _bitper  = (_clockfreq / _baud) << 16 + 7     ' 115200 baud, 8 bits
  _txmode  = %0000_0000_000_0000000000000_01_11110_0 'async tx mode, output enabled for smart output
  _rxmode  = %0000_0000_000_0000000000000_00_11111_0 'async rx mode, input  enabled for smart input

DAT
'--------------------------------------------------------------------------------------------------
'       Serial Routines
'--------------------------------------------------------------------------------------------------
_serialinit     wrpin   ##_txmode,        #_txpin       ' set asynchronous tx mode in smart pin tx
                wxpin   ##_bitper,        #_txpin       ' set tx bit period
''              setb    dirb,             #_txpin       ' enable smart pin tx  ???
''              dirh    #_txpin                         ' enable smart pin tx  ???
               
                wrpin   ##_rxmode,        #_rxpin       ' set asynchronous rx mode in smart pin rx
                wxpin   ##_bitper,        #_rxpin       ' set rx bit period
''              setb    dirb,             #_rxpin       ' enable smart pin rx ???
''              dirh    #_rxpin                         ' enable smart pin rx ??? 

                mov     lmm_x,            #CR           ' we have to prime send buffer,       
                jmp     #_sendfirst                     ' ..so send <cr>

_send           testp   #_txpin                     wc  ' busy?
        if_nc   jmp     #_send                          ' 
_sendfirst      wypin   lmm_x,            #_txpin       ' send next byte to tx pin
                ret
                
_recv           testp   #_rxpin                     wc  ' char ready?
        if_nc   jmp     #_recv                          ' 
                rdpin   lmm_x,            #_rxpin       ' get data from rx pin
                ret
'--------------------------------------------------------------------------------------------------
lmm_x           long    0

Comments

  • A single setb pr dirh is all that is need.
    You will need a shift on the received data too.
    _recv           testp   #_rxpin                     wc  ' char ready?
            if_nc   jmp     #_recv                          ' 
                    rdpin   lmm_x,            #_rxpin       ' get data from rx pin
    		shr	lmm_x,#24
                    ret
    
  • Also check the baudrate calculation.
    This is what I use currently.
    	nco = (sys_clk / baudrate) * $1_0000 & $FFFFFC00 
    	nco_f = (sys_clk - ((sys_clk / baudrate) * baudrate)) * 64 / baudrate
    
  • Cluso99Cluso99 Posts: 18,066
    Thanks ozpropdev.

    I have the send working with either but I had to change SETB to BITH.

    I forgot abou the shift for receive.

    My baud calc works. Not sure what yours is doing.

  • rjo__rjo__ Posts: 2,114
    needs
    clkset #$FF

    remember I am using a damaged P123-A9

    but on the send code... I can't get it to work with either if_c or if_nc
    what does work for me is:
    send1_char       
    
          '          testp #Tx_pin WC	' <=-
           ' if_c    jmp     #send1_char	' <=-
                   
                    WYPIN Tx_char,#Tx_Pin
                 '   akpin #Tx_Pin		' <=-
                    ret
    
  • evanhevanh Posts: 15,126
    If you're wanting something to compare with, here an example with some routines I stole from Dave Hein's work. I use his low level serial code for reporting debug info. It's pure bit-bashed so has worked from day one.
  • Cluso99Cluso99 Posts: 18,066
    edited 2017-11-27 23:00
    Here is working code for sending, including formatting, hex, decimal, etc. It is based on my old P2 debugger code.
    I have not tried receiving.

    Snippets...
    CON
    '  _clkmode = xinput
      _clockfreq = 80_000_000
    
    ' constants for serial driver
      _rxpin   = 63                                 ' P63=SI
      _txpin   = 62                                 ' P62=SO
      _baud    = 115_200
      _bitper  = (_clockfreq / _baud) << 16 + 7     ' 115200 baud, 8 bits
      _txmode  = %0000_0000_000_0000000000000_01_11110_0 'async tx mode, output enabled for smart output
      _rxmode  = %0000_0000_000_0000000000000_00_11111_0 'async rx mode, input  enabled for smart input
    
    
    '--------------------------------------------------------------------------------------------------
    '       Serial Routines
    '--------------------------------------------------------------------------------------------------
    _serialinit     wrpin   ##_txmode,        #_txpin       ' set asynchronous tx mode in smart pin tx
                    wxpin   ##_bitper,        #_txpin       ' set tx bit period + #(bits-1)
                    dirh    #_txpin                         ' enable smart pin tx 
                    
                    wrpin   ##_rxmode,        #_rxpin       ' set asynchronous rx mode in smart pin rx
                    wxpin   ##_bitper,        #_rxpin       ' set rx bit period + #(bits-1)
                    dirh    #_rxpin                         ' enable smart pin rx
    
                    mov     lmm_x,            #CR           ' we have to prime send buffer empty flag, 
                    jmp     #_sendfirst                     ' ..so send <cr>
    
    _send           testp   #_txpin                     wc  ' wait for buffer empty on tx pin
            if_nc   jmp     #_send                          ' 
    _sendfirst      wypin   lmm_x,            #_txpin       ' send byte to tx pin
                    ret                                 wcz
                    
    _recv           testp   #_rxpin                     wc  ' char ready?
            if_nc   jmp     #_recv                          ' 
                    rdpin   lmm_x,            #_rxpin       ' get data from rx pin
                    ret                                 wcz
    '--------------------------------------------------------------------------------------------------
    
    
  • Cluso99Cluso99 Posts: 18,066
    edited 2017-11-27 23:07
    In the above code, the following are calls, plus parameters...
    ''-------[ Display Char(s) ]--------------------------------------------------- <--- display char(s) --->
    ''_HubTx                                                '                       
    '' On Entry:
    ''      lmm_f = -not used-                              ' mode:
    ''      lmm_x = char(s)                                 ' char(s): up to 4 chars; B0 first; <nul> terminates
    ''                                                      '            if =$0, tx one <nul>
    '' Call Format:
    ''            CALL      @_HubTx                         '                       < call: display char(s)>
    '' On Return:
    ''      lmm_f = -same-                                  ' mode:     (unchanged)
    ''      lmm_x = -same-                                  ' char(s):  (unchanged)
    ''--------------------------------------------------------------------------------------------------
    ''-------[ Display Hex) ]------------------------------------------------------ <--- display hex --->
    ''_HubHex                                               '                       
    '' On Entry:
    ''      lmm_f = _HEX [+options]                         ' mode:  #_HEX[+_REV][+_SP][+_ndigits]
    ''                                                      '        'n' digits = 7..0 where 0 = 8 digits
    ''      lmm_x = char(s)                                 ' char(s): 
    '' Call Format:
    ''            CALL      #_HubHex                        '                       < call: display hex >
    '' On Return:
    ''      lmm_f = -same-                                  ' mode:     (unchanged)
    ''      lmm_x = -same-                                  ' char(s):  (unchanged)
    ''--------------------------------------------------------------------------------------------------
    ''-------[ Display String, <nul> terminated ]---------------------------------- <--- display string --->
    ''_HubTxString                                          '
    ' On Entry:
    ''      lmm_f = #_TXSTRING [+options]                   ' mode:   #_TXSTRING
    ''      lmm_p = 'addr'                                  ' addr:   string (hub ptr)
    '' Call Format:
    ''            CALL      #_HubTxString                   '                       < call: display string>
    '' On Return:
    ''      lmm_f = -same-                                  ' mode:   (unchanged)
    ''      lmm_p = 'addr' (next string)                    ' addr:   (hub ptr to next string)
    ''--------------------------------------------------------------------------------------------------
    ''-------[ LIST a line ]------------------------------------------------------- <--- LIST a line --->
    ''_HubList
    '' On Entry:
    ''      lmm_f   = #_LIST [+options]                     ' mode:         _LIST[+_{ADDR2|COUNT}][+_HDG][+_{MON|SMON|CODE|LONG}]
    ''      lmm_p   = 'addr'        (from)                  ' addr:    from cog addr / hub ptr
    ''      lmm_p2  = 'addr2'       (to)    (optional)      ' addr2:   to   cog addr / hub ptr (if _ADDR2 specified)
    ''      lmm_c   = 'count'       (count) (optional)      ' count:   'n' lines (hex)         (if _COUNT specified)
    ''                                                      '          Note: only addr2 or count may be specified, not both!
    '' Call Format:
    ''             CALL     #_HubList                       '                       < call: LIST a line >
    '' On Return:
    ''      lmm_f   = same except _HDG off                  ' mode:    same except _HDG will be off
    ''      lmm_p   = addr++        (from)                  ' addr:    next from cog addr / hub ptr
    ''      lmm_p2  = addr2++/same  (to)                    ' addr2:   next to addr -OR- unchanged
    ''      lmm_c   = -same-        (count)                 ' count:   (unchanged)  
    ''---------------------------------------------------------------------------------------------------
    
  • rjo__rjo__ Posts: 2,114
    excellent:)

    I didn't prime the pump.

    Thanks
  • Cluso99Cluso99 Posts: 18,066
    rjo__ wrote: »
    excellent:)

    I didn't prime the pump.

    Thanks
    IMHO a lot will get caught with that ;)
  • rjo__rjo__ Posts: 2,114
    When I did it wrong, it worked. When I did it right, it worked too!

    These Smart Pins really are smart.

  • Thank you all for the information. Transmitting $FF as part of the Smart-Pin setup would take care of the problem, too. It's just a string of logic-1s, so to external devices it would "look like" a single logic-0 to logic-1 transition that leaves the output as a logic-1. Normal serial comms after that should appear with the proper format. I'll try it later. --Jon
  • I transmit a null character to prime the transmitter since this character is largely ignored whereas an $FF may appear as garbage on a terminal screen. However, unless we have a pull-up on the line it will be sending a break condition and possible garbage characters when it connects anyway.
Sign In or Register to comment.