Forum: Mikrocontroller und Digitale Elektronik STM32F103 Flash Controller EOP-Bit


von Paul (Gast)


Lesenswert?

Hallo zusammen,

ich möchte mit dem Flash-Controller des STM32F103 eine Seite löschen. 
Dazu gehe ich wie folgt vor:
1
uint8_t pageEraseFlash(uint32_t address)
2
{
3
    // Wait for FPEC to be ready
4
    while(((FPEC->SR >> 0) & 0x01) == 1);
5
6
    // Check whether the flash is locked
7
    if(((FPEC->CR >> 7) & 0x01) == 1)
8
    {
9
        // Unlock the flash memory
10
        FPEC->KEYR = 0x45670123UL;
11
        FPEC->KEYR = 0xCDEF89ABUL;
12
    }
13
    
14
    // Enable page erase
15
    FPEC->CR &= ~(0x01 << 6);   // STRT = 0
16
    FPEC->CR |= (0x01 << 1);    // PER = 1
17
    FPEC->CR &= ~(0x01 << 0);   // PG = 0
18
    
19
    // Set address (must be within the page to erase)
20
    FPEC->AR = address;
21
    
22
    // Perform page erase
23
    FPEC->CR |= (0x01 << 6);    // STRT = 1
24
25
    // Wait for FPEC to be ready
26
    while(((FPEC->SR >> 0) & 0x01) == 1);
27
    
28
    // Wait for EOP bit to be cleared.
29
    //while(((FPEC->SR >> 5) & 0x01) == 0);
30
    
31
    FPEC->CR &= ~(0x01 << 6);   // STRT = 0
32
    FPEC->CR &= ~(0x01 << 1);   // PER = 0
33
    FPEC->CR &= ~(0x01 << 0);   // PG = 0
34
    
35
    // Check if the page has been erased correctly be reading all addresses within the page
36
    uint8_t flag = 0;
37
    for(uint32_t offset = 0; offset < PAGE_SIZE; offset += 2)
38
    {
39
        uint32_t c_addr = (address & 0xFFFFFC00UL) + offset;
40
        
41
        if((*(uint16_t*)c_addr) != 0xFFFFUL)
42
        {
43
            flag = 1;
44
        }
45
    }
46
    
47
    return flag;
48
}

Ein Problem habe ich mit der Zeile
1
while(((FPEC->SR >> 5) & 0x01) == 0);
, da wartet der Controller dann für immer. Wenn ich die Zeile 
auskommentiere (so wie oben im Code), dann funktioniert alles wie 
gewollt. Meine Frage ist nun, weiß jemand, warum das EOF-Bit im 
SR-Register nicht gesetzt wird? Kann es mit zusammen hängen, wenn man 
eine Seite löscht, die schon komplett leer ist? Das Manual sagt dazu 
leider nichts: 
https://www.st.com/content/ccc/resource/technical/document/programming_manual/ae/d8/06/54/cc/09/45/1f/CD00264852.pdf/files/CD00264852.pdf/jcr:content/translations/en.CD00264852.pdf

Viele Dank für alle Tipps!

von Paul (Gast)


Lesenswert?

Hallo,

hat jemand einen Tipp für mich? Muss ich denn den Flash-Controller zuvor 
irgendwie aktivieren? Oder muss ich irgendwelche weiteren Bit im 
Config-Register setzen? Bin echt ratlos...

von pschober (Gast)


Lesenswert?

Hallo,
an dieser Stelle
1
// Wait for FPEC to be ready
2
    while(((FPEC->SR >> 0) & 0x01) == 1);
wartest du, bis der Erase beendet ist.
Laut Datenblatt wird das EOP nach Erfolgreichem Löschen gesetzt. Wenn du 
jetzt darauf wartest, dass EOP 0 wird, wird natürlich nichts daraus.
IMHO sollte es reichen das Busy bit abzufragen, wie bereits geschehen, 
und fertig. Das EOP bit könntest höchstens noch auswerten, um einen 
Rückgabewert zu haben (löschen erfolgreich/nicht erfolgreich).

von Paul (Gast)


Lesenswert?

pschober schrieb:
> Laut Datenblatt wird das EOP nach Erfolgreichem Löschen gesetzt. Wenn du
> jetzt darauf wartest, dass EOP 0 wird, wird natürlich nichts daraus.

Ich warte aber ja darauf, dass EOP = 1 wird...

Habe den Fehler an anderer Stelle gefunden: FPEC war dummer Weise nicht 
als volatile deklariert.... So ist das eben, wenn man denkt es besser 
mit einer selbst gebastelten Library machen zu müssen....

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.