1
0
mirror of https://github.com/dschmenk/PLASMA.git synced 2025-02-20 17:29:11 +00:00

SdFat support from Arduino SPI slave

This commit is contained in:
dschmenk 2016-08-14 11:11:58 -07:00
parent 1ec6333663
commit 9170ca8602
10 changed files with 532 additions and 4 deletions

3
src/inc/args.plh Normal file
View File

@ -0,0 +1,3 @@
import args
predef argFirst, argNext
end

30
src/inc/sdfat.plh Normal file
View File

@ -0,0 +1,30 @@
//
// FAT I/O object
//
import sdFAT
struc t_fatio
word dirGet
word dirSet
word dirNew
word dirRemove
word fileRename
word fileRemove
word fileExists
word fileOpenFirst
word fileOpenNext
word fileOpen
word fileClose
word fileRead
word fileWrite
word fileSync
word fileRewind
word fileSeek
word fileSeekOffset
word filePos
word fileSize
word fileTruncate
word fileIsDir
word fileIsFile
end
word sdFAT // sdFAT interface
end

3
src/inc/spiport.plh Normal file
View File

@ -0,0 +1,3 @@
import spiport
predef spiXferByte, spiSend, spiRecv, spiWriteBuf, spiReadBuf, spiDelay
end

23
src/inc/wireio.plh Normal file
View File

@ -0,0 +1,23 @@
//
// Wiring constants for Arduino
//
const PINHIGH = 1
const PINLOW = 0
const PINOUTPUT = 1
const PININPUT = 0
const PINPULLUP = 2
//
// SPI commands to Wiring functions on Arduino
//
const CMDPINMODE = 3
const CMDDIGREAD = 4
const CMDDIGWRITE = 5
const CMDANAREAD = 6
const CMDANAWRITE = 7
//
// SPI commands to serial functions on Arduino
//
const CMDSERMODE = 8
const CMDSERAVAIL = 9
const CMDSERREAD = 10
const CMDSERWRITE = 11

33
src/libsrc/args.pla Normal file
View File

@ -0,0 +1,33 @@
include "inc/cmdsys.plh"
const cmdline = $01FF
def argDelim(str)
byte n
// Strip leading spaces
while ^str and ^(str + 1) == ' '
memcpy(str + 1, str + 2, ^str - 1)
^str--
loop
// Scan to trailing spaces (if any)
for n = 1 to ^str
if ^(str + n) <= ' '
^(str + n) = ^str - n
^str = n - 1
break
fin
next
return str
end
export def argNext(str)
str = str + ^str + 1
return argDelim(str)
end
export def argFirst
// NULL terminate command line
^(cmdline + ^cmdline + 1) = 0
return argDelim(cmdline)
end

126
src/libsrc/sdfat.pla Normal file
View File

@ -0,0 +1,126 @@
include "inc/spiport.plh"
//
// FAT I/O object
//
predef cwd, chdir, mkdir, rmdir, rename, remove, exists, openFirst, openNext, open
predef close, read, write, sync, rewind, seek, seekOfs, pos
predef size, truncate, isDir, isFile
//
// SD card FAT filesystem interface
//
export byte[] sdFAT
word[] = @cwd, @chdir, @mkdir, @rmdir, @rename, @remove, @exists, @openFirst, @openNext, @open
word[] = @close, @read, @write, @sync, @rewind, @seek, @seekOfs, @pos
word[] = @size, @truncate, @isDir, @isFile
//
// Directory related functions
//
def cwd(pathname)
byte namelen
namelen = 0
spiSend(15)
namelen = spiSend(15)//spiRecv
if namelen
spiReadBuf(pathname+1, namelen)
fin
^pathname = namelen
return namelen
end
def chdir(path)
spiWriteBuf(path + 1, ^path)
spiSend(16) // CHGDIR
return spiSend(16)//spiRecv
end
def mkdir(path)
end
def rmdir(path)
end
def rename(newpath)
end
def remove
end
def exists(path)
end
def openDir(cmd, filename)
byte namelen
namelen = 0
spiSend(cmd)
namelen = spiSend(cmd)//spiRecv
if namelen == 0xFF
namelen = 0
fin
if namelen
spiReadBuf(filename+1, namelen)
fin
^filename = namelen
return namelen
end
def openFirst(filename) // return filename in buffer
return openDir(22, filename) // OPENFIRST
end
def openNext(filename) // return filename i buffer
return openDir(23, filename) // OPENNEXT
end
//
// File related functions
//
def open(path)
end
def close
spiSend(24) // CLOSE
end
def read(buf, len)
end
def write(buf, len)
end
def sync
end
def rewind
end
def seek
end
def seekOfs
end
def pos
end
def size
end
def truncate
end
def isDir
spiSend(35) // ISDIR
return spiSend(35)//spiRecv
end
def isFile
end
//
// Init SD card FAT filesystem
//
spiSend(14) // SDINIT
spiDelay(100)
return spiRecv <> '@' // Is Arduino READY?
done

