⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mmcdump.c

📁 Simple AVR MMC dumper
💻 C
📖 第 1 页 / 共 2 页
字号:
/*****************************************************

Project : Fat filesystem and MMC-memeory card 
Version : 0.0
Date    : 1.11.2005
Author  : Ari Naukkarinen                 
Company : Metsys Oy          
             
Comments:          
Program does:
 - Read all files from MMC card (using FAT-16 filesystem)
 - Dump all sectors
 - Fill all files with 'Z'
 - Only FAT-16 compatible
 - Assume BlockSize = 512 bytes
 - Program is for educational use only (does nothing useful)
 - You have to create files using (for ex.) PC, and fill them with AVR
  
Limitations:
Program do not:
 - Create files
 - Update file size (or any other fields in DIR-entry)
 - Understand FAT-12 or FAT-32 or others (ONLY FAT-16)
               

Chip type           : ATmega32
Program type        : Application
Clock frequency     : 16,000000 MHz
Memory model        : Small
External SRAM size  : 0
Data Stack size     : 256
*****************************************************/
                                                  
// include files from CodevisionC
#include <mega8.h>
#include <spi.h>
#include <stdio.h>             
#include <stdlib.h>             
#include <delay.h> 
#include <string.h> 


#define MMC_DEBUG4      // show mmcInit messages
//#define MMC_DEBUG3      // show mmc_read, mmcWrite messages
//#define MMC_DEBUG2      // show FAT addresses




#define IDLE_STATE           0       // MMC to SPI
#define INIT_COMMAND         1       // initialize card
#define CRC_OFF              59      // CRC checking on/off (normally automatically off in SPI)
#define SET_BLKLEN           16      // Set number of bytes to transfer per block (default 512 in SPI)
#define WRITE_BLK            24      // write a block
#define READ_BLK             17      // read a block

// Data tokens values
#define STARTBYTE_RDWR          0xFE    // startbyte, block starts with 0xFE (both write and read block)
#define DR_MASK                 0x1F
#define DR_ACCEPT               0x05
                                                          
#define BlockSize			512

struct BootSec 
{
	unsigned char  	        BPB_dummy1[11];         // 11 bytes OEM-name
	unsigned int   	        BPB_BytesPerSec;        // 2 bytes
	unsigned char		BPB_SecPerClus;         // 1 byte
	unsigned int		BPB_ResrvdSector;       // 2 bytes
	unsigned char		BPB_NumOfFat;           // 1 byte
	unsigned int		BPB_RootEntries;        // 2 bytes
	unsigned int		BPB_TotSec16;           // 2 bytes
	unsigned char		BPB_Media;              // 1 byte
	unsigned int		BPB_SectPerFat;         // 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
};

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;              //reserved to NT
	unsigned char		DIR_CrtTimems;          //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_FirstCluster;       //first cluster low word                 
	unsigned long		DIR_FileSize;     
};




	
// Declare your global variables here
                     
unsigned int FatStart;                                                             
unsigned int ClustCnt;                                          // cluster counter
unsigned int SectPerCluster;
unsigned int ClusterOffset;                                                      
unsigned long   FileSize;    
unsigned int RootDirEntry;
char RxBuffer;
char TxBuff[24];
char block[512];



/* functions start */
void send_char(unsigned char sch)		                        // send data to serial port (not used)
{       char uart_stat;
        uart_stat = 0x20&UCSRA;
	{	while((uart_stat=(0x20&UCSRA)), uart_stat!=0x20);	// wait for TX complete
	       	        UDR = sch;
         }
}

void send_str()                                                         // send string to serial port (not used)
{       unsigned char i;
        i = 0;
        while(TxBuff[i] != 0)
        {       send_char(TxBuff[i]);
                i++;
        }
}

unsigned char mmc_command(unsigned char cmd, unsigned long arg) // Write command to MMC, returns R1 result code, leaves ENABLE ON
{
        unsigned char resp;
        unsigned char retry=0;
        PORTB.2 = 0;
        spi(cmd | 0x40);                                // note command is CMD-X + 0x40
        spi(arg>>24);
        spi(arg>>16);
        spi(arg>>8);
        spi(arg);
        spi(0x95);                                      // spi CRC = always 0xFF OR 0x95 for MMC_GO_IDLE_STATE command
        while((resp = spi(0xFF)) == 0xFF)
                if(retry++ > 8) break;                  // card has timed out
        return resp;                                    // Note! MMC enable is ON
}
                                                                   
unsigned char mmc_init(void) // Initialize mmc-card, returns zero if successful.
{
     unsigned char retry, i, resp=0;

     retry = 0;
     do                                                 // max 10 retries
     {
         // send 74+ (=80) dummy bits with CS high before accessing        
         for(i=0;i<10;i++)         
                spi(0xFF);
         // resetting card, go to SPI mode
         resp = mmc_command(IDLE_STATE, 0);             // command 0
         #ifdef MMC_DEBUG4
         printf("IDLE_STATE-status:%x\r\n", resp);
         #endif
         retry++;
         if(retry>10) return -1;
     } while(resp != 0x01);
 
     retry = 0;
     do                                                 // max 100 retries
     {  // send init cmd (1)
        resp = mmc_command(INIT_COMMAND, 0);
        #ifdef MMC_DEBUG4
        printf("INIT_CMD-status:%x\r\n", resp);
        #endif
        retry++;
        if(retry>100) return -1;
     } while(resp);
         
     // turn off CRC checking (not actually needed CRC-off is default)
     resp = mmc_command(CRC_OFF, 0);
     #ifdef MMC_DEBUG4
     printf("CRC_OFF-status:%x\r\n", resp);
     #endif
 
     // set block length to 512 bytes (not actually needed 512 bytes is default)
     resp = mmc_command(SET_BLKLEN, 512);
     #ifdef MMC_DEBUG4
     printf("SET_BLKLEN-status:%x\r\n", resp);
     #endif
     return 0;
}


