📄 spi_msd_driver.c
字号:
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 + -