Using variables for the pin and baud in SERIN\SEROUT
Dave Scott
Posts: 4
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?
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
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.
·
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
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.
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