I'm hoping for the collective knowledge here, as I get stuck at my current project... I'm trying to implement an update function for the application program on a PIC32CZ8110CA... µC.
The following problem:
- I'm using the µC without having written my own bootloader.
- I would like to receive the new program code during normal program execution and write it to the second application flash bank. That works so far.
- Now the new program code is verified and then the µC is ready for the bank swap and a restart.
- After the restart, the new program should run.
But I'm stuck at point with the bank swap. I think I'm setting the right bit, but after a restart the old program continues to run as if nothing had happened.
I had a similar problem with an ATSAMD51, and I was told that the function for the bank swap had to be a RAMFUNC. In retrospect, that sounds logical and it worked there too. That doesn't seem to be the problem with the PIC32CZ.
Here are the relevant parts of my code:
else if(rx_cfg_buffer[rx_cfg_gi].DATA[3] == 0x0F) // Firmwareupdate
{
if(rx_cfg_buffer[rx_cfg_gi].DATA[2] == 0x01)
{
firmware_msg_cnt = (uint32_t)((rxTestbuffer_8Bit[7+8]<<24) | rxTestbuffer_8Bit[6+8]<<16) | (rxTestbuffer_8Bit[5+8]<<8) | rxTestbuffer_8Bit[4+8]);
clean_rx_cfg_reply_data();
rx_cfg_reply.ID = rx_cfg_buffer[rx_cfg_gi].ID+1;
rx_cfg_reply.DATA[2] = 0x00;
rx_cfg_reply.DATA[3] = 0x0F;
rx_cfg_reply.DATA[4] = FIRMWAREUPDATE_MSG_LIMIT;
send_cfg_reply();
// Flashbereich löschen
panel2_firmware_erase(firmware_msg_cnt);
// Neue Firmware abholen
get_firmware(firmware_msg_cnt);
// Prüfen neue Firmware
verify_firmware(firmware_msg_cnt);
// Bank-Swap
volatile uint32_t current_panel = ((FCW_REGS->FCW_SWAP & FCW_SWAP_PFSWAP_Msk) >> FCW_SWAP_PFSWAP_Pos);
if(current_panel == 1)
FCW_ProgramFlashBankSelect(0);
else
FCW_ProgramFlashBankSelect(1);
}
}
#define PROGRAM_FLASH_BANK_1 (0U)
#define PROGRAM_FLASH_BANK_2 (1U)
#define __ramfunc__ __attribute__ ((section(".ramfunc"), unique_section, noinline))
typedef uint32_t PROGRAM_FLASH_BANK;
typedef enum
{
FCW_UNLOCK_WRKEY = 0x91C32C01,
FCW_UNLOCK_SWAPKEY = 0x91C32C02,
FCW_UNLOCK_CFGKEY = 0x91C32C04
}FCW_UNLOCK_KEY;
static void FCW_UnlockSequence(FCW_UNLOCK_KEY key)
{
FCW_REGS->FCW_KEY = (uint32_t)key;
}
__ramfunc__ void FCW_ProgramFlashBankSelect(PROGRAM_FLASH_BANK pfmBank)
{
while(((FCW_REGS->FCW_STATUS & FCW_STATUS_BUSY_Msk)) != 0U)
{
/* Do Nothing */
}
FCW_UnlockSequence(FCW_UNLOCK_SWAPKEY);
if (pfmBank == PROGRAM_FLASH_BANK_1)
{
FCW_REGS->FCW_SWAP &= (~FCW_SWAP_PFSWAP_Msk);
}
else
{
FCW_REGS->FCW_SWAP |= (FCW_SWAP_PFSWAP_Msk);
}
}
Here is the link to the data sheet: .html
Best regards and many thanks, Fabian