dev_sdhc_spi.c 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077
  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 HANDLE prvRWMutex;
  62. static const uint8_t prvSDHC_StandardInquiryData[STANDARD_INQUIRY_DATA_LEN] =
  63. {
  64. 0x00, //磁盘设备
  65. 0x80, //其中最高位D7为RMB。RMB=0,表示不可移除设备。如果RMB=1,则为可移除设备。
  66. 0x02, //各种版本号
  67. 0x02, //数据响应格式 0x02
  68. 0x1F, //附加数据长度,为31字节
  69. 0x00, //保留
  70. 0x00, //保留
  71. 0x00, //保留
  72. 'A','I','R','M','2','M',' ',' ',
  73. 'L','U','A','T','O','S','-','S','O','C',' ','U','S','B',' ',' ',
  74. '1','.','0','0'
  75. };
  76. extern const uint8_t prvCore_MSCPage00InquiryData[LENGTH_INQUIRY_PAGE00];
  77. /* USB Mass storage VPD Page 0x80 Inquiry Data for Unit Serial Number */
  78. extern const uint8_t prvCore_MSCPage80InquiryData[LENGTH_INQUIRY_PAGE80];
  79. /* USB Mass storage sense 6 Data */
  80. extern const uint8_t prvCore_MSCModeSense6data[MODE_SENSE6_LEN];
  81. /* USB Mass storage sense 10 Data */
  82. extern const uint8_t prvCore_MSCModeSense10data[MODE_SENSE10_LEN];
  83. static int32_t prvSDHC_SCSIInit(uint8_t LUN, void *pUserData)
  84. {
  85. SDHC_SPICtrlStruct *pSDHC = pUserData;
  86. if (!SDHC_IsReady(pSDHC))
  87. {
  88. SDHC_SpiInitCard(pSDHC);
  89. }
  90. return SDHC_IsReady(pSDHC)?ERROR_NONE:-ERROR_OPERATION_FAILED;
  91. }
  92. static int32_t prvSDHC_SCSIGetCapacity(uint8_t LUN, uint32_t *BlockNum, uint32_t *BlockSize, void *pUserData)
  93. {
  94. SDHC_SPICtrlStruct *pSDHC = pUserData;
  95. if (!pSDHC->Info.LogBlockSize || !pSDHC->Info.LogBlockNbr)
  96. {
  97. SDHC_SpiReadCardConfig(pSDHC);
  98. }
  99. *BlockSize = pSDHC->Info.LogBlockSize;
  100. *BlockNum = pSDHC->Info.LogBlockNbr;
  101. return 0;
  102. }
  103. static int32_t prvSDHC_SCSIIsReady(uint8_t LUN, void *pUserData)
  104. {
  105. SDHC_SPICtrlStruct *pSDHC = pUserData;
  106. return SDHC_IsReady(pSDHC)?ERROR_NONE:-ERROR_OPERATION_FAILED;
  107. }
  108. static int32_t prvSDHC_SCSIIsWriteProtected(uint8_t LUN, void *pUserData)
  109. {
  110. return 0;
  111. }
  112. static int32_t prvSDHC_SCSIReadNext(uint8_t LUN, void *pUserData);
  113. static int32_t prvSDHC_SCSIPreRead(uint8_t LUN, uint32_t BlockAddress, uint32_t BlockNums, void *pUserData)
  114. {
  115. SDHC_SPICtrlStruct *pSDHC = pUserData;
  116. if ((BlockAddress + BlockNums) > pSDHC->Info.LogBlockNbr)
  117. {
  118. DBG("%u,%u,%u", BlockAddress, BlockNums, pSDHC->Info.LogBlockNbr);
  119. return -1;
  120. }
  121. pSDHC->CurBlock = BlockAddress;
  122. pSDHC->EndBlock = BlockAddress + BlockNums;
  123. if ((pSDHC->PreCurBlock == pSDHC->CurBlock) && pSDHC->PreEndBlock)
  124. {
  125. // DBG("%u,%u,%u", pSDHC->PreCurBlock, pSDHC->CurBlock, pSDHC->PreEndBlock);
  126. pSDHC->CurBlock = pSDHC->PreEndBlock;
  127. return 0;
  128. }
  129. prvSDHC_SCSIReadNext(LUN, pUserData);
  130. return 0;
  131. }
  132. static int32_t prvSDHC_SCSIRead(uint8_t LUN, uint32_t Len, uint8_t **pOutData, uint32_t *OutLen, void *pUserData)
  133. {
  134. SDHC_SPICtrlStruct *pSDHC = pUserData;
  135. #if 1
  136. *pOutData = DBuffer_GetCache(pSDHC->SCSIDataBuf, 1);
  137. *OutLen = DBuffer_GetDataLen(pSDHC->SCSIDataBuf, 1);
  138. if (*OutLen > Len)
  139. {
  140. *OutLen = Len;
  141. }
  142. DBuffer_SetDataLen(pSDHC->SCSIDataBuf, 0, 1);
  143. DBuffer_SwapCache(pSDHC->SCSIDataBuf);
  144. if (pSDHC->USBDelayTime) //不得不降速
  145. {
  146. Task_DelayMS(pSDHC->USBDelayTime);
  147. }
  148. #else
  149. uint32_t ReadBlocks;
  150. if (pSDHC->EndBlock <= pSDHC->CurBlock) return -1;
  151. if ( ((pSDHC->EndBlock - pSDHC->CurBlock) << 9) > pSDHC->SCSIDataBuf->MaxLen)
  152. {
  153. ReadBlocks = pSDHC->SCSIDataBuf->MaxLen >> 9;
  154. }
  155. else
  156. {
  157. ReadBlocks = pSDHC->EndBlock - pSDHC->CurBlock;
  158. }
  159. SDHC_SpiReadBlocks(pSDHC, DBuffer_GetCache(pSDHC->SCSIDataBuf, 1), pSDHC->CurBlock, ReadBlocks);
  160. pSDHC->CurBlock += ReadBlocks;
  161. *pOutData = DBuffer_GetCache(pSDHC->SCSIDataBuf, 1);
  162. *OutLen = ReadBlocks << 9;
  163. #endif
  164. return SDHC_IsReady(pSDHC)?ERROR_NONE:-ERROR_OPERATION_FAILED;
  165. }
  166. static int32_t prvSDHC_SCSIReadNext(uint8_t LUN, void *pUserData)
  167. {
  168. #if 1
  169. SDHC_SPICtrlStruct *pSDHC = pUserData;
  170. uint32_t ReadBlocks;
  171. if (pSDHC->EndBlock <= pSDHC->CurBlock)
  172. {
  173. ReadBlocks = pSDHC->SCSIDataBuf->MaxLen >> 9;
  174. pSDHC->PreCurBlock = pSDHC->EndBlock;
  175. SDHC_SpiReadBlocks(pSDHC, DBuffer_GetCache(pSDHC->SCSIDataBuf, 1), pSDHC->PreCurBlock, ReadBlocks);
  176. pSDHC->PreEndBlock = pSDHC->PreCurBlock + ReadBlocks;
  177. DBuffer_SetDataLen(pSDHC->SCSIDataBuf, pSDHC->SCSIDataBuf->MaxLen, 1);
  178. return ERROR_NONE;
  179. }
  180. if ( ((pSDHC->EndBlock - pSDHC->CurBlock) << 9) > pSDHC->SCSIDataBuf->MaxLen)
  181. {
  182. ReadBlocks = pSDHC->SCSIDataBuf->MaxLen >> 9;
  183. }
  184. else
  185. {
  186. ReadBlocks = pSDHC->EndBlock - pSDHC->CurBlock;
  187. }
  188. SDHC_SpiReadBlocks(pSDHC, DBuffer_GetCache(pSDHC->SCSIDataBuf, 1), pSDHC->CurBlock, ReadBlocks);
  189. pSDHC->CurBlock += ReadBlocks;
  190. DBuffer_SetDataLen(pSDHC->SCSIDataBuf, ReadBlocks << 9, 1);
  191. #endif
  192. return ERROR_NONE;
  193. }
  194. static int32_t prvSDHC_SCSIPreWrite(uint8_t LUN, uint32_t BlockAddress, uint32_t BlockNums, void *pUserData)
  195. {
  196. SDHC_SPICtrlStruct *pSDHC = pUserData;
  197. if (!SDHC_IsReady(pSDHC)) return -1;
  198. if ((BlockAddress + BlockNums) > pSDHC->Info.LogBlockNbr)
  199. {
  200. return -1;
  201. }
  202. pSDHC->CurBlock = BlockAddress;
  203. pSDHC->EndBlock = BlockAddress + BlockNums;
  204. OS_ReInitBuffer(&pSDHC->CacheBuf, pSDHC->Info.LogBlockSize * BlockNums);
  205. return 0;
  206. }
  207. static int32_t prvSDHC_SCSIWrite(uint8_t LUN, uint8_t *Data, uint32_t Len, void *pUserData)
  208. {
  209. SDHC_SPICtrlStruct *pSDHC = pUserData;
  210. void *pData;
  211. if (!SDHC_IsReady(pSDHC)) return -1;
  212. if (pSDHC->EndBlock <= pSDHC->CurBlock) return -1;
  213. OS_BufferWrite(&pSDHC->CacheBuf, Data, Len);
  214. if (pSDHC->CacheBuf.Pos >= pSDHC->CacheBuf.MaxLen)
  215. {
  216. pData = pSDHC->CacheBuf.Data;
  217. memset(&pSDHC->CacheBuf, 0, sizeof(pSDHC->CacheBuf));
  218. Core_WriteSDHC(pSDHC, pData);
  219. }
  220. return ERROR_NONE;
  221. }
  222. static int32_t prvSDHC_SCSIUserCmd(USB_EndpointDataStruct *pEpData, MSC_SCSICtrlStruct *pMSC)
  223. {
  224. return -1;
  225. }
  226. static int32_t prvSDHC_SCSIGetMaxLUN(uint8_t *LUN, void *pUserData)
  227. {
  228. *LUN = 0;
  229. }
  230. const USB_StorageSCSITypeDef prvSDHC_SCSIFun =
  231. {
  232. prvSDHC_SCSIGetMaxLUN,
  233. prvSDHC_SCSIInit,
  234. prvSDHC_SCSIGetCapacity,
  235. prvSDHC_SCSIIsReady,
  236. prvSDHC_SCSIIsWriteProtected,
  237. prvSDHC_SCSIPreRead,
  238. prvSDHC_SCSIRead,
  239. prvSDHC_SCSIReadNext,
  240. prvSDHC_SCSIPreWrite,
  241. prvSDHC_SCSIWrite,
  242. prvSDHC_SCSIUserCmd,
  243. &prvSDHC_StandardInquiryData,
  244. &prvCore_MSCPage00InquiryData,
  245. &prvCore_MSCPage80InquiryData,
  246. &prvCore_MSCModeSense6data,
  247. &prvCore_MSCModeSense10data,
  248. };
  249. static void SDHC_SpiCS(SDHC_SPICtrlStruct *Ctrl, uint8_t OnOff)
  250. {
  251. uint8_t Temp[1] = {0xff};
  252. GPIO_Output(Ctrl->CSPin, !OnOff);
  253. if (!OnOff)
  254. {
  255. SPI_BlockTransfer(Ctrl->SpiID, Temp, Temp, 1);
  256. }
  257. }
  258. static int32_t SPIFlash_SpiIrqCB(void *pData, void *pParam)
  259. {
  260. SDHC_SPICtrlStruct *Ctrl = (SDHC_SPICtrlStruct *)pParam;
  261. #ifdef __BUILD_OS__
  262. if (Ctrl->NotifyTask)
  263. {
  264. Task_SendEvent(Ctrl->NotifyTask, DEV_SDHC_SPI_DONE, 0, 0, 0);
  265. }
  266. #endif
  267. return 0;
  268. }
  269. static uint8_t CRC7(uint8_t * chr, int cnt)
  270. {
  271. int i,a;
  272. uint8_t crc,Data;
  273. crc=0;
  274. for (a=0;a<cnt;a++)
  275. {
  276. Data=chr[a];
  277. for (i=0;i<8;i++)
  278. {
  279. crc <<= 1;
  280. if ((Data & 0x80)^(crc & 0x80))
  281. crc ^=0x09;
  282. Data <<= 1;
  283. }
  284. }
  285. crc=(crc<<1)|1;
  286. return(crc);
  287. }
  288. static void SDHC_SpiXfer(SDHC_SPICtrlStruct *Ctrl, uint8_t *Buf, uint16_t TxLen)
  289. {
  290. #ifdef __BUILD_OS__
  291. OS_EVENT Event;
  292. #endif
  293. #ifdef __BUILD_OS__
  294. if (Ctrl->NotifyTask && Ctrl->TaskCB)
  295. {
  296. Ctrl->SPIError = 0;
  297. SPI_SetCallbackFun(Ctrl->SpiID, SPIFlash_SpiIrqCB, Ctrl);
  298. SPI_Transfer(Ctrl->SpiID, Buf, Buf, TxLen, Ctrl->IsSpiDMAMode);
  299. if (Task_GetEvent(Ctrl->NotifyTask, DEV_SDHC_SPI_DONE, &Event, Ctrl->TaskCB, TxLen * CORE_TICK_1US + CORE_TICK_1MS))
  300. {
  301. Ctrl->SPIError = 1;
  302. SPI_TransferStop(Ctrl->SpiID);
  303. }
  304. SPI_SetCallbackFun(Ctrl->SpiID, NULL, NULL);
  305. }
  306. else
  307. #endif
  308. {
  309. SPI_BlockTransfer(Ctrl->SpiID, Buf, Buf, TxLen);
  310. }
  311. }
  312. static int32_t SDHC_SpiCmd(SDHC_SPICtrlStruct *Ctrl, uint8_t Cmd, uint32_t Arg, uint8_t NeedStop)
  313. {
  314. uint64_t OpEndTick;
  315. uint8_t i, TxLen, DummyLen;
  316. int32_t Result = -ERROR_OPERATION_FAILED;
  317. SDHC_SpiCS(Ctrl, 1);
  318. Ctrl->TempData[0] = 0x40|Cmd;
  319. BytesPutBe32(Ctrl->TempData + 1, Arg);
  320. Ctrl->TempData[5] = CRC7(Ctrl->TempData, 5);
  321. memset(Ctrl->TempData + 6, 0xff, 8);
  322. TxLen = 14;
  323. Ctrl->SPIError = 0;
  324. Ctrl->SDHCError = 0;
  325. SDHC_SpiXfer(Ctrl, Ctrl->TempData, TxLen);
  326. for(i = 7; i < TxLen; i++)
  327. {
  328. if (Ctrl->TempData[i] != 0xff)
  329. {
  330. Ctrl->SDHCState = Ctrl->TempData[i];
  331. if ((Ctrl->SDHCState == !Ctrl->IsInitDone) || !Ctrl->SDHCState)
  332. {
  333. Result = ERROR_NONE;
  334. }
  335. DummyLen = TxLen - i - 1;
  336. memcpy(Ctrl->ExternResult, &Ctrl->TempData[i + 1], DummyLen);
  337. Ctrl->ExternLen = DummyLen;
  338. break;
  339. }
  340. }
  341. if (NeedStop)
  342. {
  343. SDHC_SpiCS(Ctrl, 0);
  344. }
  345. if (Result)
  346. {
  347. DBG("cmd %x arg %x result %d", Cmd, Arg, Result);
  348. DBG_HexPrintf(Ctrl->TempData, TxLen);
  349. }
  350. return Result;
  351. }
  352. static int32_t SDHC_SpiReadRegData(SDHC_SPICtrlStruct *Ctrl, uint8_t *RegDataBuf, uint8_t DataLen)
  353. {
  354. uint64_t OpEndTick;
  355. int Result = ERROR_NONE;
  356. uint16_t DummyLen;
  357. uint16_t i,findResult,offset;
  358. Ctrl->SPIError = 0;
  359. Ctrl->SDHCError = 0;
  360. OpEndTick = GetSysTick() + Ctrl->SDHCReadBlockTo * 4;
  361. findResult = 0;
  362. offset = 0;
  363. for(i = 0; i < Ctrl->ExternLen; i++)
  364. {
  365. if (Ctrl->ExternResult[i] != 0xff)
  366. {
  367. if (0xfe == Ctrl->ExternResult[i])
  368. {
  369. offset = 1;
  370. }
  371. else
  372. {
  373. DBG("no 0xfe find %d,%x",i,Ctrl->ExternResult[i]);
  374. }
  375. DummyLen = Ctrl->ExternLen - i - offset;
  376. memcpy(RegDataBuf, &Ctrl->ExternResult[i + offset], DummyLen);
  377. memset(RegDataBuf + DummyLen, 0xff, DataLen - DummyLen);
  378. SDHC_SpiXfer(Ctrl, RegDataBuf + DummyLen, DataLen - DummyLen);
  379. goto SDHC_SPIREADREGDATA_DONE;
  380. }
  381. }
  382. while((GetSysTick() < OpEndTick) && !Ctrl->SDHCError)
  383. {
  384. memset(Ctrl->TempData, 0xff, 40);
  385. SDHC_SpiXfer(Ctrl, Ctrl->TempData, 40);
  386. for(i = 0; i < 40; i++)
  387. {
  388. if (Ctrl->TempData[i] != 0xff)
  389. {
  390. if (0xfe == Ctrl->TempData[i])
  391. {
  392. offset = 1;
  393. }
  394. else
  395. {
  396. DBG("no 0xfe find %d,%x",i,Ctrl->TempData[i]);
  397. }
  398. DummyLen = 40 - i - offset;
  399. if (DummyLen >= DataLen)
  400. {
  401. memcpy(RegDataBuf, &Ctrl->TempData[i + offset], DataLen);
  402. goto SDHC_SPIREADREGDATA_DONE;
  403. }
  404. else
  405. {
  406. memcpy(RegDataBuf, &Ctrl->TempData[i + offset], DummyLen);
  407. memset(RegDataBuf + DummyLen, 0xff, DataLen - DummyLen);
  408. SDHC_SpiXfer(Ctrl, RegDataBuf + DummyLen, DataLen - DummyLen);
  409. goto SDHC_SPIREADREGDATA_DONE;
  410. }
  411. }
  412. }
  413. }
  414. DBG("read config reg timeout!");
  415. Result = -ERROR_OPERATION_FAILED;
  416. SDHC_SPIREADREGDATA_DONE:
  417. SDHC_SpiCS(Ctrl, 0);
  418. return Result;
  419. }
  420. static int32_t SDHC_SpiWriteBlockData(SDHC_SPICtrlStruct *Ctrl)
  421. {
  422. uint64_t OpEndTick;
  423. int Result = -ERROR_OPERATION_FAILED;
  424. uint16_t TxLen, DoneFlag, waitCnt;
  425. uint16_t i, crc16;
  426. uint8_t *pBuf;
  427. Ctrl->SPIError = 0;
  428. Ctrl->SDHCError = 0;
  429. OpEndTick = GetSysTick() + Ctrl->SDHCWriteBlockTo;
  430. while( (Ctrl->DataBuf.Pos < Ctrl->DataBuf.MaxLen) && (GetSysTick() < OpEndTick) )
  431. {
  432. Ctrl->TempData[0] = 0xff;
  433. Ctrl->TempData[1] = 0xff;
  434. //SD_DBG("%u,%u", Ctrl->DataBuf.Pos, Ctrl->DataBuf.MaxLen);
  435. Ctrl->TempData[2] = 0xfc;
  436. memcpy(Ctrl->TempData + 3, Ctrl->DataBuf.Data + Ctrl->DataBuf.Pos * __SDHC_BLOCK_LEN__, __SDHC_BLOCK_LEN__);
  437. crc16 = CRC16Cal(Ctrl->DataBuf.Data + Ctrl->DataBuf.Pos * __SDHC_BLOCK_LEN__, __SDHC_BLOCK_LEN__, 0, CRC16_CCITT_GEN, 0);
  438. BytesPutBe16(Ctrl->TempData + 3 + __SDHC_BLOCK_LEN__, crc16);
  439. Ctrl->TempData[5 + __SDHC_BLOCK_LEN__] = 0xff;
  440. TxLen = 6 + __SDHC_BLOCK_LEN__;
  441. SDHC_SpiXfer(Ctrl, Ctrl->TempData, TxLen);
  442. if ((Ctrl->TempData[5 + __SDHC_BLOCK_LEN__] & 0x1f) != 0x05)
  443. {
  444. DBG("write data error ! x%02x", Ctrl->TempData[5 + __SDHC_BLOCK_LEN__]);
  445. Ctrl->SDHCError = 1;
  446. goto SDHC_SPIWRITEBLOCKDATA_DONE;
  447. }
  448. DoneFlag = 0;
  449. waitCnt = 0;
  450. while( (GetSysTick() < OpEndTick) && !DoneFlag )
  451. {
  452. TxLen = Ctrl->WriteWaitCnt?Ctrl->WriteWaitCnt:80;
  453. memset(Ctrl->TempData, 0xff, TxLen);
  454. SDHC_SpiXfer(Ctrl, Ctrl->TempData, TxLen);
  455. for(i = 4; i < TxLen; i++)
  456. {
  457. if (Ctrl->TempData[i] == 0xff)
  458. {
  459. DoneFlag = 1;
  460. if ((i + waitCnt) < sizeof(Ctrl->TempData))
  461. {
  462. if ((i + waitCnt) != Ctrl->WriteWaitCnt)
  463. {
  464. // DBG("%u", Ctrl->WriteWaitCnt);
  465. Ctrl->WriteWaitCnt = i + waitCnt;
  466. }
  467. }
  468. break;
  469. }
  470. }
  471. waitCnt += TxLen;
  472. }
  473. if (!DoneFlag)
  474. {
  475. DBG("write data timeout!");
  476. Ctrl->SDHCError = 1;
  477. goto SDHC_SPIWRITEBLOCKDATA_DONE;
  478. }
  479. Ctrl->DataBuf.Pos++;
  480. OpEndTick = GetSysTick() + Ctrl->SDHCWriteBlockTo;
  481. }
  482. Result = ERROR_NONE;
  483. SDHC_SPIWRITEBLOCKDATA_DONE:
  484. Ctrl->TempData[0] = 0xfd;
  485. SPI_BlockTransfer(Ctrl->SpiID, Ctrl->TempData, Ctrl->TempData, 1);
  486. OpEndTick = GetSysTick() + Ctrl->SDHCWriteBlockTo * Ctrl->DataBuf.MaxLen;
  487. DoneFlag = 0;
  488. while( (GetSysTick() < OpEndTick) && !DoneFlag )
  489. {
  490. TxLen = sizeof(Ctrl->TempData);
  491. memset(Ctrl->TempData, 0xff, TxLen);
  492. SDHC_SpiXfer(Ctrl, Ctrl->TempData, TxLen);
  493. for(i = 4; i < TxLen; i++)
  494. {
  495. if (Ctrl->TempData[i] == 0xff)
  496. {
  497. DoneFlag = 1;
  498. break;
  499. }
  500. }
  501. }
  502. SDHC_SpiCS(Ctrl, 0);
  503. return Result;
  504. }
  505. static int32_t SDHC_SpiReadBlockData(SDHC_SPICtrlStruct *Ctrl)
  506. {
  507. uint64_t OpEndTick;
  508. int Result = -ERROR_OPERATION_FAILED;
  509. uint16_t ReadLen, DummyLen, RemainingLen;
  510. uint16_t i, crc16, crc16_check;
  511. uint8_t *pBuf;
  512. Ctrl->SPIError = 0;
  513. Ctrl->SDHCError = 0;
  514. OpEndTick = GetSysTick() + Ctrl->SDHCReadBlockTo;
  515. while( (Ctrl->DataBuf.Pos < Ctrl->DataBuf.MaxLen) && (GetSysTick() < OpEndTick) )
  516. {
  517. DummyLen = (__SDHC_BLOCK_LEN__ >> 1);
  518. memset(Ctrl->TempData, 0xff, DummyLen);
  519. // SD_DBG("%u,%u", Ctrl->DataBuf.Pos, Ctrl->DataBuf.MaxLen);
  520. SDHC_SpiXfer(Ctrl, Ctrl->TempData, DummyLen);
  521. RemainingLen = 0;
  522. for(i = 0; i < DummyLen; i++)
  523. {
  524. if (Ctrl->TempData[i] == 0xfe)
  525. {
  526. ReadLen = (DummyLen - i - 1);
  527. RemainingLen = __SDHC_BLOCK_LEN__ - ReadLen;
  528. if (ReadLen)
  529. {
  530. memcpy(Ctrl->DataBuf.Data + Ctrl->DataBuf.Pos * __SDHC_BLOCK_LEN__, Ctrl->TempData + i + 1, ReadLen);
  531. }
  532. // SD_DBG("%u,%u", ReadLen, RemainingLen);
  533. goto READ_REST_DATA;
  534. }
  535. }
  536. continue;
  537. READ_REST_DATA:
  538. pBuf = Ctrl->DataBuf.Data + Ctrl->DataBuf.Pos * __SDHC_BLOCK_LEN__ + ReadLen;
  539. memset(pBuf, 0xff, RemainingLen);
  540. SDHC_SpiXfer(Ctrl, pBuf, RemainingLen);
  541. memset(Ctrl->TempData, 0xff, 2);
  542. SPI_BlockTransfer(Ctrl->SpiID, Ctrl->TempData, Ctrl->TempData, 2);
  543. // if (Ctrl->IsCRCCheck)
  544. {
  545. crc16 = CRC16Cal(Ctrl->DataBuf.Data + Ctrl->DataBuf.Pos * __SDHC_BLOCK_LEN__, __SDHC_BLOCK_LEN__, 0, CRC16_CCITT_GEN, 0);
  546. crc16_check = BytesGetBe16(Ctrl->TempData);
  547. if (crc16 != crc16_check)
  548. {
  549. DBG("crc16 error %04x %04x", crc16, crc16_check);
  550. Result = ERROR_NONE;
  551. goto SDHC_SPIREADBLOCKDATA_DONE;
  552. }
  553. }
  554. Ctrl->DataBuf.Pos++;
  555. OpEndTick = GetSysTick() + Ctrl->SDHCReadBlockTo;
  556. }
  557. Result = ERROR_NONE;
  558. SDHC_SPIREADBLOCKDATA_DONE:
  559. return Result;
  560. }
  561. static void SDHC_Recovery(SDHC_SPICtrlStruct *Ctrl)
  562. {
  563. memset(Ctrl->TempData, 0xfd, 512);
  564. SPI_SetNewConfig(Ctrl->SpiID, 12000000, 0xff);
  565. GPIO_Output(Ctrl->CSPin, 0);
  566. SDHC_SpiXfer(Ctrl, Ctrl->TempData, 512);
  567. GPIO_Output(Ctrl->CSPin, 1);
  568. memset(Ctrl->TempData, 0xff, 512);
  569. GPIO_Output(Ctrl->CSPin, 0);
  570. SDHC_SpiXfer(Ctrl, Ctrl->TempData, 512);
  571. GPIO_Output(Ctrl->CSPin, 1);
  572. SDHC_SpiCmd(Ctrl, CMD12, 0, 1);
  573. }
  574. void SDHC_SpiInitCard(void *pSDHC)
  575. {
  576. uint8_t i;
  577. uint64_t OpEndTick;
  578. SDHC_SPICtrlStruct *Ctrl = (SDHC_SPICtrlStruct *)pSDHC;
  579. Ctrl->IsInitDone = 0;
  580. Ctrl->SDHCState = 0xff;
  581. Ctrl->Info.CardCapacity = 0;
  582. Ctrl->WriteWaitCnt = 80;
  583. SPI_SetNewConfig(Ctrl->SpiID, 400000, 0xff);
  584. GPIO_Output(Ctrl->CSPin, 0);
  585. SDHC_SpiXfer(Ctrl, Ctrl->TempData, 20);
  586. GPIO_Output(Ctrl->CSPin, 1);
  587. memset(Ctrl->TempData, 0xff, 20);
  588. SDHC_SpiXfer(Ctrl, Ctrl->TempData, 20);
  589. Ctrl->SDSC = 0;
  590. if (SDHC_SpiCmd(Ctrl, CMD0, 0, 1))
  591. {
  592. goto INIT_DONE;
  593. }
  594. OpEndTick = GetSysTick() + 3 * CORE_TICK_1S;
  595. if (SDHC_SpiCmd(Ctrl, CMD8, 0x1aa, 1)) //只支持2G以上的SDHC卡
  596. {
  597. Ctrl->SDSC = 1;
  598. }
  599. WAIT_INIT_DONE:
  600. if (GetSysTick() >= OpEndTick)
  601. {
  602. goto INIT_DONE;
  603. }
  604. if (SDHC_SpiCmd(Ctrl, SD_CMD_APP_CMD, 0, 1))
  605. {
  606. goto INIT_DONE;
  607. }
  608. if (Ctrl->SDSC)
  609. {
  610. if (SDHC_SpiCmd(Ctrl, SD_CMD_SD_APP_OP_COND, 0, 1))
  611. {
  612. goto INIT_DONE;
  613. }
  614. }
  615. else
  616. {
  617. if (SDHC_SpiCmd(Ctrl, SD_CMD_SD_APP_OP_COND, 0x40000000, 1))
  618. {
  619. goto INIT_DONE;
  620. }
  621. }
  622. Ctrl->IsInitDone = !Ctrl->SDHCState;
  623. if (!Ctrl->IsInitDone)
  624. {
  625. Task_DelayMS(10);
  626. goto WAIT_INIT_DONE;
  627. }
  628. if (SDHC_SpiCmd(Ctrl, CMD58, 0, 1))
  629. {
  630. goto INIT_DONE;
  631. }
  632. Ctrl->OCR = BytesGetBe32(Ctrl->ExternResult);
  633. SPI_SetNewConfig(Ctrl->SpiID, Ctrl->SpiSpeed, 0xff);
  634. SDHC_SpiReadCardConfig(pSDHC);
  635. SD_DBG("sdcard init OK OCR:0x%08x!", Ctrl->OCR);
  636. return;
  637. INIT_DONE:
  638. if (!Ctrl->IsInitDone)
  639. {
  640. SD_DBG("sdcard init fail!");
  641. }
  642. return;
  643. }
  644. void SDHC_SpiReadCardConfig(void *pSDHC)
  645. {
  646. SDHC_SPICtrlStruct *Ctrl = (SDHC_SPICtrlStruct *)pSDHC;
  647. uint8_t CSD_Tab[18];
  648. uint8_t CID_Tab[18];
  649. SD_CSD* Csd = &Ctrl->Info.Csd;
  650. SD_CID* Cid = &Ctrl->Info.Cid;
  651. SD_CardInfo *pCardInfo = &Ctrl->Info;
  652. uint64_t Temp;
  653. uint8_t flag_SDHC = (Ctrl->OCR & 0x40000000) >> 30;
  654. Ctrl->SDSC = !flag_SDHC;
  655. if (Ctrl->Info.CardCapacity) return;
  656. if (SDHC_SpiCmd(Ctrl, CMD9, 0, 0))
  657. {
  658. goto READ_CONFIG_ERROR;
  659. }
  660. if (Ctrl->SDHCState)
  661. {
  662. goto READ_CONFIG_ERROR;
  663. }
  664. if (SDHC_SpiReadRegData(Ctrl, CSD_Tab, 18))
  665. {
  666. goto READ_CONFIG_ERROR;
  667. }
  668. /*************************************************************************
  669. CSD header decoding
  670. *************************************************************************/
  671. /* Byte 0 */
  672. Csd->CSDStruct = (CSD_Tab[0] & 0xC0) >> 6;
  673. Csd->Reserved1 = CSD_Tab[0] & 0x3F;
  674. /* Byte 1 */
  675. Csd->TAAC = CSD_Tab[1];
  676. /* Byte 2 */
  677. Csd->NSAC = CSD_Tab[2];
  678. /* Byte 3 */
  679. Csd->MaxBusClkFrec = CSD_Tab[3];
  680. /* Byte 4/5 */
  681. Csd->CardComdClasses = (CSD_Tab[4] << 4) | ((CSD_Tab[5] & 0xF0) >> 4);
  682. Csd->RdBlockLen = CSD_Tab[5] & 0x0F;
  683. /* Byte 6 */
  684. Csd->PartBlockRead = (CSD_Tab[6] & 0x80) >> 7;
  685. Csd->WrBlockMisalign = (CSD_Tab[6] & 0x40) >> 6;
  686. Csd->RdBlockMisalign = (CSD_Tab[6] & 0x20) >> 5;
  687. Csd->DSRImpl = (CSD_Tab[6] & 0x10) >> 4;
  688. /*************************************************************************
  689. CSD v1/v2 decoding
  690. *************************************************************************/
  691. if(!flag_SDHC)
  692. {
  693. Csd->version.v1.Reserved1 = ((CSD_Tab[6] & 0x0C) >> 2);
  694. Csd->version.v1.DeviceSize = ((CSD_Tab[6] & 0x03) << 10)
  695. | (CSD_Tab[7] << 2)
  696. | ((CSD_Tab[8] & 0xC0) >> 6);
  697. Csd->version.v1.MaxRdCurrentVDDMin = (CSD_Tab[8] & 0x38) >> 3;
  698. Csd->version.v1.MaxRdCurrentVDDMax = (CSD_Tab[8] & 0x07);
  699. Csd->version.v1.MaxWrCurrentVDDMin = (CSD_Tab[9] & 0xE0) >> 5;
  700. Csd->version.v1.MaxWrCurrentVDDMax = (CSD_Tab[9] & 0x1C) >> 2;
  701. Csd->version.v1.DeviceSizeMul = ((CSD_Tab[9] & 0x03) << 1)
  702. |((CSD_Tab[10] & 0x80) >> 7);
  703. }
  704. else
  705. {
  706. Csd->version.v2.Reserved1 = ((CSD_Tab[6] & 0x0F) << 2) | ((CSD_Tab[7] & 0xC0) >> 6);
  707. Csd->version.v2.DeviceSize= ((CSD_Tab[7] & 0x3F) << 16) | (CSD_Tab[8] << 8) | CSD_Tab[9];
  708. Csd->version.v2.Reserved2 = ((CSD_Tab[10] & 0x80) >> 8);
  709. }
  710. Csd->EraseSingleBlockEnable = (CSD_Tab[10] & 0x40) >> 6;
  711. Csd->EraseSectorSize = ((CSD_Tab[10] & 0x3F) << 1)
  712. |((CSD_Tab[11] & 0x80) >> 7);
  713. Csd->WrProtectGrSize = (CSD_Tab[11] & 0x7F);
  714. Csd->WrProtectGrEnable = (CSD_Tab[12] & 0x80) >> 7;
  715. Csd->Reserved2 = (CSD_Tab[12] & 0x60) >> 5;
  716. Csd->WrSpeedFact = (CSD_Tab[12] & 0x1C) >> 2;
  717. Csd->MaxWrBlockLen = ((CSD_Tab[12] & 0x03) << 2)
  718. |((CSD_Tab[13] & 0xC0) >> 6);
  719. Csd->WriteBlockPartial = (CSD_Tab[13] & 0x20) >> 5;
  720. Csd->Reserved3 = (CSD_Tab[13] & 0x1F);
  721. Csd->FileFormatGrouop = (CSD_Tab[14] & 0x80) >> 7;
  722. Csd->CopyFlag = (CSD_Tab[14] & 0x40) >> 6;
  723. Csd->PermWrProtect = (CSD_Tab[14] & 0x20) >> 5;
  724. Csd->TempWrProtect = (CSD_Tab[14] & 0x10) >> 4;
  725. Csd->FileFormat = (CSD_Tab[14] & 0x0C) >> 2;
  726. Csd->Reserved4 = (CSD_Tab[14] & 0x03);
  727. Csd->crc = (CSD_Tab[15] & 0xFE) >> 1;
  728. Csd->Reserved5 = (CSD_Tab[15] & 0x01);
  729. #if 0
  730. if (SDHC_SpiCmd(Ctrl, CMD10, 0, 0))
  731. {
  732. goto READ_CONFIG_ERROR;
  733. }
  734. if (Ctrl->SDHCState)
  735. {
  736. goto READ_CONFIG_ERROR;
  737. }
  738. if (SDHC_SpiReadRegData(Ctrl, CID_Tab, 18))
  739. {
  740. goto READ_CONFIG_ERROR;
  741. }
  742. /* Byte 0 */
  743. Cid->ManufacturerID = CID_Tab[0];
  744. /* Byte 1 */
  745. Cid->OEM_AppliID = CID_Tab[1] << 8;
  746. /* Byte 2 */
  747. Cid->OEM_AppliID |= CID_Tab[2];
  748. /* Byte 3 */
  749. Cid->ProdName1 = CID_Tab[3] << 24;
  750. /* Byte 4 */
  751. Cid->ProdName1 |= CID_Tab[4] << 16;
  752. /* Byte 5 */
  753. Cid->ProdName1 |= CID_Tab[5] << 8;
  754. /* Byte 6 */
  755. Cid->ProdName1 |= CID_Tab[6];
  756. /* Byte 7 */
  757. Cid->ProdName2 = CID_Tab[7];
  758. /* Byte 8 */
  759. Cid->ProdRev = CID_Tab[8];
  760. /* Byte 9 */
  761. Cid->ProdSN = CID_Tab[9] << 24;
  762. /* Byte 10 */
  763. Cid->ProdSN |= CID_Tab[10] << 16;
  764. /* Byte 11 */
  765. Cid->ProdSN |= CID_Tab[11] << 8;
  766. /* Byte 12 */
  767. Cid->ProdSN |= CID_Tab[12];
  768. /* Byte 13 */
  769. Cid->Reserved1 |= (CID_Tab[13] & 0xF0) >> 4;
  770. Cid->ManufactDate = (CID_Tab[13] & 0x0F) << 8;
  771. /* Byte 14 */
  772. Cid->ManufactDate |= CID_Tab[14];
  773. /* Byte 15 */
  774. Cid->CID_CRC = (CID_Tab[15] & 0xFE) >> 1;
  775. Cid->Reserved2 = 1;
  776. #endif
  777. if(flag_SDHC)
  778. {
  779. pCardInfo->LogBlockSize = 512;
  780. pCardInfo->CardBlockSize = 512;
  781. Temp = 1024 * pCardInfo->LogBlockSize;
  782. pCardInfo->CardCapacity = (pCardInfo->Csd.version.v2.DeviceSize + 1) * Temp;
  783. pCardInfo->LogBlockNbr = (pCardInfo->Csd.version.v2.DeviceSize + 1) * 1024;
  784. }
  785. else
  786. {
  787. pCardInfo->CardCapacity = (pCardInfo->Csd.version.v1.DeviceSize + 1) ;
  788. pCardInfo->CardCapacity *= (1 << (pCardInfo->Csd.version.v1.DeviceSizeMul + 2));
  789. pCardInfo->LogBlockSize = 512;
  790. pCardInfo->CardBlockSize = 1 << (pCardInfo->Csd.RdBlockLen);
  791. pCardInfo->CardCapacity *= pCardInfo->CardBlockSize;
  792. pCardInfo->LogBlockNbr = (pCardInfo->CardCapacity) / (pCardInfo->LogBlockSize);
  793. }
  794. DBG("卡容量 %lluKB", pCardInfo->CardCapacity/1024);
  795. return;
  796. READ_CONFIG_ERROR:
  797. Ctrl->IsInitDone = 0;
  798. Ctrl->SDHCError = 1;
  799. return;
  800. }
  801. void SDHC_SpiReadBlocks(void *pSDHC, uint8_t *Buf, uint32_t StartLBA, uint32_t BlockNums)
  802. {
  803. uint8_t Retry = 0;
  804. uint8_t error = 1;
  805. SDHC_SPICtrlStruct *Ctrl = (SDHC_SPICtrlStruct *)pSDHC;
  806. #ifdef __BUILD_OS__
  807. if (OS_MutexLockWtihTime(prvRWMutex, 1000))
  808. {
  809. DBG("mutex wait timeout!");
  810. return;
  811. }
  812. #endif
  813. if (Ctrl->SDSC)
  814. {
  815. if (SDHC_SpiCmd(Ctrl, CMD16, 512, 1))
  816. {
  817. goto SDHC_SPIREADBLOCKS_ERROR;
  818. }
  819. }
  820. uint32_t address;
  821. Buffer_StaticInit(&Ctrl->DataBuf, Buf, BlockNums);
  822. SDHC_SPIREADBLOCKS_START:
  823. if (Ctrl->SDSC)
  824. {
  825. address = (StartLBA + Ctrl->DataBuf.Pos) * 512;
  826. }
  827. else
  828. {
  829. address = (StartLBA + Ctrl->DataBuf.Pos);
  830. }
  831. if (SDHC_SpiCmd(Ctrl, CMD18, address, 0))
  832. {
  833. goto SDHC_SPIREADBLOCKS_CHECK;
  834. }
  835. if (SDHC_SpiReadBlockData(Ctrl))
  836. {
  837. goto SDHC_SPIREADBLOCKS_CHECK;
  838. }
  839. for (int i = 0; i < 3; i++)
  840. {
  841. if (!SDHC_SpiCmd(Ctrl, CMD12, 0, 1))
  842. {
  843. error = 0;
  844. break;
  845. }
  846. else
  847. {
  848. Ctrl->SDHCError = 0;
  849. Ctrl->IsInitDone = 1;
  850. Ctrl->SDHCState = 0;
  851. }
  852. }
  853. SDHC_SPIREADBLOCKS_CHECK:
  854. if (error)
  855. {
  856. DBG("%x,%u,%u",Ctrl->SDHCState, Ctrl->DataBuf.Pos, Ctrl->DataBuf.MaxLen);
  857. }
  858. if (Ctrl->DataBuf.Pos != Ctrl->DataBuf.MaxLen)
  859. {
  860. Retry++;
  861. DBG("%d,%u,%u", Retry, Ctrl->DataBuf.Pos, Ctrl->DataBuf.MaxLen);
  862. if (Retry > 3)
  863. {
  864. Ctrl->SDHCError = 1;
  865. goto SDHC_SPIREADBLOCKS_ERROR;
  866. }
  867. else
  868. {
  869. Ctrl->SDHCError = 0;
  870. Ctrl->IsInitDone = 1;
  871. Ctrl->SDHCState = 0;
  872. }
  873. goto SDHC_SPIREADBLOCKS_START;
  874. }
  875. #ifdef __BUILD_OS__
  876. OS_MutexRelease(prvRWMutex);
  877. #endif
  878. return;
  879. SDHC_SPIREADBLOCKS_ERROR:
  880. DBG("read error!");
  881. Ctrl->IsInitDone = 0;
  882. Ctrl->SDHCError = 1;
  883. #ifdef __BUILD_OS__
  884. OS_MutexRelease(prvRWMutex);
  885. #endif
  886. return;
  887. }
  888. void SDHC_SpiWriteBlocks(void *pSDHC, const uint8_t *Buf, uint32_t StartLBA, uint32_t BlockNums)
  889. {
  890. uint8_t Retry = 0;
  891. SDHC_SPICtrlStruct *Ctrl = (SDHC_SPICtrlStruct *)pSDHC;
  892. #ifdef __BUILD_OS__
  893. if (OS_MutexLockWtihTime(prvRWMutex, 1000))
  894. {
  895. DBG("mutex wait timeout!");
  896. return;
  897. }
  898. #endif
  899. if (Ctrl->SDSC)
  900. {
  901. if (SDHC_SpiCmd(Ctrl, CMD16, 512, 1))
  902. {
  903. goto SDHC_SPIWRITEBLOCKS_ERROR;
  904. }
  905. }
  906. uint32_t address;
  907. Buffer_StaticInit(&Ctrl->DataBuf, Buf, BlockNums);
  908. SDHC_SPIWRITEBLOCKS_START:
  909. if (Ctrl->SDSC)
  910. {
  911. address = (StartLBA + Ctrl->DataBuf.Pos) * 512;
  912. }
  913. else
  914. {
  915. address = (StartLBA + Ctrl->DataBuf.Pos);
  916. }
  917. if (SDHC_SpiCmd(Ctrl, CMD25, address, 0))
  918. {
  919. goto SDHC_SPIWRITEBLOCKS_ERROR;
  920. }
  921. if (SDHC_SpiWriteBlockData(Ctrl))
  922. {
  923. goto SDHC_SPIWRITEBLOCKS_ERROR;
  924. }
  925. if (Ctrl->DataBuf.Pos != Ctrl->DataBuf.MaxLen)
  926. {
  927. Retry++;
  928. DBG("%d", Retry);
  929. if (Retry > 3)
  930. {
  931. Ctrl->SDHCError = 1;
  932. goto SDHC_SPIWRITEBLOCKS_ERROR;
  933. }
  934. goto SDHC_SPIWRITEBLOCKS_START;
  935. }
  936. #ifdef __BUILD_OS__
  937. OS_MutexRelease(prvRWMutex);
  938. #endif
  939. return;
  940. SDHC_SPIWRITEBLOCKS_ERROR:
  941. DBG("write error!");
  942. Ctrl->IsInitDone = 0;
  943. Ctrl->SDHCError = 1;
  944. #ifdef __BUILD_OS__
  945. OS_MutexRelease(prvRWMutex);
  946. #endif
  947. return;
  948. }
  949. void *SDHC_SpiCreate(uint8_t SpiID, uint8_t CSPin)
  950. {
  951. SDHC_SPICtrlStruct *Ctrl = zalloc(sizeof(SDHC_SPICtrlStruct));
  952. Ctrl->CSPin = CSPin;
  953. Ctrl->SpiID = SpiID;
  954. Ctrl->SDHCReadBlockTo = 100 * CORE_TICK_1MS;
  955. Ctrl->SDHCWriteBlockTo = 100 * CORE_TICK_1MS;
  956. #ifdef __BUILD_OS__
  957. if (!prvRWMutex)
  958. {
  959. prvRWMutex = OS_MutexCreateUnlock();
  960. }
  961. #endif
  962. // Ctrl->IsPrintData = 1;
  963. Ctrl->SpiSpeed = 24000000;
  964. return Ctrl;
  965. }
  966. void SDHC_SpiRelease(void *pSDHC)
  967. {
  968. SDHC_SPICtrlStruct *Ctrl = (SDHC_SPICtrlStruct *)pSDHC;
  969. SDHC_Recovery(Ctrl);
  970. OS_DeInitBuffer(&Ctrl->CacheBuf);
  971. #ifdef __BUILD_OS__
  972. OS_MutexRelease(prvRWMutex);
  973. Ctrl->WaitFree = 1;
  974. Task_DelayMS(50);
  975. #endif
  976. DBG("free %x", pSDHC);
  977. }
  978. uint32_t SDHC_GetLogBlockNbr(void *pSDHC)
  979. {
  980. SDHC_SPICtrlStruct *Ctrl = (SDHC_SPICtrlStruct *)pSDHC;
  981. return Ctrl->Info.LogBlockNbr;
  982. }
  983. uint8_t SDHC_IsReady(void *pSDHC)
  984. {
  985. SDHC_SPICtrlStruct *Ctrl = (SDHC_SPICtrlStruct *)pSDHC;
  986. if (!Ctrl->SDHCState && Ctrl->IsInitDone)
  987. {
  988. return 1;
  989. }
  990. else
  991. {
  992. DBG("SDHC error, please reboot tf card");
  993. return 0;
  994. }
  995. }