⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 spi_msd_driver.c

📁 STM32_fatfs_shell_SDHC.rar
💻 C
📖 第 1 页 / 共 2 页
字号:
  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;  
}

/*******************************************************************************
* Function Name  : _read_buffer
* Description    : 
* Input          : - *buff		:
*                  - len			:
*                  - release	:
* Output         : None
* Return         : 0:NO_ERR; TRUE: Error
*******************************************************************************/
u8 _read_buffer(u8 *buff, u16 len, u8 release)
{
	u8 r1;
	u16 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;
}

/*******************************************************************************
* Function Name  : MSD_ReadSingleBlock
* Description    : 
* Input          : 
* Output         :
* Return         : 
*******************************************************************************/
u8 MSD_ReadSingleBlock(u32 sector, u8 *buffer)
{
	u8 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_ReadMultiBlock
* Description    : 
* Input          : 
* Output         :
* Return         : 
*******************************************************************************/
u8 MSD_ReadMultiBlock(u32 sector, u8 *buffer, u32 NbrOfSector)
{
	u8 r1;
	u32 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;
}

/*******************************************************************************
* Function Name  : MSD_WriteSingleBlock
* Description    : 
* Input          : 
* Output         : 
* Return         : 
*******************************************************************************/
u8 MSD_WriteSingleBlock(u32 sector, uc8 *buffer)
{
	u8 r1;
	u16 i;
	u32 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    : 
* Input          : 
* Output         : 
* Return         :
*******************************************************************************/
u8 MSD_WriteMultiBlock(u32 sector, uc8 *buffer, u32 NbrOfSector)
{
	u8 r1;
	u16 i;
	u32 n;
	u32 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;
}

/*******************************************************************************
* Function Name  : _spi_read
* Description    : 
* Input          : 
* Output         : 
* Return         :
*******************************************************************************/
__inline u8 _spi_read_write(u8 data)
{
	while((SPI1->SR & SPI_I2S_FLAG_TXE) == RESET);
  SPI1->DR = data;

  while((SPI1->SR & SPI_I2S_FLAG_RXNE) == RESET);
  return SPI1->DR;
}

/*******************************************************************************
* Function Name  : _send_command
* Description    : 
* Input          : - cmd	:
*                  - arg	:
*                  - crc	:
* Output         : None
* Return         : R1 value, response from card
*******************************************************************************/
u8 _send_command(u8 cmd, u32 arg, u8 crc)
{
  u8 r1;
  u8 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  : _send_command_hold
* Description    : 
* Input          : - cmd	:
*                  - arg	:
*                  - crc	:
* Output         : None
* Return         : R1 value, response from card
*******************************************************************************/
u8 _send_command_hold(u8 cmd, u32 arg, u8 crc)
{
  u8 r1;
  u8 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;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -