Forum: Mikrocontroller und Digitale Elektronik Atmega Eeprom/Flash andauernde Schreibfehler


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Sebastian W. (wangnick)


Angehängte Dateien:

Lesenswert?

Liebe Leute,

ich programmiere für meine Atmega1284P/W5500-Platine 
(Beitrag "Meine erste Platine") gerade einen 
Internet-Bootloader, und stoße dabei auf ein seltsames Phänomen: Eeprom 
und Flash-Speicher werden fehlerhaft beschrieben.

Dies trat beim Schreiben des Eeprom durch meinen Bootloader auf, aber 
auch beim Schreiben des NRWW durch AVR Studio/AVR Dragon.

Einer meiner Atmegas liess sich durch einen Chip-Erase inklusive Eeprom 
wieder herstellen. Beim zweiten reichte dies nicht aus: Nach zweimaligem 
Chip-Erase waren sowohl im Eeprom als auch im Flash immer noch Adressen 
ungleich 0xFF, und auch das explizite Programmieren sowohl von Flash als 
auch von Eeprom mit nur mit 0xFF gefüllten hex-Dateien durch AVR 
Studio/AVR Dragon schlug fehl.

Ich habe dann bei diesem zweiten Atmega den 3.3V-Regler umgangen und den 
uC direkt mit 5V versorgt. Dann hat der Chip-Erase funktioniert. Jetzt 
läuft auch der zweite uC wieder.

Ich frage mich jetzt aber natürlich, wie es zu diesem Zustand kommen 
konnte. Brown-out war beim ersten uC nicht aktiv, beim zweiten aber auf 
2.7V. Ich benutze eeprom_write_byte() aus der avr-libc. Ich rufe 
eeprom_busy_wait() vor dem Programmieren des Flash auf. Ich lade jeweils 
eine Seite aus dem Flash in einen SRAM-Cache, vergleiche dann die 
einlaufenden Daten mit dem Inhalt dieses Cache, und nur bei einer 
Differenz wird die Seite dann per
1
  for (pa=0; pa<SPM_PAGESIZE; pa+=2) {
2
    boot_page_fill(pa,spmdata[pa+1]<<8|spmdata[pa]);
3
  }
4
  boot_page_erase(spmpage);
5
  boot_spm_busy_wait();
6
  boot_page_write(spmpage);
7
  boot_spm_busy_wait();
in den Flash programmiert. Ein Fehler könnte sein, dass erst noch 
boot_rww_enable() gerufen werden muss, bevor dann die nächste Seite aus 
dem Flash in den Cache gelesen wird. Wie dadurch aber mein Symptom 
auftreten könnte ist mir schleierhaft.

Was das Eeprom angeht, so habe ich gelesen, das eine stabile 
Versorgungsspannung sehr wichtig ist. Nun habe ich zwar Ripple auf 3V3 
(siehe Anhang), der tritt aber vor allem bei der SPI-Kommunikation mit 
dem W5500 auf, und diese findet beim Programmieren des Eeprom gar nicht 
statt. Für Anregungen bezüglich des Ripple bin ich natürlich ebenfalls 
dankbar.

Im Anhang auch der komplette Code des Bootloaders. Sollte jemand noch 
(außer Assembler) einen guten Tipp haben, wie ich von 6KB auf unter 4KB 
komme, so dass er auch in den Atmega328P passt -- immer her damit.

LG, Sebastian

von Sebastian W. (wangnick)


Lesenswert?

Liebe Leute,

ich glaube ich habe den Fehler gefunden: Bei eingesteckter 
Micro-SD-Karte wird anscheinend bei bestimmten Kommandos/Adressen die 
ISP-Kommunikation zwischen AVR Dragon und Atmega gestört! Dadurch werden 
Flash und Eeprom falsch gelesen und auch falsch beschrieben. Wenn die 
Micro-SD-Karte entfernt wird ist alles wieder gut.

Der Grund scheint die Verwendung des SPI Slave Select bei SD-Karten zu 
sein. Bei LOW wird die Karte im SPI-Modus selektiert. Bei HIGH ist die 
SD-Karte aber nicht deselektiert sondern verbleibt im SD-Modus und wird 
in diesem Modus auch auf den Kommandostrom auf MOSI/SCK reagieren!

Jetzt dann die Frage an die Hardware-Design-Könner: Wie kann man einen 
SD-Sockel an einen uC so anschliessen, dass eine SD-Karte während der 
ISP-Programmierung des uC im Sockel verbleiben kann? Würde es ausreichen 
der Karte VDD vorzuenthalten, oder würde die Karte dann immer noch über 
MOSI/SCK mit Strom versorgt? Sollte man lieber SCK nur selektiv 
zuschalten? Gibt es dafür irgendwo ein in der Praxis bewährtes 
open-hardware Referenzdesign?

