Forum: Mikrocontroller und Digitale Elektronik Paralleles EEPROM beschreiben (page write)


von Markus R. (maggus)


Lesenswert?

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

von Michael U. (amiga)


Lesenswert?

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
2
; benutzter Flash: 128kx8, ATMEL 29C010A-12    0x1F, 0xD5
3
; benutzter Flash: 128kx8, Winbond W29C020-12  0xDA, 0x45  Product Identification nur SST-Kommando
4
 
5
flash_write_daten_loop:
6
7
    ldi    TEMP_0,0x80            ; Data Protect Disable
8
    rcall  flash_control
9
10
    ldi    TEMP_0,0x20
11
    rcall  flash_control
12
13
    rcall  wait_20ms
14
    rcall  wait_20ms
15
16
    ldi    TEMP_0,0xA0            ; Page Write
17
    rcall  flash_control
18
19
    sbrs  FLAGS,FLAG_CONTROL        ; Controlmap?
20
    lds    TEMP_0,FLASH_BANK        ; nein, Bank holen
21
    sbrc  FLAGS,FLAG_CONTROL
22
    ldi    TEMP_0,BANK_0          ; ja, immer Bnak 0 programmieren!
23
    out    BANK_PORT,TEMP_0        ; und setzen
24
    
25
    ldi    TEMP_2,128            ; Page Länge
26
27
flash_write_daten_block_loop:
28
    ld    TEMP_0,Z+            ; Daten holen
29
    st    Y+,TEMP_0            ; und schreiben
30
    dec    TEMP_2
31
    brne  flash_write_daten_block_loop
32
33
    rcall  wait_20ms
34
    rcall  wait_20ms
35
    rcall  wait_20ms
36
37
    ldi    TEMP_0,'#'
38
    rcall  uart_send_byte

Gruß aus Berlin
Michael

von Markus R. (maggus)


Lesenswert?

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

von Michael U. (amiga)


Lesenswert?

Hallo,

sorry, zuwenig kopiert...
1
.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

von Markus R. (maggus)


Lesenswert?

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

von Michael U. (amiga)


Lesenswert?

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

von Markus R. (maggus)


Lesenswert?

Hallo Michael,

danke für deine super Beschreibung, jetzt klappt sowohl das Chip-ID 
auslesen als auch das beschreiben des ROMs :-)

Grüsse,
Markus

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.