unsigned char mmc_write(unsigned long sector, unsigned char* buffer) // write to MMC (from buffer or 'Z')
{       unsigned char resp;
        unsigned int i;

        PORTB.2 = 0;                                            // set chip select
        resp = mmc_command(WRITE_BLK, sector<<9);
        #ifdef MMC_DEBUG3
        printf("Write SECT %lu:%x\r\n", sector,  resp);
        #endif
        if(resp != 0x00)        return resp;                    // check for  response
        spi(0xFF);                                              // send dummy
        spi(STARTBYTE_RDWR);                                    // send data start token
        for(i=0; i<0x200; i++)
        {       spi('Z');                                       // write data       
                // spi(*buffer++);
        }
        spi(0xFF);                                              // write 16-bit CRC (dummy values)
        spi(0xFF);
        resp = spi(0xFF);
        if( (resp & DR_MASK) != DR_ACCEPT)    return resp;      // read data response

        #ifdef MMC_DEBUG3
        printf("Data Response=0x%x\r\n", resp);
        #endif
        while(!spi(0xFF));                                      // wait until card not busy
        PORTB.2 = 1;                                            // release chip select
        return 0;                                               // return ok

}



unsigned char mmc_read(unsigned long sector, unsigned char* buffer) // Read buffer, returns zero if successful.
{
        unsigned char resp;
        unsigned int i;

        PORTB.2 = 0;                                            // set chip select
        resp = mmc_command(READ_BLK, sector<<9);                // send command:READ-BLOCK
        #ifdef MMC_DEBUG3
        printf("\r\nRead SECT %lu:%x", sector, resp );
        #endif
        if(resp != 0x00)        return resp;                    // check response
        while(spi(0xFF) != STARTBYTE_RDWR);                     // wait for block start
        for(i=0; i<0x200; i++)
        {       *buffer++ = spi(0xFF);                          // read in data
        }
        spi(0xFF);                                              // read 16-bit CRC
        spi(0xFF);
        PORTB.2 = 1;                                            // release chip select
        return 0;                                               // return OK
}                                         

dump()                                                          // dump block (sector) buffer as hex to serial port
{       unsigned char i,j;
        unsigned int m = 0;
        
        for(i=0;i<32;i++)
        {       printf("\r\n%3x:", m);
                for(j=0;j<16;j++) 
                {       printf("%3x ", block[m]);
                        m++;
                }                                  
        } 
        printf("\r\n");              
}               

txtdump()                                                       // dump block (sector) buffer as text to serial port
{       unsigned char i,j;
        unsigned int m = 0;
        
        for(i=0;i<32;i++)
        {       printf("\r\n%3x:", m);
                for(j=0;j<16;j++) 
                {       printf("%c ", block[m]);
                        m++;
                }                                  
        }
        printf("\r\n");              
                
}                                                                   

dump_file(unsigned int ClustNumber)                             // dump file ClustNumber = first cluster nuber of file
{       bit Feof;
        unsigned int dSector, i, NextClust;
        unsigned int *ptr;
        #ifdef MMC_DEBUG2
        printf("FileAllocationTable addr:%u\r\n", FatStart);
        #endif     
        Feof = 1;                                     
        while(Feof)
        {       
                dSector = ClusterOffset + (ClustNumber  - 2) * SectPerCluster; // calculate sector number
                #ifdef MMC_DEBUG2
                printf("Read Cluster:0x%x ",ClustNumber); 
                #endif
                printf("Read Sectors:", dSector); 
                for(i=0;i<SectPerCluster;i++)
                {       printf("%u, ", dSector); 
                        mmc_read(dSector,block); //Read data
                        //txtdump();
                        dSector++;
                }                
                
                // fetch next cluster number from FAT
                printf("\r\nRead FAT table\r\n");               
                dSector = FatStart + ClustNumber / 256;         // calculate current Sector number of FAT table
                printf("FatSectorAddr:%u ", dSector);
                mmc_read(dSector,block); //Read Fat table
                // dump();
                ptr = block;    
                ClustNumber&=0xFF;                              // Max offset = 0xFF
                ptr+=ClustNumber;                               // pointer to next cluster number
                NextClust =  *ptr;              // get next cluster number
                printf("PrevCluster:%u, NextCluster:%u (0x%x)\r\n",ClustNumber, NextClust, (unsigned int *) *ptr);
                if(NextClust > 0xFF00)   Feof = 0;              // only 0xFF00 checked
                ClustNumber = NextClust;
        } 

 
}                                                         
         

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -