Hardware/EIR/MMC

From Nutwiki
Jump to: navigation, search

EIR Memory Card Support

Hardware

As explained on this page, the MMC socket is not connected to the hardware SPI. The following table shows the signals and pins:

GPIO Periph. A Periph. B MMC Pin SD-Card Mode SDIO Mode SPI Mode EIR Conn.
PA15 TF A15 1 Unused CD/DAT3 CS K1-16
PA16 TK A16/BA0 5 CLK CLK SCK K1-17
PA17 TD A17/BA1 2 CMD CMD MOSI K1-18
PA18 RD NBS3/CFIOW 7 DATA DAT0 MISO K1-19
PA19 RK NCS4/CFCS0 8 IRQ DAT1 Unused K1-20
PA20 RF NCS2/CFCS1 9 RW DAT2 Unused K1-21

Two additional GPIO pins are connected to the card detection and write protect switches of the memory card socket:

GPIO Periph. A Periph. B Card Socket EIR Conn.
PC18 A20 NANDWE Card detect K3-19
PC19 A21/NANDALE   Write protect K3-20

SPI Bit Banging Driver

This driver is available since Nut/OS 4.8 in the following source code files:

nut/dev/sbi_mmc.c Low level memory card routines with SPI read and write functions as well as card and write protect detection. They are used by the block driver routines in nut/dev/mmcard.c.
nut/dev/sbi0mmc0.c Settings for "MMC0" (devSbi0MmCard0), which drives first card socket connected to the first SPI. The actual code is generated by including the source from nut/dev/sbi_mmc.c.
nut/dev/sbi0mmc1.c Settings for "MMC1" (devSbi0MmCard1), which drives second card socket connected to the first SPI. The actual code is generated by including the source from nut/dev/sbi_mmc.c.
nut/dev/sbi1mmc0.c Settings for "MMC2" (devSbi1MmCard0), which drives first card socket connected to a secondary SPI. The actual code is generated by including the source from nut/dev/sbi_mmc.c.
nut/dev/sbi1mmc1.c Settings for "MMC3" (devSbi1MmCard1), which drives second card socket connected to a secondary SPI. The actual code is generated by including the source from nut/dev/sbi_mmc.c.
nut/include/dev/sbi_mmc.h Header file, which needs to be included by the application, either directly or via dev/board.h.

This portable driver can be configured with the Nut/OS Configurator. Typically this is done when loading the EIR configuration file eir10c.conf.

[[eir10_mmc_bitbang_conf.png|File:Eir10 mmc bitbang conf 460px.png]] As expected, the performance of the bit banging driver is lousy. The following figures had been attained from a no-name micro-SD card.

Writing    64 byte blocks for 10s...9 kBytes/s
Writing   128 byte blocks for 10s...9 kBytes/s
Writing   256 byte blocks for 10s...10 kBytes/s
Writing   512 byte blocks for 10s...16 kBytes/s
Reading    64 byte blocks...24 kBytes/s
Reading   128 byte blocks...24 kBytes/s
Reading   256 byte blocks...28 kBytes/s
Reading   512 byte blocks...28 kBytes/s

SPI Bus Based Driver

In opposite to the bit banging driver explained above, the newer [[../../documents/ntn-6_spi.html|SPI bus based drivers]] allow to concurrently access several devices on the same SPI bus. Actually this had been possibly with the old driver model as well, but the application needs to take care that accesses do not overlap. In the new driver model, the bus controller driver is separated from the device driver and serializes their access.

The required drivers for the EIR are available since Nut/OS 5.0 in the following source code files:

nut/arch/arm/dev/atmel/spibus_at91ssc.c General SPI over SSC bus controller routines.
nut/arch/arm/dev/atmel/spibus0at91ssc.c SPI over SSC bus controller routines, that are specific for the first bus.
nut/include/dev/spibus_ssc.h Header file, which needs to be included by the application, either directly or via dev/board.h.
nut/dev/spi_mmc.c General memory card routines, which based on an SPI bus driver.
nut/dev/spi_mmc_gpio.c Memory card support routines, mainly GPIO functions for hardware initialization, card detect and write protect. It also includes the device structure, which makes use of nut/dev/spi_mmc.c to implement the driver.
nut/include/dev/spi_mmc_gpio.h Header file, which needs to be included by the application, either directly or via dev/board.h.

