STM8S/A Standard Peripherals Firmware Library
|
stm8s_eval_spi_sd.c
Go to the documentation of this file.
00001 /** 00002 ****************************************************************************** 00003 * @file stm8s_eval_spi_sd.c 00004 * @author MCD Application Team 00005 * @version V1.0.1 00006 * @date 30-September-2014 00007 * @brief This file provides a set of functions needed to manage the SPI SD 00008 * Card memory mounted on STM8xx-EVAL board (refer to stm8s_eval.h 00009 * to know about the boards supporting this memory). 00010 * It implements a high level communication layer for read and write 00011 * from/to this memory. The needed STM8 hardware resources (SPI and 00012 * GPIO) are defined in stm8xx_eval.h file, and the initialization is 00013 * performed in SD_LowLevel_Init() function declared in stm8xx_eval.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_LowLevel_Init() function. 00018 * 00019 * +-------------------------------------------------------+ 00020 * | Pin assignment | 00021 * +-------------------------+---------------+-------------+ 00022 * | STM8 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 * 00034 * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); 00035 * You may not use this file except in compliance with the License. 00036 * You may obtain a copy of the License at: 00037 * 00038 * http://www.st.com/software_license_agreement_liberty_v2 00039 * 00040 * Unless required by applicable law or agreed to in writing, software 00041 * distributed under the License is distributed on an "AS IS" BASIS, 00042 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00043 * See the License for the specific language governing permissions and 00044 * limitations under the License. 00045 * 00046 ****************************************************************************** 00047 */ 00048 00049 /* Includes ------------------------------------------------------------------*/ 00050 #include "stm8s_eval_spi_sd.h" 00051 00052 /** @addtogroup Utilities 00053 * @{ 00054 */ 00055 00056 /** @addtogroup STM8S_EVAL 00057 * @{ 00058 */ 00059 00060 /** @addtogroup Common 00061 * @{ 00062 */ 00063 00064 /* Private typedef -----------------------------------------------------------*/ 00065 /* Private define ------------------------------------------------------------*/ 00066 /* Private macro -------------------------------------------------------------*/ 00067 /* Private function prototypes -----------------------------------------------*/ 00068 00069 /** @defgroup STM8S_EVAL_SPI_SD_Private_Functions 00070 * @{ 00071 */ 00072 00073 /** 00074 * @brief DeInitializes the SD/SD communication. 00075 * @param None 00076 * @retval None 00077 */ 00078 void SD_DeInit(void) 00079 { 00080 SD_LowLevel_DeInit(); 00081 } 00082 00083 /** 00084 * @brief Initializes the SD/SD communication. 00085 * @param None 00086 * @retval The SD Response: 00087 * - SD_RESPONSE_FAILURE: Sequence failed 00088 * - SD_RESPONSE_NO_ERROR: Sequence succeed 00089 */ 00090 uint8_t SD_Init(void) 00091 { 00092 uint32_t i = 0; 00093 00094 /*!< Initialize SD_SPI */ 00095 SD_LowLevel_Init(); 00096 00097 /*!< SD chip select high */ 00098 SD_CS_LOW(); 00099 00100 /*!< Send dummy byte 0xFF, 10 times with CS high */ 00101 /*!< Rise CS and MOSI for 80 clocks cycles */ 00102 for (i = 0; i <= 9; i++) 00103 { 00104 /*!< Send dummy byte 0xFF */ 00105 SD_WriteByte(SD_DUMMY_BYTE); 00106 } 00107 /*------------Put SD in SPI mode--------------*/ 00108 /*!< SD initialized and set to SPI mode properly */ 00109 return (SD_GoIdleState()); 00110 } 00111 00112 /** 00113 * @brief Detect if SD card is correctly plugged in the memory slot. 00114 * @param None 00115 * @retval Return if SD is detected or not 00116 */ 00117 uint8_t SD_Detect(void) 00118 { 00119 __IO uint8_t status = SD_PRESENT; 00120 00121 /*!< Check GPIO to detect SD */ 00122 if (GPIO_ReadInputData(SD_DETECT_GPIO_PORT) & SD_DETECT_PIN) 00123 { 00124 status = SD_NOT_PRESENT; 00125 } 00126 return status; 00127 } 00128 00129 /** 00130 * @brief Returns information about specific card. 00131 * @param cardinfo: pointer to a SD_CardInfo structure that contains all SD 00132 * card information. 00133 * @retval The SD Response: 00134 * - SD_RESPONSE_FAILURE: Sequence failed 00135 * - SD_RESPONSE_NO_ERROR: Sequence succeed 00136 */ 00137 uint8_t SD_GetCardInfo(SD_CardInfo *cardinfo) 00138 { 00139 uint8_t status = SD_RESPONSE_FAILURE; 00140 00141 status = SD_GetCSDRegister(&(cardinfo->SD_csd)); 00142 status = SD_GetCIDRegister(&(cardinfo->SD_cid)); 00143 cardinfo->CardCapacity = (cardinfo->SD_csd.DeviceSize + 1) ; 00144 cardinfo->CardCapacity *= (1 << (cardinfo->SD_csd.DeviceSizeMul + 2)); 00145 cardinfo->CardBlockSize = 1 << (cardinfo->SD_csd.RdBlockLen); 00146 cardinfo->CardCapacity *= cardinfo->CardBlockSize; 00147 00148 /*!< Returns the response */ 00149 return status; 00150 } 00151 00152 /** 00153 * @brief Reads a block of data from the SD. 00154 * @param pBuffer: pointer to the buffer that receives the data read from the 00155 * SD. 00156 * @param ReadAddr: SD's internal address to read from. 00157 * @param BlockSize: the SD card Data block size. 00158 * @retval The SD Response: 00159 * - SD_RESPONSE_FAILURE: Sequence failed 00160 * - SD_RESPONSE_NO_ERROR: Sequence succeed 00161 */ 00162 uint8_t SD_ReadBlock(uint8_t* pBuffer, uint32_t ReadAddr, uint16_t BlockSize) 00163 { 00164 uint32_t i = 0; 00165 uint8_t rvalue = SD_RESPONSE_FAILURE; 00166 00167 /*!< SD chip select low */ 00168 SD_CS_LOW(); 00169 00170 /*!< Send CMD17 (SD_CMD_READ_SINGLE_BLOCK) to read one block */ 00171 SD_SendCmd(SD_CMD_READ_SINGLE_BLOCK, ReadAddr, 0xFF); 00172 00173 /*!< Check if the SD acknowledged the read block command: R1 response (0x00: no errors) */ 00174 if (!SD_GetResponse(SD_RESPONSE_NO_ERROR)) 00175 { 00176 /*!< Now look for the data token to signify the start of the data */ 00177 if (!SD_GetResponse(SD_START_DATA_SINGLE_BLOCK_READ)) 00178 { 00179 /*!< Read the SD block data : read NumByteToRead data */ 00180 for (i = 0; i < BlockSize; i++) 00181 { 00182 /*!< Save the received data */ 00183 *pBuffer = SD_ReadByte(); 00184 00185 /*!< Point to the next location where the byte read will be saved */ 00186 pBuffer++; 00187 } 00188 /*!< Get CRC bytes (not really needed by us, but required by SD) */ 00189 SD_ReadByte(); 00190 SD_ReadByte(); 00191 /*!< Set response value to success */ 00192 rvalue = SD_RESPONSE_NO_ERROR; 00193 } 00194 } 00195 /*!< SD chip select high */ 00196 SD_CS_HIGH(); 00197 00198 /*!< Send dummy byte: 8 Clock pulses of delay */ 00199 SD_WriteByte(SD_DUMMY_BYTE); 00200 00201 /*!< Returns the response */ 00202 return rvalue; 00203 00204 } 00205 00206 /** 00207 * @brief Read a buffer (many blocks) from the SD card. 00208 * @param pBuffer : pointer to the buffer that receives the data read from the SD. 00209 * @param ReadAddr : SD's internal address to read from. 00210 * @param NumByteToRead : number of bytes to read from the SD. 00211 * @retval SD Response: 00212 * - SD_RESPONSE_FAILURE: Sequence failed. 00213 * - SD_RESPONSE_NO_ERROR: Sequence succeed. 00214 */ 00215 uint8_t SD_ReadBuffer(uint8_t *pBuffer, uint32_t ReadAddr, uint32_t NumByteToRead) 00216 { 00217 uint32_t i = 0, NbrOfBlock = 0, Offset = 0; 00218 uint8_t rvalue = SD_RESPONSE_FAILURE; 00219 00220 /* Calculate number of blocks to read */ 00221 NbrOfBlock = NumByteToRead / SD_BLOCK_SIZE; 00222 /* SD chip select low */ 00223 SD_CS_LOW(); 00224 00225 /* Data transfer */ 00226 while (NbrOfBlock --) 00227 { 00228 /* Send CMD17 (SD_READ_SINGLE_BLOCK) to read one block */ 00229 SD_SendCmd (SD_CMD_READ_SINGLE_BLOCK, ReadAddr + Offset, 0xFF); 00230 /* Check if the SD acknowledged the read block command: R1 response (0x00: no errors) */ 00231 if (SD_GetResponse(SD_RESPONSE_NO_ERROR)) 00232 { 00233 return SD_RESPONSE_FAILURE; 00234 } 00235 /* Now look for the data token to signify the start of the data */ 00236 if (!SD_GetResponse(SD_START_DATA_SINGLE_BLOCK_READ)) 00237 { 00238 /* Read the SD block data : read NumByteToRead data */ 00239 for (i = 0; i < SD_BLOCK_SIZE; i++) 00240 { 00241 /* Read the pointed data */ 00242 *pBuffer = SD_ReadByte(); 00243 /* Point to the next location where the byte read will be saved */ 00244 pBuffer++; 00245 } 00246 /* Set next read address*/ 00247 Offset += 512; 00248 /* get CRC bytes (not really needed by us, but required by SD) */ 00249 SD_ReadByte(); 00250 SD_ReadByte(); 00251 /* Set response value to success */ 00252 rvalue = SD_RESPONSE_NO_ERROR; 00253 } 00254 else 00255 { 00256 /* Set response value to failure */ 00257 rvalue = SD_RESPONSE_FAILURE; 00258 } 00259 } 00260 00261 /* SD chip select high */ 00262 SD_CS_HIGH(); 00263 /* Send dummy byte: 8 Clock pulses of delay */ 00264 SD_WriteByte(SD_DUMMY_BYTE); 00265 /* Returns the response */ 00266 return rvalue; 00267 } 00268 00269 /** 00270 * @brief Writes a block on the SD 00271 * @param pBuffer: pointer to the buffer containing the data to be written on 00272 * the SD. 00273 * @param WriteAddr: address to write on. 00274 * @param BlockSize: the SD card Data block size. 00275 * @retval The SD Response: 00276 * - SD_RESPONSE_FAILURE: Sequence failed 00277 * - SD_RESPONSE_NO_ERROR: Sequence succeed 00278 */ 00279 uint8_t SD_WriteBlock(uint8_t* pBuffer, uint32_t WriteAddr, uint16_t BlockSize) 00280 { 00281 uint32_t i = 0; 00282 uint8_t rvalue = SD_RESPONSE_FAILURE; 00283 00284 /*!< SD chip select low */ 00285 SD_CS_LOW(); 00286 00287 /*!< Send CMD24 (SD_CMD_WRITE_SINGLE_BLOCK) to write multiple block */ 00288 SD_SendCmd(SD_CMD_WRITE_SINGLE_BLOCK, WriteAddr, 0xFF); 00289 00290 /*!< Check if the SD acknowledged the write block command: R1 response (0x00: no errors) */ 00291 if (!SD_GetResponse(SD_RESPONSE_NO_ERROR)) 00292 { 00293 /*!< Send a dummy byte */ 00294 SD_WriteByte(SD_DUMMY_BYTE); 00295 00296 /*!< Send the data token to signify the start of the data */ 00297 SD_WriteByte(0xFE); 00298 00299 /*!< Write the block data to SD : write count data by block */ 00300 for (i = 0; i < BlockSize; i++) 00301 { 00302 /*!< Send the pointed byte */ 00303 SD_WriteByte(*pBuffer); 00304 /*!< Point to the next location where the byte read will be saved */ 00305 pBuffer++; 00306 } 00307 00308 /* Send DUMMY bytes when the number of data to be written are lower 00309 than the SD card BLOCK size (512 Byte) */ 00310 for (; i != SD_BLOCK_SIZE; i++) 00311 { 00312 /* Send the pointed byte */ 00313 SD_WriteByte(SD_DUMMY_BYTE); 00314 } 00315 00316 /*!< Put CRC bytes (not really needed by us, but required by SD) */ 00317 SD_ReadByte(); 00318 SD_ReadByte(); 00319 00320 /*!< Read data response */ 00321 if (SD_GetDataResponse() == SD_DATA_OK) 00322 { 00323 rvalue = SD_RESPONSE_NO_ERROR; 00324 } 00325 } 00326 /*!< SD chip select high */ 00327 SD_CS_HIGH(); 00328 /*!< Send dummy byte: 8 Clock pulses of delay */ 00329 SD_WriteByte(SD_DUMMY_BYTE); 00330 00331 /*!< Returns the response */ 00332 return rvalue; 00333 00334 } 00335 00336 00337 /** 00338 * @brief Write a buffer (many blocks) in the SD card. 00339 * @note The amount of data to write should be a multiple of SD card BLOCK 00340 * size (512 Byte). 00341 * @param pBuffer : pointer to the buffer containing the data to be written on the SD. 00342 * @param WriteAddr : address to write on. 00343 * @param NumByteToWrite : number of data to write. 00344 * @retval SD Response: 00345 * - SD_RESPONSE_FAILURE: Sequence failed. 00346 * - SD_RESPONSE_NO_ERROR: Sequence succeed. 00347 */ 00348 uint8_t SD_WriteBuffer(uint8_t *pBuffer, uint32_t WriteAddr, uint32_t NumByteToWrite) 00349 { 00350 uint32_t i = 0, NbrOfBlock = 0, Offset = 0; 00351 uint8_t rvalue = SD_RESPONSE_FAILURE; 00352 00353 /* Calculate number of blocks to write */ 00354 NbrOfBlock = NumByteToWrite / SD_BLOCK_SIZE; 00355 /* SD chip select low */ 00356 SD_CS_LOW(); 00357 00358 /* Data transfer */ 00359 while (NbrOfBlock--) 00360 { 00361 /* Send CMD24 (SD_WRITE_BLOCK) to write blocks */ 00362 SD_SendCmd(SD_CMD_WRITE_SINGLE_BLOCK, WriteAddr + Offset, 0xFF); 00363 00364 /* Check if the SD acknowledged the write block command: R1 response (0x00: no errors) */ 00365 if (SD_GetResponse(SD_RESPONSE_NO_ERROR)) 00366 { 00367 return SD_RESPONSE_FAILURE; 00368 } 00369 /* Send dummy byte */ 00370 SD_WriteByte(SD_DUMMY_BYTE); 00371 /* Send the data token to signify the start of the data */ 00372 SD_WriteByte(SD_START_DATA_SINGLE_BLOCK_WRITE); 00373 /* Write the block data to SD : write count data by block */ 00374 for (i = 0; i < SD_BLOCK_SIZE; i++) 00375 { 00376 /* Send the pointed byte */ 00377 SD_WriteByte(*pBuffer); 00378 /* Point to the next location where the byte read will be saved */ 00379 pBuffer++; 00380 } 00381 /* Set next write address */ 00382 Offset += 512; 00383 /* Put CRC bytes (not really needed by us, but required by SD) */ 00384 SD_ReadByte(); 00385 SD_ReadByte(); 00386 /* Read data response */ 00387 if (SD_GetDataResponse() == SD_DATA_OK) 00388 { 00389 /* Set response value to success */ 00390 rvalue = SD_RESPONSE_NO_ERROR; 00391 } 00392 else 00393 { 00394 /* Set response value to failure */ 00395 rvalue = SD_RESPONSE_FAILURE; 00396 } 00397 } 00398 00399 /* SD chip select high */ 00400 SD_CS_HIGH(); 00401 /* Send dummy byte: 8 Clock pulses of delay */ 00402 SD_WriteByte(SD_DUMMY_BYTE); 00403 /* Returns the response */ 00404 return rvalue; 00405 } 00406 00407 /** 00408 * @brief Read the CSD card register. 00409 * Reading the contents of the CSD register in SPI mode is a simple 00410 * read-block transaction. 00411 * @param SD_csd: pointer on an SCD register structure 00412 * @retval The SD Response: 00413 * - SD_RESPONSE_FAILURE: Sequence failed 00414 * - SD_RESPONSE_NO_ERROR: Sequence succeed 00415 */ 00416 uint8_t SD_GetCSDRegister(SD_CSD* SD_csd) 00417 { 00418 uint32_t i = 0; 00419 uint8_t rvalue = SD_RESPONSE_FAILURE; 00420 uint8_t CSD_Tab[16]; 00421 00422 /*!< SD chip select low */ 00423 SD_CS_LOW(); 00424 /*!< Send CMD9 (CSD register) or CMD10(CSD register) */ 00425 SD_SendCmd(SD_CMD_SEND_CSD, 0, 0xFF); 00426 /*!< Wait for response in the R1 format (0x00 is no errors) */ 00427 if (!SD_GetResponse(SD_RESPONSE_NO_ERROR)) 00428 { 00429 if (!SD_GetResponse(SD_START_DATA_SINGLE_BLOCK_READ)) 00430 { 00431 for (i = 0; i < 16; i++) 00432 { 00433 /*!< Store CSD register value on CSD_Tab */ 00434 CSD_Tab[i] = SD_ReadByte(); 00435 } 00436 } 00437 /*!< Get CRC bytes (not really needed by us, but required by SD) */ 00438 SD_WriteByte(SD_DUMMY_BYTE); 00439 SD_WriteByte(SD_DUMMY_BYTE); 00440 /*!< Set response value to success */ 00441 rvalue = SD_RESPONSE_NO_ERROR; 00442 } 00443 /*!< SD chip select high */ 00444 SD_CS_HIGH(); 00445 /*!< Send dummy byte: 8 Clock pulses of delay */ 00446 SD_WriteByte(SD_DUMMY_BYTE); 00447 00448 /*!< Byte 0 */ 00449 SD_csd->CSDStruct = (uint8_t)((CSD_Tab[0] & 0xC0) >> 6); 00450 SD_csd->SysSpecVersion = (uint8_t)((CSD_Tab[0] & 0x3C) >> 2); 00451 SD_csd->Reserved1 = (uint8_t)(CSD_Tab[0] & 0x03); 00452 00453 /*!< Byte 1 */ 00454 SD_csd->TAAC = CSD_Tab[1]; 00455 00456 /*!< Byte 2 */ 00457 SD_csd->NSAC = CSD_Tab[2]; 00458 00459 /*!< Byte 3 */ 00460 SD_csd->MaxBusClkFrec = CSD_Tab[3]; 00461 00462 /*!< Byte 4 */ 00463 SD_csd->CardComdClasses = CSD_Tab[4] << 4; 00464 00465 /*!< Byte 5 */ 00466 SD_csd->CardComdClasses |= (CSD_Tab[5] & 0xF0) >> 4; 00467 SD_csd->RdBlockLen = (uint8_t)(CSD_Tab[5] & 0x0F); 00468 00469 /*!< Byte 6 */ 00470 SD_csd->PartBlockRead = (uint8_t)((CSD_Tab[6] & 0x80) >> 7); 00471 SD_csd->WrBlockMisalign = (uint8_t)((CSD_Tab[6] & 0x40) >> 6); 00472 SD_csd->RdBlockMisalign = (uint8_t)((CSD_Tab[6] & 0x20) >> 5); 00473 SD_csd->DSRImpl = (uint8_t)((CSD_Tab[6] & 0x10) >> 4); 00474 SD_csd->Reserved2 = 0; /*!< Reserved */ 00475 00476 SD_csd->DeviceSize = (CSD_Tab[6] & 0x03) << 10; 00477 00478 /*!< Byte 7 */ 00479 SD_csd->DeviceSize |= (CSD_Tab[7]) << 2; 00480 00481 /*!< Byte 8 */ 00482 SD_csd->DeviceSize |= (CSD_Tab[8] & 0xC0) >> 6; 00483 00484 SD_csd->MaxRdCurrentVDDMin = (uint8_t)((CSD_Tab[8] & 0x38) >> 3); 00485 SD_csd->MaxRdCurrentVDDMax = (uint8_t)((CSD_Tab[8] & 0x07)); 00486 00487 /*!< Byte 9 */ 00488 SD_csd->MaxWrCurrentVDDMin = (uint8_t)((CSD_Tab[9] & 0xE0) >> 5); 00489 SD_csd->MaxWrCurrentVDDMax = (uint8_t)((CSD_Tab[9] & 0x1C) >> 2); 00490 SD_csd->DeviceSizeMul = (uint8_t)((CSD_Tab[9] & 0x03) << 1); 00491 /*!< Byte 10 */ 00492 SD_csd->DeviceSizeMul |= (uint8_t)((CSD_Tab[10] & 0x80) >> 7); 00493 00494 SD_csd->EraseGrSize = (uint8_t)((CSD_Tab[10] & 0x40) >> 6); 00495 SD_csd->EraseGrMul = (uint8_t)((CSD_Tab[10] & 0x3F) << 1); 00496 00497 /*!< Byte 11 */ 00498 SD_csd->EraseGrMul |= (uint8_t)((CSD_Tab[11] & 0x80) >> 7); 00499 SD_csd->WrProtectGrSize = (uint8_t)((CSD_Tab[11] & 0x7F)); 00500 00501 /*!< Byte 12 */ 00502 SD_csd->WrProtectGrEnable = (uint8_t)((CSD_Tab[12] & 0x80) >> 7); 00503 SD_csd->ManDeflECC = (uint8_t)((CSD_Tab[12] & 0x60) >> 5); 00504 SD_csd->WrSpeedFact = (uint8_t)((CSD_Tab[12] & 0x1C) >> 2); 00505 SD_csd->MaxWrBlockLen = (uint8_t)((CSD_Tab[12] & 0x03) << 2); 00506 00507 /*!< Byte 13 */ 00508 SD_csd->MaxWrBlockLen |= (uint8_t)((CSD_Tab[13] & 0xC0) >> 6); 00509 SD_csd->WriteBlockPaPartial = (uint8_t)((CSD_Tab[13] & 0x20) >> 5); 00510 SD_csd->Reserved3 = 0; 00511 SD_csd->ContentProtectAppli = (uint8_t)(CSD_Tab[13] & 0x01); 00512 00513 /*!< Byte 14 */ 00514 SD_csd->FileFormatGrouop = (uint8_t)((CSD_Tab[14] & 0x80) >> 7); 00515 SD_csd->CopyFlag = (uint8_t)((CSD_Tab[14] & 0x40) >> 6); 00516 SD_csd->PermWrProtect = (uint8_t)((CSD_Tab[14] & 0x20) >> 5); 00517 SD_csd->TempWrProtect = (uint8_t)((CSD_Tab[14] & 0x10) >> 4); 00518 SD_csd->FileFormat = (uint8_t)((CSD_Tab[14] & 0x0C) >> 2); 00519 SD_csd->ECC = (uint8_t)(CSD_Tab[14] & 0x03); 00520 00521 /*!< Byte 15 */ 00522 SD_csd->CSD_CRC = (uint8_t)((CSD_Tab[15] & 0xFE) >> 1); 00523 SD_csd->Reserved4 = 1; 00524 00525 /*!< Return the response */ 00526 return rvalue; 00527 } 00528 00529 /** 00530 * @brief Read the CID card register. 00531 * Reading the contents of the CID register in SPI mode is a simple 00532 * read-block transaction. 00533 * @param SD_cid: pointer on an CID register structure 00534 * @retval The SD Response: 00535 * - SD_RESPONSE_FAILURE: Sequence failed 00536 * - SD_RESPONSE_NO_ERROR: Sequence succeed 00537 */ 00538 uint8_t SD_GetCIDRegister(SD_CID* SD_cid) 00539 { 00540 uint32_t i = 0; 00541 uint8_t rvalue = SD_RESPONSE_FAILURE; 00542 uint8_t CID_Tab[16]; 00543 00544 /*!< SD chip select low */ 00545 SD_CS_LOW(); 00546 00547 /*!< Send CMD10 (CID register) */ 00548 SD_SendCmd(SD_CMD_SEND_CID, 0, 0xFF); 00549 00550 /*!< Wait for response in the R1 format (0x00 is no errors) */ 00551 if (!SD_GetResponse(SD_RESPONSE_NO_ERROR)) 00552 { 00553 if (!SD_GetResponse(SD_START_DATA_SINGLE_BLOCK_READ)) 00554 { 00555 /*!< Store CID register value on CID_Tab */ 00556 for (i = 0; i < 16; i++) 00557 { 00558 CID_Tab[i] = SD_ReadByte(); 00559 } 00560 } 00561 /*!< Get CRC bytes (not really needed by us, but required by SD) */ 00562 SD_WriteByte(SD_DUMMY_BYTE); 00563 SD_WriteByte(SD_DUMMY_BYTE); 00564 /*!< Set response value to success */ 00565 rvalue = SD_RESPONSE_NO_ERROR; 00566 } 00567 /*!< SD chip select high */ 00568 SD_CS_HIGH(); 00569 /*!< Send dummy byte: 8 Clock pulses of delay */ 00570 SD_WriteByte(SD_DUMMY_BYTE); 00571 00572 /*!< Byte 0 */ 00573 SD_cid->ManufacturerID = CID_Tab[0]; 00574 00575 /*!< Byte 1 */ 00576 SD_cid->OEM_AppliID = CID_Tab[1] << 8; 00577 00578 /*!< Byte 2 */ 00579 SD_cid->OEM_AppliID |= CID_Tab[2]; 00580 00581 /*!< Byte 3 */ 00582 SD_cid->ProdName1 = ((uint32_t)CID_Tab[3] << 24); 00583 00584 /*!< Byte 4 */ 00585 SD_cid->ProdName1 |= ((uint32_t)CID_Tab[4] << 16); 00586 00587 /*!< Byte 5 */ 00588 SD_cid->ProdName1 |= CID_Tab[5] << 8; 00589 00590 /*!< Byte 6 */ 00591 SD_cid->ProdName1 |= CID_Tab[6]; 00592 00593 /*!< Byte 7 */ 00594 SD_cid->ProdName2 = CID_Tab[7]; 00595 00596 /*!< Byte 8 */ 00597 SD_cid->ProdRev = CID_Tab[8]; 00598 00599 /*!< Byte 9 */ 00600 SD_cid->ProdSN = ((uint32_t)CID_Tab[9] << 24); 00601 00602 /*!< Byte 10 */ 00603 SD_cid->ProdSN |= ((uint32_t)CID_Tab[10] << 16); 00604 00605 /*!< Byte 11 */ 00606 SD_cid->ProdSN |= CID_Tab[11] << 8; 00607 00608 /*!< Byte 12 */ 00609 SD_cid->ProdSN |= CID_Tab[12]; 00610 00611 /*!< Byte 13 */ 00612 SD_cid->Reserved1 |= (uint8_t)((CID_Tab[13] & 0xF0) >> 4); 00613 SD_cid->ManufactDate = (CID_Tab[13] & 0x0F) << 8; 00614 00615 /*!< Byte 14 */ 00616 SD_cid->ManufactDate |= CID_Tab[14]; 00617 00618 /*!< Byte 15 */ 00619 SD_cid->CID_CRC = (uint8_t)((CID_Tab[15] & 0xFE) >> 1); 00620 SD_cid->Reserved2 = 1; 00621 00622 /*!< Return the response */ 00623 return rvalue; 00624 } 00625 00626 /** 00627 * @brief Send 5 bytes command to the SD card. 00628 * @param Cmd: The user expected command to send to SD card. 00629 * @param Arg: The command argument. 00630 * @param Crc: The CRC. 00631 * @retval None 00632 */ 00633 void SD_SendCmd(uint8_t Cmd, uint32_t Arg, uint8_t Crc) 00634 { 00635 uint32_t i = 0x00; 00636 00637 uint8_t Frame[6]; 00638 00639 Frame[0] = (uint8_t)(Cmd | 0x40); /*!< Construct byte 1 */ 00640 00641 Frame[1] = (uint8_t)(Arg >> 24); /*!< Construct byte 2 */ 00642 00643 Frame[2] = (uint8_t)(Arg >> 16); /*!< Construct byte 3 */ 00644 00645 Frame[3] = (uint8_t)(Arg >> 8); /*!< Construct byte 4 */ 00646 00647 Frame[4] = (uint8_t)(Arg); /*!< Construct byte 5 */ 00648 00649 Frame[5] = (Crc); /*!< Construct CRC: byte 6 */ 00650 00651 for (i = 0; i < 6; i++) 00652 { 00653 SD_WriteByte(Frame[i]); /*!< Send the Cmd bytes */ 00654 } 00655 } 00656 00657 /** 00658 * @brief Get SD card data response. 00659 * @param None 00660 * @retval The SD status: Read data response xxx0<status>1 00661 * - status 010: Data accepted 00662 * - status 101: Data rejected due to a crc error 00663 * - status 110: Data rejected due to a Write error. 00664 * - status 111: Data rejected due to other error. 00665 */ 00666 uint8_t SD_GetDataResponse(void) 00667 { 00668 uint32_t i = 0; 00669 uint8_t response = 0, rvalue = 0; 00670 00671 while (i <= 64) 00672 { 00673 /*!< Read response */ 00674 response = SD_ReadByte(); 00675 /*!< Mask unused bits */ 00676 response &= 0x1F; 00677 switch (response) 00678 { 00679 case SD_DATA_OK: 00680 { 00681 rvalue = SD_DATA_OK; 00682 break; 00683 } 00684 case SD_DATA_CRC_ERROR: 00685 return SD_DATA_CRC_ERROR; 00686 case SD_DATA_WRITE_ERROR: 00687 return SD_DATA_WRITE_ERROR; 00688 default: 00689 { 00690 rvalue = SD_DATA_OTHER_ERROR; 00691 break; 00692 } 00693 } 00694 /*!< Exit loop in case of data ok */ 00695 if (rvalue == SD_DATA_OK) 00696 break; 00697 /*!< Increment loop counter */ 00698 i++; 00699 } 00700 00701 /*!< Wait null data */ 00702 while (SD_ReadByte() == 0); 00703 00704 /*!< Return response */ 00705 return response; 00706 } 00707 00708 /** 00709 * @brief Returns the SD response. 00710 * @param None 00711 * @retval The SD Response: 00712 * - SD_RESPONSE_FAILURE: Sequence failed 00713 * - SD_RESPONSE_NO_ERROR: Sequence succeed 00714 */ 00715 uint8_t SD_GetResponse(uint8_t Response) 00716 { 00717 uint32_t Count = 0xFFF; 00718 00719 /*!< Check if response is got or a timeout is happen */ 00720 while ((SD_ReadByte() != Response) && Count) 00721 { 00722 Count--; 00723 } 00724 if (Count == 0) 00725 { 00726 /*!< After time out */ 00727 return SD_RESPONSE_FAILURE; 00728 } 00729 else 00730 { 00731 /*!< Right response got */ 00732 return SD_RESPONSE_NO_ERROR; 00733 } 00734 } 00735 00736 /** 00737 * @brief Returns the SD status. 00738 * @param None 00739 * @retval The SD status. 00740 */ 00741 uint16_t SD_GetStatus(void) 00742 { 00743 uint16_t Status = 0; 00744 00745 /*!< SD chip select low */ 00746 SD_CS_LOW(); 00747 00748 /*!< Send CMD13 (SD_SEND_STATUS) to get SD status */ 00749 SD_SendCmd(SD_CMD_SEND_STATUS, 0, 0xFF); 00750 00751 Status = SD_ReadByte(); 00752 Status |= (uint16_t)(SD_ReadByte() << 8); 00753 00754 /*!< SD chip select high */ 00755 SD_CS_HIGH(); 00756 00757 /*!< Send dummy byte 0xFF */ 00758 SD_WriteByte(SD_DUMMY_BYTE); 00759 00760 return Status; 00761 } 00762 00763 /** 00764 * @brief Put SD in Idle state. 00765 * @param None 00766 * @retval The SD Response: 00767 * - SD_RESPONSE_FAILURE: Sequence failed 00768 * - SD_RESPONSE_NO_ERROR: Sequence succeed 00769 */ 00770 uint8_t SD_GoIdleState(void) 00771 { 00772 /*!< SD chip select low */ 00773 SD_CS_LOW(); 00774 00775 /*!< Send CMD0 (SD_CMD_GO_IDLE_STATE) to put SD in SPI mode */ 00776 SD_SendCmd(SD_CMD_GO_IDLE_STATE, 0, 0x95); 00777 00778 /*!< Wait for In Idle State Response (R1 Format) equal to 0x01 */ 00779 if (SD_GetResponse(SD_IN_IDLE_STATE)) 00780 { 00781 /*!< No Idle State Response: return response failure */ 00782 return SD_RESPONSE_FAILURE; 00783 } 00784 /*----------Activates the card initialization process-----------*/ 00785 do 00786 { 00787 /*!< SD chip select high */ 00788 SD_CS_HIGH(); 00789 00790 /*!< Send Dummy byte 0xFF */ 00791 SD_WriteByte(SD_DUMMY_BYTE); 00792 00793 /*!< SD chip select low */ 00794 SD_CS_LOW(); 00795 00796 /*!< Send CMD1 (Activates the card process) until response equal to 0x0 */ 00797 SD_SendCmd(SD_CMD_SEND_OP_COND, 0, 0xFF); 00798 /*!< Wait for no error Response (R1 Format) equal to 0x00 */ 00799 } 00800 while (SD_GetResponse(SD_RESPONSE_NO_ERROR)); 00801 00802 /*!< SD chip select high */ 00803 SD_CS_HIGH(); 00804 00805 /*!< Send dummy byte 0xFF */ 00806 SD_WriteByte(SD_DUMMY_BYTE); 00807 00808 return SD_RESPONSE_NO_ERROR; 00809 } 00810 00811 /** 00812 * @brief Write a byte on the SD. 00813 * @param Data: byte to send. 00814 * @retval None 00815 */ 00816 uint8_t SD_WriteByte(uint8_t Data) 00817 { 00818 /*!< Wait until the transmit buffer is empty */ 00819 while (SPI_GetFlagStatus(SPI_FLAG_TXE) == RESET) 00820 {} 00821 00822 /*!< Send the byte */ 00823 SPI_SendData(Data); 00824 00825 /*!< Wait to receive a byte*/ 00826 while (SPI_GetFlagStatus(SPI_FLAG_RXNE) == RESET) 00827 {} 00828 00829 /*!< Return the byte read from the SPI bus */ 00830 return SPI_ReceiveData(); 00831 } 00832 00833 /** 00834 * @brief Read a byte from the SD. 00835 * @param None 00836 * @retval The received byte. 00837 */ 00838 uint8_t SD_ReadByte(void) 00839 { 00840 uint8_t Data = 0; 00841 00842 /*!< Wait until the transmit buffer is empty */ 00843 while (SPI_GetFlagStatus(SPI_FLAG_TXE) == RESET) 00844 {} 00845 /*!< Send the byte */ 00846 SPI_SendData(SD_DUMMY_BYTE); 00847 00848 /*!< Wait until a data is received */ 00849 while (SPI_GetFlagStatus(SPI_FLAG_RXNE) == RESET) 00850 {} 00851 /*!< Get the received data */ 00852 Data = SPI_ReceiveData(); 00853 00854 /*!< Return the shifted data */ 00855 return Data; 00856 } 00857 00858 /** 00859 * @} 00860 */ 00861 00862 00863 /** 00864 * @} 00865 */ 00866 00867 00868 /** 00869 * @} 00870 */ 00871 00872 /** 00873 * @} 00874 */ 00875 00876 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/