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 |
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
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
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
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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.