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.

MSP430FG477 writing to internal flash only succeeds if I erased the whole segment immediately before

Hello everybody,

I have the problem that I cannot update the content in my internal flash without erasing the whole segment before the write operation. This requires me to store the whole segment beforehand, updating the content in the buffer and then writing back the whole segment.

The segment I am writing to is in information memory defined by (I typecast it to a pointer later):

const static uint16_t FLASH_SEGMENT_1 =         0x1000;

so it should not be a problem with LOCKA.

The functions that I am using are:

// inits the flash
void Internal_Flash::init()
{
	FCTL2 = FWKEY + FSSEL0 + FN1;// + FN3; // FLASH CLK= MCLK/3 = 1200/3 = 400 KHZ : MSP430AFE233
}

// erases a flash segment
void Internal_Flash::erase_sector(uint8_t* const address)
{
	FCTL3 = FWKEY;                      // Clear Lock bit
	FCTL1 = FWKEY + ERASE;              // Set Erase bit
	*address = 0;                // Dummy write to erase Flash seg
	FCTL1 = FWKEY;                            // Clear WRT bit
	FCTL3 = FWKEY + LOCK;             // Set LOCK bit
}

// writes bytes to flash
void Internal_Flash::write(uint8_t* address, const uint8_t* buf, const uint8_t len)
{
//	_DINT();
	// assert that buffer is not too large
	assert(len <= FLASH_SEGMENT_SIZE);

	FCTL3 = FWKEY;                      // Clear Lock bit 
	FCTL1 = FWKEY + WRT;                      // Set WRT bit for write operation
	for (uint8_t i = 0; i < len; i++)
	{
		*address++ = *buf++;          		// Write value to flash
	}

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

Calling erase_sector() always succeeds, but the write() command only updates the flash if erase_sector() was called before, e.g.:

            // erase flash segment
            int_flash->erase_sector((uint8_t*)Internal_Flash::FLASH_SEGMENT_1);

            // write device name
            int_flash->write((uint8_t*)Internal_Flash::FLASH_SEGMENT_1, "TEST", 4);

I already tried to disable enable interrupts while calling write() and I switched the clock timing for the flash, but nothin seems to work.


Thank you a lot for any help!

Stefan