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.

LaunchPad MSP430G2553 saving a lot of measurement data in flash memory

Other Parts Discussed in Thread: MSP430G2553

Good Morning !

I'm working on a motor controller and need to measure about  20 000  ADC10 values

in a sequence  (rate is about 1000 per second)  and   store these values in flash memory for later use.

Would you please provide me with some example code for this "eeprom emulation" as a starting point ?

 

With thanks in advance & best regards, Uli

  • Particular uC does not have enough memory anyway, so eeprom emulation does not apply here. You need external memory. Universal and widely used solution is: SDcard:

    Appnote: http://www.ti.com/lit/an/slaa281b/slaa281b.pdf

    Code: http://www.ti.com/lit/zip/slaa281

    Thread: http://e2e.ti.com/support/microcontrollers/msp43016-bit_ultra-low_power_mcus/f/166/t/18708.aspx

  • Hi,

    if you install Code Composer Studio, under View /TI Resource Explorer, you will finds of examples for flash, such as:

    And for ADC (there are more than 10).
    Good luck!
  • There is something I don't understand.

    You want to save 20k ADC10 values, assuming an ADC10 values contains 10bits, you need to write 200k bits (making concatenation, and  no other information like time stamping). 200kb is 25kB which is greater than the 16kB available on G2553 and I don't consider firmware.

    The wolverine generation is out now, I think FRAM is a good alternetive you have to consider, but the price is not the same.

    EDIT: have a look to http://www.ti.com/analog/docs/litabsmultiplefilelist.tsp?literatureNumber=slaa123&docCategoryId=1&familyId=1477

    I think with the FRAM version you only have to configure the ADC10 DMA to automatically handle all your measurement. I never use FRAM nor read lot on it but I think I could be used like RAM? There is a 1 channel DMA on G2553, you could use it to write on flash too.

     

  • HI,

        you can find the code in here and there also a bit of discussion about storing data in to flash. But consider this, u can only store about 16KB of data(including code). Looking at your needs, it seems u need external memory. any ways here is what u want.

        http://e2e.ti.com/support/microcontrollers/msp43016-bit_ultra-low_power_mcus/f/166/p/207785/736902.aspx#736902

    Regards,

    Sri.

  • sri-sri said:

    No, it's not! 

    That's about allocating const data - nothing to do with storing runtime data!

  • Dear collegues !

    Thanks a lot for the quick help !

     

    Unfortunatelly I mixed up the numbers. The number of motor turns is about 20000.

    You're fully right that I cannot store so much data in the G2553 device. And it is really not

    necessary to store the motor current value for every turn of the motor  ;-)

    The controller is for a linear actuator with 500 mm length - and one or two measurements per mm

    should be fully sufficient. And with 16 kB flash this seems to fit well enough...

     

    Thanks again & have a nice day, Uli

     

  • Hello,

    please note that there is a limited write endurance: http://www.ti.com/mcu/docs/mcuproductcontentnp.tsp?familyId=1751&sectionId=95&tabId=2840&family=mcu#4

    Best regards,

    Mikolaj

  • Hi !

    I just remembered that I should give you all the working solution I found finally ....   Have fun with it  ;-)

    Best regards, Uli

    //******************************************************************************
    // Program name:   ADC10_Flash512
    // Author      :   Dr. Ulrich Kaiser
    // Date        :   29.Dec.2012
    // Hardware    :   msp430g2553  (LaunchPad)
    // Port def.   :   P1.5  input for ADC10
    //     P1.0 output for red LED
    //     P1.6 output for green LED
    // Clock    : DCO 1MHz
    //
    //
    // Description:
    // - erase flash segment of 512 bytes
    // - perform 512  ADC10 measurements
    // - trim results to 8 bits
    // - write results into flash segment
    // - use LED outputs for time measurements with scope
    // - check the 512 stored values
    //
    // Changes:
    // 30.Dec.2012: perform 4 measurements and build average
    // 31.Dec.2012: changed from TRUNC to ROUND  ( add 2, divide by 4 )
    //              changed checker from int to long because of 512
    //
    //******************************************************************************


    #include <msp430g2553.h>

    /* heap memory */
    char  value;                                // 8-bit value to write to segment
    char  *Flash_ptr;                           // Flash pointer
    int   adc_value;
    int   voltage;
    int   j, k;
    long  check;

     

    void main(void)
    {
      WDTCTL = WDTPW + WDTHOLD;                 // Stop watchdog timer
     
      P1DIR |= 0x01;       // Port P1.0 as output    red LED
      P1DIR |= 0x40;       // Port P1.6 as output  green LED
      
      P1OUT = 0;
     
      /* clock setup */ 
      if (CALBC1_1MHZ ==0xFF || CALDCO_1MHZ == 0xFF)                                    
      { 
        while(1);                               // If calibration constants erased
                                                // do not load, trap CPU!!
      }
      
       BCSCTL1 = CALBC1_1MHZ;                    // Set DCO to 1MHz
       DCOCTL  = CALDCO_1MHZ;
                   // Assumed: MCLK 771kHz - 1428kHz
       FCTL2 = FWKEY + FSSEL0 + FN1;             // MCLK/3 for Flash Timing Generator
     
     
       P1OUT |= BIT0;       //  red LED  ON
      
         
       /* erase segment */
       Flash_ptr = (char *) 0xFC00;              // Initialize Flash pointer  of  Segment 1
       FCTL1 = FWKEY + ERASE;                    // Set Erase bit
       FCTL3 = FWKEY;                            // Clear Lock bit
       *Flash_ptr = 0;                           // Dummy write to erase Flash segment
       /* erase done */
     
      
       FCTL1 = FWKEY + WRT;                      // Set WRT bit for write operation
       Flash_ptr = (char *) 0xFC00;              // Initialize Flash pointer  of  Segment 1
      
     
       /* ADC10 setup */
       ADC10CTL0 = ADC10SHT_0 + ADC10ON + ADC10IE;  //  4 x ADC10CLKs,  ADC10ON, interrupt enabled
       ADC10CTL1 = INCH_5;                        // input A5
       ADC10AE0 |= BIT5;                          // PA.5 ADC option select
       /* ADC10 setup done */
      
      
      
       for( j=0;  j<512;  j++ )
       {
        adc_value = 0;
        for( k=0; k<4; k++ )
        {
          P1OUT |= BIT6;       //  green LED  ON   
          ADC10CTL0 |= ENC + ADC10SC;             // Sampling and conversion start   
          __bis_SR_register(CPUOFF + GIE);        // LPM0, ADC10_ISR will force exit from LPM0, General Interrupt Enabled !
          P1OUT &= ~BIT6;       // green LED  OFF    
          adc_value += ADC10MEM;     // can be monitored in HEAP
        }// for k   
       
        adc_value = ( adc_value + 2 ) >> 2 ;  // build average  by  DIV 4  (rounding)
        value = ( adc_value + 2 ) >> 2 ;   // 10 bits to 8 bits !!!     (rounding)
     
       
        P1OUT |= BIT6;       // green LED  ON
        *Flash_ptr++ = value;                   // Write value to flash segment
        P1OUT &= ~BIT6;       // green LED  OFF
      
        _NOP();                                 // SET BREAKPOINT HERE     
       }//for j
     
      
       /* clean up */
       FCTL1 = FWKEY;                            // Clear WRT bit
       FCTL3 = FWKEY + LOCK;                     // Set LOCK bit
      
       P1OUT &= ~BIT0;       // red LED  OFF

       _NOP();                                 // SET BREAKPOINT HERE 
      
       /* checker part */
      
       Flash_ptr = (char *) 0xFC00;              // Initialize Flash pointer  of  Segment 1
       //adc_value = 0;
       check = 0;
     
       for( j=0;  j<512;  j++ )
       {
          check  += *Flash_ptr++;
          _NOP();                                 // SET BREAKPOINT HERE  
       }//for j
      
       _NOP();                                 // SET BREAKPOINT HERE 
       check = check >> 9;    // divide by 512
       
        P1OUT |= BIT0;       //  red LED  ON
        voltage = (int)(  (float)check * 4 * 3.4878 );   // scale to 0 ... 3.568V
        // voltage is lower than expected because of cutting ADC10 to 8 bits !!!
       
        _NOP();                                 // SET BREAKPOINT HERE  
     
        P1OUT &= ~BIT0;       //  red LED  OFF
        P1OUT |= BIT0;       //  red LED  ON
      
    }// ---------------------------- main -----------------------------------------
      
      
      
    // ADC10 interrupt service routine
    #pragma vector=ADC10_VECTOR

    __interrupt void ADC10_ISR(void)
    {
        __bic_SR_register_on_exit( CPUOFF );        // Clear CPUOFF bit from 0(SR)
     
    }// ---------------------- ADC10_ISR -------------------------------------------------

      
    // END ===========================================================================

  • hi, actually i have a project using MSP430g2553 MCU for U turn robot ,can u help me with this one please?

  • kami dodol said:
    hi, actually i have a project using MSP430g2553 MCU for U turn robot ,can u help me with this one please?

    Yes: start with a new thread for a new topic.
    From your description, I have some serious doubt that your project is on topic "saving data in flash memory" :)

**Attention** This is a public forum