Software Framework comes to rescue: FAT32

Embedded applications make intense use of information these days, both for reading configurations and writing logs and process’ results. Developers tend to use built-in FLASH or small EEPROM memories to archive these tasks but as information gets complex, systems’ features grow and programming is done in high level languages, the need of a reliable and flexible solution takes more importance.
Is in this situation when embedded systems designers incorporates technologies available in personal computers, servers and mobile devices. Using mass storage devices like USB keys, USB-SATA disks and memory cards is a great solution for several problems including portability, capacity and reliability.
The Atmel’s AVR32 Software Framework incorporates low level drivers for SD/MMC cards, AT45DB memories and a USB mini Host driver capable of communicating with USB keys and disks. Moreover FAT12/16/32 is present as a high level API that can be connected to any low level driver.
Creating a file inside a directory, and writing something inside is as simple as this

For making use of these drivers and components the project must be configured with the following features:

  • Drivers
    • PM
    • SPI
    • USART
    • GPIO
    • INTC
  • Components
    • SD/MMC Memory Card
  • Services
    • FAT File System
    • Memory Control Access Services

Then it is necessary to set CONFIG/conf_access.h properly to activate the SD/MMC logic unit.

/*! name Activation of Logical Unit Numbers
*/
//! @{
#define LUN_0 DISABLE //!< On-Chip Virtual Memory.
#define LUN_1 DISABLE //!< AT45DBX Data Flash.
#define LUN_2 ENABLE //!< SD/MMC Card over SPI.
#define LUN_3 DISABLE
#define LUN_4 DISABLE
#define LUN_5 DISABLE
#define LUN_6 DISABLE
#define LUN_7 DISABLE
#define LUN_USB DISABLE //!< Host Mass-Storage Memory.
//! @}


/*! name Activation of Interface Features
*/
//! @{
#define ACCESS_USB DISABLED //!< MEM <-> USB interface.
#define ACCESS_MEM_TO_RAM ENABLED //!< MEM <-> RAM interface.
#define ACCESS_STREAM DISABLED //!< Streaming MEM <-> MEM interface.
#define ACCESS_STREAM_RECORD DISABLED //!< Streaming MEM <-> MEM interface in record mode.
#define ACCESS_MEM_TO_MEM DISABLED //!< MEM <-> MEM interface.
#define ACCESS_CODEC DISABLED //!< Codec interface.
//! @}

And then call this SPI initialization code from your main code:

/*! brief Initializes SD/MMC resources: GPIO, SPI and SD/MMC.
*/
static void sd_mmc_resources_init(void) {
// GPIO pins used for SD/MMC interface
static const gpio_map_t SD_MMC_SPI_GPIO_MAP = { { SD_MMC_SPI_SCK_PIN,
SD_MMC_SPI_SCK_FUNCTION }, // SPI Clock.
{ SD_MMC_SPI_MISO_PIN, SD_MMC_SPI_MISO_FUNCTION }, // MISO.
{ SD_MMC_SPI_MOSI_PIN, SD_MMC_SPI_MOSI_FUNCTION }, // MOSI.
{ SD_MMC_SPI_NPCS_PIN, SD_MMC_SPI_NPCS_FUNCTION } // Chip Select NPCS.
};
// SPI options.
spi_options_t spiOptions = {
.reg = SD_MMC_SPI_NPCS,
.baudrate = SD_MMC_SPI_MASTER_SPEED, // Defined in conf_sd_mmc_spi.h.
.bits = SD_MMC_SPI_BITS, // Defined in conf_sd_mmc_spi.h.
.spck_delay = 0, .trans_delay = 0, .stay_act = 1, .spi_mode = 0,
.modfdis = 1 };
// Assign I/Os to SPI.
gpio_enable_module(SD_MMC_SPI_GPIO_MAP, sizeof(SD_MMC_SPI_GPIO_MAP)
/ sizeof(SD_MMC_SPI_GPIO_MAP[0]));
// Initialize as master.
spi_initMaster(SD_MMC_SPI, &spiOptions);
// Set SPI selection mode: variable_ps, pcs_decode, delay.
spi_selectionMode(SD_MMC_SPI, 0, 0, 0);
// Enable SPI module.
spi_enable(SD_MMC_SPI);
// Initialize SD/MMC driver with SPI clock (PBA).
sd_mmc_spi_init(spiOptions, PBA_HZ);
}

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s