Hi Li Yong
Actually I already did that in my code. Here are the some code. Sometimes it works well. sometimes in some words it return access error. these position always are 0xffffffff. But if I rewrite these words. it can get the right value.
Thank you!
#define FTFA_STAT_ERROR_MASK 0x70
#define FTFA_STAT_CCIF 0x80
static uint32_t writeWordToFlash(uint32_t addr, uint32_t data, uint32_t opt)
{
int i;
uint32_t status;
uint32_t val;
uint8_t *chVar = (uint8_t *)&data;
hw_ftfa_fccob_t fccob;
if(addr&0x03)
{
printf("Invalid address\n");
return DAP_ERROR_ADDRESS;
}
val = readMem(REGS_FTFA_BASE);
/*Clear the old error */
if((val & FTFA_STAT_ACCERR_MASK) || (val & FTFA_STAT_FPVIOL_MASK) || (val & FTFA_STAT_RDCOLERR_MASK))
writeMem(REGS_FTFA_BASE, FTFA_STAT_ERROR_MASK);
if(opt==FTFA_CMD_PROGRAM_LONGWORD)
{
/* Prepare the FTFA FCCOB */
fccob.FCCOB0 = FTFA_CMD_PROGRAM_LONGWORD;
fccob.FCCOB1 = (uint8_t)((addr >> 16) & 0xff);
fccob.FCCOB2 = (uint8_t)((addr >> 8) & 0xff);
fccob.FCCOB3 = (uint8_t)(addr & 0xff);
fccob.FCCOB4 = chVar[3];
fccob.FCCOB5 = chVar[2];
fccob.FCCOB6 = chVar[1];
fccob.FCCOB7 = chVar[0];
/* Write FCFOC */
writeMem(FTFA_FCCOB_BASE, *(uint32_t *)(&fccob.FCCOB3));
writeMem(FTFA_FCCOB_BASE+4, *(uint32_t *)(&fccob.FCCOB7));
}
else if(opt==FTFA_CMD_PROGRAM_CHECK)
{
/*check the flash*/
fccob.FCCOB0 = FTFA_CMD_PROGRAM_CHECK;
fccob.FCCOB1 = (uint8_t)((addr >> 16) & 0xff);
fccob.FCCOB2 = (uint8_t)((addr >> 8) & 0xff);
fccob.FCCOB3 = (uint8_t)(addr & 0xff);
fccob.FCCOB4 = 0x2;
fccob.FCCOB8 = chVar[3];
fccob.FCCOB9 = chVar[2];
fccob.FCCOBA = chVar[1];
fccob.FCCOBB = chVar[0];
/* Write FCFOC */
writeMem(FTFA_FCCOB_BASE, *(uint32_t *)(&fccob.FCCOB3));
writeMem(FTFA_FCCOB_BASE+4, *(uint32_t *)(&fccob.FCCOB7));
writeMem(FTFA_FCCOB_BASE+8, *(uint32_t *)(&fccob.FCCOBB));
}
/* Start command */
writeAP(AP_CSW, AP_CSW_8BIT_TRANSFER);
writeMem(REGS_FTFA_BASE, FTFA_STAT_CCIF);
writeAP(AP_CSW, AP_CSW_DEFAULT);
/* Wait for done */
for(i=0; i<WAIT_FTFA_CCIF_COUNT; i++)
{
val = readMem(REGS_FTFA_BASE);
if(val&FTFA_STAT_ACCERR_MASK)
{
printf("Access Error. val = 0x%08x, i = %d, opt = %d\n", val, i, opt);
return DAP_ERROR_ACCESS;
}
if(val&FTFA_STAT_FPVIOL_MASK)
{
printf("Protection error. val = 0x%08x, i = %d, opt = %d\n", val, i, opt);
return DAP_ERROR_FPVIOL;
}
if(val&FTFA_STAT_RDCOLERR_MASK)
{
printf("Read collision error. val = 0x%08x, i = %d, opt = %d\n", val, i, opt);
return DAP_ERROR_RDCOLERR;
}
if(val&FTFA_STAT_ERROR_MGSTAT0)
{
printf("MGSTAT0 error. val = 0x%08x, i = %d, opt = %d\n", val, i, opt);
return DAP_ERROR_MGSTAT0;
}
if((val&0xF0)==FTFA_STAT_CCIF)
break;
}
return SWD_ERROR_OK;
}