This code talks to a 20MHz PAK-I using PIC Basic Pro and a roll your own Shiftin/Shiftout routine. The timing is different because the 20MHZ PAKs have different maximum timing than a 50MHz PAK:

pakclock con 6 ' 12us @ 20MHz (adjust for your clock)
pakclocklow con 6 ' 6uS low 12uS + 6uS + 2uS hold = 20uS = 50kbps

This code could easily be used with a PAK-II or PAK-IX since these are supersets of the PAK-I. You can compare the BS2 library provided on the disk with this code and easily add additional functions you need.

' These are some starter routines
' that will help you use the PAK-1
' Coprocessor from AWC

Include "modedefs.bas"
define LOADER_USED 1 ' comment this out if not using a boot loader
Define OSC 20
DEFINE HSER_RCSTA 90h
DEFINE HSER_TXSTA 20h
DEFINE HSER_BAUD 19200

' Change these to suit your setup
datap var portc.2 ' Data pin (I/O)
datapin var portc.2
clk var portc.3 ' Clk pin (output)


' Constants for options
FSaturate con $80 ' saturate on underflow/overflow
FRound con $40 ' round results

output clk
output datap

sioi var byte ' shiftin/shiftout counter
iobyte var byte ' shiftin/shiftout data
fpstatus var byte ' FPSTATUS - result of last operation
fpx var word ' Integer used by some routines
fpdigit var byte ' Digit returned from DIGIT
fpxlow var word ' The X register low & high
fpxhigh var word
fpb var byte ' Temporary byte
' The X register in bytes
fpxb0 var fpxlow.lowbyte
fpxb1 var fpxlow.highbyte
fpxb2 var fpxhigh.lowbyte
fpxb3 var fpxhigh.highbyte

gosub freset ' always reset!

' TEST CODE -- REPLACE WITH YOUR OWN

' Square root table
i var word
fpx=$10
gosub IODir ' demo: make an output on port 4

for i=1 to 1000 
fpx=i//2*$10 ' make output LED blink
gosub IOWrite
fpx=i ' number ' load I as integer
gosub floadint
gosub fsqrt ' compute square root
fpx=2
hserout [dec i, " - " ] ' write # and square root (2 digits)
gosub fdump 
hserout [" Error="] ' compute error by squaring the square
gosub fswap ' root and subtracting it from the number
fpx=i
gosub floadint 
gosub fswap
gosub fsquare ' square answer
gosub fsub ' subtract answer and squared result
fpx=1 ' write result
gosub fdump
hserout [13,10] ' new line
next
end



' END OF TEST CODE ----


' Reset the Pak1
FReset:
LOW DATAP
LOW CLK
pauseus 50
HIGH CLK
pauseus 50
HIGH DATAP
pauseus 50
LOW CLK 
pauseus 50
return


' Helper function
' Wait for +,-,*,/,INT,FLOAT, & DIGIT to complete
Fwaitdata:
input DATAP
if DATAPIN=1 then Fwaitdata
return


'Change sign
FChs:
fpb=10
FSendByte:
iobyte=fpb
gosub shiftoutput
return

'Absolute Value
FAbs:
fpb=17
goto FSendByte

' Store0
FSto0:
fpb=18
goto FSendByte

'Store1
FSto1:
fpb=$92
goto FSendByte

'Rcl0
FRcl0:
fpb=19
goto FSendByte

'Rcl1
FRcl1:
fpb=$93
goto FSendByte

' Load X with fpxhigh, fpxlow
FLoadX:
iobyte=1
gosub shiftoutput
iobyte=fpxb3
gosub shiftoutput
iobyte=fpxb2
gosub shiftoutput
iobyte=fpxb1
gosub shiftoutput
iobyte=fpxb0
gosub shiftoutput
return

' Load Y with fpxhigh, fpxlow
FLoadY:
iobyte=2
gosub shiftoutput
iobyte=fpxb3
gosub shiftoutput
iobyte=fpxb2
gosub shiftoutput
iobyte=fpxb1
gosub shiftoutput
iobyte=fpxb0
gosub shiftoutput
return


' Load X with 0
FZeroX:
iobyte=1
gosub shiftoutput
iobyte=0
gosub shiftoutput
iobyte=0
gosub shiftoutput
iobyte=0
gosub shiftoutput
iobyte=0
gosub shiftoutput
return

' Load Y with 0
FZeroY:
iobyte=2
gosub shiftoutput
iobyte=0
gosub shiftoutput
iobyte=0
gosub shiftoutput
iobyte=0
gosub shiftoutput
iobyte=0
gosub shiftoutput
return

' Load an integer from FPX to X
FLoadInt: 
iobyte=1
gosub shiftoutput
iobyte=0
gosub shiftoutput
iobyte=0
gosub shiftoutput
iobyte=fpx.highbyte
gosub shiftoutput
iobyte=fpx.lowbyte
gosub shiftoutput
' Convert from Int
iobyte=7
gosub shiftoutput
goto fpstat

' to int
FInt:
iobyte=11
gosub shiftoutput
gosub Fwaitdata
gosub shiftinput
fpstatus=iobyte
if fpstatus<>0 then FInterr


' Read the X register
FreadX:
fpb=3
gosub FSendByte
gosub shiftinput
fpxb3=iobyte
gosub shiftinput
fpxb2=iobyte
gosub shiftinput
fpxb1=iobyte
gosub shiftinput
fpxb0=iobyte
fpx = fpxlow
FInterr:
return


' Swap X and Y
FSwap:
fpb=4
goto FSendByte

