📄 sddriver.c
字号:
/****************************************Copyright (c)**************************************************** Guangzhou ZHIYUAN electronics Co.,LTD.** ** http://www.zyinside.com****--------------File Info-------------------------------------------------------------------------------** File Name: sddriver.c** Last modified Date: 2006.01.09** Last Version: V1.0 ** Description: API funciton of initializ,read,write SD/MMC卡 ** 初始化、读、写 SD/MMC卡的 API 函数**------------------------------------------------------------------------------------------------------** Created By: MingYuan Zheng 郑明远** Created date: 2006.01.09** Version: V1.0** Descriptions: The original version 初始版本****------------------------------------------------------------------------------------------------------** Modified by:** Modified date:** Version:** Description:**********************************************************************************************************/#include "config.h"/* SD/MMC卡信息结构体变量 the information structure variable of SD/MMC Card */sd_struct sds = {0}; /* 超时时间单位表(单位:0.000000001ns) timeout unit table */const INT32U time_unit[8] = {1000000000,100000000,10000000, 1000000,100000,10000,1000,100};/* 超时时间表 timeout value table */ const INT8U time_value[16] = {0,10,12,13,15,20,25,30, 35,40,45,50,55,60,70,80}; /* 超时时间因数表 timeout factor table */ const INT8U r2w_fator[6] = {1,2,4,8,16,32}; /* 与中断相关的全局变量 global variable releated with interrupt */#if SD_INTERRUPT_ENstatic DECLARE_WAIT_QUEUE_HEAD(wq);volatile int reading; /* 读卡(1)或写卡(1)状态 read card(1) or write card(1) status */INT8U *buffer; /* 读卡或写卡缓冲区 the buffer of read or write card */INT32 bufcnt; /* 缓冲区计数器 buffer counter */INT32 datalen; /* 读卡或写卡数据长度 the data length of read or write card */volatile int error;#endif volatile int card_insert;int card_change = 0; /* 卡改变,卡插入开拔出 */ volatile INT16U card_id = 0; /* card slot identify, added 20060330 */ /* *************************************************************************************************** 用户API函数: 初始化,读,写,擦 SD卡 User API Function: Initialize,read,write,erase SD Card *************************************************************************************************** *//*********************************************************************************************************** Function name: SD_Initialize** Descriptions: initialize SD/MMC card** 初始化SD/MMC卡 ** Input: sd_struct *sds: SD卡信息结构体 sd_struct *sds: the information structure of SD Card** Output: 0: 正确 >0: 错误码 0: right >0: error code ** Created by: MingYuan Zheng 郑明远 ** Created Date: 2006-01-09 **-------------------------------------------------------------------------------------------------------** Modified by:** Modified Date: **------------------------------------------------------------------------------------------------------********************************************************************************************************/INT8U SD_Initialize(sd_struct *sds){ INT8U response[16], ret; SD_HardWareInit(); /* 1. 初始化SD/MMC接口硬件 Initialize the hardware of SD/MMC interface */ ret = SD_ResetSD(); if (ret!= SD_NO_ERR) /* 2. 发出CMD0命令复位SD卡 send CMD0 command to reset SD/MMC card */ return ret; sds->card_type = Card_Indentify(); /* 3. 判别卡的型号:SD或MMC卡 identify card type: SD or MMC card */ ret = SD_ActiveCard(sds); /* 4. 激活SD/MMC卡 active SD/MMC card */ if (ret != SD_NO_ERR) return ret; ret = SD_ReadAllCID(16, response); /* 5. 请所有卡发送CID寄存器 ask all card send their CID number */ if (ret != SD_NO_ERR) return ret; if (sds->RCA == 0) { card_id++; sds->RCA = card_id; /* 给卡分配一个地址 assign a address */ } ret = SD_GetRCA(sds->card_type, &sds->RCA); /* 6. 得到卡的RCA get the RCA of the card */ if (ret != SD_NO_ERR) return ret; ret = SD_GetCardInfo(sds); /* 7. 读CSD寄存器,获取SD卡信息 read CSD register, get the information of SD card */ if (ret != SD_NO_ERR) return ret; SD_ClkToMax(); /* 8. 设置读/写SD/MMC时钟到最大值 set clock of reading or writing SD/MMC to maximum */ return (SD_SetBlockLen(sds->RCA, SD_BLOCKSIZE)); /* 9. 设置块的长度: 512Bytes Set the block length: 512Bytes */}/*********************************************************************************************************** Function name: SD_ReadBlock** Descriptions: read a block from SD/MMC card** 从SD/MMC卡中读出一个块** Input: sd_struct *sds : SD/MMC卡信息结构体 sd_struct *sds : the information structure of SD/MMC Card INT32U blockaddr: 块地址 INT32U blockaddr: the address of the block INT8U *recbuf : 接收缓冲区,长度512Bytes INT8U *recbuf : the buffer of receive,length is 512Bytes** Output: 1: 成功 > 0: 错误码 1: sucessfully > 0: error code ** Created by: MingYuan Zheng 郑明远 ** Created Date: 2006-01-09 **-------------------------------------------------------------------------------------------------------** Modified by:** Modified Date: **------------------------------------------------------------------------------------------------------********************************************************************************************************/INT8U SD_ReadBlock(sd_struct *sds, INT32U blockaddr, INT8U *recbuf){ INT8U ret,status[4]; INT32U stat = 0; ret = SD_ReadCard_Status(sds->RCA, 4, status); /* 读取卡的状态 read the status of the card */ if (ret != SD_NO_ERR) return ret; ret = SD_SelectCard(sds->RCA); /* CMD7,进入传输状态 CMD7, enter tranfer status */ if (ret != SD_NO_ERR) return ret; if (sds->card_type == CARDTYPE_SD) { /* 卡为SD卡 card is SD card */ ret = SD_SetBusWidth(sds->RCA, 1); /* 设置卡为数据总线方式 set card to wide data bus */ if (ret != SD_NO_ERR) return ret; } #if SD_INTERRUPT_EN SDIIMSK = SDIIMSK_TOUT | SDIIMSK_DFIN | SDIIMSK_RX_LAST | SDIIMSK_RX_FULL; reading = 1; buffer = recbuf; /* 数据缓冲区指针 buffer pointer */ bufcnt = 0; datalen = SD_BLOCKSIZE; /* 接收数据长度 receive data length */ error = SD_ERR_TIMEOUT_READ; /* be initialized to error code */#endif if (sds->card_type == CARDTYPE_SD) stat = SDIDCON_RACMD_1 | SDIDCON_BLK | SDIDCON_RX | SDIDCON_WIDE | 1 << 0; else stat = SDIDCON_RACMD_1 | SDIDCON_BLK | SDIDCON_RX | 1 << 0; SDIBSIZE = SD_BLOCKSIZE; /* 块数据的长度 block data length */ SDICON |= SDICON_FRESET; /* 复位 FIFO reset FIFO */ SDIDCON = stat; /* 写数据控制寄存器 write data control register */ ret = SD_ReadSingleBlock(blockaddr); /* 读单块命令 read single blocks command */ if (ret != SD_NO_ERR) return ret;#if SD_INTERRUPT_EN interruptible_sleep_on(&wq); /* 进入可被中断的睡眠状态, 数据在中断中自动接收 */ if (!card_insert) { return SD_ERR_NO_CARD; /* 卡未插入,返回错误 */ } if (error) { /* there is error, return error code */ return error; } ret = SD_NO_ERR;#else /* 读出数据 read data from sd card */ ret = SD_ReadBlockData(SD_BLOCKSIZE, recbuf, sds->timeout_read); #endif if (ret != SD_NO_ERR) return ret; ret = SD_DeSelectCard(); /* CMD7, 退出传输状态 */ return SD_NO_ERR; }/*********************************************************************************************************** Function name: SD_WriteBlock** Descriptions: write a block to SD/MMC card** 向SD/MMC卡中写入一个块 ** Input: sd_struct *sds : SD/MMC卡信息结构体 sd_struct *sds : the information structure of SD/MMC Card INT32U blockaddr: 块地址 INT32U blockaddr: the address of the block INT8U *sendbuf : 发送缓冲区,长度512Bytes INT8U *sendbuf : the buffer of send,length is 512Bytes** Output: 1: 成功 > 0: 错误码 1: sucessfully > 0: error code ** Created by: MingYuan Zheng 郑明远 ** Created Date: 2006-01-09 **-------------------------------------------------------------------------------------------------------** Modified by:** Modified Date: **------------------------------------------------------------------------------------------------------********************************************************************************************************/INT8U SD_WriteBlock(sd_struct *sds, INT32U blockaddr, INT8U *sendbuf){ INT8U ret,tmp[4]; INT32U stat = 0; ret = SD_ReadCard_Status(sds->RCA, 4, tmp); /* 读取卡的状态 read the status of the card */ if (ret != SD_NO_ERR) return ret; ret = SD_SelectCard(sds->RCA); /* CMD7,进入传输状态 CMD7, enter tranfer status */ if (ret != SD_NO_ERR) return ret; if (sds->card_type == CARDTYPE_SD) { /* 卡为SD卡 card is SD card */ ret = SD_SetBusWidth(sds->RCA, 1); /* 设置卡为数据总线方式 set card to wide data bus */ if (ret != SD_NO_ERR) return ret; } #if SD_INTERRUPT_EN SDIIMSK = SDIIMSK_TOUT | SDIIMSK_DFIN | SDIIMSK_TX_EMP; reading = 0; buffer = sendbuf; /* 数据缓冲区指针 buffer pointer */ bufcnt = 0; datalen = SD_BLOCKSIZE; /* 发送数据长度 send data length */ error = SD_ERR_TIMEOUT_WRITE; /* be initialized to error code */#endif if (sds->card_type == CARDTYPE_SD) stat = SDIDCON_TARSP_1 | SDIDCON_BLK | SDIDCON_TX | SDIDCON_WIDE | 1 << 0; else stat = SDIDCON_TARSP_1 | SDIDCON_BLK | SDIDCON_TX | 1 << 0; SDIBSIZE = SD_BLOCKSIZE; /* 块数据的长度 block data length */ SDICON |= SDICON_FRESET; /* 复位 FIFO reset FIFO */ SDIDCON = stat; /* 写数据控制寄存器 write data control register */ ret = SD_WriteSingleBlock(blockaddr); /* 写单块命令 write single block */ if (ret != SD_NO_ERR) return ret;#if SD_INTERRUPT_EN interruptible_sleep_on(&wq); /* 进入可被中断的睡眠状态, 数据自动接收 */ if (!card_insert) { return SD_ERR_NO_CARD; /* 卡未插入,返回错误 */ } if (error) { /* there is error, return error code */ return error; } ret = SD_NO_ERR;#else /* 写入数据到SD/MMC card write data to SD/MMC card */ ret = SD_WriteBlockData(0, SD_BLOCKSIZE, sendbuf, sds->timeout_write); /* */#endif if (ret == SD_NO_ERR) /* 读Card Status寄存器, 检查写入是否成功 */ { /* read Card Status register to check write wheather sucessfully */ ret = SD_ReadCard_Status(sds->RCA, 4, tmp); if (ret != SD_NO_ERR) return ret; /* 读寄存器失败 read register fail */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -