Go Down

Topic: [Solved] Flash Memory Programmer "AM29F040B" (Read 18634 times) previous topic - next topic

kf2qd

Timing is critical when you are trying to run fast - like connected in circuit to a CPU. To read data -t is important that you properly set the address inputs before you try to set the chip selects. * WE or *OE can be set before the *OE. Timings on the chart are generally the minimums - meaning that there is a minimum time from the address line being set before the *CE and then some delay between the *CE before the *OE or *WE have to be stable. But a best practice is set the *OE or *WE at he same time the *OE is set.

To use some of the features - sector erase for instance - you do need to be able to control all address pins.

Thanks for this discussion - I missed it when I asked if anyone had any experience with these devices... I am preparing to build a Z80 CPM single board computer, and maybe even a 65C02 based board to play with.  Will be making a Flash Programmer shield to program these devices.

BlackSharp

Thanks for your reply kf2qd,

If understand, the timing is critical for any operations. I was thinking if it's possible to bypass this problem especially for those who are not familiar with electronics, to just use the AVR interrupts and check if there is any data coming from an external device (Like EEPROM or Flash) in the reading operation for instance.

I was thinking of that, because even my reading algorithm doesn't work too, and I try to figure out if there is any missing thing that I forgot (shiftregister didn't give the correct address, timings) . I have changed my code from the arduino style to AVR style to increase the speed of the functions, unfortunately, no result too. The remaining idea that I have now is the pinchange interrupts, after that, if nothing seems to work ...  :.

I have a questions if someone can clarify these for me:
using the avr style code, Can I be able to receive and detect if there is any input coming from an external device even if the arduino pins are in output mode and not set to HIGH (Read PIND or PINB) ?
If the answer of the above question is yes why we whould change the pin mode  ?
How can I test if my flash are working or not ? Because it's very weird that til now nothing is working for me.

Thanks and sorry for the inconvenience.

pito

The timing is not critical with your application, as the arduino's bitbanging  is much slower than the minimal timing requirements of the flash memory. As I wrote previously, try to get the stuff working in slow mode, speed optimization is long way to go (and not required for your programmer..
Quote
I was thinking of that, because even my reading algorithm doesn't work too

How do you know that? Do you have a programmed chip with known data in it? Or do you try to read empty chips?

kf2qd

You can take a memory chip. put it on a breadboard and wire it fir an address and then wire the *OE to ground and then wire the *CE to ground and it will put the data for that address on the data lines. timing is not a problem.  That timing chart just shows the minimum times. Can't run the chip any faster than those timings. Can run it way slower...

Are you sure what you are putting on the address lines? Verify address inputs before you worry about anything else. If they aren't correct then everything else is a waste of time.

pito

#19
Nov 20, 2013, 04:52 pm Last Edit: Nov 20, 2013, 04:55 pm by pito Reason: 1
Several decades back we programmed PROMS and EEPROMs with 16+8 dil switches with 24 10k pullups, a 27V power source (w/ a pnp high side switch) and a push button (with a 7400 10ms mono). And it worked fine :)

BlackSharp

To answer you Pito,

Quote

How do you know that? Do you have a programmed chip with known data in it? Or do you try to read empty chips?


In fact, I don't know If the flash are empty or not, because I found a weird behavior: when I try to send a command sequence to the flash, the data is put too no problem here, however when I try to read data, is always equal the data puted before even if i changed the pins in the input mode. This is why I asked this question:

Quote

using the avr style code, Can I be able to receive and detect if there is any input coming from an external device even if the arduino pins are in output mode and not set to HIGH (Read PIND or PINB) ?


After several checks the data is always 0 not 0xFF as the flash should be, this is the reason that I was thinking about interrupts.
To answer you kf2qd I'am sure about the address lines I checked one by one using multiple addresses.

If you need something to check from your side (Code or circuit) don't hesitate to tell me.

Many thanks.

kf2qd

Here's a drawing of the schematic that will work with the programs that PITO created.

If there are any errors,please let me know Pito.

Pito - with your programs - how are you feeding the data to the programmer?

pito

