Below is the public domain assembly source code for the
bit-banged SPI routines for the PIC18F processors.
I hope someone will find this code usefull, however I do not
warrant, that the routines are error-free!
Wojtek Zabolotny
wz...@ise.pw.edu.pl
#!/bin/sh
# This is a shell archive (produced by GNU sharutils 4.6.3).
# To extract the files from this archive, save it to some FILE, remove
# everything before the `#!/bin/sh' line above, then type `sh FILE'.
#
lock_dir=_sh05572
# Made on 2008-06-01 23:54 CEST by <wzab@ipebio15>.
# Source directory was `/tmp'.
#
# Existing files will *not* be overwritten, unless `-c' is specified.
#
# This shar contains:
# length mode name
# ------ ---------- ------------------------------------------
# 3259 -rw-r--r-- spi_bb2.asm
#
MD5SUM=${MD5SUM-md5sum}
f=`${MD5SUM} --version | egrep '^md5sum .*(core|text)utils'`
test -n "${f}" && md5check=true || md5check=false
${md5check} || \
echo 'Note: not verifying md5sums. Consider installing GNU coreutils.'
save_IFS="${IFS}"
IFS="${IFS}:"
gettext_dir=FAILED
locale_dir=FAILED
first_param="$1"
for dir in $PATH
do
if test "$gettext_dir" = FAILED && test -f $dir/gettext \
&& ($dir/gettext --version >/dev/null 2>&1)
then
case `$dir/gettext --version 2>&1 | sed 1q` in
*GNU*) gettext_dir=$dir ;;
esac
fi
if test "$locale_dir" = FAILED && test -f $dir/shar \
&& ($dir/shar --print-text-domain-dir >/dev/null 2>&1)
then
locale_dir=`$dir/shar --print-text-domain-dir`
fi
done
IFS="$save_IFS"
if test "$locale_dir" = FAILED || test "$gettext_dir" = FAILED
then
echo=echo
else
TEXTDOMAINDIR=$locale_dir
export TEXTDOMAINDIR
TEXTDOMAIN=sharutils
export TEXTDOMAIN
echo="$gettext_dir/gettext -s"
fi
if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null
then if (echo -n test; echo 1,2,3) | grep n >/dev/null
then shar_n= shar_c='
'
else shar_n=-n shar_c= ; fi
else shar_n= shar_c='\c' ; fi
f=shar-touch.$$
st1=200112312359.59
st2=123123592001.59
st2tr=123123592001.5 # old SysV 14-char limit
st3=1231235901
if touch -am -t ${st1} ${f} >/dev/null 2>&1 && \
test ! -f ${st1} && test -f ${f}; then
shar_touch='touch -am -t $1$2$3$4$5$6.$7 "$8"'
elif touch -am ${st2} ${f} >/dev/null 2>&1 && \
test ! -f ${st2} && test ! -f ${st2tr} && test -f ${f}; then
shar_touch='touch -am $3$4$5$6$1$2.$7 "$8"'
elif touch -am ${st3} ${f} >/dev/null 2>&1 && \
test ! -f ${st3} && test -f ${f}; then
shar_touch='touch -am $3$4$5$6$2 "$8"'
else
shar_touch=:
echo
${echo} 'WARNING: not restoring timestamps. Consider getting and'
${echo} 'installing GNU `touch'\'', distributed in GNU coreutils...'
echo
fi
rm -f ${st1} ${st2} ${st2tr} ${st3} ${f}
#
if test ! -d ${lock_dir}
then : ; else ${echo} 'lock directory '${lock_dir}' exists'
exit 1
fi
if mkdir ${lock_dir}
then ${echo} 'x - created lock directory `'${lock_dir}\''.'
else ${echo} 'x - failed to create lock directory `'${lock_dir}\''.'
exit 1
fi
# ============= spi_bb2.asm ==============
if test -f 'spi_bb2.asm' && test "$first_param" != -c; then
${echo} 'x -SKIPPING spi_bb2.asm (file already exists)'
else
${echo} 'x - extracting spi_bb2.asm (text)'
sed 's/^X//' << 'SHAR_EOF' > 'spi_bb2.asm' &&
; Macros for the bit-bang SPI for PIC18F processors
; Version 2.0 2008.06.01
; Inspired by the:
; http://www.piclist.org/techref/postbot.asp?by=time&id=piclist/2004/03/03/105839a
; This is the public domain code written by
; Wojciech M. Zabolotny wzab(at)ise.pw.edu.pl
; The code below requires you to define:
; sdo_port, sdo_pin: port and pin used as SDI
; sdi_port, sdi_pin: port and pin used as SDO
; clk_port, clk_pin: port and pin used as SCLK
; You have to set the proper pins appropriately for outputs or inputs
; If you want to use the fastest mspi_byte_wio routine, then you need
; to define a single byte spi_outdata variable in the access bank.
; All routines emulate the MODE0 (CPHA=0, CPOL=0) of the SPI
; (as they are supposed to work with the SD/MMC memory card)
X
;The MSPI_WIO_BIT macro outputs the bit from W7 to SPI,
;and reads the bit from SPI to W0,
;simultaneously the W is shifted by 1 bit to the left
MSPI_WIO_BIT macro
; move the highest bit to the carry, and 0 to the lowest bit
X addwf WREG,0,0
; set the data line to carry
X bcf sdo_port,sdo_pin,0
X btfsc STATUS,0,0
X bsf sdo_port,sdo_pin,0
; read the input pin
X btfsc sdi_port, sdi_pin,0
; set the bit 0 in WREG to SDI
X bsf WREG,0,0
; set the clock line to 'H'
X bsf clk_port, clk_pin,0
; set the clock line to 'L'
X bcf clk_port, clk_pin, 0
X endm
X
;The MSPI_DIO_BIT macro outputs the particular bit from spi_outdata
;and reads the particular bit from SPI to WREG
;spi_outdata should be located in the access bank
MSPI_DIO_BIT macro bit_nr
; set the data line to the data bit
X bcf sdo_port,sdo_pin,0
X btfsc spi_outdata, bit_nr, 0
X bsf sdo_port,sdo_pin,0
; read the input pin
X btfsc sdi_port, sdi_pin,0
; set the bit 0 in WREG to SDI
X bsf WREG,bit_nr,0
; set the clock line to 'H'
X bsf clk_port, clk_pin,0
; set the clock line to 'L'
X bcf clk_port, clk_pin, 0
X endm
X
MSPI_O_BIT macro bit_nr
X bcf sdo_port, sdo_pin, 0
X btfsc WREG,bit_nr, 0
X bsf sdo_port, sdo_pin, 0
X bsf clk_port, clk_pin, 0
X bcf clk_port, clk_pin, 0
X endm
X
MSPI_I_BIT macro bit_nr
X btfsc sdi_port, sdi_pin, 0
X bsf WREG, bit_nr, 0
X bsf clk_port, clk_pin, 0
X bcf clk_port, clk_pin, 0
X endm
X
; Procedures
; mspi_byte_wio - sends to the SPI the byte from WREG
; reads the byte from SPI and puts it to WREG
mspi_byte_wio:
X MSPI_WIO_BIT ; 7
X MSPI_WIO_BIT ; 6
X MSPI_WIO_BIT ; 5
X MSPI_WIO_BIT ; 4
X MSPI_WIO_BIT ; 3
X MSPI_WIO_BIT ; 2
X MSPI_WIO_BIT ; 1
X MSPI_WIO_BIT ; 0
X return
X
; mspi_byte_dio - sends to the SPI the byte from spi_outdata
; reads the data from SPI and puts it to WREG
mspi_byte_dio:
X clrf WREG,0
X MSPI_DIO_BIT 7
X MSPI_DIO_BIT 6
X MSPI_DIO_BIT 5
X MSPI_DIO_BIT 4
X MSPI_DIO_BIT 3
X MSPI_DIO_BIT 2
X MSPI_DIO_BIT 1
X MSPI_DIO_BIT 0
X return
X
; mspi_byte_i - reads the byte from the SPI and puts it to the WREG
; the sdo pin remains unchanged (set it to the desired state before
; calling this procedure)
mspi_byte_i:
X clrf WREG,0
X MSPI_I_BIT 7
X MSPI_I_BIT 6
X MSPI_I_BIT 5
X MSPI_I_BIT 4
X MSPI_I_BIT 3
X MSPI_I_BIT 2
X MSPI_I_BIT 1
X MSPI_I_BIT 0
X return
X
; mspi_byte_o - sends the byte from WREG to the SPI
mspi_byte_o:
X MSPI_I_BIT 7
X MSPI_I_BIT 6
X MSPI_I_BIT 5
X MSPI_I_BIT 4
X MSPI_I_BIT 3
X MSPI_I_BIT 2
X MSPI_I_BIT 1
X MSPI_I_BIT 0
X return
X
X
SHAR_EOF
(set 20 08 06 01 23 54 06 'spi_bb2.asm'; eval "$shar_touch") &&
chmod 0644 'spi_bb2.asm'
if test $? -ne 0
then ${echo} 'restore of spi_bb2.asm failed'
fi
if ${md5check}
then (
${MD5SUM} -c >/dev/null 2>&1 || ${echo} 'spi_bb2.asm: MD5 check failed'
) << SHAR_EOF
84b5b9dd5f09010b29cb79b584549954 spi_bb2.asm
SHAR_EOF
else
test `LC_ALL=C wc -c < 'spi_bb2.asm'` -ne 3259 && \
${echo} 'restoration warning: size of spi_bb2.asm is not 3259'
fi
fi
if rm -fr ${lock_dir}
then ${echo} 'x - removed lock directory `'${lock_dir}\''.'
else ${echo} 'x - failed to remove lock directory `'${lock_dir}\''.'
exit 1
fi
exit 0