Hallo!
Seit Stunden versuche ich, den Flash Speicher auf einem ARM9
(STR912FAW44) zu beschreiben. Habe mich deshalb nun extra hier
angemeldet, nachdem ich sonst nur mitgelesen hattee. Um den Speicher zu
beschreiben verwende ich Keil und die mitgelieferten Bibliotheken. Der
Controller bootet von Bank 0, und ich möchte Daten auf Bank 1 sichern.
Ich orientiere mich an einem Beispiel.
Letztendlich sollen diese Codezeilen Daten schreiben:
1 | FMI_WriteProtectionCmd(FMI_B1S0, DISABLE);
|
2 | FMI_EraseSector(FMI_B1S0);
|
3 | FMI_Timeout_Status = FMI_WaitForLastOperation(FMI_BANK_1);
|
4 | content = 0x1114;
|
5 | FMI_WriteHalfWord(0x400000,content);
|
6 | FMI_Timeout_Status = FMI_WaitForLastOperation(FMI_BANK_1);
|
Leider erhalte ich als Status immer einen Timeout.
Da dachte ich, schaue ich doch mal in die Library.
1 | u8 FMI_WaitForLastOperation(vu32 FMI_Bank)
|
2 | {
|
3 | int tmp;
|
4 | u32 Time_Out = 0;
|
5 |
|
6 | /* Write a read status register command */
|
7 | *(vu16 *)(FMI_Bank) = 0x70;
|
8 |
|
9 | /* Wait until operation compeletion */
|
10 | while((!((*(vu16 *)FMI_Bank) & 0x80))&&(Time_Out < TIMEOUT ))
|
11 | {
|
12 | Time_Out++ ; /* Time Out */
|
13 | }
|
14 | ...
|
Darunter wird dann, je nachdem ob Time_Out den Grenzwert erreicht hat, 0
oder 1 zurückgegeben.
Beim Durchsteppen mit dem Hardware Debugger habe ich gemerkt, dass der
Code durchgesteppt funktioniert. Klar, Taktproblem, dachte ich mir, und
habe den PLL mal mit "SCU_PLLFactorsConfig(6, 25, 128);"
runtergeschraubt. Pustekuchen, nix.
Auch eine künstliche Warteschleife (die sogar etwa eine Sekunde zählt)
hat nichts gebracht. Grübeln. Den Code im Hardware Debugger wieder
laufen lassen. Beim Ablaufen irgendwann gestoppt, dabei war ich
logischerweise immer in der While Schleife, die den Timeout erhöht. Aber
allein das Anhalten im Debugger hat genügt, dass es danach weiter geht.
Hm.
Durch Zufall dann ein paar LEDs zu Diagnosezwecken angeschaltet, und
dadurch erstaunliches festgestellt:
Füge ich in die While Schleife noch einen Befehl wie "GPIO7->DR[0x3FC] =
0x02;" ein, oder auch nur "int tmp = GPIO7->DR[0x3FC];". so funktioniert
alles. Also wie folgt:
1 | while((!((*(vu16 *)FMI_Bank) & 0x80))&&(Time_Out < TIMEOUT ))
|
2 | {
|
3 | int dat;
|
4 | Time_Out++ ; /* Time Out */
|
5 | // added
|
6 | dat = GPIO7->DR[0x3FC]; //Port 7 lesen
|
7 | //GPIO7->DR[0x3FC] = 0x02; // Oder auch etwas ausgeben
|
8 | }
|
Ich kann auch GPIO6 verwenden, dieser Port wird nicht einmal verwendet.
Es scheint mir, als ob irgendeine Busaktivität etwas auslöst.
Nun bin ich ratlos.
Habt ihr eine Idee? Es kann ja nicht der Sinn sein, die mitgelieferte
Bibliothek zu verändern?
Danke schonmal!