' Load X with pi
FPI: 
iobyte=1
gosub shiftoutput
iobyte=$80
gosub shiftoutput
iobyte=$49
gosub shiftoutput
iobyte=$F
gosub shiftoutput
iobyte=$DB
gosub shiftoutput
return

' Load X with e
Fe:
iobyte=1
gosub shiftoutput
iobyte=$80
gosub shiftoutput
iobyte=$2D
gosub shiftoutput
iobyte=$F8
gosub shiftoutput
iobyte=$54
gosub shiftoutput
return

' X=X*Y
FMult:
fpb=12
fpstats:
gosub FSendByte
' Fall into next routine
' internal: wait for status
fpstat:
gosub FWaitdata
gosub shiftinput
fpstatus=iobyte
return ' status

' X=X/Y
FDiv:
fpb=13
goto fpstats

' X=X+Y
FAdd:
fpb=15
goto fpstats

' X=X-Y
FSub:
fpb=14
goto fpstats

' Get Digit (fpx is digit #) return in fpdigit
FGetDigit:
iobyte=5
gosub shiftoutput
iobyte=fpx
gosub shiftoutput
Fgetdigw:
gosub fwaitdata
gosub shiftinput
fpdigit=iobyte
return 


' Dump a number. fpx is # of digits before decimal point
' Assumes 6 digits after decimal point
' You can change by modifying $86 below
' (for example, $83 would give 3 digits)
FDump:
fdj var byte
fdnz var bit
fdjj var byte
fdjj=fpx
fpx=0
fdnz=0
gosub FgetDigit
' Remove this line to print + and space for + and 0 numbers
if fpdigit="+" or fpdigit=" " then Fdumppos
Hserout [fpdigit]
Fdumppos:
for fdj=1 to fdjj
fpx=fdjj+1-fdj
gosub FgetDigit
if fpdigit="0" and fdnz=0 then FdumpNext
fdnz=1
Hserout [fpdigit]
Fdumpnext:
next
Hserout ["."]
for fpx=$81 to $86
gosub FgetDigit
Hserout [fpdigit]
next 
return

' Set options in fpx
' $80 = saturate
' $40 = round
FOption:
iobyte=$10
gosub shiftoutput
iobyte=fpx
gosub shiftoutput
return

' Copy X to Y
FXtoY:
fpb=$17
goto FSendByte

' Copy Y to X
FYtoX:
fpb=$18
goto FSendByte

' Set I/O Direction (dir in fpx)
IODir:
iobyte=$14
gosub shiftoutput
iobyte=fpx
gosub shiftoutput
return

' Write bits in FPX to I/O port
IOWrite:
iobyte=$16
gosub shiftoutput
iobyte=fpx
gosub shiftoutput
return

' Read bits to FPX
IORead:
fpb=$15
gosub FSendByte
gosub shiftinput
fpx=iobyte
return

' Square Root, set tolerance below
' Note: the PAK-II and IX have hardware square root
fsqrt:
gosub fsto1 ' R1=target
' guess half the original #
fpxhigh=$8000
fpxlow=0
gosub floady
gosub fdiv
gosub fsto0 ' R0=guess
goto fsqrterr

freguess:
gosub frcl0 ' get guess
gosub fsquare ' square it
gosub fswap ' put it in Y
gosub frcl1 ' get target
gosub fswap ' x=guess squared; y=target
gosub fsub ' subtract
gosub freadx ' get x to fpxhigh,fpxlow
gosub frcl0 ' get guess
gosub fswap ' y=guess
fpx=2 ' x=2
gosub floadint
gosub fmult ' x=2*guess
gosub fswap ' y=2*guess
gosub floadx ' x=guess squared - target
gosub fdiv ' x=x/y
gosub fswap ' y=x/y term
gosub frcl0 ' x=guess
gosub fsub ' x=guess-term
gosub fsto0 ' new guess
fsqrterr:
gosub fsquare
gosub fswap
gosub frcl1
gosub fsub
gosub fabs
' Select your error tolerance
' more precise values may fail to converge or take a long time
' check for error<.01
fpxhigh=$7823
fpxlow=$D70A
' check for error <.001
'fpxhigh=$7503
'fpxlow=$126f
' check for error<.0001 - warming may not converge
'fpxhigh=$7151
'fpxlow=$B717
gosub floady
gosub fsub
fpx=0
gosub fgetdigit
if fpdigit="+" then freguess
' Found it!
gosub frcl0
return
End

' X=X**2 ; does not destroy Y, but destroys fpxlow/fpxhigh
' Note: PAKII and IX have this built in
Fsquare:
gosub fswap ' get y
gosub freadx ' save it
gosub fytox ' y->x
gosub fmult ' x=x*y 
gosub floady ' restore old y
return


pakclock con 6 ' 12us @ 20MHz (adjust for your clock)
pakclocklow con 6 ' 6uS low 12uS + 6uS + 2uS hold = 20uS = 50kbps

shiftoutput: ' sends iobyte
output datapin
for sioi=0 to 7
' Set data pin to 0 or 1
low datapin
if (iobyte & $80) <> $80 then goto so0
high datapin
so0:
iobyte=iobyte<<1 ' shift byte left
pauseus pakclocklow
pulsout clk,pakclock
pauseus 2
next
pauseus 50 ' give it some time to process
return

shiftinput:
input datapin
iobyte=0
for sioi=0 to 7
iobyte=iobyte<<1 ' shift left
iobyte=iobyte | datap
pauseus pakclocklow
pulsout clk,pakclock
pauseus 2 ' hold data a tick
next
return

Site contents © 1997-2014 by AWC, 310 Ivy Glen, League City, TX 77573    (281) 334-4341