📄 sd_cmd.c
字号:
**
** Parameters: mode, mode that the SD card will be set to (SD_IDLE or SD_SPI)
**
** Returns: 0 - Reset command successful
** -1 - Failed to reset the card
**
****************************************************************************/
int8 set_SD_mode(uint8 mode)
{
int16 n;
uint8 data_temp;
//***********************************************************************
if(reset_sd()) // SEND COMMAND0 TO SD CARD
return((int8) EOF);
//***********************************************************************
if(mode == SD_SPI)
{
data_temp = 0xFF;
for(n = 0; ((n < 1000) || (data_temp == 0)); n++)
{
SD_CS_ON();
data_temp = _FF_spi(0xFF);
SD_CS_OFF();
}
if(data_temp)
{
_FF_spi(0xFF);
for(n = 0; n < 100; n++)
{
if(init_sd() == 0) /* Initialization Succeeded */
break; /* SEND COMMAND1 TO SD CARD */
}
}
else
n = 100;
if(n >= 100)
return((int8) EOF);
}
return(0);
}
#ifdef _DEBUG_ON_
/****************************************************************************
**
** Read 512 bytes of data from the card and print the raw data in hex format
** to the serial port designated by the _FF_putchar() function.
**
** Parameters: sd_addr, the sector address of the card where the function
** will read from.
**
** Returns: NONE
**
****************************************************************************/
void _FF_read_disp(uint32 sd_addr)
{
uint8 resp;
uint32 n, remainder;
clear_sd_buff();
_SD_send_cmd(CMD17, sd_addr<<9); /* Send read request */
resp = _FF_spi(0xFF);
while(resp != SD_START_TOKEN)
resp = _FF_spi(0xFF);
for(n = 0; n < 512; n++)
{
remainder = n & 0xF;
if(remainder == 0)
_FF_printf(_FF_CRLFStr);
_FF_Buff[n] = _FF_spi(0xFF);
_FF_printf(_FF_02XStr, _FF_Buff[n]);
}
_FF_spi(0xFF);
_FF_spi(0xFF);
_FF_spi(0xFF);
SD_CS_OFF();
_FF_spi(0xFF);
return;
}
#endif /*_DEBUG_ON_*/
/****************************************************************************
**
** Read 1 sector of data (ususally 512 bytes) into the buffer designated by
** the *sd_read_buff pointer
**
** Parameters: sd_addr, the sector address of the card where the function
** will read from.
** *sd_read_buff, pointer to the buffer that the function will
** store the read data.
**
** Returns: 0 - Read Successful
** -1 - Read Failed
**
****************************************************************************/
int8 _FF_read(uint32 sd_addr, uint8 *sd_read_buff)
{
uint8 resp, c;
int16 n;
#ifdef _FF_READ_DEBUG_
_FF_printf(_read_addrStr, sd_addr<<9);
#endif
for(c = 0; c < 10; c++)
{
clear_sd_buff();
#ifdef _BYTES_PER_SEC_512_
_SD_send_cmd(CMD17, (sd_addr<<9)); /* read block command */
#else
_SD_send_cmd(CMD17, (sd_addr*BPB_BytsPerSec.uval16)); /* read block command */
#endif
resp = _FF_spi(0xFF);
for(n = 0; ((n < 30000) && (resp != SD_START_TOKEN)); n++)
resp = _FF_spi(0xFF);
if(resp == SD_START_TOKEN)
{
/* if it is a valid start byte => start reading SD Card */
#ifdef _BYTES_PER_SEC_512_
for(n = 0; n < 512; n++)
{
#else
for(n = 0; n < BPB_BytsPerSec.uval16; n++)
{
#endif
sd_read_buff[n] = _FF_spi(0xFF);
}
_FF_spi(0xFF);
_FF_spi(0xFF);
_FF_spi(0xFF);
SD_CS_OFF();
_FF_spi(0xFF);
_FF_error = NO_ERR;
if(sd_read_buff == _FF_Buff)
_FF_BuffAddr = sd_addr;
return(0);
}
SD_CS_OFF();
_FF_spi(0xFF);
if (c == 4)
set_SD_mode(SD_SPI); /* Try to reset and initialize the card to SPI mode */
}
_FF_error = READ_ERR;
return((int8) EOF);
}
#ifndef _READ_ONLY_
/****************************************************************************
**
** Writes 1 sector of bytes (usually 512) designated by *sd_write_buff to
** the address sd_addr.
**
** Parameters: sd_addr, the sector address of the card where the function
** will write to.
** *sd_write_buff, pointer to the buffer that the function will
** write data from.
**
** Returns: 0 - Write Successful
** -1 - Write Failed
**
****************************************************************************/
int8 _FF_write(uint32 sd_addr, uint8 *sd_write_buff)
{
#if defined(_USE_MULTIBLOCK_SINGLE_)
uint8 resp, calc, c;
int16 n;
for(c = 0; c < 4; c++)
{
clear_sd_buff();
resp = 0xFF;
_SD_send_cmd(CMD25, (sd_addr << 9)); /* Send Write Multi-Block Command */
for(n = 0; ((n < 30000) && (resp == 0xFF)); n++)
resp = _FF_spi(0xFF);
if(resp == 0)
{
#ifdef _DEBUG_MULTI_BLOCK_
_FF_printf(_FF_WriteBlockStartStr);
#endif
/* Start Sending the Packet in the correct format */
_FF_spi(0xFF);
_FF_spi(SD_MULTI_START); /* Start Block Token */
/* Send Data */
#ifdef _BYTES_PER_SEC_512_
for(n = 0; n < 512; n++)
{
#else
for(n = 0; n < BPB_BytsPerSec.uval16; n++)
{
#endif
_FF_spi(sd_write_buff[n]); /* Write Data in buffer to card */
}
_FF_spi(0xFF); /* Send 2 blank CRC bytes */
_FF_spi(0xFF);
n = 0;
do
{
resp = _FF_spi(0xFF); /* Response should be 0bXXX00101 */
} while((resp == 0xFF) && (n++ < 30000));
#ifdef _DEBUG_MULTI_BLOCK_
_FF_printf(_FF_WriteBlock02XStr, resp, n);
#endif
calc = resp | 0xE0;
if(calc == 0xE5)
{
while(_FF_spi(0xFF) == 0)
{
/* Wait for not busy */
if(n++ > 30000)
{
#ifdef _FF_WRITE_DEBUG_
_FF_printf(_FF_WriteAddrErrStr, 1);
#endif
break; /* Clear Buffer before returning 'OK' */
}
}
_FF_spi(0xFF);
_FF_spi(SD_STOP_TRANS); /* Stop Block Token */
while(_FF_spi(0xFF) == 0)
{
/* Wait for not busy */
if(n++ > 30000)
{
#ifdef _FF_WRITE_DEBUG_
_FF_printf(_FF_WriteAddrErrStr, 1);
#endif
break; /* Clear Buffer before returning 'OK' */
}
}
SD_CS_OFF();
_FF_spi(0xFF);
return(0); /* All Good, return */
}
else
{
_FF_spi(0xFF);
_FF_spi(SD_STOP_TRANS);
}
}
#ifdef _DEBUG_MULTI_BLOCK_
else
{
_FF_printf(_FF_WriteMultiStartStr, 4, resp);
}
#endif
}
SD_CS_OFF();
_FF_spi(0xFF);
return((uint8) EOF);
#else /*defined(_USE_MULTIBLOCK_SINGLE_)*/
uint8 resp, calc, c;
uint16 n;
#ifdef _FF_WRITE_DEBUG_
_FF_printf(_FF_WriteAddr_ldXStr, sd_addr<<9);
#endif
if(sd_write_buff == _FF_Buff)
_FF_BuffAddr = sd_addr;
if(sd_addr <= _FF_PartitionAddr)
{
/* if the Address is l */
_FF_error = WRITE_ERR;
return((int8) EOF);
}
for(c = 0; c < 10; c++)
{
clear_sd_buff();
#ifdef _BYTES_PER_SEC_512_
_SD_send_cmd(CMD24, (sd_addr<<9));
#else
_SD_send_cmd(CMD24, (sd_addr*(uint32)BPB_BytsPerSec.uval16));
#endif
resp = _FF_spi(0xFF);
for(n = 0; ((n < 30000) && (resp != 0x00)); n++)
resp = _FF_spi(0xFF);
if(resp == 0)
{
_FF_spi(0xFF);
_FF_spi(SD_START_TOKEN); /* Start Block Token */
#ifdef _BYTES_PER_SEC_512_
for(n = 0; n < 512; n++)
{
#else
for(n = 0; n < BPB_BytsPerSec.uval16; n++)
{
#endif
_FF_spi(sd_write_buff[n]); /* Write Data in buffer to card */
}
_FF_spi(0xFF); /* Send 2 blank CRC bytes */
_FF_spi(0xFF);
resp = _FF_spi(0xFF); /* Response should be 0bXXX00101 */
calc = resp | 0xE0;
if(calc == 0xE5)
{
n = 0;
while(_FF_spi(0xFF) == 0)
{
if(n++ > 30000)
{
#ifdef _FF_WRITE_DEBUG_
_FF_printf(_FF_WriteAddrErrStr, 1);
#endif
break; /* Clear Buffer before returning 'OK' */
}
}
SD_CS_OFF();
_FF_spi(0xFF);
_FF_error = NO_ERR;
return(0);
}
}
SD_CS_OFF();
_FF_spi(0xFF);
if (c == 5)
set_SD_mode(SD_SPI); /* Try to reset and initialize the card to SPI mode */
}
_FF_error = WRITE_ERR;
#ifdef _FF_WRITE_DEBUG_
_FF_printf(_FF_WriteAddrErrStr, 2);
#endif
return((int8) EOF);
#endif /*defined(_USE_MULTIBLOCK_SINGLE_)*/
}
#endif /*_READ_ONLY_*/
#if defined(_SD_BLOCK_WRITE_) && !defined(_READ_ONLY_)
/****************************************************************************
**
** Function used to start a block write
**
** Parameters: sd_data, byte to write in block mode
**
** Returns: 0 - Byte written successfully
** -1 - An error occurred
**
****************************************************************************/
int8 SD_write_block_start(uint32 sd_addr, uint32 blk_size)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -