STM32303C_EVAL BSP User Manual: stm32303c_eval_sd.c Source File

STM32303C EVAL BSP Drivers

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>&copy; 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   doxygen 1.7.6.1