dnx RTOS 2.2.0 "Eagle"
 All Data Structures Functions Variables Typedefs Enumerations Enumerator Groups Pages
SDSPI Driver (SPI SD Card mode driver)

Detailed Description

Description

Driver handles SD Card by using SPI interface (mode). The SPI interface is handled by file thereby can be used by any microcontroller architecture. Driver handle all SD card communication; writing or reading the card, from user point of view, looks like write or read a regular file. Data is automatically divided to blocks. Entire SD card protocol is handled by this driver. Driver support MBR partitions. Each partition can be mounted as regular file (automatic partition offset).

Note
Make sure that MISO pin is pulled-up. Pull-up is required to correct initialize the SD Card SPI interface.

Device (drivers) connection table

Grade Device In Out
0 SD Card - SPI interface
1 SPI driver SPI interface /dev/spi_sda
2 SDSPI driver /dev/spi_sda /dev/sda
3 File system /dev/sda /mnt

Supported architectures

Details

Meaning of major and minor numbers

There is special meaning of major and minor numbers. The major number selects SD card. There is possibility to use up to 256 SD Cards. The minor number selects volume and partitions as follow:

Numeration restrictions

Major number can be set in range 0 to 255. The minor number can be used in range from 0 to 4. Each new major number is a new instance of driver that can handle SD Card.

Driver initialization

To initialize driver the following code can be used:

driver_init("SDSPI", 0, 0, "/dev/sda"); // entire volume
driver_init("SDSPI", 0, 1, "/dev/sda1"); // partition 1
driver_init("SDSPI", 0, 2, "/dev/sda2"); // partition 2
driver_init("SDSPI", 0, 3, "/dev/sda3"); // partition 3
driver_init("SDSPI", 0, 4, "/dev/sda4"); // partition 4

Card 2:

driver_init("SDSPI", 1, 0, "/dev/sdb"); // entire volume
driver_init("SDSPI", 1, 1, "/dev/sdb1"); // partition 1
driver_init("SDSPI", 1, 2, "/dev/sdb2"); // partition 2
driver_init("SDSPI", 1, 3, "/dev/sdb3"); // partition 3
driver_init("SDSPI", 1, 4, "/dev/sdb4"); // partition 4

If card does not contains any partitions then SDSPIx:0 only can be used. If card has e.g. only 1 partition (MBR exist) then only one entry can be created. Created device files can be used directly by file systems.

Driver release

To release driver the following code can be used:

driver_release("SDSPI", 0, 4); // disable supporting of card 0 partition 4
driver_release("SDSPI", 1, 1); // disable supporting of card 1 partition 1

Driver configuration

Driver configuration can be done by using SDSPI_config_t object and ioctl() function.

#include <stdio.h>
#include <stdbool.h>
#include <sys/ioctl.h>
static const char *dev_path = "/dev/spi_sda";
FILE *dev = fopen(dev_path, "r+");
if (dev) {
static const SDSPI_config_t cfg = {
.filepath = "/dev/spi_sda",
.timeout = 1000
};
if (ioctl(fileno(dev), IOCTL_SDSPI__CONFIGURE, &cfg) != 0) {
perror(dev_path);
}
fclose(dev);
} else {
perror(dev_path);
}
...

Data write

Writing data to device is the same as writing data to regular file.

Data read

Reading data from device is the same as reading data from regular file.

Card initialization

There is special ioctl() request (IOCTL_SDSPI__INITIALIZE_CARD or IOCTL_STORAGE__INITIALIZE) that initialize selected SD card. Initialization can be done on any partition (e.g. sda1) giving the same effect as initialization on master card file (e.g. sda, sdb). If initialization is already done on selected partition then is not necessary to initialize remained partitions.

After initialization the MBR table should be read by driver. In this case the ioctl() request (IOCTL_SDSPI__READ_MBR or IOCTL_STORAGE__READ_MBR) should be used. This procedure load all MBR entries and set required offsets in partition files (/dev/sdxy).

The SDSPI Driver configures some options of SPI interface. There are options that should be configured by user manually:

Card initialization example code. In this example is assumption that SPI interface is configured correctly and SPI interface is visible as /dev/spi_sda file. The SDSPI driver uses this file as SD card interface (configured in project setup tool).

#include <stdio.h>
#include <sys/ioctl.h>
// SPI interface initialization
// ...
// creating SD card nodes
driver_init("SDSPI", 0, 0, "/dev/sda");
driver_init("SDSPI", 0, 1, "/dev/sda1");
// SD Card initialization
FILE *f = fopen("/dev/sda", "r+");
if (f) {
if (ioctl(fileno(f), IOCTL_STORAGE__INITIALIZE) != 0) {
puts("SD initialization error");
} else {
if (ioctl(fileno(f), IOCTL_STORAGE__READ_MBR) != 0) {
puts("SD read MBR error");
}
}
fclose(f);
}
// file system mount
mkdir("/mnt", 0777);
mount("fatfs", "/dev/sda1", "/mnt", "");
// ...

Data Structures

struct  SDSPI_config_t
 

Macros

#define IOCTL_SDSPI__CONFIGURE   _IOW(SDSPI, 0x00, SDSPI_cfg_t*)
 SDSPI configuration. More...
 
#define IOCTL_SDSPI__INITIALIZE_CARD   IOCTL_STORAGE__INITIALIZE
 Initialize SD card (OS storage request). More...
 
#define IOCTL_SDSPI__READ_MBR   IOCTL_STORAGE__READ_MBR
 Read card's MBR sector and detect partitions (OS storage request). More...
 

Data Structure Documentation

struct SDSPI_config_t

SDSPI module configuration structure.

Data Fields
const char * filepath

File path to SPI interface.

u32_t timeout

Timeout in milliseconds.

Macro Definition Documentation

#define IOCTL_SDSPI__CONFIGURE   _IOW(SDSPI, 0x00, SDSPI_cfg_t*)
Parameters
[WR]SDSPI_config_t * SDSPI configuration object.
Returns
On success 0 is returned. On error -1 is returned and errno is set.
#define IOCTL_SDSPI__INITIALIZE_CARD   IOCTL_STORAGE__INITIALIZE
Returns
On success (card initialized) 0 is returned. On error (card not initialized) -1 is returned and errno is set.
#define IOCTL_SDSPI__READ_MBR   IOCTL_STORAGE__READ_MBR
Returns
On success (MBR detected) 0 is returned. On error -1 (MBR not exist or IO error) is returned and errno is set.