|
@@ -1,942 +0,0 @@
|
|
|
-/******************** (C) COPYRIGHT 2008 STMicroelectronics ********************
|
|
|
-* File Name : msd.c
|
|
|
-* Author : MCD Application Team
|
|
|
-* Version : V2.1
|
|
|
-* Date : 05/30/2008
|
|
|
-* Description : MSD card driver source file.
|
|
|
-* Pin assignment:
|
|
|
-* ----------------------------------------------
|
|
|
-* | STM32F10x | MSD Pin |
|
|
|
-* ----------------------------------------------
|
|
|
-* | P0.4 | ChipSelect 1 |
|
|
|
-* | P0.1 / MOSI | DataIn 2 |
|
|
|
-* | | GND 3 (0 V) |
|
|
|
-* | | VDD 4 (3.3 V) |
|
|
|
-* | P0.2 / SCLK | Clock 5 |
|
|
|
-* | | GND 6 (0 V) |
|
|
|
-* | P0.0 / MISO | DataOut 7 |
|
|
|
-* -----------------------------------------------
|
|
|
-********************************************************************************
|
|
|
-* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
|
|
|
-* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE TIME.
|
|
|
-* AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
|
|
|
-* INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE
|
|
|
-* CONTENT OF SUCH SOFTWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING
|
|
|
-* INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
|
|
|
-* FOR MORE INFORMATION PLEASE CAREFULLY READ THE LICENSE AGREEMENT FILE LOCATED
|
|
|
-* IN THE ROOT DIRECTORY OF THIS FIRMWARE PACKAGE.
|
|
|
-*******************************************************************************/
|
|
|
-
|
|
|
-/* Includes ------------------------------------------------------------------*/
|
|
|
-#include "msd.h"
|
|
|
-#include <stm32f10x_spi.h>
|
|
|
-
|
|
|
-/* Private typedef -----------------------------------------------------------*/
|
|
|
-/* Private define ------------------------------------------------------------*/
|
|
|
-/* Private macro -------------------------------------------------------------*/
|
|
|
-/* Select MSD Card: ChipSelect pin low */
|
|
|
-#define MSD_CS_LOW() GPIO_ResetBits(GPIOD, GPIO_Pin_9)
|
|
|
-/* Deselect MSD Card: ChipSelect pin high */
|
|
|
-#define MSD_CS_HIGH() GPIO_SetBits(GPIOD, GPIO_Pin_9)
|
|
|
-#define MSD_SPI SPI1
|
|
|
-#define MSD_RCC_SPI RCC_APB2Periph_SPI1
|
|
|
-
|
|
|
-/* Private function prototypes -----------------------------------------------*/
|
|
|
-static void SPI_Config(void);
|
|
|
-/* Private functions ---------------------------------------------------------*/
|
|
|
-
|
|
|
-/*******************************************************************************
|
|
|
-* Function Name : MSD_Init
|
|
|
-* Description : Initializes the MSD/SD communication.
|
|
|
-* Input : None
|
|
|
-* Output : None
|
|
|
-* Return : The MSD Response: - MSD_RESPONSE_FAILURE: Sequence failed
|
|
|
-* - MSD_RESPONSE_NO_ERROR: Sequence succeed
|
|
|
-*******************************************************************************/
|
|
|
-u8 MSD_Init(void)
|
|
|
-{
|
|
|
- u32 i = 0;
|
|
|
-
|
|
|
- /* Initialize SPI */
|
|
|
- SPI_Config();
|
|
|
- /* MSD chip select high */
|
|
|
- MSD_CS_HIGH();
|
|
|
- /* Send dummy byte 0xFF, 10 times with CS high*/
|
|
|
- /* rise CS and MOSI for 80 clocks cycles */
|
|
|
- for (i = 0; i <= 9; i++)
|
|
|
- {
|
|
|
- /* Send dummy byte 0xFF */
|
|
|
- MSD_WriteByte(DUMMY);
|
|
|
- }
|
|
|
- /*------------Put MSD in SPI mode--------------*/
|
|
|
- /* MSD initialized and set to SPI mode properly */
|
|
|
- return (MSD_GoIdleState());
|
|
|
-}
|
|
|
-
|
|
|
-/*******************************************************************************
|
|
|
-* Function Name : MSD_WriteBlock
|
|
|
-* Description : Writes a block on the MSD
|
|
|
-* Input : - pBuffer : pointer to the buffer containing the data to be
|
|
|
-* written on the MSD.
|
|
|
-* - WriteAddr : address to write on.
|
|
|
-* - NumByteToWrite: number of data to write
|
|
|
-* Output : None
|
|
|
-* Return : The MSD Response: - MSD_RESPONSE_FAILURE: Sequence failed
|
|
|
-* - MSD_RESPONSE_NO_ERROR: Sequence succeed
|
|
|
-*******************************************************************************/
|
|
|
-u8 MSD_WriteBlock(u8* pBuffer, u32 WriteAddr, u16 NumByteToWrite)
|
|
|
-{
|
|
|
- u32 i = 0;
|
|
|
- u8 rvalue = MSD_RESPONSE_FAILURE;
|
|
|
-
|
|
|
- /* MSD chip select low */
|
|
|
- MSD_CS_LOW();
|
|
|
- /* Send CMD24 (MSD_WRITE_BLOCK) to write multiple block */
|
|
|
- MSD_SendCmd(MSD_WRITE_BLOCK, WriteAddr, 0xFF);
|
|
|
-
|
|
|
- /* Check if the MSD acknowledged the write block command: R1 response (0x00: no errors) */
|
|
|
- if (!MSD_GetResponse(MSD_RESPONSE_NO_ERROR))
|
|
|
- {
|
|
|
- /* Send a dummy byte */
|
|
|
- MSD_WriteByte(DUMMY);
|
|
|
- /* Send the data token to signify the start of the data */
|
|
|
- MSD_WriteByte(0xFE);
|
|
|
- /* Write the block data to MSD : write count data by block */
|
|
|
- for (i = 0; i < NumByteToWrite; i++)
|
|
|
- {
|
|
|
- /* Send the pointed byte */
|
|
|
- MSD_WriteByte(*pBuffer);
|
|
|
- /* Point to the next location where the byte read will be saved */
|
|
|
- pBuffer++;
|
|
|
- }
|
|
|
- /* Put CRC bytes (not really needed by us, but required by MSD) */
|
|
|
- MSD_ReadByte();
|
|
|
- MSD_ReadByte();
|
|
|
- /* Read data response */
|
|
|
- if (MSD_GetDataResponse() == MSD_DATA_OK)
|
|
|
- {
|
|
|
- rvalue = MSD_RESPONSE_NO_ERROR;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /* MSD chip select high */
|
|
|
- MSD_CS_HIGH();
|
|
|
- /* Send dummy byte: 8 Clock pulses of delay */
|
|
|
- MSD_WriteByte(DUMMY);
|
|
|
- /* Returns the reponse */
|
|
|
- return rvalue;
|
|
|
-}
|
|
|
-
|
|
|
-/*******************************************************************************
|
|
|
-* Function Name : MSD_ReadBlock
|
|
|
-* Description : Reads a block of data from the MSD.
|
|
|
-* Input : - pBuffer : pointer to the buffer that receives the data read
|
|
|
-* from the MSD.
|
|
|
-* - ReadAddr : MSD's internal address to read from.
|
|
|
-* - NumByteToRead : number of bytes to read from the MSD.
|
|
|
-* Output : None
|
|
|
-* Return : The MSD Response: - MSD_RESPONSE_FAILURE: Sequence failed
|
|
|
-* - MSD_RESPONSE_NO_ERROR: Sequence succeed
|
|
|
-*******************************************************************************/
|
|
|
-u8 MSD_ReadBlock(u8* pBuffer, u32 ReadAddr, u16 NumByteToRead)
|
|
|
-{
|
|
|
- u32 i = 0;
|
|
|
- u8 rvalue = MSD_RESPONSE_FAILURE;
|
|
|
-
|
|
|
- /* MSD chip select low */
|
|
|
- MSD_CS_LOW();
|
|
|
- /* Send CMD17 (MSD_READ_SINGLE_BLOCK) to read one block */
|
|
|
- MSD_SendCmd(MSD_READ_SINGLE_BLOCK, ReadAddr, 0xFF);
|
|
|
-
|
|
|
- /* Check if the MSD acknowledged the read block command: R1 response (0x00: no errors) */
|
|
|
- if (!MSD_GetResponse(MSD_RESPONSE_NO_ERROR))
|
|
|
- {
|
|
|
- /* Now look for the data token to signify the start of the data */
|
|
|
- if (!MSD_GetResponse(MSD_START_DATA_SINGLE_BLOCK_READ))
|
|
|
- {
|
|
|
- /* Read the MSD block data : read NumByteToRead data */
|
|
|
- for (i = 0; i < NumByteToRead; i++)
|
|
|
- {
|
|
|
- /* Save the received data */
|
|
|
- *pBuffer = MSD_ReadByte();
|
|
|
- /* Point to the next location where the byte read will be saved */
|
|
|
- pBuffer++;
|
|
|
- }
|
|
|
- /* Get CRC bytes (not really needed by us, but required by MSD) */
|
|
|
- MSD_ReadByte();
|
|
|
- MSD_ReadByte();
|
|
|
- /* Set response value to success */
|
|
|
- rvalue = MSD_RESPONSE_NO_ERROR;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /* MSD chip select high */
|
|
|
- MSD_CS_HIGH();
|
|
|
- /* Send dummy byte: 8 Clock pulses of delay */
|
|
|
- MSD_WriteByte(DUMMY);
|
|
|
- /* Returns the reponse */
|
|
|
- return rvalue;
|
|
|
-}
|
|
|
-
|
|
|
-/*******************************************************************************
|
|
|
-* Function Name : MSD_WriteBuffer
|
|
|
-* Description : Writes many blocks on the MSD
|
|
|
-* Input : - pBuffer : pointer to the buffer containing the data to be
|
|
|
-* written on the MSD.
|
|
|
-* - WriteAddr : address to write on.
|
|
|
-* - NumByteToWrite: number of data to write
|
|
|
-* Output : None
|
|
|
-* Return : The MSD Response: - MSD_RESPONSE_FAILURE: Sequence failed
|
|
|
-* - MSD_RESPONSE_NO_ERROR: Sequence succeed
|
|
|
-*******************************************************************************/
|
|
|
-u8 MSD_WriteBuffer(u8* pBuffer, u32 WriteAddr, u32 NumByteToWrite)
|
|
|
-{
|
|
|
- u32 i = 0, NbrOfBlock = 0, Offset = 0;
|
|
|
- u8 rvalue = MSD_RESPONSE_FAILURE;
|
|
|
-
|
|
|
- /* Calculate number of blocks to write */
|
|
|
- NbrOfBlock = NumByteToWrite / BLOCK_SIZE;
|
|
|
- /* MSD chip select low */
|
|
|
- MSD_CS_LOW();
|
|
|
-
|
|
|
- /* Data transfer */
|
|
|
- while (NbrOfBlock --)
|
|
|
- {
|
|
|
- /* Send CMD24 (MSD_WRITE_BLOCK) to write blocks */
|
|
|
- MSD_SendCmd(MSD_WRITE_BLOCK, WriteAddr + Offset, 0xFF);
|
|
|
-
|
|
|
- /* Check if the MSD acknowledged the write block command: R1 response (0x00: no errors) */
|
|
|
- if (MSD_GetResponse(MSD_RESPONSE_NO_ERROR))
|
|
|
- {
|
|
|
- return MSD_RESPONSE_FAILURE;
|
|
|
- }
|
|
|
- /* Send dummy byte */
|
|
|
- MSD_WriteByte(DUMMY);
|
|
|
- /* Send the data token to signify the start of the data */
|
|
|
- MSD_WriteByte(MSD_START_DATA_SINGLE_BLOCK_WRITE);
|
|
|
- /* Write the block data to MSD : write count data by block */
|
|
|
- for (i = 0; i < BLOCK_SIZE; i++)
|
|
|
- {
|
|
|
- /* Send the pointed byte */
|
|
|
- MSD_WriteByte(*pBuffer);
|
|
|
- /* Point to the next location where the byte read will be saved */
|
|
|
- pBuffer++;
|
|
|
- }
|
|
|
- /* Set next write address */
|
|
|
- Offset += 512;
|
|
|
- /* Put CRC bytes (not really needed by us, but required by MSD) */
|
|
|
- MSD_ReadByte();
|
|
|
- MSD_ReadByte();
|
|
|
- /* Read data response */
|
|
|
- if (MSD_GetDataResponse() == MSD_DATA_OK)
|
|
|
- {
|
|
|
- /* Set response value to success */
|
|
|
- rvalue = MSD_RESPONSE_NO_ERROR;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- /* Set response value to failure */
|
|
|
- rvalue = MSD_RESPONSE_FAILURE;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /* MSD chip select high */
|
|
|
- MSD_CS_HIGH();
|
|
|
- /* Send dummy byte: 8 Clock pulses of delay */
|
|
|
- MSD_WriteByte(DUMMY);
|
|
|
- /* Returns the reponse */
|
|
|
- return rvalue;
|
|
|
-}
|
|
|
-
|
|
|
-/*******************************************************************************
|
|
|
-* Function Name : MSD_ReadBuffer
|
|
|
-* Description : Reads multiple block of data from the MSD.
|
|
|
-* Input : - pBuffer : pointer to the buffer that receives the data read
|
|
|
-* from the MSD.
|
|
|
-* - ReadAddr : MSD's internal address to read from.
|
|
|
-* - NumByteToRead : number of bytes to read from the MSD.
|
|
|
-* Output : None
|
|
|
-* Return : The MSD Response: - MSD_RESPONSE_FAILURE: Sequence failed
|
|
|
-* - MSD_RESPONSE_NO_ERROR: Sequence succeed
|
|
|
-*******************************************************************************/
|
|
|
-u8 MSD_ReadBuffer(u8* pBuffer, u32 ReadAddr, u32 NumByteToRead)
|
|
|
-{
|
|
|
- u32 i = 0, NbrOfBlock = 0, Offset = 0;
|
|
|
- u8 rvalue = MSD_RESPONSE_FAILURE;
|
|
|
-
|
|
|
- /* Calculate number of blocks to read */
|
|
|
- NbrOfBlock = NumByteToRead / BLOCK_SIZE;
|
|
|
- /* MSD chip select low */
|
|
|
- MSD_CS_LOW();
|
|
|
-
|
|
|
- /* Data transfer */
|
|
|
- while (NbrOfBlock --)
|
|
|
- {
|
|
|
- /* Send CMD17 (MSD_READ_SINGLE_BLOCK) to read one block */
|
|
|
- MSD_SendCmd (MSD_READ_SINGLE_BLOCK, ReadAddr + Offset, 0xFF);
|
|
|
- /* Check if the MSD acknowledged the read block command: R1 response (0x00: no errors) */
|
|
|
- if (MSD_GetResponse(MSD_RESPONSE_NO_ERROR))
|
|
|
- {
|
|
|
- return MSD_RESPONSE_FAILURE;
|
|
|
- }
|
|
|
- /* Now look for the data token to signify the start of the data */
|
|
|
- if (!MSD_GetResponse(MSD_START_DATA_SINGLE_BLOCK_READ))
|
|
|
- {
|
|
|
- /* Read the MSD block data : read NumByteToRead data */
|
|
|
- for (i = 0; i < BLOCK_SIZE; i++)
|
|
|
- {
|
|
|
- /* Read the pointed data */
|
|
|
- *pBuffer = MSD_ReadByte();
|
|
|
- /* Point to the next location where the byte read will be saved */
|
|
|
- pBuffer++;
|
|
|
- }
|
|
|
- /* Set next read address*/
|
|
|
- Offset += 512;
|
|
|
- /* get CRC bytes (not really needed by us, but required by MSD) */
|
|
|
- MSD_ReadByte();
|
|
|
- MSD_ReadByte();
|
|
|
- /* Set response value to success */
|
|
|
- rvalue = MSD_RESPONSE_NO_ERROR;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- /* Set response value to failure */
|
|
|
- rvalue = MSD_RESPONSE_FAILURE;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /* MSD chip select high */
|
|
|
- MSD_CS_HIGH();
|
|
|
- /* Send dummy byte: 8 Clock pulses of delay */
|
|
|
- MSD_WriteByte(DUMMY);
|
|
|
- /* Returns the reponse */
|
|
|
- return rvalue;
|
|
|
-}
|
|
|
-
|
|
|
-/*******************************************************************************
|
|
|
-* Function Name : MSD_GetCSDRegister
|
|
|
-* Description : Read the CSD card register.
|
|
|
-* Reading the contents of the CSD register in SPI mode
|
|
|
-* is a simple read-block transaction.
|
|
|
-* Input : - MSD_csd: pointer on an SCD register structure
|
|
|
-* Output : None
|
|
|
-* Return : The MSD Response: - MSD_RESPONSE_FAILURE: Sequence failed
|
|
|
-* - MSD_RESPONSE_NO_ERROR: Sequence succeed
|
|
|
-*******************************************************************************/
|
|
|
-u8 MSD_GetCSDRegister(sMSD_CSD* MSD_csd)
|
|
|
-{
|
|
|
- u32 i = 0;
|
|
|
- u8 rvalue = MSD_RESPONSE_FAILURE;
|
|
|
- u8 CSD_Tab[16];
|
|
|
-
|
|
|
- /* MSD chip select low */
|
|
|
- MSD_CS_LOW();
|
|
|
- /* Send CMD9 (CSD register) or CMD10(CSD register) */
|
|
|
- MSD_SendCmd(MSD_SEND_CSD, 0, 0xFF);
|
|
|
-
|
|
|
- /* Wait for response in the R1 format (0x00 is no errors) */
|
|
|
- if (!MSD_GetResponse(MSD_RESPONSE_NO_ERROR))
|
|
|
- {
|
|
|
- if (!MSD_GetResponse(MSD_START_DATA_SINGLE_BLOCK_READ))
|
|
|
- {
|
|
|
- for (i = 0; i < 16; i++)
|
|
|
- {
|
|
|
- /* Store CSD register value on CSD_Tab */
|
|
|
- CSD_Tab[i] = MSD_ReadByte();
|
|
|
- }
|
|
|
- }
|
|
|
- /* Get CRC bytes (not really needed by us, but required by MSD) */
|
|
|
- MSD_WriteByte(DUMMY);
|
|
|
- MSD_WriteByte(DUMMY);
|
|
|
- /* Set response value to success */
|
|
|
- rvalue = MSD_RESPONSE_NO_ERROR;
|
|
|
- }
|
|
|
-
|
|
|
- /* MSD chip select high */
|
|
|
- MSD_CS_HIGH();
|
|
|
- /* Send dummy byte: 8 Clock pulses of delay */
|
|
|
- MSD_WriteByte(DUMMY);
|
|
|
-
|
|
|
- /* Byte 0 */
|
|
|
- MSD_csd->CSDStruct = (CSD_Tab[0] & 0xC0) >> 6;
|
|
|
- MSD_csd->SysSpecVersion = (CSD_Tab[0] & 0x3C) >> 2;
|
|
|
- MSD_csd->Reserved1 = CSD_Tab[0] & 0x03;
|
|
|
- /* Byte 1 */
|
|
|
- MSD_csd->TAAC = CSD_Tab[1] ;
|
|
|
- /* Byte 2 */
|
|
|
- MSD_csd->NSAC = CSD_Tab[2];
|
|
|
- /* Byte 3 */
|
|
|
- MSD_csd->MaxBusClkFrec = CSD_Tab[3];
|
|
|
- /* Byte 4 */
|
|
|
- MSD_csd->CardComdClasses = CSD_Tab[4] << 4;
|
|
|
- /* Byte 5 */
|
|
|
- MSD_csd->CardComdClasses |= (CSD_Tab[5] & 0xF0) >> 4;
|
|
|
- MSD_csd->RdBlockLen = CSD_Tab[5] & 0x0F;
|
|
|
- /* Byte 6 */
|
|
|
- MSD_csd->PartBlockRead = (CSD_Tab[6] & 0x80) >> 7;
|
|
|
- MSD_csd->WrBlockMisalign = (CSD_Tab[6] & 0x40) >> 6;
|
|
|
- MSD_csd->RdBlockMisalign = (CSD_Tab[6] & 0x20) >> 5;
|
|
|
- MSD_csd->DSRImpl = (CSD_Tab[6] & 0x10) >> 4;
|
|
|
- MSD_csd->Reserved2 = 0; /* Reserved */
|
|
|
- MSD_csd->DeviceSize = (CSD_Tab[6] & 0x03) << 10;
|
|
|
- /* Byte 7 */
|
|
|
- MSD_csd->DeviceSize |= (CSD_Tab[7]) << 2;
|
|
|
- /* Byte 8 */
|
|
|
- MSD_csd->DeviceSize |= (CSD_Tab[8] & 0xC0) >> 6;
|
|
|
- MSD_csd->MaxRdCurrentVDDMin = (CSD_Tab[8] & 0x38) >> 3;
|
|
|
- MSD_csd->MaxRdCurrentVDDMax = (CSD_Tab[8] & 0x07);
|
|
|
- /* Byte 9 */
|
|
|
- MSD_csd->MaxWrCurrentVDDMin = (CSD_Tab[9] & 0xE0) >> 5;
|
|
|
- MSD_csd->MaxWrCurrentVDDMax = (CSD_Tab[9] & 0x1C) >> 2;
|
|
|
- MSD_csd->DeviceSizeMul = (CSD_Tab[9] & 0x03) << 1;
|
|
|
- /* Byte 10 */
|
|
|
- MSD_csd->DeviceSizeMul |= (CSD_Tab[10] & 0x80) >> 7;
|
|
|
- MSD_csd->EraseGrSize = (CSD_Tab[10] & 0x7C) >> 2;
|
|
|
- MSD_csd->EraseGrMul = (CSD_Tab[10] & 0x03) << 3;
|
|
|
- /* Byte 11 */
|
|
|
- MSD_csd->EraseGrMul |= (CSD_Tab[11] & 0xE0) >> 5;
|
|
|
- MSD_csd->WrProtectGrSize = (CSD_Tab[11] & 0x1F);
|
|
|
- /* Byte 12 */
|
|
|
- MSD_csd->WrProtectGrEnable = (CSD_Tab[12] & 0x80) >> 7;
|
|
|
- MSD_csd->ManDeflECC = (CSD_Tab[12] & 0x60) >> 5;
|
|
|
- MSD_csd->WrSpeedFact = (CSD_Tab[12] & 0x1C) >> 2;
|
|
|
- MSD_csd->MaxWrBlockLen = (CSD_Tab[12] & 0x03) << 2;
|
|
|
- /* Byte 13 */
|
|
|
- MSD_csd->MaxWrBlockLen |= (CSD_Tab[13] & 0xc0) >> 6;
|
|
|
- MSD_csd->WriteBlockPaPartial = (CSD_Tab[13] & 0x20) >> 5;
|
|
|
- MSD_csd->Reserved3 = 0;
|
|
|
- MSD_csd->ContentProtectAppli = (CSD_Tab[13] & 0x01);
|
|
|
- /* Byte 14 */
|
|
|
- MSD_csd->FileFormatGrouop = (CSD_Tab[14] & 0x80) >> 7;
|
|
|
- MSD_csd->CopyFlag = (CSD_Tab[14] & 0x40) >> 6;
|
|
|
- MSD_csd->PermWrProtect = (CSD_Tab[14] & 0x20) >> 5;
|
|
|
- MSD_csd->TempWrProtect = (CSD_Tab[14] & 0x10) >> 4;
|
|
|
- MSD_csd->FileFormat = (CSD_Tab[14] & 0x0C) >> 2;
|
|
|
- MSD_csd->ECC = (CSD_Tab[14] & 0x03);
|
|
|
- /* Byte 15 */
|
|
|
- MSD_csd->msd_CRC = (CSD_Tab[15] & 0xFE) >> 1;
|
|
|
- MSD_csd->Reserved4 = 1;
|
|
|
-
|
|
|
- /* Return the reponse */
|
|
|
- return rvalue;
|
|
|
-}
|
|
|
-
|
|
|
-/*******************************************************************************
|
|
|
-* Function Name : MSD_GetCIDRegister
|
|
|
-* Description : Read the CID card register.
|
|
|
-* Reading the contents of the CID register in SPI mode
|
|
|
-* is a simple read-block transaction.
|
|
|
-* Input : - MSD_cid: pointer on an CID register structure
|
|
|
-* Output : None
|
|
|
-* Return : The MSD Response: - MSD_RESPONSE_FAILURE: Sequence failed
|
|
|
-* - MSD_RESPONSE_NO_ERROR: Sequence succeed
|
|
|
-*******************************************************************************/
|
|
|
-u8 MSD_GetCIDRegister(sMSD_CID* MSD_cid)
|
|
|
-{
|
|
|
- u32 i = 0;
|
|
|
- u8 rvalue = MSD_RESPONSE_FAILURE;
|
|
|
- u8 CID_Tab[16];
|
|
|
-
|
|
|
- /* MSD chip select low */
|
|
|
- MSD_CS_LOW();
|
|
|
- /* Send CMD10 (CID register) */
|
|
|
- MSD_SendCmd(MSD_SEND_CID, 0, 0xFF);
|
|
|
-
|
|
|
- /* Wait for response in the R1 format (0x00 is no errors) */
|
|
|
- if (!MSD_GetResponse(MSD_RESPONSE_NO_ERROR))
|
|
|
- {
|
|
|
- if (!MSD_GetResponse(MSD_START_DATA_SINGLE_BLOCK_READ))
|
|
|
- {
|
|
|
- /* Store CID register value on CID_Tab */
|
|
|
- for (i = 0; i < 16; i++)
|
|
|
- {
|
|
|
- CID_Tab[i] = MSD_ReadByte();
|
|
|
- }
|
|
|
- }
|
|
|
- /* Get CRC bytes (not really needed by us, but required by MSD) */
|
|
|
- MSD_WriteByte(DUMMY);
|
|
|
- MSD_WriteByte(DUMMY);
|
|
|
- /* Set response value to success */
|
|
|
- rvalue = MSD_RESPONSE_NO_ERROR;
|
|
|
- }
|
|
|
-
|
|
|
- /* MSD chip select high */
|
|
|
- MSD_CS_HIGH();
|
|
|
- /* Send dummy byte: 8 Clock pulses of delay */
|
|
|
- MSD_WriteByte(DUMMY);
|
|
|
-
|
|
|
- /* Byte 0 */
|
|
|
- MSD_cid->ManufacturerID = CID_Tab[0];
|
|
|
- /* Byte 1 */
|
|
|
- MSD_cid->OEM_AppliID = CID_Tab[1] << 8;
|
|
|
- /* Byte 2 */
|
|
|
- MSD_cid->OEM_AppliID |= CID_Tab[2];
|
|
|
- /* Byte 3 */
|
|
|
- MSD_cid->ProdName1 = CID_Tab[3] << 24;
|
|
|
- /* Byte 4 */
|
|
|
- MSD_cid->ProdName1 |= CID_Tab[4] << 16;
|
|
|
- /* Byte 5 */
|
|
|
- MSD_cid->ProdName1 |= CID_Tab[5] << 8;
|
|
|
- /* Byte 6 */
|
|
|
- MSD_cid->ProdName1 |= CID_Tab[6];
|
|
|
- /* Byte 7 */
|
|
|
- MSD_cid->ProdName2 = CID_Tab[7];
|
|
|
- /* Byte 8 */
|
|
|
- MSD_cid->ProdRev = CID_Tab[8];
|
|
|
- /* Byte 9 */
|
|
|
- MSD_cid->ProdSN = CID_Tab[9] << 24;
|
|
|
- /* Byte 10 */
|
|
|
- MSD_cid->ProdSN |= CID_Tab[10] << 16;
|
|
|
- /* Byte 11 */
|
|
|
- MSD_cid->ProdSN |= CID_Tab[11] << 8;
|
|
|
- /* Byte 12 */
|
|
|
- MSD_cid->ProdSN |= CID_Tab[12];
|
|
|
- /* Byte 13 */
|
|
|
- MSD_cid->Reserved1 |= (CID_Tab[13] & 0xF0) >> 4;
|
|
|
- /* Byte 14 */
|
|
|
- MSD_cid->ManufactDate = (CID_Tab[13] & 0x0F) << 8;
|
|
|
- /* Byte 15 */
|
|
|
- MSD_cid->ManufactDate |= CID_Tab[14];
|
|
|
- /* Byte 16 */
|
|
|
- MSD_cid->msd_CRC = (CID_Tab[15] & 0xFE) >> 1;
|
|
|
- MSD_cid->Reserved2 = 1;
|
|
|
-
|
|
|
- /* Return the reponse */
|
|
|
- return rvalue;
|
|
|
-}
|
|
|
-
|
|
|
-/*******************************************************************************
|
|
|
-* Function Name : MSD_SendCmd
|
|
|
-* Description : Send 5 bytes command to the MSD card.
|
|
|
-* Input : - Cmd: the user expected command to send to MSD card
|
|
|
-* - Arg: the command argument
|
|
|
-* - Crc: the CRC
|
|
|
-* Output : None
|
|
|
-* Return : None
|
|
|
-*******************************************************************************/
|
|
|
-void MSD_SendCmd(u8 Cmd, u32 Arg, u8 Crc)
|
|
|
-{
|
|
|
- u32 i = 0x00;
|
|
|
- u8 Frame[6];
|
|
|
-
|
|
|
- /* Construct byte1 */
|
|
|
- Frame[0] = (Cmd | 0x40);
|
|
|
- /* Construct byte2 */
|
|
|
- Frame[1] = (u8)(Arg >> 24);
|
|
|
- /* Construct byte3 */
|
|
|
- Frame[2] = (u8)(Arg >> 16);
|
|
|
- /* Construct byte4 */
|
|
|
- Frame[3] = (u8)(Arg >> 8);
|
|
|
- /* Construct byte5 */
|
|
|
- Frame[4] = (u8)(Arg);
|
|
|
- /* Construct CRC: byte6 */
|
|
|
- Frame[5] = (Crc);
|
|
|
-
|
|
|
- /* Send the Cmd bytes */
|
|
|
- for (i = 0; i < 6; i++)
|
|
|
- {
|
|
|
- MSD_WriteByte(Frame[i]);
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-/*******************************************************************************
|
|
|
-* Function Name : MSD_GetDataResponse
|
|
|
-* Description : Get MSD card data response.
|
|
|
-* Input : None
|
|
|
-* Output : None
|
|
|
-* Return : The MSD status: Read data response xxx0<status>1
|
|
|
-* - status 010: Data accecpted
|
|
|
-* - status 101: Data rejected due to a crc error
|
|
|
-* - status 110: Data rejected due to a Write error.
|
|
|
-* - status 111: Data rejected due to other error.
|
|
|
-*******************************************************************************/
|
|
|
-u8 MSD_GetDataResponse(void)
|
|
|
-{
|
|
|
- u32 i = 0;
|
|
|
- u8 response, rvalue;
|
|
|
-
|
|
|
- while (i <= 64)
|
|
|
- {
|
|
|
- /* Read resonse */
|
|
|
- response = MSD_ReadByte();
|
|
|
- /* Mask unused bits */
|
|
|
- response &= 0x1F;
|
|
|
-
|
|
|
- switch (response)
|
|
|
- {
|
|
|
- case MSD_DATA_OK:
|
|
|
- {
|
|
|
- rvalue = MSD_DATA_OK;
|
|
|
- break;
|
|
|
- }
|
|
|
-
|
|
|
- case MSD_DATA_CRC_ERROR:
|
|
|
- return MSD_DATA_CRC_ERROR;
|
|
|
-
|
|
|
- case MSD_DATA_WRITE_ERROR:
|
|
|
- return MSD_DATA_WRITE_ERROR;
|
|
|
-
|
|
|
- default:
|
|
|
- {
|
|
|
- rvalue = MSD_DATA_OTHER_ERROR;
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
- /* Exit loop in case of data ok */
|
|
|
- if (rvalue == MSD_DATA_OK)
|
|
|
- break;
|
|
|
- /* Increment loop counter */
|
|
|
- i++;
|
|
|
- }
|
|
|
- /* Wait null data */
|
|
|
- while (MSD_ReadByte() == 0);
|
|
|
- /* Return response */
|
|
|
- return response;
|
|
|
-}
|
|
|
-
|
|
|
-/*******************************************************************************
|
|
|
-* Function Name : MSD_GetResponse
|
|
|
-* Description : Returns the MSD response.
|
|
|
-* Input : None
|
|
|
-* Output : None
|
|
|
-* Return : The MSD Response: - MSD_RESPONSE_FAILURE: Sequence failed
|
|
|
-* - MSD_RESPONSE_NO_ERROR: Sequence succeed
|
|
|
-*******************************************************************************/
|
|
|
-u8 MSD_GetResponse(u8 Response)
|
|
|
-{
|
|
|
- u32 Count = 0xFFF;
|
|
|
-
|
|
|
- /* Check if response is got or a timeout is happen */
|
|
|
- while ((MSD_ReadByte() != Response) && Count)
|
|
|
- {
|
|
|
- Count--;
|
|
|
- }
|
|
|
-
|
|
|
- if (Count == 0)
|
|
|
- {
|
|
|
- /* After time out */
|
|
|
- return MSD_RESPONSE_FAILURE;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- /* Right response got */
|
|
|
- return MSD_RESPONSE_NO_ERROR;
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-/*******************************************************************************
|
|
|
-* Function Name : MSD_GetStatus
|
|
|
-* Description : Returns the MSD status.
|
|
|
-* Input : None
|
|
|
-* Output : None
|
|
|
-* Return : The MSD status.
|
|
|
-*******************************************************************************/
|
|
|
-u16 MSD_GetStatus(void)
|
|
|
-{
|
|
|
- u16 Status = 0;
|
|
|
-
|
|
|
- /* MSD chip select low */
|
|
|
- MSD_CS_LOW();
|
|
|
- /* Send CMD13 (MSD_SEND_STATUS) to get MSD status */
|
|
|
- MSD_SendCmd(MSD_SEND_STATUS, 0, 0xFF);
|
|
|
-
|
|
|
- Status = MSD_ReadByte();
|
|
|
- Status |= (u16)(MSD_ReadByte() << 8);
|
|
|
-
|
|
|
- /* MSD chip select high */
|
|
|
- MSD_CS_HIGH();
|
|
|
- /* Send dummy byte 0xFF */
|
|
|
- MSD_WriteByte(DUMMY);
|
|
|
-
|
|
|
- return Status;
|
|
|
-}
|
|
|
-
|
|
|
-/*******************************************************************************
|
|
|
-* Function Name : MSD_GoIdleState
|
|
|
-* Description : Put MSD in Idle state.
|
|
|
-* Input : None
|
|
|
-* Output : None
|
|
|
-* Return : The MSD Response: - MSD_RESPONSE_FAILURE: Sequence failed
|
|
|
-* - MSD_RESPONSE_NO_ERROR: Sequence succeed
|
|
|
-*******************************************************************************/
|
|
|
-u8 MSD_GoIdleState(void)
|
|
|
-{
|
|
|
- /* MSD chip select low */
|
|
|
- MSD_CS_LOW();
|
|
|
- /* Send CMD0 (GO_IDLE_STATE) to put MSD in SPI mode */
|
|
|
- MSD_SendCmd(MSD_GO_IDLE_STATE, 0, 0x95);
|
|
|
-
|
|
|
- /* Wait for In Idle State Response (R1 Format) equal to 0x01 */
|
|
|
- if (MSD_GetResponse(MSD_IN_IDLE_STATE))
|
|
|
- {
|
|
|
- /* No Idle State Response: return response failue */
|
|
|
- return MSD_RESPONSE_FAILURE;
|
|
|
- }
|
|
|
- /*----------Activates the card initialization process-----------*/
|
|
|
- do
|
|
|
- {
|
|
|
- /* MSD chip select high */
|
|
|
- MSD_CS_HIGH();
|
|
|
- /* Send Dummy byte 0xFF */
|
|
|
- MSD_WriteByte(DUMMY);
|
|
|
-
|
|
|
- /* MSD chip select low */
|
|
|
- MSD_CS_LOW();
|
|
|
-
|
|
|
- /* Send CMD1 (Activates the card process) until response equal to 0x0 */
|
|
|
- MSD_SendCmd(MSD_SEND_OP_COND, 0, 0xFF);
|
|
|
- /* Wait for no error Response (R1 Format) equal to 0x00 */
|
|
|
- }
|
|
|
- while (MSD_GetResponse(MSD_RESPONSE_NO_ERROR));
|
|
|
-
|
|
|
- /* MSD chip select high */
|
|
|
- MSD_CS_HIGH();
|
|
|
- /* Send dummy byte 0xFF */
|
|
|
- MSD_WriteByte(DUMMY);
|
|
|
-
|
|
|
- return MSD_RESPONSE_NO_ERROR;
|
|
|
-}
|
|
|
-
|
|
|
-/*******************************************************************************
|
|
|
-* Function Name : MSD_WriteByte
|
|
|
-* Description : Write a byte on the MSD.
|
|
|
-* Input : Data: byte to send.
|
|
|
-* Output : None
|
|
|
-* Return : None.
|
|
|
-*******************************************************************************/
|
|
|
-void MSD_WriteByte(u8 Data)
|
|
|
-{
|
|
|
- /* Wait until the transmit buffer is empty */
|
|
|
- while (SPI_I2S_GetFlagStatus(MSD_SPI, SPI_I2S_FLAG_TXE) == RESET);
|
|
|
- /* Send the byte */
|
|
|
- SPI_I2S_SendData(MSD_SPI, Data);
|
|
|
-
|
|
|
- /*!< Wait to receive a byte*/
|
|
|
- while(SPI_I2S_GetFlagStatus(MSD_SPI, SPI_I2S_FLAG_RXNE) == RESET);
|
|
|
- /*!< Return the byte read from the SPI bus */
|
|
|
- SPI_I2S_ReceiveData(MSD_SPI);
|
|
|
-}
|
|
|
-
|
|
|
-/*******************************************************************************
|
|
|
-* Function Name : MSD_ReadByte
|
|
|
-* Description : Read a byte from the MSD.
|
|
|
-* Input : None.
|
|
|
-* Output : None
|
|
|
-* Return : The received byte.
|
|
|
-*******************************************************************************/
|
|
|
-u8 MSD_ReadByte(void)
|
|
|
-{
|
|
|
- u8 Data = 0;
|
|
|
-
|
|
|
- /* Wait until the transmit buffer is empty */
|
|
|
- while (SPI_I2S_GetFlagStatus(MSD_SPI, SPI_I2S_FLAG_TXE) == RESET);
|
|
|
- /* Send the byte */
|
|
|
- SPI_I2S_SendData(MSD_SPI, DUMMY);
|
|
|
-
|
|
|
- /* Wait until a data is received */
|
|
|
- while (SPI_I2S_GetFlagStatus(MSD_SPI, SPI_I2S_FLAG_RXNE) == RESET);
|
|
|
- /* Get the received data */
|
|
|
- Data = SPI_I2S_ReceiveData(MSD_SPI);
|
|
|
-
|
|
|
- /* Return the shifted data */
|
|
|
- return Data;
|
|
|
-}
|
|
|
-
|
|
|
-/*******************************************************************************
|
|
|
-* Function Name : SPI_Config
|
|
|
-* Description : Initializes the SPI and CS pins.
|
|
|
-* Input : None
|
|
|
-* Output : None
|
|
|
-* Return : None
|
|
|
-*******************************************************************************/
|
|
|
-void SPI_Config(void)
|
|
|
-{
|
|
|
- uint32_t delay;
|
|
|
- GPIO_InitTypeDef GPIO_InitStructure;
|
|
|
- SPI_InitTypeDef SPI_InitStructure;
|
|
|
-
|
|
|
- /* GPIOA and GPIOC Periph clock enable */
|
|
|
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOD, ENABLE);
|
|
|
- /* SPI Periph clock enable */
|
|
|
- RCC_APB2PeriphClockCmd(MSD_RCC_SPI, ENABLE);
|
|
|
-
|
|
|
- /* Configure SPI pins: SCK, MISO and MOSI */
|
|
|
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
|
|
|
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
|
|
|
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
|
|
|
- GPIO_Init(GPIOA, &GPIO_InitStructure);
|
|
|
-
|
|
|
- /* Configure PD9 pin: CS pin ,PD10 : SD Power */
|
|
|
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9|GPIO_Pin_10;
|
|
|
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
|
|
|
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
|
|
|
- GPIO_Init(GPIOD, &GPIO_InitStructure);
|
|
|
-
|
|
|
- /* SPI Config */
|
|
|
- SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
|
|
|
- SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
|
|
|
- SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
|
|
|
- SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
|
|
|
- SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
|
|
|
- SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
|
|
|
- SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;
|
|
|
- SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
|
|
|
- SPI_InitStructure.SPI_CRCPolynomial = 7;
|
|
|
- SPI_Init(MSD_SPI, &SPI_InitStructure);
|
|
|
-
|
|
|
- /* SPI enable */
|
|
|
- SPI_Cmd(MSD_SPI, ENABLE);
|
|
|
-
|
|
|
- /* active SD card */
|
|
|
- GPIO_ResetBits(GPIOD, GPIO_Pin_10);
|
|
|
- for (delay = 0; delay < 0xfffff; delay ++);
|
|
|
-}
|
|
|
-
|
|
|
-/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/
|
|
|
-
|
|
|
-/*
|
|
|
- * RT-Thread SD Card Driver
|
|
|
- * 2009-04-17 Bernard first version
|
|
|
- * 2010-07-15 Modify read/write according new block driver interface
|
|
|
- */
|
|
|
-#include <rtthread.h>
|
|
|
-#include <dfs_fs.h>
|
|
|
-
|
|
|
-static struct rt_device sdcard_device;
|
|
|
-static struct dfs_partition part;
|
|
|
-
|
|
|
-#define SECTOR_SIZE 512
|
|
|
-
|
|
|
-/* RT-Thread Device Driver Interface */
|
|
|
-static rt_err_t rt_msd_init(rt_device_t dev)
|
|
|
-{
|
|
|
- sMSD_CSD MSD_csd;
|
|
|
- MSD_GetCSDRegister(&MSD_csd);
|
|
|
-
|
|
|
- return RT_EOK;
|
|
|
-}
|
|
|
-
|
|
|
-static rt_err_t rt_msd_open(rt_device_t dev, rt_uint16_t oflag)
|
|
|
-{
|
|
|
- return RT_EOK;
|
|
|
-}
|
|
|
-
|
|
|
-static rt_err_t rt_msd_close(rt_device_t dev)
|
|
|
-{
|
|
|
- return RT_EOK;
|
|
|
-}
|
|
|
-
|
|
|
-static rt_size_t rt_msd_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
|
|
|
-{
|
|
|
- rt_uint8_t status;
|
|
|
- rt_uint32_t i;
|
|
|
-
|
|
|
- status = MSD_RESPONSE_NO_ERROR;
|
|
|
- // rt_kprintf("read: 0x%x, size %d\n", pos, size);
|
|
|
-
|
|
|
- /* read all sectors */
|
|
|
- for (i = 0; i < size; i ++)
|
|
|
- {
|
|
|
- status = MSD_ReadBlock((rt_uint8_t*)((rt_uint8_t*)buffer + i * SECTOR_SIZE),
|
|
|
- (part.offset + pos + i)* SECTOR_SIZE, SECTOR_SIZE);
|
|
|
- if (status != MSD_RESPONSE_NO_ERROR)
|
|
|
- {
|
|
|
- rt_kprintf("sd card read failed\n");
|
|
|
- return 0;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if (status == MSD_RESPONSE_NO_ERROR) return size;
|
|
|
-
|
|
|
- rt_kprintf("read failed: %d\n", status);
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
-static rt_size_t rt_msd_write (rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size)
|
|
|
-{
|
|
|
- rt_uint8_t status;
|
|
|
- rt_uint32_t i;
|
|
|
-
|
|
|
- status = MSD_RESPONSE_NO_ERROR;
|
|
|
- // rt_kprintf("write: 0x%x, size %d\n", pos, size);
|
|
|
-
|
|
|
- /* write all sectors */
|
|
|
- for (i = 0; i < size; i ++)
|
|
|
- {
|
|
|
- status = MSD_WriteBuffer((rt_uint8_t*)((rt_uint8_t*)buffer + i * SECTOR_SIZE),
|
|
|
- (part.offset + pos + i)* SECTOR_SIZE, SECTOR_SIZE);
|
|
|
- if (status != MSD_RESPONSE_NO_ERROR)
|
|
|
- {
|
|
|
- rt_kprintf("sd card write failed\n");
|
|
|
- return 0;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if (status == MSD_RESPONSE_NO_ERROR) return size;
|
|
|
-
|
|
|
- rt_kprintf("write failed: %d\n", status);
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
-static rt_err_t rt_msd_control(rt_device_t dev, rt_uint8_t cmd, void *args)
|
|
|
-{
|
|
|
- RT_ASSERT(dev != RT_NULL);
|
|
|
-
|
|
|
- return RT_EOK;
|
|
|
-}
|
|
|
-
|
|
|
-void rt_hw_msd_init()
|
|
|
-{
|
|
|
- if (MSD_Init() == MSD_RESPONSE_NO_ERROR)
|
|
|
- {
|
|
|
- rt_uint8_t status;
|
|
|
- rt_uint8_t *sector;
|
|
|
-
|
|
|
- /* register sdcard device */
|
|
|
- sdcard_device.init = rt_msd_init;
|
|
|
- sdcard_device.open = rt_msd_open;
|
|
|
- sdcard_device.close = rt_msd_close;
|
|
|
- sdcard_device.read = rt_msd_read;
|
|
|
- sdcard_device.write = rt_msd_write;
|
|
|
- sdcard_device.control = rt_msd_control;
|
|
|
-
|
|
|
- /* no private */
|
|
|
- sdcard_device.user_data = RT_NULL;
|
|
|
- /* get the first sector to read partition table */
|
|
|
- sector = (rt_uint8_t*) rt_malloc (512);
|
|
|
- if (sector == RT_NULL)
|
|
|
- {
|
|
|
- rt_kprintf("allocate partition sector buffer failed\n");
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- status = MSD_ReadBlock(sector, 0, 512);
|
|
|
- if (status == MSD_RESPONSE_NO_ERROR)
|
|
|
- {
|
|
|
- /* get the first partition */
|
|
|
- status = dfs_filesystem_get_partition(&part, sector, 0);
|
|
|
- if (status != RT_EOK)
|
|
|
- {
|
|
|
- /* there is no partition table */
|
|
|
- part.offset = 0;
|
|
|
- part.size = 0;
|
|
|
- }
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- /* there is no partition table */
|
|
|
- part.offset = 0;
|
|
|
- part.size = 0;
|
|
|
- }
|
|
|
-
|
|
|
- /* release sector buffer */
|
|
|
- rt_free(sector);
|
|
|
-
|
|
|
- rt_device_register(&sdcard_device, "sd0",
|
|
|
- RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_REMOVABLE | RT_DEVICE_FLAG_STANDALONE);
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- rt_kprintf("sdcard init failed\n");
|
|
|
- }
|
|
|
-}
|