This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Erasing flash memory?

Other Parts Discussed in Thread: MSP430F2274

Hi, i want to learn how to use FNx bits in FCTL2 register. In my application SMCLK frequency 8MHz, for erase and write operation fFTG must be
in the range from ~ 257 kHz to ~ 476 kHz. FNx's value should be, FNx = 018h for ~333kHz. What should be x's value (FNx) ?

Thanks.

Ferhat

  • You could use:

    MOV.W #FWKEY+FSSEL_1+018h,&FCTL2

    or

    MOV.W #0A500h+040h+018h,&FCTL2

    or

    MOV.W #0A558h,&FCTL2

     

  • ferhat said:
    What should be x's value (FNx) ?

    x stands for a number from 0 to 5. Because there is an FN0 bit, an FN1 bit etc.

    For FNx=33, the result is FN5|FN0. (since FN5 is worth 32 and FN0 is worth 1).

    Since the 6 FN bits are the bits 0..5 of the FCTL2 register, you can just write the combined value to the FCTL2 register.

    The FSSELx bits are similar. But here FSSEL0 is worth 64 and FSSEL1 is worth 128. So you'll have to set FSSEL1 bit in FCTL2 or add 128 to the value you write to FCTL2 to set the SMCLK as source.

    For many bit-combinations where only 2 or 3 bits are combined, there are some additional defines in the form FSSEL_0..FSSEL_3 (mind the underscore), which are worth 0, 64,128 and 192.

    For FNx it makes no sense to define 64 macros of the form
    #define FN_0 0
    #define FN_1 1
    #define FN_2 2
    ...

  • The exact answer is 0x17 to divide by 24 as the divider FNx+1.

    A more interesting question is "what happens if you get the frequency wrong?"For  several years I chose the 4Mhz MCLK instead of 1 MHz SMCLK then divided by 2 instead of 3. So far no ill effects but what will happen in the long term? Will the programs just fade away...........

  • Stephen Davies said:
    So far no ill effects but what will happen in the long term? Will the programs just fade away...........

    Yes. :)

    If the clock is too high, the write and erase times are too short. Since you wrote too short, the erase does not need to be that long too, so it counterweights mostly. Yet the bits are not as deeply programmed as should be and you might encounter bits falling back to 1 after a few months, or when operating temperature increases.

    Newer MSPs have a fixed internal clock for the flash controller and do not have the clock control register anymore.

  • While debugging the msp430f2274 with the IAR Embedded Workbench IDE,
    I accidentally enabled 'Allow erase/write access to locked flash memory' and ''Allow erase/write access to BSL flash memory'.
    (This can be found by right -clicking the project -> options -> debugger -> FET Debugger -> download.)

    Now it seems that the 'factory calibrated value from flash' registers are also erased. Making it harder to calibrate the clock freq.

    Is it possible to undo recent events?

    Thanks a lot.

    Mar

  • marino back said:
    Is it possible to undo recent events?

    Sure. It should be possible to restore the original values by opening the chip and doing an analysis on quantum level. There will likely be traces of the last programming left. However, the chip is gone then, and the replacement will come with its own set of calibration data.

    In other words: no. Erased is erased. That's what erase means. Yo can reconstruct the values the same way TI initially has built them: run a softtware that compares the internal results with an external reference and calculate the the required calibration value (for reference calibration value) or step through the available DCO settings and compare the result with an external known clock source (for the clock calibration values). someone has released a program here in this forum that does the clock calibration. You should be able to locate it with the search function.

  • Jens-Michael,

    Would you mind linking the post that has the program attached?

    I was unsuccessful in several searches for this post and I am all but certain that the post is now gone.

    I know it sounds dumb but I would really appreciate it if you helped me find this post.

    Thank you for all you do for MSP, we are all greatful for your support.

  • MSP430F20xx Code Examples (slac080.zip) has the following.

    //******************************************************************************
    //  MSP430F20xx Demo - DCO Calibration Constants Programmer
    //
    //  NOTE: THIS CODE REPLACES THE TI FACTORY-PROGRAMMED DCO CALIBRATION
    //  CONSTANTS LOCATED IN INFOA WITH NEW VALUES. USE ONLY IF THE ORIGINAL
    //  CONSTANTS ACCIDENTALLY GOT CORRUPTED OR ERASED.
    //
    //  Description: This code re-programs the F2xx DCO calibration constants.
    //  A software FLL mechanism is used to set the DCO based on an external
    //  32kHz reference clock. After each calibration, the values from the
    //  clock system are read out and stored in a temporary variable. The final
    //  frequency the DCO is set to is 1MHz, and this frequency is also used
    //  during Flash programming of the constants. The program end is indicated
    //  by the blinking LED.
    //  ACLK = LFXT1/8 = 32768/8, MCLK = SMCLK = target DCO
    //  //* External watch crystal installed on XIN XOUT is required for ACLK *//
    //
    //           MSP430F20xx
    //         ---------------
    //     /|\|            XIN|-
    //      | |               | 32kHz
    //      --|RST        XOUT|-
    //        |               |
    //        |           P1.0|--> LED
    //        |           P1.4|--> SMLCK = target DCO
    //
    //  A. Dannenberg
    //  Texas Instruments Inc.
    //  May 2007
    //  Built with CCE Version: 3.2.0 and IAR Embedded Workbench Version: 3.42A
    //******************************************************************************
    #include "msp430x20x1.h"

    #define DELTA_1MHZ    244                   // 244 x 4096Hz = 999.4Hz
    #define DELTA_8MHZ    1953                  // 1953 x 4096Hz = 7.99MHz
    #define DELTA_12MHZ   2930                  // 2930 x 4096Hz = 12.00MHz
    #define DELTA_16MHZ   3906                  // 3906 x 4096Hz = 15.99MHz

    unsigned char CAL_DATA[8];                  // Temp. storage for constants
    volatile unsigned int i;
    int j;
    char *Flash_ptrA;                           // Segment A pointer
    void Set_DCO(unsigned int Delta);

    void main(void)
    {
      WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT
      for (i = 0; i < 0xfffe; i++);             // Delay for XTAL stabilization
      P1OUT = 0x00;                             // Clear P1 output latches
      P1SEL = 0x10;                             // P1.4 SMCLK output
      P1DIR = 0x11;                             // P1.0,4 output

      j = 0;                                    // Reset pointer

      Set_DCO(DELTA_16MHZ);                     // Set DCO and obtain constants
      CAL_DATA[j++] = DCOCTL;
      CAL_DATA[j++] = BCSCTL1;

      Set_DCO(DELTA_12MHZ);                     // Set DCO and obtain constants
      CAL_DATA[j++] = DCOCTL;
      CAL_DATA[j++] = BCSCTL1;

      Set_DCO(DELTA_8MHZ);                      // Set DCO and obtain constants
      CAL_DATA[j++] = DCOCTL;
      CAL_DATA[j++] = BCSCTL1;

      Set_DCO(DELTA_1MHZ);                      // Set DCO and obtain constants
      CAL_DATA[j++] = DCOCTL;
      CAL_DATA[j++] = BCSCTL1;

      Flash_ptrA = (char *)0x10C0;              // Point to beginning of seg A
      FCTL2 = FWKEY + FSSEL0 + FN1;             // MCLK/3 for Flash Timing Generator
      FCTL1 = FWKEY + ERASE;                    // Set Erase bit
      FCTL3 = FWKEY + LOCKA;                    // Clear LOCK & LOCKA bits
      *Flash_ptrA = 0x00;                       // Dummy write to erase Flash seg A
      FCTL1 = FWKEY + WRT;                      // Set WRT bit for write operation
      Flash_ptrA = (char *)0x10F8;              // Point to beginning of cal consts
      for (j = 0; j < 8; j++)
        *Flash_ptrA++ = CAL_DATA[j];            // re-flash DCO calibration data
      FCTL1 = FWKEY;                            // Clear WRT bit
      FCTL3 = FWKEY + LOCKA + LOCK;             // Set LOCK & LOCKA bit

      while (1)
      {
        P1OUT ^= 0x01;                          // Toggle LED
        for (i = 0; i < 0x4000; i++);           // SW Delay
      }
    }

    void Set_DCO(unsigned int Delta)            // Set DCO to selected frequency
    {
      unsigned int Compare, Oldcapture = 0;

      BCSCTL1 |= DIVA_3;                        // ACLK = LFXT1CLK/8
      TACCTL0 = CM_1 + CCIS_1 + CAP;            // CAP, ACLK
      TACTL = TASSEL_2 + MC_2 + TACLR;          // SMCLK, cont-mode, clear

      while (1)
      {
        while (!(CCIFG & TACCTL0));             // Wait until capture occured
        TACCTL0 &= ~CCIFG;                      // Capture occured, clear flag
        Compare = TACCR0;                       // Get current captured SMCLK
        Compare = Compare - Oldcapture;         // SMCLK difference
        Oldcapture = TACCR0;                    // Save current captured SMCLK

        if (Delta == Compare)
          break;                                // If equal, leave "while(1)"
        else if (Delta < Compare)
        {
          DCOCTL--;                             // DCO is too fast, slow it down
          if (DCOCTL == 0xFF)                   // Did DCO roll under?
            if (BCSCTL1 & 0x0f)
              BCSCTL1--;                        // Select lower RSEL
        }
        else
        {
          DCOCTL++;                             // DCO is too slow, speed it up
          if (DCOCTL == 0x00)                   // Did DCO roll over?
            if ((BCSCTL1 & 0x0f) != 0x0f)
              BCSCTL1++;                        // Sel higher RSEL
        }
      }
      TACCTL0 = 0;                              // Stop TACCR0
      TACTL = 0;                                // Stop Timer_A
      BCSCTL1 &= ~DIVA_3;                       // ACLK = LFXT1CLK
    }

  • More room for me to make errors here! I used the default watch crystal load of 6pF on my MSP430F2418s.

    I think most common watch crystals need 12.5pF ideally.

    I have had 1 board out of some 1000s where the watch crystal sometimes gave the error flag set during initiallisation.

    Maybe it was a tolerance issue - the load was on the low side of 6pF?  With 12.5pF it always initiallised OK.

    Anyhow I suggest you make sure you select the correct load for safety. 

      BCSCTL3=XT2S_2+XCAP_3;            // increase to 12.5pF

  • OCY,

    Thank you for picking up my post!

    It's funny I was looking for a code example as reference for helping another customer with a crystal oscillator issue when I also stumbled across this same code example in the readme.

    Your continued support on the MSP430 and E2E forums in general are also greatly appreciated keep up the good work!

**Attention** This is a public forum