flash access for arm7

I'm having a problem accessing flash on my arm7 processor, and I can't figure out what I'm doing wrong. I have the following code:

OUT1("FEEPRO ", GETREG32(FEEPRO)); OUT1("FEEHIDE ", GETREG32(FEEHIDE));

//SETREG32(FEEHIDE, 0xFFFFFFFF); //SETREG32(FEEPRO, 0xFFFFFFFF);

// 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

Reply to
julvr
Loading thread data ...

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.
 Click to see the full signature
Reply to
FreeRTOS.org

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

Reply to
julvr

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

Reply to
Rob Gaddi

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

Reply to
julvr

Did you set bit 3 of FEEMOD?

Reply to
Hans Odeberg

=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

Reply to
julvr

Hi,

I use this device.

I have not looked at your code, but here is some of mine that works OK (for gcc).

John Devereux

======================================================================

struct aduc7000_flash { volatile unsigned char sta __attribute__((aligned(4))) ; volatile unsigned char mod __attribute__((aligned(4))) ; volatile unsigned char con __attribute__((aligned(4))) ; volatile unsigned short dat __attribute__((aligned(4))) ; volatile unsigned short adr __attribute__((aligned(4))) ; volatile unsigned long dummy1 __attribute__((aligned(4))) ; volatile unsigned long sign __attribute__((aligned(4))) ; volatile unsigned long pro __attribute__((aligned(4))) ; volatile unsigned long hide __attribute__((aligned(4))) ; } ;

enum { FLASH_SECTOR_SIZE=0x200 };

enum { CMD_NULL, CMD_SINGLE_READ, CMD_SINGLE_WRITE, CMD_ERASE_WRITE, CMD_SINGLE_VERIFY, CMD_SINGLE_ERASE, CMD_MASS_ERASE, CMD_BURST_READ, CMD_BURST_READ_WRITE, CMD_ERASE_BURST_READ_WRITE, CMD_RESERVED_1, CMD_SIGNATURE, CMD_PROTECT, CMD_RESERVED_2, CMD_RESERED_3, CMD_PING, } COMMANDS;

/* declare pointer to flash controller registers */ static struct aduc7000_flash* const flash = (struct aduc7000_flash*) 0xFFFFF800;

/* 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);

/* sector erase unlock sequence */ flash->mod |= (1con = CMD_SINGLE_ERASE; /* wait for successful completion */ while(!(flash->sta & (1

Reply to
John Devereux

Thank you very much. I will give this a try.

John

Reply to
julvr

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.