Hi
I used the SWD to program flash in KL05 demo board. In FCCOB I set Program Longword command. But sometimes in several words they return access error (FSTAT[ACCERR]); The read data is 0xFFFFFFFF. I must do the command again for those words. then it is OK.
Thank you
Hi Wang Dongsheng,
Please be suggested to check CCIF first to make sure that there is no flash command is complete and then write 1 to this bit to launch the next longword program command.
If the problem still remains, then, please contact me again!
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;
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;
}
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;
}