#22
Nov 20, 2013, 05:29 pm Last Edit: Nov 20, 2013, 06:54 pm by pito Reason: 1
Quote
In fact, I don't know If the flash are empty or not, because I found a weird behavior: when I try to send a command sequence to the flash, the data is put too no problem here, however when I try to read data, is always equal the data puted before even if i changed the pins in the input mode.

When reading the flash you do not issue any special command sequence - you just read the flash with for example:
Code: [Select]
// read a single byte from flash
byte flash_read(unsigned long address)
{
 byte data = 0x00;  //try to change to 0xFF to see the difference
 flash_ctrl_deselect();
 flash_change_data_pins_mode(IN);  
 flash_addr_set(address);
 flash_ctrl_rd();  // rd/oe goes LOW
 delayMicroseconds(1);  // 1usec is ok when reading the flash (70ns is min)  
 data = flash_data_get();
 flash_ctrl_deselect();  // rd/oe goes HIGH, cs goes HIGH
 return data;
}

Quote
Pito - with your programs - how are you feeding the data to the programmer?

Frankly, last time I built my pc controlled eeprom programmer was in '87 where I did it by wiring a 8255A to Atari520ST' ACSI bus (an SCSI HDD bus), wrote a driver in asm, and the main program in gfbasic (or something called like that). I opened a file on the diskette, read binary  and flashed a 27C512 EEPROM (Atari TOS upgrade,, six eeproms). That is all I can say to this topic.. :)
Based on my experience with this stuff, it works fine when:
1. you carefully check the wiring (many times..)
2. you build the sw routines step by step, testing each function carefully
3. you do not try to speedup/optimize the sw - do it slow and simple, ie connect LEDs to cs, oe, we (such it lits when active), add delays so you can see the sequence, when it works properly remove the delays.
4. mind that by wiring error swapped data or address lines will write/read the flash properly (against the binary), but it will not work in your final hardware (unless you swap the lines there in the same way too)..

Feeding the data: that is the last issue I would mess with at this stage. First, try to flash several bytes (ie 4) to 4 addresses somewhere. Verify. Erase, and do it again (different data, different addresses). Repeat many times. When it works fine, then start to think how to pass the data (via serial, from an sdcard, etc).

@kf2qd: Your schematics: I would use 74HC or HCT 595 shifters, and do care about all its input pins (10.11.12.13.14) somehow..
PS: I would put pullups (ie an 8x10k sip module) on the data bus, thus I will read 0xFF even the memory is deselected.


BlackSharp

Pito,
I mean command sequence not in read operation but in write operation of course, the read operation always return 0 but when it comes to write to the flash you must change the mode of the pins in input to read data. The idea is that I should clear the address "Data = 0x00" as you mentionned in your last post.

I understand now your method to do things I'm sure that the addresses are correct, I have just to test read operation closely until it works fine, same thing for write and so on. (this time I will be careful with delays)

I will keep you informed about everything and sorry for my limited knowledge about electronics. Your help is very helpful  :).

Many thanks


pito

#24
Nov 20, 2013, 06:39 pm Last Edit: Nov 20, 2013, 06:57 pm by pito Reason: 1
Learn how to test the stuff step by step. Do not hurry, quality needs time :)
You do not need the flash memory chip inserted into the circuit for testing purposes.

For example put a few pullups (10k or similar) on a few data lines and run your flash_read(). See what it returns (it shall return 1 where the pullups are wired).

Short the pins to ground with ie 330ohm pulldowns (10k pullups still there) and read with flash_read() (you have to read 0 where the 330ohm pulldowns are wired).

Observe the data - that way you may check the data bus reads well. Do not care about addresses while checking the databus.

Try to write something on the data bus (ie 0xFF or 0x00), and then read it back while the resistors there. You have to read the logic levels set by resistors at the specific pins.

Do not short atmega's pins with a straight wire to gnd or Vcc directly, but always via the resistors - ie 10k pullup (to Vcc) and 330ohm pulldowns (to gnd).

Do not use 330ohms pulldowns in your final wiring, use it for testing purposes only (to set logical 0).

pito

I would also place 8x10k pullups on the databus, and 10k pullups on CE, OE, WE signals, as well as on all active 595 input signals..