240
src/libsrc/spiport.pla Normal file
View File

@ -0,0 +1,240 @@
import cmdsys
predef call, putc
end
//
// Bit banged spi over gameport
//
asm spiInc
!SOURCE "vmsrc/plvmzp.inc"
end
export asm spiXferByte(outbyte)
STA $C05A ; ENABLE SLAVE
LDY #0 ; ASSUME MSB IS ZERO
LDA ESTKL,X ; GET ARGUMENT
BPL + ; CHECK MSB
INY ; IT'S A ONE
+ STA $C058,Y ; WRITE BIT 7
STA $C040 ; CLOCK
LDY #0 ; DOING THIS HERE GIVES TIME FOR OUTPUT TO BECOME STABLE - NOT REALLY NEEDEDd
ASL $C061 ; READ BIT 7 INTO CARRY
ROL ; ROTATE INTO ACC
BPL + ; REPEAT FOR ALL BITS
INY
+ STA $C058,Y
STA $C040
LDY #0
ASL $C061
ROL
BPL +
INY
+ STA $C058,Y
STA $C040
LDY #0
ASL $C061
ROL
BPL +
INY
+ STA $C058,Y
STA $C040
LDY #0
ASL $C061
ROL
BPL +
INY
+ STA $C058,Y
STA $C040
LDY #0
ASL $C061
ROL
BPL +
INY
+ STA $C058,Y
STA $C040
LDY #0
ASL $C061
ROL
BPL +
INY
+ STA $C058,Y
STA $C040
LDY #0
ASL $C061
ROL
BPL +
INY
+ STA $C058,Y
STA $C040
ASL $C061
STA $C05B ; DISABLE SLAVE
ROL
STA ESTKL,X ; SAVE RETURN PARAMETER
RTS
end
asm spiReadBytes(buf, len)
LDA ESTKL+1,X
STA DSTL
LDA ESTKH+1,X
STA DSTH
LDA ESTKL,X
BEQ +
INC ESTKH,X
+ LDY #$00
- STA $C05A ; ENABLE SLAVE
STA $C040 ; CLOCK
ASL $C061 ; SHIFT IN ALL BITS STARTING WITH MSB
STA $C040
ROL
ASL $C061
STA $C040
ROL
ASL $C061
STA $C040
ROL
ASL $C061
STA $C040
ROL
ASL $C061
STA $C040
ROL
ASL $C061
STA $C040
ROL
ASL $C061
STA $C040
ROL
ASL $C061
STA $C05B ; DISABLE SLAVE
ROL
STA (DST),Y ; SAVE TO BUFFER
INY
BNE +
INC DSTH
+ DEC ESTKL,X
BNE -
DEC ESTKH,X
BNE -
INX ; REMOVE AN ARGUMENT
RTS
end
asm spiWriteBytes(buf, len)
LDA ESTKL+1,X
STA SRCL
LDA ESTKH+1,X
STA SRCH
LDA ESTKL,X
BEQ +
INC ESTKH,X
+
- STA $C05A ; ENABLE SLAVE
LDY #0 ; ASSUME MSB IS ZERO
LDA (SRC),Y ; GET BYTE
BPL + ; CHECK MSB
INY ; IT'S A ONE
+ STA $C058,Y ; WRITE BIT 7
STA $C040 ; CLOCK
LDY #0 ; DOING THIS HERE GIVES TIME FOR OUTPUT TO BECOME STABLE
ROL ; ROTATE NEXT BIT TO SEND
BPL + ; REPEAT FOR ALL BITS
INY
+ STA $C058,Y
STA $C040
LDY #0
ROL
BPL +
INY
+ STA $C058,Y
STA $C040
LDY #0
ROL
BPL +
INY
+ STA $C058,Y
STA $C040
LDY #0
ROL
BPL +
INY
+ STA $C058,Y
STA $C040
LDY #0
ROL
BPL +
INY
+ STA $C058,Y
STA $C040
LDY #0
ROL
BPL +
INY
+ STA $C058,Y
STA $C040
LDY #0
ROL
BPL +
INY
+ STA $C058,Y
STA $C040
STA $C05B ; DISABLE SLAVE
INC SRCL
BNE +
INC SRCH
+ DEC ESTKL,X
BNE -
DEC ESTKH,X
BNE -
INX ; REMOVE AN ARGUMENT
RTS
end
export def spiDelay(time)
return call($fca8, time, 0, 0, 0) // DELAY
end
export def spiSend(data)
byte timeout, status
for timeout = 0 to 50 step 10
status = spiXferByte(data)
if status <> $ff
return status
fin
spiDelay(timeout)
next
putc(status);putc('0'+data/10);putc('0'+data%10)
return status
end
export def spiRecv
return spiSend(0)
end
export def spiWriteBuf(buf, len)
spiSend(13) // CMD_BUF_WRITE
spiSend(len>>8) // LEN_HI
spiSend(len) // LEN_LO
return spiWriteBytes(buf, len)
end
export def spiReadBuf(buf, len)
spiSend(12) // CMD_BUF_READ
spiSend(len>>8) // LEN_HI
spiSend(len) // LEN_LO
return spiReadBytes(buf, len)
end
export def spiReset
byte timeout, status
^$C05B
timeout = $FF
repeat
status = spiSend(0)
timeout--
until status == '@' or !timeout // WAIT FOR READY
return status <> '@'
end
return spiReset
done

