X-Git-Url: http://git.droids-corp.org/?p=protos%2Fimu.git;a=blobdiff_plain;f=sd_main.c;h=82bb8ad9061718958bad8dbc55844436fc2d2c01;hp=47298d41e8588202a4545e459f84d71d047fcdc1;hb=de6cbbfa24c5af2030ab1a46ee94bcc8b35910b9;hpb=8d98ff2833dbd04ec343be49c416166e523ad889 diff --git a/sd_main.c b/sd_main.c index 47298d4..82bb8ad 100644 --- a/sd_main.c +++ b/sd_main.c @@ -42,7 +42,7 @@ * The first one is the one I started with, but when I implemented FAT16 write * support, I ran out of flash space and switched to the ATmega168. For FAT32, an * ATmega328 is required. - * + * * The circuit board is a self-made and self-soldered board consisting of a single * copper layer and standard DIL components, except of the MMC/SD card connector. * @@ -50,7 +50,7 @@ * eject button which, when a card is inserted, needs some space beyond the connector * itself. As an additional feature the connector has two electrical switches * to detect wether a card is inserted and wether this card is write-protected. - * + * * \section pictures Pictures * \image html pic01.jpg "The circuit board used to implement and test this application." * \image html pic02.jpg "The MMC/SD card connector on the soldering side of the circuit board." @@ -78,7 +78,7 @@ * - mkdir \\n * Creates a directory called \. * - mv \ \\n - * Renames \ to \. + * Renames \ to \. * - rm \\n * Deletes \. * - sync\n @@ -122,13 +122,13 @@ * The static RAM is mostly used for buffering memory card access, which * improves performance and reduces implementation complexity. *

- * + * *

* Please note that the numbers above do not include the C library functions * used, e.g. some string functions. These will raise the numbers somewhat * if they are not already used in other program parts. *

- * + * *

