**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, // Prop2 pin number for SD card CLK int pcmd, // Prop2 pin number for SD card CMD int pdat0, // Prop2 pin number for SD card DAT0 int ppwr, // Prop2 pin number for SD slot power switch int pled ); // Prop2 pin number for SD slot activity LED ``` **Driver Runtime ioctl() Settings** ---------------------------------------------------------------- |CTRL# | Driver symbol | Parameter | Description |------|------------------|------------|------------------ | 70 | CTRL_READCRC | 0/1 | Set, and get existing, block-read CRC processing flag. Default is 1 (Enabled). | 72 | CTRL_CLKDIV | 2..65535 | Set, and get existing, clock-divider value. Default is 4. **Spin2 Snippet For Mounting SD Card** ---------------------------------------------------------------- The following example selects the built-in 1-bit SPI mode driver and the boot-SD slot pin numbers. Note the older `_vfs_open_sdcardx()` init is not used now. ``` CON #58, MISO_EVAL, MOSI_EVAL, CS_EVAL, CLK_EVAL ' Prop2 boot pins, as per the Prop2 ROM OBJ c: "libc.spin2" PRI mountsd() | handle, rc c.printf(string(" Driver = sdmm",13,10)) handle := c._sdmm_open(CLK_EVAL, CS_EVAL, MOSI_EVAL, MISO_EVAL) 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 ```
**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. There is a few optional source lines within mountsd() function. They're each commented out. First is which driver object to bundle. The following case selects the 4-bit SD mode driver and initialises the driver with pin numbers (constants at top of source file) for Roger Loh's 4-bit SD slot add-on board. And finally, the optional ioctl() calls can change the defaults for: Processing CRC of read data, and Adjusting the data rate clock divider value. These two controls are special to the SDSD (4-bit) driver only. ``` OBJ c: "libc.spin2" sddrv: "blkdrvr/sdsd.cc" ' mmdrv: "blkdrvr/sdmm_bashed.cc" ' mmdrv: "blkdrvr/sdmm.cc" PRI mountsd() | handle, rc, 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) 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 ' NOTE: Spin2 use of ioctl() is supported from Flexspin v7.5.1 clkdiv := 0 ' disable read-block CRC processing ' c._ioctl(handle, 70, @clkdiv) clkdiv := 3 ' adjust clock divider from sysclock/4 to sysclock/3 ' c._ioctl(handle, 72, @clkdiv) ```