// trying single erase: SETREG16(FEEADR, 0x800); SETREG8(FEECON, 0x05); while (((result = GETREG16(FEESTA)) & 0x03) == 0) {} if (result & 0x02) { OUT(" Single erase failed!"); } else { OUT(" single erase done!"); }
according to the first OUT commands, FEEPRO and FEEHIDE are both
0xffffffff, which would indicate no write protection. But all attempts to erase a section of flash fails. I also tried to do a mass erase, which seems to work (FEESTA gets set to 0x01), BUT, it completes in less than a tenth of a second... Does anyone have any ideas what I'm doing wrong?
Thanks,
John
Didn't find your answer? Ask the community — no account required.
F
FreeRTOS.org
There are lots of different vendors of ARM7 processors, and lots of different vendors of Flash memory, and lots of possible implementations of the macros you are using. Therefore I have no idea what you are doing or what you might be doing wrong.
Regards,
Richard.
+ http://www.FreeRTOS.org
Designed for microcontrollers. More than 7000 downloads per month.
+ http://www.FreeRTOS.org/Documentation
FreeRTOS eBook - a step by step guide to using an RTOS.
J
julvr
s
f
or
I am using an ADuC7021 (TDMI). It has 62k of on-chip flash, which I am trying to write. The first step is of course to erase a block, but I can't get that working.
John
R
Rob Gaddi
And Richard's comment about not knowing what toolchain (compiler, etc.) you're using, and therefore having no idea what the macros you're calling actually do, still applies.
--=20 Rob Gaddi, Highland Technology Email address is currently out of order
J
julvr
I don't think there's anything wrong with the macros -- I use the same macros to set up the serial port and the timer, and both those seem to work fine. I'm using arm-elf-gcc in case that makes a difference. The following are the macros I'm using:
#define SETREG8(reg, val) do { *((volatile char *)(reg)) = (val); } while(0) #define GETREG8(reg) (*((volatile char *)(reg))) #define SETREG16(reg, val) do { *((volatile short *)(reg)) = (val); } while(0) #define GETREG16(reg) (*((volatile short *)(reg))) #define SETREG32(reg, val) do { *((volatile long *)(reg)) = (val); } while(0) #define GETREG32(reg) (*(volatile long *)(reg))
#define FEESTA ((volatile unsigned long *) 0XFFFFF800) #define FEEMOD ((volatile unsigned long *) 0XFFFFF804) #define FEECON ((volatile unsigned long *) 0XFFFFF808) #define FEEDAT ((volatile unsigned long *) 0XFFFFF80C) #define FEEADR ((volatile unsigned long *) 0XFFFFF810) #define FEESIGN ((volatile unsigned long *) 0XFFFFF818) #define FEEPRO ((volatile unsigned long *) 0XFFFFF81C) #define FEEHIDE ((volatile unsigned long *) 0XFFFFF820)
I'm again suspecting FEEPRO, as I dumped this after a reset, and it returned 0. (It seems it sometimes returns 0, and other times
0xffffffff???)
I appreciate any help anyone can give me, as I'm now completely stumped on this issue.
John
H
Hans Odeberg
Did you set bit 3 of FEEMOD?
J
julvr
=3D
=3D
I did not set that register either way during the single erases, but when I tried a mass erase, I explicitly set that register to 0xF0, and then back to 0 (which means bit 3 is unset). A single erase after this point also failed. I do not have an interrupt vector table loaded at the moment, so I would assume that this bit should remain unset.
John
J
John Devereux
Hi,
I use this device.
I have not looked at your code, but here is some of mine that works OK (for gcc).
/* Erase flash memory blocks starting at "address". A *minimum* of n-1 bytes is erased, i.e. up to the end of the physical flash erase block containing the (n-1)'th byte. We write erase commands at the erase block interval throughout the region requiring erasure. */ static void erase(void* address, unsigned long n) { /* force hword alignment */ address = (void*) ((unsigned long)address & -2);