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