Flash als EEPROM

Gast #3626329
Lesenswert?

Hallo Leute,

ich habe ein Problem beim Benutzen des Flash Speichers als EEPROM im 
dsPIC33FJ32. Ich habe mich etwas eingelesen und mir den Code unten 
geschrieben und zusammenkopiert. Zum testen soll 64 mal BBAAAAh ab der 
Adresse 5000h geschrieben werden. Bedingt funktioniert das auch schon, 
es gibt aber noch Probleme:

1
    eeprom_address = 0x5000;
2
    TBLPAG = 0x0000;//eeprom_address >> 16;    // obere Adresse
3
    WREG0  = 0x5000;                // untere Adresse
4
//  WREG0  = (unsigned int) eeprom_address;    // untere Adresse

Wenn ich die letzte Zeile auskommentiere, werden einige Werte ab der 
Adresse 5000h geschrieben, jedoch nicht alle und die Werte stimmen 
nicht.
Statt BBAAAAh steht an der Adresse 5000h nur AAAAAAh und in einigen 
weiteren Felder irgendwelche anderen Werte. Der Rest bleibt auf FFFFFFh.
Wenn ich dagegen die vorletzte Zeile auskommentiere, stimmen die Werte 
und auch die Anzahl. Dafür stehen die Werte erst ab ab der Adresse 
5180h.
Ich verstehe nun weder die erste noch die zweite Variante. Und vor Allem 
verstehe ich nicht, wieso die Varianten sich überhaupt unterscheiden. In 
beiden Fällen schreibe ich doch 5000h in WREG0.

1
void Flash_Save(void)
2
{
3
    unsigned char local_i;
4
    unsigned int eeprom_address;
5

6
    // zuerst muss die Page gelöscht werden
7
    while(NVMCONbits.WR) continue;      // falls noch ein EEPROM Befehl abgearbeitet wird --> warten
8
    NVMCON = 0x4042;
9

10
    // Befehl zum löschen eines words
11
    eeprom_address = 0x5000;
12
    TBLPAG = 0x0000;//eeprom_address >> 16;    // obere Adresse
13
    WREG0  = 0x5000;                                    // untere Adresse
14

15
    asm("TBLWTL W0, [W0]");
16
    asm("DISI #5");          // Interrupts für 5 Instructions blockieren
17

18
    NVMKEY = 0x55;          // "magic sequence"
19
    NVMKEY = 0xAA;
20

21
    NVMCONbits.WR = 1;          // löschen starten
22
    Nop();
23
    Nop();
24

25
    // dann schreiben wir das Wort ins EEPROM
26
    while(NVMCONbits.WR) continue;      // falls noch ein EEPROM Befehl abgearbeitet wird --> warten
27
    NVMCON = 0x4001;          // Befehl zum schreiben eines words
28
                                                        // untere Adresse ins W0
29
    eeprom_address = 0x5000;
30
    TBLPAG = 0x0000;//eeprom_address >> 16;    // obere Adresse
31
    WREG0  = 0x5000;                // untere Adresse
32
//  WREG0  = (unsigned int) eeprom_address;    // untere Adresse
33

34
    // Daten im Latch ablegen - 64 Worte = 1 Row
35
    for (local_i = 0;local_i<=63;local_i++)
36
    {
37
            WREG2 = 0xAAAA;//Flash_Row_Low[local_i];
38
            WREG3 = 0xBBBB;//Flash_Row_High[local_i];
39
            asm("TBLWTL W2, [W0]");
40
            asm("TBLWTH W3, [W0++]");
41
    }
42

43
    // Die Daten im Latch in die Row speichern
44
    asm("DISI #5");
45
    NVMKEY = 0x55;
46
    NVMKEY = 0xAA;
47

48
    NVMCONbits.WR = 1;
49
    Nop();
50
    Nop();
51
    while(NVMCONbits.WR) continue;
52
    NVMCON = 0x0000;
53
    IEC0bits.AD1IE = 1;
54
}
#3630261
Lesenswert?

Hallo,

ich habe letztens etwas ähnliches mit einem V850-Controller gemacht. 
Dieser hat auch kein echtes EEPROM, sondern nur einen kleinen 
"Data-Flash" zum Ablegen nichtflüchtiger Daten.
Renesas empfiehlt da ausdrücklich die eigens zur Verfügung gestellten 
Flash- und EEPROM-Libs zu benutzen, da Flash nicht wie EEPROM behandelt 
werden kann (nur seitenweises löschen/beschreiben usw...). EEPROM 
Zugriffe werden dann im Prinzip simuliert und Datenstrukturen müssen 
auch noch mit einer ID versehen werden, da die Position im Flashspeicher 
gar nicht genau bekannt ist.
Jedenfalls hätte ich das selbst niemals hinbekommen, wenn ich mir den 
Code der Renesas Library so anschaue. Eventuell solltest du auch mal 
nach solchen Libs schauen...

VG,
Thomas
Gast #3633960
Lesenswert?

Danke für den Tipp, solche Libs habe ich von Microchip auch schon 
gefunden. Aber ich bin ja eigentlich schon so nah dran. Es scheint mir 
ja auch irgendwie ein C-Problem zu sein. Schließlich sollte ja egal 
sein, wie ich die 5000h als Adresse definiere - ob direkt oder über den 
Umweg mit der Variablen.
Gast #3633985
Lesenswert?

Die Interrupt-Sperren sehen mir "klüschtig" aus. Passen die von der 
Länge? (Ohne Optimierung in 5 Instruktionen?)

Greift irgendeine ISR auf den Flash zu in der Zeit in der 
geschrieben/gelöscht wird?
Gast #3635522
Lesenswert?

Maxx schrieb:
> Die Interrupt-Sperren sehen mir "klüschtig" aus. Passen die von der
> Länge? (Ohne Optimierung in 5 Instruktionen?)
Ich werde nachher mal probieren, was passiert, wenn ich die 5 etwas 
hochschraube.

Maxx schrieb:
> Greift irgendeine ISR auf den Flash zu in der Zeit in der
> geschrieben/gelöscht wird?
Ich habe eigentlich nur 2 Interrupts konfiguriert (Timer und ADC) und 
die sind während der Routine nicht aktiv. Oder kann da noch irgendwas im 
Hintergrund ablaufen, wovon ich als Anfänger keinen Plan habe?

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren