STM32303C_EVAL BSP User Manual
|
stm32303c_eval_sd.c
Go to the documentation of this file.
00001 /** 00002 ****************************************************************************** 00003 * @file stm32303c_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 STM32303C-EVAL board. 00007 * It implements a high level communication layer for read and write 00008 * from/to this memory. The needed STM32F30x hardware resources (SPI and 00009 * GPIO) are defined in stm32303c_eval.h file, and the initialization is 00010 * performed in SD_LowLevel_Init() function declared in stm32303c_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_LowLevel_Init() function. 00015 * 00016 * +-------------------------------------------------------+ 00017 * | Pin assignment | 00018 * +-------------------------+---------------+-------------+ 00019 * | STM32F30x 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 */ 00058 00059 /* File Info : ----------------------------------------------------------------- 00060 User NOTES 00061 1. How To use this driver: 00062 -------------------------- 00063 - This driver is used to drive the micro SD external card mounted on STM32303C-EVAL 00064 evaluation board. 00065 - This driver does not need a specific component driver for the micro SD device 00066 to be included with. 00067 00068 2. Driver description: 00069 --------------------- 00070 + Initialization steps: 00071 o Initialize the micro SD card using the SD_Init() function. 00072 o To check the SD card presence you can use the function SD_IsDetected() which 00073 returns the detection status 00074 o The function SD_GetCardInfo() is used to get the micro SD card information 00075 which is stored in the structure "HAL_SD_CardInfoTypedef". 00076 00077 + Micro SD card operations 00078 o The micro SD card can be accessed with read/write block(s) operations once 00079 it is reay for access. The access cand be performed in polling 00080 mode by calling the functions SD_ReadBlocks()/SD_WriteBlocks() 00081 o The SD erase block(s) is performed using the function SD_Erase() with specifying 00082 the number of blocks to erase. 00083 o The SD runtime status is returned when calling the function SD_GetStatus(). 00084 00085 ------------------------------------------------------------------------------*/ 00086 00087 /* Includes ------------------------------------------------------------------*/ 00088 #include "stm32303c_eval_sd.h" 00089 00090 /** @addtogroup BSP 00091 * @{ 00092 */ 00093 00094 /** @addtogroup STM32303C_EVAL 00095 * @{ 00096 */ 00097 00098 /** @addtogroup STM32303C_EVAL_SD 00099 * @{ 00100 */ 00101 00102 /* Private typedef -----------------------------------------------------------*/ 00103 00104 /** @defgroup STM32303C_EVAL_SD_Private_Types_Definitions Types Definitions 00105 * @{ 00106 */ 00107 00108 /** 00109 * @} 00110 */ 00111 /* Private define ------------------------------------------------------------*/ 00112 00113 /** @addtogroup STM32303C_EVAL_SD_Private_Defines 00114 * @{ 00115 */ 00116 #define SD_DUMMY_BYTE 0xFF 00117 #define SD_NO_RESPONSE_EXPECTED 0x80 00118 /** 00119 * @} 00120 */ 00121 00122 /* Private macro -------------------------------------------------------------*/ 00123 00124 /* Private variables ---------------------------------------------------------*/ 00125 00126 /** @addtogroup STM32303C_EVAL_SD_Private_Variables 00127 * @{ 00128 */ 00129 __IO uint8_t SdStatus = SD_PRESENT; 00130 00131 /** 00132 * @} 00133 */ 00134 00135 /* Private function prototypes -----------------------------------------------*/ 00136 /** @addtogroup STM32303C_EVAL_SD_Private_Functions 00137 * @{ 00138 */ 00139 static uint8_t SD_GetCIDRegister(SD_CID* Cid); 00140 static uint8_t SD_GetCSDRegister(SD_CSD* Csd); 00141 static SD_Info SD_GetDataResponse(void); 00142 static uint8_t SD_GoIdleState(void); 00143 static uint8_t SD_SendCmd(uint8_t Cmd, uint32_t Arg, uint8_t Crc, uint8_t Response); 00144 /* Private functions ---------------------------------------------------------*/ 00145 00146 /** 00147 * @brief Initializes the SD/SD communication. 00148 * @retval The SD Response: 00149 * - MSD_ERROR : Sequence failed 00150 * - MSD_OK : Sequence succeed 00151 */ 00152 uint8_t BSP_SD_Init(void) 00153 { 00154 /* Configure IO functionalities for SD pin */ 00155 SD_IO_Init(); 00156 00157 /* Check SD card detect pin */ 00158 if(BSP_SD_IsDetected()==SD_NOT_PRESENT) 00159 { 00160 SdStatus = SD_NOT_PRESENT; 00161 return MSD_ERROR; 00162 } 00163 else 00164 { 00165 SdStatus = SD_PRESENT; 00166 } 00167 00168 /* SD initialized and set to SPI mode properly */ 00169 return (SD_GoIdleState()); 00170 } 00171 00172 /** 00173 * @brief Detects if SD card is correctly plugged in the memory slot or not. 00174 * @retval Returns if SD is detected or not 00175 */ 00176 uint8_t BSP_SD_IsDetected(void) 00177 { 00178 __IO uint8_t status = SD_PRESENT; 00179 00180 /* Check SD card detect pin */ 00181 if(HAL_GPIO_ReadPin(SD_DETECT_GPIO_PORT, SD_DETECT_PIN) != GPIO_PIN_RESET) 00182 { 00183 status = SD_NOT_PRESENT; 00184 } 00185 00186 return status; 00187 } 00188 00189 /** 00190 * @brief Returns information about specific card. 00191 * @param pCardInfo pointer to a SD_CardInfo structure that contains all SD 00192 * card information. 00193 * @retval The SD Response: 00194 * - MSD_ERROR : Sequence failed 00195 * - MSD_OK : Sequence succeed 00196 */ 00197 uint8_t BSP_SD_GetCardInfo(SD_CardInfo *pCardInfo) 00198 { 00199 uint8_t status = MSD_ERROR; 00200 00201 SD_GetCSDRegister(&(pCardInfo->Csd)); 00202 status = SD_GetCIDRegister(&(pCardInfo->Cid)); 00203 pCardInfo->CardCapacity = (pCardInfo->Csd.DeviceSize + 1) ; 00204 pCardInfo->CardCapacity *= (1 << (pCardInfo->Csd.DeviceSizeMul + 2)); 00205 pCardInfo->CardBlockSize = 1 << (pCardInfo->Csd.RdBlockLen); 00206 pCardInfo->CardCapacity *= pCardInfo->CardBlockSize; 00207 00208 /* Returns the reponse */ 00209 return status; 00210 } 00211 00212 /** 00213 * @brief Reads block(s) from a specified address in an SD card, in polling mode. 00214 * @param p32Data Pointer to the buffer that will contain the data to transmit 00215 * @param ReadAddr Address from where data is to be read 00216 * @param BlockSize SD card data block size, that should be 512 00217 * @param NumberOfBlocks Number of SD blocks to read 00218 * @retval SD status 00219 */ 00220 uint8_t BSP_SD_ReadBlocks(uint32_t* p32Data, uint64_t ReadAddr, uint16_t BlockSize, uint32_t NumberOfBlocks) 00221 { 00222 uint32_t counter = 0, offset = 0; 00223 uint8_t rvalue = MSD_ERROR; 00224 uint8_t *pData = (uint8_t *)p32Data; 00225 00226 /* Send CMD16 (SD_CMD_SET_BLOCKLEN) to set the size of the block and 00227 Check if the SD acknowledged the set block length command: R1 response (0x00: no errors) */ 00228 if (SD_IO_WriteCmd(SD_CMD_SET_BLOCKLEN, BlockSize, 0xFF, SD_RESPONSE_NO_ERROR) != HAL_OK) 00229 { 00230 return MSD_ERROR; 00231 } 00232 00233 /* Data transfer */ 00234 while (NumberOfBlocks--) 00235 { 00236 /* Send dummy byte: 8 Clock pulses of delay */ 00237 SD_IO_WriteDummy(); 00238 00239 /* Send CMD17 (SD_CMD_READ_SINGLE_BLOCK) to read one block */ 00240 /* Check if the SD acknowledged the read block command: R1 response (0x00: no errors) */ 00241 if (SD_IO_WriteCmd(SD_CMD_READ_SINGLE_BLOCK, ReadAddr + offset, 0xFF, SD_RESPONSE_NO_ERROR) != HAL_OK) 00242 { 00243 return MSD_ERROR; 00244 } 00245 00246 /* Now look for the data token to signify the start of the data */ 00247 if (SD_IO_WaitResponse(SD_START_DATA_SINGLE_BLOCK_READ) == HAL_OK) 00248 { 00249 /* Read the SD block data : read NumByteToRead data */ 00250 for (counter = 0; counter < BlockSize; counter++) 00251 { 00252 /* Read the pointed data */ 00253 *pData = SD_IO_ReadByte(); 00254 /* Point to the next location where the byte read will be saved */ 00255 pData++; 00256 } 00257 /* Set next read address*/ 00258 offset += BlockSize; 00259 /* get CRC bytes (not really needed by us, but required by SD) */ 00260 SD_IO_ReadByte(); 00261 SD_IO_ReadByte(); 00262 /* Set response value to success */ 00263 rvalue = MSD_OK; 00264 } 00265 else 00266 { 00267 /* Set response value to failure */ 00268 rvalue = MSD_ERROR; 00269 } 00270 } 00271 00272 /* Send dummy byte: 8 Clock pulses of delay */ 00273 SD_IO_WriteDummy(); 00274 /* Returns the reponse */ 00275 return rvalue; 00276 } 00277 00278 /** 00279 * @brief Writes block(s) to a specified address in an SD card, in polling mode. 00280 * @param p32Data Pointer to the buffer that will contain the data to transmit 00281 * @param WriteAddr Address from where data is to be written 00282 * @param BlockSize SD card data block size, that should be 512 00283 * @param NumberOfBlocks Number of SD blocks to write 00284 * @retval SD status 00285 */ 00286 uint8_t BSP_SD_WriteBlocks(uint32_t* p32Data, uint64_t WriteAddr, uint16_t BlockSize, uint32_t NumberOfBlocks) 00287 { 00288 uint32_t counter = 0, offset = 0; 00289 uint8_t rvalue = MSD_ERROR; 00290 uint8_t *pData = (uint8_t *)p32Data; 00291 00292 /* Data transfer */ 00293 while (NumberOfBlocks--) 00294 { 00295 /* Send CMD24 (SD_CMD_WRITE_SINGLE_BLOCK) to write blocks and 00296 Check if the SD acknowledged the write block command: R1 response (0x00: no errors) */ 00297 if (SD_IO_WriteCmd(SD_CMD_WRITE_SINGLE_BLOCK, WriteAddr + offset, 0xFF, SD_RESPONSE_NO_ERROR) != HAL_OK) 00298 { 00299 return MSD_ERROR; 00300 } 00301 00302 /* Send dummy byte */ 00303 SD_IO_WriteByte(SD_DUMMY_BYTE); 00304 00305 /* Send the data token to signify the start of the data */ 00306 SD_IO_WriteByte(SD_START_DATA_SINGLE_BLOCK_WRITE); 00307 00308 /* Write the block data to SD : write count data by block */ 00309 for (counter = 0; counter < BlockSize; counter++) 00310 { 00311 /* Send the pointed byte */ 00312 SD_IO_WriteByte(*pData); 00313 00314 /* Point to the next location where the byte read will be saved */ 00315 pData++; 00316 } 00317 00318 /* Set next write address */ 00319 offset += BlockSize; 00320 00321 /* Put CRC bytes (not really needed by us, but required by SD) */ 00322 SD_IO_ReadByte(); 00323 SD_IO_ReadByte(); 00324 00325 /* Read data response */ 00326 if (SD_GetDataResponse() == SD_DATA_OK) 00327 { 00328 /* Set response value to success */ 00329 rvalue = MSD_OK; 00330 } 00331 else 00332 { 00333 /* Set response value to failure */ 00334 rvalue = MSD_ERROR; 00335 } 00336 } 00337 00338 /* Send dummy byte: 8 Clock pulses of delay */ 00339 SD_IO_WriteDummy(); 00340 00341 /* Returns the reponse */ 00342 return rvalue; 00343 } 00344 00345 /** 00346 * @brief Read the CSD card register. 00347 * Reading the contents of the CSD register in SPI mode is a simple 00348 * read-block transaction. 00349 * @param Csd pointer on an SCD register structure 00350 * @retval SD status 00351 */ 00352 uint8_t SD_GetCSDRegister(SD_CSD* Csd) 00353 { 00354 uint32_t counter = 0; 00355 uint8_t rvalue = MSD_ERROR; 00356 uint8_t CSD_Tab[16]; 00357 00358 /* Send CMD9 (CSD register) or CMD10(CSD register) and Wait for response in the R1 format (0x00 is no errors) */ 00359 if (SD_IO_WriteCmd(SD_CMD_SEND_CSD, 0, 0xFF, SD_RESPONSE_NO_ERROR) == HAL_OK) 00360 { 00361 if (SD_IO_WaitResponse(SD_START_DATA_SINGLE_BLOCK_READ) == HAL_OK) 00362 { 00363 for (counter = 0; counter < 16; counter++) 00364 { 00365 /* Store CSD register value on CSD_Tab */ 00366 CSD_Tab[counter] = SD_IO_ReadByte(); 00367 } 00368 00369 /* Get CRC bytes (not really needed by us, but required by SD) */ 00370 SD_IO_WriteByte(SD_DUMMY_BYTE); 00371 SD_IO_WriteByte(SD_DUMMY_BYTE); 00372 00373 /* Set response value to success */ 00374 rvalue = MSD_OK; 00375 } 00376 } 00377 /* Send dummy byte: 8 Clock pulses of delay */ 00378 SD_IO_WriteDummy(); 00379 00380 if(rvalue == SD_RESPONSE_NO_ERROR) 00381 { 00382 /* Byte 0 */ 00383 Csd->CSDStruct = (CSD_Tab[0] & 0xC0) >> 6; 00384 Csd->SysSpecVersion = (CSD_Tab[0] & 0x3C) >> 2; 00385 Csd->Reserved1 = CSD_Tab[0] & 0x03; 00386 00387 /* Byte 1 */ 00388 Csd->TAAC = CSD_Tab[1]; 00389 00390 /* Byte 2 */ 00391 Csd->NSAC = CSD_Tab[2]; 00392 00393 /* Byte 3 */ 00394 Csd->MaxBusClkFrec = CSD_Tab[3]; 00395 00396 /* Byte 4 */ 00397 Csd->CardComdClasses = CSD_Tab[4] << 4; 00398 00399 /* Byte 5 */ 00400 Csd->CardComdClasses |= (CSD_Tab[5] & 0xF0) >> 4; 00401 Csd->RdBlockLen = CSD_Tab[5] & 0x0F; 00402 00403 /* Byte 6 */ 00404 Csd->PartBlockRead = (CSD_Tab[6] & 0x80) >> 7; 00405 Csd->WrBlockMisalign = (CSD_Tab[6] & 0x40) >> 6; 00406 Csd->RdBlockMisalign = (CSD_Tab[6] & 0x20) >> 5; 00407 Csd->DSRImpl = (CSD_Tab[6] & 0x10) >> 4; 00408 Csd->Reserved2 = 0; /*!< Reserved */ 00409 00410 Csd->DeviceSize = (CSD_Tab[6] & 0x03) << 10; 00411 00412 /* Byte 7 */ 00413 Csd->DeviceSize |= (CSD_Tab[7]) << 2; 00414 00415 /* Byte 8 */ 00416 Csd->DeviceSize |= (CSD_Tab[8] & 0xC0) >> 6; 00417 00418 Csd->MaxRdCurrentVDDMin = (CSD_Tab[8] & 0x38) >> 3; 00419 Csd->MaxRdCurrentVDDMax = (CSD_Tab[8] & 0x07); 00420 00421 /* Byte 9 */ 00422 Csd->MaxWrCurrentVDDMin = (CSD_Tab[9] & 0xE0) >> 5; 00423 Csd->MaxWrCurrentVDDMax = (CSD_Tab[9] & 0x1C) >> 2; 00424 Csd->DeviceSizeMul = (CSD_Tab[9] & 0x03) << 1; 00425 /* Byte 10 */ 00426 Csd->DeviceSizeMul |= (CSD_Tab[10] & 0x80) >> 7; 00427 00428 Csd->EraseGrSize = (CSD_Tab[10] & 0x40) >> 6; 00429 Csd->EraseGrMul = (CSD_Tab[10] & 0x3F) << 1; 00430 00431 /* Byte 11 */ 00432 Csd->EraseGrMul |= (CSD_Tab[11] & 0x80) >> 7; 00433 Csd->WrProtectGrSize = (CSD_Tab[11] & 0x7F); 00434 00435 /* Byte 12 */ 00436 Csd->WrProtectGrEnable = (CSD_Tab[12] & 0x80) >> 7; 00437 Csd->ManDeflECC = (CSD_Tab[12] & 0x60) >> 5; 00438 Csd->WrSpeedFact = (CSD_Tab[12] & 0x1C) >> 2; 00439 Csd->MaxWrBlockLen = (CSD_Tab[12] & 0x03) << 2; 00440 00441 /* Byte 13 */ 00442 Csd->MaxWrBlockLen |= (CSD_Tab[13] & 0xC0) >> 6; 00443 Csd->WriteBlockPaPartial = (CSD_Tab[13] & 0x20) >> 5; 00444 Csd->Reserved3 = 0; 00445 Csd->ContentProtectAppli = (CSD_Tab[13] & 0x01); 00446 00447 /* Byte 14 */ 00448 Csd->FileFormatGrouop = (CSD_Tab[14] & 0x80) >> 7; 00449 Csd->CopyFlag = (CSD_Tab[14] & 0x40) >> 6; 00450 Csd->PermWrProtect = (CSD_Tab[14] & 0x20) >> 5; 00451 Csd->TempWrProtect = (CSD_Tab[14] & 0x10) >> 4; 00452 Csd->FileFormat = (CSD_Tab[14] & 0x0C) >> 2; 00453 Csd->ECC = (CSD_Tab[14] & 0x03); 00454 00455 /* Byte 15 */ 00456 Csd->CSD_CRC = (CSD_Tab[15] & 0xFE) >> 1; 00457 Csd->Reserved4 = 1; 00458 } 00459 /* Return the reponse */ 00460 return rvalue; 00461 } 00462 00463 /** 00464 * @brief Read the CID card register. 00465 * Reading the contents of the CID register in SPI mode is a simple 00466 * read-block transaction. 00467 * @param Cid pointer on an CID register structure 00468 * @retval SD status 00469 */ 00470 static uint8_t SD_GetCIDRegister(SD_CID* Cid) 00471 { 00472 uint32_t counter = 0; 00473 uint8_t rvalue = MSD_ERROR; 00474 uint8_t CID_Tab[16]; 00475 00476 /* Send CMD10 (CID register) and Wait for response in the R1 format (0x00 is no errors) */ 00477 if (SD_IO_WriteCmd(SD_CMD_SEND_CID, 0, 0xFF, SD_RESPONSE_NO_ERROR) == HAL_OK) 00478 { 00479 if (SD_IO_WaitResponse(SD_START_DATA_SINGLE_BLOCK_READ) == HAL_OK) 00480 { 00481 /* Store CID register value on CID_Tab */ 00482 for (counter = 0; counter < 16; counter++) 00483 { 00484 CID_Tab[counter] = SD_IO_ReadByte(); 00485 } 00486 00487 /* Get CRC bytes (not really needed by us, but required by SD) */ 00488 SD_IO_WriteByte(SD_DUMMY_BYTE); 00489 SD_IO_WriteByte(SD_DUMMY_BYTE); 00490 00491 /* Set response value to success */ 00492 rvalue = MSD_OK; 00493 } 00494 } 00495 00496 /* Send dummy byte: 8 Clock pulses of delay */ 00497 SD_IO_WriteDummy(); 00498 00499 if(rvalue == MSD_OK) 00500 { 00501 /* Byte 0 */ 00502 Cid->ManufacturerID = CID_Tab[0]; 00503 00504 /* Byte 1 */ 00505 Cid->OEM_AppliID = CID_Tab[1] << 8; 00506 00507 /* Byte 2 */ 00508 Cid->OEM_AppliID |= CID_Tab[2]; 00509 00510 /* Byte 3 */ 00511 Cid->ProdName1 = CID_Tab[3] << 24; 00512 00513 /* Byte 4 */ 00514 Cid->ProdName1 |= CID_Tab[4] << 16; 00515 00516 /* Byte 5 */ 00517 Cid->ProdName1 |= CID_Tab[5] << 8; 00518 00519 /* Byte 6 */ 00520 Cid->ProdName1 |= CID_Tab[6]; 00521 00522 /* Byte 7 */ 00523 Cid->ProdName2 = CID_Tab[7]; 00524 00525 /* Byte 8 */ 00526 Cid->ProdRev = CID_Tab[8]; 00527 00528 /* Byte 9 */ 00529 Cid->ProdSN = CID_Tab[9] << 24; 00530 00531 /* Byte 10 */ 00532 Cid->ProdSN |= CID_Tab[10] << 16; 00533 00534 /* Byte 11 */ 00535 Cid->ProdSN |= CID_Tab[11] << 8; 00536 00537 /* Byte 12 */ 00538 Cid->ProdSN |= CID_Tab[12]; 00539 00540 /* Byte 13 */ 00541 Cid->Reserved1 |= (CID_Tab[13] & 0xF0) >> 4; 00542 Cid->ManufactDate = (CID_Tab[13] & 0x0F) << 8; 00543 00544 /* Byte 14 */ 00545 Cid->ManufactDate |= CID_Tab[14]; 00546 00547 /* Byte 15 */ 00548 Cid->CID_CRC = (CID_Tab[15] & 0xFE) >> 1; 00549 Cid->Reserved2 = 1; 00550 } 00551 /* Return the reponse */ 00552 return rvalue; 00553 } 00554 00555 /** 00556 * @brief Send 5 bytes command to the SD card and get response 00557 * @param Cmd The user expected command to send to SD card. 00558 * @param Arg The command argument. 00559 * @param Crc The CRC. 00560 * @param Response Expected response from the SD card 00561 * @retval SD status 00562 */ 00563 static uint8_t SD_SendCmd(uint8_t Cmd, uint32_t Arg, uint8_t Crc, uint8_t Response) 00564 { 00565 uint8_t status = MSD_ERROR; 00566 00567 if(SD_IO_WriteCmd(Cmd, Arg, Crc, Response) == HAL_OK) 00568 { 00569 status = MSD_OK; 00570 } 00571 00572 /* Send Dummy Byte */ 00573 SD_IO_WriteDummy(); 00574 00575 return status; 00576 } 00577 00578 /** 00579 * @brief Get SD card data response. 00580 * @retval The SD status: Read data response xxx0<status>1 00581 * - status 010: Data accecpted 00582 * - status 101: Data rejected due to a crc error 00583 * - status 110: Data rejected due to a Write error. 00584 * - status 111: Data rejected due to other error. 00585 */ 00586 static SD_Info SD_GetDataResponse(void) 00587 { 00588 uint32_t counter = 0; 00589 SD_Info response, rvalue; 00590 00591 while (counter <= 64) 00592 { 00593 /* Read response */ 00594 response = (SD_Info)SD_IO_ReadByte(); 00595 /* Mask unused bits */ 00596 response &= 0x1F; 00597 switch (response) 00598 { 00599 case SD_DATA_OK: 00600 { 00601 rvalue = SD_DATA_OK; 00602 break; 00603 } 00604 case SD_DATA_CRC_ERROR: 00605 return SD_DATA_CRC_ERROR; 00606 case SD_DATA_WRITE_ERROR: 00607 return SD_DATA_WRITE_ERROR; 00608 default: 00609 { 00610 rvalue = SD_DATA_OTHER_ERROR; 00611 break; 00612 } 00613 } 00614 /* Exit loop in case of data ok */ 00615 if (rvalue == SD_DATA_OK) 00616 break; 00617 /* Increment loop counter */ 00618 counter++; 00619 } 00620 00621 /* Wait null data */ 00622 while (SD_IO_ReadByte() == 0); 00623 00624 /* Return response */ 00625 return response; 00626 } 00627 00628 /** 00629 * @brief Returns the SD status. 00630 * @retval The SD status. 00631 */ 00632 uint8_t BSP_SD_GetStatus(void) 00633 { 00634 return MSD_OK; 00635 } 00636 00637 /** 00638 * @brief Put SD in Idle state. 00639 * @retval SD status 00640 */ 00641 static uint8_t SD_GoIdleState(void) 00642 { 00643 /* Send CMD0 (SD_CMD_GO_IDLE_STATE) to put SD in SPI mode and 00644 Wait for In Idle State Response (R1 Format) equal to 0x01 */ 00645 if (SD_SendCmd(SD_CMD_GO_IDLE_STATE, 0, 0x95, SD_IN_IDLE_STATE) != MSD_OK) 00646 { 00647 /* No Idle State Response: return response failue */ 00648 return MSD_ERROR; 00649 } 00650 00651 /*----------Activates the card initialization process-----------*/ 00652 /* Send CMD1 (Activates the card process) until response equal to 0x0 and 00653 Wait for no error Response (R1 Format) equal to 0x00 */ 00654 while (SD_SendCmd(SD_CMD_SEND_OP_COND, 0, 0xFF, SD_RESPONSE_NO_ERROR) != MSD_OK); 00655 00656 return MSD_OK; 00657 } 00658 /** 00659 * @brief Erases the specified memory area of the given SD card. 00660 * @param StartAddr Start byte address 00661 * @param EndAddr End byte address 00662 * @retval SD status 00663 */ 00664 uint8_t BSP_SD_Erase(uint32_t StartAddr, uint32_t EndAddr) 00665 { 00666 uint8_t rvalue = MSD_ERROR; 00667 00668 /* Send CMD32 (Erase group start) and check if the SD acknowledged the erase command: R1 response (0x00: no errors) */ 00669 if (SD_SendCmd(SD_CMD_SD_ERASE_GRP_START, StartAddr, 0xFF, SD_RESPONSE_NO_ERROR) == MSD_OK) 00670 { 00671 /* Send CMD33 (Erase group end) and Check if the SD acknowledged the erase command: R1 response (0x00: no errors) */ 00672 if (SD_SendCmd(SD_CMD_SD_ERASE_GRP_END, EndAddr, 0xFF, SD_RESPONSE_NO_ERROR) == MSD_OK) 00673 { 00674 /* Send CMD38 (Erase) and Check if the SD acknowledged the erase command: R1 response (0x00: no errors) */ 00675 if (SD_SendCmd(SD_CMD_ERASE, 0, 0xFF, SD_RESPONSE_NO_ERROR) == MSD_OK) 00676 { 00677 /* Verify that SD card is ready to use after the specific command ERASE */ 00678 if (SD_IO_WaitResponse(SD_RESPONSE_NO_ERROR) == HAL_OK) 00679 rvalue = MSD_OK; 00680 } 00681 } 00682 } 00683 00684 /* Return the reponse */ 00685 return rvalue; 00686 } 00687 /** 00688 * @} 00689 */ 00690 00691 /** 00692 * @} 00693 */ 00694 00695 /** 00696 * @} 00697 */ 00698 00699 /** 00700 * @} 00701 */ 00702 00703 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
Generated on Wed May 31 2017 10:00:44 for STM32303C_EVAL BSP User Manual by 1.7.6.1