sdcard

Tessel SD module driver

Usage no npm install needed!

<script type="module">
  import sdcard from 'https://cdn.skypack.dev/sdcard';
</script>

README

SD Card

Driver for the sdcard Tessel SD Card module. The hardware documentation for this module can be found here.

This module is not compatible with Tessel 2. It is recommended that you use a USB flash storage device for Tessel 2.

If you run into any issues you can ask for support on the SD Card Module Forums.

Installation

npm install sdcard

Example

/*********************************************
This MicroSD card example writes a text file
to the SD card, then reads the file to the
console.
*********************************************/

var tessel = require('tessel');
var sdcardlib = require('sdcard');

var sdcard = sdcardlib.use(tessel.port['A']);

sdcard.on('ready', function() {
  sdcard.getFilesystems(function(err, fss) {
    var fs = fss[0];
    console.log('Writing...');
    fs.writeFile('someFile.txt', 'Hey Tessel SDCard!', function(err) {
      console.log('Write complete. Reading...');
      fs.readFile('someFile.txt', function(err, data) {
        console.log('Read:\n', data.toString());
      });
    });
  });
});

Methods

# var  sdcard = require( 'sdcard').use(port, [options], [callback (error)] )
Initialize the card driver with the given Tessel port. You may provide an optional callback taking (err) which will be registered for the ready and error (if error parameter not null) events. Valid flags for the opts argument (which is not required either) are documented below.

# sdcard.isPresent()
Returns true if there is something physically in the slot, false if not. Can be called regardless of whether the card is ready or not, unlike the read/write calls below.

# sdcard.restart()
The card driver will normally only fire the 'ready' (or 'error') event once, after the first time a card is inserted and successfully (or unsuccessfully) initialized. If you wish to receive once of those events again, call= restart() on either the 'removed' or 'inserted' events and the driver will attempt to re-initialize the SD Card.

# sdcard.getFilesystems( callback (error, array) )
Returns (error, array) with the usable filesystems found on the card, ready to use. These filesystems will expose an API similar to the node.js 'fs' module. Currently this only supports basic FAT partitions hosted within a MBR partition table, and the fatfs driver is missing some functionality and lots of test cases. Please tread with caution and report any issues you may encounter!

Events

# sdcard.on( 'ready', callback([filesystems]) )
Fired when the card interface has been initialized and is ready to use. If the getFilesystems option was set, this event will wait to fire until with a filesystem list (like that from the sdcard.getFilesystems method) can be provided as its argument.

# sdcard.on( 'error', callback(error) )
Fired if the card interface (or any filesystems, if requested) could not become ready.

# sdcard.on( 'inserted', callback() )
If the watchCard option is set, this event will be fired when the card has been physically inserted (communications probably not initialized yet!)

# sdcard.on( 'removed', callback() )
If the watchCard option is set, this event will be fired when the card has been physically removed.

Options for sdcard.use

These flags can be provided via an opts object to sdcard.use:

# getFilesystems
If set to true, the 'ready' event will be delayed until filesystems have been fetched. (See event documentation for details.) Defaults to false.

# waitForCard
When true (the default), the library will wait for a card to be physically inserted before proceeding with initialization. If set to false, then an error will be emitted if a card is not immediately detected via the sense pin.

# watchCard
If set to true, your script will never finish but the instance will emit the 'inserted' and 'removed' events as documented above. Defaults to false.

# singleWrites
Some cards fail on WRITE_MULTIPLE_BLOCK, if set to true multiple WRITE_BLOCK calls are used instead. This is slower and false by default.

Further Examples

See the examples folder for code.

Advanced Information

Low level (raw) API

# sdcard.readBlock( i, callback (error) )
Reads the ith block of data. Callback receives up to two arguments (error, data), note that if error is not null then the value of the data parameter is undetermined.

# sdcard.readBlocks( i, buffer, callback(error, destinationLength, destination) )
Starting at the ith block, reads multiple blocks into buffer and calls cb(err, bytesRead, buffer) when done. For large contiguous reads, this can be more efficient than multiple sdcard.readBlock calls. The destination buffer's length need not be an integer multiple of sdcard.BLOCK_SIZE; any extra data from the final block will simply be discarded. [Right now, bytesRead will always equal buffer.length and you are responsible for not reading off the end of the card. This may change in the future to do a partial read instead.]

# sdcard.writeBlock( i, data, callback(error) )
Overwrites the ith block with data, which must be exactly 512 bytes long. Callback is given (error), which will be null if the write was successful. Note that at the card level, a single block write usually requires a full read/erase/rewrite operation against an entire page of blocks — see sdcard.writeBlocks if you are writing several contiguous blocks of data.

# sdcard.writeBlocks( i, data, callback(error) )
Starting at the ith block, first erases and then overwrites multiple blocks with the contents of buffer, calling cb(err) when done. The length of data must be an integer multiple of sdcard.BLOCK_SIZE. This call is significantly more efficient than sdcard.writeBlock for any size contiguous writes.

TBD: expose how many blocks the card has available!

# sdcard.BLOCK_SIZE
Currently, this will always be 512. However, for more self-documenting code or for compatibility with (potential, not necessarily planned) a future backwards-incompatible major version of this code, you may wish to use this property.

Note that all read/write requests are serialized internally. So it is okay to request a block read immediately after starting a write request to the same block; your read will see the data from your write. However note that this serialization is on a request-by-request basis and e.g. if you write updated block data in a read callback you are responsible for making sure no other conflicting writes have been queued for that particular block in the meantime!

License

© 2014 Nathan Vander Wilt. Funding for this work was provided by Technical Machine, Inc.

BSD-2-Clause or Apache-2.0 at your option.