Hi, In the code below, I am trying to erase a flash page in conjuction with a UART interrupt. By them selves, the interrupt and flash erase work fine, but when I put them together, the flash erase has no effect. Would anyone have any idea how the UART interrupt is affecting my flash erase. Thanks. #include "c8051f060.h" // SFR declarations // ------------------- void flash_erase(int startpage, int npages) { char xdata* data pagePointer = 0; / EA = 0; // temporary disable interrupts FLSCL |= 0x01; // Enable FLASH R/WR via software PSCTL = 0x03; // MOVX erases FLASH pagePointer = (char xdata*)(startpage * 512); *pagePointer = 0; // initiate the erase PSCTL = 0x00; FLSCL |= 0x01; // Disable FLASH R/WR via software } // ---------------------- void UART1_ISR (void) interrupt 20 { if (RI1) { EA = 0; flash_erase(0x1F, 1); RI1 = 0; //clears receive flag } } // --------------- int main() { WDTCN = 0xDE; //disable WDT WDTCN = 0xAD; SFRPAGE = UART1_PAGE; SCON1 = 0x50; // Receive enabled EA = 1; // global interrupt enable EIE2 |= 0x40; // Enable UART1 ISR RI1 = 1; //trigger UART1 interrupt return 0; } //-----end main
by the way, I am using the KEIL c51 compiler with an silabs c8051f060 MCU
What is main() returning to?
nothing in particular. I think that I had it in there as an artifact of another compiler that required main to have a return type.
I think you should examine the execution path after main() returns. Does it return to some code that stays in a tight loop, or restarts the program, or just runs amok, or ...
what I see
UART1_ISR (void) interrupt 20 { if (RI1) { EA = 0; // NOT RESTORED flash_erase(0x1F, 1); // MAY TAKE TOO LONG RI1 = 0; //clears receive flag // SHOULD BE FIRST } }
[HINT]: Generally, an embedded system never returns from main().
I tried the change to main "void main(void)". problem still exists. The problem is basically that when I step past the code to erase the flash, it has no effect. The flash doesn't change. I reduced the code to the absolute minimum, so in this context I am not concerned about what happens after the flash erase in terms of the interrupts staying disabled. If I do the flash erase without the interrupt, it works just fine.
"I tried the change to main "void main(void)"." Changing the return type to void is not going to prevent main() from returning. If that were the case, then flash_erase() would not return either. Let's say that when main() returns, whatever called it in the first place calls it again only to immediately trigger another UART interrupt and initiate another flash erase while the first one is likely still in progress. So this time I'll be more direct and suggest you test after adding a "for (;;);" or "while (1);" after the "RI1 = 1;" line.
Here is latest code with suggested changes. I have a break point in the ISR as shown in the code at //#### BREAK POINT HERE ##### RI1 = 0; At that break point, the code space for address 0x1f * 0x200 = 0x3E00 remains unchanged, (i.e. page not set to all 0xFF.) I think that what happens after that with main and returns is probably not relevant. #include "c8051f060.h" void flash_erase(int startpage, int npages) { char xdata* data pagePointer = 0; FLSCL |= 0x01; // Enable FLASH R/WR PSCTL = 0x03; // MOVX erases FLASH pagePointer = (char xdata*)(startpage * 512); *pagePointer = 0; // initiate erase PSCTL = 0x00; FLSCL |= 0x01; // Disable FLASH R/WR } void UART1_ISR (void) interrupt 20 { if (RI1) { EA = 0; RI1 = 0; flash_erase(0x1F, 1); //#### BREAK POINT HERE ##### RI1 = 0; } } void main(void) { WDTCN = 0xDE; //disable WDT WDTCN = 0xAD; SFRPAGE = UART1_PAGE; SCON1 = 0x50; // Receive enabled EA = 1; // global interrupt enable EIE2 |= 0x40; // Enable UART1 ISR RI1 = 1; //trigger UART1 interrupt }
Here is with while loops to prevent returns and again flash refuses to change #include "c8051f060.h" void flash_erase(int startpage, int npages) { char xdata* data pagePointer = 0; FLSCL |= 0x01; // Enable FLASH R/WR PSCTL = 0x03; // MOVX erases FLASH pagePointer = (char xdata*)(startpage * 512); *pagePointer = 0; // initiate erase PSCTL = 0x00; FLSCL |= 0x01; // Disable FLASH R/WR } void UART1_ISR (void) interrupt 20 { if (RI1) { EA = 0; RI1 = 0; flash_erase(0x1F, 1); //#### BREAK POINT HERE ##### RI1 = 0; while(1); } } void main(void) { WDTCN = 0xDE; //disable WDT WDTCN = 0xAD; SFRPAGE = UART1_PAGE; SCON1 = 0x50; // Receive enabled EA = 1; // global interrupt enable EIE2 |= 0x40; // Enable UART1 ISR RI1 = 1; //trigger UART1 interrupt while(1); }
FLSCL |= 0x01; // Enable FLASH R/WR PSCTL = 0x03; // MOVX erases FLASH pagePointer = (char xdata*)(startpage * 512); is "pagePointer" in flash? Erik
my mistake Forget to change SFRPAGE Thanks for all the input.