This is an old revision of the document!
Secure Digital (SD) is non-volatile memory card format. The Secure Digital standard is maintained by the SD Card Association (SDA) for use in portable electronic devices. SD-card working voltage is 3.3 V. Communication with a card is carried out by its SD input/output interface but can also be possible using SPI bus. SPI is best for interfacing SD-cards with microcontroller.
SD-card is basically a large quantity of memory bits which can be modified but they are difficult to understand when interfaced with other devices. Therefore file system is used to solve this problem that enables to work with files instead of full memory matrix. The most important function of a file system is to organize files logically in hard drive. The memory volume is allocated to sectors which size is usually 512 bytes. As file system functionality is better when working with large units, sectors are organized to clusters. Clusters are some integer value of consecutive sectors. If cluster size is large, large file fragmentation decreases but wasted space increases when files are small as some clusters are only partly filled.
Portative memory devices and cards use usually FAT (File Allocation Table) file system which is supported by all common operation systems. FAT file system file location table includes every file starting cluster address in drive which in turn includes index to next cluster related to the file and so on, until the ending cluster of file. Clusters in FAT are indexed with 12 b(FAT12), 16 b (FAT16) or 32 b (FAT32) size table addresses depending on version. Therefore older FAT versions caused large cluster sizes which is inefficient use of space in case of large drive volumes.
HomeLab controller module has a slot for Micro SD memory card. This is connected to the same SPI bus that Ethernet controller uses.
HomeLab library has two layers for communicating with SD-card. The first layer is directly related to communicating with drive and initialization. There are also functions to read and write to drive. The other file system layer communicates with the first layer and allows operations with files. Supported and tested are FAT12, FAT16 and FAT32 file systems.
Overview of FatFs file system package used in HomeLab library: siit.
The following example demonstrates reading and writing to a text file. If button S1 is pressed, drive and memory system is initialized. Pressing button S3 will create a directory to the drive, to where a new file with content is also created. Button S2 displays the content of created file in LCD.
#include <stdio.h> #include <homelab/module/ff.h> #include <homelab/module/diskio.h> #include <homelab/delay.h> #include <homelab/pin.h> #include <homelab/module/lcd_gfx.h> // LED pins pin led_red = PIN(C, 5); pin led_yellow = PIN(C, 4); pin led_green = PIN(C, 3); // Button pins pin button1 = PIN(C, 0); pin button2 = PIN(C, 1); pin button3 = PIN(C, 2); int main (void) { int f_err_flag = -1; //Drive error flag int d_err_flag = -1; //File system error flag char f_err_buf[16]; char d_err_buf[16]; int variableName = 0; static FATFS FATFS_Obj; FIL fil_obj; char read_buf[20]; unsigned char new_value1, old_value1 = 0; unsigned char new_value2, old_value2 = 0; unsigned char new_value3, old_value3 = 0; // Initialize LED's pin_setup_output(led_red); pin_setup_output(led_yellow); pin_setup_output(led_green); // Initialize buttons pin_setup_input_with_pullup(button1); pin_setup_input_with_pullup(button2); pin_setup_input_with_pullup(button3); // All LED's are off pin_set(led_green); pin_set(led_yellow); pin_set(led_red); // LCD initialization lcd_gfx_init(); // LCD blanking lcd_gfx_clear(); lcd_gfx_backlight(true); // Set curson to the middle of display (invisible) lcd_gfx_goto_char_xy(3, 2); // Display program name lcd_gfx_write_string("SD Card"); while (1) { // Read button values new_value1 = pin_get_debounced_value(button1); new_value2 = pin_get_debounced_value(button2); new_value3 = pin_get_debounced_value(button3); // Button S1 is pressed, register only one press if((!new_value1) && (old_value1)) { // Initialize SD-card, set error flag if failed d_err_flag = disk_initialize(0); // Delay sw_delay_ms(2); // File system initialization, // set error flag if failed f_err_flag = f_mount(0, &FATFS_Obj); // Delay sw_delay_ms(2); } // Button S2 is pressed, register only one press if((!new_value2) && (old_value2)) { // Open file "file.txt" in read mode f_open(&fil_obj, "/Homelab/file.txt", FA_READ); // Read the 14 first chars from file f_gets (read_buf,14, &fil_obj); f_close(&fil_obj); // Write the 14 first chars to LCD lcd_gfx_goto_char_xy(0, 0); lcd_gfx_write_string(read_buf); } // Button S3 is pressed, register only one press if((!new_value3) && (old_value3)) { // A random variable is saved to file variableName = 4; // Create folder "Homelab" to the drive f_mkdir("Homelab"); // Create text file "file.txt" to folder f_open(&fil_obj, "/Homelab/file.txt", FA_CREATE_NEW); // Open file in write mode f_open(&fil_obj, "/Homelab/fail.txt", FA_WRITE); // Write to file f_printf(&fil_obj, "Variable: %d", variableName); // Close file f_close(&fil_obj); } // Save the previous value of a button old_value1 = new_value1; old_value2 = new_value2; old_value3 = new_value3; // If SD-card is initialized and working, // if successful then set green LED on // If not, set red LED on if((f_err_flag == 0) && (d_err_flag == 0)) { pin_clear(led_green); pin_set(led_red); } else { pin_set(led_green); pin_clear(led_red); } // Display error flags states, these are: // -1 uninitialized // 0 no error // 1 (and up) error sprintf(f_err_buf, "Error_f: %02d", f_err_flag ); sprintf(d_err_buf, "Error_d: %02d", d_err_flag ); lcd_gfx_goto_char_xy(0, 4); lcd_gfx_write_string(f_err_buf); lcd_gfx_goto_char_xy(0, 5); lcd_gfx_write_string(d_err_buf); // Delay sw_delay_ms(2); } }