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.

Information flash in MSP430G2353

Other Parts Discussed in Thread: MSP430G2353

Hello,

I am trying to store some data in information flash of MSP430G2353 so I started with erasing the flash. I want to leave segment A alone.

Based on some online tutorials and the family guide I wrote this piece of code to do erase and dump the memory:

#define SEGMENT_D_ADDR 0x1000
#define SEGMENT_C_ADDR 0x1040
#define SEGMENT_B_ADDR 0x1080
#define SEGMENT_A_ADDR 0x10C0

void erase_segment(int *Flash_ptr){
  	FCTL3 = FWKEY;
	FCTL2 = FWKEY + FSSEL_1 + 18; //MCLK 8MHz divided by 19 = ~420kHz flash clock
	FCTL1 = FWKEY + ERASE;
	*Flash_ptr=0; //trigger erase
	while (!(FCTL3 & WAIT)){  }//busy wait until erase is complete
	FCTL1 = FWKEY; //lock the flash back
	FCTL1 = FWKEY + LOCK;
}

void dump_segment(int *Flash_ptr){
  uart_putc('\n');
  uart_putc('\r');
  uart_putc('(');
	for (uint8_t i=0;i<64;i++){
	  char num = *Flash_ptr;
	  uart_print_hex_8b(num);
	  Flash_ptr++;
	} 
  uart_putc(')');
}

I use MSPGCC, the MCLK runs at 8MHz from the DCO, UART works fine.

I execute erase_segment(SEGMENT_B_ADDR) (interrupts are disabled) and some time later dump_segment(SEGMENT_B_ADDR).

I get from the UART:

(FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF87FEFFFFFFFFFFFFFFFFFFFFFF100200D7EC7636BF12FEFFFFFFFF017E8877C2)

So the whole segment in only partially erased. Do I need to do more dummy writes? I suspected a broken device so I also tried a different G2353 with similar results.

