📄 sd.c
字号:
//if( STATUS07_00 & RSPTIMEOUT )
if( STATUS07_00 &( RSPTIMEOUT | CRC7ERROR ))
{
status = KO;
break;
}
//if( STATUS07_00 & CRC7ERROR )
//{
//status = KO;
//break;
//}
}
while( !( STATUS07_00 & XFEREND ))
{
//if( STATUS07_00 & DTIMEOUT )
if( STATUS07_00 &( DTIMEOUT | CRC16ERROR ))
{
status = KO;
break;
}
//if( STATUS07_00 & CRC16ERROR )
//{
//status = KO;
//break;
//}
//if( SDH_DMA_ACK ==( DMA_ACK_F | DMA_ACK ))
//SDH_DMA_ACK = 0;
}
// what follows is much important for SD_CIF in USB mode,Mason@20060303
//while( !( STATUS15_08 & BUSYEND )); // not used in single-block write,Mason@20061030
while( !( STATUS15_08 & BUSYEND ));
SDH_DMA_ACK = DMA_AUTO;
STATUS07_00 = 0xFF;
STATUS15_08 = BUSYEND;
*/
return status;
}
/************************************************
函 数 名: SDCIF_CMD27()
功 能:Programming of the programmable bits of the CSD(128 bits)
说 明:数据存放地址由SDH_DMA_CS决定
调 用:
全局变量:ErrVal
入口参数:无
出口参数:无
返 回 值:无
************************************************/
Bool SDCIF_CMD27( void )
{
Bool status = OK;
BLKLEN11_08 = 0x00; //SET_BLOCKLEN
BLKLEN07_00 = 128 / 8;
DATACON = XFER_MODE_1; //block write
//argument dont't care
CMDCON = WAITRSP | DATA_WITH;
CMDINDEX = PROGRAM_CSD;
while( !( STATUS07_00 & CMDSEND ));
while( !( STATUS07_00 & RSPRXVP ))
{
/*if(( STATUS07_00 & RSPTIMEOUT )
||( STATUS07_00 & CRC7ERROR ))*/
if( STATUS07_00 &( RSPTIMEOUT | CRC7ERROR ))
{
status = KO;
break;
}
}
while( !(STATUS07_00 & XFEREND ))
{
/*if(( STATUS07_00 & DTIMEOUT )
||( STATUS07_00 & CRC16ERROR ))*/
if( STATUS07_00 &( DTIMEOUT | CRC16ERROR ))
{
status = KO;
break;
}
}
while( !( STATUS15_08 & BUSYEND ));
SDH_DMA_ACK &= ~DMA_ACK_F; //DMA acknowledge flag
STATUS07_00 = 0xFF;
STATUS15_08 = BUSYEND;
return status;
}
/************************************************
函 数 名: SDCIF_CMD28()
功 能:This command sets the write protection bit of the addressed group.
The properties of write protection are coded in the card specific data(WP_GRP_SIZE)
说 明:
调 用:
全局变量:ErrVal, SD_lba(FlashAddr[3:0])
入口参数:无
出口参数:无
返 回 值:无
************************************************/
Bool SDCIF_CMD28( void )
{
Bool status = OK;
DATACON = XFER_MODE_2; //check busy
ARG31_24 = SDVar.FlashAddr[ 0 ]; //argument = SD_lba(FlashAddr[3:0])
ARG23_16 = SDVar.FlashAddr[ 1 ];
ARG15_08 = SDVar.FlashAddr[ 2 ];
ARG07_00 = SDVar.FlashAddr[ 3 ];
CMDCON = WAITRSP | DATA_WITH;
CMDINDEX = SET_WRITE_PROT;
while( !(STATUS07_00 & CMDSEND ));
while( !(STATUS07_00 & RSPRXVP ))
{
/*if(( STATUS07_00 & RSPTIMEOUT )
||( STATUS07_00 & CRC7ERROR ))*/
if( STATUS07_00 &( RSPTIMEOUT | CRC7ERROR ))
{
status = KO;
break;
}
}
while( !( STATUS15_08 & BUSYEND ));
STATUS07_00 = 0xFF;
STATUS15_08 = BUSYEND;
return status;
}
/************************************************
函 数 名: SDCIF_CMD29()
功 能:This command clears the write protection bit of the addressed group
说 明:
调 用:
全局变量:ErrVal, SD_lba(FlashAddr[3:0])
入口参数:无
出口参数:无
返 回 值:无
************************************************/
Bool SDCIF_CMD29( void )
{
Bool status = OK;
DATACON = XFER_MODE_2; //check busy
ARG31_24 = SDVar.FlashAddr[ 0 ]; //argument = SD_lba(FlashAddr[3:0])
ARG23_16 = SDVar.FlashAddr[ 1 ];
ARG15_08 = SDVar.FlashAddr[ 2 ];
ARG07_00 = SDVar.FlashAddr[ 3 ];
CMDCON = WAITRSP | DATA_WITH;
CMDINDEX = CLR_WRITE_PROT;
while( !( STATUS07_00 & CMDSEND ));
while(!( STATUS07_00 & RSPRXVP ))
{
/*if(( STATUS07_00 & RSPTIMEOUT )
||( STATUS07_00 & CRC7ERROR ))*/
if( STATUS07_00 &( RSPTIMEOUT | CRC7ERROR ))
{
status = KO;
break;
}
}
while( !( STATUS15_08 & BUSYEND ));
STATUS07_00 = 0xFF;
STATUS15_08 = BUSYEND;
return status;
}
/************************************************
函 数 名: SDCIF_CMD30()
功 能:This command asks the card to send the status of the write protection bits
说 明:数据存放地址由SDH_DMA_CS决定
调 用:
全局变量:ErrVal, SD_lba(FlashAddr[3:0])
入口参数:无
出口参数:无
返 回 值:无
************************************************/
Bool SDCIF_CMD30( void )
{
Bool status = OK;
BLKLEN11_08 = 0x00; //SET_BLOCKLEN
BLKLEN07_00 = 0x04;
DATACON = XFER_MODE_0; //block read
ARG31_24 = SDVar.FlashAddr[ 0 ]; //argument = SD_lba(FlashAddr[3:0])
ARG23_16 = SDVar.FlashAddr[ 1 ];
ARG15_08 = SDVar.FlashAddr[ 2 ];
ARG07_00 = SDVar.FlashAddr[ 3 ];
CMDCON = WAITRSP | DATA_WITH;
CMDINDEX = SEND_WRITE_PROT;
while( !( STATUS07_00 & CMDSEND ));
while( !( STATUS07_00 & RSPRXVP ))
{
/*if(( STATUS07_00 & RSPTIMEOUT )
||( STATUS07_00 & CRC7ERROR ))*/
if( STATUS07_00 &( RSPTIMEOUT | CRC7ERROR ))
{
status = KO;
break;
}
}
while( !( STATUS07_00 & XFEREND ))
{
/*if(( STATUS07_00 & DTIMEOUT )
||( STATUS07_00 & CRC16ERROR ))*/
if( STATUS07_00 &( DTIMEOUT | CRC16ERROR ))
{
status = KO;
break;
}
}
STATUS07_00 = 0xFF;
return status;
}
/************************************************
函 数 名: SDCIF_CMD32()
功 能:Sets the address of the first write block to be erased
说 明:
调 用:
全局变量:ErrVal, SD_lba(FlashAddr[3:0])
入口参数:无
出口参数:无
返 回 值:无
************************************************/
Bool SDCIF_CMD32( void )
{
Bool status = OK;
ARG31_24 = SDVar.FlashAddr[ 0 ]; //argument = SD_lba(FlashAddr[3:0])
ARG23_16 = SDVar.FlashAddr[ 1 ];
ARG15_08 = SDVar.FlashAddr[ 2 ];
ARG07_00 = SDVar.FlashAddr[ 3 ];
CMDCON = WAITRSP;
CMDINDEX = ERASE_WR_BLK_START;
while( !( STATUS07_00 & CMDSEND ));
while( !( STATUS07_00 & RSPRXVP ))
{
/*if(( STATUS07_00 & RSPTIMEOUT )
||( STATUS07_00 & CRC7ERROR ))*/
if( STATUS07_00 &( RSPTIMEOUT | CRC7ERROR ))
{
status = KO;
break;
}
}
STATUS07_00 = 0xFF;
return status;
}
/************************************************
函 数 名: SDCIF_CMD33()
功 能:Sets the address of the last write block of the continuous range to be erased
说 明:
调 用:
全局变量:ErrVal, SD_lba(FlashAddr[3:0])
入口参数:无
出口参数:无
返 回 值:无
************************************************/
Bol SDCIF_CMD33( void )
{
Bool status = OK;
ARG31_24 = SDVar.FlashAddr[ 0 ]; //argument = SD_lba(FlashAddr[3:0])
ARG23_16 = SDVar.FlashAddr[ 1 ];
ARG15_08 = SDVar.FlashAddr[ 2 ];
ARG07_00 = SDVar.FlashAddr[ 3 ];
CMDCON = WAITRSP;
CMDINDEX = ERASE_WR_BLK_END;
while( !( STATUS07_00 & CMDSEND ));
while(!(STATUS07_00 & RSPRXVP))
{
/*if(( STATUS07_00 & RSPTIMEOUT )
||( STATUS07_00 & CRC7ERROR ))*/
if( STATUS07_00 &( RSPTIMEOUT | CRC7ERROR ))
{
status = KO;
break;
}
}
STATUS07_00 = 0xFF;
return status;
}
/************************************************
函 数 名: SDCIF_CMD38()
功 能:Erases all previously selected write blocks
说 明:
调 用:
全局变量:ErrVal
入口参数:无
出口参数:无
返 回 值:无
************************************************/
Bool SDCIF_CMD38( void )
{
Bool status = OK;
//argument dont't care
DATACON = XFER_MODE_2; //check busy
CMDCON = WAITRSP;
CMDINDEX = ERASE;
while( !( STATUS07_00 & CMDSEND ));
while( !( STATUS07_00 & RSPRXVP ))
{
/*if(( STATUS07_00 & RSPTIMEOUT )
||( STATUS07_00 & CRC7ERROR ))*/
if( STATUS07_00 &( RSPTIMEOUT | CRC7ERROR ))
{
status = KO;
break;
}
}
while( !( STATUS15_08 & BUSYEND ));
STATUS07_00 = 0xFF;
STATUS15_08 = BUSYEND;
return status;
}
/************************************************
函 数 名: SDCIF_CMD42()
功 能:Used to set/reset the password or lock/unlock the card
The size of the data block is set by the SET_BLOCK_LEN command
说 明:数据存放地址由SDH_DMA_CS决定
调 用:
全局变量:ErrVal
入口参数:BlockLen: 块长度, 由CMD16设置
出口参数:无
返 回 值:无
************************************************/
Bool SDCIF_CMD42( U8 BlockLen )
{
Bool status = OK;
BLKLEN11_08 = (U8)( BlockLen >> 8 ); //SET_BLOCKLEN
BLKLEN07_00 = (U8)BlockLen;
DATACON = XFER_MODE_1; //block write
//argument dont't care
CMDCON = WAITRSP | DATA_WITH;
CMDINDEX = LOCK_UNLOCK;
while( !( STATUS07_00 & CMDSEND ));
while( !( STATUS07_00 & RSPRXVP ))
{
/*if(( STATUS07_00 & RSPTIMEOUT )
||( STATUS07_00 & CRC7ERROR ))*/
if( STATUS07_00 &( RSPTIMEOUT | CRC7ERROR ))
{
status = KO;
break;
}
}
while( !( STATUS07_00 & XFEREND ))
{
/*if(( STATUS07_00 & DTIMEOUT )
||( STATUS07_00 & CRC16ERROR ))*/
if( STATUS07_00 &( DTIMEOUT | CRC16ERROR ))
{
status = KO;
break;
}
}
while( !( STATUS15_08 & BUSYEND ));
SDH_DMA_ACK &= ~DMA_ACK_F;//DMA acknowledge flag
STATUS07_00 = 0xFF;
STATUS15_08 = BUSYEND;
return status;
}
#endif
/************************************************
函 数 名: SDCIF_CMD55()
功 能:Indicates to the card that the next command is an
application specific command rather than a
standard command
说 明:
调 用:
全局变量:RCA
入口参数:无
出口参数:无
返 回 值:无
************************************************/
Bool SDCIF_CMD55( void )
{
Bool status = OK;
ARG31_24 = SDVar.RCA[ 1 ]; //argument = RCA
ARG23_16 = SDVar.RCA[ 0 ];
ARG15_08 = 0;
ARG07_00 = 0;
CMDCON = WAITRSP;
CMDINDEX = APP_CMD;
while( !( STATUS07_00 & CMDSEND ));
while( !( STATUS07_00 & RSPRXVP ))
{
/*if(( STATUS07_00 & RSPTIMEOUT )
||( STATUS07_00 & CRC7ERROR ))*/
if( STATUS07_00 &( RSPTIMEOUT | CRC7ERROR ))
{
//STATUS07_00 = 0xFF;
//return KO;
status = KO;
break;
}
}
STATUS07_00 = 0xFF;
//return OK;
return status;
}
/************************************************
函 数 名: SDCIF_ACMD06()
功 能:Defines the data bus width('00' = 1bit or '10' = 4 bits bus)to be used for data transfer
说 明:用于SD卡
调 用:
全局变量:ErrVal, BusBits
入口参数:无
出口参数:无
返 回 值:无
************************************************/
//设置SD卡数据总线宽度
Bool SDCIF_ACMD06( void )
{
Bool status = OK;
ARG31_24 = 0;
ARG23_16 = 0;
ARG15_08 = 0;
ARG07_00 = SDVar.BusBits; //argument = bus wide
CMDCON = WAITRSP;
CMDINDEX = SET_BUS_WIDTH;
while( !( STATUS07_00 & CMDSEND ));
while( !( STATUS07_00 & RSPRXVP ))
{
/*if(( STATUS07_00 & RSPTIMEOUT )
||( STATUS07_00 & CRC7ERROR ))*/
if( STATUS07_00 &( RSPTIMEOUT | CRC7ERROR ))
{
//STATUS07_00 = 0xFF;
//return KO;
status = KO;
break;
}
}
STATUS07_00 = 0xFF;
// set up SD_CIF Host bus bit I/F after SD Card
if( SDVar.BusBits == 2 )
//SDIFCON0 = WIDEBUS | CLK_EN;
SDIFCON0 = WIDEBUS | CLK_EN/* | HISPEED*/;
else
//SDIFCON0 = WIDEBUS;
SDIFCON0 = CLK_EN;
//return OK;
return status;
}
/************************************************
函 数 名: SDCIF_ACMD13()
功 能:Send the SD Card status(512 bits)
说 明:数据存放地址由SDH_DMA_CS决定
调 用:必须先调用SDCIF_CMD55()
全局变量:ErrVal
入口参数:无
出口参数:无
返 回 值:无
************************************************/
#if 0
void SDCIF_ACMD13( void )
{
SDVar.ErrVal = 0;
//argument dont't care
BLKLEN11_08 = 0x00; //SET_BLOCKLEN
BLKLEN07_00 = 512 / 8;
CMDCON = WAITRSP | DATA_WITH;
CMDINDEX = SD_STATUS;
while( !( STATUS07_00 & CMDSEND ));
while( !( STATUS07_00 & RSPRXVP ))
{
if(( STATUS07_00 & RSPTIMEOUT )
||( STATUS07_00 & CRC7ERROR ))
{
SDVar.ErrVal = 1;
STATUS07_00 = 0xFF;
return;
}
}
while( !( STATUS07_00 & XFEREND ))
{
if(( STATUS07_00 & DTIMEOUT )
||( STATUS07_00 & CRC16ERROR ))
{
SDVar.ErrVal = 1;
STATUS07_00 = 0xFF;
return;
}
}
STATUS07_00 = 0xFF;
}
/************************************************
函 数 名: SDCIF_ACMD22()
功 能:Send the number of the written (without errors) write blocks
Responds with 32 bits + CRC data block
说 明:数据存放地址由SDH_DMA_CS决定
调 用:必须先调用SDCIF_CMD55()
全局变量:ErrVal
入口参数:无
出口参数:无
返 回 值:无
************************************************/
void SDCIF_ACMD22( void )
{
SDVar.ErrVal = 0;
//argument dont't care
BLKLEN11_08 = 0x00;//SET_BLOCKLEN
BLKLEN07_00 = 32 / 8;
CMDCON = WAITRSP | DATA_WITH;
CMDINDEX = SEND_NUMBER_WR_BLOCKS;
while( !( STATUS07_00 & CMDSEND ));
while( !( STATUS07_00 & RSPRXVP ))
{
if(( STATUS07_00 & RSPTIMEOUT )
||( STATUS07_00 & CRC7ERROR ))
{
SDVar.ErrVal = 1;
STATUS07_00 = 0xFF;
return;
}
}
while( !( STATUS07_00 & XFEREND ))
{
if(( STATUS07_00 & DTIMEOUT )
||( STATUS07_00 & CRC16ERROR ))
{
SDVar.ErrVal = 1;
STATUS07_00 = 0xFF;
return;
}
}
STATUS07_00 = 0xFF;
}
#endif
/************************************************
函 数 名: SDCIF_ACMD41()
功 能:Asks the accessed card to send its operating
condition register (OCR) content in the
response on the CMD line
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -