📄 smt_ctl.c
字号:
break;
}
if(uTimeLoop == SMT_M_MS2CNT(5))
{
smtErrInf.iSmtErr = SMT_E_ECCRDY;
iRetVal=SMT_E_FAILURE;
}
pBuffer = smtProlBuff.bFlatBuff; // Switch the address of Prolix buffer;
}
if(iRetVal == SMT_E_SUCCESS)
{
for(iLoop = 0; iLoop < SMT_S_PROLIX - 1; iLoop++)
{
*pBuffer++ = *SMT_R_DATAIO; // Read data area
}
SMT_M_INTDISABLE; // Interrupt disable
*pBuffer = *SMT_R_DATAIO; // Read last data
asm("nop");
SMT_R_CE = SMT_BYTE1; // CE is set up in high
iRetVal = smtReadyCheck(SMT_M_US2CNT(1)); // Ready check (1uS) routine is call
SMT_M_INTENABLE;
}
}
else
{
SMT_M_INTENABLE; // Interrupt enable
}
SMT_R_CE = SMT_BYTE0; // CE is set up in low
SMT_R_CLE = SMT_BYTE1; // CLE is set up in high
*SMT_R_DATAIO = SMT_C_DREAD_1; // Read command
SMT_R_CLE = SMT_BYTE0; // CLE is set up in low
SMT_R_CE = SMT_BYTE1; // CE is set up in low
return(iRetVal);
}
/************************************************************************
* smtPageProgram
* 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 smtPageProgram(unsigned long ulColumn, unsigned long ulPage, const char *pBuffer, unsigned char bVerify)
{
int iRetVal; // Return value
int iLoop; // Loop Counter
unsigned long uTimeLoop; // Time Loop Counter
union SMT_STATUS uStatus; // Status code
unsigned char *pWrtPnt;
if(smt_EraseFlg)
{
smtEraseChk();
}
// DMA Setting
*(volatile unsigned long*)0x48240 = 0x0; // clear DmaReg
*(volatile unsigned short*)0x48240 = SMT_S_DATA; // transfer count
*(volatile unsigned char*)0x48243 = 0x80; // dual transfer mode
*(volatile unsigned long*)0x48244 = (unsigned long)pBuffer; // source address
*(volatile unsigned char*)0x48247 &=0x3f; // byte transfer
*(volatile unsigned char*)0x48247 |=0x30; // src inc
*(volatile unsigned long*)0x48248 = SMT_R_AREA15; // dest address
*(volatile unsigned char*)0x4824b &=0x0f; // successive transfer mode, dest fix
*(volatile unsigned char*)0x4824b |=0x40;
SMT_R_WP = SMT_BYTE1; // WP is set up in high
SMT_R_CLE = SMT_BYTE1; // CLE is set up in high
SMT_R_CE = SMT_BYTE0; // CE is set up in low
*SMT_R_DATAIO = SMT_C_SDATINP; // Serial data input command
SMT_R_CLE = SMT_BYTE0; // CLE is set up in low
SMT_R_ALE = SMT_BYTE1; // ALE is set up in high
*SMT_R_DATAIO = SMT_M_BYTE(ulColumn, SMT_BYTE0); // Column address
*SMT_R_DATAIO = SMT_M_BYTE(ulPage, SMT_BYTE0); // Page address (LOW)
*SMT_R_DATAIO = SMT_M_BYTE(ulPage, SMT_BYTE1); // (HIGH)
if(smt_MdaSiz > 32)
{
*SMT_R_DATAIO = SMT_M_BYTE(ulPage, SMT_BYTE2);
}
SMT_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;
for(iLoop = 0; iLoop < SMT_S_DATA; iLoop++) // Write data area
{
*SMT_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 = smtProlBuff.bFlatBuff;
for(iLoop = 0 ; iLoop < SMT_S_PROLIX; iLoop++) // Write Prolix area
{
*SMT_R_DATAIO = *pWrtPnt++;
}
SMT_R_CLE = SMT_BYTE1; // CLE is set up in high
SMT_M_INTDISABLE; // Interrupt disable
*SMT_R_DATAIO = SMT_C_PROGRAM; // Page program command
asm("nop");
iRetVal = smtReadyCheck(SMT_M_MS2CNT(20)); // Ready check (20mS) routine is call
SMT_M_INTENABLE; // Interrupt enable
if(iRetVal == SMT_E_SUCCESS)
{
SMT_R_WP = SMT_BYTE0; // WP is set up in low
iRetVal = smtStatusRead(&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;
}
SMT_R_CE = SMT_BYTE0; // CE is set up in low
SMT_R_CLE = SMT_BYTE1; // CLE is set up in high
*SMT_R_DATAIO = SMT_C_DREAD_1; // Read command
SMT_R_CLE = SMT_BYTE0; // CLE is set up in low
SMT_R_CE = SMT_BYTE1; // CE is set up in low
if(bVerify)
{
iRetVal = smtVerifyCheck(ulPage, pBuffer);
}
return(iRetVal);
}
/************************************************************************
* smtProlixProgram
* 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 smtProlixProgram(unsigned long ulColumn, unsigned long ulPage, const char *pBuffer)
{
int iRetVal; // Return value
int iLoop; // Loop Counter
union SMT_STATUS uStatus; // Status code
if(smt_EraseFlg)
{
smtEraseChk();
}
iRetVal = smtMediaReset();
if(iRetVal != SMT_E_SUCCESS)
{
return(SMT_E_FAILURE);
}
SMT_R_WP = SMT_BYTE1; // WP is set up in high
SMT_R_CLE = SMT_BYTE1; // CLE is set up in high
SMT_R_CE = SMT_BYTE0; // CE is set up in low
*SMT_R_DATAIO = SMT_C_DREAD_3; // Serial data input command
*SMT_R_DATAIO = SMT_C_SDATINP; // Serial data input command
SMT_R_CLE = SMT_BYTE0; // CLE is set up in low
SMT_R_ALE = SMT_BYTE1; // ALE is set up in high
*SMT_R_DATAIO = SMT_M_BYTE(ulColumn, SMT_BYTE0); // Column address
*SMT_R_DATAIO = SMT_M_BYTE(ulPage, SMT_BYTE0); // Page address (LOW)
*SMT_R_DATAIO = SMT_M_BYTE(ulPage, SMT_BYTE1); // (HIGH)
if(smt_MdaSiz > 32)
{
*SMT_R_DATAIO = SMT_M_BYTE(ulPage, SMT_BYTE2);
}
SMT_R_ALE = SMT_BYTE0; // ALE is set up in low
for(iLoop = 0; iLoop < SMT_S_PROLIX; iLoop++)
{
*SMT_R_DATAIO = *pBuffer++; // Write prolix area
}
SMT_R_CLE = SMT_BYTE1; // CLE is set up in high
SMT_M_INTDISABLE; // Interrupt disable
*SMT_R_DATAIO = SMT_C_PROGRAM; // Page program command
asm("nop");
iRetVal = smtReadyCheck(SMT_M_MS2CNT(20)); // Ready check (20mS) routine is call
SMT_M_INTENABLE; // Interrupt disable
if(iRetVal == SMT_E_SUCCESS)
{
SMT_R_WP = SMT_BYTE0; // WP is set up in low
iRetVal = smtStatusRead(&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;
}
}
}
SMT_R_CE = SMT_BYTE0; // CE is set up in low
SMT_R_CLE = SMT_BYTE1; // CLE is set up in high
*SMT_R_DATAIO = SMT_C_DREAD_1; // Read command
SMT_R_CLE = SMT_BYTE0; // CLE is set up in low
SMT_R_CE = SMT_BYTE1; // CE is set up in low
return(iRetVal);
}
/************************************************************************
* smtReadyCheck
* 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 smtReadyCheck(unsigned long ulTime)
{
int iRetVal; // Return Value
unsigned long ulLoop; // Loop Counter
for(ulLoop = 0; ulLoop < ulTime; ulLoop++)
{
if(SMT_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);
}
/************************************************************************
* smtEraseChk
* Type : int
* Ret val : Error Code
* SMT_E_SUCCESS ( 0) ... Successful
* SMT_E_FAILURE (-1) ... Failure
* Argument : none
* Function : Block Erase result check
************************************************************************/
int smtEraseChk(void)
{
int iRetVal;
union SMT_STATUS uStatus; // Status code
if(!smt_EraseFlg)
{
return(SMT_E_SUCCESS);
}
smt_EraseFlg = 0; // Erasing flag clear
iRetVal = smtReadyCheck(SMT_M_MS2CNT(400)); // Ready check (400mS) routine is call
if(iRetVal == SMT_E_SUCCESS)
{
SMT_R_WP = SMT_BYTE0; // WP is set up in low
iRetVal = smtStatusRead(&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 + -