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

📄 mmc_sd.c

📁 在mtk平台上写的gpio口模拟spi协议的SD卡读卡器
💻 C
📖 第 1 页 / 共 2 页
字号:
/*************************************************************/
/*                   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 + -