2018-08-14 05:49 AM
Hi all,
I am using the C55 Flash Drivers on the SPC570S40E1 mcu. When trying to write data from RAM to any of the low blocks, I get a Machine Check Interrupt after I call the function FlashProgram. The same thing happens with FlashErase as well. However, if I look at the memory locations, I can see that the data is correctly written (or erased) even though I get the machine check interrupt.
Funny thing is, I can program and erase the 8KB High blocks no problem, but all low blocks create this issue.
The code is like this
#include "flash_ctrl.h"
uint32_t flash_init(void)
{
pgmCtxData.pReqCompletionFn = FlashProgram;
bcCtxData.pReqCompletionFn = BlankCheck;
pvCtxData.pReqCompletionFn = ProgramVerify;
returnCode = FlashInit( &ssdConfig );
return returnCode;
}
uint32_t utest_lock(void)
{
returnCode = GetLock(&ssdConfig, C55_BLOCK_UTEST, &blkLockState);
if (!(blkLockState & 0x00000001))
returnCode = SetLock(&ssdConfig, C55_BLOCK_UTEST, LOCK_ALL_BLOCKS);
return returnCode;
}
uint32_t unblock_address_space(void)
{
returnCode = SetLock(&ssdConfig, C55_BLOCK_LOW, UNLOCK_ALL_BLOCKS);
returnCode = SetLock(&ssdConfig, C55_BLOCK_LARGE_FIRST, UNLOCK_ALL_BLOCKS);
returnCode = SetLock(&ssdConfig, C55_BLOCK_HIGH, UNLOCK_ALL_BLOCKS);
return returnCode;
}
uint32_t erase_block(MEM_BLOCK eraseBlock)
{
switch(eraseBlock){
case LOW_BLOCK1_16K:
lowBlockSelect = 0x00000002UL;
midBlockSelect = 0;
highBlockSelect = 0;
nLargeBlockSelect.firstLargeBlockSelect = 0;
nLargeBlockSelect.secondLargeBlockSelect = 0;
break;
case LOW_BLOCK2_16K:
lowBlockSelect = 0x00000004UL;
midBlockSelect = 0;
highBlockSelect = 0;
nLargeBlockSelect.firstLargeBlockSelect = 0;
nLargeBlockSelect.secondLargeBlockSelect = 0;
break;
case LOW_BLOCK3_16K:
lowBlockSelect = 0x00000008UL;
midBlockSelect = 0;
highBlockSelect = 0;
nLargeBlockSelect.firstLargeBlockSelect = 0;
nLargeBlockSelect.secondLargeBlockSelect = 0;
break;
case LOW_BLOCK4_16K:
lowBlockSelect = 0x00000010UL;
midBlockSelect = 0;
highBlockSelect = 0;
nLargeBlockSelect.firstLargeBlockSelect = 3;
nLargeBlockSelect.secondLargeBlockSelect = 0;
break;
case LOW_BLOCK5_32K:
lowBlockSelect = 0x00000020UL;
midBlockSelect = 0;
highBlockSelect = 0;
nLargeBlockSelect.firstLargeBlockSelect = 0;
nLargeBlockSelect.secondLargeBlockSelect = 0;
break;
case LOW_BLOCK6_32K:
lowBlockSelect = 0x00000040UL;
midBlockSelect = 0;
highBlockSelect = 0;
nLargeBlockSelect.firstLargeBlockSelect = 0;
nLargeBlockSelect.secondLargeBlockSelect = 0;
break;
case LOW_BLOCK7_64K:
lowBlockSelect = 0x00000080UL;
midBlockSelect = 0;
highBlockSelect = 0;
nLargeBlockSelect.firstLargeBlockSelect = 0;
nLargeBlockSelect.secondLargeBlockSelect = 0;
break;
case LOW_BLOCK8_64K:
lowBlockSelect = 0x00000100UL;
midBlockSelect = 0;
highBlockSelect = 0;
nLargeBlockSelect.firstLargeBlockSelect = 0;
nLargeBlockSelect.secondLargeBlockSelect = 0;
break;
case LARGE_BLOCK9_128K:
lowBlockSelect = 0;
midBlockSelect = 0;
highBlockSelect = 0;
nLargeBlockSelect.firstLargeBlockSelect = 1;
nLargeBlockSelect.secondLargeBlockSelect = 0;
break;
case LARGE_BLOCK10_128K:
lowBlockSelect = 0;
midBlockSelect = 0;
highBlockSelect = 0;
nLargeBlockSelect.firstLargeBlockSelect = 2;
nLargeBlockSelect.secondLargeBlockSelect = 0;
break;
case HIGH_BLOCK0_8K:
lowBlockSelect = 0;
midBlockSelect = 0;
highBlockSelect = 0x00000001UL;
nLargeBlockSelect.firstLargeBlockSelect = 0;
nLargeBlockSelect.secondLargeBlockSelect = 0;
break;
case HIGH_BLOCK1_8K:
lowBlockSelect = 0;
midBlockSelect = 0;
highBlockSelect = 0x00000002UL;
nLargeBlockSelect.firstLargeBlockSelect = 0;
nLargeBlockSelect.secondLargeBlockSelect = 0;
break;
case HIGH_BLOCK2_8K:
lowBlockSelect = 0;
midBlockSelect = 0;
highBlockSelect = 0x00000004UL;
nLargeBlockSelect.firstLargeBlockSelect = 0;
nLargeBlockSelect.secondLargeBlockSelect = 0;
break;
case HIGH_BLOCK3_8K:
lowBlockSelect = 0;
midBlockSelect = 0;
highBlockSelect = 0x00000008;
nLargeBlockSelect.firstLargeBlockSelect = 0;
nLargeBlockSelect.secondLargeBlockSelect = 0;
break;
}
returnCode = FlashErase( &ssdConfig, C55_ERASE_MAIN, lowBlockSelect, midBlockSelect, highBlockSelect, nLargeBlockSelect );
if (returnCode == C55_OK)
while (C55_INPROGRESS == FlashCheckStatus(&ssdConfig, C55_MODE_OP_ERASE, &opResult,&dummyCtxData)) {}
return returnCode;
}
uint32_t blank_check(uint32_t dest, uint32_t size)
{
returnCode = BlankCheck(&ssdConfig, dest, size, &failAddress, &failData, &bcCtxData);
if (returnCode == C55_OK)
while (C55_INPROGRESS == FlashCheckStatus(&ssdConfig, C55_MODE_OP_BLANK_CHECK, &opResult,&bcCtxData)) {};
return returnCode;
}
uint32_t program_and_verify(uint32_t dest, uint32_t buffer, uint32_t size)
{
returnCode = FlashProgram(&ssdConfig, TRUE, dest, size, buffer, &pgmCtxData);
if (returnCode == C55_OK)
{
while (C55_INPROGRESS == FlashCheckStatus(&ssdConfig, C55_MODE_OP_PROGRAM, &opResult, &pgmCtxData)) {};
}
returnCode = ProgramVerify( &ssdConfig, dest, size, (UINT32) buffer, &failAddress, &failData, &failSource, &pvCtxData);
if (returnCode == C55_OK)
{
while (C55_INPROGRESS == FlashCheckStatus(&ssdConfig, C55_MODE_OP_PROGRAM_VERIFY, &opResult, &pvCtxData)) {};
}
return returnCode;
}
And the ssdConfig I write as
SSD_CONFIG ssdConfig = {
C55_REG_BASE, /* C55 control register base */
MAIN_ARRAY_BASE, /* base of main array */
{0, 4, 2, 2}, /* blocks info of low address space */
{0, 0, 0, 0}, /* blocks info of mid address space */
{4, 0, 0, 0}, /* blocks info of high address space */
2, /* number of blocks in 256K address space */
UTEST_ARRAY_BASE, /* base of UTEST array */
FALSE, /* interface flag indicate main or alternate interface */
C55_PROGRAMMABLE_SIZE,/* programmable size */
TRUE /* debug mode selection */
};
I call the flash_init(), utest_lock(), unblock_address_space() functions before erasing/writing with no issues.
Thanks in advance
2018-08-14 10:09 PM
Hi,
could you show us the definition of FlashProgram? This function should executed from Ram. It looks like an read while write problem.
2018-08-16 04:43 AM
Hi David,
FlashProgram function is provided in the C55 Flash Driver. I don't have access to the codes, only the binaries.
2018-08-29 01:54 AM
Hello,
you cannot erase/program in the same partition code is running.
SPC570S40E1 has only two partitions: one for code (LOW and 128K blocks) and one for dataflash (HIGH).
If your code is running on flash , you can only erase/program data flash. If you want to erase/program code space , your code must be run from ram.
Regards