📄 mmc.h
字号:
//*************************************************************************************
//------------------ SD-Card Reading and Writing -------------------
//*************************************************************************************
//#include "include\AT91SAM7X256.h"
//#include "include\lib_AT91SAM7X256.h"
# include "Board.h"
//************************操作方式定义,根据具体卡,模式设置****************************
#define USE_MMC 1 // 是否操作MMC卡(读写MMC还是SD卡,目前仅为SD)
#define Direct_IO // 直接I/O口模拟SPI模式
//#define SPI_Mode // 是否定义为SPI模式
//#define MCI_Mode // MCI操作模式
// 定义 SD卡 的SPI 接口信号:DI , DO, CLK, CS
#define SPI_DI 1<<16 // SD_DI_PIN : PA16
#define SPI_DO 1<<17 // SD_DO_PIN : PA17
#define SPI_Clock 1<<18 // SD_CLK_PIN : PA18
#define MMC_Chip_Select 1<<13 // SD_CS_PIN : PA13
//*** define SD card's MCI interface signal,only with ATSAM7A3_EK board
#define MCI_Clock // SD卡在MCI接口下的时钟管脚
#define MCI_CMD // SD command signal with MCI interface
#define MCI_D0 // SD data0 signal with MCI interface
#define MCI_D1 // Data1
#define MCI_D2 // Data2
#define MCI_D3 // Data3
#define NowSD_SPI AT91C_BASE_SPI0 //SD所使用的 SPI序号:第零号SPI接口
//***************************************************************
// Error define (定义一些初始化时必要命令的错误号 )
//-------------------------------------------------------------
#define INIT_CMD0_ERROR 0x01
#define INIT_CMD1_ERROR 0x02
#define WRITE_BLOCK_ERROR 0x03
#define READ_BLOCK_ERROR 0x04 //以上四个全为在SPI模式下的初始化错误
//-------------------------------------------------------------
// 读出卡内固定信息,从CSD寄存器中读出来,使用标准命令 Command9
typedef struct MMC_VOLUME_INFO
{ // MMC/SD Card info
int size_MB; //总字节数,通过计算得到
int sector_multiply; //以下三项,通过读CSD寄存器得到
int sector_count ; //扇区数目
int READ_BL_LEN ; //每块可读的数据长度
int name[6] ; //得到Product name.5个ASCII字符
int OID[3] ; //*********OEM ID ,16比特 2进制数 , 暂未用
int PSN[5] ; //*********Product serial number,32 bit ,暂未用
} VOLUME_INFO_TYPE;
typedef struct STORE //定义 CSD 缓冲,CSD寄存器只需要32字节(32*8=256 bit),
{
unsigned char data[256];
} BUFFER_TYPE; //256 bytes, 128 words
BUFFER_TYPE sectorBuffer;
//--------------------------------------------------------------
int readPos=0; //读写扇区内的当前位置(1 sector=512 byte),新扇区的其始点为0
int sectorPos=0; //记录当前的扇区号
int LBA_Opened=0; //Set to 1 when a sector is opened.
int Init_Flag; //Set it to 1 when Init is processing.
//---------------------------------------------------------------
// 函数申明,其功能详见定义处注释,其中读写地址使用逻辑地址即线性地址( LBA )定址,
// 协议未介绍参看其他资料 ,LBA :Ligical Block Address .LBA=(C-Cs)*PH*PS+(H-Hs)*PS+(S-Ss)
// 对于上面的公式,因LBA 采用的寻址方式,先找到当前柱面偏移处起始磁头处的总扇区数,再加上
// 当前磁头处所经过的柱面内的磁道数,最后加上在磁道内的偏移扇区( 1开始 ),资料信息见下边 (本页末)
//---------------------------------------------------------------
void MMC_Port_Init(void);
unsigned char MMC_Init(void);
unsigned char Read_Byte_MMC(void);
unsigned char Read_Byte_MMC_Long(void); // extend read ,reserved to use
void Write_Byte_MMC(unsigned char value);
void Write_Byte_MMC_Long(unsigned char value); // 保留
unsigned char MMC_Read_Block(unsigned char *CMD,unsigned char *Buffer,unsigned int Bytes);
unsigned char MMC_write_sector(unsigned long addr,unsigned char *Buffer);
unsigned char MMC_read_sector(unsigned long addr,unsigned char *Buffer);
unsigned char Write_Command_MMC(unsigned char *CMD);
unsigned char Read_CSD_MMC(unsigned char *Buffer);
unsigned char Read_CID_MMC(unsigned char *Buffer);
void MMC_get_volume_info(void);
unsigned char MMC_Start_Read_Sector(unsigned long sector);
void MMC_get_data(unsigned int Bytes,unsigned char *buffer);
void MMC_get_data_LBA(unsigned long lba, unsigned int Bytes,unsigned char *buffer);
void MMC_GotoSectorOffset(unsigned long LBA,unsigned int offset);
void MMC_LBA_Close(void);
#define delay_us_8_ asm("nop")
//******* LBA 模式的值与Head ,Cylinder。Track 的关系实列 *********
/*
C/H/S与LBA地址的对应关系:
从CHS到LBA
假设用C表示当前柱面号,H表示当前磁头号,Cs表示起始柱面号,Hs表示起始磁头号,Ss表示起始扇区号,PS表示每磁道有多少个扇区,PH表示每柱面有多少个磁道,则有以下对应关系:
LBA=(C-Cs)*PH*PS+(H-Hs)*PS+(S-Ss)
一般情况下,CS=0、HS=0、SS=1;PS=63、PH=255
那么以下可以根据公司计算,如下:
C/H/S=0/0/1,代入上述公式中得到LBA=0
C/H/S=0/0/63,代入上述公式中得到LBA=62
C/H/S=1/0/1,代入上述公式中得到LBA=63
C/H/S=220/156/18,代入上述公式中得到LBA=3544145
从LBA到CHS
在这里先介绍两种运算DIV和MOD。DIV做整除运算,即被除数除以除数所得的商的整数部分;比如5 DIV 3=1,33 DIV 6=5。
MOD是余运算,MOD运算则取商的余数;比如:5 MOD 3=2,33 MOD 6=5。
DIV和MOD是一对搭档,一个取整一个取余。各个变量按照上面的进行假设,那么有:
C=LBA DIV (PH*PS) + Cs
H=(LBA DIV PS) MOD PH + Hs
S=LBA MOD PS + Ss
如果上述不用MOD运算,只用DIV运算可以如下:
C= LBA DIV (PH*PS) + Cs
H=LBA DIV PS –(C-Cs) * Ps + Ss
S=LBA- (C-Cs) * PH * PS - (H-Hs) * PS + Ss
那么按照这个规律则有:
LBA=0,相应地C/H/S=0/0/1
LBA=62,相应地C/H/S=0/0/63
LBA=63,相应地C/H/S=1/0/1
LBA=62,相应地C/H/S=0/0/63
LBA=3544145,相应地C/H/S=220/156/18,
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -