msd.c 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937
  1. /******************** (C) COPYRIGHT 2008 STMicroelectronics ********************
  2. * File Name : msd.c
  3. * Author : MCD Application Team
  4. * Version : V2.1
  5. * Date : 05/30/2008
  6. * Description : MSD card driver source file.
  7. * Pin assignment:
  8. * ----------------------------------------------
  9. * | STM32F10x | MSD Pin |
  10. * ----------------------------------------------
  11. * | P0.4 | ChipSelect 1 |
  12. * | P0.1 / MOSI | DataIn 2 |
  13. * | | GND 3 (0 V) |
  14. * | | VDD 4 (3.3 V) |
  15. * | P0.2 / SCLK | Clock 5 |
  16. * | | GND 6 (0 V) |
  17. * | P0.0 / MISO | DataOut 7 |
  18. * -----------------------------------------------
  19. ********************************************************************************
  20. * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
  21. * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
  22. * AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
  23. * INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
  24. * CONTENT OF SUCH SOFTWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
  25. * INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
  26. * FOR MORE INFORMATION PLEASE CAREFULLY READ THE LICENSE AGREEMENT FILE LOCATED
  27. * IN THE ROOT DIRECTORY OF THIS FIRMWARE PACKAGE.
  28. *******************************************************************************/
  29. /* Includes ------------------------------------------------------------------*/
  30. #include "msd.h"
  31. /* Private typedef -----------------------------------------------------------*/
  32. /* Private define ------------------------------------------------------------*/
  33. /* Private macro -------------------------------------------------------------*/
  34. /* Select MSD Card: ChipSelect pin low */
  35. #define MSD_CS_LOW() GPIO_ResetBits(GPIOD, GPIO_Pin_9)
  36. /* Deselect MSD Card: ChipSelect pin high */
  37. #define MSD_CS_HIGH() GPIO_SetBits(GPIOD, GPIO_Pin_9)
  38. /* Private function prototypes -----------------------------------------------*/
  39. static void SPI_Config(void);
  40. /* Private functions ---------------------------------------------------------*/
  41. /*******************************************************************************
  42. * Function Name : MSD_Init
  43. * Description : Initializes the MSD/SD communication.
  44. * Input : None
  45. * Output : None
  46. * Return : The MSD Response: - MSD_RESPONSE_FAILURE: Sequence failed
  47. * - MSD_RESPONSE_NO_ERROR: Sequence succeed
  48. *******************************************************************************/
  49. u8 MSD_Init(void)
  50. {
  51. u32 i = 0;
  52. /* Initialize SPI1 */
  53. SPI_Config();
  54. /* MSD chip select high */
  55. MSD_CS_HIGH();
  56. /* Send dummy byte 0xFF, 10 times with CS high*/
  57. /* rise CS and MOSI for 80 clocks cycles */
  58. for (i = 0; i <= 9; i++)
  59. {
  60. /* Send dummy byte 0xFF */
  61. MSD_WriteByte(DUMMY);
  62. }
  63. /*------------Put MSD in SPI mode--------------*/
  64. /* MSD initialized and set to SPI mode properly */
  65. return (MSD_GoIdleState());
  66. }
  67. /*******************************************************************************
  68. * Function Name : MSD_WriteBlock
  69. * Description : Writes a block on the MSD
  70. * Input : - pBuffer : pointer to the buffer containing the data to be
  71. * written on the MSD.
  72. * - WriteAddr : address to write on.
  73. * - NumByteToWrite: number of data to write
  74. * Output : None
  75. * Return : The MSD Response: - MSD_RESPONSE_FAILURE: Sequence failed
  76. * - MSD_RESPONSE_NO_ERROR: Sequence succeed
  77. *******************************************************************************/
  78. u8 MSD_WriteBlock(u8* pBuffer, u32 WriteAddr, u16 NumByteToWrite)
  79. {
  80. u32 i = 0;
  81. u8 rvalue = MSD_RESPONSE_FAILURE;
  82. /* MSD chip select low */
  83. MSD_CS_LOW();
  84. /* Send CMD24 (MSD_WRITE_BLOCK) to write multiple block */
  85. MSD_SendCmd(MSD_WRITE_BLOCK, WriteAddr, 0xFF);
  86. /* Check if the MSD acknowledged the write block command: R1 response (0x00: no errors) */
  87. if (!MSD_GetResponse(MSD_RESPONSE_NO_ERROR))
  88. {
  89. /* Send a dummy byte */
  90. MSD_WriteByte(DUMMY);
  91. /* Send the data token to signify the start of the data */
  92. MSD_WriteByte(0xFE);
  93. /* Write the block data to MSD : write count data by block */
  94. for (i = 0; i < NumByteToWrite; i++)
  95. {
  96. /* Send the pointed byte */
  97. MSD_WriteByte(*pBuffer);
  98. /* Point to the next location where the byte read will be saved */
  99. pBuffer++;
  100. }
  101. /* Put CRC bytes (not really needed by us, but required by MSD) */
  102. MSD_ReadByte();
  103. MSD_ReadByte();
  104. /* Read data response */
  105. if (MSD_GetDataResponse() == MSD_DATA_OK)
  106. {
  107. rvalue = MSD_RESPONSE_NO_ERROR;
  108. }
  109. }
  110. /* MSD chip select high */
  111. MSD_CS_HIGH();
  112. /* Send dummy byte: 8 Clock pulses of delay */
  113. MSD_WriteByte(DUMMY);
  114. /* Returns the reponse */
  115. return rvalue;
  116. }
  117. /*******************************************************************************
  118. * Function Name : MSD_ReadBlock
  119. * Description : Reads a block of data from the MSD.
  120. * Input : - pBuffer : pointer to the buffer that receives the data read
  121. * from the MSD.
  122. * - ReadAddr : MSD's internal address to read from.
  123. * - NumByteToRead : number of bytes to read from the MSD.
  124. * Output : None
  125. * Return : The MSD Response: - MSD_RESPONSE_FAILURE: Sequence failed
  126. * - MSD_RESPONSE_NO_ERROR: Sequence succeed
  127. *******************************************************************************/
  128. u8 MSD_ReadBlock(u8* pBuffer, u32 ReadAddr, u16 NumByteToRead)
  129. {
  130. u32 i = 0;
  131. u8 rvalue = MSD_RESPONSE_FAILURE;
  132. /* MSD chip select low */
  133. MSD_CS_LOW();
  134. /* Send CMD17 (MSD_READ_SINGLE_BLOCK) to read one block */
  135. MSD_SendCmd(MSD_READ_SINGLE_BLOCK, ReadAddr, 0xFF);
  136. /* Check if the MSD acknowledged the read block command: R1 response (0x00: no errors) */
  137. if (!MSD_GetResponse(MSD_RESPONSE_NO_ERROR))
  138. {
  139. /* Now look for the data token to signify the start of the data */
  140. if (!MSD_GetResponse(MSD_START_DATA_SINGLE_BLOCK_READ))
  141. {
  142. /* Read the MSD block data : read NumByteToRead data */
  143. for (i = 0; i < NumByteToRead; i++)
  144. {
  145. /* Save the received data */
  146. *pBuffer = MSD_ReadByte();
  147. /* Point to the next location where the byte read will be saved */
  148. pBuffer++;
  149. }
  150. /* Get CRC bytes (not really needed by us, but required by MSD) */
  151. MSD_ReadByte();
  152. MSD_ReadByte();
  153. /* Set response value to success */
  154. rvalue = MSD_RESPONSE_NO_ERROR;
  155. }
  156. }
  157. /* MSD chip select high */
  158. MSD_CS_HIGH();
  159. /* Send dummy byte: 8 Clock pulses of delay */
  160. MSD_WriteByte(DUMMY);
  161. /* Returns the reponse */
  162. return rvalue;
  163. }
  164. /*******************************************************************************
  165. * Function Name : MSD_WriteBuffer
  166. * Description : Writes many blocks on the MSD
  167. * Input : - pBuffer : pointer to the buffer containing the data to be
  168. * written on the MSD.
  169. * - WriteAddr : address to write on.
  170. * - NumByteToWrite: number of data to write
  171. * Output : None
  172. * Return : The MSD Response: - MSD_RESPONSE_FAILURE: Sequence failed
  173. * - MSD_RESPONSE_NO_ERROR: Sequence succeed
  174. *******************************************************************************/
  175. u8 MSD_WriteBuffer(u8* pBuffer, u32 WriteAddr, u32 NumByteToWrite)
  176. {
  177. u32 i = 0, NbrOfBlock = 0, Offset = 0;
  178. u8 rvalue = MSD_RESPONSE_FAILURE;
  179. /* Calculate number of blocks to write */
  180. NbrOfBlock = NumByteToWrite / BLOCK_SIZE;
  181. /* MSD chip select low */
  182. MSD_CS_LOW();
  183. /* Data transfer */
  184. while (NbrOfBlock --)
  185. {
  186. /* Send CMD24 (MSD_WRITE_BLOCK) to write blocks */
  187. MSD_SendCmd(MSD_WRITE_BLOCK, WriteAddr + Offset, 0xFF);
  188. /* Check if the MSD acknowledged the write block command: R1 response (0x00: no errors) */
  189. if (MSD_GetResponse(MSD_RESPONSE_NO_ERROR))
  190. {
  191. return MSD_RESPONSE_FAILURE;
  192. }
  193. /* Send dummy byte */
  194. MSD_WriteByte(DUMMY);
  195. /* Send the data token to signify the start of the data */
  196. MSD_WriteByte(MSD_START_DATA_SINGLE_BLOCK_WRITE);
  197. /* Write the block data to MSD : write count data by block */
  198. for (i = 0; i < BLOCK_SIZE; i++)
  199. {
  200. /* Send the pointed byte */
  201. MSD_WriteByte(*pBuffer);
  202. /* Point to the next location where the byte read will be saved */
  203. pBuffer++;
  204. }
  205. /* Set next write address */
  206. Offset += 512;
  207. /* Put CRC bytes (not really needed by us, but required by MSD) */
  208. MSD_ReadByte();
  209. MSD_ReadByte();
  210. /* Read data response */
  211. if (MSD_GetDataResponse() == MSD_DATA_OK)
  212. {
  213. /* Set response value to success */
  214. rvalue = MSD_RESPONSE_NO_ERROR;
  215. }
  216. else
  217. {
  218. /* Set response value to failure */
  219. rvalue = MSD_RESPONSE_FAILURE;
  220. }
  221. }
  222. /* MSD chip select high */
  223. MSD_CS_HIGH();
  224. /* Send dummy byte: 8 Clock pulses of delay */
  225. MSD_WriteByte(DUMMY);
  226. /* Returns the reponse */
  227. return rvalue;
  228. }
  229. /*******************************************************************************
  230. * Function Name : MSD_ReadBuffer
  231. * Description : Reads multiple block of data from the MSD.
  232. * Input : - pBuffer : pointer to the buffer that receives the data read
  233. * from the MSD.
  234. * - ReadAddr : MSD's internal address to read from.
  235. * - NumByteToRead : number of bytes to read from the MSD.
  236. * Output : None
  237. * Return : The MSD Response: - MSD_RESPONSE_FAILURE: Sequence failed
  238. * - MSD_RESPONSE_NO_ERROR: Sequence succeed
  239. *******************************************************************************/
  240. u8 MSD_ReadBuffer(u8* pBuffer, u32 ReadAddr, u32 NumByteToRead)
  241. {
  242. u32 i = 0, NbrOfBlock = 0, Offset = 0;
  243. u8 rvalue = MSD_RESPONSE_FAILURE;
  244. /* Calculate number of blocks to read */
  245. NbrOfBlock = NumByteToRead / BLOCK_SIZE;
  246. /* MSD chip select low */
  247. MSD_CS_LOW();
  248. /* Data transfer */
  249. while (NbrOfBlock --)
  250. {
  251. /* Send CMD17 (MSD_READ_SINGLE_BLOCK) to read one block */
  252. MSD_SendCmd (MSD_READ_SINGLE_BLOCK, ReadAddr + Offset, 0xFF);
  253. /* Check if the MSD acknowledged the read block command: R1 response (0x00: no errors) */
  254. if (MSD_GetResponse(MSD_RESPONSE_NO_ERROR))
  255. {
  256. return MSD_RESPONSE_FAILURE;
  257. }
  258. /* Now look for the data token to signify the start of the data */
  259. if (!MSD_GetResponse(MSD_START_DATA_SINGLE_BLOCK_READ))
  260. {
  261. /* Read the MSD block data : read NumByteToRead data */
  262. for (i = 0; i < BLOCK_SIZE; i++)
  263. {
  264. /* Read the pointed data */
  265. *pBuffer = MSD_ReadByte();
  266. /* Point to the next location where the byte read will be saved */
  267. pBuffer++;
  268. }
  269. /* Set next read address*/
  270. Offset += 512;
  271. /* get CRC bytes (not really needed by us, but required by MSD) */
  272. MSD_ReadByte();
  273. MSD_ReadByte();
  274. /* Set response value to success */
  275. rvalue = MSD_RESPONSE_NO_ERROR;
  276. }
  277. else
  278. {
  279. /* Set response value to failure */
  280. rvalue = MSD_RESPONSE_FAILURE;
  281. }
  282. }
  283. /* MSD chip select high */
  284. MSD_CS_HIGH();
  285. /* Send dummy byte: 8 Clock pulses of delay */
  286. MSD_WriteByte(DUMMY);
  287. /* Returns the reponse */
  288. return rvalue;
  289. }
  290. /*******************************************************************************
  291. * Function Name : MSD_GetCSDRegister
  292. * Description : Read the CSD card register.
  293. * Reading the contents of the CSD register in SPI mode
  294. * is a simple read-block transaction.
  295. * Input : - MSD_csd: pointer on an SCD register structure
  296. * Output : None
  297. * Return : The MSD Response: - MSD_RESPONSE_FAILURE: Sequence failed
  298. * - MSD_RESPONSE_NO_ERROR: Sequence succeed
  299. *******************************************************************************/
  300. u8 MSD_GetCSDRegister(sMSD_CSD* MSD_csd)
  301. {
  302. u32 i = 0;
  303. u8 rvalue = MSD_RESPONSE_FAILURE;
  304. u8 CSD_Tab[16];
  305. /* MSD chip select low */
  306. MSD_CS_LOW();
  307. /* Send CMD9 (CSD register) or CMD10(CSD register) */
  308. MSD_SendCmd(MSD_SEND_CSD, 0, 0xFF);
  309. /* Wait for response in the R1 format (0x00 is no errors) */
  310. if (!MSD_GetResponse(MSD_RESPONSE_NO_ERROR))
  311. {
  312. if (!MSD_GetResponse(MSD_START_DATA_SINGLE_BLOCK_READ))
  313. {
  314. for (i = 0; i < 16; i++)
  315. {
  316. /* Store CSD register value on CSD_Tab */
  317. CSD_Tab[i] = MSD_ReadByte();
  318. }
  319. }
  320. /* Get CRC bytes (not really needed by us, but required by MSD) */
  321. MSD_WriteByte(DUMMY);
  322. MSD_WriteByte(DUMMY);
  323. /* Set response value to success */
  324. rvalue = MSD_RESPONSE_NO_ERROR;
  325. }
  326. /* MSD chip select high */
  327. MSD_CS_HIGH();
  328. /* Send dummy byte: 8 Clock pulses of delay */
  329. MSD_WriteByte(DUMMY);
  330. /* Byte 0 */
  331. MSD_csd->CSDStruct = (CSD_Tab[0] & 0xC0) >> 6;
  332. MSD_csd->SysSpecVersion = (CSD_Tab[0] & 0x3C) >> 2;
  333. MSD_csd->Reserved1 = CSD_Tab[0] & 0x03;
  334. /* Byte 1 */
  335. MSD_csd->TAAC = CSD_Tab[1] ;
  336. /* Byte 2 */
  337. MSD_csd->NSAC = CSD_Tab[2];
  338. /* Byte 3 */
  339. MSD_csd->MaxBusClkFrec = CSD_Tab[3];
  340. /* Byte 4 */
  341. MSD_csd->CardComdClasses = CSD_Tab[4] << 4;
  342. /* Byte 5 */
  343. MSD_csd->CardComdClasses |= (CSD_Tab[5] & 0xF0) >> 4;
  344. MSD_csd->RdBlockLen = CSD_Tab[5] & 0x0F;
  345. /* Byte 6 */
  346. MSD_csd->PartBlockRead = (CSD_Tab[6] & 0x80) >> 7;
  347. MSD_csd->WrBlockMisalign = (CSD_Tab[6] & 0x40) >> 6;
  348. MSD_csd->RdBlockMisalign = (CSD_Tab[6] & 0x20) >> 5;
  349. MSD_csd->DSRImpl = (CSD_Tab[6] & 0x10) >> 4;
  350. MSD_csd->Reserved2 = 0; /* Reserved */
  351. MSD_csd->DeviceSize = (CSD_Tab[6] & 0x03) << 10;
  352. /* Byte 7 */
  353. MSD_csd->DeviceSize |= (CSD_Tab[7]) << 2;
  354. /* Byte 8 */
  355. MSD_csd->DeviceSize |= (CSD_Tab[8] & 0xC0) >> 6;
  356. MSD_csd->MaxRdCurrentVDDMin = (CSD_Tab[8] & 0x38) >> 3;
  357. MSD_csd->MaxRdCurrentVDDMax = (CSD_Tab[8] & 0x07);
  358. /* Byte 9 */
  359. MSD_csd->MaxWrCurrentVDDMin = (CSD_Tab[9] & 0xE0) >> 5;
  360. MSD_csd->MaxWrCurrentVDDMax = (CSD_Tab[9] & 0x1C) >> 2;
  361. MSD_csd->DeviceSizeMul = (CSD_Tab[9] & 0x03) << 1;
  362. /* Byte 10 */
  363. MSD_csd->DeviceSizeMul |= (CSD_Tab[10] & 0x80) >> 7;
  364. MSD_csd->EraseGrSize = (CSD_Tab[10] & 0x7C) >> 2;
  365. MSD_csd->EraseGrMul = (CSD_Tab[10] & 0x03) << 3;
  366. /* Byte 11 */
  367. MSD_csd->EraseGrMul |= (CSD_Tab[11] & 0xE0) >> 5;
  368. MSD_csd->WrProtectGrSize = (CSD_Tab[11] & 0x1F);
  369. /* Byte 12 */
  370. MSD_csd->WrProtectGrEnable = (CSD_Tab[12] & 0x80) >> 7;
  371. MSD_csd->ManDeflECC = (CSD_Tab[12] & 0x60) >> 5;
  372. MSD_csd->WrSpeedFact = (CSD_Tab[12] & 0x1C) >> 2;
  373. MSD_csd->MaxWrBlockLen = (CSD_Tab[12] & 0x03) << 2;
  374. /* Byte 13 */
  375. MSD_csd->MaxWrBlockLen |= (CSD_Tab[13] & 0xc0) >> 6;
  376. MSD_csd->WriteBlockPaPartial = (CSD_Tab[13] & 0x20) >> 5;
  377. MSD_csd->Reserved3 = 0;
  378. MSD_csd->ContentProtectAppli = (CSD_Tab[13] & 0x01);
  379. /* Byte 14 */
  380. MSD_csd->FileFormatGrouop = (CSD_Tab[14] & 0x80) >> 7;
  381. MSD_csd->CopyFlag = (CSD_Tab[14] & 0x40) >> 6;
  382. MSD_csd->PermWrProtect = (CSD_Tab[14] & 0x20) >> 5;
  383. MSD_csd->TempWrProtect = (CSD_Tab[14] & 0x10) >> 4;
  384. MSD_csd->FileFormat = (CSD_Tab[14] & 0x0C) >> 2;
  385. MSD_csd->ECC = (CSD_Tab[14] & 0x03);
  386. /* Byte 15 */
  387. MSD_csd->msd_CRC = (CSD_Tab[15] & 0xFE) >> 1;
  388. MSD_csd->Reserved4 = 1;
  389. /* Return the reponse */
  390. return rvalue;
  391. }
  392. /*******************************************************************************
  393. * Function Name : MSD_GetCIDRegister
  394. * Description : Read the CID card register.
  395. * Reading the contents of the CID register in SPI mode
  396. * is a simple read-block transaction.
  397. * Input : - MSD_cid: pointer on an CID register structure
  398. * Output : None
  399. * Return : The MSD Response: - MSD_RESPONSE_FAILURE: Sequence failed
  400. * - MSD_RESPONSE_NO_ERROR: Sequence succeed
  401. *******************************************************************************/
  402. u8 MSD_GetCIDRegister(sMSD_CID* MSD_cid)
  403. {
  404. u32 i = 0;
  405. u8 rvalue = MSD_RESPONSE_FAILURE;
  406. u8 CID_Tab[16];
  407. /* MSD chip select low */
  408. MSD_CS_LOW();
  409. /* Send CMD10 (CID register) */
  410. MSD_SendCmd(MSD_SEND_CID, 0, 0xFF);
  411. /* Wait for response in the R1 format (0x00 is no errors) */
  412. if (!MSD_GetResponse(MSD_RESPONSE_NO_ERROR))
  413. {
  414. if (!MSD_GetResponse(MSD_START_DATA_SINGLE_BLOCK_READ))
  415. {
  416. /* Store CID register value on CID_Tab */
  417. for (i = 0; i < 16; i++)
  418. {
  419. CID_Tab[i] = MSD_ReadByte();
  420. }
  421. }
  422. /* Get CRC bytes (not really needed by us, but required by MSD) */
  423. MSD_WriteByte(DUMMY);
  424. MSD_WriteByte(DUMMY);
  425. /* Set response value to success */
  426. rvalue = MSD_RESPONSE_NO_ERROR;
  427. }
  428. /* MSD chip select high */
  429. MSD_CS_HIGH();
  430. /* Send dummy byte: 8 Clock pulses of delay */
  431. MSD_WriteByte(DUMMY);
  432. /* Byte 0 */
  433. MSD_cid->ManufacturerID = CID_Tab[0];
  434. /* Byte 1 */
  435. MSD_cid->OEM_AppliID = CID_Tab[1] << 8;
  436. /* Byte 2 */
  437. MSD_cid->OEM_AppliID |= CID_Tab[2];
  438. /* Byte 3 */
  439. MSD_cid->ProdName1 = CID_Tab[3] << 24;
  440. /* Byte 4 */
  441. MSD_cid->ProdName1 |= CID_Tab[4] << 16;
  442. /* Byte 5 */
  443. MSD_cid->ProdName1 |= CID_Tab[5] << 8;
  444. /* Byte 6 */
  445. MSD_cid->ProdName1 |= CID_Tab[6];
  446. /* Byte 7 */
  447. MSD_cid->ProdName2 = CID_Tab[7];
  448. /* Byte 8 */
  449. MSD_cid->ProdRev = CID_Tab[8];
  450. /* Byte 9 */
  451. MSD_cid->ProdSN = CID_Tab[9] << 24;
  452. /* Byte 10 */
  453. MSD_cid->ProdSN |= CID_Tab[10] << 16;
  454. /* Byte 11 */
  455. MSD_cid->ProdSN |= CID_Tab[11] << 8;
  456. /* Byte 12 */
  457. MSD_cid->ProdSN |= CID_Tab[12];
  458. /* Byte 13 */
  459. MSD_cid->Reserved1 |= (CID_Tab[13] & 0xF0) >> 4;
  460. /* Byte 14 */
  461. MSD_cid->ManufactDate = (CID_Tab[13] & 0x0F) << 8;
  462. /* Byte 15 */
  463. MSD_cid->ManufactDate |= CID_Tab[14];
  464. /* Byte 16 */
  465. MSD_cid->msd_CRC = (CID_Tab[15] & 0xFE) >> 1;
  466. MSD_cid->Reserved2 = 1;
  467. /* Return the reponse */
  468. return rvalue;
  469. }
  470. /*******************************************************************************
  471. * Function Name : MSD_SendCmd
  472. * Description : Send 5 bytes command to the MSD card.
  473. * Input : - Cmd: the user expected command to send to MSD card
  474. * - Arg: the command argument
  475. * - Crc: the CRC
  476. * Output : None
  477. * Return : None
  478. *******************************************************************************/
  479. void MSD_SendCmd(u8 Cmd, u32 Arg, u8 Crc)
  480. {
  481. u32 i = 0x00;
  482. u8 Frame[6];
  483. /* Construct byte1 */
  484. Frame[0] = (Cmd | 0x40);
  485. /* Construct byte2 */
  486. Frame[1] = (u8)(Arg >> 24);
  487. /* Construct byte3 */
  488. Frame[2] = (u8)(Arg >> 16);
  489. /* Construct byte4 */
  490. Frame[3] = (u8)(Arg >> 8);
  491. /* Construct byte5 */
  492. Frame[4] = (u8)(Arg);
  493. /* Construct CRC: byte6 */
  494. Frame[5] = (Crc);
  495. /* Send the Cmd bytes */
  496. for (i = 0; i < 6; i++)
  497. {
  498. MSD_WriteByte(Frame[i]);
  499. }
  500. }
  501. /*******************************************************************************
  502. * Function Name : MSD_GetDataResponse
  503. * Description : Get MSD card data response.
  504. * Input : None
  505. * Output : None
  506. * Return : The MSD status: Read data response xxx0<status>1
  507. * - status 010: Data accecpted
  508. * - status 101: Data rejected due to a crc error
  509. * - status 110: Data rejected due to a Write error.
  510. * - status 111: Data rejected due to other error.
  511. *******************************************************************************/
  512. u8 MSD_GetDataResponse(void)
  513. {
  514. u32 i = 0;
  515. u8 response, rvalue;
  516. while (i <= 64)
  517. {
  518. /* Read resonse */
  519. response = MSD_ReadByte();
  520. /* Mask unused bits */
  521. response &= 0x1F;
  522. switch (response)
  523. {
  524. case MSD_DATA_OK:
  525. {
  526. rvalue = MSD_DATA_OK;
  527. break;
  528. }
  529. case MSD_DATA_CRC_ERROR:
  530. return MSD_DATA_CRC_ERROR;
  531. case MSD_DATA_WRITE_ERROR:
  532. return MSD_DATA_WRITE_ERROR;
  533. default:
  534. {
  535. rvalue = MSD_DATA_OTHER_ERROR;
  536. break;
  537. }
  538. }
  539. /* Exit loop in case of data ok */
  540. if (rvalue == MSD_DATA_OK)
  541. break;
  542. /* Increment loop counter */
  543. i++;
  544. }
  545. /* Wait null data */
  546. while (MSD_ReadByte() == 0);
  547. /* Return response */
  548. return response;
  549. }
  550. /*******************************************************************************
  551. * Function Name : MSD_GetResponse
  552. * Description : Returns the MSD response.
  553. * Input : None
  554. * Output : None
  555. * Return : The MSD Response: - MSD_RESPONSE_FAILURE: Sequence failed
  556. * - MSD_RESPONSE_NO_ERROR: Sequence succeed
  557. *******************************************************************************/
  558. u8 MSD_GetResponse(u8 Response)
  559. {
  560. u32 Count = 0xFFF;
  561. /* Check if response is got or a timeout is happen */
  562. while ((MSD_ReadByte() != Response) && Count)
  563. {
  564. Count--;
  565. }
  566. if (Count == 0)
  567. {
  568. /* After time out */
  569. return MSD_RESPONSE_FAILURE;
  570. }
  571. else
  572. {
  573. /* Right response got */
  574. return MSD_RESPONSE_NO_ERROR;
  575. }
  576. }
  577. /*******************************************************************************
  578. * Function Name : MSD_GetStatus
  579. * Description : Returns the MSD status.
  580. * Input : None
  581. * Output : None
  582. * Return : The MSD status.
  583. *******************************************************************************/
  584. u16 MSD_GetStatus(void)
  585. {
  586. u16 Status = 0;
  587. /* MSD chip select low */
  588. MSD_CS_LOW();
  589. /* Send CMD13 (MSD_SEND_STATUS) to get MSD status */
  590. MSD_SendCmd(MSD_SEND_STATUS, 0, 0xFF);
  591. Status = MSD_ReadByte();
  592. Status |= (u16)(MSD_ReadByte() << 8);
  593. /* MSD chip select high */
  594. MSD_CS_HIGH();
  595. /* Send dummy byte 0xFF */
  596. MSD_WriteByte(DUMMY);
  597. return Status;
  598. }
  599. /*******************************************************************************
  600. * Function Name : MSD_GoIdleState
  601. * Description : Put MSD in Idle state.
  602. * Input : None
  603. * Output : None
  604. * Return : The MSD Response: - MSD_RESPONSE_FAILURE: Sequence failed
  605. * - MSD_RESPONSE_NO_ERROR: Sequence succeed
  606. *******************************************************************************/
  607. u8 MSD_GoIdleState(void)
  608. {
  609. /* MSD chip select low */
  610. MSD_CS_LOW();
  611. /* Send CMD0 (GO_IDLE_STATE) to put MSD in SPI mode */
  612. MSD_SendCmd(MSD_GO_IDLE_STATE, 0, 0x95);
  613. /* Wait for In Idle State Response (R1 Format) equal to 0x01 */
  614. if (MSD_GetResponse(MSD_IN_IDLE_STATE))
  615. {
  616. /* No Idle State Response: return response failue */
  617. return MSD_RESPONSE_FAILURE;
  618. }
  619. /*----------Activates the card initialization process-----------*/
  620. do
  621. {
  622. /* MSD chip select high */
  623. MSD_CS_HIGH();
  624. /* Send Dummy byte 0xFF */
  625. MSD_WriteByte(DUMMY);
  626. /* MSD chip select low */
  627. MSD_CS_LOW();
  628. /* Send CMD1 (Activates the card process) until response equal to 0x0 */
  629. MSD_SendCmd(MSD_SEND_OP_COND, 0, 0xFF);
  630. /* Wait for no error Response (R1 Format) equal to 0x00 */
  631. }
  632. while (MSD_GetResponse(MSD_RESPONSE_NO_ERROR));
  633. /* MSD chip select high */
  634. MSD_CS_HIGH();
  635. /* Send dummy byte 0xFF */
  636. MSD_WriteByte(DUMMY);
  637. return MSD_RESPONSE_NO_ERROR;
  638. }
  639. /*******************************************************************************
  640. * Function Name : MSD_WriteByte
  641. * Description : Write a byte on the MSD.
  642. * Input : Data: byte to send.
  643. * Output : None
  644. * Return : None.
  645. *******************************************************************************/
  646. void MSD_WriteByte(u8 Data)
  647. {
  648. /* Wait until the transmit buffer is empty */
  649. while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);
  650. /* Send the byte */
  651. SPI_I2S_SendData(SPI1, Data);
  652. }
  653. /*******************************************************************************
  654. * Function Name : MSD_ReadByte
  655. * Description : Read a byte from the MSD.
  656. * Input : None.
  657. * Output : None
  658. * Return : The received byte.
  659. *******************************************************************************/
  660. u8 MSD_ReadByte(void)
  661. {
  662. u8 Data = 0;
  663. /* Wait until the transmit buffer is empty */
  664. while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);
  665. /* Send the byte */
  666. SPI_I2S_SendData(SPI1, DUMMY);
  667. /* Wait until a data is received */
  668. while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);
  669. /* Get the received data */
  670. Data = SPI_I2S_ReceiveData(SPI1);
  671. /* Return the shifted data */
  672. return Data;
  673. }
  674. /*******************************************************************************
  675. * Function Name : SPI_Config
  676. * Description : Initializes the SPI1 and CS pins.
  677. * Input : None
  678. * Output : None
  679. * Return : None
  680. *******************************************************************************/
  681. void SPI_Config(void)
  682. {
  683. u16 i, j;
  684. GPIO_InitTypeDef GPIO_InitStructure;
  685. SPI_InitTypeDef SPI_InitStructure;
  686. /* GPIOA and GPIOC Periph clock enable */
  687. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOD, ENABLE);
  688. /* SPI1 Periph clock enable */
  689. RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
  690. /* Configure SPI1 pins: SCK, MISO and MOSI */
  691. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
  692. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  693. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  694. GPIO_Init(GPIOA, &GPIO_InitStructure);
  695. /* Configure PD9 pin: CS pin ,PD10 : SD Power */
  696. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9|GPIO_Pin_10;
  697. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  698. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  699. GPIO_Init(GPIOD, &GPIO_InitStructure);
  700. /* SPI1 Config */
  701. SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
  702. SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
  703. SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
  704. SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
  705. SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
  706. SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
  707. SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;
  708. SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
  709. SPI_InitStructure.SPI_CRCPolynomial = 7;
  710. SPI_Init(SPI1, &SPI_InitStructure);
  711. /* SPI1 enable */
  712. SPI_Cmd(SPI1, ENABLE);
  713. /* active SD card */
  714. GPIO_ResetBits(GPIOD, GPIO_Pin_10);
  715. for(i=0;i<65530;i++)
  716. {
  717. for(j=0;j<5000;j++)
  718. ;
  719. }
  720. }
  721. /******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/
  722. /*
  723. * RT-Thread SD Card Driver
  724. * 20090417 Bernard
  725. */
  726. #include <rtthread.h>
  727. #include <dfs_fs.h>
  728. struct rt_device sdcard_device;
  729. struct dfs_partition part;
  730. #define SECTOR_SIZE 512
  731. /* RT-Thread Device Driver Interface */
  732. static rt_err_t rt_sdcard_init(rt_device_t dev)
  733. {
  734. sMSD_CSD MSD_csd;
  735. MSD_GetCSDRegister(&MSD_csd);
  736. return RT_EOK;
  737. }
  738. static rt_err_t rt_sdcard_open(rt_device_t dev, rt_uint16_t oflag)
  739. {
  740. return RT_EOK;
  741. }
  742. static rt_err_t rt_sdcard_close(rt_device_t dev)
  743. {
  744. return RT_EOK;
  745. }
  746. static rt_size_t rt_sdcard_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
  747. {
  748. rt_uint8_t status;
  749. rt_uint32_t i;
  750. status = MSD_RESPONSE_NO_ERROR;
  751. rt_kprintf("read: 0x%x, size %d\n", pos, size);
  752. /* read all sectors */
  753. for (i = 0; i < size / SECTOR_SIZE; i ++)
  754. {
  755. status = MSD_ReadBlock((rt_uint8_t*)((rt_uint8_t*)buffer + i * SECTOR_SIZE),
  756. (part.offset + i)* SECTOR_SIZE + pos,
  757. SECTOR_SIZE);
  758. if (status != MSD_RESPONSE_NO_ERROR)
  759. {
  760. rt_kprintf("sd card read failed\n");
  761. return 0;
  762. }
  763. }
  764. if (status == MSD_RESPONSE_NO_ERROR) return size;
  765. rt_kprintf("read failed: %d\n", status);
  766. return 0;
  767. }
  768. static rt_size_t rt_sdcard_write (rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size)
  769. {
  770. rt_uint8_t status;
  771. rt_uint32_t i;
  772. status = MSD_RESPONSE_NO_ERROR;
  773. rt_kprintf("write: 0x%x, size %d\n", pos, size);
  774. /* read all sectors */
  775. for (i = 0; i < size / SECTOR_SIZE; i ++)
  776. {
  777. status = MSD_WriteBuffer((rt_uint8_t*)((rt_uint8_t*)buffer + i * SECTOR_SIZE),
  778. (part.offset + i)* SECTOR_SIZE + pos,
  779. SECTOR_SIZE);
  780. if (status != MSD_RESPONSE_NO_ERROR)
  781. {
  782. rt_kprintf("sd card write failed\n");
  783. return 0;
  784. }
  785. }
  786. if (status == MSD_RESPONSE_NO_ERROR) return size;
  787. rt_kprintf("write failed: %d\n", status);
  788. return 0;
  789. }
  790. static rt_err_t rt_sdcard_control(rt_device_t dev, rt_uint8_t cmd, void *args)
  791. {
  792. return RT_EOK;
  793. }
  794. void rt_hw_sdcard_init()
  795. {
  796. if (MSD_Init() == MSD_RESPONSE_NO_ERROR)
  797. {
  798. rt_uint8_t status;
  799. rt_uint8_t *sector;
  800. /* register sdcard device */
  801. sdcard_device.init = rt_sdcard_init;
  802. sdcard_device.open = rt_sdcard_open;
  803. sdcard_device.close = rt_sdcard_close;
  804. sdcard_device.read = rt_sdcard_read;
  805. sdcard_device.write = rt_sdcard_write;
  806. sdcard_device.control = rt_sdcard_control;
  807. /* no private */
  808. sdcard_device.private = RT_NULL;
  809. /* get the first sector to read partition table */
  810. sector = (rt_uint8_t*) rt_malloc (512);
  811. if (sector == RT_NULL)
  812. {
  813. rt_kprintf("allocate partition sector buffer failed\n");
  814. return;
  815. }
  816. status = MSD_ReadBlock(sector, 0, 512);
  817. if (status == MSD_RESPONSE_NO_ERROR)
  818. {
  819. /* get the first partition */
  820. status = dfs_filesystem_get_partition(&part, sector, 0);
  821. if (status != RT_EOK)
  822. {
  823. /* there is no partition table */
  824. part.offset = 0;
  825. part.size = 0;
  826. }
  827. }
  828. else
  829. {
  830. /* there is no partition table */
  831. part.offset = 0;
  832. part.size = 0;
  833. }
  834. /* release sector buffer */
  835. rt_free(sector);
  836. rt_device_register(&sdcard_device, "sd0",
  837. RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_REMOVABLE | RT_DEVICE_FLAG_STANDALONE);
  838. }
  839. else
  840. {
  841. rt_kprintf("sdcard init failed\n");
  842. }
  843. }