Hallo, die uC's der MSP430x2xx-Famile besitzen einen Speicherbereich (TLV-Structure) in dem spezifische Werte für den Abgleich des Taktes und des ADC-Wandlers enthalten sind. Dieser Bereich bleibt auch erhalten, wenn der uC stromlos ist und wird auch garantiert nicht von anderen Teilen neu überschrieben. Einige Speicheradressen sind dort noch frei und ich würde sie gerne verwenden um eigene Daten ablegen zu können. (sozusagen als Ersatz für einen externen Speicher) Hat jemand damit bereits Erfahrungen? Ich schaffe es nämlich nicht diesen Teil zu überschreiben. (Habe versucht den Wert 0xFF auf der Adresse 0x10EE zu überschreiben)
Ist das nicht der Teil des Flash-ROMs, der auch als INFO-Memory bezeichnet wird? Der sollte dann genauso beschrieben werden können, wie das restliche Flash-ROM. Wie hast Du denn versucht, den Bereich zu beschreiben?
Ja, so wie ich das verstanden habe, ist das der Bereich Info-Memory. Das schreiben habe ich so versucht:
1 | #define ADRESSE_OFFSET (CAL_ADC_25T85+1)*2+4
|
2 | |
3 | volatile unsigned char *p_adresse; |
4 | p_adresse= &TLV_ADC12_1_TAG; // setze auf Adresse TLV_ADC12_1_TAG |
5 | p_adresse += ADRESSE_OFFSET; // Springe weiter auf Adresse 0x10EE |
6 | |
7 | (*p_adresse) = 0x00; // enthält sonst den Wert 0xFF |
Auch wenn ich den Wert auf dieser Adresse im Debug-Modus ändern möchte, ändert er ihn nicht. (Auf "normalen" Adressen geht es aber)
Der INFO-Bereich ist ein Flash-Speicher, der nicht wie RAM beschrieben werden kann, sondern programmiert werden muss. Wie das geht, steht im User-Guide unter Kap.7 (Flash Memory Controller) und in den Code-Beispielen von TI. Ausserdem ist dieser INFO-Bereich extra gegen Löschen und Überschreiben geschützt, da er "sensible" Daten enthält (also z.B. Kalibrierung des internen DCO usw.) Zum Löschen muss daher zusätzlich zu LOCK = 0 auch LOCKA = 0 gesetzt werden!
Hier noch ein Code-Ausschnitt von TI, in dem genau dieser INFO-A Bereich neu beschrieben wird:
1 | Flash_ptrA = (char *)0x10C0; // Point to beginning of seg A |
2 | FCTL2 = FWKEY + FSSEL0 + FN1; // MCLK/3 for Flash Timing Generator |
3 | FCTL1 = FWKEY + ERASE; // Set Erase bit |
4 | FCTL3 = FWKEY + LOCKA; // Clear LOCK & LOCKA bits |
5 | *Flash_ptrA = 0x00; // Dummy write to erase Flash seg A |
6 | FCTL1 = FWKEY + WRT; // Set WRT bit for write operation |
7 | Flash_ptrA = (char *)0x10F8; // Point to beginning of cal consts |
8 | for (j = 0; j < 8; j++) |
9 | *Flash_ptrA++ = CAL_DATA[j]; // re-flash DCO calibration data |
10 | FCTL1 = FWKEY; // Clear WRT bit |
11 | FCTL3 = FWKEY + LOCKA + LOCK; // Set LOCK & LOCKA bit |
Man beachte hierbei, dass das LOCKA-Bit durch 1-setzen zwischen den Werten 0 und 1 getoggelt wird! (0-setzen hat keine Wirkung!)
Die beiden mittleren Segmente B und C sind offensichtlich unbelegt, hier solltest du deine Versuche machen. So wie ich das DB interpretiere, kannst du nur ein komplettes Segment löschen und die DCO-Kalibrierung ab 01F8H in Segment A wäre in deinem Fall mit weg. Arno
>kannst du nur ein komplettes Segment löschen und die DCO-Kalibrierung ab >01F8H in Segment A wäre in deinem Fall mit weg. Ja und nein! Richtig, man kann immer nur ein komplettes Segment löschen und die Daten darin wären somit futsch. Da aber in der Regel immer nur ein paar Bytes im INFO-Segment neu beschrieben werden und der Rest erhalten bleiben soll, kommt man eigentlich eh nicht drumherum, vor dem Löschen ein Backup des Segments im RAM abzulegen, dort die entsprechenden Daten zu ändern und dann das komplette Segment neu zu beschreiben. Somit werden die Kalibrierdaten erhalten. Wenn man allerdings mit den anderen INFO-Bereichen (B,...) auskommt, sollten man tatsächlich das INFO-A zunächst mal unangetastet lassen!
Stimmt, es ist dann sicher besser ich nutze nur die Segmente B bis D. Ich habe mal den oben genannten Code (auch im Codebeispiel "msp430x24x_dco_flashcal.c" von TI enthalten) probiert. Damit kann ich komischerweise aber nur die Werte für den Quarz ändern. Gehe ich auf eine andere Adresse (z.B. 0x10EE), dann steht dort bei einem Neustart immer nur der Wert 0xFF. (Das gleiche passiert wenn ich auf ein anderes Segment zugreifen möchte)
Poste mal Deinen Code, ansonsten kann man nur raten, was passiert oder eben nicht passiert!
Das hier ist der Code, bei dem ich versuche die Werte für den Quarz (was auch gelingt), und einen Wert auf der Adresse 0x10C4 (was nicht gelingt) zu ändern:
1 | void main(void) |
2 | {
|
3 | WDTCTL = WDTPW + WDTHOLD; // Stop WDT |
4 | |
5 | // Meine Anwendung läuft ohne externen Quarz
|
6 | // for (i = 0; i < 0xfffe; i++); // Delay for XTAL stabilization
|
7 | |
8 | j = 0; // Reset pointer |
9 | |
10 | CAL_DATA[j++] = CALDCO_16MHZ; |
11 | CAL_DATA[j++] = CALBC1_16MHZ; |
12 | CAL_DATA[j++] = CALDCO_12MHZ; |
13 | CAL_DATA[j++] = CALBC1_12MHZ; |
14 | CAL_DATA[j++] = CALDCO_8MHZ; |
15 | CAL_DATA[j++] = CALBC1_8MHZ; |
16 | CAL_DATA[j++] = CALDCO_1MHZ; |
17 | CAL_DATA[j++] = CALBC1_1MHZ; |
18 | |
19 | Flash_ptrA = (char *)0x10C0; // Point to beginning of segA |
20 | FCTL2 = FWKEY + FSSEL0 + FN1; // MCLK/3 for Flash Timing Generator |
21 | FCTL1 = FWKEY + ERASE; // Set Erase bit |
22 | FCTL3 = FWKEY + LOCKA; // Clear LOCK & LOCKA bits |
23 | *Flash_ptrA = 0x00; // Dummy write to erase Flash segA |
24 | FCTL1 = FWKEY + WRT; // Set WRT bit for write operation |
25 | Flash_ptrA = (char *)0x10F8; // Point to beginning of cal consts |
26 | for (j = 0; j < 8; j++) |
27 | *Flash_ptrA++ = CAL_DATA[j]; // re-flash DCO calibration data |
28 | Flash_ptrA = (char *)0x10C4; |
29 | |
30 | *Flash_ptrA++ = 0x00; // zum Testen geschrieben |
31 | *Flash_ptrA++ = 0x0f; // Diese Werte sind jedoch nach einem |
32 | *Flash_ptrA++ = 0xf0; // erneuten Start des Mikrocontrollers |
33 | // wieder auf dem Wert 0xFF
|
34 | |
35 | FCTL1 = FWKEY; // Clear WRT bit |
36 | FCTL3 = FWKEY + LOCKA + LOCK; // Set LOCK & LOCKA bit |
37 | }
|
Entweder es ist schon zu spät... ... oder ich sehe da eigentlich wirklich keinen Fehler?! Allerdings behaupte ich mal, dass (aus welchem Grund auch immer) bei Dir gar nichts ins INFO geschrieben wird, nicht mal die Kalibrierwerte. Du kopierst Dir ja die derzeitigen Werte in CAL_DATA[] und schreibst dieselben dann zurück ins Flash. Du siehst also gar nicht, was und ob überhaupt geschrieben wird! Kontrolliere mal Deinen Systemclock (DCO ?) und den Teiler für den Flash Controller. Der braucht 257 - 476kHz, ansonsten kann Müll rauskommen. Schau Dir vielleicht mal das FAIL-Flag in FCTL3 an (vorher löschen), ob der Clock Probleme macht. Ausserdem muss Vcc > 2,2V sein! Mehr fällt mir jetzt gerade auch nicht ein.
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.