Active-Semi Solutions for Sustainability
Chinese (Simplified)English

Flash programming error

Ask an EngineerCategory: GeneralFlash programming error
Robert McIntosh asked 7 months ago

I have separate applications that are sharing a flash write algorithm. In one codebase everything is working fine. I can write to flash pages with variables and save and recall after power cycle.
In another code base, I am having some problems. The page is different, but I don’t think that is an issue.
The problem is that in the second case, often the page will not be written after I supply four 32 bit words. I understand that 4 words are required to trigger a save to flash. In the event the save to flash is triggered, the order of the words is not correct. The first 32 bit word that I supply ends up at the end of the 4 dword section.
My data:
0x20000e78 (Hex)
0x8d3d (Hex)
0x8db7 (Hex)
0x8dbd (Hex)
Flash representation:
00008D3D 00008DB7 00008DBD 20000E78
the last dword should have been in the first address, but I find it at the end.
My flash write algorithms are simple enough to include here:

PAC5XXX_RAMFUNC void wait_for_flash_write()
{
	volatile uint32_t i;
	if(PAC55XX_MEMCTL->MEMSTATUS.WBUSY == 0)
		return;

	while (PAC55XX_MEMCTL->MEMSTATUS.WBUSY == 1)
		;

	// must delay exit to allow flash update to finish
	i = 0;
	while(i < 100)
		i++;

}

PAC5XXX_RAMFUNC void write_flash_words_to_pointer(uint32_t* flash_pointer, int32_t* data_buffer, uint32_t number_of_dwords) {
	int32_t i;
	for (i = 0; i < number_of_dwords; i++) {
		*flash_pointer++ = data_buffer[i];
		wait_for_flash_write();
	}
	while (i % 4 != 0) {
		i++;
		*flash_pointer++ = i;
		wait_for_flash_write();
	}
}

uint32_t flash_program_from_address(uint32_t *flash_address, uint16_t *word_buffer, uint32_t number_of_words)
{
	uint32_t *dword_buffer = (uint32_t *) word_buffer;

	if(PAC55XX_MEMCTL->FLASHLOCK != FLASH_LOCK_ALLOW_WRITE_ERASE_FLASH)
		PAC55XX_MEMCTL->FLASHLOCK = FLASH_LOCK_ALLOW_WRITE_ERASE_FLASH;

	write_flash_words_to_pointer(flash_address, dword_buffer, number_of_words / 2);

	return 0;
}

I call the function using address 0x8000 which should be 32nd flash page. I use the Active-Semi implementation of eclipse and GNU compiler.
Thanks for any help you can give,
Rob M

2 Answers
Jose Quinones answered 7 months ago

Hi Robert,
I will be looking further into this today. In the meantime, could you try the following? After you unlock the FLASH, can you set the write word count to 0? (PAC55XX_MEMCTL->MEMCTL.WRITEWORDCNT = 0;). Although it should be 0 after reset, we are wondering if for some reason the function to write FLASH is being interrupted and the call is happening when Word Count is something different than 0.

Robert McIntosh answered 7 months ago

Thanks for this, the answer was the WRITEWORDCNT. When I reset it to 0 the flash works.