Part Number: MSP430F5659
Other Parts Discussed in Thread: MSP-FET
Hi Everybody,
I am running into a hard to track down a bug that I am wondering if anyone can give any input as to things to check out. Our company has a product that utilizes flash for factory settings. On certain pcb's we are running into unexpected resets. The tricky thing about this bug is that when using the debugger it always fails between the first and second call to __write_extended_byte() however the exact location changes from run to run. Below is the section of the code in both C and the disassembly window that roughly causes the problem. Ultimately I am running out of ways to attempt to debug this and I was hoping somebody may be able to give a good suggestion for how to attack this problem. Thanks for all your feedback!
C Code
void WriteFlashWords(uint32_t xAddress, void *xData, uint16_t bytes)
{
uint16_t *data = (uint16_t *)xData;
uint16_t offset;
uint16_t tmp_SR; // holds a temporary copy of the CPU Status Register
uint16_t bytes_1 = bytes - 1;
if (bytes == 0)
{
return;
}
// There are currently only three areas of Flash that LJ3 devices (loggers, sensors, and testers) should ever be writing to:
// * Settings sectors
// * FOTA image sectors (note: some devices like the loggers will not store FOTA images in internal Flash protected here)
// * All the INFO memories -- see ProductDefs.h for definition
if( ((SETTINGS_SECTORS_START <= xAddress) && (xAddress+bytes < SETTINGS_SECTORS_END)) ||
((FOTA_IMG_SECTORS_START <= xAddress) && (xAddress+bytes < FOTA_IMG_SECTORS_END)) ||
((INFO_MEM_SECTOR_START <= xAddress) && (xAddress+bytes < INFO_MEM_SECTOR_END)) )
{
// Get a copy of the Status Register so we can tell at the end of the function if
// interrupts need to be re-enabled or not...
tmp_SR = __get_register(0x2);
// Make sure interrupts are disabled ...
__disable_interrupt();
FCTL3 = FWKEY; // clear main lock -- doesn't impact LOCKA since writing a 0 to LOCKA doesn't clear it
FCTL1 = FWKEY + WRT; // write mode
// Write an even number of bytes...
for(offset = 0; offset < bytes_1; offset += 2)
{
// Do we need to conditionally check the address where we're going to write?
__write_extended_word(xAddress + offset, data[offset/2]); // write word at a time for better efficiency
}
// Handle the odd byte...
if (bytes > offset)
{
__write_extended_byte(xAddress + offset, data[offset/2]);
}
FCTL1 = FWKEY; // clear erase bit
FCTL3 = FWKEY + LOCK; // (main) lock -- caller should lock LOCKA if needed
// Re-enable interrupts if necessary...
if((tmp_SR & GIE) == GIE)
{
__enable_interrupt();
}
}
else
{
ASSERT(false);
}
}
Disassembly
// Write an even number of bytes...
for(offset = 0; offset < bytes_1; offset += 2)
0b43 CLR.W R11
0c3c JMP 0x10b90
--- flash.c -- 81 ------------------------------------------
{
// Do we need to conditionally check the address where we're going to write?
__write_extended_word(xAddress + offset, data[offset/2]); // write word at a time for better efficiency
0f4a MOV.W R10, R15
0e49 MOV.W R9, R14
0e5b ADD.W R11, R14
0f63 ADC.W R15
0d4b MOV.W R11, R13
5d03 RRUM.W #1, R13
0d5d RLA.W R13
0d57 ADD.W R7, R13
2d4d MOV.W @R13, R13
b113c840 CALLA #0x140c8 <___write_extended_word>
}
2b53 ADD.W #2, R11
0b95 CMP.W R5, R11
f22b JNC 0x10b78
--- flash.c -- 85 ------------------------------------------
// Handle the odd byte...
if (bytes > offset)
0b98 CMP.W R8, R11
0b2c JC 0x10bae
--- flash.c -- 88 ------------------------------------------
{
__write_extended_byte(xAddress + offset, data[offset/2]);
0f4a MOV.W R10, R15
0e49 MOV.W R9, R14
0e5b ADD.W R11, R14
0f63 ADC.W R15
0d4b MOV.W R11, R13
5d03 RRUM.W #1, R13
0d5d RLA.W R13
0d57 ADD.W R7, R13
2d4d MOV.W @R13, R13
b113b440 CALLA #0x140b4 <___write_extended_byte>
--- flash.c -- 90 ------------------------------------------
}
FCTL1 = FWKEY; // clear erase bit
b24000a54001 MOV.W #0xa500, &0x0140
FCTL3 = FWKEY + LOCK; // (main) lock -- caller should lock LOCKA if needed
b24010a54401 MOV.W #0xa510, &0x0144
--- flash.c -- 94 ------------------------------------------
// Re-enable interrupts if necessary...
if((tmp_SR & GIE) == GIE)
36b2 BIT.W #8, R6
0124 JZ 0x10bc0
--- flash.c -- 97 ------------------------------------------
{
__enable_interrupt();
32d2 EINT
063c JMP 0x10bce
--- flash.c -- 99 ------------------------------------------
}
}
else
{
ASSERT(false);
3f401c8c MOV.W #0x8c1c, R15
3e406700 MOV.W #0x0067, R14
b113620a CALLA #0x10a62 <_assert>
7417 POPM.W R4-R11
1001 RETA




