Working with the AT91SAM9260 controller from atmel, I get a lot of errors when I try to program the NOR flash AT49BV160 which is connected at NSC0.
The problem is, that I have no communication at NRD, NRW0 and NCS0, when I try to program the flash or turn on the power of this board (BMS pin is high during the reset).
During the programming via the jtag interface I get a lot of errors (validation failed). Erase and programming was successfull (said uvision).
Maybe someone of you working with this controller, could show me the right commands / settings (especially to configurate this flash).
thank you in advance - best regards
Stefan
Hello Stefan,
It seems that you have a custom board with NOR flash and you are trying to program it with our flash algorithm which was made for Atmel AT91SAM9260 board which has Serial (SPI driven) DataFlash chip and not NOR Flash.
So what you have to do is write your own Flash Algorithm for your NOR Flash chip you can use similar algorithm for example AT49xV32x from \Keil\ARM\Flash folder.
Also what you have to (and this is why you do not see anything happening on NRD, NWR0 and NCS0 pins) is enable hardware to work with NOR Flash.
Our agorithm that is default for AT91SAM9260 is for Serial DataFlash which is on Atmel board.
thank you for your answer.
I'm using the algorithm AT49xV16A (from keil) which is similar to the AT49BV160TD.
You're right, I'm programming the three SMC controller registers for the NCS0 and now I'm able to see something happining on NRD NWE and NCS0 (but only when I try to programm the flash).
Do you know if there's anything else to enable to use the NOR flash? Because, when I run a short application in the internal RAM and I use the memcpy-instruction to copy some code into the NOR flash - nothing happens on NWE or NCS0. I also programm the three SMC controller registers (in the startup-file).
best regards Stefan
It is logical that you get some action on pins when you try programming.
I'm not really sure what is the problem now?
Anyways it is strange to me that you are mentioning memcpy for copying code to NOR flash, NOR flash is programmed by entering instructions first and then entering data. For example for programming: M16(base_adr + 0x0AAA) = 0xAA; M16(base_adr + 0x1554) = 0x55; M16(base_adr + 0x0AAA) = 0xA0; M16(adr) = *((unsigned short *) buf);
so you have to enter commands before every 16-bit value you write to NOR flas.
So I don't see how you planed to do that with memcpy?
Please, ask more (detailed) clear questions if you still have problems.
thanks for your answer. I tried to program a new algorithm for the flash memory.
The memory flash doesn't provide an "chip erase" command (only a sector erase command) - could you tell me how is it possible to use the "erase-button" (Flash>Erase) in the uvision IDE to erase the whole memory flash? I think that this function will be called if I / you press the erase-button.
int EraseChip (void) { // Start Chip Erase Command //return (Polling(base_adr)); // Wait until Erase completed return 0; }
There's the datashheet of this memory flash: The command table is on page 15. www.atmel.com/.../doc3591.pdf
If you do not have EraseChip function implemented in your flash algorithm (delete EraseChip function, do not leave it empty), ULINK driver will automatically call EraseSector command for each sector of the flash.
Important things to define are in FlashDev.c and they are "Device Size in Bytes" and "Size and Address of Sectors". According to these 2 parameters ULINK driver knows how many times it has to call SectorErase command and with what address increments.
thanks for your answer. At the moment, when I press the erase-button (under Flash->Erase) -> nothing happens on the pins NCS0, NWE0.
I deleted the EraseChip-Function. The sector-erase-chip function is:
int EraseSector (unsigned long adr) { // Start Erase Sector Command M16(base_adr + 0x0AAA) = 0x20; M16(adr) = 0xD0; return (Polling(adr)); // Wait until Erase completed }
Sector Erase/Confirm: 2 cycles Addr: XX (any addr) 20 (data) and the second cycle is SA(sector addr) and D0 (data).
The polling-function: q3 is the VPP status and q7 determine if sector erase or Word Program is complete.
int Polling (unsigned long adr) { unsigned int q7; //1: ready 0: busy fsr.v = M16(adr); q7 = fsr.b.q7; do { fsr.v = M16(adr); if (fsr.b.q7 == 1) return (0); // Done q7 = fsr.b.q7; if (fsr.b.q3 == 1) break; // VPP not high enough } while (fsr.b.q7 == 0); // Check for Timeout fsr.v = M16(adr); q7 = fsr.b.q7; fsr.v = M16(adr); if (fsr.b.q7 == 1) return (0); // Done //M16(adr) = 0xF0; // Reset Device return (1); // Failed }
Under options-for-target->utlities I have a short init-file, where I start the clocks and program the three SMC controller registers. The clock function is directly from keil (and works).
//Control Register: 16bit databus, NRD, NWE controlled _WDWORD(0xFFFFEC0C,0x00021003); //Cycle Register: NWE_Cycle - NRD_Cycle _WDWORD(0xFFFFEC08, 0x00070007); //Setup Register: NWE_Setup - NCS_WR_Setup - NRD_Setup - NCS_RD_Setup _WDWORD(0xFFFFEC00, 0x00000001); //Pulse Register: NWE_Pulse - NCS_WR_Pulse - NRD_Pulse - NCS_RD_Pulse _WDWORD(0xFFFFEC04, 0x07070703);
I hope you could tell me what I'm doing wrong so that I have no signal output (on NCS0, NWE...) when I press the erase-button.
here's my configuration from the FlashDev.c-file:
struct FlashDevice const FlashDevice = { FLASH_DRV_VERS, // Driver Version, do not modify! "AT49BV160 Flash", // Device Name EXT16BIT, // Device Type 0x000000, // Device Start Address 0x200000, // Device Size in Bytes (2MB) 1024, // Programming Page Size 0, // Reserved, must be 0 0xFF, // Initial Content of Erased Memory 100, // Program Page Timeout 100 mSec 1000, // Erase Sector Timeout 1000 mSec // Specify Size and Address of Sectors 0x10000, 0x000000, // Sector Size 64kB (31 Sectors) 0x02000, 0x1F0000, // Sector Size 8kB (8 Sectors) SECTOR_END };
The flash memory is 2MB,. 1024 page size and the sector size is 64kB and 8kB....
Hi Stefan,
my guess is that you did not enable clocks for SMC (in PMC_PCER register). Anyways seems that pins and clocks are not fully configured.
Hi Milorad,
there's no such clock (especially for the SMC controller).
I disable the pio mode, select peripheral A and disable the pull-ups. And now the NCS0 signal and NRD signal goes low if I tried to erase the nor flash.
// Specify Size and Address of Sectors 0x10000, 0x000000, // Sector Size 64kB (31 Sectors) 0x02000, 0x1F0000, // Sector Size 8kB (8 Sectors)
Could you tell me the way I get the start addr from the sector 8kb (0x1F0000)? In the datasheet there's a table about the start and end of each sector. The last 64k sector ends at 0xF7FFF and the first 8k sector starts at F80000.
How do I have to name the read function in the flash algorithm (FlashProg.c)? Because I have to write 0xFF (as command) to one addr.
At the moment I see that somethings happens on the pins (ncs0, nrd and nwe) but the veryfication failed. I think that I'm not able to read out anything from the flash.
Anyways seems that pins and clocks are not fully configured
Here's the clock-enable-function:
FUNC void Clock_Setup (void) { // Setup clock; XTAL = 18.432000 MHz, // PLLA = 96.109714 MHz, // Processor = 96.109714 MHz _WDWORD(PMC+ 0x20, 0x0000FF01); // CKGR_MOR: Enable main oscillator _sleep_(100); // Wait for stable Main Oscillator _WDWORD(PMC+ 0x28, 0x20483F0E); // CKGR_PLLAR: Configure PLL A _sleep_(100); // Wait for stable PLL A _WDWORD(PMC+ 0x30, 0x00000000); // PMC_MCKR: MDIV and PRES fields _sleep_(100); // Wait for Main Master Clock ready _WDWORD(PMC+ 0x30, 0x00000002); // PMC_MCKR: all fields _sleep_(100); // Wait for Main Master Clock ready }
Your SectorErase fuction will be called with addresses of each sector correctly, so you do not need to worry about sector address.
Why do you want to get sector address?
As this is NOR flash you do not need to specify any Read function because processor should be able to directly read from NOR flash and it uses directly reading to verify what has been written.
In other words you can not specify read function you could specify Verify function but in your case you do not need it as flash should be readable directly at its memory addresses.
You could try this by entering debug and looking at flash memory addresses where your flash is mapped if you do not see what you have written then everything still does not function as expected.
My guess is that you still do not write to flash correctly.
Best regards, Milorad
that's right. When I try to erase the whole flash memory then I get a signal on NCS0 and NRD; but when I try to download some code to the memory there's no activity on NWE or at the whole databus. Only at the address bus, NCS0 and NRD is an activity.
The programming algorithm for the flash is:
int ProgramPage (unsigned long adr, unsigned long sz, unsigned char *buf) { int i; for (i = 0; i < ((sz+1)/2); i++) { // Start Program Command M16(base_adr + 0x15) = 0x10; M16(adr) = *((unsigned short *) buf); if (Polling(adr) != 0) return (1); buf += 2; adr += 2; } return (0); }
Datasheet: Word-Program: Cycle 1: Addr=XX and Data 40/10 - I'm not sure what this means (40 / 10)? I tried to use 0x40 and 0x10 - but nothing has changed.
Cycle 2: Addr=Addr and Data is Din
I'm not sure, where there could be another error in my configuration.
can you answer following questions: - do you have flash connected in 16-bit bus? - do you have !WP pin connected High? - did you connect A1 processor line to A0 on flash? (flash expects half word address on A0..A19, and this means that A1 which is first half word address on processor has to be connected to A0 on flash chip, and all other lines are shifted by one, meaning:
proc A1 -> flash A0 proc A2 -> flash A1 ... proc A20 -> flash A19
If answers to previous questions are yes can you then try this for SectorErase:
int EraseSector (unsigned long adr) { // Start Erase Sector Command M16(adr) = 0x20; M16(adr) = 0xD0; return (Polling(adr)); }
- do you have flash connected in 16-bit bus?
_WDWORD(0xFFFFEC0C,0x00021003);
this is the mode register for the SMC controller (NCS0), where I selected 16bit databus mode, write operation controlled by NWE, read operation controlled by NRD, NWAIT disabled, TDF data float time = 2, standard read, page mode not enableda and TDF optimization disabled.
If answers to previous questions are yes can you then try this for
yes, the connections are correct (and as you described it in your last message).
It's still the same problem -> no activity on NWE and the databus (0x20 and 0xD0), when I try to erase the chip. There's only a activity at NCS0, the addressbus and NRD. All control signals (NWE, NCS0 and NRD), as well as all address lines are connected direct to the memory.
I have installed two bidirectional transceivers for the whole databus (between the controller and the flash memory). OE (transceiver) is always low active when the sdram (which is not connected at the moment) won't be active (-> so it's always low which is correct). And NRD is connected to control the T/R (transmit / receive) pin. If NRD is low then the information goes from the memory to the controller.
www.fairchildsemi.com/.../74LVTH245.pdf
That's my hardware wiring.
can you try in initialization:
_WDWORD(0xFFFFEC00,0x3F3F3F3F); _WDWORD(0xFFFFEC04,0x7F7F7F7F); _WDWORD(0xFFFFEC08,0x01FF01FF); _WDWORD(0xFFFFEC0C,0x000F1103);
Did you see anything on NWR or NRD?
When I try this configuration, then I see nothing on NRD, NCS0 and NWE... No signal at all.