/*******************************************************************************
* Function Name  : MSD_ReadSingleBlock
* Description    : None
* Input          : - sector:
*				   - buffer:
* Output         : None
* Return         : None
* Attention		 : None
*******************************************************************************/
int MSD_ReadSingleBlock(uint32_t sector, uint8_t *buffer)
{
    uint8_t r1;

    /* if ver = SD2.0 HC, sector need <<9 */
    if(CardInfo.CardType != CARDTYPE_SDV2HC)
    {
        sector = sector << 9;
    }

    /* Send CMD17 : Read single block command */
    r1 = _send_command(CMD17, sector, 0);

    if(r1 != 0x00)
    {
        return 1;
    }

    /* Start read and return the result */
    r1 = _read_buffer(buffer, MSD_BLOCKSIZE, RELEASE);

    /* Send stop data transmit command - CMD12 */
    _send_command(CMD12, 0, 0);

    return r1;
}
/*******************************************************************************
* Function Name  : MSD_ReadMultipleBlock
* Description    : None
* Input          : - sector:
*				   - buffer:
                   - count:扇区数
* Output         : None
* Return         : count  返回读剩余扇区数	0:OK 其它:ERROR
* Attention		 : None
*******************************************************************************/
int MSD_ReadMultipleBlock(uint32_t sector, uint8_t *buffer, uint8_t count)
{
    uint8_t r1;

    /* if ver = SD2.0 HC, sector need <<9 */
    if(CardInfo.CardType != CARDTYPE_SDV2HC)
    {
        sector = sector << 9;
    }
    /* Send CMD18 : Read multiple block command */
    r1 = _send_command(CMD18, sector, 0);

    if(r1 != 0x00)
    {
        return 1;
    }

    do
    {
        if (_read_buffer(buffer, MSD_BLOCKSIZE, HOLD)) break;
        buffer += 512;
    }
    while (--count);

    /* Send stop data transmit command - CMD12 */
    _send_command(CMD12, 0, 0);

    return count;
}
void
WiFlyDevice::sleep( unsigned seconds )
{
   _enter_command_mode();
   _send_command( F( "set sys wake " ), true );
   _uart->print( seconds + 1 );
   _send_command( F( "" ) );
   _send_command( F( "set sys sleep 1" ) );
   _send_command( F( "exit" ), false, "EXIT" );
   delay( 2 );
}
bool
WiFlyDevice::join( const char* ssid,
                   bool command_mode )
{
   // Make sure we are in command mode.
   if( !command_mode )
      _enter_command_mode();

   _send_command( F( "join " ), true );
   if( _send_command( ssid, false, "Associated!") )
   {
      delay( 2000 );
      return _find_in_response( "IP=" );
   }
   return false;
}
const char*
WiFlyDevice::ip()
{
   /*

     The return value is intended to be dropped directly
     into calls to 'print' or 'println' style methods.

   */
   static char ip[IP_ADDRESS_BUFFER_SIZE] = "";

   // TODO: Ensure we're not in a connection?

   _enter_command_mode();

   // Version 2.19 of the WiFly firmware has a "get ip a" command but
   // we can't use it because we want to work with 2.18 too.
   _send_command( F( "get ip" ), false, "IP=" );

   char newChar;
   byte offset = 0;

   // Copy the IP address from the response into our buffer
   while( offset < IP_ADDRESS_BUFFER_SIZE )
   {
      newChar = _uart->read();

      if( newChar == ':' )
      {
         ip[offset] = '\x00';
         break;
      }
      else if( newChar != -1 )
      {
         ip[offset] = newChar;
         offset++;
      }
   }

   // This handles the case when we reach the end of the buffer
   // in the loop. (Which should never happen anyway.)
   // And hopefully this prevents us from failing completely if
   // there's a mistake above.
   ip[IP_ADDRESS_BUFFER_SIZE-1] = '\x00';

   // This should skip the remainder of the output.
   // TODO: Handle this better?
   _wait_for_response( "<" );
   while (_uart->read() != ' '); // Skip the prompt.

   // For some reason the "sendCommand" approach leaves the system
   // in a state where it misses the first/next connection so for
   // now we don't check the response.
   // TODO: Fix this
   _uart->println( "exit" );
   //_send_command("exit", false, "EXIT");

   return ip;
}
bool
WiFlyDevice::join( const char* ssid,
                   const char* passphrase,
                   bool is_wpa )
{
   // Make sure we are in command mode.
   _enter_command_mode();

   // TODO: Handle escaping spaces/$ in passphrase and SSID

   _send_command( F( "set wlan "), true );
   if( is_wpa )
      _send_command( F( "passphrase "), true );
   else
      _send_command( F( "key "), true );
   _send_command( passphrase );
   return join( ssid, true );
}
//! Sends a command
void COMMAND_INTERPRETER::_send_cmd(byte packet_id, void *buf){

	String* buffer = (String*) buf;

	if(packet_id == USB_DEVICE_CMD){

		//! Construct a command
		_send_command((byte*)buf[0]);
	}
}
/*******************************************************************************
* Function Name  : MSD_ReadMultiBlock
* Description    : None
* Input          : - sector:
*				   - buffer:
*                  - NbrOfSector:
* Output         : None
* Return         : None
* Attention		 : None
*******************************************************************************/
int MSD_ReadMultiBlock(uint32_t sector, uint8_t *buffer, uint32_t NbrOfSector)
{
  uint8_t r1;
  uint32_t i;

  /* if ver = SD2.0 HC, sector need <<9 */
  if(CardInfo.CardType != CARDTYPE_SDV2HC)
  {
	 sector = sector<<9;
  }

  /* Send CMD18 : Read multi block command */
  r1 = _send_command(CMD18, sector, 0);
  if(r1 != 0x00)
  {
     return 1;
  }

  /* Start read	*/
  for(i=0; i<NbrOfSector; i++)
  {
     if(_read_buffer(buffer+i*MSD_BLOCKSIZE, MSD_BLOCKSIZE, HOLD))
     {
		 /* Send stop data transmit command - CMD12	*/
		 _send_command(CMD12, 0, 0);
		 /* chip disable and dummy byte */
		 ;
		 return 2;
     }
  }

  /* Send stop data transmit command - CMD12 */
  _send_command(CMD12, 0, 0);

  /* chip disable and dummy byte */
  _CARD_DISABLE();
  _spi_read_write(DUMMY_BYTE);

  return 0;
}
/*******************************************************************************
* 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;
}
示例#10
0
/*******************************************************************************
* Function Name  : MSD_ReadSingleBlock
* Description    : None
* Input          : - sector:
*				   - buffer:
* Output         : None
* Return         : None
* Attention		 : None
*******************************************************************************/
int MSD_ReadSingleBlock_DMA(uint32_t sector, uint8_t *buffer)
{
    DMA_InitTypeDef  DMA_InitStructure;
    u8 rvalue = MSD_RESPONSE_FAILURE;
    uint8_t r1;
    uint16_t retry;
    char DuumyClock = DUMMY_BYTE;

    if(CardInfo.CardType != CARDTYPE_SDV2HC)
    {
        sector = sector << 9;
    }
    /*initial dma channel 2*/
    DMA_DeInit(DMA1_Channel4);
    DMA_DeInit(DMA1_Channel5);
    DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&SPI2->DR;
    DMA_InitStructure.DMA_MemoryBaseAddr = (u32)buffer;
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
    DMA_InitStructure.DMA_BufferSize = 200;
    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);
    SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Tx, ENABLE);
    SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Rx, ENABLE);
    //    DMA_ClearFlag(DMA_FLAG_TC2);
    /* Send CMD17 : Read single block command */
    r1 = _send_command(CMD17, sector, 0);

    if(r1 != 0x00)
    {
        return 1;
    }

    /* Card enable, Prepare to read	*/
    _card_enable();

    /* Wait start-token 0xFE */
    for(retry = 0; retry < 2000; retry++)
    {
        r1 = _spi_read_write(DUMMY_BYTE);
        if(r1 == 0xFE)
        {
            retry = 0;
            break;
        }
    }

    /* Timeout return	*/
    if(retry == 2000)
    {
        _card_disable();
        return 1;
    }

    DMA_Cmd(DMA1_Channel5, ENABLE);
    DMA_Cmd(DMA1_Channel4, ENABLE);

    while(!DMA_GetFlagStatus(DMA1_FLAG_TC5));

    while(!DMA_GetFlagStatus(DMA1_FLAG_TC4));

    DMA_ClearFlag(DMA1_FLAG_TC4);

    /* 2bytes dummy CRC */
    _spi_read_write(DUMMY_BYTE);
    _spi_read_write(DUMMY_BYTE);

    /* chip disable and dummy byte */
    _card_disable();
    _spi_read_write(DUMMY_BYTE);

    /* Set response value to success */
    rvalue = MSD_RESPONSE_NO_ERROR;
    DMA_Cmd(DMA1_Channel4, DISABLE);
    DMA_Cmd(DMA1_Channel5, DISABLE);




    /* Returns the reponse */
    return rvalue;
}
示例#11
0
/*******************************************************************************
* Function Name  : MSD_Init
* Description    : SD Card initializtion
* Input          : None
* Output         : None
* Return         : None
* Attention		 : None
*******************************************************************************/
int MSD_Init(void)
{
    uint8_t r1;
    uint8_t buff[6] = {0};
    uint16_t retry;
    uint16_t retry_time = 5;
    //	uint32 lu32SDStatus = 0;
    //	uint8 err;


    gu8SDStatus = 0;

    /* Check , if no card insert */
    //if( _card_insert() )
    //{
    /* FATFS error flag */
    //return -1;
    //}

    /* Power on and delay some times */
    for(retry = 0; retry < 0x100; retry++)
    {
        _card_power_on();
    }

    /* Satrt send 74 clocks at least */
    for(retry = 0; retry < 10; retry++)
    {
        _spi_read_write(DUMMY_BYTE);
    }

    /* Start send CMD0 till return 0x01 means in IDLE state */
    /*begin:yangfei modified 2013-09-28 for SD卡重试次数太多,等待时间太长,SD卡正常的时候只需1次就能成功*/
#if 0
    for(retry = 0; retry < 0xFFF; retry++)
#else
    for(retry = 0; retry < retry_time; retry++)
#endif
    {
        r1 = _send_command(CMD0, 0, 0x95);
        if(r1 == 0x01)
        {
            retry = 0;
            break;
        }
    }
    /* Timeout return */
#if 0
    if(retry == 0xFFF)
#else
    if(retry == retry_time)
#endif
    {
        gu8SDStatus = 1;
        return 1;
    }
    /*end:yangfei modified 2013-09-28 for SD卡重试次数太多,等待时间太长,SD卡正常的时候只需1次就能成功*/

    /* Get the card type, version */
    r1 = _send_command_hold(CMD8, 0x1AA, 0x87);
    /* r1=0x05 -> V1.0 */
    if(r1 == 0x05)
    {
        CardInfo.CardType = CARDTYPE_SDV1;

        /* End of CMD8, chip disable and dummy byte */
        _card_disable();
        _spi_read_write(DUMMY_BYTE);

        /* SD1.0/MMC start initialize */
        /* Send CMD55+ACMD41, No-response is a MMC card, otherwise is a SD1.0 card */
        for(retry = 0; retry < 0xFFF; retry++)
        {
            r1 = _send_command(CMD55, 0, 0);			/* should be return 0x01 */
            if(r1 != 0x01)
            {
                return r1;
            }

            r1 = _send_command(ACMD41, 0, 0);			/* should be return 0x00 */
            if(r1 == 0x00)
            {
                retry = 0;
                break;
            }
        }

        /* MMC card initialize start */
        if(retry == 0xFFF)
        {
            for(retry = 0; retry < 0xFFF; retry++)
            {
                r1 = _send_command(CMD1, 0, 0);		/* should be return 0x00 */
                if(r1 == 0x00)
                {
                    retry = 0;
                    break;
                }
            }

            /* Timeout return */
            if(retry == 0xFFF)
            {
                gu8SDStatus = 2;
                return 2;
            }

            CardInfo.CardType = CARDTYPE_MMC;
        }

        /* Set spi speed high */
        MSD_SPIHighSpeed(1);

        /* CRC disable */
        r1 = _send_command(CMD59, 0, 0x01);
        if(r1 != 0x00)
        {
            return r1;		/* response error, return r1 */
        }

        /* Set the block size */
        r1 = _send_command(CMD16, MSD_BLOCKSIZE, 0xFF);
        if(r1 != 0x00)
        {
            return r1;		/* response error, return r1 */
        }
    }

    /* r1=0x01 -> V2.x, read OCR register, check version */
    else if(r1 == 0x01)
    {
        /* 4Bytes returned after CMD8 sent	*/
        buff[0] = _spi_read_write(DUMMY_BYTE);				/* should be 0x00 */
        buff[1] = _spi_read_write(DUMMY_BYTE);				/* should be 0x00 */
        buff[2] = _spi_read_write(DUMMY_BYTE);				/* should be 0x01 */
        buff[3] = _spi_read_write(DUMMY_BYTE);				/* should be 0xAA */

        /* End of CMD8, chip disable and dummy byte */
        _card_disable();
        _spi_read_write(DUMMY_BYTE);

        /* Check voltage range be 2.7-3.6V	*/
        if(buff[2] == 0x01 && buff[3] == 0xAA)
        {
            for(retry = 0; retry < 0xFFF; retry++)
            {
                r1 = _send_command(CMD55, 0, 0);			/* should be return 0x01 */
                if(r1 != 0x01)
                {
                    return r1;
                }

                r1 = _send_command(ACMD41, 0x40000000, 0);	/* should be return 0x00 */
                if(r1 == 0x00)
                {
                    retry = 0;
                    break;
                }
            }

            /* Timeout return */
            if(retry == 0xFFF)
            {
                gu8SDStatus = 3;
                return 3;
            }

            /* Read OCR by CMD58 */
            r1 = _send_command_hold(CMD58, 0, 0);
            if(r1 != 0x00)
            {
                return r1;		/* response error, return r1 */
            }

            buff[0] = _spi_read_write(DUMMY_BYTE);
            buff[1] = _spi_read_write(DUMMY_BYTE);
            buff[2] = _spi_read_write(DUMMY_BYTE);
            buff[3] = _spi_read_write(DUMMY_BYTE);

            /* End of CMD58, chip disable and dummy byte */
            _card_disable();
            _spi_read_write(DUMMY_BYTE);

            /* OCR -> CCS(bit30)  1: SDV2HC	 0: SDV2 */
            if(buff[0] & 0x40)
            {
                CardInfo.CardType = CARDTYPE_SDV2HC;
            }
            else
            {
                CardInfo.CardType = CARDTYPE_SDV2;
            }

            /* Set spi speed high */
            MSD_SPIHighSpeed(1);
        }
    }



    return 0;
}
示例#12
0
/*******************************************************************************
* Function Name  : MSD_GetCardInfo
* Description    : Get SD Card Information
* Input          : None
* Output         : None
* Return         : 0:NO_ERR; TRUE: Error
* Attention		 : None
*******************************************************************************/
int MSD_GetCardInfo(PMSD_CARDINFO cardinfo)
{
    uint8_t r1;
    uint8_t CSD_Tab[16];
    uint8_t CID_Tab[16];

    /* Send CMD9, Read CSD */
    r1 = _send_command(CMD9, 0, 0xFF);
    if(r1 != 0x00)
    {
        return r1;
    }

    if(_read_buffer(CSD_Tab, 16, RELEASE))
    {
        return 1;
    }

    /* Send CMD10, Read CID */
    r1 = _send_command(CMD10, 0, 0xFF);
    if(r1 != 0x00)
    {
        return r1;
    }

    if(_read_buffer(CID_Tab, 16, RELEASE))
    {
        return 2;
    }

    /* Byte 0 */
    cardinfo->CSD.CSDStruct = (CSD_Tab[0] & 0xC0) >> 6;
    cardinfo->CSD.SysSpecVersion = (CSD_Tab[0] & 0x3C) >> 2;
    cardinfo->CSD.Reserved1 = CSD_Tab[0] & 0x03;
    /* Byte 1 */
    cardinfo->CSD.TAAC = CSD_Tab[1] ;
    /* Byte 2 */
    cardinfo->CSD.NSAC = CSD_Tab[2];
    /* Byte 3 */
    cardinfo->CSD.MaxBusClkFrec = CSD_Tab[3];
    /* Byte 4 */
    cardinfo->CSD.CardComdClasses = CSD_Tab[4] << 4;
    /* Byte 5 */
    cardinfo->CSD.CardComdClasses |= (CSD_Tab[5] & 0xF0) >> 4;
    cardinfo->CSD.RdBlockLen = CSD_Tab[5] & 0x0F;
    /* Byte 6 */
    cardinfo->CSD.PartBlockRead = (CSD_Tab[6] & 0x80) >> 7;
    cardinfo->CSD.WrBlockMisalign = (CSD_Tab[6] & 0x40) >> 6;
    cardinfo->CSD.RdBlockMisalign = (CSD_Tab[6] & 0x20) >> 5;
    cardinfo->CSD.DSRImpl = (CSD_Tab[6] & 0x10) >> 4;
    cardinfo->CSD.Reserved2 = 0; /* Reserved */
    cardinfo->CSD.DeviceSize = (CSD_Tab[6] & 0x03) << 10;
    /* Byte 7 */
    cardinfo->CSD.DeviceSize |= (CSD_Tab[7]) << 2;
    /* Byte 8 */
    cardinfo->CSD.DeviceSize |= (CSD_Tab[8] & 0xC0) >> 6;
    cardinfo->CSD.MaxRdCurrentVDDMin = (CSD_Tab[8] & 0x38) >> 3;
    cardinfo->CSD.MaxRdCurrentVDDMax = (CSD_Tab[8] & 0x07);
    /* Byte 9 */
    cardinfo->CSD.MaxWrCurrentVDDMin = (CSD_Tab[9] & 0xE0) >> 5;
    cardinfo->CSD.MaxWrCurrentVDDMax = (CSD_Tab[9] & 0x1C) >> 2;
    cardinfo->CSD.DeviceSizeMul = (CSD_Tab[9] & 0x03) << 1;
    /* Byte 10 */
    cardinfo->CSD.DeviceSizeMul |= (CSD_Tab[10] & 0x80) >> 7;
    cardinfo->CSD.EraseGrSize = (CSD_Tab[10] & 0x7C) >> 2;
    cardinfo->CSD.EraseGrMul = (CSD_Tab[10] & 0x03) << 3;
    /* Byte 11 */
    cardinfo->CSD.EraseGrMul |= (CSD_Tab[11] & 0xE0) >> 5;
    cardinfo->CSD.WrProtectGrSize = (CSD_Tab[11] & 0x1F);
    /* Byte 12 */
    cardinfo->CSD.WrProtectGrEnable = (CSD_Tab[12] & 0x80) >> 7;
    cardinfo->CSD.ManDeflECC = (CSD_Tab[12] & 0x60) >> 5;
    cardinfo->CSD.WrSpeedFact = (CSD_Tab[12] & 0x1C) >> 2;
    cardinfo->CSD.MaxWrBlockLen = (CSD_Tab[12] & 0x03) << 2;
    /* Byte 13 */
    cardinfo->CSD.MaxWrBlockLen |= (CSD_Tab[13] & 0xc0) >> 6;
    cardinfo->CSD.WriteBlockPaPartial = (CSD_Tab[13] & 0x20) >> 5;
    cardinfo->CSD.Reserved3 = 0;
    cardinfo->CSD.ContentProtectAppli = (CSD_Tab[13] & 0x01);
    /* Byte 14 */
    cardinfo->CSD.FileFormatGrouop = (CSD_Tab[14] & 0x80) >> 7;
    cardinfo->CSD.CopyFlag = (CSD_Tab[14] & 0x40) >> 6;
    cardinfo->CSD.PermWrProtect = (CSD_Tab[14] & 0x20) >> 5;
    cardinfo->CSD.TempWrProtect = (CSD_Tab[14] & 0x10) >> 4;
    cardinfo->CSD.FileFormat = (CSD_Tab[14] & 0x0C) >> 2;
    cardinfo->CSD.ECC = (CSD_Tab[14] & 0x03);
    /* Byte 15 */
    cardinfo->CSD.CSD_CRC = (CSD_Tab[15] & 0xFE) >> 1;
    cardinfo->CSD.Reserved4 = 1;

    if(cardinfo->CardType == CARDTYPE_SDV2HC)
    {
        /* Byte 7 */
        cardinfo->CSD.DeviceSize = (u16)(CSD_Tab[8]) * 256;
        /* Byte 8 */
        cardinfo->CSD.DeviceSize += CSD_Tab[9] ;
    }

    cardinfo->Capacity = cardinfo->CSD.DeviceSize * MSD_BLOCKSIZE * 1024;
    cardinfo->BlockSize = MSD_BLOCKSIZE;

    /* Byte 0 */
    cardinfo->CID.ManufacturerID = CID_Tab[0];
    /* Byte 1 */
    cardinfo->CID.OEM_AppliID = CID_Tab[1] << 8;
    /* Byte 2 */
    cardinfo->CID.OEM_AppliID |= CID_Tab[2];
    /* Byte 3 */
    cardinfo->CID.ProdName1 = CID_Tab[3] << 24;
    /* Byte 4 */
    cardinfo->CID.ProdName1 |= CID_Tab[4] << 16;
    /* Byte 5 */
    cardinfo->CID.ProdName1 |= CID_Tab[5] << 8;
    /* Byte 6 */
    cardinfo->CID.ProdName1 |= CID_Tab[6];
    /* Byte 7 */
    cardinfo->CID.ProdName2 = CID_Tab[7];
    /* Byte 8 */
    cardinfo->CID.ProdRev = CID_Tab[8];
    /* Byte 9 */
    cardinfo->CID.ProdSN = CID_Tab[9] << 24;
    /* Byte 10 */
    cardinfo->CID.ProdSN |= CID_Tab[10] << 16;
    /* Byte 11 */
    cardinfo->CID.ProdSN |= CID_Tab[11] << 8;
    /* Byte 12 */
    cardinfo->CID.ProdSN |= CID_Tab[12];
    /* Byte 13 */
    cardinfo->CID.Reserved1 |= (CID_Tab[13] & 0xF0) >> 4;
    /* Byte 14 */
    cardinfo->CID.ManufactDate = (CID_Tab[13] & 0x0F) << 8;
    /* Byte 15 */
    cardinfo->CID.ManufactDate |= CID_Tab[14];
    /* Byte 16 */
    cardinfo->CID.CID_CRC = (CID_Tab[15] & 0xFE) >> 1;
    cardinfo->CID.Reserved2 = 1;

    return 0;
}
示例#13
0
/*******************************************************************************
* Function Name  : MSD_WriteMultipleBlock
* Description    : None
* Input          : - sector:
*				   - buffer:
* Output         : None
* Return         : None
* Attention		 : None
*******************************************************************************/
int MSD_WriteMultipleBlock(uint32_t sector, uc8 *buffer, uint8_t count)
{
    uint8_t r1;
    uint16_t i;
    uint32_t retry;

    /* if ver = SD2.0 HC, sector need <<9 */
    if(CardInfo.CardType != CARDTYPE_SDV2HC)
    {
        sector = sector << 9;
    }
    if(CardInfo.CardType != CARDTYPE_MMC)
    {
        _send_command(ACMD23, count, 0);
    }
    /* Send CMD25 : Write multiple block command */
    r1 = _send_command(CMD25, sector, 0);

    if(r1 != 0x00)
    {
        return 1;
    }

    /* Card enable, Prepare to write */
    _card_enable();
    _spi_read_write(DUMMY_BYTE);
    _spi_read_write(DUMMY_BYTE);
    _spi_read_write(DUMMY_BYTE);
    /* Start data write token: 0xFE */
    //_spi_read_write(0xFE);

    do
    {
        _spi_read_write(0xFC);
        for(i = 0; i < MSD_BLOCKSIZE; i++)
        {
            _spi_read_write(*buffer++);
        }
        /* 2Bytes dummy CRC */
        _spi_read_write(DUMMY_BYTE);
        _spi_read_write(DUMMY_BYTE);

        /* MSD card accept the data */
        r1 = _spi_read_write(DUMMY_BYTE);
        if((r1 & 0x1F) != 0x05)
        {
            _card_disable();
            return 2;
        }

        /* Wait all the data programm finished */
        retry = 0;
        while(_spi_read_write(DUMMY_BYTE) == 0x00)
        {
            /* Timeout return */
            if(retry++ == 0x40000)
            {
                _card_disable();
                return 3;
            }
        }

    }
    while (--count);

    r1 = _spi_read_write(0xFD);
    if(r1 == 0x00)
    {
        return 4;
    }

    /* Wait all the data programm finished */
    retry = 0;
    while(_spi_read_write(DUMMY_BYTE) == 0x00)
    {
        /* Timeout return */
        if(retry++ == 0x40000)
        {
            _card_disable();
            return 5;
        }
    }
    /* chip disable and dummy byte */
    _card_disable();
    _spi_read_write(DUMMY_BYTE);

    return count;
}
示例#14
0
/************************************************************************************
* Function Name  : MSD_WriteMultipleBlock_DMA(uint32_t sector, uc8 *buffer,u16 NumByteToWrite)
* Description    : None
* Input          : - sector:
*				   - buffer:
* Output         : None
* Return         : None
* Attention		 : None
************************************************************************************/
int MSD_WriteMultipleBlock_DMA(uint32_t sector, uc8 *buffer, u8 NbrOfSector, u16 NumByteToWrite)
{
    uint8 r1;
    //  uint16_t i=0;
    uint32_t retry;
    u8 value = 0;
    //  INT8U err;
    u8 rvalue = MSD_RESPONSE_FAILURE;
    DMA_InitTypeDef DMA_InitStructure;                                    //定义DMA初始化结构体

    /*begin:yangfei added 2012.11.29*/
    //    debug("MSD_WriteMultipleBlock_DMA\r\n");
    _card_enable();
    DMA_DeInit(DMA1_Channel5);
    DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&SPI2->DR;
    DMA_InitStructure.DMA_MemoryBaseAddr = (u32)buffer;
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
    DMA_InitStructure.DMA_BufferSize = NumByteToWrite;
    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_Medium;
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
    DMA_Init(DMA1_Channel5, &DMA_InitStructure);
    /* Enable DMA1 Channel5 Transfer Complete interrupt */
    DMA_ITConfig(DMA1_Channel5, DMA_IT_TC, ENABLE);
    SPI_I2S_DMACmd(SPI2, SPI_I2S_DMAReq_Tx, ENABLE);
    /*end:yangfei added 2012.11.29*/
    //SPI_DMA_Send_Init(buffer,MSD_BLOCKSIZE);
    /* if ver = SD2.0 HC, sector need <<9 */
    if(CardInfo.CardType != CARDTYPE_SDV2HC)
    {
        sector = sector << 9;
    }
    if(CardInfo.CardType != CARDTYPE_MMC)
    {
        _send_command(ACMD23, NbrOfSector, 0);
    }
    /* Send CMD25 : Write multiple block command */
    MSD_SendCmd(CMD25, sector, 0xff);
    //_spi_read_write(DUMMY_BYTE);
    //_spi_read_write(DUMMY_BYTE);
    if (!MSD_GetResponse(MSD_RESPONSE_NO_ERROR))
    {
        _spi_read_write(DUMMY_BYTE);
        /* Start data write token: 0xFE */
        _spi_read_write(0xFC);

        /*begin:yangfei added 2012.11.28*/
        DMA_Cmd(DMA1_Channel5, ENABLE);

#ifdef DMA1_IRQ
        OSFlagPend(Sem_SD_DMA, (OS_FLAGS)1, OS_FLAG_WAIT_SET_ALL, 0, &err); //请求信号量集的第0位置1
        DMA_ClearFlag(DMA1_FLAG_TC5);
#else

        while(!DMA_GetFlagStatus(DMA1_FLAG_TC5))  ;
        DMA_ClearFlag(DMA1_FLAG_TC5);
#endif
        /* 2Bytes dummy CRC */
        _spi_read_write(DUMMY_BYTE);
        _spi_read_write(DUMMY_BYTE);

        value = MSD_GetDataResponse();

        if (value == MSD_DATA_OK)
        {
            rvalue = MSD_RESPONSE_NO_ERROR;
        }
        //	   debug("value=%x\r\n",value);
    }
    /* Send end of transmit token: 0xFD */
    r1 = _spi_read_write(0xFD);
    if(r1 == 0x00)
    {
        return 4;
    }
    /*begin:yangfei added 2012.12.07 for wait programm finished else write error*/
    /* Wait all the data programm finished */
    retry = 0;
    while(_spi_read_write(DUMMY_BYTE) == 0x00)
    {
        /* Timeout return */
        if(retry++ == 0x40000)
        {
            _card_disable();
            return 3;
        }
    }
    /* chip disable and dummy byte */
    _card_disable();
    _spi_read_write(DUMMY_BYTE);

    /*yangfei added*/
    DMA_Cmd(DMA1_Channel5, DISABLE);

    return rvalue;
}
/*******************************************************************************
* Function Name  : MSD_Init
* Description    : SD Card initializtion
* Input          : None
* Output         : None
* Return         : None
* Attention		 : None
*******************************************************************************/
int MSD_Init(void)
{
	uint8_t r1;
	uint8_t buff[6] = {0};
	uint16_t retry;

	/* Check , if no card insert */
	if(_NO_CARD_INSERT())
	{
		//printf("There is no card detected! \r\n");
			return -1;
	}

	/* Power on and delay some times */
	for(retry=0; retry<0x100; retry++)
	{
		_CARD_POWER_ON();
	}

	/* Satrt send 74 clocks at least */
	for(retry=0; retry<10; retry++)
	{
		_spi_read_write(DUMMY_BYTE);
	}

	/* Start send CMD0 till return 0x01 means in IDLE state */
	for(retry=0; retry<0xFFF; retry++)
	{
		r1 = _send_command(CMD0, 0, 0x95);
		if(r1 == 0x01)
		{
			retry = 0;
			break;
		}
	}
	/* Timeout return */
	if(retry == 0xFFF)
	{
		//printf("Reset card into IDLE state failed!\r\n");
		return 1;
	}

	/* Get the card type, version */
	r1 = _send_command_hold(CMD8, 0x1AA, 0x87);
	/* r1=0x05 -> V1.0 */
	if(r1 == 0x05)
	{
		CardInfo.CardType = CARDTYPE_SDV1;

		/* End of CMD8, chip disable and dummy byte */
		_CARD_DISABLE();
		_spi_read_write(DUMMY_BYTE);

		/* SD1.0/MMC start initialize */
		/* Send CMD55+ACMD41, No-response is a MMC card, otherwise is a SD1.0 card */
		for(retry=0; retry<0xFFF; retry++)
		{
			r1 = _send_command(CMD55, 0, 0);			/* should be return 0x01 */
			if(r1 != 0x01)
			{
				//printf("Send CMD55 should return 0x01, response=0x%02x\r\n", r1);
				return r1;
			}

			r1 = _send_command(ACMD41, 0, 0);			/* should be return 0x00 */
			if(r1 == 0x00)
			{
				retry = 0;
				break;
			}
		}

		/* MMC card initialize start */
		if(retry == 0xFFF)
		{
			for(retry=0; retry<0xFFF; retry++)
			{
				r1 = _send_command(CMD1, 0, 0);		/* should be return 0x00 */
				if(r1 == 0x00)
				{
					retry = 0;
					break;
				}
			}

			/* Timeout return */
			if(retry == 0xFFF)
			{
				//printf("Send CMD1 should return 0x00, response=0x%02x\r\n", r1);
				return 2;
			}

			CardInfo.CardType = CARDTYPE_MMC;
			//printf("Card Type: MMC\r\n");
		}
		/* SD1.0 card detected, print information */
		else
		{
			//printf("Card Type: SD V1\r\n");
		}

		/* Set spi speed high */
		MSD_SPIHighSpeed(1);

		/* CRC disable */
		r1 = _send_command(CMD59, 0, 0x01);
		if(r1 != 0x00)
		{
			//printf("Send CMD59 should return 0x00, response=0x%02x\r\n", r1);
			return r1;		/* response error, return r1 */
		}

		/* Set the block size */
		r1 = _send_command(CMD16, MSD_BLOCKSIZE, 0xFF);
		if(r1 != 0x00)
		{
			//printf("Send CMD16 should return 0x00, response=0x%02x\r\n", r1);
			return r1;		/* response error, return r1 */
		}
	}
	/* r1=0x01 -> V2.x, read OCR register, check version */
	else if(r1 == 0x01)
	{
		/* 4Bytes returned after CMD8 sent	*/
		buff[0] = _spi_read_write(DUMMY_BYTE);				/* should be 0x00 */
		buff[1] = _spi_read_write(DUMMY_BYTE);				/* should be 0x00 */
		buff[2] = _spi_read_write(DUMMY_BYTE);				/* should be 0x01 */
		buff[3] = _spi_read_write(DUMMY_BYTE);				/* should be 0xAA */

		/* End of CMD8, chip disable and dummy byte */
		_CARD_DISABLE();
		_spi_read_write(DUMMY_BYTE);

		/* Check voltage range be 2.7-3.6V	*/
		if(buff[2]==0x01 && buff[3]==0xAA)
		{
			for(retry=0; retry<0xFFF; retry++)
			{
				r1 = _send_command(CMD55, 0, 0);			/* should be return 0x01 */
				if(r1!=0x01)
				{
					//printf("Send CMD55 should return 0x01, response=0x%02x\r\n", r1);
					return r1;
				}

				r1 = _send_command(ACMD41, 0x40000000, 0);	/* should be return 0x00 */
				if(r1 == 0x00)
				{
					retry = 0;
					break;
				}
			}

			/* Timeout return */
			if(retry == 0xFFF)
			{
				//printf("Send ACMD41 should return 0x00, response=0x%02x\r\n", r1);
				return 3;
			}

			/* Read OCR by CMD58 */
			r1 = _send_command_hold(CMD58, 0, 0);
			if(r1!=0x00)
			{
				//printf("Send CMD58 should return 0x00, response=0x%02x\r\n", r1);
				return r1;		/* response error, return r1 */
			}

			buff[0] = _spi_read_write(DUMMY_BYTE);
			buff[1] = _spi_read_write(DUMMY_BYTE);
			buff[2] = _spi_read_write(DUMMY_BYTE);
			buff[3] = _spi_read_write(DUMMY_BYTE);

			/* End of CMD58, chip disable and dummy byte */
			_CARD_DISABLE();
			_spi_read_write(DUMMY_BYTE);

			/* OCR -> CCS(bit30)  1: SDV2HC	 0: SDV2 */
			if(buff[0] & 0x40)
			{
				CardInfo.CardType = CARDTYPE_SDV2HC;
				//printf("Card Type: SD V2HC\r\n");
			}
			else
			{
				CardInfo.CardType = CARDTYPE_SDV2;
				//printf("Card Type: SD V2\r\n");
			}

			/* Set spi speed high */
			MSD_SPIHighSpeed(1);
		}
	}
	return 0;
}
/*******************************************************************************
* Function Name  : MSD_WriteSingleBlock
* Description    : None
* Input          : - sector:
*				   - buffer:
* Output         : None
* Return         : None
* Attention		 : None
*******************************************************************************/
int MSD_WriteSingleBlock(uint32_t sector, uc8 *buffer)
{
  uint8_t r1;
  uint16_t i;
  uint32_t retry;

  /* if ver = SD2.0 HC, sector need <<9 */
  if(CardInfo.CardType != CARDTYPE_SDV2HC)
  {
	 sector = sector<<9;
  }

  /* Send CMD24 : Write single block command */
  r1 = _send_command(CMD24, sector, 0);

  if(r1 != 0x00)
  {
	 return 1;
  }

  /* Card enable, Prepare to write */
  _CARD_ENABLE();
  _spi_read_write(DUMMY_BYTE);
  _spi_read_write(DUMMY_BYTE);
  _spi_read_write(DUMMY_BYTE);
  /* Start data write token: 0xFE */
  _spi_read_write(0xFE);

  /* Start single block write the data buffer */
  for(i=0; i<MSD_BLOCKSIZE; i++)
  {
    _spi_read_write(*buffer++);
  }

  /* 2Bytes dummy CRC */
  _spi_read_write(DUMMY_BYTE);
  _spi_read_write(DUMMY_BYTE);

  /* MSD card accept the data */
  r1 = _spi_read_write(DUMMY_BYTE);
  if((r1&0x1F) != 0x05)
  {
    _CARD_DISABLE();
    return 2;
  }

  /* Wait all the data programm finished */
  retry = 0;
  while(_spi_read_write(DUMMY_BYTE) == 0x00)
  {
	 /* Timeout return */
	 if(retry++ == 0x40000)
	 {
	    _CARD_DISABLE();
	    return 3;
	 }
  }

  /* chip disable and dummy byte */
  _CARD_DISABLE();
  _spi_read_write(DUMMY_BYTE);

  return 0;
}
/*******************************************************************************
* Function Name  : MSD_WriteMultiBlock
* Description    : None
* Input          : - sector:
*				   - buffer:
*                  - NbrOfSector:
* Output         : None
* Return         : None
* Attention		 : None
*******************************************************************************/
int MSD_WriteMultiBlock(uint32_t sector, uc8 *buffer, uint32_t NbrOfSector)
{
  uint8_t r1;
  uint16_t i;
  uint32_t n;
  uint32_t retry;

  /* if ver = SD2.0 HC, sector need <<9 */
  if(CardInfo.CardType != CARDTYPE_SDV2HC)
  {
	  sector = sector<<9;
  }

  /* Send command ACMD23 berfore multi write if is not a MMC card */
  if(CardInfo.CardType != CARDTYPE_MMC)
  {
	  _send_command(ACMD23, NbrOfSector, 0x00);
  }

  /* Send CMD25 : Write nulti block command	*/
  r1 = _send_command(CMD25, sector, 0);

  if(r1 != 0x00)
  {
	  return 1;
  }

  /* Card enable, Prepare to write */
  _CARD_ENABLE();
  _spi_read_write(DUMMY_BYTE);
  _spi_read_write(DUMMY_BYTE);
  _spi_read_write(DUMMY_BYTE);

  for(n=0; n<NbrOfSector; n++)
  {
	 /* Start multi block write token: 0xFC */
	 _spi_read_write(0xFC);

	 for(i=0; i<MSD_BLOCKSIZE; i++)
	 {
		_spi_read_write(*buffer++);
	 }

	 /* 2Bytes dummy CRC */
	 _spi_read_write(DUMMY_BYTE);
	 _spi_read_write(DUMMY_BYTE);

	 /* MSD card accept the data */
	 r1 = _spi_read_write(DUMMY_BYTE);
	 if((r1&0x1F) != 0x05)
	 {
	    _CARD_DISABLE();
	    return 2;
	 }

	 /* Wait all the data programm finished	*/
	 retry = 0;
	 while(_spi_read_write(DUMMY_BYTE) != 0xFF)
	 {
		/* Timeout return */
		if(retry++ == 0x40000)
		{
		   _CARD_DISABLE();
		   return 3;
		}
	 }
  }

  /* Send end of transmit token: 0xFD */
  r1 = _spi_read_write(0xFD);
  if(r1 == 0x00)
  {
	 return 4;
  }

  /* Wait all the data programm finished */
  retry = 0;
  while(_spi_read_write(DUMMY_BYTE) != 0xFF)
  {
	 /* Timeout return */
	 if(retry++ == 0x40000)
	 {
	     _CARD_DISABLE();
	     return 5;
	 }
  }

  /* chip disable and dummy byte */
  _CARD_DISABLE();
  _spi_read_write(DUMMY_BYTE);

  return 0;
}