/*******************************************************************************
* Function Name  : _send_command
* Description    : None
* Input          : - cmd:
*				   - arg:
*                  - crc:
* Output         : None
* Return         : R1 value, response from card
* Attention		 : None
*******************************************************************************/
int _send_command(uint8_t cmd, uint32_t arg, uint8_t crc)
{
    uint8_t r1;
    uint8_t retry;

    /* Dummy byte and chip enable */
    _spi_read_write(DUMMY_BYTE);
    _card_enable();

    /* Command, argument and crc */
    _spi_read_write(cmd | 0x40);
    _spi_read_write(arg >> 24);
    _spi_read_write(arg >> 16);
    _spi_read_write(arg >> 8);
    _spi_read_write(arg);
    _spi_read_write(crc);

    /* Wait response, quit till timeout */
    for(retry = 0; retry < 200; retry++)
    {
        r1 = _spi_read_write(DUMMY_BYTE);
        if(r1 != 0xFF)
        {
            break;
        }
    }

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

    return r1;
}
/*******************************************************************************
* Function Name  : _read_buffer
* Description    : None
* Input          : - *buff:
*				   - len:
*				   - release:
* Output         : None
* Return         : 0:NO_ERR; TRUE: Error
* Attention		 : None
*******************************************************************************/
int _read_buffer(uint8_t *buff, uint16_t len, uint8_t release)
{
    uint8_t r1;
    uint16_t retry;

    /* 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;
    }

    /* Start reading */
    for(retry = 0; retry < len; retry++)
    {
        *(buff + retry) = _spi_read_write(DUMMY_BYTE);
    }

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

    /* chip disable and dummy byte */
    if(release)
    {
        _card_disable();
        _spi_read_write(DUMMY_BYTE);
    }

    return 0;
}
Beispiel #3
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 */
		 _card_disable();
		 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;
}
Beispiel #4
0
/*****************************************************************************
   Send a Command to Flash card and get a Response
   cmd:  cmd index
   arg: argument for the cmd
   return the received response of the commond
*****************************************************************************/
static rt_uint8_t _spi_sd_sendcmd( rt_uint8_t cmd, rt_uint32_t arg, rt_uint8_t crc )
{
	rt_uint32_t n;
	rt_uint8_t r1;
#if 1
	if( cmd & 0x80 )                                    /* ACMD<n> is the command sequence of CMD55-CMD<n> */
	{
		cmd &= 0x7F;
		r1	= _spi_sd_sendcmd( APP_CMD, 0, DUMMY_CRC ); /* CMD55 */
		if( r1 > 1 )
		{
			return r1;                                  /* cmd send failed */
		}
	}
#endif
	/* Select the card and wait for ready */
//	LPC17xx_SPI_DeSelect();
//	LPC17xx_SPI_Select();
//	if (_spi_sd_wait4ready() == false ) return 0xFF;

	_spi_send_recv( DUMMY_BYTE );
	_card_enable( );
	_spi_send_recv( cmd );
	_spi_send_recv( arg >> 24 );
	_spi_send_recv( arg >> 16 );
	_spi_send_recv( arg >> 8 );
	_spi_send_recv( arg );
	_spi_send_recv( crc );

#if 0
	n = 10; /* Wait for a valid response in timeout of 10 attempts */
	do
	{
		r1 = _spi_send_recv( DUMMY_BYTE );
	}
	while( ( r1 & 0x80 ) && --n );
#endif

#if 1
	for( n = 0; n < 200; n++ )
	{
		r1 = _spi_send_recv( DUMMY_BYTE );
		if( r1 != 0xFF )
		{
			break;
		}
	}
#endif	
	_card_disable( );
	_spi_send_recv( DUMMY_BYTE );
	return r1; /* Return with the response value */
}
Beispiel #5
0
/* Read MMC/SD Card device configuration. */
static rt_uint8_t _spi_sd_readcfg( SDCFG *cfg )
{
	rt_uint8_t	i;
	rt_uint16_t csize;
	rt_uint8_t	n, csd[16];
	rt_uint8_t	retv = false;

	/* Read the OCR - Operations Condition Register. */
	if( _spi_sd_sendcmd_hold( READ_OCR, 0, DUMMY_CRC ) != 0x00 )
	{
		goto x;
	}
	for( i = 0; i < 4; i++ )
	{
		cfg->ocr[i] = _spi_send_recv( DUMMY_BYTE );
	}
	_card_disable( );
	_spi_send_recv( DUMMY_BYTE );

	/* Read the CID - Card Identification. */
	if( _spi_sd_sendcmd_hold( SEND_CID, 0, DUMMY_CRC ) != 0x00 )
	{
		goto x;
	}
	if( _spi_sd_readdatablock( cfg->cid, 16, RELEASE ) == false )
	{
		goto x;
	}

	rt_kprintf("\r\nCID=");
	for (i=0;i<16;i++) rt_kprintf("%02x ",cfg->cid[i]);

	/* Read the CSD - Card Specific Data. */
	if( ( _spi_sd_sendcmd_hold( SEND_CSD, 0, DUMMY_CRC ) != 0x00 ) ||
	    ( _spi_sd_readdatablock( cfg->csd, 16, RELEASE ) == false ) )
	{
		goto x;
	}

	rt_kprintf("\r\nCSD=");
	for (i=0;i<16;i++) rt_kprintf("%02x ",cfg->csd[i]);

	cfg->sectorsize = SD_SECTOR_SIZE;

	/* Get number of sectors on the disk (DWORD) */
	if( ( cfg->csd[0] >> 6 ) == 1 )                                                                                                     /* SDC ver 2.00 */
	{
		csize			= cfg->csd[9] + ( (rt_uint16_t)cfg->csd[8] << 8 ) + 1;
		cfg->sectorcnt	= (rt_uint32_t)csize << 10;
	} else                                                                                                                              /* SDC ver 1.XX or MMC*/
	{
Beispiel #6
0
/***********************************************************
* Function:
* Description:
* Input:
* Input:
* Output:
* Return:
* Others:
***********************************************************/
static rt_uint8_t _spi_sd_readdatablock( rt_uint8_t *buff, rt_uint32_t cnt, rt_uint8_t release )
{
	rt_uint8_t	r1;
	rt_uint16_t retry;
	_card_enable( );
	for( retry = 0; retry < 2000; retry++ )
	{
		r1 = _spi_send_recv( DUMMY_BYTE );
		if( r1 == 0xFE )
		{
			retry = 0;
			break;
		}
	}
	if( retry == 2000 )
	{
		_card_disable( );
		return false;
	}
	for( retry = 0; retry < cnt; retry++ )
	{
		*( buff + retry ) = _spi_send_recv( DUMMY_BYTE );
	}

	// 2bytes dummy CRC
	_spi_send_recv( DUMMY_BYTE );
	_spi_send_recv( DUMMY_BYTE );

	// chip disable and dummy byte
	if( release )
	{
		_card_disable( );
		_spi_send_recv( DUMMY_BYTE );
	}
	return true;
}
Beispiel #7
0
void _spi1_init( )
{
	SPI_InitTypeDef		SPI_InitStructure;
	GPIO_InitTypeDef	GPIO_InitStructure;

	RCC_APB2PeriphClockCmd( RCC_APB2Periph_SPI1, ENABLE );

	RCC_AHB1PeriphClockCmd( RCC_AHB1Periph_GPIOA, ENABLE );

	GPIO_PinAFConfig( GPIOA, GPIO_PinSource5, GPIO_AF_SPI1 );
	GPIO_PinAFConfig( GPIOA, GPIO_PinSource6, GPIO_AF_SPI1 );
	GPIO_PinAFConfig( GPIOA, GPIO_PinSource7, GPIO_AF_SPI1 );

	GPIO_InitStructure.GPIO_Mode	= GPIO_Mode_AF;
	GPIO_InitStructure.GPIO_Speed	= GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_OType	= GPIO_OType_PP;
	GPIO_InitStructure.GPIO_PuPd	= GPIO_PuPd_DOWN;

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
	GPIO_Init( GPIOA, &GPIO_InitStructure );

	GPIO_InitStructure.GPIO_Pin		= GPIO_Pin_4;
	GPIO_InitStructure.GPIO_Mode	= GPIO_Mode_OUT;
	GPIO_InitStructure.GPIO_OType	= GPIO_OType_PP;
	GPIO_InitStructure.GPIO_Speed	= GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_PuPd	= GPIO_PuPd_NOPULL;
	GPIO_Init( GPIOA, &GPIO_InitStructure );

	//_card_power_off();
	_card_disable( );

	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_Low;
	SPI_InitStructure.SPI_CPHA		= SPI_CPHA_1Edge;
//	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_256;

	SPI_InitStructure.SPI_FirstBit		= SPI_FirstBit_MSB;
	SPI_InitStructure.SPI_CRCPolynomial = 7;
	SPI_Init( SPI1, &SPI_InitStructure );

	SPI_Cmd( SPI1, ENABLE );
}
Beispiel #8
0
/*****************************************************************************
   Write "count" Sector(s) starting from sector index "sector",
   buff -> [sector, sector+1, ... sector+count-1]
   if success, return true, otherwise return false
*****************************************************************************/
static rt_uint8_t _spi_sd_writesector( rt_uint32_t sector, const rt_uint8_t *buff, rt_uint32_t count )
{
	if( !( CardType & CT_BLOCK ) )
	{
		sector *= 512;  /* Convert to byte address if needed */
	}
	if( count == 1 )    /* Single block write */
	{
		if( ( _spi_sd_sendcmd( WRITE_BLOCK, sector, DUMMY_CRC ) == 0 )
		    && _spi_sd_writedatablock( buff, TOKEN_SINGLE_BLOCK ) )
		{
			count = 0;
		}
	} else              /* Multiple block write */
	{
		if( CardType & CT_SDC )
		{
			_spi_sd_sendcmd( SET_WR_BLK_ERASE_COUNT, count, DUMMY_CRC );
		}
		if( _spi_sd_sendcmd( WRITE_MULT_BLOCK, sector, DUMMY_CRC ) == 0 )
		{
			do
			{
				if( !_spi_sd_writedatablock( buff, TOKEN_MULTI_BLOCK ) )
				{
					break;
				}
				buff += 512;
			}
			while( --count );
#if 1
			if( !_spi_sd_writedatablock( 0, TOKEN_STOP_TRAN ) ) /* STOP_TRAN token */
			{
				count = 1;
			}
#else
			_spi_send_recv( TOKEN_STOP_TRAN );
#endif
		}
	}
	//LPC17xx_SPI_Release();
	//SPI_SSOutputCmd(SPI1,DISABLE);
	_card_disable( );
	_spi_send_recv( DUMMY_BYTE );
	return count ? false : true;
}
Beispiel #9
0
/*****************************************************************************
   Read "count" Sector(s) starting from sector index "sector",
   buff <- [sector, sector+1, ... sector+count-1]
   if success, return true, otherwise return false
*****************************************************************************/
static rt_uint8_t _spi_sd_readsector( rt_uint32_t sector, rt_uint8_t * buff, rt_uint32_t count )
{
	/* Convert to byte address if needed */
	if( !( CardType & CT_BLOCK ) )
	{
		sector *= SD_SECTOR_SIZE;
	}

	if( count == 1 ) /* Single block read */
	{
		if( _spi_sd_sendcmd_hold( READ_BLOCK, sector, DUMMY_CRC ) != 0x0 )
		{
			return false;
		}
		if( !_spi_sd_readdatablock( buff, SD_SECTOR_SIZE, RELEASE ) )
		{
			return false;
		}
		//if (_spi_sd_sendcmd(STOP_TRAN, 0,DUMMY_CRC) != 0x0) return false;
		return true;
	} else   /* Multiple block read */
	{
		if( !_spi_sd_sendcmd( READ_MULT_BLOCK, sector, DUMMY_CRC ) )
		{
			return false;
		}
		do
		{
			if( !_spi_sd_readdatablock( buff, SD_SECTOR_SIZE, HOLD ) )
			{
				return false;
			}
			buff += SD_SECTOR_SIZE;
		}
		while( --count );
		_spi_sd_sendcmd( STOP_TRAN, 0, DUMMY_CRC ); /* STOP_TRANSMISSION */
	}
	//LPC17xx_SPI_Release();
	//SPI_SSOutputCmd(SPI1,DISABLE);
	_card_disable( );
	_spi_send_recv( DUMMY_BYTE );
	return true;
}
Beispiel #10
0
/*******************************************************************************
* Function Name  : MSD_SPI_Configuration
* Description    : SD Card SPI Configuration
* Input          : None
* Output         : None
* Return         : None
* Attention		 : None
*******************************************************************************/
void MSD_SPI_Configuration(void)
{		
  GPIO_InitTypeDef GPIO_InitStructure;

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE); 

  /* SPI1 Remap enable */
//  GPIO_PinRemapConfig(GPIO_Remap_SPI1, ENABLE );

  /**
  *	SPI1_SCK -> PA5 , SPI1_MISO -> PA6 , SPI1_MOSI ->	PA7
  */		
  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);
  /**
  *	SD_CS -> PA4 
  */		
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
  /**
  * SD_CD -> PB0
  */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
  GPIO_Init(GPIOB, &GPIO_InitStructure);

  _card_disable(); 

  MSD_SPIHighSpeed(0);		

  SPI_Cmd(SPI1, ENABLE);
}
/*******************************************************************************
* 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;
}
/*******************************************************************************
* 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;
}
/*******************************************************************************
* 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;
}
/************************************************************************************
* 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;
}
Beispiel #15
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;
}
Beispiel #16
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; 

	/* Check , if no card insert 
    if( _card_insert() )
	{ 
#ifdef PRINT_INFO 
		printf("There is no card detected! \r\n");
#endif
	  // 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 */
  for(retry=0; retry<0xFFF; retry++) {
    r1 = _send_command(CMD0, 0, 0x95);
    if(r1 == 0x01) {
      retry = 0;
      break;
    }
  }
  
  /* Timeout return */
  if(retry == 0xFFF) {
#ifdef PRINT_INFO 
    printf("Reset card into IDLE state failed!\r\n");
#endif
    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) {
#ifdef PRINT_INFO 
        printf("Send CMD55 should return 0x01, response=0x%02x\r\n", r1);
#endif
        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) {
#ifdef PRINT_INFO
        printf("Send CMD1 should return 0x00, response=0x%02x\r\n", r1);
#endif
        return 2;
      }
                
      CardInfo.CardType = CARDTYPE_MMC;		
