?? 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 + -