/*********************************************************************************************************
** 函数名称: MMC_disk_write
** 功能描述:
** 输 入: buff :Data to be written
** sector:Sector address (LBA)
** count:Number of sectors to write (1..255)
** 输 出: TRUE,正常返回
** FALSE,出错返回
********************************************************************************************************/
int MMC_disk_write (const BYTE *buff,DWORD sector,BYTE count)
{
sector *= 512; /* Convert to byte address if needed */
if (count == 1) /* Single block read */
{
if(xmit_datablock (buff, sector,1))/* WRITE_SINGLE_BLOCK */
count = 0;
}
else /* Multiple block read */
{
if(xmit_datablock(buff, sector,count*512))/* WRITE_SINGLE_BLOCK */
count = 0;
}
return count ? RES_ERROR : RES_OK;
}
/*-----------------------------------------------------------------------*/
/* Send a data packet to MMC */
/*-----------------------------------------------------------------------*/
/* 512 byte data block to be transmitted */
/* Data/Stop token */
static BOOL xmit_datablock (const BYTE *buff,DWORD sector,UINT token)
{
//Polling write Mode
int status;
unsigned int wrt_num=0;
UINT blk_num;
blk_num=token;
rSDIFSTA=rSDIFSTA|(1<<16); // FIFO reset
rSDIDCON=(2<<22)|(1<<20)|(1<<17)|(Wide<<16)|(1<<14)|(3<<12)|(blk_num<<0); //YH 040220
//Word Tx, Tx after rsp, blk, 1bit bus, Tx start, blk num
rSDICARG=sector; // CMD24/25(addr)
REWTCMD:
if(blk_num<2) // SINGLE_WRITE
{
rSDICCON=(0x1<<9)|(0x1<<8)|0x58; //sht_resp, wait_resp, dat, start, CMD24
if(!Chk_CMDend(24, 1)) //-- Check end of CMD24
goto REWTCMD;
}
else // MULTI_WRITE
{
rSDICCON=(0x1<<9)|(0x1<<8)|0x59; //sht_resp, wait_resp, dat, start, CMD25
if(!Chk_CMDend(25, 1)) //-- Check end of CMD25
goto REWTCMD;
}
rSDICSTA=0xa00; // Clear cmd_end(with rsp)
while(wrt_num<128*blk_num) // 512=128*4 bytes
{
status=rSDIFSTA;
if((status&0x2000)==0x2000)
{
rSDIDAT=br_LD_DWORD(buff);
buff+=4;
wrt_num++;
}
}
if(!Chk_DATend())
return FALSE;
rSDIDCON=rSDIDCON&~(7<<12); //YH 040220, Clear Data Transfer mode => no operation, Cleata Data Transfer start
rSDIDSTA=0x10; // Clear data Tx/Rx end
if(blk_num>1)
{
//--Stop cmd(CMD12)
REWCMD12:
rSDIDCON=(1<<18)|(1<<17)|(0<<16)|(1<<14)|(1<<12)|(blk_num<<0); //YH 040220
rSDICARG=0x0; //CMD12(stuff bit)
rSDICCON=(0x1<<9)|(0x1<<8)|0x4c; //sht_resp, wait_resp, start, CMD12
//-- Check end of CMD12
if(!Chk_CMDend(12, 1))
goto REWCMD12;
rSDICSTA=0xa00; // Clear cmd_end(with rsp)
//-- Check end of DATA(with busy state)
if(!Chk_BUSYend())
Uart_Printf("error\n");
rSDIDSTA=0x08; //! Should be cleared by writing '1'.
}
return TRUE; // Return with success
} |