📄 mmc_sd.c
字号:
/*************************************************************/
/* SD/MMC操作函数库 */
/* 环境WinAVR 20060421 */
/* 作者:Bozai(章其波) */
/* E-mail:sudazqb@163.com */
/* 2006年11月26日 */
/*************************************************************/
/* FAT diriver for MiniMP3 Player */
/* */
/* Platform : MMC_SD */
/* */
/* Author : ZHANGNU */
/* E-mail : zhangnu@ginwave.com */
/* Date : 2007-11-20 */
/*
CID 128 Card identification number; card individual number for identification. Mandatory.
RCA 16 Relative card address; local system address of a card, dynamically suggested by the card and approved by the host during initialization. Mandatory.
DSR 16 Driver Stage Register; to configure the card's output drivers. Optional.
CSD 128 Card Specific Data; information about the card operation conditions. Mandatory
SCR 64 SD Configuration Register; information about the SD Memory Card’s Special Features capabilities. Mandatory
OCR 32 Operation condition register. Mandatory.
部分SD存储卡命令 Command Mnemonic Argument Reply Description
0 (0x00) GO_IDLE_STATE none R1 Resets the SD card. resets all cards to idle state
2 ALL_SEND_CID
3 0x03 SEND_RELATIVE_ADDR
4 SET_DSR
7 SELECT/DESELECT_CARD
9 (0x09) SEND_CSD none R1 Sends card-specific data.
10 (0x0a) SEND_CID none R1 Sends card identification.
12 STOP_TRANSMISSION
13 SEND_STATUS
15 GO_INACTIVE_STATE
16 SET_BLOCKLEN
17 (0x11) READ_SINGLE_BLOCK address R1 Reads a block at byte address.
18 READ_MULTIPLE_BLOCK
24 (0x18) WRITE_BLOCK address R1 Writes a block at byte address.
25 WRITE_MULTIPLE_BLOCK
26 PROGRAM_CSD
55 (0x37) APP_CMD none R1 Prefix for application command.
59 (0x3b) CRC_ON_OFF Only Bit 0 R1 Argument sets CRC on (1) or off (0).
41 (0x29) SEND_OP_COND none R1 Starts card initialization
*/
/*******************************************************************/
#include "drv_comm.h"
#include "stdio.h"
#include "sccb.h"
#include "med_api.h"
#include "alerter_sw.h"
#include "alerter_hw.h"
#include "gpio_hw.h"
#include "gpio_sw.h"
#include "gpio_drv.h"
#include "MMC_SD.h"
typedef unsigned char BYTE;
const BYTE SD_CS_PIN = GPIO_PORT_8; //CS引脚定义
const BYTE SD_DO_PIN = GPIO_PORT_4 ;
const BYTE SD_CLK_PIN = GPIO_PORT_3;
const BYTE SD_DIN_PIN = GPIO_PORT_9;
extern void SPI_CS_Assert(void)
{
GPIO_InitIO(1, SD_CS_PIN);
GPIO_WriteIO(0,SD_CS_PIN);
}
extern void SPI_CS_Deassert(void)
{
GPIO_InitIO(1, SD_CS_PIN);
GPIO_WriteIO(1,SD_CS_PIN);
}
unsigned char DISK_CAPACITY[8]= //磁盘容量//在SD初始化后会修改
{
0x00,0x0F,0x1C,0xF0,
0x00,0x00,0x02,0x00
};
unsigned char SPI_ReadByte=0xff;
//预置SD 命令CMD
#define GO_IDLE_STATE 0x00 //resets all cards to idle state
#define ALL_SEND_CID 0x02 //asks any card to send the CID numbers on the CMD line (any card that is connected to the host will respond)
#define SEND_RELATIVE_ADDR 0x03 //ask the card to publish a new relativeaddress (RCA)
#define SET_DSR 0x04 //programs the DSR of all cards
#define SELECT_DESELECT_CARD 0x07 //
#define SEND_CSD 0x09 //none R1 Sends card-specific data.
#define SEND_CID 0x0a //none R1 Sends card identification
#define STOP_TRANSMISSION 0x0c //forces the card to stop transmission
#define SEND_STATUS 0x0e //addressed card sends its status register.
#define GO_INACTIVE_STATE 0x0f //sets the card to inactive state in order to protect the card stack against communication breakdowns.
#define SET_BLOCKLEN 0x10 //sets the block length
#define SD_RxBufferSize 1920
#define MMC_PRINTF dbg_print
unsigned int SSC_rx_lisr_tp_value=0;
unsigned int SSC_tx_lisr_tp_value=0;
//收缓冲区
unsigned char SD_RX_buffer[SD_RxBufferSize] ;
//read指针
unsigned char SD_RX_buffer_R = 0;
//write指针
unsigned char SD_RX_buffer_W = 0;
unsigned char SD_DI_hisr_PID;
//低速模式 //spi low speed
void SPI_Low(void)
{
//SSCBR = 0x0103; // SCLK running at 50kHz
}
//高速模式 //spi full speed
void SPI_High(void)
{
//SSCBR = 0x000C; // SCLK running at 8*50K=500K (original)
}
void WDR(void)
{}
#define TICKS_PER_MSEC 5000
void delay(kal_uint32 ms)
{
int i;
int j;
for (j = 0; j < ms; j++)
{
for (i = 0; i < TICKS_PER_MSEC; i++)
{
__asm
{
NOP
}
}
}
}
void con_DelayMs(unsigned int ms)
{
#if 1
int i;
int j;
for (j = 0; j < ms; j++)
{
for (i = 0; i < TICKS_PER_MSEC; i++)
{
__asm
{
NOP
}
}
}
#else
//Delay(ms);
unsigned int i,j;
for(i = 0; i < ms; i++)
{
for(j=0;j<470;j++)
{
__asm
{
NOP
}
}
}
#endif
}
/****************************************************************************************
* Function:.... SPI_INIT
* Parameters:
* Returns:......
* Description: 初始化spi 口
* Created:.... zhangnu
* Modified:.... 2007-11-02
****************************************************************************************/
void SPI_INIT(void)
{
//SD_RX_buffer[SD_RxBufferSize] =0;
memset(SD_RX_buffer, 0 , sizeof(SD_RX_buffer));
GPIO_ModeSetup(SD_CLK_PIN,0);
GPIO_InitIO(1, SD_CLK_PIN);
GPIO_WriteIO(0,SD_CLK_PIN);
GPIO_ModeSetup(SD_CS_PIN,0);
GPIO_InitIO(1, SD_CS_PIN);
GPIO_WriteIO(0,SD_CS_PIN);
GPIO_ModeSetup(SD_DIN_PIN,0);
GPIO_InitIO(1, SD_DIN_PIN);
GPIO_WriteIO(0,SD_DIN_PIN);
GPIO_ModeSetup(SD_DO_PIN,0);
GPIO_InitIO(0, SD_DO_PIN);
GPIO_WriteIO(0,SD_DO_PIN);
SPI_Low();
}
//写一个字节到sd卡
extern void SPIBYTE_write(unsigned char iodata)
{
unsigned char num,b;
num=0x80;
//写一个8位数据
for (b=0;b<0x08;b++)
{
WDR();//feed the dog
GPIO_WriteIO(0,SD_CLK_PIN);//sck=0
if(iodata&num)
GPIO_WriteIO(1,SD_DIN_PIN); //do=1
else
GPIO_WriteIO(0,SD_DIN_PIN);//do=0
con_DelayMs(4);//4
WDR();//feed the dog
GPIO_WriteIO(1,SD_CLK_PIN);//sck=1
con_DelayMs(4);//4
if(num>0x01)
num=num>>1;
}
}
//读一个字节从sd卡
extern unsigned char SPIBYTE_read(void)
{
unsigned char data,temp,b;
data=0;
temp=0;
for (b=0;b<0x08;b++)
{
WDR();//feed the dog
GPIO_WriteIO(0,SD_CLK_PIN);//sck=0
con_DelayMs(4);//4
WDR();//feed the dog
GPIO_WriteIO(1,SD_CLK_PIN);//sck=1
temp=GPIO_ReadIO(SD_DO_PIN);
WDR();//feed the dog
if(temp)
{
data|=0x01;
}
if(b<7)
{
data=data<<1;//
}
con_DelayMs(4);//4
WDR();//feed the dog
}
return data;
}
//写读一个字节 //write one byte
extern unsigned char SPI_WriteByte(unsigned char val)
{
unsigned char SSCRB;
SPIBYTE_write(val);
con_DelayMs(4);
SSCRB=SPIBYTE_read();
return (unsigned char)SSCRB;
}
#if 0
/****************************************************************************************
* Function:.... SD_SSC_rx_lisr
* Parameters:
* Returns:.....
* Description: SPI RX中断服务程序
* Created:.... zhangnu
* Modified:.... 2007-11-02
****************************************************************************************/
OS_PROCESS(SD_SSC_rx_lisr)
{
RESETBIT(SSC0RIC, 6); // disable int
RESETBIT(SSC0RIC, 7); //clear int request flags
// PCL_37=GPIO_PIN | OUTPUT_PIN | DATA_PIN(0);
SSC_rx_lisr_tp_value++; //for test only
//如果循环队列已满,直接丢弃,@960应是足够大的缓存
if(((SD_RX_buffer_W + 1) % SD_RxBufferSize) == SD_RX_buffer_R)
{
SD_RX_buffer[SD_RxBufferSize] =0;
}
else
{
SD_RX_buffer[SD_RX_buffer_W++] = (unsigned char)SSCRB;
SPI_ReadByte=SSCRB;
SD_RX_buffer_W %= SD_RxBufferSize;
//if(SD_RX_buffer_W % 20 == 0) //收到6个才触发高级中断一次
//if(get_fsem(SD_DI_hisr_PID) < 1)
//{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -