I wanted to add more details to my original post in this thread about programming the second flash bank (high blocks / BANK2) on MPC5646B using the SSD_C90FL driver.
BANK1 can be programmed without issues using the standard SSD_C90FL example. For BANK2, however, I still cannot get a working ssd_config configuration or correct block masks.
What I have checked and tried so far:
According to the block map in the MPC5646B Reference Manual, BANK2 consists of high blocks.
I have attempted to determine the addresses and masks for FlashErase() and FlashProgram() experimentally, but no success so far.
Unlocking via FlashSetLock() for high blocks does not work — likely due to incorrect mask values or base address settings.
I would appreciate help with the following points:
The correct SSD_CONFIG structure settings for BANK2 (addresses, sizes, number of blocks).
Whether a separate base address is required for BANK2 or if it shares the same base as BANK1.
Correct mask values for lowBlockLock, midBlockLock, and highBlockLock when unlocking high blocks.
A working example of FlashErase() and FlashProgram() calls for BANK2 on MPC5646B.
If anyone can share a working code snippet (or a link to an application note/example) where BANK2 is covered in detail for MPC5646B, that would be very helpful.
Here is my current draft configuration and code skeleton for BANK2:
#include "ssd_types.h"
#include "ssd_c90fl.h" // Header name may vary depending on SSD package
/* ======== TODO: Replace with exact values from MPC5646B RM ======== */
/* Fill in:
- P-Flash base address (main array)
- BANK2 (high blocks) start address, block size, number of blocks
- Shadow/UTEST base (if required)
- Correct lock/select masks for high blocks
*/
#define PFLASH_BASE 0x00XXXXXXu // TODO: base P-Flash address
#define BANK2_FIRST_BLOCK_ADDR 0x00YYYYYYu // TODO: start of first high block
#define BANK2_BLOCK_SIZE 0x00040000u // TODO: block size (e.g., 256KB)
#define BANK2_BLOCK_COUNT 0x00000004u // TODO: number of high blocks
#define DEMO_TARGET_ADDR (BANK2_FIRST_BLOCK_ADDR)
#define HIGH_BLOCK_SEL_MASK 0x00000001u // TODO: correct high block select mask
#define HIGH_BLOCK_LOCK_MASK 0x00000001u // TODO: correct high block lock mask
SSD_CONFIG ssdConfig = {
/* pFlashBase */ PFLASH_BASE,
/* uTestBase */ 0xXXXXXXu, // TODO: UTEST/shadow base (if required)
/* lowBlockNum */ 0,
/* midBlockNum */ 0,
/* highBlockNum */ BANK2_BLOCK_COUNT,
/* blockInfo */ NULL,
/* debugMode */ 0u,
/* callBack */ NULL
};
uint32_t demoBuf[64] = {0};
static void FillDemoBuffer(void)
{
for (uint32_t i = 0; i < (sizeof(demoBuf)/sizeof(demoBuf[0])); ++i) {
demoBuf[i] = 0xA5A50000u + i;
}
}
int ProgramBank2Demo(void)
{
uint32_t ret;
FLASH_SSD_CONFIG flashCfg = ssdConfig;
ret = FlashInit(&flashCfg);
if (ret != FTFx_OK) return ret;
ret = FlashSetLock(&flashCfg,
/* lowLock */ 0x00000000u,
/* midLock */ 0x00000000u,
/* highLock */ ~HIGH_BLOCK_LOCK_MASK);
if (ret != FTFx_OK) return ret;
ret = FlashBlockSelect(&flashCfg,
/* lowSel */ 0x00000000u,
/* midSel */ 0x00000000u,
/* highSel */ HIGH_BLOCK_SEL_MASK,
/* selInfo */ 0);
if (ret != FTFx_OK) return ret;
ret = FlashErase(&flashCfg,
/* dest */ DEMO_TARGET_ADDR,
/* size */ BANK2_BLOCK_SIZE,
/* key */ ERS_KEY);
if (ret != FTFx_OK) return ret;
FillDemoBuffer();
ret = FlashProgram(&flashCfg,
/* dest */ DEMO_TARGET_ADDR,
/* size */ sizeof(demoBuf),
/* pSource */ (uint32_t)demoBuf);
if (ret != FTFx_OK) return ret;
ret = FlashVerifyProgram(&flashCfg,
/* dest */ DEMO_TARGET_ADDR,
/* size */ sizeof(demoBuf),
/* pSource */ (uint32_t)demoBuf,
/* margin */ VERIFY_ALL);
return ret;
}