Cluso's SD Card Cog Driver for P2
Cluso99
Posts: 18,069
in Propeller 2
Release to come shortly after I test it out.
Note the attached file is a placeholder. I hope that the forum software will then let me add files.
Here is a brief description (from the code)...
Note the attached file is a placeholder. I hope that the forum software will then let me add files.
Here is a brief description (from the code)...
'' +-----------------------------------------------------------------------------------------------+ '' + * This driver is designed to run in its' own cog. + '' + * Commands and Parameters are passed from other Cog(s) via the HUB Parameter Block (mailbox) + '' + * The hub address of the HUB Parameter Block must be passed to this driver in PTRA on + '' + startup. This is achieved by performing a SETQ ptra_val immediatly before the COGINIT that + '' + loads and starts this cog. + '' + * The driver is available for use if the command byte of the mailbox is read as zero ($0) + '' + * It is essential that the Command byte is set last, after the hub buffer pointer and the + '' + sector# have been written. + '' + * The result (status) of the Command will be returned via the mailbox and the command will + '' + be cleared to zero ($0). + '' + * Read and Write Block Commands (ReadSector, WriteSector, ReadCSDCID) will read/write the + '' + data to/from HUB as pointed to in the mailbox ptrbuffer long at the sector# in the mailbox + '' + sector long. Note sector will be ignored for ReadCSDCID. + '' + * A sector is always 512 bytes. The CSDCID command will return 32 bytes. + '' +-----------------------------------------------------------------------------------------------+ '' + * It will be presumed that an SD Card presides on the designated pins. + '' + * No checks other than a quick read of the /CS pin to ensure it is HI. + '' +-----------------------------------------------------------------------------------------------+ '' + PTRA = pointer to HUB Parameter Block (mailbox) - passed by SETQ before COGINIT + '' + PTRB = pointer to Hub Buffer (for readCSDCID, readSector, writeSector data) + '' +-----------------------------------------------------------------------------------------------+Commands
SD_Idle = "0" ' no command SD_Init = "M" ' initialise the SD card (mount) SD_CSDCID = "C" ' read CSD & CID SD_Read = "R" ' read a sector SD_Write = "W" ' write a sector SD_Stop = "S" ' stop cardMailbox
' the following 4 longs are read from the mailbox atomically using SETQ command long 0 '\ command/status/xxx/xxx reserv long 0 '| reserved (later SD Pin definition) ptrbuffer long 0 '| hub address of data buffer blocknr long 0 '/ sector# to read/write '+-----------------------------------------------------------------------------+ ' | +3 | +2 | +1 | +0 | ' +---------------------------------------------------------------+ ' +$0C | <--------------------- hubDataAddress ----------------------> | Parameter3 ' +---------------------------------------------------------------+ ' +$08 | <--------------------- hubDataAddress ----------------------> | Parameter2 ' +---------------------------------------------------------------+ ' +$04 | SDpin_CS | SDpin_CLK | SDpin_DI | SDpin_DO | Parameter1 ' +---------------------------------------------------------------+ ' +$00 | LOCKID+1 | COGID+1 | Status (from) | Command (to) | Parameter0 ' +---------------------------------------------------------------+
spin2
918B
Comments
I wasn’t going for multiple block reads or writes, at least for now. There is a lot of time wasted by the cards so I’m not sure how much of a boost you’d get.
I’ve been thinking of locks for multiple cogs accessing the driver. Depends on how the mailbox works out. Currently I do a setq #4 rdlong to read the whole mailbox in 4 clocks after setup time. With this method locks should be unnecessary. Just write the 4 and read them back to ensure you were the one who got the job. Otherwise wait until the mailbox is free again. Tho thinking, locks would chew less power, and use cogatn so the sd cog could sleep.
BTW I don’t think locks on sad sectors or files will happen. I know we used them years ago on minis that were less powerful than this chip.
And I’ve been trying to convert Kyes SD file access from spin to PASM using Eric’s spin2cpp. It’s looking interesting.
For simple read only filesystem cases, there may be techniques where you can get away with no mailbox locks as you pointed out. Once there are multiple writers we'll probably want to use a locking mechanism when we write to the FAT or directories, or when anything needs to do a read/modify/write cycle within a single block for example and that same block can potentially be accessed by another COG in the meantime.
This looks good. Seems to me we are going to need an shareable object format very soon! Relocatable PASM code is one way I guess.
Here's my multi-block routine for reference:
--- read multiple sectors in continuous multiblock mode
A quick example of how to use it and how long it takes:
EDIT: just to convince you that block mode is worthwhile here are random sector read times including a sequential read of the next block. So a 300k file would take 1.5 seconds to read, about 15 times longer than the multi-block mode.