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.

MSP430F47197 flash goes crazy!

I have the following code:

#include <msp430f47197.h>
#include <stdbool.h>

bool flag = true;
unsigned short read_flash (unsigned short address);
void erase_flash(unsigned short address);
void write_flash (char value,unsigned short address);

 const char numbers[]={0x7D,0x05,0x3E,0x7A,0x63,0x5B,0x5F,0x70,0x7F,0x7B};

int main(void)
{
  
  volatile unsigned int i;
  WDTCTL = WDTPW + WDTHOLD;                 // Stop watchdog timer

  FLL_CTL0 |= XCAP11PF;                     // Configure load caps

  // Wait for xtal to stabilize
  do
  {
    IFG1 &= ~OFIFG;                         // Clear OSCFault flag
    for (i = 0x47FF; i > 0; i--);           // Time for flag to set
  }
  while ((IFG1 & OFIFG));                   // OSCFault flag still set?
  
  P5SEL =BIT1+BIT2+BIT3+BIT4;               // Set COM pins for LCD
  LCDACTL = LCDON+LCD4MUX;                  // 4mux LCD, ACLK/32
  LCDAPCTL0 = 0x7F;                         // Segments 0-24
  for( i = 1; i <= 20; i ++)
  {
    LCDMEM[i] = 0;                          // Clear LCD  We have 20 LCDMemory 
  }

 

  
  P5SEL =BIT1+BIT2+BIT3+BIT4;               // Set COM pins for LCD
  LCDACTL = LCDON+LCD4MUX;                  // 4mux LCD, ACLK/32
  LCDAPCTL0 = 0xF6;                         // Segments 0-24
  
    erase_flash(0x0ffB1);  // erasing the flash 
 //  write_flash(0x67,0x0ffc0);  // Writing 'H'
       
       
       
       for (i =0; i <= 9 ; i++)
       {
         
         LCDMEM[4] =  numbers[i]; 
           write_flash(numbers[i],0x0ffB1);
            read_flash(0x0ffB1); 
           __delay_cycles(1000000);
       }
       
       
       
   
  
}



void erase_flash(unsigned short address)
{
     char *Flash_ptr;                          
     Flash_ptr = (char*) address;             
     FCTL1 = FWKEY + ERASE;                  
     FCTL3 = FWKEY;
     *Flash_ptr = 0;
     FCTL3 = FWKEY +  LOCK;
}
void write_flash (char value,unsigned short address)
{
  char *Flash_ptr;                        
  Flash_ptr = (char*) address;            
  FCTL1 = FWKEY + ERASE;                  
  FCTL3 = FWKEY;                          
  FCTL1 = FWKEY + WRT;                      
  *Flash_ptr = value;
  FCTL1 = FWKEY;                           
  FCTL3 = FWKEY +  LOCK;                    
}

unsigned short read_flash (unsigned short address)
{
  char value;
  char *Flash_ptr;
  Flash_ptr = (char*) address;             
  value = *Flash_ptr;
  LCDMEM[2] = value  ;
  return (value);
}

It counts 0 to 9 .... on one cell of the LCD and on the other it shows the flash memory's content which is as the same as count-up cell.

The LCD shows like this:

            flash           ram

1 sec :    0                0

2 sec:     1                1

3 sec:    (dummy)     2

4 sec:                       3

5 sec:                       4

                         ...

