This fairly complicated sketch demonstrates streaming disk I/O via a simple packet protocol. It supports initializing an SD card on any face, setting the current block number, and performing buffered reads and writes to sequential addresses on the card.

Here, first I initialized to the east with 'ie', then set the block number to 20000, then wrote some data with 'w' packets, and finally read it back with 'r' packets.

  Ln 241.416 Card has 7563000 blocks
  wNow we can blast data into the disk just about
  w as fast as we can send packets.  Let's
  w do a sync now, to make sure everything's stashed safely..
  L:Now we can blast data into the d
  L:isk just about as fast as we can
  L: send packets.  Let's do a sync 
  L:now, to make sure everything's s
  L:tashed safely..[00][00][00][00][00][00][00][00][00][00][00][00][00][00][00][00][00]

In that example, I did a 'sync' between the writing and reading, but that wasn't strictly necessary -- the ensuing reads would have worked without it -- but if I'd done, say, another 'ie' instead without syncing, some or all (in this case, all) of my writes would have been lost.

Note also that when I read beyond what I'd written, I got 'null bytes', which this sketch printed as '[00]' because of the handy '#' flag provided in the '%#c' printf format. If your disk has already been used for data storage, you might see any values there instead.

// SD Card 3: Streaming buffered SD card I/O via packet commands
#include "SFBSDRaw.h"           // Load the SDRaw library

SDRaw mySD;                     // Allocate space for a raw sdcard controller
u8 buffer[512];                 // And a disk-block-sized buffer
bool initted = false;           // So we can blink different if initted
u64 lastAddress;                // Remember where we where

void doInit(u8 * packet) {      // E.g., 'iw' tries to init west
  u8 face;
  if (packetScanf(packet,"i%F\n",&face) != 3) return; // Ignore bad formats
  mySD.begin(face);             // Set up for 'IXM SD Cell' connectivity 
  if ((initted = mySD.init())) {     // Try to init, remember if it worked
    mySD.setBlockBuffer(buffer,512); // Success!  Provide a block buffer
    logNormal("Card has %d blocks\n", mySD.getBlockCount());
  lastAddress = 0;              // Reset position
void doBlock(u8 * packet) {     // Sets lastAddress to some block number
  if (!initted) return;         // Not ready
  u32 block;
  if (packetScanf(packet,"b%d\n",&block) != 3) return; // Ignore bad formats
  lastAddress = ((u64) block)*512;  // Convert to byte address
void doWrite(u8 * packet) {     // Writes contents of packet starting at lastAddress
  if (!initted) return;         // Not ready
  u32 len = packetLength(packet)-1; // All but the leading 'w'
  if (mySD.write(lastAddress,&packet[1],len)) lastAddress += len;
  else logNormal("Write failed\n");
void doRead(u8 *) {             // Read 32 bytes starting at lastAddress
  if (!initted) return;         // Not ready
  pprintf("L:");                // Start the response
  for (u32 i = 0; i < 32; ++i) {
    u8 ch;
    if (!,&ch,1)) break; // Read a byte if possible
    pprintf("%#c",ch);          // Send it out, escaping 'non-printable' bytes
  pprintf("\n");                // End the response
void doSync(u8 *) {
  if (!initted) return;         // Not ready
  mySD.sync();                  // Do it
void setup() {
  Body.reflex('i',doInit);      // Try to init the card
  Body.reflex('b',doBlock);     // Specify block number to start at
  Body.reflex('r',doRead);      // Read some bytes from the card
  Body.reflex('w',doWrite);     // Write some bytes to the card
  Body.reflex('s',doSync);      // Ensure everything's been written

void loop() { 

Generated on Fri Apr 22 06:54:11 2011 for SFB by doxygen 1.5.9