* When opening a partition, filesystem, file or directory, a little amount * of RAM is used, as listed in the following table. Depending on the library @@ -157,7 +157,7 @@ * 49 * * - * + * * \endhtmlonly * * \section adaptation Adapting the software to your needs @@ -174,7 +174,7 @@ * * For further information, visit the project's * FAQ page. - * + * * \section bugs Bugs or comments? * If you have comments or found a bug in the software - there might be some * of them - you may contact me per mail at feedback@roland-riegel.de. @@ -183,7 +183,7 @@ * Thanks go to Ulrich Radig, who explained on his homepage how to interface * MMC cards to the Atmel microcontroller (http://www.ulrichradig.de/). * I adapted his work for my circuit. - * + * * \section copyright Copyright 2006-2012 by Roland Riegel * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License version 2 as published by @@ -208,7 +208,7 @@ static uint8_t read_line(char* buffer, uint8_t buffer_length); static uint32_t strtolong(const char* str); static uint8_t find_file_in_dir(struct fat_fs_struct* fs, struct fat_dir_struct* dd, const char* name, struct fat_dir_entry_struct* dir_entry); -static struct fat_file_struct* open_file_in_dir(struct fat_fs_struct* fs, struct fat_dir_struct* dd, const char* name); +static struct fat_file_struct* open_file_in_dir(struct fat_fs_struct* fs, struct fat_dir_struct* dd, const char* name); static uint8_t print_disk_info(const struct fat_fs_struct* fs); int main() @@ -221,333 +221,333 @@ int main() while(1) { - /* setup sd card slot */ - if(!sd_raw_init()) - { + /* setup sd card slot */ + if(!sd_raw_init()) + { #if DEBUG - uart_puts_p(PSTR("MMC/SD initialization failed\n")); + uart_puts_p(PSTR("MMC/SD initialization failed\n")); #endif - continue; - } + continue; + } - /* open first partition */ - struct partition_struct* partition = partition_open(sd_raw_read, - sd_raw_read_interval, + /* open first partition */ + struct partition_struct* partition = partition_open(sd_raw_read, + sd_raw_read_interval, #if SD_RAW_WRITE_SUPPORT - sd_raw_write, - sd_raw_write_interval, + sd_raw_write, + sd_raw_write_interval, #else - 0, - 0, + 0, + 0, #endif - 0 - ); - - if(!partition) - { - /* If the partition did not open, assume the storage device - * is a "superfloppy", i.e. has no MBR. - */ - partition = partition_open(sd_raw_read, - sd_raw_read_interval, + 0 + ); + + if(!partition) + { + /* If the partition did not open, assume the storage device + * is a "superfloppy", i.e. has no MBR. + */ + partition = partition_open(sd_raw_read, + sd_raw_read_interval, #if SD_RAW_WRITE_SUPPORT - sd_raw_write, - sd_raw_write_interval, + sd_raw_write, + sd_raw_write_interval, #else - 0, - 0, + 0, + 0, #endif - -1 - ); - if(!partition) - { + -1 + ); + if(!partition) + { #if DEBUG - uart_puts_p(PSTR("opening partition failed\n")); + uart_puts_p(PSTR("opening partition failed\n")); #endif - continue; - } - } - - /* open file system */ - struct fat_fs_struct* fs = fat_open(partition); - if(!fs) - { + continue; + } + } + + /* open file system */ + struct fat_fs_struct* fs = fat_open(partition); + if(!fs) + { #if DEBUG - uart_puts_p(PSTR("opening filesystem failed\n")); + uart_puts_p(PSTR("opening filesystem failed\n")); #endif - continue; - } + continue; + } - /* open root directory */ - struct fat_dir_entry_struct directory; - fat_get_dir_entry_of_path(fs, "/", &directory); + /* open root directory */ + struct fat_dir_entry_struct directory; + fat_get_dir_entry_of_path(fs, "/", &directory); - struct fat_dir_struct* dd = fat_open_dir(fs, &directory); - if(!dd) - { + struct fat_dir_struct* dd = fat_open_dir(fs, &directory); + if(!dd) + { #if DEBUG - uart_puts_p(PSTR("opening root directory failed\n")); + uart_puts_p(PSTR("opening root directory failed\n")); #endif - continue; - } - - /* print some card information as a boot message */ - print_disk_info(fs); - - /* provide a simple shell */ - char buffer[24]; - while(1) - { - /* print prompt */ - uart_putc('>'); - uart_putc(' '); - - /* read command */ - char* command = buffer; - if(read_line(command, sizeof(buffer)) < 1) - continue; - - /* execute command */ - if(strcmp_P(command, PSTR("init")) == 0) - { - break; - } - else if(strncmp_P(command, PSTR("cd "), 3) == 0) - { - command += 3; - if(command[0] == '\0') - continue; - - /* change directory */ - struct fat_dir_entry_struct subdir_entry; - if(find_file_in_dir(fs, dd, command, &subdir_entry)) - { - struct fat_dir_struct* dd_new = fat_open_dir(fs, &subdir_entry); - if(dd_new) - { - fat_close_dir(dd); - dd = dd_new; - continue; - } - } - - uart_puts_p(PSTR("directory not found: ")); - uart_puts(command); - uart_putc('\n'); - } - else if(strcmp_P(command, PSTR("ls")) == 0) - { - /* print directory listing */ - struct fat_dir_entry_struct dir_entry; - while(fat_read_dir(dd, &dir_entry)) - { - uint8_t spaces = sizeof(dir_entry.long_name) - strlen(dir_entry.long_name) + 4; - - uart_puts(dir_entry.long_name); - uart_putc(dir_entry.attributes & FAT_ATTRIB_DIR ? '/' : ' '); - while(spaces--) - uart_putc(' '); - uart_putdw_dec(dir_entry.file_size); - uart_putc('\n'); - } - } - else if(strncmp_P(command, PSTR("cat "), 4) == 0) - { - command += 4; - if(command[0] == '\0') - continue; - - /* search file in current directory and open it */ - struct fat_file_struct* fd = open_file_in_dir(fs, dd, command); - if(!fd) - { - uart_puts_p(PSTR("error opening ")); - uart_puts(command); - uart_putc('\n'); - continue; - } - - /* print file contents */ - uint8_t buffer[8]; - uint32_t offset = 0; - intptr_t count; - while((count = fat_read_file(fd, buffer, sizeof(buffer))) > 0) - { - uart_putdw_hex(offset); - uart_putc(':'); - for(intptr_t i = 0; i < count; ++i) - { - uart_putc(' '); - uart_putc_hex(buffer[i]); - } - uart_putc('\n'); - offset += 8; - } - - fat_close_file(fd); - } - else if(strcmp_P(command, PSTR("disk")) == 0) - { - if(!print_disk_info(fs)) - uart_puts_p(PSTR("error reading disk info\n")); - } + continue; + } + + /* print some card information as a boot message */ + print_disk_info(fs); + + /* provide a simple shell */ + char buffer[24]; + while(1) + { + /* print prompt */ + uart_putc('>'); + uart_putc(' '); + + /* read command */ + char* command = buffer; + if(read_line(command, sizeof(buffer)) < 1) + continue; + + /* execute command */ + if(strcmp_P(command, PSTR("init")) == 0) + { + break; + } + else if(strncmp_P(command, PSTR("cd "), 3) == 0) + { + command += 3; + if(command[0] == '\0') + continue; + + /* change directory */ + struct fat_dir_entry_struct subdir_entry; + if(find_file_in_dir(fs, dd, command, &subdir_entry)) + { + struct fat_dir_struct* dd_new = fat_open_dir(fs, &subdir_entry); + if(dd_new) + { + fat_close_dir(dd); + dd = dd_new; + continue; + } + } + + uart_puts_p(PSTR("directory not found: ")); + uart_puts(command); + uart_putc('\n'); + } + else if(strcmp_P(command, PSTR("ls")) == 0) + { + /* print directory listing */ + struct fat_dir_entry_struct dir_entry; + while(fat_read_dir(dd, &dir_entry)) + { + uint8_t spaces = sizeof(dir_entry.long_name) - strlen(dir_entry.long_name) + 4; + + uart_puts(dir_entry.long_name); + uart_putc(dir_entry.attributes & FAT_ATTRIB_DIR ? '/' : ' '); + while(spaces--) + uart_putc(' '); + uart_putdw_dec(dir_entry.file_size); + uart_putc('\n'); + } + } + else if(strncmp_P(command, PSTR("cat "), 4) == 0) + { + command += 4; + if(command[0] == '\0') + continue; + + /* search file in current directory and open it */ + struct fat_file_struct* fd = open_file_in_dir(fs, dd, command); + if(!fd) + { + uart_puts_p(PSTR("error opening ")); + uart_puts(command); + uart_putc('\n'); + continue; + } + + /* print file contents */ + uint8_t buffer[8]; + uint32_t offset = 0; + intptr_t count; + while((count = fat_read_file(fd, buffer, sizeof(buffer))) > 0) + { + uart_putdw_hex(offset); + uart_putc(':'); + for(intptr_t i = 0; i < count; ++i) + { + uart_putc(' '); + uart_putc_hex(buffer[i]); + } + uart_putc('\n'); + offset += 8; + } + + fat_close_file(fd); + } + else if(strcmp_P(command, PSTR("disk")) == 0) + { + if(!print_disk_info(fs)) + uart_puts_p(PSTR("error reading disk info\n")); + } #if FAT_WRITE_SUPPORT - else if(strncmp_P(command, PSTR("rm "), 3) == 0) - { - command += 3; - if(command[0] == '\0') - continue; - - struct fat_dir_entry_struct file_entry; - if(find_file_in_dir(fs, dd, command, &file_entry)) - { - if(fat_delete_file(fs, &file_entry)) - continue; - } - - uart_puts_p(PSTR("error deleting file: ")); - uart_puts(command); - uart_putc('\n'); - } - else if(strncmp_P(command, PSTR("touch "), 6) == 0) - { - command += 6; - if(command[0] == '\0') - continue; - - struct fat_dir_entry_struct file_entry; - if(!fat_create_file(dd, command, &file_entry)) - { - uart_puts_p(PSTR("error creating file: ")); - uart_puts(command); - uart_putc('\n'); - } - } - else if(strncmp_P(command, PSTR("mv "), 3) == 0) - { - command += 3; - if(command[0] == '\0') - continue; - - char* target = command; - while(*target != ' ' && *target != '\0') - ++target; - - if(*target == ' ') - *target++ = '\0'; - else - continue; - - struct fat_dir_entry_struct file_entry; - if(find_file_in_dir(fs, dd, command, &file_entry)) - { - if(fat_move_file(fs, &file_entry, dd, target)) - continue; - } - - uart_puts_p(PSTR("error moving file: ")); - uart_puts(command); - uart_putc('\n'); - } - else if(strncmp_P(command, PSTR("write "), 6) == 0) - { - command += 6; - if(command[0] == '\0') - continue; - - char* offset_value = command; - while(*offset_value != ' ' && *offset_value != '\0') - ++offset_value; - - if(*offset_value == ' ') - *offset_value++ = '\0'; - else - continue; - - /* search file in current directory and open it */ - struct fat_file_struct* fd = open_file_in_dir(fs, dd, command); - if(!fd) - { - uart_puts_p(PSTR("error opening ")); - uart_puts(command); - uart_putc('\n'); - continue; - } - - int32_t offset = strtolong(offset_value); - if(!fat_seek_file(fd, &offset, FAT_SEEK_SET)) - { - uart_puts_p(PSTR("error seeking on ")); - uart_puts(command); - uart_putc('\n'); - - fat_close_file(fd); - continue; - } - - /* read text from the shell and write it to the file */ - uint8_t data_len; - while(1) - { - /* give a different prompt */ - uart_putc('<'); - uart_putc(' '); - - /* read one line of text */ - data_len = read_line(buffer, sizeof(buffer)); - if(!data_len) - break; - - /* write text to file */ - if(fat_write_file(fd, (uint8_t*) buffer, data_len) != data_len) - { - uart_puts_p(PSTR("error writing to file\n")); - break; - } - } - - fat_close_file(fd); - } - else if(strncmp_P(command, PSTR("mkdir "), 6) == 0) - { - command += 6; - if(command[0] == '\0') - continue; - - struct fat_dir_entry_struct dir_entry; - if(!fat_create_dir(dd, command, &dir_entry)) - { - uart_puts_p(PSTR("error creating directory: ")); - uart_puts(command); - uart_putc('\n'); - } - } + else if(strncmp_P(command, PSTR("rm "), 3) == 0) + { + command += 3; + if(command[0] == '\0') + continue; + + struct fat_dir_entry_struct file_entry; + if(find_file_in_dir(fs, dd, command, &file_entry)) + { + if(fat_delete_file(fs, &file_entry)) + continue; + } + + uart_puts_p(PSTR("error deleting file: ")); + uart_puts(command); + uart_putc('\n'); + } + else if(strncmp_P(command, PSTR("touch "), 6) == 0) + { + command += 6; + if(command[0] == '\0') + continue; + + struct fat_dir_entry_struct file_entry; + if(!fat_create_file(dd, command, &file_entry)) + { + uart_puts_p(PSTR("error creating file: ")); + uart_puts(command); + uart_putc('\n'); + } + } + else if(strncmp_P(command, PSTR("mv "), 3) == 0) + { + command += 3; + if(command[0] == '\0') + continue; + + char* target = command; + while(*target != ' ' && *target != '\0') + ++target; + + if(*target == ' ') + *target++ = '\0'; + else + continue; + + struct fat_dir_entry_struct file_entry; + if(find_file_in_dir(fs, dd, command, &file_entry)) + { + if(fat_move_file(fs, &file_entry, dd, target)) + continue; + } + + uart_puts_p(PSTR("error moving file: ")); + uart_puts(command); + uart_putc('\n'); + } + else if(strncmp_P(command, PSTR("write "), 6) == 0) + { + command += 6; + if(command[0] == '\0') + continue; + + char* offset_value = command; + while(*offset_value != ' ' && *offset_value != '\0') + ++offset_value; + + if(*offset_value == ' ') + *offset_value++ = '\0'; + else + continue; + + /* search file in current directory and open it */ + struct fat_file_struct* fd = open_file_in_dir(fs, dd, command); + if(!fd) + { + uart_puts_p(PSTR("error opening ")); + uart_puts(command); + uart_putc('\n'); + continue; + } + + int32_t offset = strtolong(offset_value); + if(!fat_seek_file(fd, &offset, FAT_SEEK_SET)) + { + uart_puts_p(PSTR("error seeking on ")); + uart_puts(command); + uart_putc('\n'); + + fat_close_file(fd); + continue; + } + + /* read text from the shell and write it to the file */ + uint8_t data_len; + while(1) + { + /* give a different prompt */ + uart_putc('<'); + uart_putc(' '); + + /* read one line of text */ + data_len = read_line(buffer, sizeof(buffer)); + if(!data_len) + break; + + /* write text to file */ + if(fat_write_file(fd, (uint8_t*) buffer, data_len) != data_len) + { + uart_puts_p(PSTR("error writing to file\n")); + break; + } + } + + fat_close_file(fd); + } + else if(strncmp_P(command, PSTR("mkdir "), 6) == 0) + { + command += 6; + if(command[0] == '\0') + continue; + + struct fat_dir_entry_struct dir_entry; + if(!fat_create_dir(dd, command, &dir_entry)) + { + uart_puts_p(PSTR("error creating directory: ")); + uart_puts(command); + uart_putc('\n'); + } + } #endif #if SD_RAW_WRITE_BUFFERING - else if(strcmp_P(command, PSTR("sync")) == 0) - { - if(!sd_raw_sync()) - uart_puts_p(PSTR("error syncing disk\n")); - } + else if(strcmp_P(command, PSTR("sync")) == 0) + { + if(!sd_raw_sync()) + uart_puts_p(PSTR("error syncing disk\n")); + } #endif - else - { - uart_puts_p(PSTR("unknown command: ")); - uart_puts(command); - uart_putc('\n'); - } - } - - /* close directory */ - fat_close_dir(dd); - - /* close file system */ - fat_close(fs); - - /* close partition */ - partition_close(partition); + else + { + uart_puts_p(PSTR("unknown command: ")); + uart_puts(command); + uart_putc('\n'); + } + } + + /* close directory */ + fat_close_dir(dd); + + /* close file system */ + fat_close(fs); + + /* close partition */ + partition_close(partition); } - + return 0; } @@ -558,35 +558,35 @@ uint8_t read_line(char* buffer, uint8_t buffer_length) uint8_t read_length = 0; while(read_length < buffer_length - 1) { - uint8_t c = uart_getc(); - - if(c == 0x08 || c == 0x7f) - { - if(read_length < 1) - continue; - - --read_length; - buffer[read_length] = '\0'; - - uart_putc(0x08); - uart_putc(' '); - uart_putc(0x08); - - continue; - } - - uart_putc(c); - - if(c == '\n') - { - buffer[read_length] = '\0'; - break; - } - else - { - buffer[read_length] = c; - ++read_length; - } + uint8_t c = uart_getc(); + + if(c == 0x08 || c == 0x7f) + { + if(read_length < 1) + continue; + + --read_length; + buffer[read_length] = '\0'; + + uart_putc(0x08); + uart_putc(' '); + uart_putc(0x08); + + continue; + } + + uart_putc(c); + + if(c == '\n') + { + buffer[read_length] = '\0'; + break; + } + else + { + buffer[read_length] = c; + ++read_length; + } } return read_length; @@ -596,7 +596,7 @@ uint32_t strtolong(const char* str) { uint32_t l = 0; while(*str >= '0' && *str <= '9') - l = l * 10 + (*str++ - '0'); + l = l * 10 + (*str++ - '0'); return l; } @@ -605,11 +605,11 @@ uint8_t find_file_in_dir(struct fat_fs_struct* fs, struct fat_dir_struct* dd, co { while(fat_read_dir(dd, dir_entry)) { - if(strcmp(dir_entry->long_name, name) == 0) - { - fat_reset_dir(dd); - return 1; - } + if(strcmp(dir_entry->long_name, name) == 0) + { + fat_reset_dir(dd); + return 1; + } } return 0; @@ -619,7 +619,7 @@ struct fat_file_struct* open_file_in_dir(struct fat_fs_struct* fs, struct fat_di { struct fat_dir_entry_struct file_entry; if(!find_file_in_dir(fs, dd, name, &file_entry)) - return 0; + return 0; return fat_open_file(fs, &file_entry); } @@ -627,11 +627,11 @@ struct fat_file_struct* open_file_in_dir(struct fat_fs_struct* fs, struct fat_di uint8_t print_disk_info(const struct fat_fs_struct* fs) { if(!fs) - return 0; + return 0; struct sd_raw_info disk_info; if(!sd_raw_get_info(&disk_info)) - return 0; + return 0; uart_puts_p(PSTR("manuf: 0x")); uart_putc_hex(disk_info.manufacturer); uart_putc('\n'); uart_puts_p(PSTR("oem: ")); uart_puts((char*) disk_info.oem); uart_putc('\n'); @@ -639,14 +639,14 @@ uint8_t print_disk_info(const struct fat_fs_struct* fs) uart_puts_p(PSTR("rev: ")); uart_putc_hex(disk_info.revision); uart_putc('\n'); uart_puts_p(PSTR("serial: 0x")); uart_putdw_hex(disk_info.serial); uart_putc('\n'); uart_puts_p(PSTR("date: ")); uart_putw_dec(disk_info.manufacturing_month); uart_putc('/'); - uart_putw_dec(disk_info.manufacturing_year); uart_putc('\n'); + uart_putw_dec(disk_info.manufacturing_year); uart_putc('\n'); uart_puts_p(PSTR("size: ")); uart_putdw_dec(disk_info.capacity / 1024 / 1024); uart_puts_p(PSTR("MB\n")); uart_puts_p(PSTR("copy: ")); uart_putw_dec(disk_info.flag_copy); uart_putc('\n'); uart_puts_p(PSTR("wr.pr.: ")); uart_putw_dec(disk_info.flag_write_protect_temp); uart_putc('/'); - uart_putw_dec(disk_info.flag_write_protect); uart_putc('\n'); + uart_putw_dec(disk_info.flag_write_protect); uart_putc('\n'); uart_puts_p(PSTR("format: ")); uart_putw_dec(disk_info.format); uart_putc('\n'); uart_puts_p(PSTR("free: ")); uart_putdw_dec(fat_get_fs_free(fs)); uart_putc('/'); - uart_putdw_dec(fat_get_fs_size(fs)); uart_putc('\n'); + uart_putdw_dec(fat_get_fs_size(fs)); uart_putc('\n'); return 1; }