BlackSharp

Yeah sure Pito, but if data is coming from the flash and the pullups are still there the result will be always 1 even if I read the flash or not (because the current flow to the inputs) am I wrong ?
Rather I have put the pulldown resistors in the data bus to be always 0 until something is coming from the flash to change the logic to 5v.

I will try your idea since you are more experienced with this stuff :)

pito

#27
Nov 20, 2013, 08:43 pm Last Edit: Nov 20, 2013, 09:04 pm by pito Reason: 1
Quote
but if data is coming from the flash and the pullups are still there the result will be always 1 even if I read the flash or not (because the current flow to the inputs) am I wrong ?

The 10k pullups are weak, so the flash chip will pull them down to 0 easily when the flash chip outputs the 0. You may use internal atmega's pullups as well.

When there are none pullups, especially on the control wires, the device (ie flash) will get an undefined input level when the atmega has its outputs highZ (ie set as a digi input or an analog input) ie during a reset, etc.

99.9% of today's control signals are active LOW, idle HIGH (ie see CE, WE, OE). Therefore we use pullups to maintain their inactive (idle) states even the logic outputs which drive them are in highZ. With such setup you can create a "wired or" (several open drain outputs drive single logic input) too..

Imagine the flash chip, inserted into the socket, and the CE signal is highZ (ie atmega's pin which drives the CE is set as an input or analog input). The CE will float without the pullup, and therefore the random LOW levels will activate the flash chip randomly. The same with WE, OE..

BlackSharp

Hello there,

I followed your suggestions to read correctly the chip, the addresses are correct, the data are correct. The read operation now works well and gives me always the same data. I got also from the electronic shop another AM29F040B flash which is already programmed and contain data to test my reading operation and everything is ok.

This is a Sample data from the chip.  I always got the same data from it:

Code: [Select]

C2 C4 F5 F6 F1 F5 F0 F1 F1 F0 F4 F9 F0 C0 DE D9 C6 16 Bytes
D5 E0 E0 E0 E0 E0 E0 E0 C1 C3 D5 D2 C1 E0 E0 E0 E0 33 Bytes
E0 E0 E0 E0 E0 E0 E0 E0 E0 E0 E0 C0 CF EF FF FF FF 50 Bytes
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 67 Bytes
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 84 Bytes
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 101 Bytes
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 118 Bytes
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 135 Bytes
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 152 Bytes
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 169 Bytes
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 186 Bytes
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 203 Bytes
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 220 Bytes
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 237 Bytes
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 254 Bytes
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 271 Bytes
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 288 Bytes
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 305 Bytes
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 322 Bytes
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 339 Bytes
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 356 Bytes
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 373 Bytes
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 390 Bytes
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 407 Bytes
FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 424 Bytes
C4 C1 C5 D7 CF CF E0 E0 E0 E0 E0 E0 E0 E0 E0 E0 E0 441 Bytes
E0 E0 E0 C0 DF C1 E4 D1 C4 C1 C9 C8 C1 D4 D3 D5 E0 458 Bytes
E0 E0 E0 E0 E0 E0 E0 E0 E0 E0 E0 C0 F0 C1 ED CB C4 475 Bytes
C5 E0 D4 CF CD C1 D3 CF E0 E0 E0 E0 E0 E0 E0 E0 E0 492 Bytes
E0 E0 C0 C3 C1 FA EB C4 CF C4 C7 C5 E0 E0 E0 E0 E0 509 Bytes
E0 E0 E0 E0 E0 E0 E0 E0 E0 E0 C0 E7 C1 FB FD C4 D2 526 Bytes
E0 E0 E0 E0 E0 E0 E0 E0 E0 E0 E0 E0 E0 E0 E0 E0 E0 543 Bytes
E0 C0 C1 C1 E8 E7 C5 C1 C7 CC C5 E0 E0 E0 E0 E0 E0 560 Bytes
E0 E0 E0 E0 E0 E0 E0 E0 E0 C0 C8 C1 E9 ED C6 C9 C1 577 Bytes
D4 E0 E0 E0 E0 E0 E0 E0 E0 E0 E0 E0 E0 E0 E0 E0 E0 594 Bytes
C0 EC C1 EB DD C6 CF D2 C4 E0 E0 E0 E0 E0 E0 E0 E0 611 Bytes
E0 E0 E0 E0 E0 E0 E0 E0 C0 C7 C1 EB E5 C6 CF D2 C4 628 Bytes
E0 D5 D3 C1 E0 E0 E0 E0 E0 E0 E0 E0 E0 E0 E0 E0 C1 645 Bytes
E3 C2 E2 CF C6 D3 CF E0 E0 E0 E0 E0 E0 E0 E0 E0 E0 662 Bytes
E0 E0 E0 E0 E0 E0 E0 C0 C5 C2 C3 E1 C7 C1 DA E0 E0 679 Bytes
E0 E0 E0 E0 E0 E0 E0 E0 E0 E0 E0 E0 E0 E0 E0 C0 C6 696 Bytes
C2 C4 FF C7 C5 CE C5 D2 C1 CC E0 CD CF D4 CF D2 D3 713 Bytes
E0 E0 E0 E0 E0 E0 C0 C1 C2 C6 E3 C7 C5 CF E0 E0 E0 730 Bytes
E0 E0 E0 E0 E0 E0 E0 E0 E0 E0 E0 E0 E0 E0 C0 CD C2 747 Bytes
C6 E9 C7 CD C3 E0 E0 E0 E0 E0 E0 E0 E0 E0 E0 E0 E0 764 Bytes
E0 E0 E0 E0 E0 C0 E3 C2 CA F7 C7 D2 C5 C1 D4 E0 D7 781 Bytes
C1 CC CC E0 CD CF D4 CF D2 D3 E0 E0 E0 C0 C5 C2 C8 798 Bytes
C9 C8 CF CE C4 C1 E0 E0 E0 E0 E0 E0 E0 E0 E0 E0 E0 815 Bytes
E0 E0 E0 E0 C0 FB C2 C9 E7 C8 D9 D5 CE C4 C1 C9 E0 832 Bytes
E0 E0 E0 E0 E0 E0 E0 E0 E0 E0 E0 E0 C0 D5 C2 EB C9 849 Bytes
C9 CE C6 C9 CE C9 D4 C9 E0 E0 E0 E0 E0 E0 E0 E0 E0 866 Bytes
E0 E0 E0 C0 F0 C3 C2 C7 C9 CE CE CF C3 C5 CE D4 C9 883 Bytes
E0 E0 E0 E0 E0 E0 E0 E0 E0 E0 E0 C0 CD C3 CF E7 C9 900 Bytes

Reading is Complete.



However, the write operation is still not working. After reading again the datasheet, I found an interesting thing to try: is the "Autoselect mode" to get info from the chip. I wrote several functions such as (Get ID, Get device ID and Test sectors protection).
I was very surprised when I saw that my  sectors verification function return every time 0x01 which it means that the sectors are protected, however, the GET ID and Get device ID functions return different values in comparison to what it mentioned in the datasheet (0x37 for Manufacturer ID, 0x06 for device id). The same thing for the other chip except reading operation of course.


Do you think that the problem is from the sectors protections ?
If the sectors are protected, does the chip accepts  write command sequences as  well ?

kf2qd

Sector Protect is to keep those sectors from being re-written without first going through the process of clearing the protection bits. That would be used where part of the chip is really ROM and part of the chip is used for parameter storage. Wouldn't want to re-write the ROM, but parameters would need to be changed from time to time.

Chips by different manufacturers will return different ID codes. You need the datasheet for your exact chip. It may not make any difference, but the ID would help flag a chip that is too slow or in some other way might be incompatible. On the other hand it might not make any difference.

Your conditions for the line breaks on your display have a problem. The first line is 17 bytes. Don't know how you are saving this info but that might give you a problem.

Here are a couple pictures of my progress on a programmer. Waiting to get some chips in. Once I have the 595's I can then use a 628128 to begin to test some functions.  The write  routine would have to be different - either that or just be aware that a couple addresses are going to be trashed by the write routine. Read should work just fine. Just do all reads and writes as if it were from the upper half of a 256x8 chip so the CS2 pin is held high...

Go Up