comparison libs/STM32F10x_StdPeriph_Lib_V3.5.0/Utilities/STM32_EVAL/Common/stm32_eval_spi_sd.c @ 0:c59513fd84fb

Initial commit of STM32 test code.
author Daniel O'Connor <darius@dons.net.au>
date Mon, 03 Oct 2011 21:19:15 +1030
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:c59513fd84fb
1 /**
2 ******************************************************************************
3 * @file stm32_eval_spi_sd.c
4 * @author MCD Application Team
5 * @version V4.5.0
6 * @date 07-March-2011
7 * @brief This file provides a set of functions needed to manage the SPI SD
8 * Card memory mounted on STM32xx-EVAL board (refer to stm32_eval.h
9 * to know about the boards supporting this memory).
10 * It implements a high level communication layer for read and write
11 * from/to this memory. The needed STM32 hardware resources (SPI and
12 * GPIO) are defined in stm32xx_eval.h file, and the initialization is
13 * performed in SD_LowLevel_Init() function declared in stm32xx_eval.c
14 * file.
15 * You can easily tailor this driver to any other development board,
16 * by just adapting the defines for hardware resources and
17 * SD_LowLevel_Init() function.
18 *
19 * +-------------------------------------------------------+
20 * | Pin assignment |
21 * +-------------------------+---------------+-------------+
22 * | STM32 SPI Pins | SD | Pin |
23 * +-------------------------+---------------+-------------+
24 * | SD_SPI_CS_PIN | ChipSelect | 1 |
25 * | SD_SPI_MOSI_PIN / MOSI | DataIn | 2 |
26 * | | GND | 3 (0 V) |
27 * | | VDD | 4 (3.3 V)|
28 * | SD_SPI_SCK_PIN / SCLK | Clock | 5 |
29 * | | GND | 6 (0 V) |
30 * | SD_SPI_MISO_PIN / MISO | DataOut | 7 |
31 * +-------------------------+---------------+-------------+
32 ******************************************************************************
33 * @attention
34 *
35 * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
36 * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
37 * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
38 * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
39 * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
40 * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
41 *
42 * <h2><center>&copy; COPYRIGHT 2011 STMicroelectronics</center></h2>
43 ******************************************************************************
44 */
45
46 /* Includes ------------------------------------------------------------------*/
47 #include "stm32_eval_spi_sd.h"
48
49 /** @addtogroup Utilities
50 * @{
51 */
52
53 /** @addtogroup STM32_EVAL
54 * @{
55 */
56
57 /** @addtogroup Common
58 * @{
59 */
60
61 /** @addtogroup STM32_EVAL_SPI_SD
62 * @brief This file includes the SD card driver of STM32-EVAL boards.
63 * @{
64 */
65
66 /** @defgroup STM32_EVAL_SPI_SD_Private_Types
67 * @{
68 */
69 /**
70 * @}
71 */
72
73
74 /** @defgroup STM32_EVAL_SPI_SD_Private_Defines
75 * @{
76 */
77 /**
78 * @}
79 */
80
81 /** @defgroup STM32_EVAL_SPI_SD_Private_Macros
82 * @{
83 */
84 /**
85 * @}
86 */
87
88
89 /** @defgroup STM32_EVAL_SPI_SD_Private_Variables
90 * @{
91 */
92 /**
93 * @}
94 */
95
96
97 /** @defgroup STM32_EVAL_SPI_SD_Private_Function_Prototypes
98 * @{
99 */
100 /**
101 * @}
102 */
103
104
105 /** @defgroup STM32_EVAL_SPI_SD_Private_Functions
106 * @{
107 */
108
109 /**
110 * @brief DeInitializes the SD/SD communication.
111 * @param None
112 * @retval None
113 */
114 void SD_DeInit(void)
115 {
116 SD_LowLevel_DeInit();
117 }
118
119 /**
120 * @brief Initializes the SD/SD communication.
121 * @param None
122 * @retval The SD Response:
123 * - SD_RESPONSE_FAILURE: Sequence failed
124 * - SD_RESPONSE_NO_ERROR: Sequence succeed
125 */
126 SD_Error SD_Init(void)
127 {
128 uint32_t i = 0;
129
130 /*!< Initialize SD_SPI */
131 SD_LowLevel_Init();
132
133 /*!< SD chip select high */
134 SD_CS_HIGH();
135
136 /*!< Send dummy byte 0xFF, 10 times with CS high */
137 /*!< Rise CS and MOSI for 80 clocks cycles */
138 for (i = 0; i <= 9; i++)
139 {
140 /*!< Send dummy byte 0xFF */
141 SD_WriteByte(SD_DUMMY_BYTE);
142 }
143 /*------------Put SD in SPI mode--------------*/
144 /*!< SD initialized and set to SPI mode properly */
145 return (SD_GoIdleState());
146 }
147
148 /**
149 * @brief Detect if SD card is correctly plugged in the memory slot.
150 * @param None
151 * @retval Return if SD is detected or not
152 */
153 uint8_t SD_Detect(void)
154 {
155 __IO uint8_t status = SD_PRESENT;
156
157 /*!< Check GPIO to detect SD */
158 if (GPIO_ReadInputData(SD_DETECT_GPIO_PORT) & SD_DETECT_PIN)
159 {
160 status = SD_NOT_PRESENT;
161 }
162 return status;
163 }
164
165 /**
166 * @brief Returns information about specific card.
167 * @param cardinfo: pointer to a SD_CardInfo structure that contains all SD
168 * card information.
169 * @retval The SD Response:
170 * - SD_RESPONSE_FAILURE: Sequence failed
171 * - SD_RESPONSE_NO_ERROR: Sequence succeed
172 */
173 SD_Error SD_GetCardInfo(SD_CardInfo *cardinfo)
174 {
175 SD_Error status = SD_RESPONSE_FAILURE;
176
177 status = SD_GetCSDRegister(&(cardinfo->SD_csd));
178 status = SD_GetCIDRegister(&(cardinfo->SD_cid));
179 cardinfo->CardCapacity = (cardinfo->SD_csd.DeviceSize + 1) ;
180 cardinfo->CardCapacity *= (1 << (cardinfo->SD_csd.DeviceSizeMul + 2));
181 cardinfo->CardBlockSize = 1 << (cardinfo->SD_csd.RdBlockLen);
182 cardinfo->CardCapacity *= cardinfo->CardBlockSize;
183
184 /*!< Returns the reponse */
185 return status;
186 }
187
188 /**
189 * @brief Reads a block of data from the SD.
190 * @param pBuffer: pointer to the buffer that receives the data read from the
191 * SD.
192 * @param ReadAddr: SD's internal address to read from.
193 * @param BlockSize: the SD card Data block size.
194 * @retval The SD Response:
195 * - SD_RESPONSE_FAILURE: Sequence failed
196 * - SD_RESPONSE_NO_ERROR: Sequence succeed
197 */
198 SD_Error SD_ReadBlock(uint8_t* pBuffer, uint32_t ReadAddr, uint16_t BlockSize)
199 {
200 uint32_t i = 0;
201 SD_Error rvalue = SD_RESPONSE_FAILURE;
202
203 /*!< SD chip select low */
204 SD_CS_LOW();
205
206 /*!< Send CMD17 (SD_CMD_READ_SINGLE_BLOCK) to read one block */
207 SD_SendCmd(SD_CMD_READ_SINGLE_BLOCK, ReadAddr, 0xFF);
208
209 /*!< Check if the SD acknowledged the read block command: R1 response (0x00: no errors) */
210 if (!SD_GetResponse(SD_RESPONSE_NO_ERROR))
211 {
212 /*!< Now look for the data token to signify the start of the data */
213 if (!SD_GetResponse(SD_START_DATA_SINGLE_BLOCK_READ))
214 {
215 /*!< Read the SD block data : read NumByteToRead data */
216 for (i = 0; i < BlockSize; i++)
217 {
218 /*!< Save the received data */
219 *pBuffer = SD_ReadByte();
220
221 /*!< Point to the next location where the byte read will be saved */
222 pBuffer++;
223 }
224 /*!< Get CRC bytes (not really needed by us, but required by SD) */
225 SD_ReadByte();
226 SD_ReadByte();
227 /*!< Set response value to success */
228 rvalue = SD_RESPONSE_NO_ERROR;
229 }
230 }
231 /*!< SD chip select high */
232 SD_CS_HIGH();
233
234 /*!< Send dummy byte: 8 Clock pulses of delay */
235 SD_WriteByte(SD_DUMMY_BYTE);
236
237 /*!< Returns the reponse */
238 return rvalue;
239 }
240
241 /**
242 * @brief Reads multiple block of data from the SD.
243 * @param pBuffer: pointer to the buffer that receives the data read from the
244 * SD.
245 * @param ReadAddr: SD's internal address to read from.
246 * @param BlockSize: the SD card Data block size.
247 * @param NumberOfBlocks: number of blocks to be read.
248 * @retval The SD Response:
249 * - SD_RESPONSE_FAILURE: Sequence failed
250 * - SD_RESPONSE_NO_ERROR: Sequence succeed
251 */
252 SD_Error SD_ReadMultiBlocks(uint8_t* pBuffer, uint32_t ReadAddr, uint16_t BlockSize, uint32_t NumberOfBlocks)
253 {
254 uint32_t i = 0, Offset = 0;
255 SD_Error rvalue = SD_RESPONSE_FAILURE;
256
257 /*!< SD chip select low */
258 SD_CS_LOW();
259 /*!< Data transfer */
260 while (NumberOfBlocks--)
261 {
262 /*!< Send CMD17 (SD_CMD_READ_SINGLE_BLOCK) to read one block */
263 SD_SendCmd (SD_CMD_READ_SINGLE_BLOCK, ReadAddr + Offset, 0xFF);
264 /*!< Check if the SD acknowledged the read block command: R1 response (0x00: no errors) */
265 if (SD_GetResponse(SD_RESPONSE_NO_ERROR))
266 {
267 return SD_RESPONSE_FAILURE;
268 }
269 /*!< Now look for the data token to signify the start of the data */
270 if (!SD_GetResponse(SD_START_DATA_SINGLE_BLOCK_READ))
271 {
272 /*!< Read the SD block data : read NumByteToRead data */
273 for (i = 0; i < BlockSize; i++)
274 {
275 /*!< Read the pointed data */
276 *pBuffer = SD_ReadByte();
277 /*!< Point to the next location where the byte read will be saved */
278 pBuffer++;
279 }
280 /*!< Set next read address*/
281 Offset += 512;
282 /*!< get CRC bytes (not really needed by us, but required by SD) */
283 SD_ReadByte();
284 SD_ReadByte();
285 /*!< Set response value to success */
286 rvalue = SD_RESPONSE_NO_ERROR;
287 }
288 else
289 {
290 /*!< Set response value to failure */
291 rvalue = SD_RESPONSE_FAILURE;
292 }
293 }
294 /*!< SD chip select high */
295 SD_CS_HIGH();
296 /*!< Send dummy byte: 8 Clock pulses of delay */
297 SD_WriteByte(SD_DUMMY_BYTE);
298 /*!< Returns the reponse */
299 return rvalue;
300 }
301
302 /**
303 * @brief Writes a block on the SD
304 * @param pBuffer: pointer to the buffer containing the data to be written on
305 * the SD.
306 * @param WriteAddr: address to write on.
307 * @param BlockSize: the SD card Data block size.
308 * @retval The SD Response:
309 * - SD_RESPONSE_FAILURE: Sequence failed
310 * - SD_RESPONSE_NO_ERROR: Sequence succeed
311 */
312 SD_Error SD_WriteBlock(uint8_t* pBuffer, uint32_t WriteAddr, uint16_t BlockSize)
313 {
314 uint32_t i = 0;
315 SD_Error rvalue = SD_RESPONSE_FAILURE;
316
317 /*!< SD chip select low */
318 SD_CS_LOW();
319
320 /*!< Send CMD24 (SD_CMD_WRITE_SINGLE_BLOCK) to write multiple block */
321 SD_SendCmd(SD_CMD_WRITE_SINGLE_BLOCK, WriteAddr, 0xFF);
322
323 /*!< Check if the SD acknowledged the write block command: R1 response (0x00: no errors) */
324 if (!SD_GetResponse(SD_RESPONSE_NO_ERROR))
325 {
326 /*!< Send a dummy byte */
327 SD_WriteByte(SD_DUMMY_BYTE);
328
329 /*!< Send the data token to signify the start of the data */
330 SD_WriteByte(0xFE);
331
332 /*!< Write the block data to SD : write count data by block */
333 for (i = 0; i < BlockSize; i++)
334 {
335 /*!< Send the pointed byte */
336 SD_WriteByte(*pBuffer);
337 /*!< Point to the next location where the byte read will be saved */
338 pBuffer++;
339 }
340 /*!< Put CRC bytes (not really needed by us, but required by SD) */
341 SD_ReadByte();
342 SD_ReadByte();
343
344 /*!< Read data response */
345 if (SD_GetDataResponse() == SD_DATA_OK)
346 {
347 rvalue = SD_RESPONSE_NO_ERROR;
348 }
349 }
350 /*!< SD chip select high */
351 SD_CS_HIGH();
352 /*!< Send dummy byte: 8 Clock pulses of delay */
353 SD_WriteByte(SD_DUMMY_BYTE);
354
355 /*!< Returns the reponse */
356 return rvalue;
357 }
358
359 /**
360 * @brief Writes many blocks on the SD
361 * @param pBuffer: pointer to the buffer containing the data to be written on
362 * the SD.
363 * @param WriteAddr: address to write on.
364 * @param BlockSize: the SD card Data block size.
365 * @param NumberOfBlocks: number of blocks to be written.
366 * @retval The SD Response:
367 * - SD_RESPONSE_FAILURE: Sequence failed
368 * - SD_RESPONSE_NO_ERROR: Sequence succeed
369 */
370 SD_Error SD_WriteMultiBlocks(uint8_t* pBuffer, uint32_t WriteAddr, uint16_t BlockSize, uint32_t NumberOfBlocks)
371 {
372 uint32_t i = 0, Offset = 0;
373 SD_Error rvalue = SD_RESPONSE_FAILURE;
374
375 /*!< SD chip select low */
376 SD_CS_LOW();
377 /*!< Data transfer */
378 while (NumberOfBlocks--)
379 {
380 /*!< Send CMD24 (SD_CMD_WRITE_SINGLE_BLOCK) to write blocks */
381 SD_SendCmd(SD_CMD_WRITE_SINGLE_BLOCK, WriteAddr + Offset, 0xFF);
382 /*!< Check if the SD acknowledged the write block command: R1 response (0x00: no errors) */
383 if (SD_GetResponse(SD_RESPONSE_NO_ERROR))
384 {
385 return SD_RESPONSE_FAILURE;
386 }
387 /*!< Send dummy byte */
388 SD_WriteByte(SD_DUMMY_BYTE);
389 /*!< Send the data token to signify the start of the data */
390 SD_WriteByte(SD_START_DATA_SINGLE_BLOCK_WRITE);
391 /*!< Write the block data to SD : write count data by block */
392 for (i = 0; i < BlockSize; i++)
393 {
394 /*!< Send the pointed byte */
395 SD_WriteByte(*pBuffer);
396 /*!< Point to the next location where the byte read will be saved */
397 pBuffer++;
398 }
399 /*!< Set next write address */
400 Offset += 512;
401 /*!< Put CRC bytes (not really needed by us, but required by SD) */
402 SD_ReadByte();
403 SD_ReadByte();
404 /*!< Read data response */
405 if (SD_GetDataResponse() == SD_DATA_OK)
406 {
407 /*!< Set response value to success */
408 rvalue = SD_RESPONSE_NO_ERROR;
409 }
410 else
411 {
412 /*!< Set response value to failure */
413 rvalue = SD_RESPONSE_FAILURE;
414 }
415 }
416 /*!< SD chip select high */
417 SD_CS_HIGH();
418 /*!< Send dummy byte: 8 Clock pulses of delay */
419 SD_WriteByte(SD_DUMMY_BYTE);
420 /*!< Returns the reponse */
421 return rvalue;
422 }
423
424 /**
425 * @brief Read the CSD card register.
426 * Reading the contents of the CSD register in SPI mode is a simple
427 * read-block transaction.
428 * @param SD_csd: pointer on an SCD register structure
429 * @retval The SD Response:
430 * - SD_RESPONSE_FAILURE: Sequence failed
431 * - SD_RESPONSE_NO_ERROR: Sequence succeed
432 */
433 SD_Error SD_GetCSDRegister(SD_CSD* SD_csd)
434 {
435 uint32_t i = 0;
436 SD_Error rvalue = SD_RESPONSE_FAILURE;
437 uint8_t CSD_Tab[16];
438
439 /*!< SD chip select low */
440 SD_CS_LOW();
441 /*!< Send CMD9 (CSD register) or CMD10(CSD register) */
442 SD_SendCmd(SD_CMD_SEND_CSD, 0, 0xFF);
443 /*!< Wait for response in the R1 format (0x00 is no errors) */
444 if (!SD_GetResponse(SD_RESPONSE_NO_ERROR))
445 {
446 if (!SD_GetResponse(SD_START_DATA_SINGLE_BLOCK_READ))
447 {
448 for (i = 0; i < 16; i++)
449 {
450 /*!< Store CSD register value on CSD_Tab */
451 CSD_Tab[i] = SD_ReadByte();
452 }
453 }
454 /*!< Get CRC bytes (not really needed by us, but required by SD) */
455 SD_WriteByte(SD_DUMMY_BYTE);
456 SD_WriteByte(SD_DUMMY_BYTE);
457 /*!< Set response value to success */
458 rvalue = SD_RESPONSE_NO_ERROR;
459 }
460 /*!< SD chip select high */
461 SD_CS_HIGH();
462 /*!< Send dummy byte: 8 Clock pulses of delay */
463 SD_WriteByte(SD_DUMMY_BYTE);
464
465 /*!< Byte 0 */
466 SD_csd->CSDStruct = (CSD_Tab[0] & 0xC0) >> 6;
467 SD_csd->SysSpecVersion = (CSD_Tab[0] & 0x3C) >> 2;
468 SD_csd->Reserved1 = CSD_Tab[0] & 0x03;
469
470 /*!< Byte 1 */
471 SD_csd->TAAC = CSD_Tab[1];
472
473 /*!< Byte 2 */
474 SD_csd->NSAC = CSD_Tab[2];
475
476 /*!< Byte 3 */
477 SD_csd->MaxBusClkFrec = CSD_Tab[3];
478
479 /*!< Byte 4 */
480 SD_csd->CardComdClasses = CSD_Tab[4] << 4;
481
482 /*!< Byte 5 */
483 SD_csd->CardComdClasses |= (CSD_Tab[5] & 0xF0) >> 4;
484 SD_csd->RdBlockLen = CSD_Tab[5] & 0x0F;
485
486 /*!< Byte 6 */
487 SD_csd->PartBlockRead = (CSD_Tab[6] & 0x80) >> 7;
488 SD_csd->WrBlockMisalign = (CSD_Tab[6] & 0x40) >> 6;
489 SD_csd->RdBlockMisalign = (CSD_Tab[6] & 0x20) >> 5;
490 SD_csd->DSRImpl = (CSD_Tab[6] & 0x10) >> 4;
491 SD_csd->Reserved2 = 0; /*!< Reserved */
492
493 SD_csd->DeviceSize = (CSD_Tab[6] & 0x03) << 10;
494
495 /*!< Byte 7 */
496 SD_csd->DeviceSize |= (CSD_Tab[7]) << 2;
497
498 /*!< Byte 8 */
499 SD_csd->DeviceSize |= (CSD_Tab[8] & 0xC0) >> 6;
500
501 SD_csd->MaxRdCurrentVDDMin = (CSD_Tab[8] & 0x38) >> 3;
502 SD_csd->MaxRdCurrentVDDMax = (CSD_Tab[8] & 0x07);
503
504 /*!< Byte 9 */
505 SD_csd->MaxWrCurrentVDDMin = (CSD_Tab[9] & 0xE0) >> 5;
506 SD_csd->MaxWrCurrentVDDMax = (CSD_Tab[9] & 0x1C) >> 2;
507 SD_csd->DeviceSizeMul = (CSD_Tab[9] & 0x03) << 1;
508 /*!< Byte 10 */
509 SD_csd->DeviceSizeMul |= (CSD_Tab[10] & 0x80) >> 7;
510
511 SD_csd->EraseGrSize = (CSD_Tab[10] & 0x40) >> 6;
512 SD_csd->EraseGrMul = (CSD_Tab[10] & 0x3F) << 1;
513
514 /*!< Byte 11 */
515 SD_csd->EraseGrMul |= (CSD_Tab[11] & 0x80) >> 7;
516 SD_csd->WrProtectGrSize = (CSD_Tab[11] & 0x7F);
517
518 /*!< Byte 12 */
519 SD_csd->WrProtectGrEnable = (CSD_Tab[12] & 0x80) >> 7;
520 SD_csd->ManDeflECC = (CSD_Tab[12] & 0x60) >> 5;
521 SD_csd->WrSpeedFact = (CSD_Tab[12] & 0x1C) >> 2;
522 SD_csd->MaxWrBlockLen = (CSD_Tab[12] & 0x03) << 2;
523
524 /*!< Byte 13 */
525 SD_csd->MaxWrBlockLen |= (CSD_Tab[13] & 0xC0) >> 6;
526 SD_csd->WriteBlockPaPartial = (CSD_Tab[13] & 0x20) >> 5;
527 SD_csd->Reserved3 = 0;
528 SD_csd->ContentProtectAppli = (CSD_Tab[13] & 0x01);
529
530 /*!< Byte 14 */
531 SD_csd->FileFormatGrouop = (CSD_Tab[14] & 0x80) >> 7;
532 SD_csd->CopyFlag = (CSD_Tab[14] & 0x40) >> 6;
533 SD_csd->PermWrProtect = (CSD_Tab[14] & 0x20) >> 5;
534 SD_csd->TempWrProtect = (CSD_Tab[14] & 0x10) >> 4;
535 SD_csd->FileFormat = (CSD_Tab[14] & 0x0C) >> 2;
536 SD_csd->ECC = (CSD_Tab[14] & 0x03);
537
538 /*!< Byte 15 */
539 SD_csd->CSD_CRC = (CSD_Tab[15] & 0xFE) >> 1;
540 SD_csd->Reserved4 = 1;
541
542 /*!< Return the reponse */
543 return rvalue;
544 }
545
546 /**
547 * @brief Read the CID card register.
548 * Reading the contents of the CID register in SPI mode is a simple
549 * read-block transaction.
550 * @param SD_cid: pointer on an CID register structure
551 * @retval The SD Response:
552 * - SD_RESPONSE_FAILURE: Sequence failed
553 * - SD_RESPONSE_NO_ERROR: Sequence succeed
554 */
555 SD_Error SD_GetCIDRegister(SD_CID* SD_cid)
556 {
557 uint32_t i = 0;
558 SD_Error rvalue = SD_RESPONSE_FAILURE;
559 uint8_t CID_Tab[16];
560
561 /*!< SD chip select low */
562 SD_CS_LOW();
563
564 /*!< Send CMD10 (CID register) */
565 SD_SendCmd(SD_CMD_SEND_CID, 0, 0xFF);
566
567 /*!< Wait for response in the R1 format (0x00 is no errors) */
568 if (!SD_GetResponse(SD_RESPONSE_NO_ERROR))
569 {
570 if (!SD_GetResponse(SD_START_DATA_SINGLE_BLOCK_READ))
571 {
572 /*!< Store CID register value on CID_Tab */
573 for (i = 0; i < 16; i++)
574 {
575 CID_Tab[i] = SD_ReadByte();
576 }
577 }
578 /*!< Get CRC bytes (not really needed by us, but required by SD) */
579 SD_WriteByte(SD_DUMMY_BYTE);
580 SD_WriteByte(SD_DUMMY_BYTE);
581 /*!< Set response value to success */
582 rvalue = SD_RESPONSE_NO_ERROR;
583 }
584 /*!< SD chip select high */
585 SD_CS_HIGH();
586 /*!< Send dummy byte: 8 Clock pulses of delay */
587 SD_WriteByte(SD_DUMMY_BYTE);
588
589 /*!< Byte 0 */
590 SD_cid->ManufacturerID = CID_Tab[0];
591
592 /*!< Byte 1 */
593 SD_cid->OEM_AppliID = CID_Tab[1] << 8;
594
595 /*!< Byte 2 */
596 SD_cid->OEM_AppliID |= CID_Tab[2];
597
598 /*!< Byte 3 */
599 SD_cid->ProdName1 = CID_Tab[3] << 24;
600
601 /*!< Byte 4 */
602 SD_cid->ProdName1 |= CID_Tab[4] << 16;
603
604 /*!< Byte 5 */
605 SD_cid->ProdName1 |= CID_Tab[5] << 8;
606
607 /*!< Byte 6 */
608 SD_cid->ProdName1 |= CID_Tab[6];
609
610 /*!< Byte 7 */
611 SD_cid->ProdName2 = CID_Tab[7];
612
613 /*!< Byte 8 */
614 SD_cid->ProdRev = CID_Tab[8];
615
616 /*!< Byte 9 */
617 SD_cid->ProdSN = CID_Tab[9] << 24;
618
619 /*!< Byte 10 */
620 SD_cid->ProdSN |= CID_Tab[10] << 16;
621
622 /*!< Byte 11 */
623 SD_cid->ProdSN |= CID_Tab[11] << 8;
624
625 /*!< Byte 12 */
626 SD_cid->ProdSN |= CID_Tab[12];
627
628 /*!< Byte 13 */
629 SD_cid->Reserved1 |= (CID_Tab[13] & 0xF0) >> 4;
630 SD_cid->ManufactDate = (CID_Tab[13] & 0x0F) << 8;
631
632 /*!< Byte 14 */
633 SD_cid->ManufactDate |= CID_Tab[14];
634
635 /*!< Byte 15 */
636 SD_cid->CID_CRC = (CID_Tab[15] & 0xFE) >> 1;
637 SD_cid->Reserved2 = 1;
638
639 /*!< Return the reponse */
640 return rvalue;
641 }
642
643 /**
644 * @brief Send 5 bytes command to the SD card.
645 * @param Cmd: The user expected command to send to SD card.
646 * @param Arg: The command argument.
647 * @param Crc: The CRC.
648 * @retval None
649 */
650 void SD_SendCmd(uint8_t Cmd, uint32_t Arg, uint8_t Crc)
651 {
652 uint32_t i = 0x00;
653
654 uint8_t Frame[6];
655
656 Frame[0] = (Cmd | 0x40); /*!< Construct byte 1 */
657
658 Frame[1] = (uint8_t)(Arg >> 24); /*!< Construct byte 2 */
659
660 Frame[2] = (uint8_t)(Arg >> 16); /*!< Construct byte 3 */
661
662 Frame[3] = (uint8_t)(Arg >> 8); /*!< Construct byte 4 */
663
664 Frame[4] = (uint8_t)(Arg); /*!< Construct byte 5 */
665
666 Frame[5] = (Crc); /*!< Construct CRC: byte 6 */
667
668 for (i = 0; i < 6; i++)
669 {
670 SD_WriteByte(Frame[i]); /*!< Send the Cmd bytes */
671 }
672 }
673
674 /**
675 * @brief Get SD card data response.
676 * @param None
677 * @retval The SD status: Read data response xxx0<status>1
678 * - status 010: Data accecpted
679 * - status 101: Data rejected due to a crc error
680 * - status 110: Data rejected due to a Write error.
681 * - status 111: Data rejected due to other error.
682 */
683 uint8_t SD_GetDataResponse(void)
684 {
685 uint32_t i = 0;
686 uint8_t response, rvalue;
687
688 while (i <= 64)
689 {
690 /*!< Read resonse */
691 response = SD_ReadByte();
692 /*!< Mask unused bits */
693 response &= 0x1F;
694 switch (response)
695 {
696 case SD_DATA_OK:
697 {
698 rvalue = SD_DATA_OK;
699 break;
700 }
701 case SD_DATA_CRC_ERROR:
702 return SD_DATA_CRC_ERROR;
703 case SD_DATA_WRITE_ERROR:
704 return SD_DATA_WRITE_ERROR;
705 default:
706 {
707 rvalue = SD_DATA_OTHER_ERROR;
708 break;
709 }
710 }
711 /*!< Exit loop in case of data ok */
712 if (rvalue == SD_DATA_OK)
713 break;
714 /*!< Increment loop counter */
715 i++;
716 }
717
718 /*!< Wait null data */
719 while (SD_ReadByte() == 0);
720
721 /*!< Return response */
722 return response;
723 }
724
725 /**
726 * @brief Returns the SD response.
727 * @param None
728 * @retval The SD Response:
729 * - SD_RESPONSE_FAILURE: Sequence failed
730 * - SD_RESPONSE_NO_ERROR: Sequence succeed
731 */
732 SD_Error SD_GetResponse(uint8_t Response)
733 {
734 uint32_t Count = 0xFFF;
735
736 /*!< Check if response is got or a timeout is happen */
737 while ((SD_ReadByte() != Response) && Count)
738 {
739 Count--;
740 }
741 if (Count == 0)
742 {
743 /*!< After time out */
744 return SD_RESPONSE_FAILURE;
745 }
746 else
747 {
748 /*!< Right response got */
749 return SD_RESPONSE_NO_ERROR;
750 }
751 }
752
753 /**
754 * @brief Returns the SD status.
755 * @param None
756 * @retval The SD status.
757 */
758 uint16_t SD_GetStatus(void)
759 {
760 uint16_t Status = 0;
761
762 /*!< SD chip select low */
763 SD_CS_LOW();
764
765 /*!< Send CMD13 (SD_SEND_STATUS) to get SD status */
766 SD_SendCmd(SD_CMD_SEND_STATUS, 0, 0xFF);
767
768 Status = SD_ReadByte();
769 Status |= (uint16_t)(SD_ReadByte() << 8);
770
771 /*!< SD chip select high */
772 SD_CS_HIGH();
773
774 /*!< Send dummy byte 0xFF */
775 SD_WriteByte(SD_DUMMY_BYTE);
776
777 return Status;
778 }
779
780 /**
781 * @brief Put SD in Idle state.
782 * @param None
783 * @retval The SD Response:
784 * - SD_RESPONSE_FAILURE: Sequence failed
785 * - SD_RESPONSE_NO_ERROR: Sequence succeed
786 */
787 SD_Error SD_GoIdleState(void)
788 {
789 /*!< SD chip select low */
790 SD_CS_LOW();
791
792 /*!< Send CMD0 (SD_CMD_GO_IDLE_STATE) to put SD in SPI mode */
793 SD_SendCmd(SD_CMD_GO_IDLE_STATE, 0, 0x95);
794
795 /*!< Wait for In Idle State Response (R1 Format) equal to 0x01 */
796 if (SD_GetResponse(SD_IN_IDLE_STATE))
797 {
798 /*!< No Idle State Response: return response failue */
799 return SD_RESPONSE_FAILURE;
800 }
801 /*----------Activates the card initialization process-----------*/
802 do
803 {
804 /*!< SD chip select high */
805 SD_CS_HIGH();
806
807 /*!< Send Dummy byte 0xFF */
808 SD_WriteByte(SD_DUMMY_BYTE);
809
810 /*!< SD chip select low */
811 SD_CS_LOW();
812
813 /*!< Send CMD1 (Activates the card process) until response equal to 0x0 */
814 SD_SendCmd(SD_CMD_SEND_OP_COND, 0, 0xFF);
815 /*!< Wait for no error Response (R1 Format) equal to 0x00 */
816 }
817 while (SD_GetResponse(SD_RESPONSE_NO_ERROR));
818
819 /*!< SD chip select high */
820 SD_CS_HIGH();
821
822 /*!< Send dummy byte 0xFF */
823 SD_WriteByte(SD_DUMMY_BYTE);
824
825 return SD_RESPONSE_NO_ERROR;
826 }
827
828 /**
829 * @brief Write a byte on the SD.
830 * @param Data: byte to send.
831 * @retval None
832 */
833 uint8_t SD_WriteByte(uint8_t Data)
834 {
835 /*!< Wait until the transmit buffer is empty */
836 while(SPI_I2S_GetFlagStatus(SD_SPI, SPI_I2S_FLAG_TXE) == RESET)
837 {
838 }
839
840 /*!< Send the byte */
841 SPI_I2S_SendData(SD_SPI, Data);
842
843 /*!< Wait to receive a byte*/
844 while(SPI_I2S_GetFlagStatus(SD_SPI, SPI_I2S_FLAG_RXNE) == RESET)
845 {
846 }
847
848 /*!< Return the byte read from the SPI bus */
849 return SPI_I2S_ReceiveData(SD_SPI);
850 }
851
852 /**
853 * @brief Read a byte from the SD.
854 * @param None
855 * @retval The received byte.
856 */
857 uint8_t SD_ReadByte(void)
858 {
859 uint8_t Data = 0;
860
861 /*!< Wait until the transmit buffer is empty */
862 while (SPI_I2S_GetFlagStatus(SD_SPI, SPI_I2S_FLAG_TXE) == RESET)
863 {
864 }
865 /*!< Send the byte */
866 SPI_I2S_SendData(SD_SPI, SD_DUMMY_BYTE);
867
868 /*!< Wait until a data is received */
869 while (SPI_I2S_GetFlagStatus(SD_SPI, SPI_I2S_FLAG_RXNE) == RESET)
870 {
871 }
872 /*!< Get the received data */
873 Data = SPI_I2S_ReceiveData(SD_SPI);
874
875 /*!< Return the shifted data */
876 return Data;
877 }
878
879 /**
880 * @}
881 */
882
883
884 /**
885 * @}
886 */
887
888
889 /**
890 * @}
891 */
892
893 /**
894 * @}
895 */
896
897 /**
898 * @}
899 */
900
901 /******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/