I'll apreciate your help.

  • In last line of erase_segment function must be FCTL3 = FWKEY + LOCK not  FCTL1 = FWKEY + LOCK

  • just an adddition to what Zrno had said.

    It would be easier if u sub functionize, Flash initialization, Write and Erase. Here is the sample code which I had made some time back.

    #include "ToFlash.h"
    
    void init_Flash( void );
    void Data_Erase_Main(void);
    void write_Flash1(int n, int m,uint8_t wr_index);
    
    //volatile int *P_int;
    int *P_int;
    
    void init_Flash(void)
      {
    		    BCSCTL1 = CALBC1_1MHZ;                    // Set DCO to 1MHz
    		    DCOCTL = CALDCO_1MHZ;
    		    FCTL2 = FWKEY + FSSEL0 + FN1;             // MCLK/3 for Flash Timing Generator
      }
    
    void Data_Erase_Main(void)
      {
    			//int *P_int1;
    			FCTL2 = FWKEY + FSSEL0 + FN1;
    
    			//----------------------------------------------------------------------------------
    			FCTL3 = FWKEY;                    // clr LOCK bit
    			FCTL1 = FWKEY + ERASE;           // activate segment erase mode
    			P_int = (int*)0xC000;
    			*P_int = 0;                      // Dummy write to erase.
    			_NOP();
    
    			//-----------------------------------------------------------------------------------
    			FCTL3 = FWKEY;                   // clr LOCK bit
    			FCTL1 = FWKEY + ERASE;           // activate segment erase mode
    			//seg 2
    			P_int = (int*)0xC200;
    			*P_int = 0;                      // Dummy write to erase.
    			_NOP();
    
    			//-----------------------------------------------------------------------------------
    			FCTL3 = FWKEY;                   // clr LOCK bit
    			FCTL1 = FWKEY + ERASE;           // activate segment erase mode
    			//seg 3
    			P_int = (int*)0xC400;
    			*P_int = 0;                      // Dummy write to erase.
    			_NOP();
    
    			//-----------------------------------------------------------------------------------
    			FCTL3 = FWKEY;                    // clr LOCK bit
    			FCTL1 = FWKEY + ERASE;            // activate segment erase mode
    			//seg 4
    			P_int = (int*)0xC600;
    			*P_int = 0;                       // Dummy write to erase.
    			_NOP();
    
    			//-----------------------------------------------------------------------------------
    			FCTL3 = FWKEY;                    // clr LOCK bit
    			FCTL1 = FWKEY + ERASE;            // activate segment erase mode
    			//seg 5
    			P_int = (int*)0xC800;
    			*P_int = 0;                      // Dummy write to erase.
    			_NOP();
    
    			//-----------------------------------------------------------------------------------
    			FCTL3 = FWKEY;                   // clr LOCK bit
    			FCTL1 = FWKEY + ERASE;           // activate segment erase mode
    			//seg 6
    			P_int = (int*)0xCA00;
    			*P_int = 0;                      // Dummy write to erase.
    			_NOP();
    
      }
    
    
     void write_Flash1(int n, int m, uint8_t wr_index)
     {
     	       	//char *P_int;
    	 switch(wr_index)
    	 {
    	 	 case 1:{	P_int = (int*)0xC000; break;}                     // Intiate pointer to selected location
    	 	 case 2:{	P_int = (int*)0xC200; break;}                    // Intiate pointer to selected location
    	 	 case 3:{	P_int = (int*)0xC400; break;}                    // Intiate pointer to selected location
    	 	 case 4:{	P_int = (int*)0xC600; break;}                    // Intiate pointer to selected location
    	 	 case 5:{	P_int = (int*)0xC800; break;}                    // Intiate pointer to selected location
    	 	 case 6:{	P_int = (int*)0xCA00; break;}                    // Intiate pointer to selected location
    	 }
    				FCTL2 = FWKEY + FSSEL0 + FN1;
    				FCTL3 = FWKEY;                         // CLR LOCK Bit
    
    				P_int = P_int + m;                          // Address pointing to the location of flash where data to be writtten
    
    				FCTL1 = FWKEY + WRT;            // Set WRT bit to enable WRT mode
    
    				*P_int = n;                                     // Put data in to the location
    
    				FCTL1 = FWKEY;
    				FCTL3 = FWKEY + LOCK;
    
     }
    

  • Thanks for the snippets. It turned out to be probably a problem with my UART (or USB<->UART bridge or maybe buffer overrun). I dumped the information area using mspdebug hexout 0x1000 256 dump.hex and got crystal-clear:

    :10100000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF0
    :10101000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0
    :10102000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0
    :10103000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0
    :10104000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB0
    :10105000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0
    :10106000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90
    :10107000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80
    :10108000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70
    :10109000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF60
    :1010A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50
    :1010B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40
    :1010C000878FFE16FFFFFFFFFFFFFFFFFFFFFFFF02
    :1010D000FFFFFFFFFFFFFFFFFFFF10100280000078
    :1010E000D780EC0276033681BF011202FE08FFFFB3
    :1010F000FFFFFFFFFFFF01087E8F888E778DC2867E
    :00000001FF
    

    Then I tried writing 0xCAFE..... to SEGMENT_D_ADDR, SEGMENT_C_ADDR+8 and  SEGMENT_B_ADDR+16. It worked:

    :10100000FECABEBAFFFFFFFFFFFFFFFFFFFFFFFFAC
    :10101000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE0
    :10102000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0
    :10103000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC0
    :10104000FFFFFFFFFFFFFFFFFECABEBAFFFFFFFF6C
    :10105000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA0
    :10106000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF90
    :10107000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF80
    :10108000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF70
    :10109000FECABEBAFFFFFFFFFFFFFFFFFFFFFFFF1C
    :1010A000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF50
    :1010B000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40
    :1010C000878FFE16FFFFFFFFFFFFFFFFFFFFFFFF02
    :1010D000FFFFFFFFFFFFFFFFFFFF10100280000078
    :1010E000D780EC0276033681BF011202FE08FFFFB3
    :1010F000FFFFFFFFFFFF01087E8F888E778DC2867E
    :00000001FF
    

  • Well, the CAFE is there, but where does the BABE come from? I surely like it if a babe is bringing me the coffee, but in this case I’d be less happy if a BABE shows up unexpectedly J