View File

@ -9,6 +9,10 @@ ED = ED\#FF2000
SB = SB\#FF2000
ROD = ROD\#FE1000
SIEVE = SIEVE\#FE1000
ARGS = ARGS\#FE1000
SPIPORT = SPIPORT\#FE1000
SDFAT = SDFAT\#FE1000
FATCAT = FATCAT\#FE1000
WIZNET = WIZNET\#FE1000
UTHERNET2= UTHERNET2\#FE1000
UTHERNET= UTHERNET\#FE1000
@ -53,7 +57,7 @@ TXTTYPE = .TXT
#SYSTYPE = \#FF2000
#TXTTYPE = \#040000
all: $(PLASM) $(PLVM) $(PLVM01) $(PLVM02) $(PLVM03) $(CMD) $(MEMMGR) $(MEMTEST) $(FIBER) $(SB) $(MON) $(ROD) $(SIEVE) $(UTHERNET2) $(UTHERNET) $(ETHERIP) $(INET) $(DHCP) $(HTTPD) $(ROGUE) $(ROGUEMAP) $(ROGUECOMBAT) $(ROGUEIO) $(HGR1) $(TONE) $(DGR) $(DGRTEST) $(PORTIO)
all: $(PLASM) $(PLVM) $(PLVM01) $(PLVM02) $(PLVM03) $(CMD) $(ARGS) $(MEMMGR) $(MEMTEST) $(FIBER) $(SB) $(MON) $(ROD) $(SIEVE) $(UTHERNET2) $(UTHERNET) $(ETHERIP) $(INET) $(DHCP) $(HTTPD) $(ROGUE) $(ROGUEMAP) $(ROGUECOMBAT) $(ROGUEIO) $(HGR1) $(TONE) $(DGR) $(DGRTEST) $(PORTIO) $(SPIPORT) $(SDFAT) $(FATCAT)
clean:
-rm *FE1000 *FF2000 $(PLASM) $(PLVM) $(PLVM01) $(PLVM02) $(PLVM03)
@ -110,6 +114,10 @@ $(SB): toolsrc/sb.pla $(PLVM02) $(PLASM) toolsrc/sb.pla
./$(PLASM) -A < toolsrc/sb.pla > toolsrc/sb.a
acme --setpc 8192 -o $(SB) toolsrc/sb.a
$(ARGS): libsrc/args.pla $(PLVM02) $(PLASM)
./$(PLASM) -AM < libsrc/args.pla > libsrc/args.a
acme --setpc 4094 -o $(ARGS) libsrc/args.a
$(MEMMGR): libsrc/memmgr.pla $(PLVM02) $(PLASM)
./$(PLASM) -AM < libsrc/memmgr.pla > libsrc/memmgr.a
acme --setpc 4094 -o $(MEMMGR) libsrc/memmgr.a
@ -162,6 +170,18 @@ $(TONE): libsrc/tone.pla $(PLVM02) $(PLASM)
./$(PLASM) -AM < libsrc/tone.pla > libsrc/tone.a
acme --setpc 4094 -o $(TONE) libsrc/tone.a
$(FATCAT): samplesrc/fatcat.pla $(PLVM02) $(PLASM)
./$(PLASM) -AM < samplesrc/fatcat.pla > samplesrc/fatcat.a
acme --setpc 4094 -o $(FATCAT) samplesrc/fatcat.a
$(SDFAT): libsrc/sdfat.pla $(PLVM02) $(PLASM)
./$(PLASM) -AM < libsrc/sdfat.pla > libsrc/sdfat.a
acme --setpc 4094 -o $(SDFAT) libsrc/sdfat.a
$(SPIPORT): libsrc/spiport.pla $(PLVM02) $(PLASM)
./$(PLASM) -AM < libsrc/spiport.pla > libsrc/spiport.a
acme --setpc 4094 -o $(SPIPORT) libsrc/spiport.a
$(PORTIO): libsrc/portio.pla $(PLVM02) $(PLASM)
./$(PLASM) -AM < libsrc/portio.pla > libsrc/portio.a
acme --setpc 4094 -o $(PORTIO) libsrc/portio.a