Why the flash goes crazy from 2 on?!!!

  • Oh Shoot!  I found what the problem was!  I must move the 

     erase_flash(0x0ffB1); to the for loop as follows!

    What a tricky flash!!!

    #include <msp430f47197.h>
    #include <stdbool.h>
    
    bool flag = true;
    unsigned short read_flash (unsigned short address);
    void erase_flash(unsigned short address);
    void write_flash (char value,unsigned short address);
    
     const char numbers[]={0x7D,0x05,0x3E,0x7A,0x63,0x5B,0x5F,0x70,0x7F,0x7B};
    
    int main(void)
    {
      
      volatile unsigned int i;
      WDTCTL = WDTPW + WDTHOLD;                 // Stop watchdog timer
    
      FLL_CTL0 |= XCAP11PF;                     // Configure load caps
    
      // Wait for xtal to stabilize
      do
      {
        IFG1 &= ~OFIFG;                         // Clear OSCFault flag
        for (i = 0x47FF; i > 0; i--);           // Time for flag to set
      }
      while ((IFG1 & OFIFG));                   // OSCFault flag still set?
      
      P5SEL =BIT1+BIT2+BIT3+BIT4;               // Set COM pins for LCD
      LCDACTL = LCDON+LCD4MUX;                  // 4mux LCD, ACLK/32
      LCDAPCTL0 = 0x7F;                         // Segments 0-24
      for( i = 1; i <= 20; i ++)
      {
        LCDMEM[i] = 0;                          // Clear LCD  We have 20 LCDMemory 
      }
    
     
    
      
      P5SEL =BIT1+BIT2+BIT3+BIT4;               // Set COM pins for LCD
      LCDACTL = LCDON+LCD4MUX;                  // 4mux LCD, ACLK/32
      LCDAPCTL0 = 0xF6;                         // Segments 0-24
      
        // erasing the flash 
     //  write_flash(0x67,0x0ffc0);  // Writing 'H'
           
           
           
           for (i =0; i <= 9 ; i++)
           {
             
             LCDMEM[4] =  numbers[i]; 
              erase_flash(0x0ffB1); 
               write_flash(numbers[i],0x0ffB1);
                read_flash(0x0ffB1); 
               __delay_cycles(1000000);
           }
           
           
           
       
      
    }
    
    
    
    void erase_flash(unsigned short address)
    {
         char *Flash_ptr;                          
         Flash_ptr = (char*) address;             
         FCTL1 = FWKEY + ERASE;                  
         FCTL3 = FWKEY;
         *Flash_ptr = 0;
         FCTL3 = FWKEY +  LOCK;
    }
    void write_flash (char value,unsigned short address)
    {
      char *Flash_ptr;                        
      Flash_ptr = (char*) address;            
      FCTL1 = FWKEY + ERASE;                  
      FCTL3 = FWKEY;                          
      FCTL1 = FWKEY + WRT;                      
      *Flash_ptr = value;
      FCTL1 = FWKEY;                           
      FCTL3 = FWKEY +  LOCK;                    
    }
    
    unsigned short read_flash (unsigned short address)
    {
      char value;
      char *Flash_ptr;
      Flash_ptr = (char*) address;             
      value = *Flash_ptr;
      LCDMEM[2] = value  ;
      return (value);
    }
    

  • But I am still struggling with the following statement.

    How I can show the "power loss" on such code?! Meaning that the systems understands that the power went off lets say when "4" turns to "5" and when I switch on again it shows the following message:

    "Power went off. The last digit was:"   4

    maybe using SVS or other alternatives?

    Any idea please?

    Because the only thing that can help me is FLASH as it is there and cannot be gone by the "power loss" ... I was going to use a flag but it failed! Well, it is normal! It is written in ram! 

  • Just curious: why you are doing this? What you want to achieve?

  • CaEngineer said:
    maybe using SVS or other alternatives?

    SVMh with interrupt.

  • Ilmars said:
    SVMh with interrupt.

    Excuse me I have heard about SVM: Supply Voltage Supervisor but not SVMh! With interrupt? Can you please be more specific?

  • Dear llmars,

    This will be part of an Energy meter where the kWh gets lost by power loss and goes back when I find a way to store the it in Flash and read it from when it MCU goes alive!

  • CaEngineer said:
    Excuse me I have heard about SVM: Supply Voltage Supervisor but not SVMh! With interrupt? Can you please be more specific?

    Wel.. I missed that you use 4-series. SVM (unfortunately for you) is present on 5-series.

    This still leaves comparator option as voltage detector for you. Well. If you have big enough power supply storage capacitors, you can use ADC too. Or just external power supply supervisor IC connected to IO pin with pin interrupt enabled.

  • Ilmars said:
    Wel.. I missed that you use 4-series. SVM (unfortunately for you) is present on 5-series.

    Yes I use MSP430F4  not 5.


    As for the hardware-wise perspective of view, I know that I need to detect the voltage where it goes below to a certain voltage or not. And I believe the evaluation module in terms of ADC is already assigned and on my board as well.

    As for the code, I will keep sharing my problem that will face later on!

    Thank you!

  • I found something strange!!!

    When I have a code with RAM + FLASH together! after power on Reset it shows nothing on the display!!! Whereas, when I run it on RAM only after power on reset I have the value on the screen! Can anyone explain this to me please?

    Here is the code as follows.

    #include <msp430f47197.h>
    
    void LCD_init(void);          // Definition of LCD initialization
    void DelayMs(int Ms);               
    void LCD_cmd(unsigned char cmd);     
    void LCD_dat(unsigned char byte);       
    unsigned short read_flash (unsigned short address);
    void erase_flash(unsigned short address);
    void write_flash (char value,unsigned short address);
    int lengthCal( double len);
    long Show(long z );
    long Flash(long d);
    
    
    int main(void)
    {
      
      WDTCTL = WDTPW + WDTHOLD;                 // Stop watchdog timer
      
      P7DIR = 0x00; // Redundant
            P8OUT = 0;    // Before set DIR
            P8DIR = 0x07; //P8.2=>EN, P8.1=>RW, P8.0=>RS
    
            DelayMs(100);  // OR USING  __delay_cycles()
            LCD_init();
            DelayMs(50);
    
                 // ****************************** Just to show "1" on the bottom line of display!*************
           LCD_cmd(0xc0);
           LCD_dat(49);
    
    // ******************************Flash part of the code *********** Show "1" on the top line of LCD LCD_cmd(0x80); erase_flash(0x0FFB1); write_flash(1,0x0FFB1); read_flash(0x0FFB1); } void erase_flash(unsigned short address) { char *Flash_ptr; Flash_ptr = (char*) address; FCTL1 = FWKEY + ERASE; FCTL3 = FWKEY; *Flash_ptr = 0; // FCTL3 = FWKEY + LOCK; } void write_flash (char value,unsigned short address) { char *Flash_ptr; Flash_ptr = (char*) address; FCTL1 = FWKEY + ERASE; FCTL3 = FWKEY; FCTL1 = FWKEY + WRT; *Flash_ptr = value; FCTL1 = FWKEY; FCTL3 = FWKEY + LOCK; } unsigned short read_flash (unsigned short address) { char value; char *Flash_ptr; Flash_ptr = (char*) address; value = *Flash_ptr; LCD_dat(value + 48) ; return (value); } void LCD_init(void) { LCD_cmd(0x38); // 8-bit mode 5*8 dots ==> Page 17 of the LCD datasheet: Function Set LCD_cmd(0x0C); // Blinking display ==> Page 16 of the LCD datasheet: Display ON/OFF Control LCD_cmd(0x06); // Blinking cursor ==> Page 15 of NMTC-S0802XRGHS: Entry Mode Set LCD_cmd(0x01); // Clear Display ==> Page 15 of the LCD } void DelayMs(int Ms) { volatile int i; // To counteract "optimization" while(Ms>0) { for(i=0;i<100;i++); Ms--; } } void LCD_cmd(unsigned char cmd) { P8OUT &= 0xF8; // EN=0,RW=0,RS=0 P7OUT = cmd; P8OUT |= 0x04; // En = 1; P7DIR = 0xFF; // out P7 __delay_cycles(2); //Insurance P8OUT &= 0xFB; // En = 0; P7DIR = 0; // float P7 DelayMs(3); } void LCD_dat(unsigned char byte) { P8OUT &= 0xF8; // EN=0,RW=0,RS=0 P8OUT |= 0x01; // change to RS=1 P7DIR = 0xFF; // P7 out P7OUT = byte; P8OUT |= 0x04; // EN=1 __delay_cycles(2); // Insurance P8OUT &= 0xFB; // EN=0 P7DIR = 0; // P7 float DelayMs(3); }

     

  • CaEngineer said:
    erase_flash(0x0FFB1);

    Well, erasing 0xFFB1 means erasing the whole segment 0xFE00 to 0xFFFF (flash can't be erased byte-wise, only a whole segment at a time). Which also erases the interrupt vector table, including the reset vector that points to the start of your program.

**Attention** This is a public forum