Beispiel #1
0
/***********************************************************
* Function:
* Description:
* Input:
* Input:
* Output:
* Return:
* Others:
***********************************************************/
static rt_uint8_t _spi_sd_sendcmd_hold( rt_uint8_t cmd, rt_uint32_t arg, rt_uint8_t crc )
{
	rt_uint32_t r1, n;
#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
	_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 );

	for( n = 0; n < 200; n++ )
	{
		r1 = _spi_send_recv( DUMMY_BYTE );
		if( r1 != 0xFF )
		{
			break;
		}
	}
	return ( r1 ); /* Return with the response value */
}
/*******************************************************************************
* Function Name  : _send_command_hold
* Description    : None
* Input          : - cmd:
*				   - arg:
*                  - crc:
* Output         : None
* Return         : R1 value, response from card
* Attention		 : None
*******************************************************************************/
int _send_command_hold(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;
        }
    }

    return r1;
}
Beispiel #3
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 */
}
/*******************************************************************************
* 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 #5
0
/*****************************************************************************
   Write 512 bytes
   buffer: 512 byte data block to be transmitted
   token:  0xFE -> single block
   0xFC -> multi block
   0xFD -> Stop
*****************************************************************************/
static rt_uint8_t _spi_sd_writedatablock( const rt_uint8_t *buff, rt_uint8_t token )
{
	rt_uint8_t resp, i=0;

	i = i;                      // avoid warning
	_card_enable( );
	_spi_send_recv( DUMMY_BYTE );
	_spi_send_recv( DUMMY_BYTE );
	_spi_send_recv( DUMMY_BYTE );
	_spi_send_recv( token );    /* send data token first*/

	if( token != TOKEN_STOP_TRAN )
	{
		for( i = 512 / 4; i; i-- )
		{
			_spi_send_recv( *buff++ );
			_spi_send_recv( *buff++ );
			_spi_send_recv( *buff++ );
			_spi_send_recv( *buff++ );
		}
		_spi_send_recv( DUMMY_CRC );            /* 16-bit CRC (Dummy) */
		_spi_send_recv( DUMMY_CRC );

		resp = _spi_send_recv( DUMMY_BYTE );    /* Receive data response */
		if( ( resp & 0x1F ) != 0x05 )           /* If not accepted, return with error */
		{
			return false;
		}
		if( _spi_sd_wait4ready( ) == false )    /* Wait while Flash Card is busy. */
		{
			return false;
		}
	}

	return true;
}
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;
}
/*******************************************************************************
* 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_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 #10
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;
}