#ifdef PRINT_INFO 
      printf("Card Type : MMC\r\n");
#endif 				
    }
    
    /* SD1.0 card detected, print information */
#ifdef PRINT_INFO
    else {
      printf("Card Type : SD V1\r\n");
    }
#endif 	
    /* Set spi speed high */
    MSD_SPIHighSpeed(1);		
          
    /* CRC disable */
    r1 = _send_command(CMD59, 0, 0x01);
    if(r1 != 0x00) {
#ifdef PRINT_INFO 
      printf("Send CMD59 should return 0x00, response=0x%02x\r\n", r1);
#endif
      return r1;		/* response error, return r1 */
    }
              
    /* Set the block size */
    r1 = _send_command(CMD16, MSD_BLOCKSIZE, 0xFF);
    if(r1 != 0x00) {
#ifdef PRINT_INFO
      printf("Send CMD16 should return 0x00, response=0x%02x\r\n", r1);
#endif
      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) {
#ifdef PRINT_INFO 
          printf("Send CMD55 should return 0x01, response=0x%02x\r\n", r1);
#endif
            return r1;
          }

          r1 = _send_command(ACMD41, 0x40000000, 0);	/* should be return 0x00 */
          if(r1 == 0x00) {
            retry = 0;
            break;
          }
        }
            
    /* Timeout return */
    if(retry == 0xFFF) {
#ifdef PRINT_INFO
      printf("Send ACMD41 should return 0x00, response=0x%02x\r\n", r1);
#endif
                return 3;
        }

        /* Read OCR by CMD58 */
    r1 = _send_command_hold(CMD58, 0, 0);
    if(r1!=0x00)
    {
#ifdef PRINT_INFO
    printf("Send CMD58 should return 0x00, response=0x%02x\r\n", r1);
#endif
    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;
#ifdef PRINT_INFO 
    printf("Card Type : SD V2HC\r\n");
#endif 	
  } else {
    CardInfo.CardType = CARDTYPE_SDV2;
#ifdef PRINT_INFO
    printf("Card Type : SD V2\r\n");
#endif 	
  }
  
    /* Set spi speed high */
    MSD_SPIHighSpeed(1);
    }	
  }
  return 0;
}