📄 ms.c
字号:
if((status = MS_TPC_SetRWAdrs(MS_STA0_REG,2,MS_SYS_REG,10))!=MS_NOERROR)
goto ERR_EXIT;
if((status = MS_TPC_WriteReg((kal_uint32*)data,10))!=MS_NOERROR)
goto ERR_EXIT;
// write page data into page buffer
if((status = MS_TPC_WritePage(txbuffer))!=MS_NOERROR)
goto ERR_EXIT;
// send SET_CMD[BLOCK_WRITE] ~ page mode
if((status = MS_TPC_SetCmd(CMD_BLOCK_WRITE,&intreg))!=MS_NOERROR)
goto ERR_EXIT;
// check int register
if((intreg & INT_ERR))
return MS_ERR_WRITEFAIL;
return MS_NOERROR;
ERR_EXIT:
#ifdef MSDC_USE_INT
// reset the events
kal_set_eg_events(MSDC_Events, 0, KAL_AND);
#endif
MS_API_ResetFlash();
MS_API_ClrBuffer();
return status;
}
/*************************************************************************
* FUNCTION
* MS_API_WriteBlock
*
* DESCRIPTION
* 1. write numpage pages form spage during a block or till the end of the block
* 2. make sure extra contains meaingful data.
* 3. the content of extra will be written to every modified page
*
* PARAMETERS
* blkadrs: physical block address
* txbuffer: buffer for the write data
* extra: buffer for the extra data
* spage: start of the writing page number
* numpage: number of the pages to write
* writtenpage: pages really be written
*
* RETURNS
* MS_STATUS
*
* GLOBALS AFFECTED
*
* NOTE
* .
*
*************************************************************************/
MS_STATUS MS_API_WriteBlock(kal_uint32 blkadrs, kal_uint32* txbuffer, kal_uint32* extra, kal_uint8 spage, kal_uint8 numpage, kal_uint8 *writtenpage)
{
MS_STATUS status;
kal_uint8 data[12],intreg,*ptr,i;
if(gMS.is_wp)
return MS_ERR_WP;
if(blkadrs == 0 || blkadrs == 1)
return MS_ERR_WP;
ptr = (kal_uint8*)extra;
// set parameters
data[0] = (kal_uint8)(blkadrs >> 16); // block address 2
data[1] = (kal_uint8)(blkadrs >> 8); // block address 1
data[2] = (kal_uint8)blkadrs; // block address 0
data[3] = (kal_uint8)BLOCK_MODE; // access mode
data[4] = spage; // page number of the block
data[5] = *ptr; // overwriteflag
data[6] = *(ptr+1); // managementflag
data[7] = *(ptr+2); // logical address 1
data[8] = *(ptr+3); // logical address 0
if((status = MS_TPC_SetRWAdrs(MS_STA0_REG,2,MS_BLKADRS2_REG,9))!=MS_NOERROR)
goto ERR_EXIT;
if((status = MS_TPC_WriteReg((kal_uint32*)data,9))!=MS_NOERROR)
goto ERR_EXIT;
// send SET_CMD[BLOCK_WRITE] ~ block mode
if((status = MS_TPC_SetCmd(CMD_BLOCK_WRITE,&intreg))!=MS_NOERROR)
goto ERR_EXIT;
*writtenpage = 0;
for(i = 0; i < numpage; i++)
{
if(!gMSDC_Handle.mIsPresent)
return MS_ERR_CARD_NOT_PRESENT;
// read status0~1
if((status = MS_TPC_ReadReg((kal_uint32*)data,2))!=MS_NOERROR)
goto ERR_EXIT;
// check int register
if((intreg & INT_ERR))
return MS_ERR_WRITEFAIL;
// check last page
if( intreg & INT_CED)
return MS_LASTPAGE;
if((data[0] & STA0_BE) && (intreg & INT_BREQ))
{
// set auto command
MS_SetAcmd(TPC_GET_INT,1);
if((status = MS_TPC_WritePage(txbuffer))!=MS_NOERROR)
goto ERR_EXIT;
txbuffer += MS_PAGE_SIZE/sizeof(kal_uint32);
(*writtenpage)++;
}
#ifndef MSDC_INT
if((status = MS_WaitCmdRdyOrTo())!=MS_NOERROR)
goto ERR_EXIT;
#endif
// read fifo to get int register
while(MSDC_IS_FIFO_EMPTY && gMSDC_Handle.mIsPresent);
intreg = *(volatile kal_uint8*)MSDC_DAT;
}
// reach the number of page
// check last page
if( intreg & INT_CED)
return (*writtenpage == numpage)?MS_NOERROR:MS_LASTPAGE;
else{
// send block end to stop the transmission
MS_TPC_SetCmd(CMD_BLOCK_END,&intreg);
}
// clear the fifo
MSDC_CLR_FIFO();
return MS_NOERROR;
ERR_EXIT:
#ifdef MSDC_USE_INT
// reset the events
kal_set_eg_events(MSDC_Events, 0, KAL_AND);
#endif
MS_API_ResetFlash();
MS_API_ClrBuffer();
return status;
}
/*************************************************************************
* FUNCTION
* MS_API_CopyPage
*
* DESCRIPTION
* Copy pages from spage following numpage pages in the r_blkadrs to w_blkadrs
*
* PARAMETERS
* w_blkadrs: destination
* r_blkadrs: source
* spage: starting page
* numpage: number of pages to copy
*
* RETURNS
* MS_STATUS
*
* GLOBALS AFFECTED
*
* NOTE
*
*
*************************************************************************/
MS_STATUS MS_API_CopyPage(kal_uint32 w_blkadrs, kal_uint32 r_blkadrs, kal_uint8 spage,kal_uint8 numpage)
{
MS_STATUS status;
kal_uint8 data[12],i,intreg;
if(gMS.is_wp)
return MS_ERR_WP;
for(i = 0; i < numpage; i++)
{
// set read parameters
data[0] = (kal_uint8)(r_blkadrs >> 16); // block address 2
data[1] = (kal_uint8)(r_blkadrs >> 8); // block address 1
data[2] = (kal_uint8)r_blkadrs; // block address 0
data[3] = (kal_uint8)PAGE_MODE; // access mode
data[4] = spage+i; // page number of the block
if((status = MS_TPC_SetRWAdrs(MS_STA0_REG,2,MS_BLKADRS2_REG,5))!=MS_NOERROR)
return status;
if((status = MS_TPC_WriteReg((kal_uint32*)data,5))!=MS_NOERROR)
return status;
// send SET_CMD[BLOCK_READ] ~ page mode
if((status = MS_TPC_SetCmd(CMD_BLOCK_READ,&intreg))!=MS_NOERROR)
return status;
// read status0~1
if((status = MS_TPC_ReadReg((kal_uint32*)data,2))!=MS_NOERROR)
return status;
// check int register
if(!(intreg & INT_CED))
return MS_ERRORS;
// uncorrectable errors
if((intreg & INT_ERR))
{
// chect the status1
if(*((kal_uint8*)data +1) & (STA1_UCFG | STA1_UCEX | STA1_UCDT))
return MS_ERR_UC;
}
// check MB and FB0 of status0
if(data[0] & (STA0_MB | STA0_FB0))
return MS_ERR_STABUSY;
// data is ready at pagebuffer
if(data[0] & STA0_BF)
{
//read extra data
if((status = MS_TPC_SetRWAdrs(MS_OVERWRITE_REG,MS_EXTRA_RSIZE,MS_BLKADRS2_REG,9))!=MS_NOERROR)
return status;
if((status = MS_TPC_ReadReg((kal_uint32*)((kal_uint8*)data+5),MS_EXTRA_RSIZE))!=MS_NOERROR)
return status;
// set the parameter for page write
data[0] = (kal_uint8)(w_blkadrs >> 16); // block address 2
data[1] = (kal_uint8)(w_blkadrs >> 8); // block address 1
data[2] = (kal_uint8)w_blkadrs; // block address 0
data[3] = (kal_uint8)PAGE_MODE; // access mode
data[4] = spage+i; // page number of the block
if((status = MS_TPC_SetRWAdrs(MS_STA0_REG,2,MS_BLKADRS2_REG,9))!=MS_NOERROR)
return status;
if((status = MS_TPC_WriteReg((kal_uint32*)data,9))!=MS_NOERROR)
return status;
// send SET_CMD[BLOCK_WRITE] ~ page mode
if((status = MS_TPC_SetCmd(CMD_BLOCK_WRITE,&intreg))!=MS_NOERROR)
return status;
// check int register
if((intreg & INT_ERR))
return MS_ERR_WRITEFAIL;
// short data state error
if( !(intreg & INT_CED))
return MS_ERRORS;
}else
return MS_ERRORS;
}// end of for(i)
return MS_NOERROR;
}
/*************************************************************************
* FUNCTION
* MS_API_EraseBlock
*
* DESCRIPTION
* Erase the specific block with its extra data
*
* PARAMETERS
* blkadrs: physical block address to be erased
*
* RETURNS
* MS_STATUS
*
* GLOBALS AFFECTED
*
* NOTE
* After erased, the content of the block and extra data will filled with 0xff
*
*************************************************************************/
MS_STATUS MS_API_EraseBlock(kal_uint32 blkadrs)
{
MS_STATUS status;
kal_uint8 data[4],intreg;
if(gMS.is_wp)
return MS_ERR_WP;
if(blkadrs == 0 || blkadrs == 1)
return MS_ERR_WP;
data[0] = (kal_uint8)(blkadrs >> 16); // block address 2
data[1] = (kal_uint8)(blkadrs >> 8); // block address 1
data[2] = (kal_uint8)blkadrs; // block address 0
if((status = MS_TPC_SetRWAdrs(MS_STA0_REG,2,MS_BLKADRS2_REG,3))!=MS_NOERROR)
return status;
if((status = MS_TPC_WriteReg((kal_uint32*)data,3))!=MS_NOERROR)
return status;
if((status = MS_TPC_SetCmd(CMD_BLOCK_ERASE,&intreg))!=MS_NOERROR)
return status;
if(intreg & INT_ERR)
return MS_ERR_ERASEFAIL;
return MS_NOERROR;
}
/*************************************************************************
* FUNCTION
* MS_API_ReadExtraData
*
* DESCRIPTION
* read the extra data from the page of a block
*
* PARAMETERS
* blkadrs: physical block address
* page: page number of the block
* extra: extra data
*
* RETURNS
* MS_STATUS
*
* GLOBALS AFFECTED
*
* NOTE
*
*************************************************************************/
MS_STATUS MS_API_ReadExtraData(kal_uint32 blkadrs, kal_uint8 page, kal_uint32 *extra)
{
MS_STATUS status;
kal_uint8 data[8],intreg;
// set parameters
data[0] = MS_SYS_DEFAULT;
data[1] = (kal_uint8)(blkadrs >> 16); // block address 2
data[2] = (kal_uint8)(blkadrs >> 8); // block address 1
data[3] = (kal_uint8)blkadrs; // block address 0
data[4] = (kal_uint8)EXTRA_MODE; // access mode
data[5] = page; // page number of the block
if((status = MS_TPC_SetRWAdrs(MS_STA0_REG,2,MS_SYS_REG,6))!=MS_NOERROR)
return status;
if((status = MS_TPC_WriteReg((kal_uint32*)data,6))!=MS_NOERROR)
return status;
// send SET_CMD[BLOCK_READ] ~ extra mode
if((status = MS_TPC_SetCmd(CMD_BLOCK_READ,&intreg))!=MS_NOERROR)
return status;
// read status0~1
if((status = MS_TPC_ReadReg((kal_uint32*)data,2))!=MS_NOERROR)
return status;
if((intreg & INT_ERR) && ( data[1] & (STA1_UCEX | STA1_UCFG)))
return MS_ERRORS;
// read extra data
if(intreg & INT_CED)
{
if((status = MS_TPC_SetRWAdrs(MS_OVERWRITE_REG,MS_EXTRA_RSIZE,MS_BLKADRS2_REG,5))!=MS_NOERROR)
return status;
if((status = MS_TPC_ReadReg(extra,MS_EXTRA_RSIZE))!=MS_NOERROR)
return status;
}
else
return MS_ERRORS;
return MS_NOERROR;
}
/*************************************************************************
* FUNCTION
* MS_API_WriteExtraData
*
* DESCRIPTION
* write the extra data to the page of a block
*
* PARAMETERS
* blkadrs: physical block address
* page: page number of the block
* extra: extra data
*
* RETURNS
* MS_STATUS
*
* GLOBALS AFFECTED
*
* NOTE
*
*************************************************************************/
MS_STATUS MS_API_WriteExtraData(kal_uint32 blkadrs, kal_uint8 page, kal_uint32 *extra)
{
MS_STATUS status;
kal_uint8 data[9],intreg,*ptr;
if(gMS.is_wp)
return MS_ERR_WP;
ptr = (kal_uint8*)extra;
// set parameters
data[0] = (kal_uint8)(blkadrs >> 16); // block address 2
data[1] = (kal_uint8)(blkadrs >> 8); // block address 1
data[2] = (kal_uint8)blkadrs; // block address 0
data[3] = (kal_uint8)EXTRA_MODE; // access mode
data[4] = page; // page number of the block
data[5] = *ptr; // overwriteflag
data[6] = *(ptr+1); // managementflag
data[7] = *(ptr+2); // logical address 1
data[8] = *(ptr+3); // logical address 0
if((status = MS_TPC_SetRWAdrs(MS_STA0_REG,2,MS_BLKADRS2_REG,9))!=MS_NOERROR)
return status;
if((status = MS_TPC_WriteReg((kal_uint32*)data,9))!=MS_NOERROR)
return status;
// send SET_CMD[BLOCK_READ] ~ page mode
if((status = MS_TPC_SetCmd(CMD_BLOCK_WRITE,&intreg))!=MS_NOERROR)
return status;
if((intreg & INT_ERR) || !(intreg & INT_CED))
return MS_ERRORS;
return MS_NOERROR;
}
/*************************************************************************
* FUNCTION
* MS_API_OverwriteExtraData
*
* DESCRIPTION
* Overwrite the OverwriteFlag of single page
*
* PARAMETERS
* blkadrs: physical block address
* page: page number of the block
* overwrite: overwrite flag byte
*
* RETURNS
* MS_STATUS
*
* GLOBALS AFFECTED
*
* NOTE
*
*************************************************************************/
MS_STATUS MS_API_OverwriteExtraData(kal_uint32 blkadrs, kal_uint8 page, kal_uint8 overwrite)
{
MS_STATUS status;
kal_uint8 data[6],intreg;
if(gMS.is_wp)
return MS_ERR_WP;
// set parameters
data[0] = (kal_uint8)(blkadrs >> 16); // block address 2
data[1] = (kal_uint8)(blkadrs >> 8); // block address 1
data[2] = (kal_uint8)blkadrs; // block address 0
data[3] = (kal_uint8)OVERWRITE_MODE; // access mode
data[4] = page; // page number of the block
data[5] = overwrite; // overwriteflag
if((status = MS_TPC_SetRWAdrs(MS_STA0_REG,2,MS_BLKADRS2_REG,6))!=MS_NOERROR)
return status;
if((status = MS_TPC_WriteReg((kal_uint32*)data,6))!=MS_NOERROR)
return status;
// send SET_CMD[BLOCK_READ] ~ page mode
if((status = MS_TPC_SetCmd(CMD_BLOCK_WRITE,&intreg))!=MS_NOERROR)
return status;
if((intreg & INT_ERR) || !(intreg & INT_CED))
return MS_ERRORS;
return MS_NOERROR;
}
/*************************************************************************
* FUNCTION
* MS_API_ResetFlash
*
* DESCRIPTION
* Flash Memory Controller is forced to reset.
*
* PARAMETERS
*
* RETURNS
* MS_STATUS
*
* GLOBALS AFFECTED
*
* NOTE
*
*************************************************************************/
MS_STATUS MS_API_ResetFlash()
{
MS_STATUS status;
// send the TPC (1 bytes data)
MS_SendTPC(TPC_SET_CMD,1);
// write 1 byte data into fifo
while(MSDC_IS_FIFO_FULL && gMSDC_Handle.mIsPresent);
*(volatile kal_uint8*)MSDC_DAT = CMD_RESET;
// wait cmd ready or busy timeout
if((status = MS_WaitCmdRdyOrTo())!=MS_NOERROR)
return status;
return MS_NOERROR;
}
/*************************************************************************
* FUNCTION
* MS_API_Sleep
*
* DESCRIPTION
* To suspend the oscillation for the internal clock of MS
*
* PARAMETERS
*
* RETURNS
* MS_STATUS
*
* GLOBALS AFFECTED
*
* NOTE
*
*************************************************************************/
MS_STATUS MS_API_Sleep()
{
MS_STATUS status;
kal_uint8 intreg;
if((status = MS_TPC_SetCmd(CMD_SLEEP,&intreg))!=MS_NOERROR)
return status;
if(!(intreg & INT_CED))
return MS_ERRORS;
return MS_NOERROR;
}
/*************************************************************************
* FUNCTION
* MS_API_ClrBuffer
*
* DESCRIPTION
* To clear the data in PageBuffer
*
* PARAMETERS
*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -