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.

USB Interrupt conflict when erasing flash Info segment?

Guru 15580 points
Other Parts Discussed in Thread: MSP430F5515, MSP430F5510, MSP430F5514

CCS v5.3

MSP430F5515

I am trying to save modified configuration parameters in an INFO segment of flash while my app is running. It appears that you must disable global interrupts during the flash erase cycle (according to the example code flashwrite_01 and flashwrite_02). However, when I _disable_interrupts() my USB connection crashes. I have tried USB_suspend() and USB_resume before and after the flash erase cycle, but it disconnects the USB connection (not acceptable). I have tried all combinations and variations of disabling and enabling interrupts to no avail.

Can someone suggest a way to temporarily suspend USB activity while erasing an info segment in flash?

Here is my code:

void SaveFlashParameters()
{
config_block_t * Flash_ptr; // Initialize Flash pointer
Flash_ptr = (config_block_t *) ".infoD";

USB_suspend(); //We must suspend the USB process since disabling interrupts during flash erase interferes with USB event interrupts

WORD bGIE = __get_SR_register() &GIE; //save interrupt status
__disable_interrupt(); // 5xx Workaround: Disable global
                                        // interrupt while erasing.
FCTL3 = FWKEY; // Clear Lock bit
FCTL1 = FWKEY+ERASE; // Set Erase bit
*(unsigned int *)Flash_ptr = 0; // Dummy write to erase Flash seg

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

*Flash_ptr = config_block; //write config_block to flash

FCTL1 = FWKEY; // Clear WRT bit
FCTL3 = FWKEY+LOCK; // Set LOCK bit
__bis_SR_register(bGIE); //restore interrupt status
// __enable_interrupt();

USB_resume();
}

  • Of course, interrupts must be disabled if flash controller is modifying some memory segments overlapped with interrupts code. But in any other case (action on info segment) don't see the reason for disabling interrupts. Don't understand why it is used in "MSP430F550x_flashwrite_01.c ", in "MSP430F550x_flashwrite_02.c" there is no interrupts disabling.

    Don't see any reason why USB connection is broken (if there is no traffic) in case of disabled interrupts.

    For example, in my SBW+ programmer, PC send 5.75 KB to MSP430F5xx over USB at once. After first received packet (64 bytes) MSP4305xx starting to prepare target devices for flashing. When USB transfer is complete, interrupts are disabled (because don't want to have timing disalignment during flashing target devices). There is no any traffic on USB, and there is no crashing. When flashing is finished interrupts are enabled again, and MSP4305xx send ack to PC that is ready for new command. 

  • Zrno,

    Thanks for the feedback.

    zrno soli said:
    But in any other case (action on info segment) don't see the reason for disabling interrupts

    I'm not sure but it looks like this is a workaround for some sort of F5xx issue.

    zrno soli said:
    in "MSP430F550x_flashwrite_02.c" there is no interrupts disabling.

    In the flashwrite_02 code sample I have, there *is* a disable interrupt (see highlighted code below).

    int main(void)
    {
    unsigned long * Flash_ptrD; // Initialize Flash pointer Seg D
    unsigned long value;
    WDTCTL = WDTPW+WDTHOLD; // Stop WDT

    Flash_ptrD = (unsigned long *) 0x1800; // Initialize Flash pointer
    value = 0x12345678; // Initialize Value
    __disable_interrupt(); // 5xx Workaround: Disable global
    // interrupt while erasing. Re-Enable
    // GIE if needed
    FCTL3 = FWKEY; // Clear Lock bit
    FCTL1 = FWKEY+ERASE; // Set Erase bit
    *(unsigned int *)Flash_ptrD = 0; // Dummy write to erase Flash seg
    FCTL1 = FWKEY+BLKWRT; // Enable long-word write
    *(unsigned long *)Flash_ptrD = value; // Write to Flash
    FCTL1 = FWKEY; // Clear WRT bit
    FCTL3 = FWKEY+LOCK; // Set LOCK bit
    while(1); // Loop forever, SET BREAKPOINT HERE
    }

    zrno soli said:
    Don't see any reason why USB connection is broken (if there is no traffic) in case of disabled interrupts.

    My post wasn't clear on this. If I disable interrupts, the re-enable them after the flash erase/write, the USB link crashes. If I use Suspend/Resume, the USB disconnects, then reconnects, which in my application requires the user to acknowledge the reconnected USB port. What I would like is a way to simply pause USB activity during flash erase, then continue USB activity transparent to the user.

    zrno soli said:
    There is no any traffic on USB, and there is no crashing.

    Unfortunately, my application continues to receive polling requests from the host PC during the flash erase/write sequence. I don't have an easy way to prevent this.

    Thanks again for your thoughts.

  • I am referring to slac394c MSP430F550x MSP430F5510 C Code Examples (Rev. C) and slac300d MSP430F552x C Examples (IAR and CCSv4) (Rev. D)

    In MSP430F55xx_flashwrite_01.c there are 2 function, write_SegC and copy_C2D. You only want to update value in info segment, and this is done by write_SegC. Function for copying segment C to D, copy_C2D have interrupt disable workaround, but you don't need this function.

    In MSP430F55xx_flashwrite_02.c double word write example, there is no interrupt disable workaround.

    In MSP430F55xx_flashwrite_03.c different segment/bank example, there is no interrupt disable workaround.

  • zrno,

    zrno soli said:
    am referring to slac394c MSP430F550x MSP430F5510 C Code Examples (Rev. C)

    I couldn't find that file on line. Do you have a link?

    I did find this one (slac166), which is where my code samples came from:

    http://www.ti.com/general/docs/lit/getliterature.tsp?baseLiteratureNumber=slac166&fileType=zip

    FYI, I got rid of _disable_interrupt() and still have the USB crash problem. I guess I need to look elsewhere.

  • http://www.ti.com/litv/zip/slac394c

    http://www.ti.com/litv/zip/slac300f

    Just remove all code used for update info segment, too be sure that problem is somewhere else.

  • zrno,

    Well, I had an error in my code (Flash_ptr = (config_block_t *) ".infoD";) that was apparently causing the problem. I got rid of the _disable_interrupt() and now everything works as expected. No crashing USB!!

    Thanks again for your thoughts and help.


  • zrno soli said:
    But in any other case (action on info segment) don't see the reason for disabling interrupts.

    If the flash controller is busy erasing any flash segment or writing to any flash segment, it cannot read any other flash cell and report it to the processor. Instead, the processor reads 0x3fff, which is the JMP $ instruction. Unfortunately, when an interrupt occurs, the processor fetches 0x3ff as the ISR address and jumps into the void. So during any write/erase operation, interrupts have to be disabled.
    An exception is the 5x/6x family, where it is possible to read from flash while a different flash block (64k) is mass-erased. However, on some MSPs this still doesn't work and is listed as erratum.

    zrno soli said:
    Don't see any reason why USB connection is broken (if there is no traffic) in case of disabled interrupts.

    Indeed, unless there is an interrupt overflow during the flash write sequence, that means, the same interrupt happens twice, so the first is discarded, like receiving two data blocks, there is no reason why delaying the ISR execution would crash the MSP. If the MSP were inside a different ISR, interrupts would be similarly blocked (no interrupt, even with higher priority, can interrupt the execution of an ISR - unless you manually and explicitly enable interrupt nesting and exactly know what you're doing (not recommended! really!)

  • Hi,

    Sorry to interrupt but I still have some confusion with the interrupts during flash programming.
    We are using MSP430F5514 and we need to program a small data (only "1" byte) into the Flash memory.

    The problem is, we have a timer running and we may get timer interrupt while the flash is programmed(1 byte).
    The program is in main memory and we want to program INFO memory.

    From the user guide and the comments above I understood that during erase or write operation from flash,
    the CPU will loop('JMP $') until the flash operation is finished.
    But it is also written that in case of "Bank erase", the CPU will fetch Valid instruction
    From any other flash location. This may be the case of Mike's program working without _disable_interrupt().
    Can I assume the INFO memory is a different BANK from Main?

    I would like to reconfirm, do we have to disable the interrupt every time
    when we need to program the flash (Info memory)?

    Regards

  • Simply put: while busy erasing a segment or writing, the flash controller will return 0x3FFF to any read request. In case of an instruction fetch, this is no problem, since 0x3FFF is the JMP $ instruction (and makes the CPU jump on place), but in case of an ISR vector fetch, this will retrieve 0x3FFF as the ISR address, and as soon as the flash write is done, the CPU will execute an ISR at 0x3FFF (and there is of course none).

    The only exception is (and only on some MSPs) if you erase a bank (64k) which is not the bank containing the interrupt vectors (and, to be useful, not the bank containing your ISRs). In this case, interrupts don’t need to be disabled during the bank erase (but during the following write, they have to).
    You can disable and re-enable (restore) the interrupt state for every byte you write. This makes the writing slower but reduces interrupt latency to a minimum. It does not work for block write mode, as during block write, the flash read is disabled all the time.
    However, your timer interrupts are not lost while interrupts are disabled. They are still pending, yet not executed as long as GIE is clear. The only problems are the prolonged reaction time and possible overruns if you stay with disabled interrupts too long.
    Which for example will be the case for a flash segment erase (several milliseconds) and a 1ms timer interrupt.

  • Thank you so much..

    Regards.

  • I know you thoroughly answered this topic, but I just wanted to be completely clear on this one thing:

    Does this apply to information flash too? I thought it was only necessary to disable interrupts when writing/erasing the main flash.

  • Any flash. Info memory is part of flash block 0, regarding the internal handling.

    One additional note: clearing GIE won’t prevent an NMI, so if you enabled any NMI source (such as OFIE), you’ll need to clear all these IE bits before the flash write.

  • Okay that makes sense, thank you!

**Attention** This is a public forum