HOME

HARDWARE

SOFTWARE

IMAGES

SOURCE

DOWNLOADS

LINKS

EMBEDDED SD/MMC CARD INTERFACE WITH FAT32 FILESYSTEM SUPPORT

 

SD/MMC Drivers:

All the SD/MMC card functions are collectively given in “mmc.h”. User code should only call file_open() and append_file() unless you are sure of what you are doing.

 

uint8_t spi (uint8_t d)

          Initiate an SPI transaction – send byte d to the slave and return the 8 bit response from the slave

 

void sendcommand(uint8_t command, uint8_t a, uint8_t b, uint8_t c, uint8_t d, uint8_t crc);

     Send the 48-bit command with 8 bit command index command, 32 bit parameter a b c d, and 8 bit CRC.

 

uint8_t card_response();

  Get response byte from the card. Keep sending 0xFF to the card till a valid byte (not 0xFF) is returned. If, in 700 tries, no valid response is forthcoming, return 0xFF, indicating failure. Number of attempts requires optimisation.

 

uint8_t mmc_init();

Initialise the SD/MMC card. If successful return 1, else return 0. TODO – make the card type identification more rigorous. Can support for HCSD cards be added?

 

uint8_t mmc_read_sector(uint32_t address);

  Read a sector specified by the 32 bit sector address and store it in RAM in the 512 byte variable pointed to by buffer. Returns 1 for success and 0 for failure.

 

uint8_t mmc_read_sector_x(uint32_t address);

  Internal operation for mmc_read_sector(). Must never be called by user code. Ensures that a sector that is already in the buffer will not be read from the card.

 

uint8_t mmc_filesystem_init();

Initialises the filesystem present on the card after verifying that it is FAT32. Returns 1 for success and 0 for failure. In case filesystem initialisation fails the user code must NOT write to the card, else risk destroying existing data and making the card permanently unusable.

TODO – the check for FAT32 has to be made more robust.

 

uint8_t mmc_write_sector(uint32_t address);

     Writes the data from buffer in RAM to sector on card specified by address. Returns 1 for success and 0 for failure. TODO: Seen to return success in the rare case when a sector is write protected in software.

 

uint8_t create_file();

  Looks into the first sector of the root directory of the file system.  If the root directory is empty, creates a file named “AVR.txt” and adds 512 bytes of junk data to it.  Returns 1 for success and 0 for failure. Users can instead customise the content of this first 512 byte sector.

 

uint32_t buffered_sector= 0xffffffff;

     Global variable that stores the address of the last sector copied into the buffer. Any code that modifies the buffer must first set this variable to an invalid value (eg 0x00). Before a sector is read by mmc_read_sector() this variable is checked to eliminate redundant card reads.

 

uint8_t file_open();

      Encapsulated form of all initialisation procedures. Results in success (Return value 1) if SD/MMC initialisation succeeds, file system check succeeds, root directory is empty and file create is successful. Else returns 0.

 

uint8_t append_file();

          Appends 512 bytes of data from RAM buffer to the file created by file_open(). First data is written, the FATs are updated, then file entry is updated with the new file size. The create/modify/accessed dates are spoofed since there is no real time clock on this hardware. Users must add this functionality as per their requirements.

 

global filesystem related variables

volatile uint32_t LBA_offset = 0, fat_offset_a, fat_offset_b, max_sectors, last_cluster_written=0, file_size=0;

 

LBA_offset    :                  offset to the data area of the card. (file area). Must not be used if 0.

Fat_offset_a :                  offset to the primary FAT (File Allocation Table). Must not be used if 0.

Fat_offset_a :                  offset to the backup FAT (File Allocation Table). Must not be used if 0.

Max_sectors :                  Last valid sector of the data area. File append must check to see that this is not crossed.

Last_cluster_written:        Cluster number of the last cluster written to the file. Checked and updated by update file

 

uint8_t *buffer;

Pointer to the 512 byte variable in ram that is used as temporary storage. Must be initialised (by user code) before any function call that reads or writes data on the SD/MMC card. See example program.

 

#define CMD0 0x40  //software reset; GO_IDLE_STATE

The file also contains the hexadecimal values and descriptive names of commands used in the SPI mode.

 

USART driver: “USART.h”

 

This driver file contains all the standard USART functions for using the RS232 port as an I/O terminal. Users may use their own drivers if required.

 

void delay (uint16_t k);

Low level loop based delay function.

 

void USART_init();

Initialises the USART module.

 

void putbyte( char byte);

sends an 8 bit value ‘byte’ over the USART.

 

char getbyte();

Waits to receive a byte over the USART and return the received value.

 

void send_text(char *p);

Sends a text string pointed to by *p over the USART.