LG, Sebastian

von Stefan F. (Gast)


Lesenswert?

Du darfst nicht die Spannungsversorgung wegnehmen, weil die Spannung an 
allen Pins nicht höher als VDD und nicht niedriger and GND sein darf.

Du musst wohl eher Tristate-Puffer zwischen die beiden Datenleitungen 
schalten, und damit die Leitungen unterbrechen, wenn die SD Karte nicht 
angesprochen wird.

> Gibt es dafür irgendwo ein in der Praxis bewährtes open-hardware Referenzdesign?

Für mich hat es sich bewährt, SD Karten immer an separaten Leitungen zu 
betreiben. Notfalls per Software-ISP. Sobald andere Sachen mit am Bus 
hängen, hat man immer wieder Stress mit einzelnen SD Karten.

von Sebastian W. (wangnick)


Lesenswert?

Hallo Stefan,

Stefan us schrieb:
>> Gibt es dafür irgendwo ein in der Praxis bewährtes open-hardware 
Referenzdesign?
> Für mich hat es sich bewährt, SD Karten immer an separaten Leitungen zu
> betreiben. Notfalls per Software-ISP. Sobald andere Sachen mit am Bus
> hängen, hat man immer wieder Stress mit einzelnen SD Karten.

Ich glaube du hast recht und ich sollte einen HC4053 einplanen.

Im Grunde kann dieser Fall ja auch während des Betriebs auftreten, also 
wenn SD_CS HIGH ist (also SD-Modus) und man fleissig mit anderen 
SPI-Teilnehmern wie zum Beispiel dem W5500 kommuniziert: Die SD-Karte 
könnte einige der ankommenden MOSI/SCK-Signale als SD-Modus-Kommando 
auffassen und entsprechend auf MISO antworten.

Danach wäre dann aber auch sowohl 
http://arduino.cc/en/uploads/Main/arduino-ethernet-R3-schematic.pdf als 
auch 
http://arduino.cc/en/uploads/Main/arduino-ethernet-shield-06-schematic.pdf 
fehlerhaft?

LG, Sebastian

: Bearbeitet durch User
von Sascha W. (sascha-w)


Lesenswert?

Sebastian Wangnick schrieb:
> Hallo Stefan,
>
> Stefan us schrieb:
> Im Grunde kann dieser Fall ja auch während des Betriebs auftreten, also
> wenn SD_CS HIGH ist (also SD-Modus) und man fleissig mit anderen
> SPI-Teilnehmern wie zum Beispiel dem W5500 kommuniziert: Die SD-Karte
> könnte einige der ankommenden MOSI/SCK-Signale als SD-Modus-Kommando
> auffassen und entsprechend auf MISO antworten.
nein, in der Spec steht, wenn der SPI-Modus einmal aktiviert wurde, 
lässt er sich nur durch Abschalten der Betriebsspannung wieder auf 
SD-Mode umschalten.
D.h. man sollte immer zuerst die Karte auf SPI-Mode initialisieren und 
erst dann mit anderen SPI-Slave's reden.
Wenn du die Karte beim ISP drin lässt, dann solltest du dafür sorgen, 
das auch während des ISP-Zugriffs CS auf High bleibt, denn der 
µC-Ausgang ist während dieser Zeit hochohmig.


Sascha

von Sebastian W. (wangnick)


Lesenswert?

Hallo Sascha,

Sascha Weber schrieb:
> Wenn du die Karte beim ISP drin lässt, dann solltest du dafür sorgen,
> das auch während des ISP-Zugriffs CS auf High bleibt, denn der
> µC-Ausgang ist während dieser Zeit hochohmig.

Ich hab ja (siehe 
http://www.mikrocontroller.net/attachment/201634/W5500-Mega-V02-final-sch.png) 
einen Pullup an DAT3 (SD_CS). Nur reicht das eben nicht wenn die Karte 
im SD-Modus bleibt.

Sascha Weber schrieb:
> wenn der SPI-Modus einmal aktiviert wurde,
> lässt er sich nur durch Abschalten der Betriebsspannung wieder auf
> SD-Mode umschalten.
> D.h. man sollte immer zuerst die Karte auf SPI-Mode initialisieren und
> erst dann mit anderen SPI-Slave's reden.

Also, nach dem Anschalten oder Einstecken ist der SD-Modus aktiviert. 
Den Fall mit dem Anschalten kann man beim Start abfangen, indem man eine 
eventuell eingesteckte Karte in den SPI-Modus bringt. Und auch während 
des Betriebs muss man jedes Einstecken erkennen und die Karte in den 
SPI-Modus bringen bevor man die Kommunikation mit anderen 
SPI-Teilnehmern fortsetzt.

Ein guter Workaround, aber eine Hardware-Lösung ist wohl sicherer.

LG, Sebastian

: Bearbeitet durch User
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.