Skip to main content

SD/MMC Cards

SD and MMC cards are exposed through TinyCLR's File System library, with the FAT16/FAT32 file system handled by the built-in driver. SD cards over the built-in SDIO interface use one StorageController name; SPI-attached SD cards go through the ManagedFileSystem software utility driver.

NuGet packages: GHIElectronics.TinyCLR.IO, GHIElectronics.TinyCLR.Devices.Storage, and GHIElectronics.TinyCLR.Pins.

Mounting an SD card​

using GHIElectronics.TinyCLR.Devices.Storage;
using GHIElectronics.TinyCLR.IO;
using GHIElectronics.TinyCLR.Pins;

var sd = StorageController.FromName(FEZBit.StorageController.SdCard);
var drive = FileSystem.Mount(sd.Hdc);

Once mounted, drive.Name gives you the root path (something like A:\) — pass it to DirectoryInfo, FileStream, and the rest of System.IO to read and write files.

Reading and writing files​

See the File System page for a complete read/write example. The short version:

using System.IO;
using System.Text;
using GHIElectronics.TinyCLR.IO;

var file = new FileStream(drive.Name + "log.txt", FileMode.OpenOrCreate);
file.Write(Encoding.UTF8.GetBytes("hello"), 0, 5);
file.Flush();

FileSystem.Flush(sd.Hdc); // Flush the file-system buffers to the card.
tip

Always call FileSystem.Flush(sd.Hdc) before removing power or pulling the card — otherwise pending writes can be lost.

SPI-attached SD cards​

When the SD card is wired over SPI instead of the native SDIO interface, use the ManagedFileSystem software utility driver to bridge the SPI bus to the file-system layer.

The same FAT16/FAT32 file-system code from the File System page works on top of it — only the controller setup differs. Check the driver's source in the TinyCLR-Drivers repo for the current API.

Advanced: tuning the SD clock speed​

The default SDMMC clock runs at 25 MHz. Some board designs or low-cost SD cards can't keep up cleanly at that speed and need a slower clock for reliable operation. The clock divider is exposed through a Marshal write to a TinyCLR-internal configuration address:

using System;
using System.Runtime.InteropServices;

const int SD_CLOCK_ADDRESS_REG = 0x00000004;

// Divider: 0,1,2,3 → 25 MHz; 4 → 12 MHz; 5 → 10 MHz; 6 → 8 MHz; ...
var clockDivider = 4;

Marshal.WriteInt32((IntPtr)SD_CLOCK_ADDRESS_REG, clockDivider);

Use this only if you're seeing read/write errors that go away at lower clock speeds. Most boards run reliably at the default and don't need tuning.

API reference​

NamespaceDescription
GHIElectronics.TinyCLR.Devices.StorageStorage controller for mounting SD cards
GHIElectronics.TinyCLR.IOFile system I/O classes