From 82f8229c8f189ac53f6f8ac62f43f26a1796ef62 Mon Sep 17 00:00:00 2001 From: David Voswinkel Date: Wed, 5 Aug 2009 21:01:14 +0200 Subject: [PATCH] add mmc and fat layer --- avr/usbload/Makefile | 2 +- avr/usbload/fat.c | 286 ++++++++++++++ avr/usbload/fat.h | 107 ++++++ avr/usbload/main.c | 66 +++- avr/usbload/mmc.c | 259 +++++++++++++ avr/usbload/mmc.h | 43 +++ quickdev16.tmproj | 879 ------------------------------------------- 7 files changed, 751 insertions(+), 891 deletions(-) create mode 100644 avr/usbload/fat.c create mode 100644 avr/usbload/fat.h create mode 100644 avr/usbload/mmc.c create mode 100644 avr/usbload/mmc.h diff --git a/avr/usbload/Makefile b/avr/usbload/Makefile index 93a5557..6bb1ef9 100644 --- a/avr/usbload/Makefile +++ b/avr/usbload/Makefile @@ -30,7 +30,7 @@ SIZE = avr-size ifeq ($(DEBUG),1) LDFLAGS = -Wl,-u,vfprintf -lprintf_flt CFLAGS = -Iusbdrv -I. -DDEBUG_LEVEL=0 - OBJECTS = usbdrv/usbdrv.o usbdrv/usbdrvasm.o usbdrv/oddebug.o main.o usb_bulk.o uart.o fifo.o sram.o crc.o debug.o dump.o timer.o watchdog.o rle.c loader.o info.o shared_memory.o + OBJECTS = usbdrv/usbdrv.o usbdrv/usbdrvasm.o usbdrv/oddebug.o main.o usb_bulk.o uart.o fifo.o sram.o crc.o debug.o dump.o timer.o watchdog.o rle.c loader.o info.o shared_memory.o mmc.o fat.o else LDFLAGS = -Wl,-u CFLAGS = -Iusbdrv -I. -DDEBUG_LEVEL=0 -DNO_DEBUG -DNO_INFO diff --git a/avr/usbload/fat.c b/avr/usbload/fat.c new file mode 100644 index 0000000..b155241 --- /dev/null +++ b/avr/usbload/fat.c @@ -0,0 +1,286 @@ +/* + * ####################################################################################### FAT for AVR (MMC/SD) Copyright (C) 2004 + * Ulrich Radig Bei Fragen und Verbesserungen wendet euch per EMail an mail@ulrichradig.de oder im Forum meiner Web Page : + * www.ulrichradig.de Dieses Programm ist freie Software. Sie können es unter den Bedingungen der GNU General Public License, wie + * von der Free Software Foundation veröffentlicht, weitergeben und/oder modifizieren, entweder gemäß Version 2 der Lizenz oder (nach + * Ihrer Option) jeder späteren Version. Die Veröffentlichung dieses Programms erfolgt in der Hoffnung, daß es Ihnen von Nutzen sein + * wird, aber OHNE IRGENDEINE GARANTIE, sogar ohne die implizite Garantie der MARKTREIFE oder der VERWENDBARKEIT FÜR EINEN BESTIMMTEN + * ZWECK. Details finden Sie in der GNU General Public License. Sie sollten eine Kopie der GNU General Public License zusammen mit + * diesem Programm erhalten haben. Falls nicht, schreiben Sie an die Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307, USA. ####################################################################################### + */ + +#include "fat.h" +unsigned char cluster_size; +unsigned int fat_offset; +unsigned int cluster_offset; +unsigned int volume_boot_record_addr; + + // ############################################################################ + // Auslesen Cluster Size der MMC/SD Karte und Speichern der größe ins EEprom + // Auslesen Cluster Offset der MMC/SD Karte und Speichern der größe ins EEprom +void fat_init(uint8_t * Buffer) +// ############################################################################ +{ + struct BootSec *bootp; // Zeiger auf Bootsektor Struktur + + // unsigned char Buffer[BlockSize]; + + // volume_boot_record_addr = fat_addr (Buffer); + mmc_read_sector(MASTER_BOOT_RECORD, Buffer); // Read Master Boot Record + if (Buffer[510] == 0x55 && Buffer[511] == 0xAA) { + FAT_DEBUG("MBR Signatur found!\r\n"); + } + + else { + FAT_DEBUG("MBR Signatur not found!\r\n"); + while (1); + } + volume_boot_record_addr = Buffer[VBR_ADDR] + (Buffer[VBR_ADDR + 1] << 8); + mmc_read_sector(volume_boot_record_addr, Buffer); + if (Buffer[510] == 0x55 && Buffer[511] == 0xAA) { + FAT_DEBUG("VBR Signatur found!\r\n"); + } + + else { + FAT_DEBUG("VBR Signatur not found!\r\n"); + volume_boot_record_addr = MASTER_BOOT_RECORD; // <- added by Hennie + mmc_read_sector(MASTER_BOOT_RECORD, Buffer); // Read Master Boot Record + } + bootp = (struct BootSec *) Buffer; + cluster_size = bootp->BPB_SecPerClus; + fat_offset = bootp->BPB_RsvdSecCnt; + cluster_offset = ((bootp->BPB_BytesPerSec * 32) / BlockSize); + cluster_offset += fat_root_dir_addr(Buffer); +} + // ############################################################################ + // Auslesen der Adresse des First Root Directory von Volume Boot Record +unsigned int fat_root_dir_addr(unsigned char *Buffer) +// ############################################################################ +{ + struct BootSec *bootp; // Zeiger auf Bootsektor Struktur + unsigned int FirstRootDirSecNum; + + // auslesen des Volume Boot Record von der MMC/SD Karte + mmc_read_sector(volume_boot_record_addr, Buffer); + bootp = (struct BootSec *) Buffer; + + // berechnet den ersten Sector des Root Directory + FirstRootDirSecNum = (bootp->BPB_RsvdSecCnt + + (bootp->BPB_NumFATs * bootp->BPB_FATSz16)); + FirstRootDirSecNum += volume_boot_record_addr; + return (FirstRootDirSecNum); +} + + // ############################################################################ + // Ausgabe des angegebenen Directory Eintrag in Entry_Count + // ist kein Eintrag vorhanden, ist der Eintrag im + // Rückgabe Cluster 0xFFFF. Es wird immer nur ein Eintrag ausgegeben + // um Speicherplatz zu sparen um es auch für kleine Atmels zu benutzen +unsigned int fat_read_dir_ent(unsigned int dir_cluster, // Angabe Dir Cluster + unsigned char Entry_Count, // Angabe welcher Direintrag + unsigned long *Size, // Rückgabe der File Größe + unsigned char *Dir_Attrib, // Rückgabe des Dir Attributs + unsigned char *Buffer) // Working Buffer +// ############################################################################ +{ + unsigned char *pointer; + unsigned int TMP_Entry_Count = 0; + unsigned long Block = 0; + struct DirEntry *dir; // Zeiger auf einen Verzeichniseintrag + unsigned int blk; + unsigned int a; + unsigned char b; + pointer = Buffer; + if (dir_cluster == 0) { + Block = fat_root_dir_addr(Buffer); + } + + else { + + // Berechnung des Blocks aus BlockCount und Cluster aus FATTabelle + // Berechnung welcher Cluster zu laden ist + // Auslesen der FAT - Tabelle + fat_load(dir_cluster, &Block, Buffer); + Block = ((Block - 2) * cluster_size) + cluster_offset; + } + + // auslesen des gesamten Root Directory + for (blk = Block;; blk++) { + mmc_read_sector(blk, Buffer); // Lesen eines Blocks des Root Directory + for (a = 0; a < BlockSize; a = a + 32) { + dir = (struct DirEntry *) &Buffer[a]; // Zeiger auf aktuellen Verzeichniseintrag holen + if (dir->DIR_Name[0] == 0) // Kein weiterer Eintrag wenn erstes Zeichen des Namens 0 ist + { + return (0xFFFF); + } + // Prüfen ob es ein 8.3 Eintrag ist + // Das ist der Fall wenn es sich nicht um einen Eintrag für lange Dateinamen + // oder um einen als gelöscht markierten Eintrag handelt. + if ((dir->DIR_Attr != ATTR_LONG_NAME) && + (dir->DIR_Name[0] != DIR_ENTRY_IS_FREE)) { + + // Ist es der gewünschte Verzeichniseintrag + if (TMP_Entry_Count == Entry_Count) { + + // Speichern des Verzeichnis Eintrages in den Rückgabe Buffer + for ( b = 0; b < 11; b++) { + if (dir->DIR_Name[b] != SPACE) { + if (b == 8) { + *pointer++ = '.'; + } + *pointer++ = dir->DIR_Name[b]; + } + } + *pointer++ = '\0'; + *Dir_Attrib = dir->DIR_Attr; + + // Speichern der Filegröße + *Size = dir->DIR_FileSize; + + // Speichern des Clusters des Verzeichniseintrages + dir_cluster = dir->DIR_FstClusLO; + + // Eintrag gefunden Rücksprung mit Cluster File Start + return (dir_cluster); + } + TMP_Entry_Count++; + } + } + } + return (0xFFFF); // Kein Eintrag mehr gefunden Rücksprung mit 0xFFFF +} + + // ############################################################################ + // Auslesen der Cluster für ein File aus der FAT + // in den Buffer(512Byte). Bei einer 128MB MMC/SD + // Karte ist die Cluster größe normalerweise 16KB groß + // das bedeutet das File kann max. 4MByte groß sein. + // Bei größeren Files muß der Buffer größer definiert + // werden! (Ready) + // Cluster = Start Clusterangabe aus dem Directory +void fat_load(unsigned int Cluster, // Angabe Startcluster + unsigned long *Block, unsigned char *TMP_Buffer) // Workingbuffer +// ############################################################################ +{ + + // Zum Überprüfen ob der FAT Block schon geladen wurde + unsigned int FAT_Block_Store = 0; + + // Byte Adresse innerhalb des Fat Blocks + unsigned int FAT_Byte_Addresse; + + // FAT Block Adresse + unsigned int FAT_Block_Addresse; + unsigned int a; + + // Berechnung für den ersten FAT Block (FAT Start Addresse) + for (a = 0;; a++) { + if (a == *Block) { + *Block = (0x0000FFFF & Cluster); + return; + } + if (Cluster == 0xFFFF) { + break; // Ist das Ende des Files erreicht Schleife beenden + } + // Berechnung des Bytes innerhalb des FAT Block´s + FAT_Byte_Addresse = (Cluster * 2) % BlockSize; + + // Berechnung des Blocks der gelesen werden muß + FAT_Block_Addresse = + ((Cluster * 2) / BlockSize) + volume_boot_record_addr + fat_offset; + + // Lesen des FAT Blocks + // Überprüfung ob dieser Block schon gelesen wurde + if (FAT_Block_Addresse != FAT_Block_Store) { + FAT_Block_Store = FAT_Block_Addresse; + + // Lesen des FAT Blocks + mmc_read_sector(FAT_Block_Addresse, TMP_Buffer); + } + // Lesen der nächsten Clusternummer + Cluster = + (TMP_Buffer[FAT_Byte_Addresse + 1] << 8) + + TMP_Buffer[FAT_Byte_Addresse]; + } + return; +} + + // ############################################################################ + // Lesen eines 512Bytes Blocks von einem File +void fat_read_file(unsigned int Cluster, // Angabe des Startclusters vom File + unsigned char *Buffer, // Workingbuffer + unsigned long BlockCount) // Angabe welcher Bock vom File geladen + // werden soll a 512 Bytes +// ############################################################################ +{ + + // Berechnung des Blocks aus BlockCount und Cluster aus FATTabelle + // Berechnung welcher Cluster zu laden ist + unsigned long Block = (BlockCount / cluster_size); + + // Auslesen der FAT - Tabelle + fat_load(Cluster, &Block, Buffer); + Block = ((Block - 2) * cluster_size) + cluster_offset; + + // Berechnung des Blocks innerhalb des Cluster + Block += (BlockCount % cluster_size); + + // Read Data Block from Device + mmc_read_sector(Block, Buffer); + return; +} + + // ############################################################################ + // Lesen eines 512Bytes Blocks von einem File +void fat_write_file(unsigned int cluster, // Angabe des Startclusters vom File + unsigned char *buffer, // Workingbuffer + unsigned long blockCount) // Angabe welcher Bock vom File gespeichert + // werden soll a 512 Bytes +// ############################################################################ +{ + + // Berechnung des Blocks aus BlockCount und Cluster aus FATTabelle + // Berechnung welcher Cluster zu speichern ist + unsigned char tmp_buffer[513]; + unsigned long block = (blockCount / cluster_size); + + // Auslesen der FAT - Tabelle + fat_load(cluster, &block, tmp_buffer); + block = ((block - 2) * cluster_size) + cluster_offset; + + // Berechnung des Blocks innerhalb des Cluster + block += (blockCount % cluster_size); + + // Write Data Block to Device + mmc_write_sector(block, buffer); + return; +} + + // #################################################################################### + // Sucht ein File im Directory +unsigned char fat_search_file(unsigned char *File_Name, // Name des zu suchenden Files + unsigned int *Cluster, // Angabe Dir Cluster welches + // durchsucht werden soll + // und Rückgabe des clusters + // vom File welches gefunden + // wurde + unsigned long *Size, // Rückgabe der File Größe + unsigned char *Dir_Attrib, // Rückgabe des Dir Attributs + unsigned char *Buffer) // Working Buffer +// #################################################################################### +{ + unsigned int Dir_Cluster_Store = *Cluster; + unsigned char a ; + for (a = 0; a < 100; a++) { + *Cluster = + fat_read_dir_ent(Dir_Cluster_Store, a, Size, Dir_Attrib, Buffer); + if (*Cluster == 0xffff) { + return (0); // File not Found + } + if (strcasecmp((char *) File_Name, (char *) Buffer) == 0) { + return (1); // File Found + } + } + return (2); // Error +} diff --git a/avr/usbload/fat.h b/avr/usbload/fat.h new file mode 100644 index 0000000..3af2730 --- /dev/null +++ b/avr/usbload/fat.h @@ -0,0 +1,107 @@ +/* + * ####################################################################################### Connect ARM to MMC/SD Copyright (C) 2004 + * Ulrich Radig ####################################################################################### + */ + +#ifndef _FAT_H_ +#define _FAT_H_ +#include +#include "mmc.h" +#include "uart.h" + +#define FAT_DEBUG uart_puts + // #define FAT_DEBUG(...) + + // Prototypes +extern unsigned int fat_root_dir_addr(unsigned char *); +extern unsigned int fat_read_dir_ent(unsigned int, unsigned char, + unsigned long *, unsigned char *, + unsigned char *); +extern void fat_load(unsigned int, unsigned long *, unsigned char *); +extern void fat_read_file(unsigned int, unsigned char *, unsigned long); +extern void fat_write_file(unsigned int, unsigned char *, unsigned long); +extern void fat_init(uint8_t * Buffer); +extern unsigned char fat_search_file(unsigned char *, unsigned int *, + unsigned long *, unsigned char *, + unsigned char *); + + // Block Size in Bytes +#define BlockSize 512 + + // Master Boot Record +#define MASTER_BOOT_RECORD 0 + + // Volume Boot Record location in Master Boot Record +#define VBR_ADDR 0x1C6 + + // define ASCII +#define SPACE 0x20 +#define DIR_ENTRY_IS_FREE 0xE5 +#define FIRST_LONG_ENTRY 0x01 +#define SECOND_LONG_ENTRY 0x42 + + // define DIR_Attr +#define ATTR_LONG_NAME 0x0F +#define ATTR_READ_ONLY 0x01 +#define ATTR_HIDDEN 0x02 +#define ATTR_SYSTEM 0x04 +#define ATTR_VOLUME_ID 0x08 +#define ATTR_DIRECTORY 0x10 +#define ATTR_ARCHIVE 0x20 +struct BootSec { + unsigned char BS_jmpBoot[3]; + unsigned char BS_OEMName[8]; + unsigned int BPB_BytesPerSec; // 2 bytes + unsigned char BPB_SecPerClus; + unsigned int BPB_RsvdSecCnt; // 2 bytes + unsigned char BPB_NumFATs; + unsigned int BPB_RootEntCnt; // 2 bytes + unsigned int BPB_TotSec16; // 2 bytes + unsigned char BPB_Media; + unsigned int BPB_FATSz16; // 2 bytes + unsigned int BPB_SecPerTrk; // 2 bytes + unsigned int BPB_NumHeads; // 2 bytes + unsigned long BPB_HiddSec; // 4 bytes + unsigned long BPB_TotSec32; // 4 bytes +}; + + // FAT12 and FAT16 Structure Starting at Offset 36 +#define BS_DRVNUM 36 +#define BS_RESERVED1 37 +#define BS_BOOTSIG 38 +#define BS_VOLID 39 +#define BS_VOLLAB 43 +#define BS_FILSYSTYPE 54 + + // FAT32 Structure Starting at Offset 36 +#define BPB_FATSZ32 36 +#define BPB_EXTFLAGS 40 +#define BPB_FSVER 42 +#define BPB_ROOTCLUS 44 +#define BPB_FSINFO 48 +#define BPB_BKBOOTSEC 50 +#define BPB_RESERVED 52 + +#define FAT32_BS_DRVNUM 64 +#define FAT32_BS_RESERVED1 65 +#define FAT32_BS_BOOTSIG 66 +#define FAT32_BS_VOLID 67 +#define FAT32_BS_VOLLAB 71 +#define FAT32_BS_FILSYSTYPE 82 + // End of Boot Sctor and BPB Structure +struct DirEntry { + unsigned char DIR_Name[11]; // 8 chars filename + unsigned char DIR_Attr; // file attributes RSHA, Longname, Drive Label, Directory + unsigned char DIR_NTRes; // set to zero + unsigned char DIR_CrtTimeTenth; // creation time part in milliseconds + unsigned int DIR_CrtTime; // creation time + unsigned int DIR_CrtDate; // creation date + unsigned int DIR_LastAccDate; // last access date + unsigned int DIR_FstClusHI; // first cluster high word + unsigned int DIR_WrtTime; // last write time + unsigned int DIR_WrtDate; // last write date + unsigned int DIR_FstClusLO; // first cluster low word + unsigned long DIR_FileSize; +}; + +#endif // _FAT_H_ diff --git a/avr/usbload/main.c b/avr/usbload/main.c index 48f5e5b..5d45e94 100644 --- a/avr/usbload/main.c +++ b/avr/usbload/main.c @@ -43,6 +43,9 @@ #include "rle.h" #include "loader.h" #include "shared_memory.h" +#include "mmc.h" +#include "fat.h" + extern const char _rom[] PROGMEM; @@ -309,6 +312,53 @@ usbMsgLen_t usbFunctionSetup(uchar data[8]) /* * ------------------------------------------------------------------------- */ + +#ifdef ENABLE_TEST + +void test_sdcard(){ + uint16_t fat_cluster = 0; + uint8_t fat_attrib = 0; + uint32_t fat_size = 0; + uint32_t rom_addr = 0; + uint8_t bank_cnt = 0; + uint16_t crc = 0; + uint16_t block_cnt; + + #define FILENAME "mrdo.smc" //failed + #define ROMSIZE 2 // 4 == 4mbit == 512kb + #define BUFFER_SIZE 512 + #define BLOCKS (ROMSIZE << 8) + + while ( mmc_init() !=0) { + info("No sdcard...\n"); + } + info("MMC Init done\n"); + fat_init(read_buffer); + info("FAT Init done.\n"); + info("Look for %s\n",FILENAME); + + if (fat_search_file((uint8_t*)FILENAME, + &fat_cluster, + &fat_size, + &fat_attrib, + read_buffer) == 1) { + + + for (block_cnt=0; block_cnt + + // ############################################################################ + // Routine zur Initialisierung der MMC/SD-Karte (SPI-MODE) +unsigned char mmc_init() +// ############################################################################ +{ + unsigned int Timeout = 0, i; + + // Konfiguration des Ports an der die MMC/SD-Karte angeschlossen wurde + DDRC |= ((1 << MMC_DO) | (1 << MMC_CS) | (1 << MMC_CLK)); + DDRC &= ~(1 << MMC_DI); + PORTC |= ((1 << MMC_DO) | (1 << MMC_DI) | (1 << MMC_CS)); + + // Wartet eine kurze Zeit + _delay_ms(10); + + // Initialisiere MMC/SD-Karte in den SPI-Mode + for (i = 0; i < 250; i++) { + PORTC ^= (1 << MMC_CLK); + _delay_us(4); + } + PORTC &= ~(1 << MMC_CLK); + _delay_us(10); + PORTC &= ~(1 << MMC_CS); + _delay_us(3); + + // Sendet Commando CMD0 an MMC/SD-Karte + unsigned char CMD[] = { 0x40, 0x00, 0x00, 0x00, 0x00, 0x95 }; + while (mmc_write_command(CMD) != 1) { + if (Timeout++ > 20) { + MMC_Disable(); + printf("fail1\n"); + return (1); // Abbruch bei Commando1 (Return Code1) + } + } + + // Sendet Commando CMD1 an MMC/SD-Karte + Timeout = 0; + CMD[0] = 0x41; // Commando 1 + CMD[5] = 0xFF; + while (mmc_write_command(CMD) != 0) { + if (Timeout++ > 800) { + MMC_Disable(); + printf("fail2\n"); + return (9); // Abbruch bei Commando2 (Return Code2) + } + } + return (0); +} + + // ############################################################################ + // Sendet ein Commando an die MMC/SD-Karte +unsigned char mmc_write_command(unsigned char *cmd) +// ############################################################################ +{ + unsigned char tmp = 0xff; + unsigned int Timeout = 0; + unsigned char a; + + // sendet 6 Byte Commando + for (a = 0; a < 0x06; a++) // sendet 6 Byte Commando zur MMC/SD-Karte + { + mmc_write_byte(*cmd++); + } + + // Wartet auf ein gültige Antwort von der MMC/SD-Karte + while (tmp == 0xff) { + tmp = mmc_read_byte(); + if (Timeout++ > 50) { + break; // Abbruch da die MMC/SD-Karte nicht Antwortet + } + } + return (tmp); +} + + // ############################################################################ + // Routine zum Empfangen eines Bytes von der MMC-Karte +unsigned char mmc_read_byte(void) +// ############################################################################ +{ + uint8_t Byte = 0, j; + for (j = 0; j < 8; j++) { + Byte = (Byte << 1); + PORTC |= (1 << MMC_CLK); + _delay_us(4); + if (PINC & (1 << MMC_DI)) { + Byte |= 1; + } + + else { + Byte &= ~1; + } + PORTC &= ~(1 << MMC_CLK); + _delay_us(4); + } + return (Byte); +} + + // ############################################################################ + // Routine zum Senden eines Bytes zur MMC-Karte +void mmc_write_byte(unsigned char Byte) +// ############################################################################ +{ + uint8_t i; + for (i = 0; i < 8; i++) { + if (Byte & 0x80) { + PORTC |= (1 << MMC_DO); + } + + else { + PORTC &= ~(1 << MMC_DO); + } + Byte = (Byte << 1); + PORTC |= (1 << MMC_CLK); + _delay_us(4); + PORTC &= ~(1 << MMC_CLK); + _delay_us(4); + } + PORTC |= (1 << MMC_DO); +} + + // ############################################################################ + // Routine zum schreiben eines Blocks(512Byte) auf die MMC/SD-Karte +unsigned char mmc_write_sector(unsigned long addr, unsigned char *Buffer) +// ############################################################################ +{ + unsigned char tmp; + + // Commando 24 zum schreiben eines Blocks auf die MMC/SD - Karte + unsigned char cmd[] = { 0x58, 0x00, 0x00, 0x00, 0x00, 0xFF }; + unsigned char a; + unsigned int i; + + /* + * Die Adressierung der MMC/SD-Karte wird in Bytes angegeben, addr wird von Blocks zu Bytes umgerechnet danach werden diese in + * das Commando eingefügt + */ + addr = addr << 9; // addr = addr * 512 + cmd[1] = ((addr & 0xFF000000) >> 24); + cmd[2] = ((addr & 0x00FF0000) >> 16); + cmd[3] = ((addr & 0x0000FF00) >> 8); + + // Sendet Commando cmd24 an MMC/SD-Karte (Write 1 Block/512 Bytes) + tmp = mmc_write_command(cmd); + if (tmp != 0) { + return (tmp); + } + // Wartet einen Moment und sendet einen Clock an die MMC/SD-Karte + for (a = 0; a < 100; a++) { + mmc_read_byte(); + } + + // Sendet Start Byte an MMC/SD-Karte + mmc_write_byte(0xFE); + + // Schreiben des Bolcks (512Bytes) auf MMC/SD-Karte + for (a = 0; i < 512; i++) { + mmc_write_byte(*Buffer++); + } + + // CRC-Byte schreiben + mmc_write_byte(0xFF); // Schreibt Dummy CRC + mmc_write_byte(0xFF); // CRC Code wird nicht benutzt + + // Fehler beim schreiben? (Data Response XXX00101 = OK) + if ((mmc_read_byte() & 0x1F) != 0x05) + return (1); + + // Wartet auf MMC/SD-Karte Bussy + while (mmc_read_byte() != 0xff) { + }; + return (0); +} + + // ############################################################################ + // Routine zum lesen des CID Registers von der MMC/SD-Karte (16Bytes) +void mmc_read_block(unsigned char *cmd, unsigned char *Buffer, + unsigned int Bytes) +// ############################################################################ +{ + unsigned int a; + + // Sendet Commando cmd an MMC/SD-Karte + if (mmc_write_command(cmd) != 0) { + return; + } + // Wartet auf Start Byte von der MMC/SD-Karte (FEh/Start Byte) + while (mmc_read_byte() != 0xfe) { + }; + + // Lesen des Bolcks (normal 512Bytes) von MMC/SD-Karte + for (a = 0; a < Bytes; a++) { + *Buffer++ = mmc_read_byte(); + } + + // CRC-Byte auslesen + mmc_read_byte(); // CRC - Byte wird nicht ausgewertet + mmc_read_byte(); // CRC - Byte wird nicht ausgewertet + return; +} + + // ############################################################################ + // Routine zum lesen eines Blocks(512Byte) von der MMC/SD-Karte +unsigned char mmc_read_sector(unsigned long addr, unsigned char *Buffer) +// ############################################################################ +{ + + // Commando 16 zum lesen eines Blocks von der MMC/SD - Karte + unsigned char cmd[] = { 0x51, 0x00, 0x00, 0x00, 0x00, 0xFF }; + + /* + * Die Adressierung der MMC/SD-Karte wird in Bytes angegeben, addr wird von Blocks zu Bytes umgerechnet danach werden diese in + * das Commando eingefügt + */ + addr = addr << 9; // addr = addr * 512 + cmd[1] = ((addr & 0xFF000000) >> 24); + cmd[2] = ((addr & 0x00FF0000) >> 16); + cmd[3] = ((addr & 0x0000FF00) >> 8); + mmc_read_block(cmd, Buffer, 512); + return (0); +} + + // ############################################################################ + // Routine zum lesen des CID Registers von der MMC/SD-Karte (16Bytes) +unsigned char mmc_read_cid(unsigned char *Buffer) +// ############################################################################ +{ + + // Commando zum lesen des CID Registers + unsigned char cmd[] = { 0x4A, 0x00, 0x00, 0x00, 0x00, 0xFF }; + mmc_read_block(cmd, Buffer, 16); + return (0); +} + + // ############################################################################ + // Routine zum lesen des CSD Registers von der MMC/SD-Karte (16Bytes) +unsigned char mmc_read_csd(unsigned char *Buffer) +// ############################################################################ +{ + + // Commando zum lesen des CSD Registers + unsigned char cmd[] = { 0x49, 0x00, 0x00, 0x00, 0x00, 0xFF }; + mmc_read_block(cmd, Buffer, 16); + return (0); +} diff --git a/avr/usbload/mmc.h b/avr/usbload/mmc.h new file mode 100644 index 0000000..2188a60 --- /dev/null +++ b/avr/usbload/mmc.h @@ -0,0 +1,43 @@ +/* + * ####################################################################################### Connect ARM to MMC/SD Copyright (C) 2004 + * Ulrich Radig ####################################################################################### + */ + +#ifndef _MMC_H_ +#define _MMC_H_ + +#include + + // #define SPI_Mode 1 //1 = Hardware SPI | 0 = Software SPI +//#define SPI_Mode 1 + +#define MMC_Write PORTB // Port an der die MMC/SD-Karte angeschlossen ist also des SPI +#define MMC_Read PINB +#define MMC_Direction_REG DDRB + +#define MMC_CS PB4 +#define MMC_DO PB6 +#define MMC_DI PB5 +#define MMC_CLK PB7 +//#define SPI_SS PC4 // Nicht Benutz muß aber definiert werden + + // Prototypes +extern unsigned char mmc_read_byte(void); +extern void mmc_write_byte(unsigned char); +extern void mmc_read_block(unsigned char *, unsigned char *, unsigned in); +extern unsigned char mmc_init(void); +extern unsigned char mmc_read_sector(unsigned long, unsigned char *); +extern unsigned char mmc_write_sector(unsigned long, unsigned char *); +extern unsigned char mmc_write_command(unsigned char *); +extern unsigned char mmc_read_csd(unsigned char *); +extern unsigned char mmc_read_cid(unsigned char *); + + // set MMC_Chip_Select to high (MMC/SD-Karte Inaktiv) +#define MMC_Disable() MMC_Write|= (1< - currentDocument - avr/usbload/main.c documents @@ -21,616 +19,6 @@ 271 metaData - avr/bootloader/config.h - - caret - - column - 0 - line - 22 - - firstVisibleColumn - 0 - firstVisibleLine - 0 - - avr/usbload/Makefile - - caret - - column - 11 - line - 18 - - firstVisibleColumn - 0 - firstVisibleLine - 1 - - avr/usbload/commandline/Makefile - - caret - - column - 0 - line - 24 - - firstVisibleColumn - 0 - firstVisibleLine - 0 - - avr/usbload/commandline/opendevice.c - - caret - - column - 0 - line - 0 - - columnSelection - - firstVisibleColumn - 0 - firstVisibleLine - 26 - selectFrom - - column - 0 - line - 0 - - selectTo - - column - 3 - line - 19 - - - avr/usbload/commandline/snesuploader.ll - - caret - - column - 36 - line - 9 - - firstVisibleColumn - 0 - firstVisibleLine - 0 - - avr/usbload/config.h - - caret - - column - 0 - line - 23 - - firstVisibleColumn - 0 - firstVisibleLine - 0 - - avr/usbload/crc.c - - caret - - column - 0 - line - 31 - - columnSelection - - firstVisibleColumn - 0 - firstVisibleLine - 0 - selectFrom - - column - 0 - line - 21 - - selectTo - - column - 0 - line - 31 - - - avr/usbload/debug.c - - caret - - column - 31 - line - 39 - - firstVisibleColumn - 0 - firstVisibleLine - 0 - - avr/usbload/debug.h - - caret - - column - 6 - line - 30 - - columnSelection - - firstVisibleColumn - 0 - firstVisibleLine - 0 - selectFrom - - column - 4 - line - 30 - - selectTo - - column - 11 - line - 30 - - - avr/usbload/dump.c - - caret - - column - 0 - line - 26 - - firstVisibleColumn - 0 - firstVisibleLine - 0 - - avr/usbload/dump.h - - caret - - column - 0 - line - 19 - - firstVisibleColumn - 0 - firstVisibleLine - 0 - - avr/usbload/fifo.c - - caret - - column - 17 - line - 22 - - firstVisibleColumn - 0 - firstVisibleLine - 0 - - avr/usbload/info.c - - caret - - column - 4 - line - 33 - - firstVisibleColumn - 0 - firstVisibleLine - 0 - - avr/usbload/info.h - - caret - - column - 22 - line - 32 - - firstVisibleColumn - 0 - firstVisibleLine - 0 - - avr/usbload/loader.c - - caret - - column - 0 - line - 0 - - firstVisibleColumn - 0 - firstVisibleLine - 1664 - - avr/usbload/loader.h - - caret - - column - 0 - line - 0 - - firstVisibleColumn - 0 - firstVisibleLine - 0 - - avr/usbload/main.c - - caret - - column - 0 - line - 0 - - firstVisibleColumn - 0 - firstVisibleLine - 452 - - avr/usbload/requests.h - - caret - - column - 0 - line - 19 - - firstVisibleColumn - 0 - firstVisibleLine - 0 - - avr/usbload/rle.c - - caret - - column - 0 - line - 0 - - firstVisibleColumn - 0 - firstVisibleLine - 14 - - avr/usbload/rle.h - - caret - - column - 0 - line - 0 - - firstVisibleColumn - 0 - firstVisibleLine - 0 - - avr/usbload/shared_memory.c - - caret - - column - 0 - line - 0 - - firstVisibleColumn - 0 - firstVisibleLine - 46 - - avr/usbload/shared_memory.h - - caret - - column - 0 - line - 0 - - firstVisibleColumn - 0 - firstVisibleLine - 0 - - avr/usbload/sram.c - - caret - - column - 0 - line - 32 - - firstVisibleColumn - 0 - firstVisibleLine - 0 - - avr/usbload/sram.h - - caret - - column - 0 - line - 19 - - firstVisibleColumn - 0 - firstVisibleLine - 0 - - avr/usbload/timer.c - - caret - - column - 0 - line - 31 - - firstVisibleColumn - 0 - firstVisibleLine - 22 - - avr/usbload/timer.h - - caret - - column - 0 - line - 29 - - columnSelection - - firstVisibleColumn - 0 - firstVisibleLine - 0 - selectFrom - - column - 0 - line - 0 - - selectTo - - column - 0 - line - 29 - - - avr/usbload/uart.c - - caret - - column - 0 - line - 26 - - firstVisibleColumn - 0 - firstVisibleLine - 0 - - avr/usbload/usb_bulk.c - - caret - - column - 0 - line - 37 - - firstVisibleColumn - 0 - firstVisibleLine - 0 - - avr/usbload/watchdog.c - - caret - - column - 0 - line - 22 - - firstVisibleColumn - 0 - firstVisibleLine - 0 - - poc/avr_sdcard/checksize - - caret - - column - 0 - line - 0 - - firstVisibleColumn - 0 - firstVisibleLine - 0 - - poc/avr_sdcard/fat.c - - caret - - column - 0 - line - 0 - - firstVisibleColumn - 0 - firstVisibleLine - 0 - - poc/avr_sdcard/fat.h - - caret - - column - 0 - line - 0 - - firstVisibleColumn - 0 - firstVisibleLine - 0 - - poc/avr_sdcard/main.c - - caret - - column - 0 - line - 0 - - firstVisibleColumn - 0 - firstVisibleLine - 422 - - poc/avr_sdcard/main.lst - - caret - - column - 0 - line - 0 - - firstVisibleColumn - 0 - firstVisibleLine - 405 - - poc/avr_sdcard/main.map - - caret - - column - 0 - line - 0 - - firstVisibleColumn - 0 - firstVisibleLine - 526 - - poc/avr_sdcard/main.sym - - caret - - column - 0 - line - 0 - - firstVisibleColumn - 0 - firstVisibleLine - 0 - - poc/avr_sdcard/mmc.c - - caret - - column - 16 - line - 292 - - firstVisibleColumn - 0 - firstVisibleLine - 5 - - poc/avr_sdcard/mmc.h - - caret - - column - 0 - line - 24 - - firstVisibleColumn - 0 - firstVisibleLine - 4 - - scripts/conv_rle.py - - caret - - column - 0 - line - 32 - - firstVisibleColumn - 0 - firstVisibleLine - 7 - snes/banktest/LoadGraphics.asm caret @@ -659,274 +47,7 @@ firstVisibleLine 211 - snes/loader/main.asm - - caret - - column - 14 - line - 232 - - firstVisibleColumn - 0 - firstVisibleLine - 259 - - snes/loader/routines/joypadread.asm - - caret - - column - 0 - line - 0 - - firstVisibleColumn - 0 - firstVisibleLine - 75 - - snes/loader/routines/menusystem.asm - - caret - - column - 0 - line - 0 - - firstVisibleColumn - 0 - firstVisibleLine - 655 - - snes/loader/routines/miscdata.asm - - caret - - column - 0 - line - 5 - - firstVisibleColumn - 0 - firstVisibleLine - 0 - - tools/ffsample/avr/Makefile_ata - - caret - - column - 0 - line - 0 - - firstVisibleColumn - 0 - firstVisibleLine - 0 - - tools/ffsample/avr/Makefile_cfc - - caret - - column - 0 - line - 0 - - firstVisibleColumn - 0 - firstVisibleLine - 0 - - tools/ffsample/avr/Makefile_cfmm - - caret - - column - 0 - line - 0 - - firstVisibleColumn - 0 - firstVisibleLine - 0 - - tools/ffsample/avr/Makefile_mmc - - caret - - column - 0 - line - 0 - - firstVisibleColumn - 0 - firstVisibleLine - 0 - - tools/ffsample/avr/cfmm.c - - caret - - column - 0 - line - 0 - - firstVisibleColumn - 0 - firstVisibleLine - 0 - - tools/ffsample/avr/ff.c - - caret - - column - 0 - line - 0 - - firstVisibleColumn - 0 - firstVisibleLine - 0 - - tools/ffsample/avr/ff.h - - caret - - column - 0 - line - 0 - - firstVisibleColumn - 0 - firstVisibleLine - 0 - - tools/ffsample/avr/main.c - - caret - - column - 30 - line - 177 - - firstVisibleColumn - 0 - firstVisibleLine - 152 - - tools/ffsample/avr/mmc.c - - caret - - column - 0 - line - 0 - - firstVisibleColumn - 0 - firstVisibleLine - 15 - - tools/ffsample/avr/rtc.c - - caret - - column - 0 - line - 0 - - firstVisibleColumn - 0 - firstVisibleLine - 0 - - tools/huffman/huffman-encode.c - - caret - - column - 14 - line - 443 - - firstVisibleColumn - 0 - firstVisibleLine - 418 - - openDocuments - - snes/loader/main.asm - snes/loader/routines/joypadread.asm - snes/loader/routines/menusystem.asm - snes/loader/routines/miscdata.asm - avr/usbload/main.c - tools/huffman/huffman-encode.c - scripts/conv_rle.py - avr/usbload/loader.h - poc/avr_sdcard/fat.h - poc/avr_sdcard/fat.c - poc/avr_sdcard/main.c - poc/avr_sdcard/mmc.c - poc/avr_sdcard/main.sym - poc/avr_sdcard/mmc.h - poc/avr_sdcard/main.map - poc/avr_sdcard/main.lst - tools/ffsample/avr/Makefile_ata - tools/ffsample/avr/ff.h - tools/ffsample/avr/ff.c - tools/ffsample/avr/Makefile_mmc - tools/ffsample/avr/Makefile_cfc - tools/ffsample/avr/Makefile_cfmm - tools/ffsample/avr/rtc.c - tools/ffsample/avr/mmc.c - tools/ffsample/avr/main.c - tools/ffsample/avr/cfmm.c - poc/avr_sdcard/checksize - avr/usbload/loader.c - avr/usbload/timer.h - avr/usbload/timer.c - avr/usbload/uart.c - avr/usbload/usb_bulk.c - avr/usbload/watchdog.c - avr/usbload/debug.h - avr/usbload/debug.c - avr/usbload/fifo.c - avr/usbload/commandline/Makefile - avr/usbload/info.c - avr/usbload/dump.h - avr/usbload/info.h - avr/bootloader/config.h - avr/usbload/config.h - avr/usbload/Makefile - avr/usbload/shared_memory.c - avr/usbload/shared_memory.h - avr/usbload/commandline/opendevice.c - avr/usbload/sram.h - avr/usbload/requests.h - avr/usbload/rle.c - avr/usbload/sram.c - avr/usbload/rle.h - avr/usbload/dump.c - avr/usbload/crc.c - avr/usbload/commandline/snesuploader.ll - showFileHierarchyDrawer showFileHierarchyPanel