Other Parts Discussed in Thread: MSPWARE
Hello,
We are currently experiencing some field failures on our product which we have narrowed down to some sort of Flash memory corruption on our MSP430G2353.
We have found evidence from a few select examples of failures where portions of our information memory segment have been erased or corrupted, and were hoping to get to the root of why this is happening so we can prevent the issue from occurring entirely if possible. We’re not sure if the issue (which doesn’t seem to be widespread) is related to location/environment, or a by-product of something that we are doing in our firmware.
A few beginning questions:
- Are there any known environmental factors (static shock, electrical storms, humidity, etc) that can cause Flash corruption/erasure?
- Is there a cutoff voltage where the flash could be corrupted? Would this only happen if the low voltage event happened during a flash write/erase?
- We are operating at 8MHz and the “Safe Operating Area” graph in Figure 1 of the product datasheet seems to show the cutoff of flash writing at 2.2V, but this graph also seems to show that program execution would not occur under those same conditions.
- Could we get specificity on what happens if our core voltage slides below the suggested supply voltage for program execution?
- Figure 12 of the DS seems to say that BOR doesn’t happen till 1.35V… what happens if we are at 2.0V and attempt a flash write?
- Is there a difference in voltage required for flash erase and flash write?
Below I have copied our base code for flash erase and flash writes. Our basic operation is to read the flash segment into RAM, modify the RAM buffer with our desired contents, erase the flash, then reprogram the entire segment with our desired contents, one 16-bit word at a time starting at the lowest address. Our MCLK is at 8MHz, SMCLK = MCLK/8 = 1MHz, flash timing generator = MCLK/2 = 500kHz.
Is there anything in that process or the code below that should be changed?
/****************************************************************************** * EraseFlash - Erase a segment of flash in the MSP430 ******************************************************************************/ void EraseFlash(unsigned int address) { __disable_interrupt(); // Disable interrupts. This is important, otherwise, // a flash operation in progress while interrupt may // crash the system. HOLD_WATCHDOG_TIMER(); // Disable watchdog timer while(FCTL3 & BUSY); // Check if Flash being used FCTL2 = FWKEY | FSSEL_2 | FN0; // Clk = SMCLK/2 FCTL3 = FWKEY; // Clear Lock bit FCTL1 = FWKEY | ERASE; // Set Erase bit *((unsigned int*)address) = 0; // Dummy write to erase Flash segment while(FCTL3 & BUSY); // Check if Flash being used FCTL1 = FWKEY; // Clear Erase bit FCTL3 = FWKEY | LOCK; // Set LOCK bit RESUME_WATCHDOG_TIMER(); __enable_interrupt(); } /****************************************************************************** * WriteFlash - Write a segment of flash in the MSP430 ******************************************************************************/ void WriteFlash(unsigned int address, unsigned int *flash_buffer) { unsigned char i; unsigned int* ptr_to_addr = (unsigned int*) address; __disable_interrupt(); // Disable interrupts. HOLD_WATCHDOG_TIMER(); // Disable watchdog timer while(FCTL3 & BUSY); // Check if Flash being used FCTL2 = FWKEY | FSSEL_2 | FN0; // Clk = SMCLK/2 FCTL3 = FWKEY; // Clear Lock bit FCTL1 = FWKEY | WRT; // Set WRT bits for write operation for (i = 0; i < (FLASH_INFO_SEGMENT_SIZE/2); i++) // Word write is faster than byte write { *ptr_to_addr = *flash_buffer; // copy value to flash ptr_to_addr++; flash_buffer++; while(FCTL3 & BUSY); // Check if word write is done } FCTL1 = FWKEY; // Clear WRT bit while(FCTL3 & BUSY); // Check if Flash being used FCTL3 = FWKEY | LOCK; // Set LOCK bit RESUME_WATCHDOG_TIMER(); __enable_interrupt(); }
One more thing of note is a sample of the data that we found as being corrupt, which is below.
The curious thing to note on this is although we are doing word-wise writes of 16-bit values, our data showed the low byte of one value (at 0x1044) intact, while the high byte of the same word, and multiple following bytes, all seemingly erased to 0xFF. Is there any reason this should be? Does the compiler break down these writes into single byte writes? Or is this indicative of a failed/interrupted flash write?
Segment D: 1000: xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx 1010: xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx 1020: xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx 1030: xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx Segment C: 1040: xx xx xx xx 7C FF FF FF FF FF FF FF xx xx xx xx 1050: xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx 1060: xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx 1070: xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx Segment B: 1080: xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx 1090: xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx 10A0: xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx 10B0: xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx
Regards,
Tyler Witt