dev_sdhc_spi.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729
  1. #include "user.h"
  2. #define CMD0 (0) /* GO_IDLE_STATE */
  3. #define CMD1 (1) /* SEND_OP_COND */
  4. #define CMD2 (2)
  5. #define ACMD41 (0x80+41) /* SEND_OP_COND (SDC) */
  6. #define CMD8 (8) /* SEND_IF_COND */
  7. #define CMD9 (9) /* SEND_CSD */
  8. #define CMD10 (10) /* SEND_CID */
  9. #define CMD12 (12) /* STOP_TRANSMISSION */
  10. #define CMD13 (13) /* SEND_STATUS */
  11. #define ACMD13 (0x80+13) /* SD_STATUS (SDC) */
  12. #define CMD16 (16) /* SET_BLOCKLEN */
  13. #define CMD17 (17) /* READ_SINGLE_BLOCK */
  14. #define CMD18 (18) /* READ_MULTIPLE_BLOCK */
  15. #define CMD23 (23) /* SET_BLOCK_COUNT */
  16. #define ACMD23 (0x80+23) /* SET_WR_BLK_ERASE_COUNT (SDC) */
  17. #define CMD24 (24) /* WRITE_BLOCK */
  18. #define CMD25 (25) /* WRITE_MULTIPLE_BLOCK */
  19. #define CMD32 (32) /* ERASE_ER_BLK_START */
  20. #define CMD33 (33) /* ERASE_ER_BLK_END */
  21. #define CMD38 (38) /* ERASE */
  22. #define CMD55 (55) /* APP_CMD */
  23. #define CMD58 (58) /* READ_OCR */
  24. #define SD_CMD_GO_IDLE_STATE 0 /* CMD0 = 0x40 */
  25. #define SD_CMD_SEND_OP_COND 1 /* CMD1 = 0x41 */
  26. #define SD_CMD_SEND_IF_COND 8 /* CMD8 = 0x48 */
  27. #define SD_CMD_SEND_CSD 9 /* CMD9 = 0x49 */
  28. #define SD_CMD_SEND_CID 10 /* CMD10 = 0x4A */
  29. #define SD_CMD_STOP_TRANSMISSION 12 /* CMD12 = 0x4C */
  30. #define SD_CMD_SEND_STATUS 13 /* CMD13 = 0x4D */
  31. #define SD_CMD_SET_BLOCKLEN 16 /* CMD16 = 0x50 */
  32. #define SD_CMD_READ_SINGLE_BLOCK 17 /* CMD17 = 0x51 */
  33. #define SD_CMD_READ_MULT_BLOCK 18 /* CMD18 = 0x52 */
  34. #define SD_CMD_SET_BLOCK_COUNT 23 /* CMD23 = 0x57 */
  35. #define SD_CMD_WRITE_SINGLE_BLOCK 24 /* CMD24 = 0x58 */
  36. #define SD_CMD_WRITE_MULT_BLOCK 25 /* CMD25 = 0x59 */
  37. #define SD_CMD_PROG_CSD 27 /* CMD27 = 0x5B */
  38. #define SD_CMD_SET_WRITE_PROT 28 /* CMD28 = 0x5C */
  39. #define SD_CMD_CLR_WRITE_PROT 29 /* CMD29 = 0x5D */
  40. #define SD_CMD_SEND_WRITE_PROT 30 /* CMD30 = 0x5E */
  41. #define SD_CMD_SD_ERASE_GRP_START 32 /* CMD32 = 0x60 */
  42. #define SD_CMD_SD_ERASE_GRP_END 33 /* CMD33 = 0x61 */
  43. #define SD_CMD_UNTAG_SECTOR 34 /* CMD34 = 0x62 */
  44. #define SD_CMD_ERASE_GRP_START 35 /* CMD35 = 0x63 */
  45. #define SD_CMD_ERASE_GRP_END 36 /* CMD36 = 0x64 */
  46. #define SD_CMD_UNTAG_ERASE_GROUP 37 /* CMD37 = 0x65 */
  47. #define SD_CMD_ERASE 38 /* CMD38 = 0x66 */
  48. #define SD_CMD_SD_APP_OP_COND 41 /* CMD41 = 0x69 */
  49. #define SD_CMD_APP_CMD 55 /* CMD55 = 0x77 */
  50. #define SD_CMD_READ_OCR 58 /* CMD55 = 0x79 */
  51. #define SD_DEFAULT_BLOCK_SIZE (512)
  52. #define SD_DBG DBG_INFO
  53. enum
  54. {
  55. DEV_SDCARD_SPI_DONE = SERVICE_EVENT_ID_START + 1,
  56. SDCARD_STATE_IDLE = 0,
  57. SDCARD_STATE_RUN,
  58. SDCARD_STATE_READ,
  59. SDCARD_STATE_WRITE,
  60. };
  61. static void SDHC_SpiCS(SDHC_SPICtrlStruct *Ctrl, uint8_t OnOff)
  62. {
  63. uint8_t Temp[1] = {0xff};
  64. GPIO_Output(Ctrl->CSPin, !OnOff);
  65. if (!OnOff)
  66. {
  67. SPI_BlockTransfer(Ctrl->SpiID, Temp, Temp, 1);
  68. }
  69. }
  70. static int32_t SPIFlash_SpiIrqCB(void *pData, void *pParam)
  71. {
  72. SDHC_SPICtrlStruct *Ctrl = (SDHC_SPICtrlStruct *)pParam;
  73. #ifdef __BUILD_OS__
  74. if (Ctrl->NotifyTask)
  75. {
  76. Task_SendEvent(Ctrl->NotifyTask, DEV_SDHC_SPI_DONE, 0, 0, 0);
  77. }
  78. #endif
  79. return 0;
  80. }
  81. static uint8_t CRC7(uint8_t * chr, int cnt)
  82. {
  83. int i,a;
  84. uint8_t crc,Data;
  85. crc=0;
  86. for (a=0;a<cnt;a++)
  87. {
  88. Data=chr[a];
  89. for (i=0;i<8;i++)
  90. {
  91. crc <<= 1;
  92. if ((Data & 0x80)^(crc & 0x80))
  93. crc ^=0x09;
  94. Data <<= 1;
  95. }
  96. }
  97. crc=(crc<<1)|1;
  98. return(crc);
  99. }
  100. static void SDHC_SpiXfer(SDHC_SPICtrlStruct *Ctrl, uint8_t *Buf, uint16_t TxLen)
  101. {
  102. #ifdef __BUILD_OS__
  103. Task_EventStruct Event;
  104. #endif
  105. #ifdef __BUILD_OS__
  106. if (Ctrl->NotifyTask && Ctrl->TaskCB)
  107. {
  108. Ctrl->SPIError = 0;
  109. SPI_SetCallbackFun(Ctrl->SpiID, SPIFlash_SpiIrqCB, Ctrl);
  110. SPI_Transfer(Ctrl->SpiID, Buf, Buf, TxLen, Ctrl->IsSpiDMAMode);
  111. if (Task_GetEvent(Ctrl->NotifyTask, DEV_SDHC_SPI_DONE, &Event, Ctrl->TaskCB, TxLen * CORE_TICK_1US + CORE_TICK_1MS))
  112. {
  113. Ctrl->SPIError = 1;
  114. SPI_TransferStop(Ctrl->SpiID);
  115. }
  116. SPI_SetCallbackFun(Ctrl->SpiID, NULL, NULL);
  117. }
  118. else
  119. #endif
  120. {
  121. SPI_BlockTransfer(Ctrl->SpiID, Buf, Buf, TxLen);
  122. }
  123. }
  124. static int32_t SDHC_SpiCmd(SDHC_SPICtrlStruct *Ctrl, uint8_t Cmd, uint32_t Arg, uint8_t NeedStop)
  125. {
  126. uint64_t OpEndTick;
  127. uint8_t i, TxLen, DummyLen;
  128. int32_t Result = -ERROR_OPERATION_FAILED;
  129. SDHC_SpiCS(Ctrl, 1);
  130. Ctrl->TempData[0] = 0x40|Cmd;
  131. BytesPutBe32(Ctrl->TempData + 1, Arg);
  132. Ctrl->TempData[5] = CRC7(Ctrl->TempData, 5);
  133. memset(Ctrl->TempData + 6, 0xff, 8);
  134. TxLen = 14;
  135. if (Ctrl->IsPrintData)
  136. {
  137. DBG_HexPrintf(Ctrl->TempData, TxLen);
  138. }
  139. Ctrl->SPIError = 0;
  140. Ctrl->SDHCError = 0;
  141. SDHC_SpiXfer(Ctrl, Ctrl->TempData, TxLen);
  142. if (Ctrl->IsPrintData)
  143. {
  144. DBG_HexPrintf(Ctrl->TempData, TxLen);
  145. }
  146. for(i = 7; i < TxLen; i++)
  147. {
  148. if (Ctrl->TempData[i] != 0xff)
  149. {
  150. Ctrl->SDHCState = Ctrl->TempData[i];
  151. if ((Ctrl->SDHCState == !Ctrl->IsInitDone) || !Ctrl->SDHCState)
  152. {
  153. Result = ERROR_NONE;
  154. }
  155. DummyLen = TxLen - i - 1;
  156. memcpy(Ctrl->ExternResult, &Ctrl->TempData[i + 1], DummyLen);
  157. Ctrl->ExternLen = DummyLen;
  158. break;
  159. }
  160. }
  161. if (NeedStop)
  162. {
  163. SDHC_SpiCS(Ctrl, 0);
  164. }
  165. return Result;
  166. }
  167. static int32_t SDHC_SpiReadRegData(SDHC_SPICtrlStruct *Ctrl, uint8_t *RegDataBuf, uint8_t DataLen)
  168. {
  169. uint64_t OpEndTick;
  170. int Result = ERROR_NONE;
  171. uint16_t DummyLen;
  172. uint16_t i,findResult;
  173. Ctrl->SPIError = 0;
  174. Ctrl->SDHCError = 0;
  175. OpEndTick = GetSysTick() + Ctrl->SDHCReadBlockTo;
  176. findResult = 0;
  177. for(i = 0; i < Ctrl->ExternLen; i++)
  178. {
  179. if (0xfe == Ctrl->ExternResult[i])
  180. {
  181. DummyLen = Ctrl->ExternLen - i - 1;
  182. if (Ctrl->IsPrintData)
  183. {
  184. DBG_HexPrintf(&Ctrl->ExternResult[i], DummyLen + 1);
  185. }
  186. memcpy(RegDataBuf, &Ctrl->ExternResult[i + 1], DummyLen);
  187. memset(RegDataBuf + DummyLen, 0xff, DataLen - DummyLen);
  188. SDHC_SpiXfer(Ctrl, RegDataBuf + DummyLen, DataLen - DummyLen);
  189. if (Ctrl->IsPrintData)
  190. {
  191. DBG_HexPrintf(RegDataBuf + DummyLen, DataLen - DummyLen);
  192. }
  193. goto SDHC_SPIREADREGDATA_DONE;
  194. }
  195. }
  196. while((GetSysTick() < OpEndTick) && !Ctrl->SDHCError)
  197. {
  198. memset(Ctrl->TempData, 0xff, 40);
  199. SDHC_SpiXfer(Ctrl, Ctrl->TempData, 40);
  200. if (Ctrl->IsPrintData)
  201. {
  202. DBG_HexPrintf(Ctrl->TempData, 40);
  203. }
  204. for(i = 0; i < 40; i++)
  205. {
  206. if (0xfe == Ctrl->TempData[i])
  207. {
  208. DummyLen = 40 - i - 1;
  209. if (DummyLen >= DataLen)
  210. {
  211. memcpy(RegDataBuf, &Ctrl->TempData[i + 1], DataLen);
  212. goto SDHC_SPIREADREGDATA_DONE;
  213. }
  214. else
  215. {
  216. memcpy(RegDataBuf, &Ctrl->TempData[i + 1], DummyLen);
  217. memset(RegDataBuf + DummyLen, 0xff, DataLen - DummyLen);
  218. SDHC_SpiXfer(Ctrl, RegDataBuf + DummyLen, DataLen - DummyLen);
  219. goto SDHC_SPIREADREGDATA_DONE;
  220. }
  221. }
  222. }
  223. }
  224. Result = -ERROR_OPERATION_FAILED;
  225. SDHC_SPIREADREGDATA_DONE:
  226. SDHC_SpiCS(Ctrl, 0);
  227. return Result;
  228. }
  229. static int32_t SDHC_SpiWriteBlockData(SDHC_SPICtrlStruct *Ctrl)
  230. {
  231. uint64_t OpEndTick;
  232. int Result = -ERROR_OPERATION_FAILED;
  233. uint16_t TxLen, DoneFlag, waitCnt;
  234. uint16_t i, crc16;
  235. uint8_t *pBuf;
  236. Ctrl->SPIError = 0;
  237. Ctrl->SDHCError = 0;
  238. OpEndTick = GetSysTick() + Ctrl->SDHCWriteBlockTo * CORE_TICK_1MS;
  239. while( (Ctrl->DataBuf.Pos < Ctrl->DataBuf.MaxLen) && (GetSysTick() < OpEndTick) )
  240. {
  241. Ctrl->TempData[0] = 0xff;
  242. Ctrl->TempData[1] = 0xff;
  243. //SD_DBG("%u,%u", Ctrl->DataBuf.Pos, Ctrl->DataBuf.MaxLen);
  244. Ctrl->TempData[2] = 0xfc;
  245. memcpy(Ctrl->TempData + 3, Ctrl->DataBuf.Data + Ctrl->DataBuf.Pos * __SDHC_BLOCK_LEN__, __SDHC_BLOCK_LEN__);
  246. crc16 = CRC16Cal(Ctrl->DataBuf.Data + Ctrl->DataBuf.Pos * __SDHC_BLOCK_LEN__, __SDHC_BLOCK_LEN__, 0, CRC16_CCITT_GEN, 0);
  247. BytesPutBe16(Ctrl->TempData + 3 + __SDHC_BLOCK_LEN__, crc16);
  248. Ctrl->TempData[5 + __SDHC_BLOCK_LEN__] = 0xff;
  249. TxLen = 6 + __SDHC_BLOCK_LEN__;
  250. SDHC_SpiXfer(Ctrl, Ctrl->TempData, TxLen);
  251. if ((Ctrl->TempData[5 + __SDHC_BLOCK_LEN__] & 0x1f) != 0x05)
  252. {
  253. DBG("write data error ! x%02x", Ctrl->TempData[5 + __SDHC_BLOCK_LEN__]);
  254. Ctrl->SDHCError = 1;
  255. goto SDHC_SPIWRITEBLOCKDATA_DONE;
  256. }
  257. DoneFlag = 0;
  258. waitCnt = 0;
  259. while( (GetSysTick() < OpEndTick) && !DoneFlag )
  260. {
  261. TxLen = Ctrl->WriteWaitCnt?Ctrl->WriteWaitCnt:40;
  262. memset(Ctrl->TempData, 0xff, TxLen);
  263. SDHC_SpiXfer(Ctrl, Ctrl->TempData, TxLen);
  264. for(i = 0; i < TxLen; i++)
  265. {
  266. if (Ctrl->TempData[i] == 0xff)
  267. {
  268. DoneFlag = 1;
  269. if ((i + waitCnt) < sizeof(Ctrl->TempData))
  270. {
  271. if ((i + waitCnt) != Ctrl->WriteWaitCnt)
  272. {
  273. // DBG("%u", Ctrl->WriteWaitCnt);
  274. Ctrl->WriteWaitCnt = i + waitCnt;
  275. }
  276. }
  277. break;
  278. }
  279. }
  280. waitCnt += TxLen;
  281. }
  282. if (!DoneFlag)
  283. {
  284. DBG("write data timeout!");
  285. Ctrl->SDHCError = 1;
  286. goto SDHC_SPIWRITEBLOCKDATA_DONE;
  287. }
  288. Ctrl->DataBuf.Pos++;
  289. OpEndTick = GetSysTick() + Ctrl->SDHCWriteBlockTo * CORE_TICK_1MS;
  290. }
  291. Result = ERROR_NONE;
  292. SDHC_SPIWRITEBLOCKDATA_DONE:
  293. Ctrl->TempData[0] = 0xfd;
  294. SPI_BlockTransfer(Ctrl->SpiID, Ctrl->TempData, Ctrl->TempData, 1);
  295. OpEndTick = GetSysTick() + Ctrl->SDHCWriteBlockTo * CORE_TICK_1MS * Ctrl->DataBuf.MaxLen;
  296. DoneFlag = 0;
  297. while( (GetSysTick() < OpEndTick) && !DoneFlag )
  298. {
  299. TxLen = sizeof(Ctrl->TempData);
  300. memset(Ctrl->TempData, 0xff, TxLen);
  301. SDHC_SpiXfer(Ctrl, Ctrl->TempData, TxLen);
  302. for(i = 0; i < TxLen; i++)
  303. {
  304. if (Ctrl->TempData[i] == 0xff)
  305. {
  306. DoneFlag = 1;
  307. break;
  308. }
  309. }
  310. }
  311. SDHC_SpiCS(Ctrl, 0);
  312. return Result;
  313. }
  314. static int32_t SDHC_SpiReadBlockData(SDHC_SPICtrlStruct *Ctrl)
  315. {
  316. uint64_t OpEndTick;
  317. int Result = -ERROR_OPERATION_FAILED;
  318. uint16_t ReadLen, DummyLen, RemainingLen;
  319. uint16_t i, crc16, crc16_check;
  320. uint8_t *pBuf;
  321. Ctrl->SPIError = 0;
  322. Ctrl->SDHCError = 0;
  323. OpEndTick = GetSysTick() + Ctrl->SDHCReadBlockTo * CORE_TICK_1MS;
  324. while( (Ctrl->DataBuf.Pos < Ctrl->DataBuf.MaxLen) && (GetSysTick() < OpEndTick) )
  325. {
  326. DummyLen = (__SDHC_BLOCK_LEN__ >> 1);
  327. memset(Ctrl->TempData, 0xff, DummyLen);
  328. // SD_DBG("%u,%u", Ctrl->DataBuf.Pos, Ctrl->DataBuf.MaxLen);
  329. SDHC_SpiXfer(Ctrl, Ctrl->TempData, DummyLen);
  330. RemainingLen = 0;
  331. for(i = 0; i < DummyLen; i++)
  332. {
  333. if (Ctrl->TempData[i] == 0xfe)
  334. {
  335. ReadLen = (DummyLen - i - 1);
  336. RemainingLen = __SDHC_BLOCK_LEN__ - ReadLen;
  337. if (ReadLen)
  338. {
  339. memcpy(Ctrl->DataBuf.Data + Ctrl->DataBuf.Pos * __SDHC_BLOCK_LEN__, Ctrl->TempData + i + 1, ReadLen);
  340. }
  341. // SD_DBG("%u,%u", ReadLen, RemainingLen);
  342. goto READ_REST_DATA;
  343. }
  344. }
  345. continue;
  346. READ_REST_DATA:
  347. pBuf = Ctrl->DataBuf.Data + Ctrl->DataBuf.Pos * __SDHC_BLOCK_LEN__ + ReadLen;
  348. memset(pBuf, 0xff, RemainingLen);
  349. SDHC_SpiXfer(Ctrl, pBuf, RemainingLen);
  350. memset(Ctrl->TempData, 0xff, 2);
  351. SPI_BlockTransfer(Ctrl->SpiID, Ctrl->TempData, Ctrl->TempData, 2);
  352. crc16 = CRC16Cal(Ctrl->DataBuf.Data + Ctrl->DataBuf.Pos * __SDHC_BLOCK_LEN__, __SDHC_BLOCK_LEN__, 0, CRC16_CCITT_GEN, 0);
  353. crc16_check = BytesGetBe16(Ctrl->TempData);
  354. if (crc16 != crc16_check)
  355. {
  356. DBG("crc16 error %04x %04x", crc16, crc16_check);
  357. Result = ERROR_NONE;
  358. goto SDHC_SPIREADBLOCKDATA_DONE;
  359. }
  360. Ctrl->DataBuf.Pos++;
  361. OpEndTick = GetSysTick() + Ctrl->SDHCReadBlockTo * CORE_TICK_1MS;
  362. }
  363. Result = ERROR_NONE;
  364. SDHC_SPIREADBLOCKDATA_DONE:
  365. return Result;
  366. }
  367. void SDHC_SpiInitCard(void *pSDHC)
  368. {
  369. uint8_t i;
  370. uint64_t OpEndTick;
  371. SDHC_SPICtrlStruct *Ctrl = (SDHC_SPICtrlStruct *)pSDHC;
  372. memset(Ctrl->TempData, 0xff, 20);
  373. Ctrl->IsInitDone = 0;
  374. Ctrl->SDHCState = 0xff;
  375. Ctrl->Info.CardCapacity = 0;
  376. Ctrl->WriteWaitCnt = 40;
  377. GPIO_Output(Ctrl->CSPin, 0);
  378. SDHC_SpiXfer(Ctrl, Ctrl->TempData, 20);
  379. GPIO_Output(Ctrl->CSPin, 1);
  380. memset(Ctrl->TempData, 0xff, 20);
  381. SDHC_SpiXfer(Ctrl, Ctrl->TempData, 20);
  382. Ctrl->IsMMC = 0;
  383. if (SDHC_SpiCmd(Ctrl, CMD0, 0, 1))
  384. {
  385. goto INIT_DONE;
  386. }
  387. OpEndTick = GetSysTick() + 1 * CORE_TICK_1S;
  388. if (SDHC_SpiCmd(Ctrl, CMD8, 0x1aa, 1)) //只支持2G以上的SDHC卡
  389. {
  390. goto INIT_DONE;
  391. }
  392. WAIT_INIT_DONE:
  393. if (GetSysTick() >= OpEndTick)
  394. {
  395. goto INIT_DONE;
  396. }
  397. if (SDHC_SpiCmd(Ctrl, SD_CMD_APP_CMD, 0, 1))
  398. {
  399. goto INIT_DONE;
  400. }
  401. if (SDHC_SpiCmd(Ctrl, SD_CMD_SD_APP_OP_COND, 0x40000000, 1))
  402. {
  403. goto INIT_DONE;
  404. }
  405. Ctrl->IsInitDone = !Ctrl->SDHCState;
  406. if (!Ctrl->IsInitDone)
  407. {
  408. goto WAIT_INIT_DONE;
  409. }
  410. if (SDHC_SpiCmd(Ctrl, CMD58, 0, 1))
  411. {
  412. goto INIT_DONE;
  413. }
  414. Ctrl->OCR = BytesGetBe32(Ctrl->ExternResult);
  415. // SD_DBG("sdcard init OK OCR:0x%08x!", Ctrl->OCR);
  416. return;
  417. INIT_DONE:
  418. if (!Ctrl->IsInitDone)
  419. {
  420. SD_DBG("sdcard init fail!");
  421. }
  422. return;
  423. }
  424. void SDHC_SpiReadCardConfig(void *pSDHC)
  425. {
  426. SDHC_SPICtrlStruct *Ctrl = (SDHC_SPICtrlStruct *)pSDHC;
  427. uint8_t CSD_Tab[18];
  428. uint8_t CID_Tab[18];
  429. SD_CSD* Csd = &Ctrl->Info.Csd;
  430. SD_CID* Cid = &Ctrl->Info.Cid;
  431. SD_CardInfo *pCardInfo = &Ctrl->Info;
  432. uint64_t Temp;
  433. uint8_t flag_SDHC = (Ctrl->OCR & 0x40000000) >> 30;
  434. if (Ctrl->Info.CardCapacity) return;
  435. if (SDHC_SpiCmd(Ctrl, CMD9, 0, 0))
  436. {
  437. goto READ_CONFIG_ERROR;
  438. }
  439. if (Ctrl->SDHCState)
  440. {
  441. goto READ_CONFIG_ERROR;
  442. }
  443. if (SDHC_SpiReadRegData(Ctrl, CSD_Tab, 18))
  444. {
  445. goto READ_CONFIG_ERROR;
  446. }
  447. /*************************************************************************
  448. CSD header decoding
  449. *************************************************************************/
  450. /* Byte 0 */
  451. Csd->CSDStruct = (CSD_Tab[0] & 0xC0) >> 6;
  452. Csd->Reserved1 = CSD_Tab[0] & 0x3F;
  453. /* Byte 1 */
  454. Csd->TAAC = CSD_Tab[1];
  455. /* Byte 2 */
  456. Csd->NSAC = CSD_Tab[2];
  457. /* Byte 3 */
  458. Csd->MaxBusClkFrec = CSD_Tab[3];
  459. /* Byte 4/5 */
  460. Csd->CardComdClasses = (CSD_Tab[4] << 4) | ((CSD_Tab[5] & 0xF0) >> 4);
  461. Csd->RdBlockLen = CSD_Tab[5] & 0x0F;
  462. /* Byte 6 */
  463. Csd->PartBlockRead = (CSD_Tab[6] & 0x80) >> 7;
  464. Csd->WrBlockMisalign = (CSD_Tab[6] & 0x40) >> 6;
  465. Csd->RdBlockMisalign = (CSD_Tab[6] & 0x20) >> 5;
  466. Csd->DSRImpl = (CSD_Tab[6] & 0x10) >> 4;
  467. /*************************************************************************
  468. CSD v1/v2 decoding
  469. *************************************************************************/
  470. if(!flag_SDHC)
  471. {
  472. Csd->version.v1.Reserved1 = ((CSD_Tab[6] & 0x0C) >> 2);
  473. Csd->version.v1.DeviceSize = ((CSD_Tab[6] & 0x03) << 10)
  474. | (CSD_Tab[7] << 2)
  475. | ((CSD_Tab[8] & 0xC0) >> 6);
  476. Csd->version.v1.MaxRdCurrentVDDMin = (CSD_Tab[8] & 0x38) >> 3;
  477. Csd->version.v1.MaxRdCurrentVDDMax = (CSD_Tab[8] & 0x07);
  478. Csd->version.v1.MaxWrCurrentVDDMin = (CSD_Tab[9] & 0xE0) >> 5;
  479. Csd->version.v1.MaxWrCurrentVDDMax = (CSD_Tab[9] & 0x1C) >> 2;
  480. Csd->version.v1.DeviceSizeMul = ((CSD_Tab[9] & 0x03) << 1)
  481. |((CSD_Tab[10] & 0x80) >> 7);
  482. }
  483. else
  484. {
  485. Csd->version.v2.Reserved1 = ((CSD_Tab[6] & 0x0F) << 2) | ((CSD_Tab[7] & 0xC0) >> 6);
  486. Csd->version.v2.DeviceSize= ((CSD_Tab[7] & 0x3F) << 16) | (CSD_Tab[8] << 8) | CSD_Tab[9];
  487. Csd->version.v2.Reserved2 = ((CSD_Tab[10] & 0x80) >> 8);
  488. }
  489. Csd->EraseSingleBlockEnable = (CSD_Tab[10] & 0x40) >> 6;
  490. Csd->EraseSectorSize = ((CSD_Tab[10] & 0x3F) << 1)
  491. |((CSD_Tab[11] & 0x80) >> 7);
  492. Csd->WrProtectGrSize = (CSD_Tab[11] & 0x7F);
  493. Csd->WrProtectGrEnable = (CSD_Tab[12] & 0x80) >> 7;
  494. Csd->Reserved2 = (CSD_Tab[12] & 0x60) >> 5;
  495. Csd->WrSpeedFact = (CSD_Tab[12] & 0x1C) >> 2;
  496. Csd->MaxWrBlockLen = ((CSD_Tab[12] & 0x03) << 2)
  497. |((CSD_Tab[13] & 0xC0) >> 6);
  498. Csd->WriteBlockPartial = (CSD_Tab[13] & 0x20) >> 5;
  499. Csd->Reserved3 = (CSD_Tab[13] & 0x1F);
  500. Csd->FileFormatGrouop = (CSD_Tab[14] & 0x80) >> 7;
  501. Csd->CopyFlag = (CSD_Tab[14] & 0x40) >> 6;
  502. Csd->PermWrProtect = (CSD_Tab[14] & 0x20) >> 5;
  503. Csd->TempWrProtect = (CSD_Tab[14] & 0x10) >> 4;
  504. Csd->FileFormat = (CSD_Tab[14] & 0x0C) >> 2;
  505. Csd->Reserved4 = (CSD_Tab[14] & 0x03);
  506. Csd->crc = (CSD_Tab[15] & 0xFE) >> 1;
  507. Csd->Reserved5 = (CSD_Tab[15] & 0x01);
  508. #if 0
  509. if (SDHC_SpiCmd(Ctrl, CMD10, 0, 0))
  510. {
  511. goto READ_CONFIG_ERROR;
  512. }
  513. if (Ctrl->SDHCState)
  514. {
  515. goto READ_CONFIG_ERROR;
  516. }
  517. if (SDHC_SpiReadRegData(Ctrl, CID_Tab, 18))
  518. {
  519. goto READ_CONFIG_ERROR;
  520. }
  521. /* Byte 0 */
  522. Cid->ManufacturerID = CID_Tab[0];
  523. /* Byte 1 */
  524. Cid->OEM_AppliID = CID_Tab[1] << 8;
  525. /* Byte 2 */
  526. Cid->OEM_AppliID |= CID_Tab[2];
  527. /* Byte 3 */
  528. Cid->ProdName1 = CID_Tab[3] << 24;
  529. /* Byte 4 */
  530. Cid->ProdName1 |= CID_Tab[4] << 16;
  531. /* Byte 5 */
  532. Cid->ProdName1 |= CID_Tab[5] << 8;
  533. /* Byte 6 */
  534. Cid->ProdName1 |= CID_Tab[6];
  535. /* Byte 7 */
  536. Cid->ProdName2 = CID_Tab[7];
  537. /* Byte 8 */
  538. Cid->ProdRev = CID_Tab[8];
  539. /* Byte 9 */
  540. Cid->ProdSN = CID_Tab[9] << 24;
  541. /* Byte 10 */
  542. Cid->ProdSN |= CID_Tab[10] << 16;
  543. /* Byte 11 */
  544. Cid->ProdSN |= CID_Tab[11] << 8;
  545. /* Byte 12 */
  546. Cid->ProdSN |= CID_Tab[12];
  547. /* Byte 13 */
  548. Cid->Reserved1 |= (CID_Tab[13] & 0xF0) >> 4;
  549. Cid->ManufactDate = (CID_Tab[13] & 0x0F) << 8;
  550. /* Byte 14 */
  551. Cid->ManufactDate |= CID_Tab[14];
  552. /* Byte 15 */
  553. Cid->CID_CRC = (CID_Tab[15] & 0xFE) >> 1;
  554. Cid->Reserved2 = 1;
  555. #endif
  556. if(flag_SDHC)
  557. {
  558. pCardInfo->LogBlockSize = 512;
  559. pCardInfo->CardBlockSize = 512;
  560. Temp = 1024 * pCardInfo->LogBlockSize;
  561. pCardInfo->CardCapacity = (pCardInfo->Csd.version.v2.DeviceSize + 1) * Temp;
  562. pCardInfo->LogBlockNbr = (pCardInfo->Csd.version.v2.DeviceSize + 1) * 1024;
  563. }
  564. else
  565. {
  566. pCardInfo->CardCapacity = (pCardInfo->Csd.version.v1.DeviceSize + 1) ;
  567. pCardInfo->CardCapacity *= (1 << (pCardInfo->Csd.version.v1.DeviceSizeMul + 2));
  568. pCardInfo->LogBlockSize = 512;
  569. pCardInfo->CardBlockSize = 1 << (pCardInfo->Csd.RdBlockLen);
  570. pCardInfo->CardCapacity *= pCardInfo->CardBlockSize;
  571. pCardInfo->LogBlockNbr = (pCardInfo->CardCapacity) / (pCardInfo->LogBlockSize);
  572. }
  573. // DBG("卡容量 %lluKB", pCardInfo->CardCapacity/1024);
  574. return;
  575. READ_CONFIG_ERROR:
  576. Ctrl->IsInitDone = 0;
  577. Ctrl->SDHCError = 1;
  578. return;
  579. }
  580. void SDHC_SpiReadBlocks(void *pSDHC, uint8_t *Buf, uint32_t StartLBA, uint32_t BlockNums)
  581. {
  582. uint8_t Retry = 0;
  583. SDHC_SPICtrlStruct *Ctrl = (SDHC_SPICtrlStruct *)pSDHC;
  584. Buffer_StaticInit(&Ctrl->DataBuf, Buf, BlockNums);
  585. SDHC_SPIREADBLOCKS_START:
  586. if (SDHC_SpiCmd(Ctrl, CMD18, StartLBA + Ctrl->DataBuf.Pos, 0))
  587. {
  588. goto SDHC_SPIREADBLOCKS_ERROR;
  589. }
  590. if (SDHC_SpiReadBlockData(Ctrl))
  591. {
  592. goto SDHC_SPIREADBLOCKS_ERROR;
  593. }
  594. if (SDHC_SpiCmd(Ctrl, CMD12, 0, 1))
  595. {
  596. goto SDHC_SPIREADBLOCKS_ERROR;
  597. }
  598. if (Ctrl->DataBuf.Pos != Ctrl->DataBuf.MaxLen)
  599. {
  600. Retry++;
  601. DBG("%d", Retry);
  602. if (Retry > 3)
  603. {
  604. Ctrl->SDHCError = 1;
  605. goto SDHC_SPIREADBLOCKS_ERROR;
  606. }
  607. goto SDHC_SPIREADBLOCKS_START;
  608. }
  609. return;
  610. SDHC_SPIREADBLOCKS_ERROR:
  611. DBG("!");
  612. Ctrl->IsInitDone = 0;
  613. Ctrl->SDHCError = 1;
  614. return;
  615. }
  616. void SDHC_SpiWriteBlocks(void *pSDHC, const uint8_t *Buf, uint32_t StartLBA, uint32_t BlockNums)
  617. {
  618. uint8_t Retry = 0;
  619. SDHC_SPICtrlStruct *Ctrl = (SDHC_SPICtrlStruct *)pSDHC;
  620. Buffer_StaticInit(&Ctrl->DataBuf, Buf, BlockNums);
  621. SDHC_SPIREADBLOCKS_START:
  622. if (SDHC_SpiCmd(Ctrl, CMD25, StartLBA + Ctrl->DataBuf.Pos, 0))
  623. {
  624. goto SDHC_SPIREADBLOCKS_ERROR;
  625. }
  626. if (SDHC_SpiWriteBlockData(Ctrl))
  627. {
  628. goto SDHC_SPIREADBLOCKS_ERROR;
  629. }
  630. if (Ctrl->DataBuf.Pos != Ctrl->DataBuf.MaxLen)
  631. {
  632. Retry++;
  633. if (Retry > 3)
  634. {
  635. Ctrl->SDHCError = 1;
  636. goto SDHC_SPIREADBLOCKS_ERROR;
  637. }
  638. goto SDHC_SPIREADBLOCKS_START;
  639. }
  640. return;
  641. SDHC_SPIREADBLOCKS_ERROR:
  642. Ctrl->IsInitDone = 0;
  643. Ctrl->SDHCError = 1;
  644. return;
  645. }
  646. void *SDHC_SpiCreate(uint8_t SpiID, uint8_t CSPin)
  647. {
  648. SDHC_SPICtrlStruct *Ctrl = zalloc(sizeof(SDHC_SPICtrlStruct));
  649. Ctrl->CSPin = CSPin;
  650. Ctrl->SpiID = SpiID;
  651. Ctrl->SDHCReadBlockTo = 5 * CORE_TICK_1MS;
  652. Ctrl->SDHCWriteBlockTo = 25 * CORE_TICK_1MS;
  653. // Ctrl->IsPrintData = 1;
  654. return Ctrl;
  655. }
  656. uint32_t SDHC_GetLogBlockNbr(void *pSDHC)
  657. {
  658. SDHC_SPICtrlStruct *Ctrl = (SDHC_SPICtrlStruct *)pSDHC;
  659. return Ctrl->Info.LogBlockNbr;
  660. }
  661. uint8_t SDHC_IsReady(void *pSDHC)
  662. {
  663. SDHC_SPICtrlStruct *Ctrl = (SDHC_SPICtrlStruct *)pSDHC;
  664. if (!Ctrl->SDHCState && Ctrl->IsInitDone)
  665. {
  666. return 1;
  667. }
  668. else
  669. {
  670. return 0;
  671. }
  672. }