**4-bit SD mode SD card driver plug-in to Flexspin's FAT filesystem layer** ================================================================ * Propeller 2 only. Can be used with Spin2, Basic, C and any languages supported by the Flexspin compiler. * Multi-cog and multi-SD card capable, as of v1.2. Per-transaction pin management allows multiple cogs to access a single card. * Requires Flexspin compiler version 7.0.0 or later. The example tester uses the newly added _vfs_open_fat_handle() API, replacing the older preset list of vfs device open functions. The driver itself uses newly added features around "inline" assembly. Spin/Basic support for C's ioctl() function requires Flexspin version 7.5.1 or later. * Requires a 4-bit wired SD slot. Pull-ups are required. Main wiring restriction is the four DAT pins have to be in-order on 4-bit pin boundary. Examples: * * https://forums.parallax.com/discussion/174988/new-sd-mode-p2-accessory-board/p1 * * https://forums.parallax.com/discussion/comment/1570122/#Comment_1570122 * * A basic 4-bit SD slot, without power switch, by hand wired pillaged SD slot - https://forums.parallax.com/discussion/comment/1563018/#Comment_1563018 * Writes can easily exceed 10 MB/s on fast cards, and reads 20 MB/s. There is also the option of disabling block read CRC processing to allow reads at sysclock/2. Default is sysclock/4. * There is two example programs that demonstrate mounting and use of the drivers as plug-ins. You'll need to dig around the examples to eke out the details. They are defaulted to using 1-bit SPI mode driver and the boot slot pin-out. * Also included is two other drivers, using 1-bit SPI mode. One is just a copy of Flexspin's built-in sdmm.cc driver repackaged to be a plug-in. The other is a rehash that plainly bit-bashes the SPI instead of using any smartpins. ---------------------------------------------------------------- **Driver Open/Init Declaration** ---------------------------------------------------------------- vfs_file_t *_sdsd_open( int pclk, int pcmd, int pdat0, int ppwr, int pled ); pclk is Prop2 pin for SD card CLK pcmd is Prop2 pin for SD card CMD pdat0 is Prop2 pin for SD card DAT0 ppwr is Prop2 pin for SD slot power switch pled is Prop2 pin for SD slot activity LED **Driver Runtime ioctl() Settings** ---------------------------------------------------------------- |CTRL# | Driver symbol | Parameter | Description |------|------------------|------------|------------------ | 70 | CTRL_READCRC | 0/1 | Get existing and newly set block-read CRC processing flag. Default is 1 (Enabled). | 72 | CTRL_CLKDIV | 0..65535 | Get existing and newly set clock-divider value. Default is 4. **Spin2 Snippet For Mounting SD Card** ---------------------------------------------------------------- ``` PRI mountsd() | handle, rc, clkdiv c.puts(string(" Driver = sdsd")) handle := sddrv._sdsd_open(3, 2, 4, -1, 0) rc := c.mount(string("/sd"), c._vfs_open_fat_handle(handle)) if rc c.printf(string(" device open failed! handle = %x, mount() = %d, errno = %d: %s",13,10), ... handle, rc, errno, c.strerror(errno)) abort 1 clkdiv := 3 ' adjust clock divider from sysclock/4 to sysclock/3 c._ioctl(handle, 72, @clkdiv) ' supported from Flexspin v7.5.1 ```
---------------------------------------------------------------- **Getting Familiar With Demonstration Source Code** ---------------------------------------------------------------- The user API is via the standard libc file operations, like fopen()/fclose()/fread()/fwrite() etc. Or via Posix equivalents like open()/close()/read()/write() etc. They are well documented in C references manuals. In the demonstration speed tester source code, the mountsd() function/method shows how to init the driver. Ahead of that is the driver object attaching. In C it's a struct __using(). In Spin2 it's an OBJ entry, alongside the additional libc.spin2 entry to provide the needed support in Spin2. There is a few optional source lines within mountsd() function. They're each commented out. First is which driver object to attach. Then the open/init of the driver with the specific I/O pins to use. The following example selects the 4-bit SD mode driver and uses a list of pin constants (as per top of source file) for Roger Loh's 4-bit SD slot add-on board. ``` OBJ c: "libc.spin2" sddrv: "blkdrvr/sdsd.cc" ' mmdrv: "blkdrvr/sdmm_bashed.cc" ' mmdrv: "blkdrvr/sdmm.cc" PRI mountsd() | handle, clkdiv ' c.printf(string(" Driver = sdmm",13,10)) ' c.printf(string(" Driver = sdmm_bashed",13,10)) ' handle := c._sdmm_open(CLK_EVAL, CS_EVAL, MOSI_EVAL, MISO_EVAL) ' handle := c._sdmm_open(CLK_RL, CS_RL, MOSI_RL, MISO_RL) ' handle := mmdrv._sdmm_open(CLK_EVAL, CS_EVAL, MOSI_EVAL, MISO_EVAL) ' handle := mmdrv._sdmm_open(CLK_RL, CS_RL, MOSI_RL, MISO_RL) ' handle := mmdrv._sdmm_open(CLK_EH, CS_EH, MOSI_EH, MISO_EH) c.printf(string(" Driver = sdsd",13,10)) handle := sddrv._sdsd_open(CLK_RL, CMD_RL, DAT0_RL, PWR_RL, LED_RL) ' handle := sddrv._sdsd_open(CLK_EH, CMD_EH, DAT0_EH, -1, -1) ``` The following example selects the built-in 1-bit SPI mode driver and uses a list of pin constants for the boot SD slot. ``` OBJ c: "libc.spin2" ' sddrv: "blkdrvr/sdsd.cc" ' mmdrv: "blkdrvr/sdmm_bashed.cc" ' mmdrv: "blkdrvr/sdmm.cc" PRI mountsd() | handle, clkdiv c.printf(string(" Driver = sdmm",13,10)) ' c.printf(string(" Driver = sdmm_bashed",13,10)) handle := c._sdmm_open(CLK_EVAL, CS_EVAL, MOSI_EVAL, MISO_EVAL) ' handle := c._sdmm_open(CLK_RL, CS_RL, MOSI_RL, MISO_RL) ' handle := mmdrv._sdmm_open(CLK_EVAL, CS_EVAL, MOSI_EVAL, MISO_EVAL) ' handle := mmdrv._sdmm_open(CLK_RL, CS_RL, MOSI_RL, MISO_RL) ' handle := mmdrv._sdmm_open(CLK_EH, CS_EH, MOSI_EH, MISO_EH) ' c.printf(string(" Driver = sdsd",13,10)) ' handle := sddrv._sdsd_open(CLK_RL, CMD_RL, DAT0_RL, PWR_RL, LED_RL) ' handle := sddrv._sdsd_open(CLK_EH, CMD_EH, DAT0_EH, -1, -1) ```