No special configuration required for the bus controller driver, because it has been specifically designed for the AT91SAM7SE CPU that is mounted on the EIR board. All memory card specific configuration items are either included in the eir10c.conf file or used with default values. However, earlier versions of the configuration file do not include the settings for the card detect and write protect switches. You may add them manually.

[[eir10_mmc_socket_conf.png|File:Eir10 mmc socket conf 480px.png]] The performance gain compared to the bit banging driver is quite impressive. The following figures had been attained from the same micro-SD card as above.

Writing    64 byte blocks for 10s...28 kBytes/s
Writing   128 byte blocks for 10s...26 kBytes/s
Writing   256 byte blocks for 10s...30 kBytes/s
Writing   512 byte blocks for 10s...37 kBytes/s
Writing  1024 byte blocks for 10s...256 kBytes/s
Writing  2048 byte blocks for 10s...359 kBytes/s
Writing  4096 byte blocks for 10s...436 kBytes/s
Reading    64 byte blocks...114 kBytes/s
Reading   128 byte blocks...161 kBytes/s
Reading   256 byte blocks...198 kBytes/s
Reading   512 byte blocks...229 kBytes/s
Reading  1024 byte blocks...242 kBytes/s
Reading  2048 byte blocks...242 kBytes/s
Reading  4096 byte blocks...242 kBytes/s

Application Code

An application that wants to use an MMC driver, must register it first. For the bit banging driver this is done by simply calling

#include <dev/sbi_mmc.h>

NutRegisterDevice(&devSbi0MmCard0, 0, 0);

When using the new SSC based driver, the registration requires a different call and different header files to attach the MMC driver to the SPI bus:

#include <dev/spibus_ssc.h>
#include <dev/spi_mmc_gpio.h>

NutRegisterSpiDevice(&devSpiMmcGpio, &spiBus0Ssc, 0);

All these registration functions initialize the hardware and return 0 on success or -1 in case of an error. The following part is identical for all MMC drivers.

Typically, applications will use the FAT file system to access the data on the card. In fact, Nut/OS currently doesn't support any other. The Nut/OS PHAT filesystem driver supports FAT12, FAT16 and FAT32 including long filename support. Also this driver needs to be registered:

NutRegisterDevice(&devPhat0, 0, 0);

Now the application is ready to mount the file system on the memory card by using a C standard function:

#include <io.h>
#include <fcntl.h>

int volid;

volid = _open("MMC0:1/PHAT0", _O_RDWR | _O_BINARY);

The path is composed of following parts: Name of the memory card driver, followed by a colon, followed by the number of the partition, followed by a slash and finally followed by the name of the file system driver.

The function returns a file handle (volume identifier) or -1 if the mounting failed. Depending on the format of the memory card, this call may take several seconds, or even a few minutes with the bit banging driver.

When successfully mounted, the application code can use all supported C standard functions to create, delete, read or write files.

Before removing the card or switching off the power supply, the application should close all open files and unmount the file system with

_close(volid);

This is mandatory, if data had been written. Otherwise the file system may become corrupted. There is currently no support in Nut/OS to repair corrupted FAT filesystems.

Known Problems

While MultiMedia and SD-Cards seem to work, I'm not able to mount SDHC cards.

Support for SDHC cards had been added since Nut/OS 5.0.5.

When trying to mount cards formatted with FAT12 or FAT16, the related open call never returns.

This bug has been fixed in Nut/OS 5.0.5.

The bit banging driver works on the EIR board, but the SPI/SSC bus controller doesn't.

When using the bus controller driver, it is required to short pins 17 and 20 at port A connector K1, as explained on this page.

The bit banging driver fails to read blocks larger than 512 bytes.

There is currently no fix available.




Return to the EIR project page.