49
src/samplesrc/fatcat.pla Normal file
View File

@ -0,0 +1,49 @@
include "inc/cmdsys.plh"
include "inc/args.plh"
include "inc/sdfat.plh"
word arg
byte[64] cwd
byte[64] pathname
def fatCat(path)
byte filename[32]
sdFAT:dirSet(path)
puts("Directory of "); puts(path); puts(":\n")
sdFAT:fileOpenFirst(@filename)
while filename
puts(" "); puts(@filename)
if sdFAT:fileIsDir(); putc('/'); fin
putln
sdFAT:fileClose()
sdFAT:fileOpenNext(@filename)
loop
end
sdFAT:dirGet(@cwd)
if cwd[cwd] <> '/' // append '/' to cwd if needed
cwd++
cwd[cwd] = '/'
fin
arg = argNext(argFirst)
if ^arg
while ^arg
if ^(arg + 1) <> '/' // relative path argument - append to cwd
memcpy(@pathname, @cwd, cwd + 1)
else
pathname = 0 // absolute path
fin
memcpy(@pathname + pathname + 1, arg + 1, ^arg) // append path argument
pathname = pathname + ^arg
if pathname[pathname] <> '/'
pathname++
pathname[pathname] = '/'
fin
fatCat(@pathname)
arg = argNext(arg)
loop
else
fatCat(@cwd)
fin
done

View File

@ -33,7 +33,7 @@ predef loadmod, execmod, lookupstrmod
//
// System variable.
//
word version = $0092 // 00.92
word version = $0093 // 00.93
word systemflags = 0
word heap
word xheap = $0800
@ -1188,9 +1188,10 @@ def striptrail(strptr)
for i = 1 to ^strptr
if ^(strptr + i) <= ' '
^strptr = i - 1
return
return strptr
fin
next
return strptr
end
def parsecmd(strptr)
byte cmd
@ -1317,7 +1318,7 @@ while 1
execsys(@cmdln)
break
is '+'
execmod(@cmdln)
execmod(striptrail(@cmdln))
break
otherwise
cout('?')