Forum: Mikrocontroller und Digitale Elektronik MSP430i2041 Infomemory


von Frank B. (rank_b)


Lesenswert?

Hallo,
ich möchte mit dem MSP430i2041 Daten in den Infomemory schreiben. Als 
Beispiel wollte ich eine einfache int Zahl speichern. Ich kann diese 
zwar auch einmal speichern, aber bei dem Versuch eine weitere Zahl auf 
die gleiche Speicheradresse abzulegen, funktioniert es nicht. Es bleibt 
einfach die alte Zahl im Speicher.
Wo ist mein Denkfehler?


#define SETUP_FLASH_DATA    0x1060

void EraseInt(int* addr)
{

  while(BUSY & FCTL3);                 // Check if Flash being used
  FCTL2 = FWKEY + FSSEL1 + FN0 + FN2 + FN5; // MCLK/42 for Flash Timing 
Generator
  FCTL1 = FWKEY + ERASE;             // Set Erase bit
  FCTL3 = FWKEY;                     // Clear Lock bit
  *addr = 0;                         // Dummy write to erase Flash 
segment



  while(BUSY & FCTL3);                 // Check if Flash being used
  FCTL1 = FWKEY;                       // Clear WRT bit
  FCTL3 = FWKEY + LOCK;                // Set LOCK bit

}

void WriteInt(int value)
{

  int* addr = (int*)SETUP_FLASH_DATA;

  EraseInt(addr);

  FCTL2 = FWKEY + FSSEL1 + FN0 + FN2 + FN5;
  FCTL3 = FWKEY;
  FCTL1 = FWKEY + WRT;

  *addr++ = value;

  FCTL1 = FWKEY;
  FCTL3 = FWKEY + LOCKSEG;


}

: Bearbeitet durch User
von Frank B. (rank_b)


Lesenswert?

ich habe auch mal das Beispiel von Texas Instruments ausprobiert. Ich 
kann auch hier nur einmal einen Wert schreiben, dann gehts nicht mehr.
Hat keiner eine Idee?

#define SEGSTART 0x1070          // Address of the beginning of the 
Flash Information Segment
#define SEG_LEN  0x10            // Number of bytes within segment to 
erase/write

unsigned char value = 0xAA;      // 8-bit value to write to segment

// Function Prototype
void write_InfoSeg(char value);
void eraseFlash();

void main(void) {
    WDTCTL = WDTPW | WDTHOLD;                   // Stop Watchdog Timer

    FCTL2 = FWKEY | FSSEL_1 | FN1 | FN3 | FN5;  // MCLK/42 for Flash 
Timing Generator
    //eraseFlash();
    write_InfoSeg(value++);                     // Write value to 
Information Segment, increment value

    while(1) {
          __no_operation();                     // SET BREAKPOINT HERE
    }
}

void write_InfoSeg(char value) {
    unsigned char *Flash_ptr;                   // Flash pointer
    unsigned int i;

    Flash_ptr = (unsigned char *)SEGSTART;      // Initialize Flash 
pointer

    if(FCTL3 & LOCKSEG) {                       // If Info Seg is stil 
locked
        FCTL3 = FWKEY | LOCKSEG;                // Clear LOCKSEG bit
    }
    FCTL1 = FWKEY | WRT;                        // Set WRT bit for write 
operation

    for (i = 0; i < SEG_LEN; i++) {
        *Flash_ptr++ = value;                   // Write value to flash
    }

    FCTL1 = FWKEY;                              // Clear WRT bit
    FCTL3 = FWKEY | LOCKSEG;                    // Set LOCKSEG bit
}

von Erik (Gast)


Lesenswert?

war das nicht beim Flash Speicher so .

kann man nur Segmentweise löschen .

mfg Erik

von Frank B. (rank_b)


Lesenswert?

Erik schrieb:
> war das nicht beim Flash Speicher so .
>
> kann man nur Segmentweise löschen .
>
> mfg Erik

Ja, das hab ich alles schon probiert. Irgend was übersehe ich da.

von Clemens L. (c_l)


Lesenswert?

Beim TI-Beispiel hast du eraseFlash() auskommentiert.

Dein Programm behandelt LOCK und LOCKSEG inkonsistent. (Das LOCKSEG-Bit 
wird durch Schreiben einer 1 umgeschalter.)

(Und ich hoffe, du hast eine Sicherheitskopie der Kalibrierungs-Daten.)

von Frank B. (rank_b)


Lesenswert?

Hallo,
ich arbeite mit IAR und dem MSP403i2041.
Mit IRA habe ich die Möglichkeit den Infomemory zu sichern. Nun wollte 
ich den Infomemory wieder herstellen über "Memory Restore". Er zeigt mir 
auch die Daten richtig an, scheint sie dann aber dann aber nicht in den 
Speicher  zu übertragen.
Wenn ich mit den Infomenory nach einem Restore anschaue, sind die Daten 
nicht mehr vorhanden. Es geht hier speziell um die Kalibrierungsdaten, 
die ich wieder herstellen möchte.

Kann mir hier jemand weiterhelfen?

von Mike (Gast)


Lesenswert?

Lösungsvorschlag:

#include "msp430.h"
#include "driverlib/driverlib.h"

#define SEGSTART 0x1060
#define SEG_LEN  0x10    // Number of bytes within segment to 
erase/write

#define SEGSTART_CALB 0x13C0

unsigned char value = 0xC5;      // 8-bit value to write to segment

unsigned char vArray[32] = {0x00};

// Function Prototype
void write_InfoSeg(char value);
void vCopyFlashToArray();

void main(void) {
    WDTCTL = WDTPW | WDTHOLD;                   // Stop Watchdog Timer

    FCTL2 = FWKEY | FSSEL_1 | FN1 | FN3 | FN5;

    _NOP();

    vCopyFlashToArray();  //Store Calib-Data to Array

    write_InfoSeg(value++); // Write value to Information Segment,

    while(1) {
          __no_operation();                     // SET BREAKPOINT HERE
    }
}

void write_InfoSeg(char value) {
    unsigned char *Flash_ptr;                   // Flash pointer
    unsigned int i;

    Flash_ptr = (unsigned char *)SEGSTART;      // Initialize Flash 
pointer

    if(FCTL3 & LOCKSEG) {             // If Info Seg is stil locked
        FCTL3 = FWKEY | LOCKSEG;      // Clear LOCKSEG bit
    }

    FCTL1 = FWKEY | ERASE;            // Set WRT bit for write operation
    *Flash_ptr = 0;
    FCTL1 = FWKEY &~ ERASE;


    FlashCtl_unlockInfo();
    FCTL1 = FWKEY | WRT;              // Set WRT bit for write operation


    for (i = 0; i < SEG_LEN; i++) {
        *Flash_ptr++ = value;         // Write value to flash
    }

    Flash_ptr = (unsigned char *)SEGSTART_CALB;

    for (i = 0; i < SEG_LEN; i++) {
        *Flash_ptr++ = vArray[i];      // Write value to flash
    }
    FlashCtl_lockInfo();

    FCTL1 = FWKEY;                     // Clear WRT bit
    FCTL3 = FWKEY | LOCKSEG;           // Set LOCKSEG bit
}

// -----------------------------------------------------------
void vCopyFlashToArray(){

   unsigned char *Flash_ptr;

   Flash_ptr = (unsigned char *)SEGSTART_CALB;

    for(int i = 0; i<32;i++)
      vArray[i] = *Flash_ptr++;

   _NOP();
}

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.