I have a simple routine which erases several pages of flash. It starts at
0xF400 and works up, Fine for F400, F600, F800, but resets (FERROR) for FA00. As I understand it that should be the last page below the FC00 boundary.I am using a C8051F340-TB development kit board, powered over USB, running at 48 MHz.
Any suggestions?
TIA,
Bill Davy
This is the C code:
#define bmVDMEN_in_VDM0CN 0x80
#define bmPORSF_in_RSTSRC 0x02
#define bmPSWE_in_PSCTL 0x01
#define bmPSEE_in_PSCTL 0x02
#define bmFLRT_in_FLSCL 0x10
#define bmFLBWE_in_PFE0CN 0x01
#define FLASH_BEGIN 0xF400
#define FLASH_END 0xFC00
#define FLASH_PAGE_SIZE 512
#define BEGIN_CRITICAL F1 = EA, EA = 0;
#define END_CRITICAL EA = F1;
/* extern */ void EraseFlash(void)
{//
// Writing anything on any byte initiates erase when PSEE = 1 & PSWE = 1
//
u8 xdata * pFlash;
ASSERT( VDM0CN & bmVDMEN_in_VDM0CN );
FLSCL |= bmFLRT_in_FLSCL; // As our clock is 48MHz.
PSCTL &= ~bmPSWE_in_PSCTL;
PSCTL &= ~bmPSEE_in_PSCTL;
for(pFlash = (u8 xdata *)FLASH_BEGIN;
pFlash < (u8 xdata *)FLASH_END;
pFlash += FLASH_PAGE_SIZE)
{BEGIN_CRITICAL
FLKEY = 0xA5;
FLKEY = 0xF1;
PSCTL |= bmPSEE_in_PSCTL;
PSCTL |= bmPSWE_in_PSCTL;
*pFlash = 0; // initiate page erasePSCTL &= ~bmPSWE_in_PSCTL;
PSCTL &= ~bmPSEE_in_PSCTL;
END_CRITICAL
}//Step 1. Disable interrupts (recommended).
//Step 2. Write the first key code to FLKEY: 0xA5.
//Step 3. Write the second key code to FLKEY: 0xF1.
//Step 4. Set the PSEE bit (register PSCTL).
//Step 5. Set the PSWE bit (register PSCTL).
//Step 6. Using the MOVX instruction, write a data byte to any location within the 512-byte page to be erased.
//Step 7. Clear the PSWE bit (register PSCTL).
//Step 8. Clear the PSEE bit (register PSCTI).
return;
}The following is the Keil disassembly listing.
75: for(pFlash = (u8 xdata *)FLASH_BEGIN;76: pFlash < (u8 xdata *)FLASH_END;
C:0x407D 538FFD ANL PSCTL(0x8F),#PCA0CP4(0xFD)
77: pFlash += FLASH_PAGE_SIZE)C:0x4080 90F400 MOV DPTR,#0xF400
C:0x4083 C3 CLR C
C:0x4084 E583 MOV A,DPH(0x83)
C:0x4086 94FC SUBB A,#PCA0CPH0(0xFC)
C:0x4088 502A JNC C:40B4
78: {79: BEGIN_CRITICAL
C:0x408A A2AF MOV C,EA(0xA8.7)
C:0x408C 92D1 MOV F1(0xD0.1),C
C:0x408E C2AF CLR EA(0xA8.7)
80: FLKEY = 0xA5;C:0x4090 75B7A5 MOV FLKEY(0xB7),#P1MDOUT(0xA5)
81: FLKEY = 0xF1;C:0x4093 75B7F1 MOV FLKEY(0xB7),#P0MDIN(0xF1)
82: PSCTL |= bmPSEE_in_PSCTL;C:0x4096 438F02 ORL PSCTL(0x8F),#0x02
83: PSCTL |= bmPSWE_in_PSCTL;C:0x4099 438F01 ORL PSCTL(0x8F),#0x01
84: *pFlash = 0; // initiate page eraseC:0x409C E4 CLR A
C:0x409D F0 MOVX @DPTR,A
85: PSCTL &= ~bmPSWE_in_PSCTL;C:0x409E 538FFE ANL PSCTL(0x8F),#PCA0CPH4(0xFE)
86: PSCTL &= ~bmPSEE_in_PSCTL;C:0x40A1 538FFD ANL PSCTL(0x8F),#PCA0CP4(0xFD)
87: END_CRITICALC:0x40A4 A2D1 MOV C,F1(0xD0.1)
C:0x40A6 92AF MOV EA(0xA8.7),C
88: }89: //Step 1. Disable interrupts (recommended).
90: //Step 2. Write the first key code to FLKEY: 0xA5.91: //Step 3. Write the second key code to FLKEY: 0xF1.
92: //Step 4. Set the PSEE bit (register PSCTL).93: //Step 5. Set the PSWE bit (register PSCTL).
94: //Step 6. Using the MOVX instruction, write a data byte to any location within the 512-byte page to be erased.95: //Step 7. Clear the PSWE bit (register PSCTL).
96: //Step 8. Clear the PSEE bit (register PSCTI).