Exemple #1
0
/*******************************************************************************
MicroSD initialization                                    return: 0x00=success
*******************************************************************************/
u8 MSD_Init(void)
{  u32 i=0;
  SPI_Config();
  MSD_CS_HIGH();
  for(i=0; i <10; i++) MSD_WriteByte(DUMMY);  //Send dummy byte: 8 Clock pulses of delay
  return MSD_GoIdleState();
}
Exemple #2
0
/*******************************************************************************************************************
** 函数名称: void SD_HardWareInit()				Name:	  void SD_HardWareInit()
** 功能描述: 初始化访问SD卡的硬件条件			Function: initialize the hardware condiction that access sd card
** 输   入: 无									Input:	  NULL
** 输   出: 无									Output:	  NULL
********************************************************************************************************************/
void SD_HardWareInit(void)
{ 
	SPI_Config();							/* 配置,初始化,SPI接口和SD片选       	*/	
    
	MSD_CS_HIGH();

//	SPI_Clk400k();							/* 配置BSPI波特率为400k       			*/	
}
Exemple #3
0
void if_spiInit(hwInterface *iface)
{
  euint8 i;
   //硬件SPI初始化
  SPI_Config();

  MSD_CS_HIGH();

  /* Send 20 spi commands with card not selected */
  for (i = 0;i < 21;i++)
    my_if_spiSend(iface, 0xff);
}
Exemple #4
0
euint8 if_spiSend(hwInterface *iface, euint8 outgoing)
{
	euint8 incoming;

	MSD_CS_LOW();
	SPI1->DR = outgoing; /* SPI_I2S_SendData(SPI1, outgoing); */
	while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);
	incoming = SPI1->DR; /* SPI_I2S_ReceiveData(SPI1);        */
	MSD_CS_HIGH();

	return(incoming);
}
Exemple #5
0
/*******************************************************************************
* 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();
  Delay_us();

  /* 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;
}
Exemple #6
0
void if_spiInit(hwInterface *iface)
{
	euint8 i; 

	SPI_Config();
	MSD_CS_HIGH();

	/* Send 20 spi commands with card not selected */
	for(i=0;i<21;i++)
		my_if_spiSend(iface,0xff);
		
  /* Speed up */
	if_spiSetSpeed(SPI_BaudRatePrescaler_2); 
}
Exemple #7
0
/*******************************************************************************
 MicroSD Read a Block                                   return: 0x00=success
*******************************************************************************/
u8 MSD_ReadBlock(u8* pBuffer, u32 ReadAddr, u16 NumByteToRead)
{ u32 i = 0; u8 rvalue = MSD_RESPONSE_FAILURE;
  mutex++;
  while (mutex > 1);
  MSD_CS_LOW(); Delay_us();
  MSD_SendCmd(MSD_READ_SINGLE_BLOCK, ReadAddr, 0xFF);//send CMD17
  if (!MSD_GetResponse(MSD_RESPONSE_NO_ERROR)) {
    if (!MSD_GetResponse(MSD_START_DATA_SINGLE_BLOCK_READ)) {
      for (i = 0; i < NumByteToRead; i++) {
        *pBuffer = MSD_ReadByte(); pBuffer++;
      }
      MSD_ReadByte(); MSD_ReadByte();                //DUMMY CRC bytes
      rvalue = MSD_RESPONSE_NO_ERROR;
    }
  }
  MSD_CS_HIGH(); MSD_WriteByte(DUMMY);               //Send dummy byte: 8 Clock pulses of delay
  mutex--;
  return rvalue;
}
Exemple #8
0
/*******************************************************************************
 MicroSD Write a Block                                   return: 0x00=success
*******************************************************************************/
u8 MSD_WriteBlock(u8* pBuffer, u32 WriteAddr, u16 NumByteToWrite)
{ u32 i=0; u8 rvalue = MSD_RESPONSE_FAILURE;
  mutex++;
  while (mutex > 1);
  MSD_CS_LOW(); Delay_us();
  MSD_SendCmd(MSD_WRITE_BLOCK, WriteAddr, 0xFF);//Send CMD24
  if(!MSD_GetResponse(MSD_RESPONSE_NO_ERROR)){
    MSD_WriteByte(DUMMY);                       //Send dummy byte: 8 Clock pulses of delay
    MSD_WriteByte(0xFE);
    for(i=0; i<NumByteToWrite; i++) {
      MSD_WriteByte(*pBuffer); pBuffer++;
    }
    MSD_ReadByte(); MSD_ReadByte();             //DUMMY CRC bytes
    if(MSD_GetDataResponse()==MSD_DATA_OK) rvalue=MSD_RESPONSE_NO_ERROR;
  }
  MSD_CS_HIGH(); MSD_WriteByte(DUMMY);          //Send dummy byte: 8 Clock pulses of delay
  mutex--;
  return rvalue;
}
Exemple #9
0
/*******************************************************************************
* 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();
  Delay_us();

  /* 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_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_DMA(u8 *pBuffer, u32 ReadAddr, u16 NumByteToRead)
{
    u8 rvalue = MSD_RESPONSE_FAILURE;
    DMA_InitTypeDef  DMA_InitStructure;
    char DuumyClock[512];
    //  INT8U err;
    memset(DuumyClock, 0xff, 512);
    //  debug("MSD_ReadBlock_DMA!\r\n");
    if(CardInfo.CardType != CARDTYPE_SDV2HC)
    {
        ReadAddr = ReadAddr << 9;
    }
    /* MSD chip select low */
    MSD_CS_LOW();
    DMA_DeInit(DMA1_Channel4);
    DMA_DeInit(DMA1_Channel5);
    DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&SPI2->DR;
    DMA_InitStructure.DMA_MemoryBaseAddr = (u32)pBuffer;
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
    DMA_InitStructure.DMA_BufferSize = 512;
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
    DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
    DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
    DMA_Init(DMA1_Channel4, &DMA_InitStructure);


    DMA_InitStructure.DMA_MemoryBaseAddr = (u32)DuumyClock;  //512字节的dummy
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
    //DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
    DMA_InitStructure.DMA_Priority = DMA_Priority_Low;
    DMA_Init(DMA1_Channel5, &DMA_InitStructure);

    /* Enable DMA1 Channel4 Transfer Complete interrupt */
    DMA_ITConfig(DMA1_Channel4, DMA_IT_TC, ENABLE);
    /* Enable DMA1 Channel5 Transfer Complete interrupt */
    DMA_ITConfig(DMA1_Channel5, DMA_IT_TC, ENABLE);

    SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Tx, ENABLE);
    SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Rx, ENABLE);
    /* Send CMD17 (MSD_READ_SINGLE_BLOCK) to read one block */
    MSD_SendCmd(CMD17, 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))
        {

            DMA_Cmd(DMA1_Channel5, ENABLE);
            DMA_Cmd(DMA1_Channel4, ENABLE);
#ifdef DMA1_IRQ
            OSFlagPend(Sem_SD_DMA, (OS_FLAGS)3, OS_FLAG_WAIT_SET_ALL, 0, &err); //请求信号量集的第0和第1位且都置1。
            //debug("MSD_ReadBlock_DMA OSFlagPend err=%d \r\n",err);
            DMA_ClearFlag(DMA1_FLAG_TC4);
#else
            while(!DMA_GetFlagStatus(DMA1_FLAG_TC5));

            while(!DMA_GetFlagStatus(DMA1_FLAG_TC4));

            DMA_ClearFlag(DMA1_FLAG_TC4);
#endif
            /* 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
        {
            //debug("\r\n erro:MSD_START_DATA_SINGLE_BLOCK_READ\r\n");
        }
    }
    else
    {
        //debug("\r\n error:MSD_RESPONSE_NO_ERROR\r\n");
    }

    DMA_Cmd(DMA1_Channel4, DISABLE);
    DMA_Cmd(DMA1_Channel5, DISABLE);
    /* MSD chip select high */
    MSD_CS_HIGH();
    /* Send dummy byte: 8 Clock pulses of delay */
    MSD_WriteByte(DUMMY_BYTE);

    /* Send stop data transmit command - CMD12 */
    _send_command(CMD12, 0, 0);
    /* Returns the reponse */
    return rvalue;
}
Exemple #11
0
/*******************************************************************************************************************
** 函数名称: void SPI_CS_Deassert()				Name:	  void SPI_CS_Deassert()
** 功能描述: 不片选SPI从机						Function: not select the SPI slave 
** 输   入: 无									Input:	  NULL
** 输   出: 无									Output:	  NULL
********************************************************************************************************************/
void SPI_CS_Deassert(void)
{
	MSD_CS_HIGH();			    				/* 不片选SPI从机  not select the SPI slave */
}
Exemple #12
0
/*******************************************************************************
* 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();
  Delay_us();

  /* 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->CRC = (CSD_Tab[15] & 0xFE) >> 1;
  MSD_csd->Reserved4 = 1;

  /* Return the reponse */
  return rvalue;
}
Exemple #13
0
/*******************************************************************************
* 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();
  Delay_us();

  /* 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->CRC = (CID_Tab[15] & 0xFE) >> 1;
  MSD_cid->Reserved2 = 1;

  /* Return the reponse */
  return rvalue;
}