Shop OBEX P1 Docs P2 Docs Learn Events
Using variables for the pin and baud in SERIN\SEROUT — Parallax Forums

Using variables for the pin and baud in SERIN\SEROUT

Dave ScottDave Scott Posts: 4
edited 2006-09-29 05:33 in General Discussion
I would like to use a single function to write to\read from several different
pins using SERIN\SEROUT. SX\B doesn't seem to allow a variable for the pin or baud rate.

Because of this I need a separate function for each pin that I want to access.

Is there a way around this?

Comments

  • BeanBean Posts: 8,129
    edited 2006-09-29 02:10
    Dave,
    On the SX chip the pin is coded INTO the assembly instruction.

    Therefore you cannot (easily) have one command that works on different pins.

    The way you would have to do this is to create a port mask, then "AND" and "OR" the mask with the port to affect different pins. If the pins are on different ports, it is all the harder to do.

    I guess the short answer is "it can be done, but it's not easy. And not with the standard SERIN/SEROUT commands".

    Bean.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Cheap used 4-digit LED display with driver IC·www.hc4led.com

    Low power SD Data Logger www.sddatalogger.com
    SX-Video Display Modules www.sxvm.com

    There are only two guaranteed ways to become weathy.
    Spend less than you make.
    Make more than you spend.
    ·
  • Mike CookMike Cook Posts: 829
    edited 2006-09-29 02:49

    Terry,

    When you have time can you post an example of OR or AND the mask with the port to affect different pins, in SX/B? SX28 or 48 would be helpful (same port). I think this is beyond my 'grasp' right now!

    Thanks,

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Mike
  • Sparks-R-FunSparks-R-Fun Posts: 388
    edited 2006-09-29 03:48
    Dave,

    If you are not opposed to adding an extra chip (or two) to your circuit a MUX/DEMUX combo could accomplish this 'serial pin switching' in hardware for you. Basically all serial data would enter the SX on one pin and leave on another allowing you to use a single subroutine for each. The other SX pins that you would have been using as additional data pins would then become 'select pins.' The state of those pins would select which external device is to be connected to the (now dedicated) send and receive pins for each call to the serial subroutines.

    Just a thought. idea.gif
  • Peter VerkaikPeter Verkaik Posts: 3,956
    edited 2006-09-29 05:33
    You need to encode a pin in a byte.
    I did this by storing the port address (5 to 9 for ra to re) in the highnib
    and the pin number (0 to 7 for pin0 to pin7) in the lownib.

    See this thread:
    http://forums.parallax.com/showthread.php?p=542815

    Here is the uart transmit part of the library file.
    The library is made up of macros so no code is created until you
    use any of those macros. See the test file in the above thread.

    ;file lib_uartTransmit.inc

    _lib_uart_tx_var macro nr, prefix
    org data
    expand
    vp??nr??_bank equ ($ & $F8) | nr
    lib_tx_count = $+0 ;number of bits
    lib_tx_divide = $+1 ;timing counter
    lib_tx_low = $+2 ;shift register
    lib_tx_high = $+3 ;value
    lib_tx_format = $+4
    · lib_tx_bits_0 = lib_tx_format.0 ;bits 1 and 0 specify number of total bits
    · lib_tx_bits_1 = lib_tx_format.1 ;01 -> 9bits, 10 -> 10bits, 11 -> 11bits (start+data+parity+stop)
    · lib_tx_7bits = lib_tx_format.2 ;set for 7 databits (0 = 8 databits)
    · lib_tx_even = lib_tx_format.3 ;set for even parity
    · lib_tx_odd = lib_tx_format.4 ;set for odd parity
    · lib_tx_data = lib_tx_format.5 ;set if valid value, cleared after value grabbed
    · lib_tx_enable = lib_tx_format.6 ;set to enable uart
    · lib_tx_parity = lib_tx_format.7 ;parity bit placeholder
    lib_tx_baud = $+5 ;baudrate
    lib_tx_datapin = $+6 ;high nib = port (5 to 9), low nib = pin (0 to 7)
    · lib_tx_error = lib_tx_datapin.3 ;set if parity error
    lib_tx_hspin = $+7 ;high nib = port (5 to 9), low nib = pin (0 to 7)
    prefix??_??bank equ ($ & $F0) | nr
    prefix??_??count ds 1 ;number of bits
    prefix??_??divide ds 1 ;timing counter
    prefix??_??low ds 1 ;shift register
    prefix??_??high ds 1 ;value
    prefix??_??format ds 1
    · prefix??_??bits_0 equ prefix??_??format.0 ;bits 1 and 0 specify number of total bits
    · prefix??_??bits_1 equ prefix??_??format.1 ;01 -> 9bits, 10 -> 10bits, 11 -> 11bits (start+data+parity+stop)
    · prefix??_??7bits equ prefix??_??format.2 ;set for 7 databits (0 = 8 databits)
    · prefix??_??even equ prefix??_??format.3 ;set for even parity
    · prefix??_??odd equ prefix??_??format.4 ;set for odd parity
    · prefix??_??data equ prefix??_??format.5 ;set if valid value, cleared after value grabbed
    · prefix??_??enable equ prefix??_??format.6 ;set to enable uart
    · prefix??_??parity equ prefix??_??format.7 ;parity bit placeholder
    prefix??_??baud ds 1 ;baudrate
    prefix??_??datapin ds 1 ;high nib = port (5 to 9), low nib = pin (0 to 7)
    · prefix??_??error equ prefix??_??datapin.3 ;set if parity error
    prefix??_??hspin ds 1 ;high nib = port (5 to 9), low nib = pin (0 to 7)
    noexpand
    data = $
    endm

    lib_uartTransmit macro nr, prefix, datapin, hspin, format, baud, thread
    if nr >= maxvp
    · error "vp number too high"
    endif
    ifndef vp_uartTransmit
    vp_uartTransmit
    endif
    ifndef vp_dirbuf
    vp_dirbuf
    endif
    ifndef vp_parity
    vp_parity
    endif
    vp??nr??_thread = thread
    _lib_uart_tx_var nr,prefix
    org code
    expand
    vp??nr??_init
    mov fsr,#vp??nr??_bank
    mov lib_tx_format,#format
    mov lib_tx_baud,#baud
    mov lib_tx_datapin,#datapin
    mov lib_tx_hspin,#hspin
    noexpand
    code = $
    expand
    org vp??nr??_isr
    jmp @uart_tx_isr
    noexpand
    endm

    _lib_uartTransmit_lowsize equ $002
    _lib_uartTransmit_lowhalf macro
    org code
    begin = $
    expand
    uart_tx_isr jmp _uart_tx_isr
    uart_tx_task jmp _uart_tx_task
    noexpand
    code = $
    if _lib_uartTransmit_lowsize > code - begin
    · error P2W "_uartTransmit_lowsize too large"
    endif
    if _lib_uartTransmit_lowsize < code - begin
    · error "_uartTransmit_lowsize too small"
    endif
    endm

    _lib_uartTransmit_highsize equ $04E
    _lib_uartTransmit_highhalf macro
    org code
    begin = $
    expand
    _uart_tx_isr
    mov fsr,vp_bank ;select target uart bank
    jnb lib_tx_enable,:txdone
    decsz lib_tx_divide ;time for next bit?
    jmp :txdone ;no
    mov w,lib_tx_baud ;renew delay time
    mov lib_tx_divide,w
    test··· lib_tx_count ;bits to send?
    snz
    jmp :txdone ;no
    clc ;ready stop bit
    rr lib_tx_high ;and shift to next bit
    rr lib_tx_low
    mov w,lib_tx_datapin ;pin number 0 to 7 in lownib
    call pin_mask ;get ORmask for pin
    stc
    snb lib_tx_low.5 ;clear carry and keep ORmask to make pin high
    not w ;set carry and make ANDmask to make pin low
    sb lib_tx_low.5
    clc
    mov vp_portpin,w ;save bitmask
    mov w,<>lib_tx_datapin ;port (ra to re) in lownib
    or w,#$F0
    mov fsr,w ;portA_dirbuf to portE_dirbuf
    mov w,vp_portpin ;get bitmask
    snc
    and indf,w
    sc
    or indf,w
    mov w,vp_bank ;select target uart bank
    mov fsr,w
    dec lib_tx_count ;decrement bit counter
    jnz :txdone
    call pin_mask ;set vp flag
    or vp_flags,w
    :txdone
    retp
    _uart_tx_task
    sb lib_tx_data
    retp
    snb lib_tx_7bits ;8 databits?
    clrb lib_tx_high.7 ;no, clear b7 for parity calculation
    mov w,lib_tx_high
    call @even_parity
    snb lib_tx_7bits ;8 databits?
    setb lib_tx_high.7 ;no, ready stop bit
    jnb lib_tx_odd,:uot1
    movb C,/vp_portpin.0
    jmp :uot2
    :uot1
    jnb lib_tx_even,:uot3
    movb C,vp_portpin.0
    :uot2
    jnb lib_tx_7bits,:uot4 ;7 databits?
    movb lib_tx_high.7,C ;yes, move parity into b7
    :uot3
    stc ;ready stop bit
    :uot4
    clrb lib_tx_low.7 ;setup start bit
    rr lib_tx_high ;rotate in parity bit or stop bit
    rr lib_tx_low
    not lib_tx_high ;inverted mode
    not lib_tx_low
    mov w,lib_tx_format ;get total number of bits
    and w,#$03 ;1, 2 or 3
    or w,#$08 ;9, 10, or 11
    mov lib_tx_count,w ;now uart vp starts to transmit
    clrb lib_tx_data ;mark byte grabbed
    retp
    noexpand
    code = $
    if _lib_uartTransmit_highsize > code - begin
    · error P2W "_uartTransmit_highsize too large"
    endif
    if _lib_uartTransmit_highsize < code - begin
    · error "_uartTransmit_highsize too small"
    endif
    endm

    ;end of file lib_uartTransmit.inc


    regards peter
Sign In or Register to comment.