mikrocontroller.net

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


Autor: Markus R. (maggus)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Michael U. (amiga)
Datum:

Bewertung
0 lesenswert
nicht 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.
; benutzter Flash: 128kx8, SST 29EE010-150    0xBF, 0x07  kein Chip-Erase, Product Identification nur SST-Kommando
; benutzter Flash: 128kx8, ATMEL 29C010A-12    0x1F, 0xD5
; benutzter Flash: 128kx8, Winbond W29C020-12  0xDA, 0x45  Product Identification nur SST-Kommando
 
flash_write_daten_loop:

    ldi    TEMP_0,0x80            ; Data Protect Disable
    rcall  flash_control

    ldi    TEMP_0,0x20
    rcall  flash_control

    rcall  wait_20ms
    rcall  wait_20ms

    ldi    TEMP_0,0xA0            ; Page Write
    rcall  flash_control

    sbrs  FLAGS,FLAG_CONTROL        ; Controlmap?
    lds    TEMP_0,FLASH_BANK        ; nein, Bank holen
    sbrc  FLAGS,FLAG_CONTROL
    ldi    TEMP_0,BANK_0          ; ja, immer Bnak 0 programmieren!
    out    BANK_PORT,TEMP_0        ; und setzen
    
    ldi    TEMP_2,128            ; Page Länge

flash_write_daten_block_loop:
    ld    TEMP_0,Z+            ; Daten holen
    st    Y+,TEMP_0            ; und schreiben
    dec    TEMP_2
    brne  flash_write_daten_block_loop

    rcall  wait_20ms
    rcall  wait_20ms
    rcall  wait_20ms

    ldi    TEMP_0,'#'
    rcall  uart_send_byte

Gruß aus Berlin
Michael

Autor: Markus R. (maggus)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Michael U. (amiga)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

sorry, zuwenig kopiert...
.macro  setbank                            ; lädt 16Bit @1 nach @0 High und @0 Low
    push  TEMP_0
    ldi     TEMP_0,@0
    out     BANK_PORT,TEMP_0
    pop    TEMP_0
.endmacro

flash_control:
    push  ZH
    push  ZL
    push  TEMP_1
    push  TEMP_2
    
    ldi    TEMP_1,0xAA
    load_p  Z,0x5555            ; Kommand 1        0101 0101
    setbank  BANK_1
    st    Z,TEMP_1            ; und schreiben

    ldi    TEMP_1,0x55
    load_p  Z,0x2AAA | 0x4000        ; Kommand 2        0010 1010
    setbank  BANK_0
    st    Z,TEMP_1            ; und schreiben

    load_p  Z,0x5555            ; Kommand 1        0101 0101
    setbank  BANK_1
    st    Z,TEMP_0            ; und schreiben

    pop    TEMP_2
    pop    TEMP_1
    pop    ZL
    pop    ZH

    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

Autor: Markus R. (maggus)
Datum:

Bewertung
0 lesenswert
nicht 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:
    
  PORTD &= ~(1<<PD5);   // chip enable
  PORTD |= (1<<PD6);    // Write rom = off
  PORTD |= (1<<PD7);   //read rom = off
  adr16 = 0x5555;
  value = 0xAA;
  adr8_h = adr16 >> 8;     // high byte
  adr8_l = adr16 & 0xFF;   // low byte
  PORTA = adr8_h;
  PORTC = adr8_l;
  PORTB = value;
  _delay_ms(10);
  PORTD &= ~(1<<PD6);   // write rom = on
  _delay_ms(10);
  PORTD |= (1<<PD6);    // wprite rom = off
  _delay_ms(100);

Die Adressleitungen hängen an PORTA und PORTC, die Datenleitungen an 
PORTB.

Grüsse,
Markus

Autor: Michael U. (amiga)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Markus R. (maggus)
Datum:

Bewertung
0 lesenswert
nicht 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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.