msd.c 29 KB

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