📄 mcp_ctl.c
字号:
if(uTimeLoop == SMT_M_MS2CNT(5))
{
smtErrInf.iSmtErr = SMT_E_ECCRDY;
iRetVal=SMT_E_FAILURE;
}
(unsigned short*)pBuffer = smtProlBuff.bFlatBuff; // Switch the address of Prolix buffer;
}
if(iRetVal ==SMT_E_SUCCESS )
{ for(iLoop = 0; iLoop < SMT_S_PROLIX-2; iLoop+=2)
{
*(unsigned short*)pBuffer = *MCP_R_DATAIO; // Read data area
pBuffer +=2;
}
// SMT_M_INTDISABLE; // Interrupt disable
*(unsigned short*)pBuffer = *MCP_R_DATAIO; // Read last data
asm("nop");
iRetVal = mcpReadyCheck(SMT_M_US2CNT(1)); // Ready check (1uS) routine is call
// SMT_M_INTENABLE; // Interrupt enable
}
// }
// else
// {
// SMT_M_INTENABLE; // Interrupt enable
}
MCP_R_CLE = SMT_BYTE1; // CLE is set up in high
*MCP_R_DATAIO = SMT_C_DREAD_1; // Read command
MCP_R_CLE = SMT_BYTE0; // CLE is set up in low
return(iRetVal);
}
/************************************************************************
* mcpPageProgram
* Type : int
* Ret val : Error Code
* SMT_E_SUCCESS ( 0) ... Successful
* SMT_E_FAILURE (-1) ... Failure
* Argument : unsigned long ulColumn ... Column address
* unsigned long ulPage ... Page address
* const char *pBuffer ... Read data buffer
* unsigned char bVerify ... Verify Enable/Disable flag
* Function : Page program function
************************************************************************/
int mcpPageProgram(unsigned long ulColumn, unsigned long ulPage, const char *pBuffer, unsigned char bVerify)
{
int iRetVal; // Return value
int iLoop; // Loop Counter
union SMT_STATUS uStatus; // Status code
unsigned long uTimeLoop; // Time Loop Counter
unsigned short *pWrtPnt; //16bit device
unsigned short ulCvtPage;
if(mcp_EraseFlg)
{
mcpEraseChk();
}
if((unsigned long)pBuffer & 0x01) // check if pBuffer Address A0
{
memcpy(ulTranBuf, pBuffer , SMT_S_DATA);
pWrtPnt = ulTranBuf;
}
else
pWrtPnt = (unsigned short *)pBuffer;
ulCvtPage = ulPage + mcp_offset;
// DMA Setting
*(volatile unsigned long*)0x48240 = 0x0; // clear DmaReg
*(volatile unsigned short*)0x48240 = SMT_S_DATA/2; // transfer count
*(volatile unsigned char*)0x48243 = 0x80; // dual transfer mode
*(volatile unsigned long*)0x48244 = (unsigned long)pWrtPnt; // source address
*(volatile unsigned char*)0x48247 |=0x70; // 16bit transfer, src inc
*(volatile unsigned long*)0x48248 = (unsigned long)SMT_R_AREA15; // dest address
*(volatile unsigned char*)0x4824b &=0x0f; // successive transfer mode, dest fix
*(volatile unsigned char*)0x4824b |=0x40;
MCP_R_WP = SMT_BYTE1; // WP is set up in high
MCP_R_CLE = SMT_BYTE1; // CLE is set up in high
*MCP_R_DATAIO = SMT_C_SDATINP; // Serial data input command
MCP_R_CLE = SMT_BYTE0; // CLE is set up in low
MCP_R_ALE = SMT_BYTE1; // ALE is set up in high
*MCP_R_DATAIO = SMT_M_BYTE(ulColumn, SMT_BYTE0); // Column address
*MCP_R_DATAIO = SMT_M_BYTE(ulCvtPage, SMT_BYTE0); // Page address (LOW)
*MCP_R_DATAIO = SMT_M_BYTE(ulCvtPage, SMT_BYTE1); // (HIGH)
if(mcp_MdaSiz > 32)
{
*MCP_R_DATAIO = SMT_M_BYTE(ulCvtPage, SMT_BYTE2);
}
MCP_R_ALE = SMT_BYTE0; // ALE is set up in low
SMT_ECC_RST; // Reset ECC
SMT_ECC_EN; // Enable ECC
SMT_DMA_ENABLE;
SMT_DMA_TRG;
// pWrtPnt = (unsigned char *)pBuffer; //8bit device
/* pWrtPnt = (unsigned short *)pBuffer; // 16bit device
for(iLoop = 0; iLoop < SMT_S_DATA; iLoop+=2) // Write data area
{
*MCP_R_DATAIO = *pWrtPnt++;
}
*/
for(uTimeLoop = 0; uTimeLoop<SMT_M_US2CNT(10); uTimeLoop++)
{
if(!SMT_DMA_FLAG)
break;
}
SMT_ECC_DIS; // Disable ECC
/* Check ECC Redy */
for(uTimeLoop = 0; uTimeLoop <SMT_M_MS2CNT(5); uTimeLoop++)
{
if(SMT_ECC_RDY)
break;
}
if(uTimeLoop < SMT_M_MS2CNT(5)){ //ECC Ready Ok
smtProlBuff.stDatBuff.bEcc1[0] = *ECC_A0_LPL_ADDR; //LP0
smtProlBuff.stDatBuff.bEcc1[1] = *ECC_A0_LPH_ADDR; //LP1
smtProlBuff.stDatBuff.bEcc1[2] = *ECC_A0_CP_ADDR; //CP
smtProlBuff.stDatBuff.bEcc2[0] = *ECC_A1_LPL_ADDR;
smtProlBuff.stDatBuff.bEcc2[1] = *ECC_A1_LPH_ADDR;
smtProlBuff.stDatBuff.bEcc2[2] = *ECC_A1_CP_ADDR;
pWrtPnt = (unsigned short*)smtProlBuff.bFlatBuff;
for(iLoop = 0 ; iLoop < SMT_S_PROLIX; iLoop+=2) // Write Prolix area
{
*MCP_R_DATAIO = *pWrtPnt++;
}
MCP_R_CLE = SMT_BYTE1; // CLE is set up in high
// SMT_M_INTDISABLE; // Interrupt disable
*MCP_R_DATAIO = SMT_C_PROGRAM; // Page program command
asm("nop");
iRetVal = mcpReadyCheck(SMT_M_MS2CNT(20)); // Ready check (20mS) routine is call
// SMT_M_INTENABLE; // Interrupt enable
if(iRetVal == SMT_E_SUCCESS)
{
MCP_R_WP = SMT_BYTE0; // WP is set up in low
iRetVal = mcpStatusRead(&uStatus.bByte); // Status read routine is call
if(iRetVal == SMT_E_SUCCESS)
{
if(((uStatus.stBit.bRB)&&(uStatus.stBit.bPF)) // Status = Ready? and Erase = Fail?
||(!uStatus.stBit.bRB)) // or Status = Busy?
{
smtErrInf.iSmtErr = SMT_E_PAGPROG; // ERROR : Page program error !!
iRetVal = SMT_E_FAILURE;
}
}
}
}
else{
smtErrInf.iSmtErr = SMT_E_ECCRDY;
iRetVal=SMT_E_FAILURE;
}
MCP_R_CLE = SMT_BYTE1; // CLE is set up in high
*MCP_R_DATAIO = SMT_C_DREAD_1; // Read command
MCP_R_CLE = SMT_BYTE0; // CLE is set up in low
if(bVerify)
{
iRetVal = smtVerifyCheck(ulPage, pBuffer);
}
return(iRetVal);
}
/************************************************************************
* mcpProlixProgram
* Type : int
* Ret val : Error Code
* SMT_E_SUCCESS ( 0) ... Successful
* SMT_E_FAILURE (-1) ... Failure
* Argument : unsigned long ulColumn ... Column address
* unsigned long ulPage ... Page address
* const char *pBuffer ... Read data buffer (16 Bytes)
* Function : Prolix program function
************************************************************************/
int mcpProlixProgram(unsigned long ulColumn, unsigned long ulPage, const char *pBuffer)
{
int iRetVal; // Return value
int iLoop; // Loop Counter
union SMT_STATUS uStatus; // Status code
if(mcp_EraseFlg)
{
mcpEraseChk();
}
ulPage += mcp_offset;
iRetVal = mcpMediaReset();
if(iRetVal != SMT_E_SUCCESS)
{
return(SMT_E_FAILURE);
}
MCP_R_WP = SMT_BYTE1; // WP is set up in high
MCP_R_CLE = SMT_BYTE1; // CLE is set up in high
*MCP_R_DATAIO = SMT_C_DREAD_3; // Serial data input command
*MCP_R_DATAIO = SMT_C_SDATINP; // Serial data input command
MCP_R_CLE = SMT_BYTE0; // CLE is set up in low
MCP_R_ALE = SMT_BYTE1; // ALE is set up in high
*MCP_R_DATAIO = SMT_M_BYTE(ulColumn, SMT_BYTE0); // Column address
*MCP_R_DATAIO = SMT_M_BYTE(ulPage, SMT_BYTE0); // Page address (LOW)
*MCP_R_DATAIO = SMT_M_BYTE(ulPage, SMT_BYTE1); // (HIGH)
if(mcp_MdaSiz > 32)
{
*MCP_R_DATAIO = SMT_M_BYTE(ulPage, SMT_BYTE2);
}
MCP_R_ALE = SMT_BYTE0; // ALE is set up in low
for(iLoop = 0; iLoop < SMT_S_PROLIX; iLoop+=2)
{
*MCP_R_DATAIO = *(unsigned short*)pBuffer; // Write prolix area
pBuffer+=2;
}
MCP_R_CLE = SMT_BYTE1; // CLE is set up in high
// SMT_M_INTDISABLE; // Interrupt disable
*MCP_R_DATAIO = SMT_C_PROGRAM; // Page program command
asm("nop");
iRetVal = mcpReadyCheck(SMT_M_MS2CNT(20)); // Ready check (20mS) routine is call
// SMT_M_INTENABLE; // Interrupt disable
if(iRetVal == SMT_E_SUCCESS)
{
MCP_R_WP = SMT_BYTE0; // WP is set up in low
iRetVal = mcpStatusRead(&uStatus.bByte); // Status read routine is call
if(iRetVal == SMT_E_SUCCESS)
{
if(((uStatus.stBit.bRB)&&(uStatus.stBit.bPF)) // Status = Ready? and Erase = Fail?
||(!uStatus.stBit.bRB)) // or Status = Busy?
{
smtErrInf.iSmtErr = SMT_E_PAGPROG; // ERROR : Page program error !!
iRetVal = SMT_E_FAILURE;
}
}
}
MCP_R_CLE = SMT_BYTE1; // CLE is set up in high
*MCP_R_DATAIO = SMT_C_DREAD_1; // Read command
MCP_R_CLE = SMT_BYTE0; // CLE is set up in low
return(iRetVal);
}
/************************************************************************
* mcpReadyCheck
* Type : int
* Ret val : Error Code
* SMT_E_SUCCESS ( 0) ... Successful
* SMT_E_FAILURE (-1) ... Failure
* Argument : unsigned long ulTime ... Wait time
* Function : Ready statuc check
************************************************************************/
int mcpReadyCheck(unsigned long ulTime)
{
int iRetVal; // Return Value
unsigned long ulLoop; // Loop Counter
for(ulLoop = 0; ulLoop < ulTime; ulLoop++)
{
if(MCP_R_RB) // Ready?
{
break;
}
}
if(ulLoop < ulTime)
{
iRetVal = SMT_E_SUCCESS;
smtErrInf.iSmtErr = SMT_E_SUCCESS;
}
else
{
iRetVal = SMT_E_FAILURE;
smtErrInf.iSmtErr = SMT_E_TIMEOUT;
}
return(iRetVal);
}
/************************************************************************
* mcpEraseChk
* Type : int
* Ret val : Error Code
* SMT_E_SUCCESS ( 0) ... Successful
* SMT_E_FAILURE (-1) ... Failure
* Argument : none
* Function : Block Erase result check
************************************************************************/
int mcpEraseChk(void)
{
int iRetVal;
union SMT_STATUS uStatus; // Status code
if(!mcp_EraseFlg)
{
return(SMT_E_SUCCESS);
}
mcp_EraseFlg = 0; // Erasing flag clear
iRetVal = mcpReadyCheck(SMT_M_MS2CNT(400)); // Ready check (400mS) routine is call
if(iRetVal == SMT_E_SUCCESS)
{
MCP_R_WP = SMT_BYTE0; // WP is set up in low
iRetVal = mcpStatusRead(&uStatus.bByte); // Status read routine is call
if(iRetVal == SMT_E_SUCCESS)
{
if(((uStatus.stBit.bRB)&&(uStatus.stBit.bPF)) // Status = Ready? and Erase = Fail?
||(!uStatus.stBit.bRB)) // or Status = Busy?
{
smtErrInf.iSmtErr = SMT_E_BKERASE; // ERROR : Block erase error !!
iRetVal = SMT_E_FAILURE;
}
}
}
return(iRetVal);
}
/***** End of file *****/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -