sddriver.c
上传用户:yj_qqy
上传日期:2017-01-28
资源大小:2911k
文件大小:25k
源码类别:

uCOS

开发平台:

C/C++

  1. /****************************************Copyright (c)**************************************************
  2. **                               Hangzhou yh software  Co.,LTD.
  3. **                                     
  4. **                                 http://www.armgcc.com
  5. **
  6. **--------------File Info-------------------------------------------------------------------------------
  7. ** File name: sddriver.c
  8. ** Last modified Date: 2007-10-15
  9. ** Last Version: V1.0
  10. ** Descriptions: SD/MMC卡读写模块: 物理层 用户API函数
  11. **
  12. **------------------------------------------------------------------------------------------------------
  13. ** Created by: lhlzjut@hotmail.com
  14. ** Created date: 2007-10-15
  15. ** Version: V1.0
  16. ** Descriptions: The original version
  17. **
  18. **------------------------------------------------------------------------------------------------------
  19. ********************************************************************************************************/
  20. #include <stdio.h>
  21. #include "sdhal.h"
  22. #include "sdcmd.h"
  23. #include "sddriver.h"
  24. #if SD_UCOSII_EN    
  25. #include  "ucos_ii.h"
  26. #endif
  27. #if SD_UCOSII_EN
  28. OS_EVENT *pSemSD = NULL; /* 卡访问权限信号量 semaphore that access card */
  29. #endif 
  30. /* SD卡信息结构体变量 the information structure variable of SD Card */
  31. sd_struct sds;
  32. /* 超时时间单位表(单位:0.000000001ns) timeout unit table */
  33. const INT32U time_unit[8] = {1000000000,100000000,10000000,
  34.  1000000,100000,10000,1000,100};
  35. /* 超时时间表 timeout value table */  
  36. const INT8U time_value[16] = {0,10,12,13,15,20,25,30,
  37.                               35,40,45,50,55,60,70,80};
  38.  
  39. /* 超时时间因数表 timeout factor table */                              
  40. const INT8U r2w_fator[8] = {1,2,4,8,16,32,64,128};                           
  41.  
  42. void SD_Sleep(INT32U cpt_loop)
  43. {
  44.   while (cpt_loop -- != 0);
  45. }   
  46. /*       
  47. ***************************************************************************************************
  48.      用户API函数:  初始化,读,写,擦 SD卡  User API Function: Initialize,read,write,erase SD Card 
  49. ***************************************************************************************************
  50. */
  51. /*******************************************************************************************************************
  52. ** 函数名称: INT8U SD_Initialize() Name:   INT8U SD_Initialize()
  53. ** 功能描述: 初始化SD/MMC卡 Function: initialize SD/MMC card
  54. ** 输   入: 无 Input:   NULL
  55. ** 输    出: 0:   成功    >0:  错误码 Output:   0:  right >0:  error code
  56. ********************************************************************************************************************/
  57. INT8U SD_Initialize(void)
  58. {
  59. INT8U recbuf[4],ret;
  60. #if SD_UCOSII_EN
  61. if (pSemSD == NULL)
  62. {
  63.      pSemSD = OSSemCreate(1); /* 创建访问SD/MMC卡信号量 create SD/MMC semaphore */ 
  64. if (pSemSD == NULL)
  65.   return SD_ERR_CREATE_SEMSD;
  66. }     
  67. #endif
  68.    
  69.     SD_StartSD();
  70.     SD_HardWareInit();      /* 初始化读写SD卡的硬件条件 Initialize the hardware that access SD Card */
  71.     
  72.     if (SD_ChkCard() != 1) /* 检查卡是否插入 check weather card is inserted */
  73.     {
  74.      ret = SD_ERR_NO_CARD;   
  75.      goto SD_ERR;
  76.     }
  77.         
  78.     SPI_CS_Assert(); /* 1. 置CS为低 assert CS */  
  79. SD_SPIDelay(200); /* 2. 至少延时 74 clock delay more than 74 clock */
  80.     
  81. SPI_CS_Deassert(); /* 3. 置CS为高 dessert CS */
  82.     SD_SPIDelay(4); /* 4. 延时2(8 clock) delay 2(8 clock) */
  83.      
  84.     SD_Sleep(1000000);
  85.     
  86.     ret = SD_ResetSD(); /* 5. 发出CMDO命令复位SD卡 send CMD0 command to reset sd card */
  87.    
  88.     if (ret != SD_NO_ERR)
  89.         goto SD_ERR;
  90.  
  91.   ret = SD_ActiveInit(); /* 6. 激活卡进入初始化过程. active card initialize process */
  92.   if (ret != SD_NO_ERR)
  93.   goto SD_ERR;
  94.     
  95.     ret = SD_ReadOCR(4, recbuf);   /* 7. 读OCR寄存器,查询卡支持的电压值 read OCR register,get the supported voltage */
  96.     if (ret != SD_NO_ERR)
  97.         goto SD_ERR;
  98.     
  99.     if ((recbuf[1] & MSK_OCR_33) != MSK_OCR_33)
  100.     {   
  101.         ret = SD_ERR_VOL_NOTSUSP; /* 不支持3.3V,返回错误码  not support 3.3V,return error code */
  102.      goto SD_ERR;
  103.     }
  104.           
  105. #if SD_CRC_EN        
  106.     ret = SD_EnableCRC(1); /* 使能CRC校验 enable CRC check */
  107. if (ret != SD_NO_ERR)  
  108.    goto SD_ERR;
  109. #endif
  110.     ret = SD_SetBlockLen(SD_BLOCKSIZE); /* 8. 设置块的长度: 512Bytes Set the block length: 512Bytes */
  111.     if (ret != SD_NO_ERR)  
  112.         goto SD_ERR;
  113.         
  114.     ret = SD_GetCardInfo(); /* 9. 读CSD寄存器,获取SD卡信息 read CSD register, get the information of SD card */    
  115. if (ret != SD_NO_ERR)
  116. goto SD_ERR;
  117. SD_EndSD();
  118. SPI_ClkToMax(); /* 10. 设置SPI时钟到最大值 set SPI clock to maximum */
  119. return SD_NO_ERR; /* 初始化成功 initialize sucessfully */
  120. SD_ERR:
  121. SD_EndSD();
  122. return ret;
  123. }
  124. /********************************************************************************************************************
  125. ** 函数名称: INT8U SD_ReadBlock() Name:   INT8U SD_ReadBlock()
  126. ** 功能描述: 从SD/MMC卡中读一个块 Function: read a single block from SD/MMC card
  127. ** 输   入: INT32U blockaddr: 块地址 Input:    INT32U blockaddr: address of block
  128.  INT8U *recbuf   : 接收缓冲区,长度512Bytes     INT8U *recbuf   : the buffer of receive,length is 512Bytes
  129. ** 输    出: 0:   成功    >0:  错误码 Output:   0:  right >0:  error code
  130. *********************************************************************************************************************/
  131. INT8U SD_ReadBlock(INT32U blockaddr,INT32U len, INT8U *recbuf)
  132. {
  133. INT8U ret; 
  134. SD_StartSD(); /* 向OS申请访问卡信号量 request semaphore acessed SD/MMC to OS */
  135.     if (SD_ChkCard() != 1)
  136.     {
  137.      SD_EndSD();
  138.      return SD_ERR_NO_CARD;    /* 卡没完全插入卡中 card is not inserted entirely */
  139. }
  140. if (blockaddr > sds.block_num)
  141. {
  142. SD_EndSD();
  143. return SD_ERR_OVER_CARDRANGE; /* 操作超出卡容量范围 operate over the card range */
  144. }
  145.   ret = SD_ReadSingleBlock(blockaddr); /* 读单块命令 read single blocks command */
  146.   if (ret != SD_NO_ERR)
  147.   {
  148.   SD_EndSD();
  149.   return ret;
  150.   }
  151.  
  152.    ret = SD_ReadBlockData(len, recbuf); /* 读出数据 read data from sd card */
  153. SD_EndSD(); /* 归还访问卡信号量 return semaphore acessed SD/MMC to OS */
  154. return ret;
  155. }
  156. /********************************************************************************************************************
  157. ** 函数名称: INT8U SD_ReadMultiBlock() Name:   INT8U SD_ReadMultiBlock()
  158. ** 功能描述: 从SD/MMC卡中读多个块 Function: read multi blocks from SD/MMC card
  159. ** 输   入: INT32U blockaddr: 块地址 Input:   INT32U blockaddr: address of block
  160.  INT32U blocknum : 块数量   INT32U blocknum : the numbers of block
  161.  INT8U *recbuf   : 接收缓冲区,每块512字节   INT8U *recbuf   : the buffer of receive,each block length is 512Bytes
  162. ** 输    出: 0:   成功    >0:  错误码 Output:   0:  right >0:  error code
  163. *********************************************************************************************************************/
  164. #if SD_ReadMultiBlock_EN
  165. INT8U SD_ReadMultiBlock(INT32U blockaddr, INT32U blocknum, INT8U *recbuf)
  166. {
  167.     INT32U i;
  168.     INT8U ret;
  169.        
  170. SD_StartSD(); /* 向OS申请访问卡信号量 request semaphore acessed SD/MMC to OS */
  171.     if (SD_ChkCard() != 1)
  172.     {
  173.      SD_EndSD();
  174.      return SD_ERR_NO_CARD;    /* 卡没完全插入卡中 card is not inserted entirely */
  175. }
  176. if ((blockaddr + blocknum) > sds.block_num)
  177. {
  178. SD_EndSD();
  179. return SD_ERR_OVER_CARDRANGE; /* 操作超出卡容量范围 operate over the card range */
  180. }       
  181.     
  182. ret = SD_ReadMultipleBlock(blockaddr); /* 读多块命令 read multiple blocks command */
  183. if (ret != SD_NO_ERR)
  184. {
  185. SD_EndSD(); /* 归还访问卡信号量 return semaphore acessed SD/MMC to OS */
  186. return ret;
  187.     }
  188.     
  189.     for (i = 0; i < blocknum; i++)
  190.     { /* 读出数据 read data from SD/MMC card */
  191.      ret = SD_ReadBlockData(SD_BLOCKSIZE, recbuf);
  192.      if (ret == SD_NO_ERR)
  193.         recbuf = recbuf + SD_BLOCKSIZE;
  194.      else
  195.      {
  196.      SD_EndSD();
  197.      return ret;
  198.      }
  199.     }
  200.    
  201.   ret = SD_StopTransmission();     /* 结束数据传输 stop transmission operation */ 
  202.  
  203.   SD_EndSD();
  204. return ret; 
  205. }
  206. #endif
  207. /********************************************************************************************************************
  208. ** 函数名称: INT8U SD_WriteBlock() Name:   INT8U SD_WriteBlock()
  209. ** 功能描述: 向SD/MMC卡中写入一个块 Function: write a block to SD/MMC card
  210. ** 输   入: INT32U blockaddr: 块地址 Input:    INT32U blockaddr: address of block
  211.  INT8U *sendbuf  : 发送缓冲区,长度512Bytes      INT8U *sendbuf  : the buffer of send,length is 512Bytes
  212. ** 输    出: 0:   成功    >0:  错误码 Output:   0:  right >0:  error code
  213. *********************************************************************************************************************/
  214. INT8U SD_WriteBlock(INT32U blockaddr, INT32U len, INT8U *sendbuf)
  215. {
  216. INT8U ret,tmp[2];
  217. SD_StartSD(); /* 向OS申请访问卡信号量 request semaphore acessed SD/MMC to OS */
  218.     if (SD_ChkCard() != 1)
  219.     {
  220.      SD_EndSD();
  221.      return SD_ERR_NO_CARD;    /* 卡没完全插入卡中 card is not inserted entirely */
  222. }
  223. if (blockaddr > sds.block_num)
  224. {
  225. SD_EndSD();
  226. return SD_ERR_OVER_CARDRANGE; /* 操作超出卡容量范围 operate over the card range */
  227. }
  228. if (SD_ChkCardWP() == 1)
  229. {
  230. SD_EndSD();
  231. return SD_ERR_WRITE_PROTECT; /* 卡有写保护 */
  232. }
  233. ret = SD_WriteSingleBlock(blockaddr); /* 写单块命令 write single block */
  234. if (ret != SD_NO_ERR)
  235. {
  236. SD_EndSD();
  237. return ret;
  238. }
  239. ret = SD_WriteBlockData(0, len, sendbuf); /* 写入数据 write data */
  240.  
  241. if (ret == SD_NO_ERR) /* 读Card Status寄存器, 检查写入是否成功 */
  242.   { /* read Card Status register to check write wheather sucessfully */
  243.   ret = SD_ReadCard_Status(2, tmp);
  244.   if (ret != SD_NO_ERR)
  245.   {
  246.   SD_EndSD();
  247.   return ret; /* 读寄存器失败 read register fail */
  248. }
  249.   if((tmp[0] != 0) || (tmp[1] != 0))
  250.   {
  251.   SD_EndSD();
  252. ret = SD_ERR_WRITE_BLK;        /* 响应指示写失败 response indicate write fail */
  253.   }
  254.   }
  255.   
  256.     SD_EndSD();
  257.   return ret; /* 返回写入结果 return the result of writing */
  258. }
  259. /**********************************************************************************************************************
  260. ** 函数名称: INT8U SD_WriteMultiBlock() Name:   INT8U SD_WriteMultiBlock()
  261. ** 功能描述: 向SD/MMC卡中写入多个块 Function: write multi blocks to SD/MMC card
  262. ** 输   入: INT32U blockaddr: 块地址 Input:   INT32U blockaddr: address of block
  263.  INT32U blocknum : 块数量   INT32U blocknum : the numbers of block
  264.  INT8U *sendbuf  : 发送缓冲区每块512字节       INT8U *sendbuf  : the send buffer,each block length is 512Bytes
  265. ** 输    出: 0:   成功    >0:  错误码 Output:   0:  right >0:  error code
  266. ***********************************************************************************************************************/
  267. #if SD_WriteMultiBlock_EN
  268. INT8U SD_WriteMultiBlock(INT32U blockaddr, INT32U blocknum, INT8U *sendbuf)
  269. {
  270. INT32U i;
  271. INT8U ret,tmp[2];
  272. SD_StartSD(); /* 向OS申请访问卡信号量 request semaphore acessed SD/MMC to OS */
  273.     if (SD_ChkCard() != 1)
  274.     {
  275.      SD_EndSD();
  276.      return SD_ERR_NO_CARD;    /* 卡没完全插入卡中 card is not inserted entirely */
  277. }
  278. if ((blockaddr + blocknum) > sds.block_num)
  279. {
  280. SD_EndSD();
  281. return SD_ERR_OVER_CARDRANGE; /* 操作超出卡容量范围 operate over the card range */
  282. }
  283. if (SD_ChkCardWP() == 1)
  284. {
  285. SD_EndSD();
  286. return SD_ERR_WRITE_PROTECT; /* 卡有写保护 */
  287. }
  288. ret = SD_WriteMultipleBlock(blockaddr); /* 写多块命令 write multiple blocks command */
  289. if (ret != SD_NO_ERR)
  290. {
  291. SD_EndSD();
  292. return ret;
  293. }
  294.     for (i = 0; i < blocknum; i++)
  295.     {
  296.   ret = SD_WriteBlockData(1, SD_BLOCKSIZE, sendbuf); /* 写入数据 write data */
  297.   if (ret == SD_NO_ERR)
  298.   sendbuf = sendbuf + SD_BLOCKSIZE;
  299.   else
  300.   { /* 写失败 write fail */
  301. SD_StopTransmission(); /* 停止数据传输 stop data transmission */
  302. SD_WaitBusy(SD_WAIT_WRITE); /* 等待 waiting */
  303. SD_EndSD();
  304. return ret;
  305. }
  306. }
  307.    
  308.     SD_StopMultiToken(); /* 发送数据停止令牌 send data stop token */
  309.       
  310.     ret = SD_WaitBusy(SD_WAIT_WRITE); /* 等待写入的完成 wait for finishing writing */
  311.     if (ret != SD_NO_ERR)
  312.     {
  313.      SD_EndSD();
  314.      return SD_ERR_TIMEOUT_WRITE;
  315.     }
  316.     
  317.     if (sds.card_type == CARDTYPE_SD)
  318.     {
  319.     ret = SD_GetNumWRBlcoks(&i); /* 读正确写入的块数 read the blocks that be written correctly */
  320.     if (ret != SD_NO_ERR)
  321.     {
  322.     SD_EndSD();
  323.        return ret;
  324.     }
  325.     if(i != blocknum)
  326. ret =  SD_ERR_WRITE_BLKNUMS; /* 正确写入块数错误 the blocks that be written correctly is error */
  327.     }
  328.     else
  329.     {
  330.       ret = SD_ReadCard_Status(2, tmp);
  331.   if (ret != SD_NO_ERR)
  332.   {
  333.   SD_EndSD();
  334.   return ret; /* 读寄存器失败 read register fail */
  335. }
  336.   if((tmp[0] != 0) || (tmp[1] != 0))
  337. ret = SD_ERR_WRITE_BLK;        /* 响应指示写失败 response indicate write fail */
  338.     }
  339.      
  340.     SD_EndSD();         
  341. return ret; /* 返回写入成功 return write sucessfully */
  342. }
  343. #endif
  344. /*********************************************************************************************************************
  345. ** 函数名称: INT8U SD_EraseBlock() Name:   INT8U SD_EraseBlock()
  346. ** 功能描述: 擦除SD/MMC卡中的块 Function: Erase the block of SD/MMC card
  347. ** 输   入: INT32U startaddr: 起始地址 Input:    INT32U startaddr: start address
  348.  INT32U endaddr  : 终止地址   INT32U endaddr  : end address
  349. ** 输    出: 0:   成功    >0:  错误码 Output:   0:  right >0:  error code
  350. ** 注    意: startaddr 和 blocknum 建议为 sds.erase_unit 的整数倍, 因为有的卡只能以 sds.erase_unit 为单位进行擦除
  351. *********************************************************************************************************************/
  352. #if SD_EraseBlock_EN
  353. INT8U SD_EraseBlock(INT32U startaddr, INT32U blocknum)
  354. {
  355. INT32 tmp;
  356. INT8U ret;
  357. SD_StartSD(); /* 向OS申请访问卡信号量 request semaphore acessed SD/MMC to OS */
  358.     if (SD_ChkCard() != 1)
  359.     {
  360.      SD_EndSD();
  361.      return SD_ERR_NO_CARD;    /* 卡没完全插入卡中 card is not inserted entirely */
  362. }
  363. if ((startaddr + blocknum) > sds.block_num)
  364. {
  365. SD_EndSD();
  366. return SD_ERR_OVER_CARDRANGE; /* 操作超出卡容量范围 operate over the card range */
  367. }
  368. if (SD_ChkCardWP() == 1)
  369. {
  370. SD_EndSD();
  371. return SD_ERR_WRITE_PROTECT; /* 卡有写保护 */
  372. }
  373. tmp = blocknum - sds.erase_unit;
  374. while(tmp >= 0)  /* 每次擦除扇区 once erase is sector size */
  375. {
  376. ret = SD_EraseStartBlock(startaddr); /* 选择起始块地址 select start address */
  377. if (ret != SD_NO_ERR)
  378. {
  379. SD_EndSD();
  380. return ret;
  381. }
  382. ret = SD_EraseEndBlock(startaddr + sds.erase_unit - 1); /* 选择终止块地址 select end address */
  383. if (ret != SD_NO_ERR)
  384. {
  385. SD_EndSD();
  386. return ret;
  387. }
  388. ret = SD_EraseSelectedBlock(); /* 擦除所选的块 erase blocks selected */
  389. if (ret != SD_NO_ERR)
  390. {
  391. SD_EndSD();
  392. return ret;
  393. }
  394. startaddr += sds.erase_unit; /* 起始地址递增 */
  395. blocknum  -= sds.erase_unit;
  396. tmp = blocknum - sds.erase_unit;
  397. };
  398. if (blocknum > 0) /* 擦除不够once_erase块 */
  399. { /* erase blocks that numbers is not enough once_erase */
  400. ret = SD_EraseStartBlock(startaddr);
  401. if (ret != SD_NO_ERR)
  402. {
  403. SD_EndSD();
  404. return ret;
  405. }
  406. ret = SD_EraseEndBlock(startaddr + blocknum - 1);
  407. if (ret != SD_NO_ERR)
  408. {
  409. SD_EndSD();
  410. return ret;
  411. }
  412. ret = SD_EraseSelectedBlock();
  413. if (ret != SD_NO_ERR)
  414. {
  415. SD_EndSD();
  416. return ret;
  417. }
  418. }
  419. SD_EndSD();
  420. return SD_NO_ERR; /* 返回擦除成功 return erase sucessfully */
  421. }
  422. #endif
  423. /*****************************************************************
  424.      下面为子程序
  425.  
  426. *****************************************************************/
  427. /*******************************************************************************************************************
  428. ** 函数名称: INT8U SD_GetCardInfo() Name:   INT8U SD_GetCardInfo()
  429. ** 功能描述: 获得SD/MMC卡的信息 Function: get the information of SD/MMC card
  430. ** 输   入: INT8U cardtype: 卡类型 Input:    INT8U cardtype: card type
  431. ** 输    出: 0:   成功    >0:  错误码 Output:   0:  right >0:  error code
  432. *******************************************************************************************************************/
  433. INT8U SD_GetCardInfo()
  434. {
  435. INT32U tmp;
  436. INT8U csdbuf[16],ret;
  437. ret = SD_ReadCSD(16, csdbuf);        /* 读CSD寄存器    read CSD register */
  438. if (ret != SD_NO_ERR)
  439. return ret;
  440. SD_CalTimeout(csdbuf); /* 计算超时时间值 calculate timeout value */
  441. /* 计算块的最大长度  */ /* calculate the size of a sector */
  442. sds.block_len = 1 << (csdbuf[READ_BL_LEN_POS] & READ_BL_LEN_MSK);   /* (2 ^ READ_BL_LEN) */
  443. /* 计算卡中块的个数 */ /* calculate the sector numbers of the SD Card */
  444. sds.block_num = ((csdbuf[C_SIZE_POS1] & C_SIZE_MSK1) << 10) +
  445.         (csdbuf[C_SIZE_POS2] << 2) +
  446.     ((csdbuf[C_SIZE_POS3] & C_SIZE_MSK3) >> 6) + 1; /* (C_SIZE + 1)*/
  447.     
  448. tmp = ((csdbuf[C_SIZE_MULT_POS1] & C_SIZE_MULT_MSK1) << 1) +   
  449.       ((csdbuf[C_SIZE_MULT_POS2] & C_SIZE_MULT_MSK2) >> 7) + 2; /* (C_SIZE_MULT + 2) */
  450.     
  451.     /* 获得卡中块的数量 */ /* get the block numbers in card */
  452. sds.block_num = sds.block_num * (1 << tmp); /* (C_SIZE + 1) * 2 ^ (C_SIZE_MULT + 2) */
  453. /* 计算擦除的单位(单位: 块) */
  454. if (sds.card_type == CARDTYPE_MMC)
  455. {     
  456. tmp  = ((csdbuf[ERASE_GRP_SIZE_POS] & ERASE_GRP_SIZE_MSK) >> 2) + 1;   /* (ERASE_GRP_SIZE + 1)  */ 
  457. /* (ERASE_GRP_SIZE + 1) * (ERASE_GRP_MULTI + 1) */
  458. tmp *= ((csdbuf[ERASE_GRP_MULTI_POS1] & ERASE_GRP_MULTI_MSK1) << 3) +
  459.        ((csdbuf[ERASE_GRP_MULTI_POS2] & ERASE_GRP_MULTI_MSK2) >> 5) + 1;
  460. }
  461. else /*calculate the size of sector */
  462. tmp = ((csdbuf[SECTOR_SIZE_POS1] & SECTOR_SIZE_MSK1) << 1) +  
  463.           ((csdbuf[SECTOR_SIZE_POS2] & SECTOR_SIZE_MSK2) >> 7) + 1; /* SD: SECTOR_SIZE */
  464. sds.erase_unit = tmp;      /* 擦除单位(块) */ 
  465. return SD_NO_ERR; /* 返回执行成功 return perform sucessfully */
  466. }
  467. /*******************************************************************************************************************
  468. ** 函数名称: INT8U SD_CalTimeout() Name:   INT8U SD_CalTimeout()
  469. ** 功能描述: 计算读/写/擦超时时间 Function: calculate timeout of reading,writing,erasing
  470. ** 输   入: INT8U *csdbuf : CSD寄存器内容 Input:    INT8U *csdbuf : CSD register content
  471. ** 输    出: 0:   成功    >0:  错误码 Output:   0:  right >0:  error code
  472. *******************************************************************************************************************/
  473. INT8U SD_CalTimeout(INT8U *csdbuf)
  474. {
  475. INT32U tmp;
  476. INT8U time_u,time_v,fator;
  477. sds.timeout_read = READ_TIMEOUT_100MS; /* 默认读超时为100ms */
  478. sds.timeout_write = WRITE_TIMEOUT_250MS; /* 默认写超时为250ms */
  479. sds.timeout_erase = WRITE_TIMEOUT_250MS;
  480. time_u = (csdbuf[TAAC_POS] & TAAC_MSK); /* 读超时时间单位 read timeout unit */
  481. time_v = (csdbuf[TAAC_POS] & NSAC_MSK) >> 3; /* 读超时时间值   read timeout value */
  482. fator = (csdbuf[R2WFACTOR_POS] & R2WFACTOR_MSK) >> 2; /* 读超时时间因数 read timeout factor */
  483. if(time_v == 0) return SD_ERR_CARD_PARAM; /* 卡参数有错误 card parameter is error */
  484. tmp = SPI_CLOCK * time_value[time_v] / 10 / time_unit[time_u]; /* TACC * f (单位 unit: clock) */
  485. tmp = tmp + csdbuf[NSAC_POS] * 100; /* TACC * f + NSAC * 100 (单位 unit: clock) */
  486. /* 计算得到的超时值 the timeout value of being calculated */
  487. sds.timeout_read = tmp;
  488. sds.timeout_write = tmp * r2w_fator[fator]; /* (TACC * f + NSAC * 100) * R2WFACTOR (单位 unit:clock)*/
  489. if (sds.card_type == CARDTYPE_SD)
  490. {
  491. sds.timeout_read  = sds.timeout_read * 100 / 8; /* 实际值为计算值的100倍 */
  492. sds.timeout_write = sds.timeout_write * 100 / 8;
  493. if (sds.timeout_read > READ_TIMEOUT_100MS) /* 取计算值与默认值中的最小值 */
  494. sds.timeout_read = READ_TIMEOUT_100MS;
  495. if (sds.timeout_write > WRITE_TIMEOUT_250MS)
  496. sds.timeout_write = WRITE_TIMEOUT_250MS;
  497. }
  498. else
  499. {
  500. sds.timeout_read  = sds.timeout_read * 10 / 8; /* 实际值为计算值的10倍 */
  501. sds.timeout_write = sds.timeout_write * 10 / 8;
  502. }
  503. sds.timeout_erase = sds.timeout_write;
  504. #if SD_UCOSII_EN
  505. sds.timeout_read = (sds.timeout_read << 3) * OS_TICKS_PER_SEC / SPI_CLOCK; 
  506. sds.timeout_write =(sds.timeout_write << 3) * OS_TICKS_PER_SEC / SPI_CLOCK;
  507. sds.timeout_erase = sds.timeout_write; /* (单位 unit: os tick) */
  508. #endif
  509. return SD_NO_ERR;
  510. }
  511. /*******************************************************************************************************************
  512. ** 函数名称: INT8U SD_ActiveInit() Name:   INT8U SD_ActiveInit()
  513. ** 功能描述: 激活卡,并获得卡型 Function: active card, and get the card type 
  514. ** 输   入: 无   Input:    NULL
  515. ** 输    出: 0:   成功    >0:  错误码 Output:   0:  right >0:  error code
  516. ** 函数说明: 该命令不断重复发送到SD卡,直到响应R1的Bit0(Idle)位为0,表示SD卡内部初始化处理完成。
  517.      当响应的Idle位为0时,SD卡就完全进入SPI模式了。当然重复发送命令CMD1是有次数限制的,
  518.      最大次数为宏定义SD_IDLE_WAIT_MAX.
  519. *******************************************************************************************************************/
  520. INT8U SD_ActiveInit(void)
  521. {
  522. INT8U param[4] = {0,0,0,0},resp[5],ret;
  523. INT32U i = 0;
  524.   do 
  525.     { /* 发出CMD1, 查询卡的状态, send CMD1 to poll card status */
  526.         ret = SD_SendCmd(CMD1, param, CMD1_R, resp);
  527.         if (ret != SD_NO_ERR)
  528.         return ret;
  529.         i ++;
  530.     }while (((resp[0] & MSK_IDLE) == MSK_IDLE) && (i <= SD_IDLE_WAIT_MAX));
  531.      /* 如果响应R1的最低位Idle位为1,则继续循环 */
  532.      /* if response R1 Idle bit is 1,continue recycle */    
  533.     if (i >= SD_IDLE_WAIT_MAX)
  534.         return SD_ERR_TIMEOUT_WAITIDLE; /* 超时,返回错误 time out,return error */
  535.     ret = SD_SendCmd(CMD55, param, CMD55_R, resp);
  536.     if (ret != SD_NO_ERR)
  537.         return ret;
  538.        
  539.     ret = SD_SendCmd(ACMD41, param, ACMD41_R, resp); /* 激活内部初始化命令 active card to initialize process internal */
  540.     if (ret != SD_NO_ERR)
  541.      return SD_ERR_UNKNOWN_CARD;
  542.     
  543.     if ((resp[0] & 0xFE) == 0)
  544.        sds.card_type = CARDTYPE_SD; /* 是SD卡 the card is SD card */
  545.     else
  546.      sds.card_type = CARDTYPE_MMC; /* 是MMC卡 the card is MMC card */
  547. return SD_NO_ERR;
  548. }
  549. /*******************************************************************************************************************
  550. ** 函数名称: void SD_StartSD() Name:   INT8U SD_StartSD()
  551. ** 功能描述: 向操作系统申请访问SD卡的权限 Function: request the right of operating sd to OS
  552. ** 输   入: 无 Input:   NULL
  553. ** 返  回: 无 return:   NULL
  554. ********************************************************************************************************************/
  555. void SD_StartSD(void)
  556. {
  557. #if SD_UCOSII_EN
  558. INT8U ret;
  559. OSSemPend(pSemSD, 0, &ret); /* 等待访问卡信号量可用 wait for semaphore that accessed Card */
  560. #endif
  561. }
  562. /*******************************************************************************************************************
  563. ** 函数名称: void SD_EndSD() Name:   INT8U SD_EndSD()
  564. ** 功能描述: 访问SD卡的权限归还操作系统 Function: return the right of operating sd to OS
  565. ** 输   入: 无 Input:   NULL
  566. ** 返  回: 无 return:   NULL
  567. ********************************************************************************************************************/
  568. void SD_EndSD(void)
  569. {
  570. #if SD_UCOSII_EN
  571. OSSemPost(pSemSD); /* 将访问卡信号量还给操作系统 return the semaphore accessing Card to OS */
  572. #endif
  573. }
  574. /*******************************************************************************************************************
  575. ** 函数名称: INT16U SD_GetZLGSDVer() Name:   INT16U SD_GetZLGSDVer()
  576. ** 功能描述: 得到ZLG/SD的版本号 Function: get the version of ZLG/SD
  577. ** 输   入: 无 Input:    NULL
  578. ** 输   出: 版本号 Output:   Version
  579. ** 版本记录:
  580.  V1.0   支持访问SD 卡,只能在前后台系统运行
  581.  
  582.  V2.0   支持访问SD和MMC卡,可运行于前后系统或UCOS-II
  583. *******************************************************************************************************************/
  584. INT16U SD_GetZLGSDVer(void)
  585. {
  586. return 0x0200; /* 版本号为 2.00 */
  587. }