Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
stm32_adafruit_sd.c
00001 /** 00002 ****************************************************************************** 00003 * @file stm32_adafruit_sd.c 00004 * @author MCD Application Team 00005 * @version V1.0.0 00006 * @date 22-April-2014 00007 * @brief This file provides a set of functions needed to manage the SD card 00008 * mounted on the Adafruit 1.8" TFT LCD shield (reference ID 802), 00009 * that is used with the STM32 Nucleo board through SPI interface. 00010 * It implements a high level communication layer for read and write 00011 * from/to this memory. The needed STM32XXxx hardware resources (SPI and 00012 * GPIO) are defined in stm32XXxx_nucleo.h file, and the initialization is 00013 * performed in SD_IO_Init() function declared in stm32XXxx_nucleo.c 00014 * file. 00015 * You can easily tailor this driver to any other development board, 00016 * by just adapting the defines for hardware resources and 00017 * SD_IO_Init() function. 00018 * 00019 * +-------------------------------------------------------+ 00020 * | Pin assignment | 00021 * +-------------------------+---------------+-------------+ 00022 * | STM32XXxx SPI Pins | SD | Pin | 00023 * +-------------------------+---------------+-------------+ 00024 * | SD_SPI_CS_PIN | ChipSelect | 1 | 00025 * | SD_SPI_MOSI_PIN / MOSI | DataIn | 2 | 00026 * | | GND | 3 (0 V) | 00027 * | | VDD | 4 (3.3 V)| 00028 * | SD_SPI_SCK_PIN / SCLK | Clock | 5 | 00029 * | | GND | 6 (0 V) | 00030 * | SD_SPI_MISO_PIN / MISO | DataOut | 7 | 00031 * +-------------------------+---------------+-------------+ 00032 ****************************************************************************** 00033 * @attention 00034 * 00035 * <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2> 00036 * 00037 * Redistribution and use in source and binary forms, with or without modification, 00038 * are permitted provided that the following conditions are met: 00039 * 1. Redistributions of source code must retain the above copyright notice, 00040 * this list of conditions and the following disclaimer. 00041 * 2. Redistributions in binary form must reproduce the above copyright notice, 00042 * this list of conditions and the following disclaimer in the documentation 00043 * and/or other materials provided with the distribution. 00044 * 3. Neither the name of STMicroelectronics nor the names of its contributors 00045 * may be used to endorse or promote products derived from this software 00046 * without specific prior written permission. 00047 * 00048 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00049 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00050 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00051 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 00052 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00053 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 00054 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00055 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 00056 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00057 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00058 * 00059 ****************************************************************************** 00060 */ 00061 00062 /* File Info : ----------------------------------------------------------------- 00063 User NOTES 00064 1. How to use this driver: 00065 -------------------------- 00066 - This driver does not need a specific component driver for the micro SD device 00067 to be included with. 00068 00069 2. Driver description: 00070 --------------------- 00071 + Initialization steps: 00072 o Initialize the micro SD card using the BSP_SD_Init() function. 00073 o Cheking the SD card presence is not managed because SD detection pin is 00074 not physically mapped on the Adafruit shield. 00075 o The function BSP_SD_GetCardInfo() is used to get the micro SD card information 00076 which is stored in the structure "SD_CardInfo". 00077 00078 + Micro SD card operations 00079 o The micro SD card can be accessed with read/write block(s) operations once 00080 it is ready for access. The access can be performed in polling 00081 mode by calling the functions BSP_SD_ReadBlocks()/BSP_SD_WriteBlocks() 00082 00083 o The SD erase block(s) is performed using the function BSP_SD_Erase() with 00084 specifying the number of blocks to erase. 00085 o The SD runtime status is returned when calling the function BSP_SD_GetStatus(). 00086 00087 @note This driver's version interfacing SD card using SPI protocol, supports only 00088 SDSC (Secure Digital Standard Capacity) cards (capacity up to 4GB). 00089 ------------------------------------------------------------------------------*/ 00090 00091 /* Includes ------------------------------------------------------------------*/ 00092 #include "stm32_adafruit_sd.h" 00093 00094 /** @addtogroup BSP 00095 * @{ 00096 */ 00097 00098 /** @addtogroup STM32_ADAFRUIT 00099 * @{ 00100 */ 00101 00102 /** @defgroup STM32_ADAFRUIT_SD 00103 * @{ 00104 */ 00105 00106 /* Private typedef -----------------------------------------------------------*/ 00107 00108 /** @defgroup STM32_ADAFRUIT_SD_Private_Types_Definitions 00109 * @{ 00110 */ 00111 00112 /** 00113 * @} 00114 */ 00115 00116 /* Private define ------------------------------------------------------------*/ 00117 00118 /** @defgroup STM32_ADAFRUIT_SD_Private_Defines 00119 * @{ 00120 */ 00121 #define SD_DUMMY_BYTE 0xFF 00122 #define SD_NO_RESPONSE_EXPECTED 0x80 00123 /** 00124 * @} 00125 */ 00126 00127 /* Private macro -------------------------------------------------------------*/ 00128 00129 /** @defgroup STM32_ADAFRUIT_SD_Private_Macros 00130 * @{ 00131 */ 00132 00133 /** 00134 * @} 00135 */ 00136 00137 /* Private variables ---------------------------------------------------------*/ 00138 00139 /** @defgroup STM32_ADAFRUIT_SD_Private_Variables 00140 * @{ 00141 */ 00142 __IO uint8_t SdStatus = SD_PRESENT; 00143 00144 /** 00145 * @} 00146 */ 00147 00148 /* Private function prototypes -----------------------------------------------*/ 00149 static uint8_t SD_GetCIDRegister(SD_CID* Cid); 00150 static uint8_t SD_GetCSDRegister(SD_CSD* Csd); 00151 static uint8_t SD_GetDataResponse(void); 00152 static uint8_t SD_GoIdleState(void); 00153 static uint8_t SD_SendCmd(uint8_t Cmd, uint32_t Arg, uint8_t Crc, uint8_t Response); 00154 00155 /** @defgroup STM32_ADAFRUIT_SD_Private_Function_Prototypes 00156 * @{ 00157 */ 00158 /** 00159 * @} 00160 */ 00161 00162 /* Private functions ---------------------------------------------------------*/ 00163 00164 /** @defgroup STM32_ADAFRUIT_SD_Private_Functions 00165 * @{ 00166 */ 00167 00168 /** 00169 * @brief Initializes the SD/SD communication. 00170 * @param None 00171 * @retval The SD Response: 00172 * - MSD_ERROR: Sequence failed 00173 * - MSD_OK: Sequence succeed 00174 */ 00175 uint8_t BSP_SD_Init(void) 00176 { 00177 uint8_t status = MSD_ERROR; 00178 00179 /* Configure IO functionalities for SD pin */ 00180 SD_IO_Init(); 00181 00182 /* SD detection pin is not physically mapped on the Adafruit shield */ 00183 SdStatus = SD_PRESENT; 00184 00185 /* SD initialized and set to SPI mode properly */ 00186 status = SD_GoIdleState(); 00187 00188 if (status == SD_RESPONSE_NO_ERROR) 00189 { 00190 return MSD_OK; 00191 } 00192 else 00193 { 00194 return MSD_ERROR; 00195 } 00196 } 00197 00198 /** 00199 * @brief Returns information about specific card. 00200 * @param pCardInfo: Pointer to a SD_CardInfo structure that contains all SD 00201 * card information. 00202 * @retval The SD Response: 00203 * - MSD_ERROR: Sequence failed 00204 * - MSD_OK: Sequence succeed 00205 */ 00206 uint8_t BSP_SD_GetCardInfo(SD_CardInfo *pCardInfo) 00207 { 00208 uint8_t status = MSD_ERROR; 00209 00210 SD_GetCSDRegister(&(pCardInfo->Csd)); 00211 status = SD_GetCIDRegister(&(pCardInfo->Cid)); 00212 pCardInfo->CardCapacity = (pCardInfo->Csd.DeviceSize + 1) ; 00213 pCardInfo->CardCapacity *= (1 << (pCardInfo->Csd.DeviceSizeMul + 2)); 00214 pCardInfo->CardBlockSize = 1 << (pCardInfo->Csd.RdBlockLen); 00215 pCardInfo->CardCapacity *= pCardInfo->CardBlockSize; 00216 00217 /* Returns the reponse */ 00218 if (status == SD_RESPONSE_NO_ERROR) 00219 { 00220 return MSD_OK; 00221 } 00222 else 00223 { 00224 return MSD_ERROR; 00225 } 00226 } 00227 00228 /** 00229 * @brief Reads block(s) from a specified address in the SD card, in polling mode. 00230 * @param pData: Pointer to the buffer that will contain the data to transmit 00231 * @param ReadAddr: Address from where data is to be read 00232 * @param BlockSize: SD card data block size, that should be 512 00233 * @param NumOfBlocks: Number of SD blocks to read 00234 * @retval SD status 00235 */ 00236 uint8_t BSP_SD_ReadBlocks(uint32_t* pData, uint32_t ReadAddr, uint16_t BlockSize, uint32_t NumberOfBlocks) 00237 { 00238 uint32_t counter = 0, offset = 0; 00239 uint8_t rvalue = MSD_ERROR; 00240 uint8_t *ptr = (uint8_t*) pData; 00241 00242 /* Send CMD16 (SD_CMD_SET_BLOCKLEN) to set the size of the block and 00243 Check if the SD acknowledged the set block length command: R1 response (0x00: no errors) */ 00244 if (SD_IO_WriteCmd(SD_CMD_SET_BLOCKLEN, BlockSize, 0xFF, SD_RESPONSE_NO_ERROR) != 0) 00245 { 00246 return MSD_ERROR; 00247 } 00248 00249 /* Data transfer */ 00250 while (NumberOfBlocks--) 00251 { 00252 /* Send dummy byte: 8 Clock pulses of delay */ 00253 SD_IO_WriteDummy(); 00254 00255 /* Send CMD17 (SD_CMD_READ_SINGLE_BLOCK) to read one block */ 00256 /* Check if the SD acknowledged the read block command: R1 response (0x00: no errors) */ 00257 if (SD_IO_WriteCmd(SD_CMD_READ_SINGLE_BLOCK, ReadAddr + offset, 0xFF, SD_RESPONSE_NO_ERROR) != 0) 00258 { 00259 return MSD_ERROR; 00260 } 00261 00262 /* Now look for the data token to signify the start of the data */ 00263 if (!SD_IO_WaitResponse(SD_START_DATA_SINGLE_BLOCK_READ)) 00264 { 00265 /* Read the SD block data : read NumByteToRead data */ 00266 for (counter = 0; counter < BlockSize; counter++) 00267 { 00268 /* Read the pointed data */ 00269 *ptr = SD_IO_ReadByte(); 00270 /* Point to the next location where the byte read will be saved */ 00271 ptr++; 00272 } 00273 /* Set next read address*/ 00274 offset += BlockSize; 00275 /* get CRC bytes (not really needed by us, but required by SD) */ 00276 SD_IO_ReadByte(); 00277 SD_IO_ReadByte(); 00278 /* Set response value to success */ 00279 rvalue = MSD_OK; 00280 } 00281 else 00282 { 00283 /* Set response value to failure */ 00284 rvalue = MSD_ERROR; 00285 } 00286 } 00287 00288 /* Send dummy byte: 8 Clock pulses of delay */ 00289 SD_IO_WriteDummy(); 00290 00291 /* Return the reponse */ 00292 return rvalue; 00293 } 00294 00295 /** 00296 * @brief Writes block(s) to a specified address in the SD card, in polling mode. 00297 * @param pData: Pointer to the buffer that will contain the data to transmit 00298 * @param WriteAddr: Address from where data is to be written 00299 * @param BlockSize: SD card data block size, that should be 512 00300 * @param NumOfBlocks: Number of SD blocks to write 00301 * @retval SD status 00302 */ 00303 uint8_t BSP_SD_WriteBlocks(uint32_t* pData, uint32_t WriteAddr, uint16_t BlockSize, uint32_t NumberOfBlocks) 00304 { 00305 uint32_t counter = 0, offset = 0; 00306 uint8_t rvalue = MSD_ERROR; 00307 uint8_t *ptr = (uint8_t*) pData; 00308 00309 /* Data transfer */ 00310 while (NumberOfBlocks--) 00311 { 00312 /* Send CMD24 (SD_CMD_WRITE_SINGLE_BLOCK) to write blocks and 00313 Check if the SD acknowledged the write block command: R1 response (0x00: no errors) */ 00314 if (SD_IO_WriteCmd(SD_CMD_WRITE_SINGLE_BLOCK, WriteAddr + offset, 0xFF, SD_RESPONSE_NO_ERROR)) 00315 { 00316 return MSD_ERROR; 00317 } 00318 00319 /* Send dummy byte */ 00320 SD_IO_WriteByte(SD_DUMMY_BYTE); 00321 00322 /* Send the data token to signify the start of the data */ 00323 SD_IO_WriteByte(SD_START_DATA_SINGLE_BLOCK_WRITE); 00324 00325 /* Write the block data to SD : write count data by block */ 00326 for (counter = 0; counter < BlockSize; counter++) 00327 { 00328 /* Send the pointed byte */ 00329 SD_IO_WriteByte(*ptr); 00330 00331 /* Point to the next location where the byte read will be saved */ 00332 ptr++; 00333 } 00334 00335 /* Set next write address */ 00336 offset += BlockSize; 00337 00338 /* Put CRC bytes (not really needed by us, but required by SD) */ 00339 SD_IO_ReadByte(); 00340 SD_IO_ReadByte(); 00341 00342 /* Read data response */ 00343 if (SD_GetDataResponse() == SD_DATA_OK) 00344 { 00345 /* Set response value to success */ 00346 rvalue = MSD_OK; 00347 } 00348 else 00349 { 00350 /* Set response value to failure */ 00351 rvalue = MSD_ERROR; 00352 } 00353 } 00354 00355 /* Send dummy byte: 8 Clock pulses of delay */ 00356 SD_IO_WriteDummy(); 00357 00358 /* Return the reponse */ 00359 return rvalue; 00360 } 00361 00362 /** 00363 * @brief Reads the SD card SCD register. 00364 * Reading the contents of the CSD register in SPI mode is a simple 00365 * read-block transaction. 00366 * @param Csd: pointer on an SCD register structure 00367 * @retval SD status 00368 */ 00369 static uint8_t SD_GetCSDRegister(SD_CSD* Csd) 00370 { 00371 uint32_t counter = 0; 00372 uint8_t rvalue = SD_RESPONSE_FAILURE; 00373 uint8_t CSD_Tab[16]; 00374 00375 /* Send CMD9 (CSD register) or CMD10(CSD register) and Wait for response in the R1 format (0x00 is no errors) */ 00376 if (!SD_IO_WriteCmd(SD_CMD_SEND_CSD, 0, 0xFF, SD_RESPONSE_NO_ERROR)) 00377 { 00378 if (!SD_IO_WaitResponse(SD_START_DATA_SINGLE_BLOCK_READ)) 00379 { 00380 for (counter = 0; counter < 16; counter++) 00381 { 00382 /* Store CSD register value on CSD_Tab */ 00383 CSD_Tab[counter] = SD_IO_ReadByte(); 00384 } 00385 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 /* Set response value to success */ 00391 rvalue = SD_RESPONSE_NO_ERROR; 00392 } 00393 } 00394 /* Send dummy byte: 8 Clock pulses of delay */ 00395 SD_IO_WriteDummy(); 00396 00397 if(rvalue == SD_RESPONSE_NO_ERROR) 00398 { 00399 /* Byte 0 */ 00400 Csd->CSDStruct = (CSD_Tab[0] & 0xC0) >> 6; 00401 Csd->SysSpecVersion = (CSD_Tab[0] & 0x3C) >> 2; 00402 Csd->Reserved1 = CSD_Tab[0] & 0x03; 00403 00404 /* Byte 1 */ 00405 Csd->TAAC = CSD_Tab[1]; 00406 00407 /* Byte 2 */ 00408 Csd->NSAC = CSD_Tab[2]; 00409 00410 /* Byte 3 */ 00411 Csd->MaxBusClkFrec = CSD_Tab[3]; 00412 00413 /* Byte 4 */ 00414 Csd->CardComdClasses = CSD_Tab[4] << 4; 00415 00416 /* Byte 5 */ 00417 Csd->CardComdClasses |= (CSD_Tab[5] & 0xF0) >> 4; 00418 Csd->RdBlockLen = CSD_Tab[5] & 0x0F; 00419 00420 /* Byte 6 */ 00421 Csd->PartBlockRead = (CSD_Tab[6] & 0x80) >> 7; 00422 Csd->WrBlockMisalign = (CSD_Tab[6] & 0x40) >> 6; 00423 Csd->RdBlockMisalign = (CSD_Tab[6] & 0x20) >> 5; 00424 Csd->DSRImpl = (CSD_Tab[6] & 0x10) >> 4; 00425 Csd->Reserved2 = 0; /*!< Reserved */ 00426 00427 Csd->DeviceSize = (CSD_Tab[6] & 0x03) << 10; 00428 00429 /* Byte 7 */ 00430 Csd->DeviceSize |= (CSD_Tab[7]) << 2; 00431 00432 /* Byte 8 */ 00433 Csd->DeviceSize |= (CSD_Tab[8] & 0xC0) >> 6; 00434 00435 Csd->MaxRdCurrentVDDMin = (CSD_Tab[8] & 0x38) >> 3; 00436 Csd->MaxRdCurrentVDDMax = (CSD_Tab[8] & 0x07); 00437 00438 /* Byte 9 */ 00439 Csd->MaxWrCurrentVDDMin = (CSD_Tab[9] & 0xE0) >> 5; 00440 Csd->MaxWrCurrentVDDMax = (CSD_Tab[9] & 0x1C) >> 2; 00441 Csd->DeviceSizeMul = (CSD_Tab[9] & 0x03) << 1; 00442 /* Byte 10 */ 00443 Csd->DeviceSizeMul |= (CSD_Tab[10] & 0x80) >> 7; 00444 00445 Csd->EraseGrSize = (CSD_Tab[10] & 0x40) >> 6; 00446 Csd->EraseGrMul = (CSD_Tab[10] & 0x3F) << 1; 00447 00448 /* Byte 11 */ 00449 Csd->EraseGrMul |= (CSD_Tab[11] & 0x80) >> 7; 00450 Csd->WrProtectGrSize = (CSD_Tab[11] & 0x7F); 00451 00452 /* Byte 12 */ 00453 Csd->WrProtectGrEnable = (CSD_Tab[12] & 0x80) >> 7; 00454 Csd->ManDeflECC = (CSD_Tab[12] & 0x60) >> 5; 00455 Csd->WrSpeedFact = (CSD_Tab[12] & 0x1C) >> 2; 00456 Csd->MaxWrBlockLen = (CSD_Tab[12] & 0x03) << 2; 00457 00458 /* Byte 13 */ 00459 Csd->MaxWrBlockLen |= (CSD_Tab[13] & 0xC0) >> 6; 00460 Csd->WriteBlockPaPartial = (CSD_Tab[13] & 0x20) >> 5; 00461 Csd->Reserved3 = 0; 00462 Csd->ContentProtectAppli = (CSD_Tab[13] & 0x01); 00463 00464 /* Byte 14 */ 00465 Csd->FileFormatGrouop = (CSD_Tab[14] & 0x80) >> 7; 00466 Csd->CopyFlag = (CSD_Tab[14] & 0x40) >> 6; 00467 Csd->PermWrProtect = (CSD_Tab[14] & 0x20) >> 5; 00468 Csd->TempWrProtect = (CSD_Tab[14] & 0x10) >> 4; 00469 Csd->FileFormat = (CSD_Tab[14] & 0x0C) >> 2; 00470 Csd->ECC = (CSD_Tab[14] & 0x03); 00471 00472 /* Byte 15 */ 00473 Csd->CSD_CRC = (CSD_Tab[15] & 0xFE) >> 1; 00474 Csd->Reserved4 = 1; 00475 } 00476 00477 /* Return the reponse */ 00478 return rvalue; 00479 } 00480 00481 /** 00482 * @brief Reads the SD card CID register. 00483 * Reading the contents of the CID register in SPI mode is a simple 00484 * read-block transaction. 00485 * @param Cid: pointer on an CID register structure 00486 * @retval SD status 00487 */ 00488 static uint8_t SD_GetCIDRegister(SD_CID* Cid) 00489 { 00490 uint32_t counter = 0; 00491 uint8_t rvalue = SD_RESPONSE_FAILURE; 00492 uint8_t CID_Tab[16]; 00493 00494 /* Send CMD10 (CID register) and Wait for response in the R1 format (0x00 is no errors) */ 00495 if (!SD_IO_WriteCmd(SD_CMD_SEND_CID, 0, 0xFF, SD_RESPONSE_NO_ERROR)) 00496 { 00497 if (!SD_IO_WaitResponse(SD_START_DATA_SINGLE_BLOCK_READ)) 00498 { 00499 /* Store CID register value on CID_Tab */ 00500 for (counter = 0; counter < 16; counter++) 00501 { 00502 CID_Tab[counter] = SD_IO_ReadByte(); 00503 } 00504 00505 /* Get CRC bytes (not really needed by us, but required by SD) */ 00506 SD_IO_WriteByte(SD_DUMMY_BYTE); 00507 SD_IO_WriteByte(SD_DUMMY_BYTE); 00508 00509 /* Set response value to success */ 00510 rvalue = SD_RESPONSE_NO_ERROR; 00511 } 00512 } 00513 00514 /* Send dummy byte: 8 Clock pulses of delay */ 00515 SD_IO_WriteDummy(); 00516 00517 if(rvalue == SD_RESPONSE_NO_ERROR) 00518 { 00519 /* Byte 0 */ 00520 Cid->ManufacturerID = CID_Tab[0]; 00521 00522 /* Byte 1 */ 00523 Cid->OEM_AppliID = CID_Tab[1] << 8; 00524 00525 /* Byte 2 */ 00526 Cid->OEM_AppliID |= CID_Tab[2]; 00527 00528 /* Byte 3 */ 00529 Cid->ProdName1 = CID_Tab[3] << 24; 00530 00531 /* Byte 4 */ 00532 Cid->ProdName1 |= CID_Tab[4] << 16; 00533 00534 /* Byte 5 */ 00535 Cid->ProdName1 |= CID_Tab[5] << 8; 00536 00537 /* Byte 6 */ 00538 Cid->ProdName1 |= CID_Tab[6]; 00539 00540 /* Byte 7 */ 00541 Cid->ProdName2 = CID_Tab[7]; 00542 00543 /* Byte 8 */ 00544 Cid->ProdRev = CID_Tab[8]; 00545 00546 /* Byte 9 */ 00547 Cid->ProdSN = CID_Tab[9] << 24; 00548 00549 /* Byte 10 */ 00550 Cid->ProdSN |= CID_Tab[10] << 16; 00551 00552 /* Byte 11 */ 00553 Cid->ProdSN |= CID_Tab[11] << 8; 00554 00555 /* Byte 12 */ 00556 Cid->ProdSN |= CID_Tab[12]; 00557 00558 /* Byte 13 */ 00559 Cid->Reserved1 |= (CID_Tab[13] & 0xF0) >> 4; 00560 Cid->ManufactDate = (CID_Tab[13] & 0x0F) << 8; 00561 00562 /* Byte 14 */ 00563 Cid->ManufactDate |= CID_Tab[14]; 00564 00565 /* Byte 15 */ 00566 Cid->CID_CRC = (CID_Tab[15] & 0xFE) >> 1; 00567 Cid->Reserved2 = 1; 00568 } 00569 /* Return the reponse */ 00570 return rvalue; 00571 } 00572 00573 /** 00574 * @brief Sends 5 bytes command to the SD card and get response 00575 * @param Cmd: The user expected command to send to SD card. 00576 * @param Arg: The command argument. 00577 * @param Crc: The CRC. 00578 * @param Response: Expected response from the SD card 00579 * @retval SD status 00580 */ 00581 static uint8_t SD_SendCmd(uint8_t Cmd, uint32_t Arg, uint8_t Crc, uint8_t Response) 00582 { 00583 uint8_t status; 00584 00585 status = (uint8_t)SD_IO_WriteCmd(Cmd, Arg, Crc, Response); 00586 00587 /* Send Dummy Byte */ 00588 SD_IO_WriteDummy(); 00589 00590 return status; 00591 } 00592 00593 /** 00594 * @brief Gets the SD card data response. 00595 * @param None 00596 * @retval The SD status: Read data response xxx0<status>1 00597 * - status 010: Data accecpted 00598 * - status 101: Data rejected due to a crc error 00599 * - status 110: Data rejected due to a Write error. 00600 * - status 111: Data rejected due to other error. 00601 */ 00602 static uint8_t SD_GetDataResponse(void) 00603 { 00604 uint32_t counter = 0; 00605 uint8_t response = SD_RESPONSE_FAILURE; 00606 uint8_t rvalue = SD_DATA_OTHER_ERROR; 00607 00608 while (counter <= 64) 00609 { 00610 /* Read response */ 00611 response = SD_IO_ReadByte(); 00612 00613 /* Mask unused bits */ 00614 response &= 0x1F; 00615 switch (response) 00616 { 00617 case SD_DATA_OK: 00618 { 00619 rvalue = SD_DATA_OK; 00620 break; 00621 } 00622 case SD_DATA_CRC_ERROR: 00623 return SD_DATA_CRC_ERROR; 00624 case SD_DATA_WRITE_ERROR: 00625 return SD_DATA_WRITE_ERROR; 00626 default: 00627 { 00628 rvalue = SD_DATA_OTHER_ERROR; 00629 break; 00630 } 00631 } 00632 /* Exit loop in case of data ok */ 00633 if (rvalue == SD_DATA_OK) 00634 break; 00635 00636 /* Increment loop counter */ 00637 counter++; 00638 } 00639 00640 /* Wait null data */ 00641 while (SD_IO_ReadByte() == 0); 00642 00643 /* Return response */ 00644 return response; 00645 } 00646 00647 /** 00648 * @brief Returns the SD status. 00649 * @param None 00650 * @retval The SD status. 00651 */ 00652 uint8_t BSP_SD_GetStatus(void) 00653 { 00654 uint16_t status = 0; 00655 00656 /* Send CMD13 (SD_SEND_STATUS) to get SD status */ 00657 SD_SendCmd(SD_CMD_SEND_STATUS, 0, 0xFF, SD_NO_RESPONSE_EXPECTED); 00658 00659 status = SD_IO_ReadByte(); 00660 status |= (uint16_t)(SD_IO_ReadByte() << 8); 00661 00662 /* Send Dummy Byte */ 00663 SD_IO_WriteDummy(); 00664 00665 /* Find SD status according to card state */ 00666 if (status == SD_RESPONSE_NO_ERROR) 00667 { 00668 return MSD_OK; 00669 } 00670 else 00671 { 00672 return MSD_ERROR; 00673 } 00674 } 00675 00676 /** 00677 * @brief Put the SD in Idle state. 00678 * @param None 00679 * @retval SD status 00680 */ 00681 static uint8_t SD_GoIdleState(void) 00682 { 00683 /* Send CMD0 (SD_CMD_GO_IDLE_STATE) to put SD in SPI mode and 00684 wait for In Idle State Response (R1 Format) equal to 0x01 */ 00685 if (SD_SendCmd(SD_CMD_GO_IDLE_STATE, 0, 0x95, SD_IN_IDLE_STATE) != SD_RESPONSE_NO_ERROR) 00686 { 00687 /* No Idle State Response: return response failue */ 00688 return SD_RESPONSE_FAILURE; 00689 } 00690 00691 /*----------Activates the card initialization process-----------*/ 00692 /* Send CMD1 (Activates the card process) until response equal to 0x0 and 00693 Wait for no error Response (R1 Format) equal to 0x00 */ 00694 while (SD_SendCmd(SD_CMD_SEND_OP_COND, 0, 0xFF, SD_RESPONSE_NO_ERROR) != SD_RESPONSE_NO_ERROR); 00695 00696 return SD_RESPONSE_NO_ERROR; 00697 } 00698 00699 /** 00700 * @brief Erases the specified memory area of the given SD card. 00701 * @param StartAddr: Start byte address 00702 * @param EndAddr: End byte address 00703 * @retval SD status 00704 */ 00705 uint8_t BSP_SD_Erase(uint32_t StartAddr, uint32_t EndAddr) 00706 { 00707 uint8_t rvalue = SD_RESPONSE_FAILURE; 00708 00709 /* Send CMD32 (Erase group start) and check if the SD acknowledged the erase command: R1 response (0x00: no errors) */ 00710 if (!SD_SendCmd(SD_CMD_SD_ERASE_GRP_START, StartAddr, 0xFF, SD_RESPONSE_NO_ERROR)) 00711 { 00712 /* Send CMD33 (Erase group end) and Check if the SD acknowledged the erase command: R1 response (0x00: no errors) */ 00713 if (!SD_SendCmd(SD_CMD_SD_ERASE_GRP_END, EndAddr, 0xFF, SD_RESPONSE_NO_ERROR)) 00714 { 00715 /* Send CMD38 (Erase) and Check if the SD acknowledged the erase command: R1 response (0x00: no errors) */ 00716 if (!SD_SendCmd(SD_CMD_ERASE, 0, 0xFF, SD_RESPONSE_NO_ERROR)) 00717 { 00718 /* Verify that SD card is ready to use after the specific command ERASE */ 00719 rvalue = (uint8_t)SD_IO_WaitResponse(SD_RESPONSE_NO_ERROR); 00720 } 00721 } 00722 } 00723 00724 /* Return the reponse */ 00725 if (rvalue == SD_RESPONSE_NO_ERROR) 00726 { 00727 return MSD_OK; 00728 } 00729 else 00730 { 00731 return MSD_ERROR; 00732 } 00733 } 00734 00735 /** 00736 * @} 00737 */ 00738 00739 /** 00740 * @} 00741 */ 00742 00743 /** 00744 * @} 00745 */ 00746 00747 /** 00748 * @} 00749 */ 00750 00751 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
Generated on Tue Jul 12 2022 20:10:41 by
