STM3210C_EVAL BSP User Manual: stm3210c_eval_sd.c Source File

STM3210C EVAL BSP Drivers

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