msd.c 30 KB

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