Hallo,
Ich habe hier ein paralleles page-write EEPROM 29EE010 (Datenblatt gibts
hier: http://www.datasheetcatalog.org/datasheets/400/489767_DS.pdf ).
Die Adress-, Daten- und Steuerleitungen sind mit einem ATmega162
verbuden. Das auslesen des ROMs funktioniert auch schon, nur am
beschreiben haperts noch.
Vielleicht kann sich jemand von euch mal das Datenblatt, speziell den
Write-Zyklus (Figure 5, Seite 12 und Figure15), ansehen und mir sagen,
wie der Ablauf aufgebaut sein muss. Zum auslesen des ROMs sieht er z.B.
so aus:
- WR = 1 //write aus
- CE = 0 //chip enable an
- OE = 1 //output enable aus
- gewünschte adresse auf A0-A16 legen
- 1ms warten
- OE = 0 //output enable an
- 1ms warten
- wert von D0-D7 ablesen
Grüsse,
Markus
Hallo,
zum Schreiben mußt Du erstmal die Data Protection abschalten bzw.
richtig setzen. Kommt darauf an, ob er ladenneu ist ider so wie meine
BIOS-Roms aus alten Mainboards sind.
Der ASM-Ausschnitt stammt aus einer Display-Software von mir, ist nur
rauskopiert. Falls was fehlt -> nachfragen...
Der Flash hängt als externer Speicher an einem Mega8515 und speicher
Fonzs und Grafiken für ein 480x64 LCD.
1
; benutzter Flash: 128kx8, SST 29EE010-150 0xBF, 0x07 kein Chip-Erase, Product Identification nur SST-Kommando
Hallo Michael und danke für die Antwort,
allerdings bin ich mit Assembler absolut nicht vertraut.
Mit "rcall flashcontrol" scheinst du die subroutine aufzurufen, die dann
dafür zuständig ist, 0x80 an das ROM auszugeben. Und genau da liegt ja
das Problem: Ich werde aus dem Datenblatt nicht schlau, wie der Ablauf
des Write-zyklus ist.
Weiterhin steht im datenblatt, die SDP muss aktiviert werden, um einen
Page-write ausführen zu können, warum wird er bei dir deaktiviert? (auch
wenn mir deaktivieren zum schreiben sinnvoller erscheint oO)
Muss man eigentlich immer 128 bytes schreiben oder gibt es auch eine
möglichkeit, jede einzelne adresse einzeln zu beschreiben?
Mein ROM ist ein altes BIOS, ist also nicht fabrikneu.
Grüsse,
Markus
.macro setbank ; lädt 16Bit @1 nach @0 High und @0 Low
2
push TEMP_0
3
ldi TEMP_0,@0
4
out BANK_PORT,TEMP_0
5
pop TEMP_0
6
.endmacro
7
8
flash_control:
9
push ZH
10
push ZL
11
push TEMP_1
12
push TEMP_2
13
14
ldi TEMP_1,0xAA
15
load_p Z,0x5555 ; Kommand 1 0101 0101
16
setbank BANK_1
17
st Z,TEMP_1 ; und schreiben
18
19
ldi TEMP_1,0x55
20
load_p Z,0x2AAA | 0x4000 ; Kommand 2 0010 1010
21
setbank BANK_0
22
st Z,TEMP_1 ; und schreiben
23
24
load_p Z,0x5555 ; Kommand 1 0101 0101
25
setbank BANK_1
26
st Z,TEMP_0 ; und schreiben
27
28
pop TEMP_2
29
pop TEMP_1
30
pop ZL
31
pop ZH
32
33
ret
Das macro setbanl setzt die Bank auf dem Port, die Adressen A0...A13
werden über das Memory-Interface angesteuert, die Adressen A14...A16
sind an PB0...PB2. Es werden also immer 16kB Bereiche eingeblendet.
Da die Kommandobytes an bestimmte Adressen geschickt werden müssen, die
bei mir dadurch nicht in der gleichen Bank liegen, wird da
umgeschalltet.
Schau erstmal, daß Du Hersteller und Typ ausgelesen bekommst, dann hast
Du das mit den Kommandos verstanden. Die Typen weichen je nach
Hersteller und Version bei den unterstützten Kommandos etwas voneinander
ab, in meinem ersten Posting oben meine Anmerkungen zu den Typen, die
ich bisher erfolgreich benutzt habe.
Die BIOS Flash sind normalerweise komplett Write Protect, da muß sowieso
der Protect-Mode erstmal passend zurückgesetzt werden.
Hat mich auch ein paar Abende gekostet, bis es so lief, wie es sollte.
Ach so: ja, man muß immer eine Page löschen und neu schreiben.
Sind ja eben Flash und keine EEPROM oder sowas.
Gruß aus Berlin
Michael
Hallo,
mein Problem besteht ja darin, dass ich nicht weiß, wann welche
Leitungen (Adressen, Daten, WR, OE...) wie gesetzt sein müssen um ein
solches Kommando zu übertragen. Im ersten Posting hatte ich ja den
Ablauf für das Auslesen einer bestimmten Adresse gepostet, der auch
funktioniert. So einen Ablauf muss es ja auch für das schreiben eines
Steuerkommandos geben.
Ich habs mal folgendermaßen probiert, was aber nicht wirklich zu
funktionieren scheint:
1
2
PORTD&=~(1<<PD5);// chip enable
3
PORTD|=(1<<PD6);// Write rom = off
4
PORTD|=(1<<PD7);//read rom = off
5
adr16=0x5555;
6
value=0xAA;
7
adr8_h=adr16>>8;// high byte
8
adr8_l=adr16&0xFF;// low byte
9
PORTA=adr8_h;
10
PORTC=adr8_l;
11
PORTB=value;
12
_delay_ms(10);
13
PORTD&=~(1<<PD6);// write rom = on
14
_delay_ms(10);
15
PORTD|=(1<<PD6);// wprite rom = off
16
_delay_ms(100);
Die Adressleitungen hängen an PORTA und PORTC, die Datenleitungen an
PORTB.
Grüsse,
Markus
Hallo,
du steuerst ihn "zu Fuß" an?
Du hast ihn doch an einem Mega162, warum benutzt Du nicht dessen
XMEM-Interface?
Es geht natürlich auch so.
Ich fange mal von vorn an. ;-)
Grundstellung:
Datenport Eingang
Controlleitungen Ausgang
Adressen Ausgang.
WR, OE, CE auf 1
lese:
Lesezyklus:
Adressen anlegen
CE auf 0
OE auf 0
Wartezeit*
Daten lesen
OE auf 1
CE auf 1
*Wartezeit zwischen aktiv und Lesen brauchst Du keine bis 8MHz
AVR-Clock, bei 16MHz ebtl. 1-2 NOP.
Meine 29EE010 von ST laufen auch mit 16MHz Takt am XMEM ohne Waitzyklen
obwohl es außerhalb der garantierten Timings ist.
Hattest Du so ähnlich, ging ja auch bei Dir.
schreibe:
Schreibzyklus:
Datenport auf Ausgang
Adressen anlegen
Daten anlegen
CE auf 0
WE auf 0
1-2 Takte warten (NOP)
WE auf 1
CE auf 1
Datenport auf Eingang
Das in 2 Subroutinen gepackt und erstmal fertig...
sende_steuerbyte:
Steuerkommando schreiben:
Adresse auf 0x5555
Daten 0xAA
schreibe
Adresse auf 0x2AAA
Daten auf 0x55
schreibe
Adresse auf 0x5555
Daten Steuerbyte
schreibe
Auch als Subroutine oder sowas basteln
flash_id_lesen:
Steuerbyte 0x80
sende_steuerbyte
Steuerbyte 0x60
sende_steuerbyte
10µs warten - Wartezeiten der Kommandos im Datenblatt beachten
Adresse = 0x00
lese -> Manufakturer
Adresse = 0x01
lese -> Device-ID
Steuerbyte 0xF0
sende_steuerbyte Fzbktion wieder abschalten
Das muß funktionieren und die für Deinen Chip gültigen Daten
zurückliefern.
Wenn das geht dann einfach
schreibe_page:
Steuerbyte 0x80
sende_steuerbyte
Steuerbyte 0x20 -> schaltet Data Protection aus
sende_steuerbyte
40ms warten
Steuerbyte 0xA0 -> Page Write
sende_steuerbyte
128 Byte Daten an Page schreiben (Pageabfänge beachten!)
60ms warten -> der Flash schreibt jetzt seinen internen Buffer ins
Flash
Das auch als Subroutine basteln.
Dann hast Du alles, um mit den Flashs alles machen zu konnen.
Gruß aus Berlin
Michael