I am using an ADuC7021 for my embedded application. one task is to drive a 7-seg display, another task is to store parameters in Flash/EE. The refresh display function is called every 2.5ms. The flash erase is called when the next flash page is not blank.
The problem I have is that when the flash page is erased, everything else stops for 24ms. This causes a beat in the display. I have been looking at running the relevant sections of code from RAM during Flash erase, but this does not appear to have any effect - it still all stops.
I have generated a small test program, the object of which is to demonstrate something (anything) running during flash erase. I am simply toggling a pin and monitoring it on a scope, I then erase a Flash page and can see a 24ms gap in the toggling.
The test code is:
// test program running at absolute minimum overhead to investigate running code // through a Flash erase cycle #define MUX0 0x00200000 // output: 0 0 1 0 0 0 0 0 = 0x20 #define MUX1 0x00400000 // output: 0 1 0 0 0 0 0 0 = 0x40 #define MUX2 0x00800000 // output: 1 0 0 0 0 0 0 0 = 0x80 #define FEE_ERASE_WRITE_DIS 0x0000 // 0b00000000 00000000 Default #define FEE_ERASE_WRITE_EN 0x0008 // 0b00000000 00001000 #include <ADuC7021.h> void setbit( int signal) { GP0SET = signal; // set output bit GP0SET = 0; } void clrbit( int signal) { GP0CLR = signal; // Clear output bit GP0CLR = 0; } int main(void) { int x; x = 0; GP0CON = 0x00001003; // set port 0 GPIO pins GP0DAT = 0xF0E00000; // set outputs while ( 10000 > x++) // limit run time { setbit(MUX0); // toggle output pin clrbit(MUX0); if (0 == x % 1000) // periodically erase flash/EE { FEEMOD = FEE_ERASE_WRITE_EN; // enable erase write FEEADR = 0x7FFF; // write to address register FEECON = ERASE_PAGE; // write to command register FEEMOD = FEE_ERASE_WRITE_DIS; // disable erase write } } }
using this scatter file:
LR_IROM1 0x00080000 0x0000F800 { ; load region size_region ER_IROM1 0x00080000 0x0000F800 { ; load address = execution address *.o (RESET, +First) *(InRoot$$Sections) .ANY (+RO) } RW_IRAM1 0x00010000 0x00002000 { ; RW data minimalram.o (+RO +ZI +RW) .ANY (+RW +ZI) } }
What am I missing?
Hello Kristin,
I did not run your code, but I have some things to mention which may help: First, do not start a new operation if flash is busy (check bit 0 in FEESTA).
The definition of ERASE_PAGE is missing. There seem to be two possibilities: 0x05 single erase 0x03 erase write For erase write, the manual states that this operation takes 20ms. So you may want to try the combination of single erase, continue to work while flash is busy, followed by single write.
Additional notes: The manual I looked at says FEE_ERASE_WRITE_EN enables an interrupt on termination of the operation - seems you don't use it. And keep in mind flash wearing - do not write too often.
Regards
Martin
Is the program running out of flash memory? It may be possible that accessing _any_ part of the flash memory is not possible during an erase cycle (which, according to the chip documentation, takes approximately 24ms).
I'm not familiar with the ADuC7021, but with the chip I use, the CPU can still run out of RAM while the flash ROM is being erased. So you might try to move all essential functions to RAM.
The example program above is all running out of RAM, hence the scatter file. What I am trying to achieve is running the essential functions from RAM whilst the flash is erasing. At the moment it isn't. BTW the ERASE_PAGE is in the ADuc7021.h file and it is a single erase.