STM3210C_EVAL BSP User Manual
|
stm3210c_eval_sd.c
Go to the documentation of this file.
00001 /** 00002 ****************************************************************************** 00003 * @file stm3210c_eval_sd.c 00004 * @author MCD Application Team 00005 * @version V7.0.0 00006 * @date 14-April-2017 00007 * @brief This file provides a set of functions needed to manage the SPI SD 00008 * Card memory mounted on STM3210C-EVAL board. 00009 * It implements a high level communication layer for read and write 00010 * from/to this memory. The needed STM32F10x hardware resources (SPI and 00011 * GPIO) are defined in stm3210c_eval.h file, and the initialization is 00012 * performed in SD_IO_Init() function declared in stm3210c_eval.c 00013 * file. 00014 * You can easily tailor this driver to any other development board, 00015 * by just adapting the defines for hardware resources and 00016 * SD_IO_Init() function. 00017 * 00018 * +-------------------------------------------------------+ 00019 * | Pin assignment | 00020 * +-------------------------+---------------+-------------+ 00021 * | STM32F10x SPI Pins | SD | Pin | 00022 * +-------------------------+---------------+-------------+ 00023 * | SD_SPI_CS_PIN | ChipSelect | 2 | 00024 * | SD_SPI_MOSI_PIN / MOSI | DataIn | 3 | 00025 * | | GND | 9 (0 V) | 00026 * | | VDD | 4 (3.3 V)| 00027 * | SD_SPI_SCK_PIN / SCLK | Clock | 5 | 00028 * | | GND | 6 (0 V) | 00029 * | SD_SPI_MISO_PIN / MISO | DataOut | 7 | 00030 * +-------------------------+---------------+-------------+ 00031 ****************************************************************************** 00032 * @attention 00033 * 00034 * <h2><center>© COPYRIGHT(c) 2016 STMicroelectronics</center></h2> 00035 * 00036 * Redistribution and use in source and binary forms, with or without modification, 00037 * are permitted provided that the following conditions are met: 00038 * 1. Redistributions of source code must retain the above copyright notice, 00039 * this list of conditions and the following disclaimer. 00040 * 2. Redistributions in binary form must reproduce the above copyright notice, 00041 * this list of conditions and the following disclaimer in the documentation 00042 * and/or other materials provided with the distribution. 00043 * 3. Neither the name of STMicroelectronics nor the names of its contributors 00044 * may be used to endorse or promote products derived from this software 00045 * without specific prior written permission. 00046 * 00047 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00048 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00049 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00050 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 00051 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00052 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 00053 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00054 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 00055 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00056 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00057 * 00058 ****************************************************************************** 00059 */ 00060 00061 /* File Info : ----------------------------------------------------------------- 00062 User NOTES 00063 1. How To use this driver: 00064 -------------------------- 00065 - This driver is used to drive the micro SD external card mounted on STM3210C-EVAL 00066 evaluation board. 00067 - This driver does not need a specific component driver for the micro SD device 00068 to be included with. 00069 00070 2. Driver description: 00071 --------------------- 00072 + Initialization steps: 00073 o Initialize the micro SD card using the BSP_SD_Init() function. 00074 o To check the SD card presence you can use the function BSP_SD_IsDetected() which 00075 returns the detection status 00076 o The function BSP_SD_GetCardInfo() is used to get the micro SD card information 00077 which is stored in the structure "HAL_SD_CardInfoTypedef". 00078 00079 + Micro SD card operations 00080 o The micro SD card can be accessed with read/write block(s) operations once 00081 it is reay for access. The access cand be performed in polling 00082 mode by calling the functions BSP_SD_ReadBlocks()/BSP_SD_WriteBlocks() 00083 o The SD erase block(s) is performed using the function BSP_SD_Erase() with specifying 00084 the number of blocks to erase. 00085 o The SD runtime status is returned when calling the function BSP_SD_GetCardState(). 00086 00087 ------------------------------------------------------------------------------*/ 00088 00089 /* Includes ------------------------------------------------------------------*/ 00090 #include "stm3210c_eval_sd.h" 00091 #include "stdlib.h" 00092 #include "string.h" 00093 #include "stdio.h" 00094 /** @addtogroup BSP 00095 * @{ 00096 */ 00097 00098 /** @addtogroup STM3210C_EVAL 00099 * @{ 00100 */ 00101 00102 /** @defgroup STM3210C_EVAL_SD STM3210C EVAL SD 00103 * @{ 00104 */ 00105 00106 /* Private typedef -----------------------------------------------------------*/ 00107 00108 /** @defgroup STM3210C_EVAL_SD_Private_Types_Definitions STM3210C EVAL SD Private Types Definitions 00109 * @{ 00110 */ 00111 typedef struct { 00112 uint8_t r1; 00113 uint8_t r2; 00114 uint8_t r3; 00115 uint8_t r4; 00116 uint8_t r5; 00117 } SD_CmdAnswer_typedef; 00118 00119 00120 /** 00121 * @} 00122 */ 00123 00124 /* Private define ------------------------------------------------------------*/ 00125 00126 /** @defgroup STM3210C_EVAL_SD_Private_Defines STM3210C EVAL SD Private Defines 00127 * @{ 00128 */ 00129 00130 #define SD_DUMMY_BYTE 0xFF 00131 00132 #define SD_MAX_FRAME_LENGTH 17 /* Lenght = 16 + 1 */ 00133 #define SD_CMD_LENGTH 6 00134 00135 #define SD_MAX_TRY 100 /* Number of try */ 00136 00137 #define SD_CSD_STRUCT_V1 0x2 /* CSD struct version V1 */ 00138 #define SD_CSD_STRUCT_V2 0x1 /* CSD struct version V2 */ 00139 00140 00141 /** 00142 * @brief SD ansewer format 00143 */ 00144 typedef enum { 00145 SD_ANSWER_R1_EXPECTED, 00146 SD_ANSWER_R1B_EXPECTED, 00147 SD_ANSWER_R2_EXPECTED, 00148 SD_ANSWER_R3_EXPECTED, 00149 SD_ANSWER_R4R5_EXPECTED, 00150 SD_ANSWER_R7_EXPECTED, 00151 }SD_Answer_type; 00152 00153 /** 00154 * @brief Start Data tokens: 00155 * Tokens (necessary because at nop/idle (and CS active) only 0xff is 00156 * on the data/command line) 00157 */ 00158 #define SD_TOKEN_START_DATA_SINGLE_BLOCK_READ 0xFE /* Data token start byte, Start Single Block Read */ 00159 #define SD_TOKEN_START_DATA_MULTIPLE_BLOCK_READ 0xFE /* Data token start byte, Start Multiple Block Read */ 00160 #define SD_TOKEN_START_DATA_SINGLE_BLOCK_WRITE 0xFE /* Data token start byte, Start Single Block Write */ 00161 #define SD_TOKEN_START_DATA_MULTIPLE_BLOCK_WRITE 0xFD /* Data token start byte, Start Multiple Block Write */ 00162 #define SD_TOKEN_STOP_DATA_MULTIPLE_BLOCK_WRITE 0xFD /* Data toke stop byte, Stop Multiple Block Write */ 00163 00164 /** 00165 * @brief Commands: CMDxx = CMD-number | 0x40 00166 */ 00167 #define SD_CMD_GO_IDLE_STATE 0 /* CMD0 = 0x40 */ 00168 #define SD_CMD_SEND_OP_COND 1 /* CMD1 = 0x41 */ 00169 #define SD_CMD_SEND_IF_COND 8 /* CMD8 = 0x48 */ 00170 #define SD_CMD_SEND_CSD 9 /* CMD9 = 0x49 */ 00171 #define SD_CMD_SEND_CID 10 /* CMD10 = 0x4A */ 00172 #define SD_CMD_STOP_TRANSMISSION 12 /* CMD12 = 0x4C */ 00173 #define SD_CMD_SEND_STATUS 13 /* CMD13 = 0x4D */ 00174 #define SD_CMD_SET_BLOCKLEN 16 /* CMD16 = 0x50 */ 00175 #define SD_CMD_READ_SINGLE_BLOCK 17 /* CMD17 = 0x51 */ 00176 #define SD_CMD_READ_MULT_BLOCK 18 /* CMD18 = 0x52 */ 00177 #define SD_CMD_SET_BLOCK_COUNT 23 /* CMD23 = 0x57 */ 00178 #define SD_CMD_WRITE_SINGLE_BLOCK 24 /* CMD24 = 0x58 */ 00179 #define SD_CMD_WRITE_MULT_BLOCK 25 /* CMD25 = 0x59 */ 00180 #define SD_CMD_PROG_CSD 27 /* CMD27 = 0x5B */ 00181 #define SD_CMD_SET_WRITE_PROT 28 /* CMD28 = 0x5C */ 00182 #define SD_CMD_CLR_WRITE_PROT 29 /* CMD29 = 0x5D */ 00183 #define SD_CMD_SEND_WRITE_PROT 30 /* CMD30 = 0x5E */ 00184 #define SD_CMD_SD_ERASE_GRP_START 32 /* CMD32 = 0x60 */ 00185 #define SD_CMD_SD_ERASE_GRP_END 33 /* CMD33 = 0x61 */ 00186 #define SD_CMD_UNTAG_SECTOR 34 /* CMD34 = 0x62 */ 00187 #define SD_CMD_ERASE_GRP_START 35 /* CMD35 = 0x63 */ 00188 #define SD_CMD_ERASE_GRP_END 36 /* CMD36 = 0x64 */ 00189 #define SD_CMD_UNTAG_ERASE_GROUP 37 /* CMD37 = 0x65 */ 00190 #define SD_CMD_ERASE 38 /* CMD38 = 0x66 */ 00191 #define SD_CMD_SD_APP_OP_COND 41 /* CMD41 = 0x69 */ 00192 #define SD_CMD_APP_CMD 55 /* CMD55 = 0x77 */ 00193 #define SD_CMD_READ_OCR 58 /* CMD55 = 0x79 */ 00194 00195 /** 00196 * @brief SD reponses and error flags 00197 */ 00198 typedef enum 00199 { 00200 /* R1 answer value */ 00201 SD_R1_NO_ERROR = (0x00), 00202 SD_R1_IN_IDLE_STATE = (0x01), 00203 SD_R1_ERASE_RESET = (0x02), 00204 SD_R1_ILLEGAL_COMMAND = (0x04), 00205 SD_R1_COM_CRC_ERROR = (0x08), 00206 SD_R1_ERASE_SEQUENCE_ERROR= (0x10), 00207 SD_R1_ADDRESS_ERROR = (0x20), 00208 SD_R1_PARAMETER_ERROR = (0x40), 00209 00210 /* R2 answer value */ 00211 SD_R2_NO_ERROR = 0x00, 00212 SD_R2_CARD_LOCKED = 0x01, 00213 SD_R2_LOCKUNLOCK_ERROR = 0x02, 00214 SD_R2_ERROR = 0x04, 00215 SD_R2_CC_ERROR = 0x08, 00216 SD_R2_CARD_ECC_FAILED = 0x10, 00217 SD_R2_WP_VIOLATION = 0x20, 00218 SD_R2_ERASE_PARAM = 0x40, 00219 SD_R2_OUTOFRANGE = 0x80, 00220 00221 /** 00222 * @brief Data response error 00223 */ 00224 SD_DATA_OK = (0x05), 00225 SD_DATA_CRC_ERROR = (0x0B), 00226 SD_DATA_WRITE_ERROR = (0x0D), 00227 SD_DATA_OTHER_ERROR = (0xFF) 00228 } SD_Error; 00229 00230 /** 00231 * @} 00232 */ 00233 00234 /* Private variables ---------------------------------------------------------*/ 00235 00236 /** @defgroup STM3210C_EVAL_SD_Private_Variables STM3210C EVAL SD Private Variables 00237 * @{ 00238 */ 00239 __IO uint8_t SdStatus = SD_NOT_PRESENT; 00240 00241 /* flag_SDHC : 00242 0 : Standard capacity 00243 1 : High capacity 00244 */ 00245 uint16_t flag_SDHC = 0; 00246 00247 /** 00248 * @} 00249 */ 00250 00251 /* Private function prototypes -----------------------------------------------*/ 00252 static uint8_t SD_GetCIDRegister(SD_CID* Cid); 00253 static uint8_t SD_GetCSDRegister(SD_CSD* Csd); 00254 static uint8_t SD_GetDataResponse(void); 00255 static uint8_t SD_GoIdleState(void); 00256 static SD_CmdAnswer_typedef SD_SendCmd(uint8_t Cmd, uint32_t Arg, uint8_t Crc, uint8_t Answer); 00257 static uint8_t SD_WaitData(uint8_t data); 00258 static uint8_t SD_ReadData(void); 00259 00260 /* Private functions ---------------------------------------------------------*/ 00261 00262 /** @defgroup STM3210C_EVAL_SD_Exported_Functions STM3210C EVAL SD Exported Functions 00263 * @{ 00264 */ 00265 00266 /** 00267 * @brief Initializes the SD/SD communication. 00268 * @retval The SD Response: 00269 * - MSD_ERROR : Sequence failed 00270 * - MSD_OK : Sequence succeed 00271 */ 00272 uint8_t BSP_SD_Init(void) 00273 { 00274 /* Configure IO functionalities for SD pin */ 00275 SD_IO_Init(); 00276 00277 /* Check SD card detect pin */ 00278 if(BSP_SD_IsDetected()==SD_NOT_PRESENT) 00279 { 00280 SdStatus = SD_NOT_PRESENT; 00281 } 00282 else 00283 { 00284 SdStatus = SD_PRESENT; 00285 } 00286 00287 /* SD initialized and set to SPI mode properly */ 00288 return (SD_GoIdleState()); 00289 } 00290 00291 /** 00292 * @brief Detects if SD card is correctly plugged in the memory slot or not. 00293 * @retval Returns if SD is detected or not 00294 */ 00295 uint8_t BSP_SD_IsDetected(void) 00296 { 00297 __IO uint8_t status = SD_PRESENT; 00298 00299 /* Check SD card detect pin */ 00300 if(HAL_GPIO_ReadPin(SD_DETECT_GPIO_PORT, SD_DETECT_PIN) != GPIO_PIN_RESET) 00301 { 00302 status = SD_NOT_PRESENT; 00303 } 00304 00305 return status; 00306 } 00307 00308 /** 00309 * @brief Returns information about specific card. 00310 * @param pCardInfo: pointer to a SD_CardInfo structure that contains all SD 00311 * card information. 00312 * @retval The SD Response: 00313 * - MSD_ERROR : Sequence failed 00314 * - MSD_OK : Sequence succeed 00315 */ 00316 uint8_t BSP_SD_GetCardInfo(SD_CardInfo *pCardInfo) 00317 { 00318 uint8_t status; 00319 00320 status = SD_GetCSDRegister(&(pCardInfo->Csd)); 00321 status|= SD_GetCIDRegister(&(pCardInfo->Cid)); 00322 if(flag_SDHC == 1 ) 00323 { 00324 pCardInfo->LogBlockSize = 512; 00325 pCardInfo->CardBlockSize = 512; 00326 pCardInfo->CardCapacity = (pCardInfo->Csd.version.v2.DeviceSize + 1) * 1024 * pCardInfo->LogBlockSize; 00327 pCardInfo->LogBlockNbr = (pCardInfo->CardCapacity) / (pCardInfo->LogBlockSize); 00328 } 00329 else 00330 { 00331 pCardInfo->CardCapacity = (pCardInfo->Csd.version.v1.DeviceSize + 1) ; 00332 pCardInfo->CardCapacity *= (1 << (pCardInfo->Csd.version.v1.DeviceSizeMul + 2)); 00333 pCardInfo->LogBlockSize = 512; 00334 pCardInfo->CardBlockSize = 1 << (pCardInfo->Csd.RdBlockLen); 00335 pCardInfo->CardCapacity *= pCardInfo->CardBlockSize; 00336 pCardInfo->LogBlockNbr = (pCardInfo->CardCapacity) / (pCardInfo->LogBlockSize); 00337 } 00338 00339 return status; 00340 } 00341 /** 00342 * @brief Reads block(s) from a specified address in the SD card, in polling mode. 00343 * @param pData: Pointer to the buffer that will contain the data to transmit 00344 * @param ReadAddr: Address from where data is to be read. The address is counted 00345 * in blocks of 512bytes 00346 * @param NumOfBlocks: Number of SD blocks to read 00347 * @param Timeout: This parameter is used for compatibility with BSP implementation 00348 * @retval SD status 00349 */ 00350 uint8_t BSP_SD_ReadBlocks(uint32_t *pData, uint32_t ReadAddr, uint32_t NumOfBlocks, uint32_t Timeout) 00351 { 00352 uint32_t offset = 0; 00353 uint8_t retr = BSP_SD_ERROR; 00354 SD_CmdAnswer_typedef response; 00355 uint16_t BlockSize = 512; 00356 00357 /* Send CMD16 (SD_CMD_SET_BLOCKLEN) to set the size of the block and 00358 Check if the SD acknowledged the set block length command: R1 response (0x00: no errors) */ 00359 response = SD_SendCmd(SD_CMD_SET_BLOCKLEN, BlockSize, 0xFF, SD_ANSWER_R1_EXPECTED); 00360 SD_IO_CSState(1); 00361 SD_IO_WriteByte(SD_DUMMY_BYTE); 00362 if ( response.r1 != SD_R1_NO_ERROR) 00363 { 00364 goto error; 00365 } 00366 00367 /* Data transfer */ 00368 while (NumOfBlocks--) 00369 { 00370 /* Send CMD17 (SD_CMD_READ_SINGLE_BLOCK) to read one block */ 00371 /* Check if the SD acknowledged the read block command: R1 response (0x00: no errors) */ 00372 response = SD_SendCmd(SD_CMD_READ_SINGLE_BLOCK, (ReadAddr + offset) * (flag_SDHC == 1 ? 1: BlockSize), 0xFF, SD_ANSWER_R1_EXPECTED); 00373 if ( response.r1 != SD_R1_NO_ERROR) 00374 { 00375 goto error; 00376 } 00377 00378 /* Now look for the data token to signify the start of the data */ 00379 if (SD_WaitData(SD_TOKEN_START_DATA_SINGLE_BLOCK_READ) == BSP_SD_OK) 00380 { 00381 /* Read the SD block data : read NumByteToRead data */ 00382 SD_IO_ReadData((uint8_t*)pData + offset, BlockSize); 00383 00384 /* Set next read address*/ 00385 offset += BlockSize; 00386 /* get CRC bytes (not really needed by us, but required by SD) */ 00387 SD_IO_WriteByte(SD_DUMMY_BYTE); 00388 SD_IO_WriteByte(SD_DUMMY_BYTE); 00389 } 00390 else 00391 { 00392 goto error; 00393 } 00394 00395 /* End the command data read cycle */ 00396 SD_IO_CSState(1); 00397 SD_IO_WriteByte(SD_DUMMY_BYTE); 00398 } 00399 00400 retr = BSP_SD_OK; 00401 00402 error : 00403 /* Send dummy byte: 8 Clock pulses of delay */ 00404 SD_IO_CSState(1); 00405 SD_IO_WriteByte(SD_DUMMY_BYTE); 00406 00407 /* Return the reponse */ 00408 return retr; 00409 } 00410 00411 /** 00412 * @brief Writes block(s) to a specified address in the SD card, in polling mode. 00413 * @param pData: Pointer to the buffer that will contain the data to transmit 00414 * @param WriteAddr: Address from where data is to be written. The address is counted 00415 * in blocks of 512bytes 00416 * @param NumOfBlocks: Number of SD blocks to write 00417 * @param Timeout: This parameter is used for compatibility with BSP implementation 00418 * @retval SD status 00419 */ 00420 uint8_t BSP_SD_WriteBlocks(uint32_t *pData, uint32_t WriteAddr, uint32_t NumOfBlocks, uint32_t Timeout) 00421 { 00422 uint32_t offset = 0; 00423 uint8_t retr = BSP_SD_ERROR; 00424 SD_CmdAnswer_typedef response; 00425 uint16_t BlockSize = 512; 00426 00427 /* Send CMD16 (SD_CMD_SET_BLOCKLEN) to set the size of the block and 00428 Check if the SD acknowledged the set block length command: R1 response (0x00: no errors) */ 00429 response = SD_SendCmd(SD_CMD_SET_BLOCKLEN, BlockSize, 0xFF, SD_ANSWER_R1_EXPECTED); 00430 SD_IO_CSState(1); 00431 SD_IO_WriteByte(SD_DUMMY_BYTE); 00432 if ( response.r1 != SD_R1_NO_ERROR) 00433 { 00434 goto error; 00435 } 00436 00437 /* Data transfer */ 00438 while (NumOfBlocks--) 00439 { 00440 /* Send CMD24 (SD_CMD_WRITE_SINGLE_BLOCK) to write blocks and 00441 Check if the SD acknowledged the write block command: R1 response (0x00: no errors) */ 00442 response = SD_SendCmd(SD_CMD_WRITE_SINGLE_BLOCK, (WriteAddr + offset) * (flag_SDHC == 1 ? 1 : BlockSize), 0xFF, SD_ANSWER_R1_EXPECTED); 00443 if (response.r1 != SD_R1_NO_ERROR) 00444 { 00445 goto error; 00446 } 00447 00448 /* Send dummy byte for NWR timing : one byte between CMDWRITE and TOKEN */ 00449 SD_IO_WriteByte(SD_DUMMY_BYTE); 00450 SD_IO_WriteByte(SD_DUMMY_BYTE); 00451 00452 /* Send the data token to signify the start of the data */ 00453 SD_IO_WriteByte(SD_TOKEN_START_DATA_SINGLE_BLOCK_WRITE); 00454 00455 /* Write the block data to SD */ 00456 SD_IO_WriteData((uint8_t*)pData + offset, BlockSize); 00457 00458 /* Set next write address */ 00459 offset += BlockSize; 00460 00461 /* Put CRC bytes (not really needed by us, but required by SD) */ 00462 SD_IO_WriteByte(SD_DUMMY_BYTE); 00463 SD_IO_WriteByte(SD_DUMMY_BYTE); 00464 00465 /* Read data response */ 00466 if (SD_GetDataResponse() != SD_DATA_OK) 00467 { 00468 /* Set response value to failure */ 00469 goto error; 00470 } 00471 00472 SD_IO_CSState(1); 00473 SD_IO_WriteByte(SD_DUMMY_BYTE); 00474 } 00475 retr = BSP_SD_OK; 00476 00477 error : 00478 /* Send dummy byte: 8 Clock pulses of delay */ 00479 SD_IO_CSState(1); 00480 SD_IO_WriteByte(SD_DUMMY_BYTE); 00481 00482 /* Return the reponse */ 00483 return retr; 00484 } 00485 00486 /** 00487 * @brief Erases the specified memory area of the given SD card. 00488 * @param StartAddr: Start address in Blocks (Size of a block is 512bytes) 00489 * @param EndAddr: End address in Blocks (Size of a block is 512bytes) 00490 * @retval SD status 00491 */ 00492 uint8_t BSP_SD_Erase(uint32_t StartAddr, uint32_t EndAddr) 00493 { 00494 uint8_t retr = BSP_SD_ERROR; 00495 SD_CmdAnswer_typedef response; 00496 uint16_t BlockSize = 512; 00497 00498 /* Send CMD32 (Erase group start) and check if the SD acknowledged the erase command: R1 response (0x00: no errors) */ 00499 response = SD_SendCmd(SD_CMD_SD_ERASE_GRP_START, (StartAddr) * (flag_SDHC == 1 ? 1 : BlockSize), 0xFF, SD_ANSWER_R1_EXPECTED); 00500 SD_IO_CSState(1); 00501 SD_IO_WriteByte(SD_DUMMY_BYTE); if (response.r1 == SD_R1_NO_ERROR) 00502 { 00503 /* Send CMD33 (Erase group end) and Check if the SD acknowledged the erase command: R1 response (0x00: no errors) */ 00504 response = SD_SendCmd(SD_CMD_SD_ERASE_GRP_END, (EndAddr*512) * (flag_SDHC == 1 ? 1 : BlockSize), 0xFF, SD_ANSWER_R1_EXPECTED); 00505 SD_IO_CSState(1); 00506 SD_IO_WriteByte(SD_DUMMY_BYTE); 00507 if (response.r1 == SD_R1_NO_ERROR) 00508 { 00509 /* Send CMD38 (Erase) and Check if the SD acknowledged the erase command: R1 response (0x00: no errors) */ 00510 response = SD_SendCmd(SD_CMD_ERASE, 0, 0xFF, SD_ANSWER_R1B_EXPECTED); 00511 if (response.r1 == SD_R1_NO_ERROR) 00512 { 00513 retr = BSP_SD_OK; 00514 } 00515 SD_IO_CSState(1); 00516 SD_IO_WriteByte(SD_DUMMY_BYTE); 00517 } 00518 } 00519 00520 /* Return the reponse */ 00521 return retr; 00522 } 00523 00524 /** 00525 * @brief Returns the SD status. 00526 * @param None 00527 * @retval The SD status. 00528 */ 00529 uint8_t BSP_SD_GetCardState(void) 00530 { 00531 SD_CmdAnswer_typedef retr; 00532 00533 /* Send CMD13 (SD_SEND_STATUS) to get SD status */ 00534 retr = SD_SendCmd(SD_CMD_SEND_STATUS, 0, 0xFF, SD_ANSWER_R2_EXPECTED); 00535 SD_IO_CSState(1); 00536 SD_IO_WriteByte(SD_DUMMY_BYTE); 00537 00538 /* Find SD status according to card state */ 00539 if(( retr.r1 == SD_R1_NO_ERROR) && ( retr.r2 == SD_R2_NO_ERROR)) 00540 { 00541 return BSP_SD_OK; 00542 } 00543 00544 return BSP_SD_ERROR; 00545 } 00546 00547 /** 00548 * @brief Reads the SD card SCD register. 00549 * Reading the contents of the CSD register in SPI mode is a simple 00550 * read-block transaction. 00551 * @param Csd: pointer on an SCD register structure 00552 * @retval SD status 00553 */ 00554 uint8_t SD_GetCSDRegister(SD_CSD* Csd) 00555 { 00556 uint16_t counter = 0; 00557 uint8_t CSD_Tab[16]; 00558 uint8_t retr = BSP_SD_ERROR; 00559 SD_CmdAnswer_typedef response; 00560 00561 /* Send CMD9 (CSD register) or CMD10(CSD register) and Wait for response in the R1 format (0x00 is no errors) */ 00562 response = SD_SendCmd(SD_CMD_SEND_CSD, 0, 0xFF, SD_ANSWER_R1_EXPECTED); 00563 if(response.r1 == SD_R1_NO_ERROR) 00564 { 00565 if (SD_WaitData(SD_TOKEN_START_DATA_SINGLE_BLOCK_READ) == BSP_SD_OK) 00566 { 00567 for (counter = 0; counter < 16; counter++) 00568 { 00569 /* Store CSD register value on CSD_Tab */ 00570 CSD_Tab[counter] = SD_IO_WriteByte(SD_DUMMY_BYTE); 00571 } 00572 00573 /* Get CRC bytes (not really needed by us, but required by SD) */ 00574 SD_IO_WriteByte(SD_DUMMY_BYTE); 00575 SD_IO_WriteByte(SD_DUMMY_BYTE); 00576 00577 /************************************************************************* 00578 CSD header decoding 00579 *************************************************************************/ 00580 00581 /* Byte 0 */ 00582 Csd->CSDStruct = (CSD_Tab[0] & 0xC0) >> 6; 00583 Csd->Reserved1 = CSD_Tab[0] & 0x3F; 00584 00585 /* Byte 1 */ 00586 Csd->TAAC = CSD_Tab[1]; 00587 00588 /* Byte 2 */ 00589 Csd->NSAC = CSD_Tab[2]; 00590 00591 /* Byte 3 */ 00592 Csd->MaxBusClkFrec = CSD_Tab[3]; 00593 00594 /* Byte 4/5 */ 00595 Csd->CardComdClasses = (CSD_Tab[4] << 4) | ((CSD_Tab[5] & 0xF0) >> 4); 00596 Csd->RdBlockLen = CSD_Tab[5] & 0x0F; 00597 00598 /* Byte 6 */ 00599 Csd->PartBlockRead = (CSD_Tab[6] & 0x80) >> 7; 00600 Csd->WrBlockMisalign = (CSD_Tab[6] & 0x40) >> 6; 00601 Csd->RdBlockMisalign = (CSD_Tab[6] & 0x20) >> 5; 00602 Csd->DSRImpl = (CSD_Tab[6] & 0x10) >> 4; 00603 00604 /************************************************************************* 00605 CSD v1/v2 decoding 00606 *************************************************************************/ 00607 00608 if(flag_SDHC == 0) 00609 { 00610 Csd->version.v1.Reserved1 = ((CSD_Tab[6] & 0x0C) >> 2); 00611 00612 Csd->version.v1.DeviceSize = ((CSD_Tab[6] & 0x03) << 10) 00613 | (CSD_Tab[7] << 2) 00614 | ((CSD_Tab[8] & 0xC0) >> 6); 00615 Csd->version.v1.MaxRdCurrentVDDMin = (CSD_Tab[8] & 0x38) >> 3; 00616 Csd->version.v1.MaxRdCurrentVDDMax = (CSD_Tab[8] & 0x07); 00617 Csd->version.v1.MaxWrCurrentVDDMin = (CSD_Tab[9] & 0xE0) >> 5; 00618 Csd->version.v1.MaxWrCurrentVDDMax = (CSD_Tab[9] & 0x1C) >> 2; 00619 Csd->version.v1.DeviceSizeMul = ((CSD_Tab[9] & 0x03) << 1) 00620 |((CSD_Tab[10] & 0x80) >> 7); 00621 } 00622 else 00623 { 00624 Csd->version.v2.Reserved1 = ((CSD_Tab[6] & 0x0F) << 2) | ((CSD_Tab[7] & 0xC0) >> 6); 00625 Csd->version.v2.DeviceSize= ((CSD_Tab[7] & 0x3F) << 16) | (CSD_Tab[8] << 8) | CSD_Tab[9]; 00626 Csd->version.v2.Reserved2 = ((CSD_Tab[10] & 0x80) >> 8); 00627 } 00628 00629 Csd->EraseSingleBlockEnable = (CSD_Tab[10] & 0x40) >> 6; 00630 Csd->EraseSectorSize = ((CSD_Tab[10] & 0x3F) << 1) 00631 |((CSD_Tab[11] & 0x80) >> 7); 00632 Csd->WrProtectGrSize = (CSD_Tab[11] & 0x7F); 00633 Csd->WrProtectGrEnable = (CSD_Tab[12] & 0x80) >> 7; 00634 Csd->Reserved2 = (CSD_Tab[12] & 0x60) >> 5; 00635 Csd->WrSpeedFact = (CSD_Tab[12] & 0x1C) >> 2; 00636 Csd->MaxWrBlockLen = ((CSD_Tab[12] & 0x03) << 2) 00637 |((CSD_Tab[13] & 0xC0) >> 6); 00638 Csd->WriteBlockPartial = (CSD_Tab[13] & 0x20) >> 5; 00639 Csd->Reserved3 = (CSD_Tab[13] & 0x1F); 00640 Csd->FileFormatGrouop = (CSD_Tab[14] & 0x80) >> 7; 00641 Csd->CopyFlag = (CSD_Tab[14] & 0x40) >> 6; 00642 Csd->PermWrProtect = (CSD_Tab[14] & 0x20) >> 5; 00643 Csd->TempWrProtect = (CSD_Tab[14] & 0x10) >> 4; 00644 Csd->FileFormat = (CSD_Tab[14] & 0x0C) >> 2; 00645 Csd->Reserved4 = (CSD_Tab[14] & 0x03); 00646 Csd->crc = (CSD_Tab[15] & 0xFE) >> 1; 00647 Csd->Reserved5 = (CSD_Tab[15] & 0x01); 00648 00649 retr = BSP_SD_OK; 00650 } 00651 } 00652 00653 /* Send dummy byte: 8 Clock pulses of delay */ 00654 SD_IO_CSState(1); 00655 SD_IO_WriteByte(SD_DUMMY_BYTE); 00656 00657 /* Return the reponse */ 00658 return retr; 00659 } 00660 00661 /** 00662 * @brief Reads the SD card CID register. 00663 * Reading the contents of the CID register in SPI mode is a simple 00664 * read-block transaction. 00665 * @param Cid: pointer on an CID register structure 00666 * @retval SD status 00667 */ 00668 uint8_t SD_GetCIDRegister(SD_CID* Cid) 00669 { 00670 uint32_t counter = 0; 00671 uint8_t retr = BSP_SD_ERROR; 00672 uint8_t CID_Tab[16]; 00673 SD_CmdAnswer_typedef response; 00674 00675 /* Send CMD10 (CID register) and Wait for response in the R1 format (0x00 is no errors) */ 00676 response = SD_SendCmd(SD_CMD_SEND_CID, 0, 0xFF, SD_ANSWER_R1_EXPECTED); 00677 if(response.r1 == SD_R1_NO_ERROR) 00678 { 00679 if(SD_WaitData(SD_TOKEN_START_DATA_SINGLE_BLOCK_READ) == BSP_SD_OK) 00680 { 00681 /* Store CID register value on CID_Tab */ 00682 for (counter = 0; counter < 16; counter++) 00683 { 00684 CID_Tab[counter] = SD_IO_WriteByte(SD_DUMMY_BYTE); 00685 } 00686 00687 /* Get CRC bytes (not really needed by us, but required by SD) */ 00688 SD_IO_WriteByte(SD_DUMMY_BYTE); 00689 SD_IO_WriteByte(SD_DUMMY_BYTE); 00690 00691 /* Byte 0 */ 00692 Cid->ManufacturerID = CID_Tab[0]; 00693 00694 /* Byte 1 */ 00695 Cid->OEM_AppliID = CID_Tab[1] << 8; 00696 00697 /* Byte 2 */ 00698 Cid->OEM_AppliID |= CID_Tab[2]; 00699 00700 /* Byte 3 */ 00701 Cid->ProdName1 = CID_Tab[3] << 24; 00702 00703 /* Byte 4 */ 00704 Cid->ProdName1 |= CID_Tab[4] << 16; 00705 00706 /* Byte 5 */ 00707 Cid->ProdName1 |= CID_Tab[5] << 8; 00708 00709 /* Byte 6 */ 00710 Cid->ProdName1 |= CID_Tab[6]; 00711 00712 /* Byte 7 */ 00713 Cid->ProdName2 = CID_Tab[7]; 00714 00715 /* Byte 8 */ 00716 Cid->ProdRev = CID_Tab[8]; 00717 00718 /* Byte 9 */ 00719 Cid->ProdSN = CID_Tab[9] << 24; 00720 00721 /* Byte 10 */ 00722 Cid->ProdSN |= CID_Tab[10] << 16; 00723 00724 /* Byte 11 */ 00725 Cid->ProdSN |= CID_Tab[11] << 8; 00726 00727 /* Byte 12 */ 00728 Cid->ProdSN |= CID_Tab[12]; 00729 00730 /* Byte 13 */ 00731 Cid->Reserved1 |= (CID_Tab[13] & 0xF0) >> 4; 00732 Cid->ManufactDate = (CID_Tab[13] & 0x0F) << 8; 00733 00734 /* Byte 14 */ 00735 Cid->ManufactDate |= CID_Tab[14]; 00736 00737 /* Byte 15 */ 00738 Cid->CID_CRC = (CID_Tab[15] & 0xFE) >> 1; 00739 Cid->Reserved2 = 1; 00740 00741 retr = BSP_SD_OK; 00742 } 00743 } 00744 00745 /* Send dummy byte: 8 Clock pulses of delay */ 00746 SD_IO_CSState(1); 00747 SD_IO_WriteByte(SD_DUMMY_BYTE); 00748 00749 /* Return the reponse */ 00750 return retr; 00751 } 00752 00753 /** 00754 * @brief Sends 5 bytes command to the SD card and get response 00755 * @param Cmd: The user expected command to send to SD card. 00756 * @param Arg: The command argument. 00757 * @param Crc: The CRC. 00758 * @param Answer: SD_ANSWER_NOT_EXPECTED or SD_ANSWER_EXPECTED 00759 * @retval SD status 00760 */ 00761 SD_CmdAnswer_typedef SD_SendCmd(uint8_t Cmd, uint32_t Arg, uint8_t Crc, uint8_t Answer) 00762 { 00763 uint8_t frame[SD_CMD_LENGTH], frameout[SD_CMD_LENGTH]; 00764 SD_CmdAnswer_typedef retr = {0xFF, 0xFF , 0xFF, 0xFF, 0xFF}; 00765 00766 /* R1 Lenght = NCS(0)+ 6 Bytes command + NCR(min1 max8) + 1 Bytes answer + NEC(0) = 15bytes */ 00767 /* R1b identical to R1 + Busy information */ 00768 /* R2 Lenght = NCS(0)+ 6 Bytes command + NCR(min1 max8) + 2 Bytes answer + NEC(0) = 16bytes */ 00769 00770 /* Prepare Frame to send */ 00771 frame[0] = (Cmd | 0x40); /* Construct byte 1 */ 00772 frame[1] = (uint8_t)(Arg >> 24); /* Construct byte 2 */ 00773 frame[2] = (uint8_t)(Arg >> 16); /* Construct byte 3 */ 00774 frame[3] = (uint8_t)(Arg >> 8); /* Construct byte 4 */ 00775 frame[4] = (uint8_t)(Arg); /* Construct byte 5 */ 00776 frame[5] = (Crc | 0x01); /* Construct byte 6 */ 00777 00778 /* Send the command */ 00779 SD_IO_CSState(0); 00780 SD_IO_WriteReadData(frame, frameout, SD_CMD_LENGTH); /* Send the Cmd bytes */ 00781 00782 switch(Answer) 00783 { 00784 case SD_ANSWER_R1_EXPECTED : 00785 retr.r1 = SD_ReadData(); 00786 break; 00787 case SD_ANSWER_R1B_EXPECTED : 00788 retr.r1 = SD_ReadData(); 00789 retr.r2 = SD_IO_WriteByte(SD_DUMMY_BYTE); 00790 /* Set CS High */ 00791 SD_IO_CSState(1); 00792 HAL_Delay(1); 00793 /* Set CS Low */ 00794 SD_IO_CSState(0); 00795 00796 /* Wait IO line return 0xFF */ 00797 while (SD_IO_WriteByte(SD_DUMMY_BYTE) != 0xFF); 00798 break; 00799 case SD_ANSWER_R2_EXPECTED : 00800 retr.r1 = SD_ReadData(); 00801 retr.r2 = SD_IO_WriteByte(SD_DUMMY_BYTE); 00802 break; 00803 case SD_ANSWER_R3_EXPECTED : 00804 case SD_ANSWER_R7_EXPECTED : 00805 retr.r1 = SD_ReadData(); 00806 retr.r2 = SD_IO_WriteByte(SD_DUMMY_BYTE); 00807 retr.r3 = SD_IO_WriteByte(SD_DUMMY_BYTE); 00808 retr.r4 = SD_IO_WriteByte(SD_DUMMY_BYTE); 00809 retr.r5 = SD_IO_WriteByte(SD_DUMMY_BYTE); 00810 break; 00811 default : 00812 break; 00813 } 00814 return retr; 00815 } 00816 00817 /** 00818 * @brief Gets the SD card data response and check the busy flag. 00819 * @retval The SD status: Read data response xxx0<status>1 00820 * - status 010: Data accecpted 00821 * - status 101: Data rejected due to a crc error 00822 * - status 110: Data rejected due to a Write error. 00823 * - status 111: Data rejected due to other error. 00824 */ 00825 uint8_t SD_GetDataResponse(void) 00826 { 00827 uint8_t dataresponse; 00828 uint8_t rvalue = SD_DATA_OTHER_ERROR; 00829 00830 dataresponse = SD_IO_WriteByte(SD_DUMMY_BYTE); 00831 SD_IO_WriteByte(SD_DUMMY_BYTE); /* read the busy response byte*/ 00832 00833 /* Mask unused bits */ 00834 switch (dataresponse & 0x1F) 00835 { 00836 case SD_DATA_OK: 00837 rvalue = SD_DATA_OK; 00838 00839 /* Set CS High */ 00840 SD_IO_CSState(1); 00841 /* Set CS Low */ 00842 SD_IO_CSState(0); 00843 00844 /* Wait IO line return 0xFF */ 00845 while (SD_IO_WriteByte(SD_DUMMY_BYTE) != 0xFF); 00846 break; 00847 case SD_DATA_CRC_ERROR: 00848 rvalue = SD_DATA_CRC_ERROR; 00849 break; 00850 case SD_DATA_WRITE_ERROR: 00851 rvalue = SD_DATA_WRITE_ERROR; 00852 break; 00853 default: 00854 break; 00855 } 00856 00857 /* Return response */ 00858 return rvalue; 00859 } 00860 00861 00862 /** 00863 * @brief Put the SD in Idle state. 00864 * @retval SD status 00865 */ 00866 uint8_t SD_GoIdleState(void) 00867 { 00868 SD_CmdAnswer_typedef response; 00869 __IO uint8_t counter = 0; 00870 /* Send CMD0 (SD_CMD_GO_IDLE_STATE) to put SD in SPI mode and 00871 wait for In Idle State Response (R1 Format) equal to 0x01 */ 00872 do{ 00873 counter++; 00874 response = SD_SendCmd(SD_CMD_GO_IDLE_STATE, 0, 0x95, SD_ANSWER_R1_EXPECTED); 00875 SD_IO_CSState(1); 00876 SD_IO_WriteByte(SD_DUMMY_BYTE); 00877 if(counter >= SD_MAX_TRY) 00878 { 00879 return BSP_SD_ERROR; 00880 } 00881 } 00882 while(response.r1 != SD_R1_IN_IDLE_STATE); 00883 00884 00885 /* Send CMD8 (SD_CMD_SEND_IF_COND) to check the power supply status 00886 and wait until response (R7 Format) equal to 0xAA and */ 00887 response = SD_SendCmd(SD_CMD_SEND_IF_COND, 0x1AA, 0x87, SD_ANSWER_R7_EXPECTED); 00888 SD_IO_CSState(1); 00889 SD_IO_WriteByte(SD_DUMMY_BYTE); 00890 if((response.r1 & SD_R1_ILLEGAL_COMMAND) == SD_R1_ILLEGAL_COMMAND) 00891 { 00892 /* initialise card V1 */ 00893 do 00894 { 00895 /* initialise card V1 */ 00896 /* Send CMD55 (SD_CMD_APP_CMD) before any ACMD command: R1 response (0x00: no errors) */ 00897 response = SD_SendCmd(SD_CMD_APP_CMD, 0x00000000, 0xFF, SD_ANSWER_R1_EXPECTED); 00898 SD_IO_CSState(1); 00899 SD_IO_WriteByte(SD_DUMMY_BYTE); 00900 00901 /* Send ACMD41 (SD_CMD_SD_APP_OP_COND) to initialize SDHC or SDXC cards: R1 response (0x00: no errors) */ 00902 response = SD_SendCmd(SD_CMD_SD_APP_OP_COND, 0x00000000, 0xFF, SD_ANSWER_R1_EXPECTED); 00903 SD_IO_CSState(1); 00904 SD_IO_WriteByte(SD_DUMMY_BYTE); 00905 } 00906 while(response.r1 == SD_R1_IN_IDLE_STATE); 00907 flag_SDHC = 0; 00908 } 00909 else if(response.r1 == SD_R1_IN_IDLE_STATE) 00910 { 00911 /* initialise card V2 */ 00912 do { 00913 00914 /* Send CMD55 (SD_CMD_APP_CMD) before any ACMD command: R1 response (0x00: no errors) */ 00915 response = SD_SendCmd(SD_CMD_APP_CMD, 0, 0xFF, SD_ANSWER_R1_EXPECTED); 00916 SD_IO_CSState(1); 00917 SD_IO_WriteByte(SD_DUMMY_BYTE); 00918 00919 /* Send ACMD41 (SD_CMD_SD_APP_OP_COND) to initialize SDHC or SDXC cards: R1 response (0x00: no errors) */ 00920 response = SD_SendCmd(SD_CMD_SD_APP_OP_COND, 0x40000000, 0xFF, SD_ANSWER_R1_EXPECTED); 00921 SD_IO_CSState(1); 00922 SD_IO_WriteByte(SD_DUMMY_BYTE); 00923 } 00924 while(response.r1 == SD_R1_IN_IDLE_STATE); 00925 00926 if((response.r1 & SD_R1_ILLEGAL_COMMAND) == SD_R1_ILLEGAL_COMMAND) 00927 { 00928 do { 00929 /* Send CMD55 (SD_CMD_APP_CMD) before any ACMD command: R1 response (0x00: no errors) */ 00930 response = SD_SendCmd(SD_CMD_APP_CMD, 0, 0xFF, SD_ANSWER_R1_EXPECTED); 00931 SD_IO_CSState(1); 00932 SD_IO_WriteByte(SD_DUMMY_BYTE); 00933 if(response.r1 != SD_R1_IN_IDLE_STATE) 00934 { 00935 return BSP_SD_ERROR; 00936 } 00937 /* Send ACMD41 (SD_CMD_SD_APP_OP_COND) to initialize SDHC or SDXC cards: R1 response (0x00: no errors) */ 00938 response = SD_SendCmd(SD_CMD_SD_APP_OP_COND, 0x00000000, 0xFF, SD_ANSWER_R1_EXPECTED); 00939 SD_IO_CSState(1); 00940 SD_IO_WriteByte(SD_DUMMY_BYTE); 00941 } 00942 while(response.r1 == SD_R1_IN_IDLE_STATE); 00943 } 00944 00945 /* Send CMD58 (SD_CMD_READ_OCR) to initialize SDHC or SDXC cards: R3 response (0x00: no errors) */ 00946 response = SD_SendCmd(SD_CMD_READ_OCR, 0x00000000, 0xFF, SD_ANSWER_R3_EXPECTED); 00947 SD_IO_CSState(1); 00948 SD_IO_WriteByte(SD_DUMMY_BYTE); 00949 if(response.r1 != SD_R1_NO_ERROR) 00950 { 00951 return BSP_SD_ERROR; 00952 } 00953 flag_SDHC = (response.r2 & 0x40) >> 6; 00954 } 00955 else 00956 { 00957 return BSP_SD_ERROR; 00958 } 00959 00960 return BSP_SD_OK; 00961 } 00962 00963 /** 00964 * @brief Waits a data until a value different from SD_DUMMY_BITE 00965 * @param None 00966 * @retval the value read 00967 */ 00968 uint8_t SD_ReadData(void) 00969 { 00970 uint8_t timeout = 0x08; 00971 uint8_t readvalue; 00972 00973 /* Check if response is got or a timeout is happen */ 00974 do { 00975 readvalue = SD_IO_WriteByte(SD_DUMMY_BYTE); 00976 timeout--; 00977 00978 }while ((readvalue == SD_DUMMY_BYTE) && timeout); 00979 00980 /* Right response got */ 00981 return readvalue; 00982 } 00983 00984 /** 00985 * @brief Waits a data from the SD card 00986 * @param data : Expected data from the SD card 00987 * @retval BSP_SD_OK or BSP_SD_TIMEOUT 00988 */ 00989 uint8_t SD_WaitData(uint8_t data) 00990 { 00991 uint16_t timeout = 0xFFFF; 00992 uint8_t readvalue; 00993 00994 /* Check if response is got or a timeout is happen */ 00995 00996 do { 00997 readvalue = SD_IO_WriteByte(SD_DUMMY_BYTE); 00998 timeout--; 00999 }while ((readvalue != data) && timeout); 01000 01001 if (timeout == 0) 01002 { 01003 /* After time out */ 01004 return BSP_SD_TIMEOUT; 01005 } 01006 01007 /* Right response got */ 01008 return BSP_SD_OK; 01009 } 01010 01011 /** 01012 * @} 01013 */ 01014 01015 /** 01016 * @} 01017 */ 01018 01019 /** 01020 * @} 01021 */ 01022 01023 /** 01024 * @} 01025 */ 01026 01027 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
Generated on Fri Apr 14 2017 13:00:47 for STM3210C_EVAL BSP User Manual by 1.7.6.1