First, as Sergey already stated: the FWKEY is not to be ORed into FCTL2, it has
to REPLACE the upper 8 bit of FCTL2. If you want to keep the lower bits and
just add flags, the correct solution would be
FCTL2= (FCTL2&0xff) | FWKEY | ...
The watchdog timer has to be treated in a similar way.
About the debugger, you should be aware what's going on while flashing:
While any flash action is active, the flash memory will respond to _every_
memory read access with a "JMP on self" opcode, a jump to its own address.
This way, the processor is still fetching and executing commands, but will
effectively do nothing, not even incrementing the program counter.
After the flash operation finished, the processor will get the real opcode at
this location and continue as if nothing happened. Even the timers did proceed
in the meantime.
BUT
- every attempt to fetch any flash data will result in this bogus opcode, no
matter whether the processor is fetching an opcode, the debugger is reading or
the processor wants to get an interrupt vector.
- due to the latter, every interrupt occurring while a flash operation is in
progress will lead to the processor fetching the 'jump on self' opcode instead
of the real interrupt vector, trying to ececute code somewhere in the
depths of unknown and probably uninitialized memory.
If you're executing your flash functions from withing processor RAM, the
processor will continue executing normally (this allows faster block writes and
is used by most programmers for JTAG flashing),
BUT
- any access to a ROM-located constant will return bogus data
- any interrupt wil be as fatal as described above
- any call of code in FLASH will effectively stop the processor until the
operation completed
Also keep in mind that a flash operation takes several milliseconds, so
probably your timers have overrun, you missed several
capture/compare-interrupts, your UARTs have missed several bytes and so on.
Unfortunately, these problems arise no matter whether you're flashing/erasing
main or configuration memory. Even if config mem has a different blocksize and
address, the controller makes no difference.
This is unlike the AVR processors, where you'll have a section of FLASH which
can still be read while writing to the other section. Not to mention the EEPROM
on AVR or PIC processors, which can be written to
without blocking any interrupts.
JMGross
Original Message:
--------------------------
Hi All,
Not exactly a mspgcc question, but hoping someone on the list can help.
I am trying to write some functions to store away data in Flash using the
msp430 ISP sequence.
Following the datasheet, I have come up with the following:
void FlashErase_SegmentD(void) {
FCTL2 |= FWKEY + FSSEL1 + FN5; // ensure 257khz < SMCLK/32 < 476khz TODO
check this!
FCTL3 |= FWKEY; // Clear lock
FCTL1 |= FWKEY + ERASE; // Enable segment erase
*((uint16_t*)0x1002) = 0; // Dummy write to a word in flash segment D
FCTL3 |= FWKEY + LOCK; // Done, set lock
}
void FlashWrite_SegmentD(uint16_t* address, uint16_t data ) {
FCTL2 |= FWKEY + FSSEL1 + FN5; // ensure 257khz < SMCLK/32 < 476khz TODO
check this!
FCTL3 |= FWKEY; // Clear lock
FCTL1 |= FWKEY + WRT; // Enable write
*address = data; // Write word.
FCTL3 |= FWKEY + LOCK; // Done, set lock
}
What I am seeing is the MSP430 hang on either function ..
I am using the internal DCO at a calibrated 16Mhz. I know I am slightly out
of spec using a 32 divider (500Khz), but it should still work.
I am using mspgcc-gdb from within eclipse while testing this .. maybe the
stopping of the CPU during flash programming is upsetting the debugger?
I will try running without the debugger, but in the meantime would like some
feedback ..
Many Thanks,
Bernie