Forum: Mikrocontroller und Digitale Elektronik TLV Struktur vom MSP430F247 (interner Flash)


von Hans W. (hans_wurst)


Lesenswert?

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)

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

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?

von Hans W. (hans_wurst)


Lesenswert?

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)

von Stefan (Gast)


Lesenswert?

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!

von Stefan (Gast)


Lesenswert?

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!)

von Arno H. (arno_h)


Lesenswert?

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

von Stefan (Gast)


Lesenswert?

>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!

von Hans W. (hans_wurst)


Lesenswert?

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)

von Stefan (Gast)


Lesenswert?

Poste mal Deinen Code, ansonsten kann man nur raten, was passiert oder 
eben nicht passiert!

von Hans W. (hans_wurst)


Lesenswert?

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
}

von Stefan (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.