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
My Prop boards: P8XBlade2, RamBlade, CpuBlade, TriBlade
Prop OS (also see Sphinx, PropDos, PropCmd, Spinix)
Website: www.clusos.com
Prop Tools (Index) , Emulators (Index) , ZiCog (Z80)

Comments

  • 11 Comments sorted by Date Added Votes
  • 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
    
    Melbourne, Australia
  • 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
    
    Melbourne, Australia
  • 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.

    My Prop boards: P8XBlade2, RamBlade, CpuBlade, TriBlade
    Prop OS (also see Sphinx, PropDos, PropCmd, Spinix)
    Website: www.clusos.com
    Prop Tools (Index) , Emulators (Index) , ZiCog (Z80)
  • 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
    
  • 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.
    The Prisoner's Dilemma, in english - "Selfishness beats altruism within groups. Altruistic groups beat selfish groups." - Quoted part from 2007, D.S Wilson/E.O Wilson.
  • Cluso99Cluso99 Posts: 13,017
    edited November 27 Vote Up0Vote Down
    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
    '--------------------------------------------------------------------------------------------------
    
    
    My Prop boards: P8XBlade2, RamBlade, CpuBlade, TriBlade
    Prop OS (also see Sphinx, PropDos, PropCmd, Spinix)
    Website: www.clusos.com
    Prop Tools (Index) , Emulators (Index) , ZiCog (Z80)
  • Cluso99Cluso99 Posts: 13,017
    edited November 27 Vote Up0Vote Down
    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)  
    ''---------------------------------------------------------------------------------------------------
    
    My Prop boards: P8XBlade2, RamBlade, CpuBlade, TriBlade
    Prop OS (also see Sphinx, PropDos, PropCmd, Spinix)
    Website: www.clusos.com
    Prop Tools (Index) , Emulators (Index) , ZiCog (Z80)
  • excellent:)

    I didn't prime the pump.

    Thanks
  • rjo__ wrote: »
    excellent:)

    I didn't prime the pump.

    Thanks
    IMHO a lot will get caught with that ;)
    My Prop boards: P8XBlade2, RamBlade, CpuBlade, TriBlade
    Prop OS (also see Sphinx, PropDos, PropCmd, Spinix)
    Website: www.clusos.com
    Prop Tools (Index) , Emulators (Index) , ZiCog (Z80)
  • When I did it wrong, it worked. When I did it right, it worked too!

    These Smart Pins really are smart.

Sign In or Register to comment.