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.

Writing Information Memory (Segment A)

Other Parts Discussed in Thread: MSP430F169

This is a code from TI example for CCE:

 

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

  Flash_ptr = (char *) 0x1080;              // Initialize Flash pointer
  FCTL1 = FWKEY + ERASE;                    // Set Erase bit
  FCTL3 = FWKEY;                            // Clear Lock bit
  *Flash_ptr = 0;                           // Dummy write to erase Flash segment

  FCTL1 = FWKEY + WRT;                      // Set WRT bit for write operation

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

  FCTL1 = FWKEY;                            // Clear WRT bit
  FCTL3 = FWKEY + LOCK;                     // Set LOCK bit
}

 

can you tell me, why the pointer is a char?

that means it can contain only half of the address, and here:   Flash_ptr = (char *) 0x1080;

They put the 0x80 to the pointer, so how it works??

 

and the variable i can be easily unsigned char - they don't need 2 bytes for it.

 

Greetings

  • Hi,

    from which example did you take the code? From my point of view this is a typo? The pointer must be of type int and the variable is of type (unsigned) char.

    So, it should look like:

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

      Flash_ptr = (int *) 0x1080;              // Initialize Flash pointer
      FCTL1 = FWKEY + ERASE;                    // Set Erase bit
      FCTL3 = FWKEY;                            // Clear Lock bit
      *Flash_ptr = 0;                           // Dummy write to erase Flash segment

      FCTL1 = FWKEY + WRT;                      // Set WRT bit for write operation

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

      FCTL1 = FWKEY;                            // Clear WRT bit
      FCTL3 = FWKEY + LOCK;                     // Set LOCK bit
    }

    Be carefull when using SegmentA since the calibration constants were stored there! Have a look at the post http://e2e.ti.com/forums/p/6402/24510.aspx#24510 ; I've posted an example there which can be used for accessing all INFO memory segments. Because you use a variable as argument the function will access (erase) the memory segment in which this variable is stored.

    Rgds
    G**buster

  • I have downloaded the CCE for MSP430F169.

    I think the calibration data is not in 1xx family, so I can freely use this segment.

    Thanks for answer. I'll try it at the evening (the Europe one :))

  • The address for InfoA Flash for F169 is from 0x1080 to 0x10FF. It consists of 128 bytes.

    I do not know c, much less about CCE. But I think the pointer in the original posting is okay. The pointer is an address; itself consists of 2 bytes. But it is meant to point to a single byte.

    It is okay to change the pointer to point to an int too. But then you should write 64 times, not 128 times.

    I am not sure that the rest of the code is correct. I think you cannot erase a segment and write 128 bytes (or 64 int) in one FCTL operation. See the F1xx Users Guide.

  • code is fine, the ptr type and value need to be chars

     

    the statement  char  *Flash_ptr;   defines a pointer to a char

     Flash_ptr = (char *) 0x1080; ,  sets an address for a char pointer, the pointer itself is an int

     

     

     

     

     

  • You are right. The pointer is not char, it points to char. I have to start using pointers to get used to them!

     

    I have read the documentation carefully and It looks like you can do more than one write with one FCTL setting, but it looks like with writing 64 bytes one by one you exceed the programming time.

    And it also looks like programming 64 bytes using word programming does not exceed this time. Anyway I would rather use block write for more bytes, and use normal write operation for writing just couple of bytes.

    Thank you all for answers.

     

    Another question:

    How does the pointer look like is it not just the address, it is shifted or something?

    Why they cast pointer in this:

    Flash_ptr = (char *) 0x1080;              // Initialize Flash pointer

    the normal:

    Flash_ptr = 0x1080;

    will not work?

    how exactly looks Flash_ptr after this operation?

     

     

  • To c-compiler:(a) Flash_ptr is a pointer to char, (b) 0x1080 is an int, (c) you cannot assign an int to a pointer to char, but (d) you can cast an int into a pointer to char.

    After executing: Flash_ptr = (char *) 0x1080; Flash_ptr will have the value 0x1080.

    All these are rules in the c language. (I cannot stand the heat, thus I stayed out of the kitchen.)

  • joseph radomski said:

    code is fine, the ptr type and value need to be chars

    the statement char  *Flash_ptr;   defines a pointer to a char

     Flash_ptr = (char *) 0x1080; ,  sets an address for a char pointer, the pointer itself is an it

    The code may be fine, but I do not think it will do what the OP wanted to accomplish.

  • Dear Friends,

    The sample codes still cannot be used to change the Segment A of the Information Memory.  The post,  http://e2e.ti.com/forums/p/6402/24510.aspx#24510,  was removed or you may give the wrong link string. Does anyone know how to change the data of the Segment A?  Thank you.

    Sunglin.

  • Segment A is specially protected and the users guitde tells you what steps to perform to unprotect it before doing the write.

    BTW: this protection isn't on all MSPs.

  • Well i think code given above is not working because you are fatching your code from flash memory and code given above is used when you are fetching your code from ram,

    This code can not be used when you are fetching code from your flash memory. For this you have first erase the the segment and then you have to write the info memory byte by byte.

    I am attching my code file for better understanding. hope, you will find it useful

    #include"headers.h"
    
    /*
     * app_flash.c
     *
     *  Created on: 05-Dec-2013
     *      Author: Rajni Bhojani
     */
    
    /*
     * 		WRITE MODE
     * 			  BLKWRT   WRT
     * 				0		1			BYTE/WORD WRITE
     * 				1		1			BLOCK WRITE
     *
     *		ERASE FLASH MEMORY
     *			MERAS	ERASE
     *				0		1			SEGMENT ERASE
     *				1		0			MASS ERASE ALL MAIN MEMORY SEGMENT
     *				1		1			ERASE ALL FLASH MEMORY
     *
     *		IN ERASE MODE ANY WRITE CAN ERASE WHOLE SEGEMNT OR AS PER SELECTION.
     *		WITHOUT ANY CONFIGURATION ANY WRITE OPERATION IGNORED
     *
     *		As per data sheet flash controller Clock Frequency should be 257-476 KHz.
     *
     */
    
    #define BLOCK_SIZE					64
    #define SEGMENT_A_START_ADDRESS		0x1000
    #define SEGMENT_B_START_ADDRESS		0x1080
    #define SEGMENT_A_SIZE				0X80
    #define SEGMENT_B_SIZE				0X80
    
    #define FLW_KEY						0xA500				// key that needed at every write cycle
    #define FL_MCLK						0x0040				// MCLK for flash controller
    #define FL_DIV20					0x0013				// clock is devided by value + 1
    
    #define SET_LOCK					FCTL3 = FLW_KEY + LOCK				// Lock the any write or erasing operation(ignored) to flash.
    #define CLEAR_LOCK					FCTL3 = FLW_KEY						// Clear the lock to enable write and erasing.
    
    #define WRITE_BYTE_MODE				FCTL1 = FLW_KEY + WRT				// set write byte or word mode
    #define WRITE_BLOCK_MODE			FCTL1 = FLW_KEY + BLKWRT + WRT		// set block write mode
    #define CLEAR_WRITEBIT				FCTL1 = FLW_KEY
    
    #define SEGMENT_ERASE				FCTL1 = FLW_KEY +ERASE				// Set segment erase mode
    #define MAINMEMORY_ERASE			FCTL1 = FLW_KEY +MERAS				// Set main memory erase mode
    #define FLASH_ERASE					FCTL1 = ERASE + MERAS				// Set flash erase mode
    
    #define WAIT_FORLOCK				while((FCTL3 & LOCK))
    
    #define WAIT_FORNEXTBYTE			while(!(FCTL3 & WAIT))				// During block write cycle
    																		// After every byte write we have to wait for this byte set
    																		// This says that i am ready for nex byte
    
    /************************************************************************************************
     * 		FUNCTION		:	InitFlashController
     * 		DISCRIPTION		:	INIT THE FLASH CONTROLLER TO CONTROLL THE OPERATION (WRITE/ERASE).
     ************************************************************************************************
     */
    void InitFlashController() {
    
    	FCTL2 = FLW_KEY + FL_MCLK + FL_DIV20;						// Clock will be around 400 KHz
    																// MCLK is selected
    }
    
    
    /************************************************************************************************
     * 		FUNCTION		:	Flash_WriteByte
     * 		DISCRIPTION		:	This can modify the byte in flash memory
     *
     * 		NOTE			:	CAN ONLY DO THE BIT 1 VALUE TO 0 VALUE IF YOU WNT TO DO THE REVERSE
     * 							ONLY WAY TO ERASE THE SEGMENT AND REWRITE THE SEGMENT
     * 							EXAMPLE : 0XFF CAN BE TRANSFERED TO 0XAA, OR ANY OTHER VALUE BUT
     * 									  0X00 CAN NOT BE TRANSFERED TO ANY VALUE
     ************************************************************************************************
     */
    void Flash_WriteByte(unsigned int address, unsigned char Write_Data) {
    
    	__disable_interrupt();
    
    	WRITE_BYTE_MODE;
    	CLEAR_LOCK;
    	*((unsigned char*)address) = Write_Data;
    
    	SET_LOCK;
    	__enable_interrupt();
    }
    
    
    /************************************************************************************************
     * 		FUNCTION		:	Flash_WriteBlock
     * 		DISCRIPTION		:	TO MODIFY VALUE OF THE ENTIRE BLOCK
     ************************************************************************************************
     */
    void Flash_WriteBlock(unsigned int address, unsigned char* Write_Data) {
    
    	unsigned char i;
    
    	__disable_interrupt();
    
    	WRITE_BLOCK_MODE;
    	CLEAR_LOCK;
    
    	for(i=BLOCK_SIZE; i; i--) {
    		Flash_WriteByte(address++, *(Write_Data++));
    	}
    
    	SET_LOCK;
    	__enable_interrupt();
    }
    
    
    /************************************************************************************************
     * 		FUNCTION		:	Erase_Segment
     * 		DISCRIPTION		:	TO ERASE SEGMENT YOU HAVE TO PASS THE ANY ADDRESS FALL WITHIN THAT
     * 							segment RANGE
     ************************************************************************************************
     */
    void Erase_Segment(unsigned int segment_address) {
    
    	__disable_interrupt();
    
    	SEGMENT_ERASE;
    	CLEAR_LOCK;
    
    	*((unsigned char*)segment_address) = 0;		// will erase segment
    
    	SET_LOCK;
    }
    
    
    /************************************************************************************************
     * 		FUNCTION		:	ModifyInfoASegment
     * 		DISCRIPTION		:	TO MODIFY THE SEGMENT A
     ************************************************************************************************
     */
    void ModifyInfoASegment(unsigned char* Info_MemoryBuffer) {
    
    	Erase_Segment(SEGMENT_A_START_ADDRESS);
    
    	Flash_WriteBlock(SEGMENT_A_START_ADDRESS, Info_MemoryBuffer);
    	Flash_WriteBlock(SEGMENT_A_START_ADDRESS+BLOCK_SIZE, Info_MemoryBuffer+BLOCK_SIZE);
    }
    
    
    /************************************************************************************************
     * 		FUNCTION		:	ModifyInfoBSegment
     * 		DISCRIPTION		:	TO MODIFY THE SEGMENT B
     ************************************************************************************************
     */
    void ModifyInfoBSegment(unsigned char *Info_MemoryBuffer) {
    
    	Erase_Segment(SEGMENT_B_START_ADDRESS);
    
    	Flash_WriteBlock(SEGMENT_B_START_ADDRESS, Info_MemoryBuffer);
    	Flash_WriteBlock(SEGMENT_B_START_ADDRESS+BLOCK_SIZE, Info_MemoryBuffer+BLOCK_SIZE);
    }
    
    
    /************************************************************************************************
     * 		FUNCTION		:	ModifyInfoBSegment
     * 		DISCRIPTION		:	TO MODIFY INFO SEGMENT
     ************************************************************************************************
     */
    void WriteInfoSegment(unsigned char* Info_MemoryBuffer) {
    
    	ModifyInfoASegment(Info_MemoryBuffer);
    	ModifyInfoBSegment(Info_MemoryBuffer + SEGMENT_A_SIZE);
    }
    
    
    
    
    
    

  • Rajnikant bhojani said:
    Well i think code given above is not working because you are fatching your code from flash memory and code given above is used when you are fetching your code from ram,

    You can write to flash through code that resides in flash too. That is no problem. It's just that you cannot (obviously) write to the flash segment in which your flash write code resides (as you need to erase it first and this would also erase your writing code). And you cannot use block write mode, as in this mode, flash is not accessible until you are done writing - and you cannot complete writing if the CPU cannot proceed because it cannot fetch the next instruction from flash.

    And writing to flash from a flash-based function is a bit slower (because you cannot use block write mode). However, there is no general problem writing to info memory form a function that executes in flash.

  • Jens-Michael Gross said:

    Well i think code given above is not working because you are fatching your code from flash memory and code given above is used when you are fetching your code from ram,

    You can write to flash through code that resides in flash too. That is no problem. It's just that you cannot (obviously) write to the flash segment in which your flash write code resides (as you need to erase it first and this would also erase your writing code). And you cannot use block write mode, as in this mode, flash is not accessible until you are done writing - and you cannot complete writing if the CPU cannot proceed because it cannot fetch the next instruction from flash.

    And writing to flash from a flash-based function is a bit slower (because you cannot use block write mode). However, there is no general problem writing to info memory form a function that executes in flash.

    [/quote]

    Thanks for your consideration through the code I have made some mistake. Still it gives true output because of block write will be over written by byte write mode. I have updated the file and attaching it again and thanks once again jeans-micheal.0844.Flash_Memory.docx

**Attention** This is a public forum