I have a custom bootloader communicating with the host using I2C and running in FC00-FFFF address space. I2C slave is interrupt driven. To program flash, an I2C command is send to erase the application space F800-FBFF. Before executing ERASE command the code verifies that the application space has non-0xFFFF words in it. If non-0xFFFF word is found, the sector is erased and the following sector is checked for non-0xFFF words. Since erasing is executed from ISR, I2C bus is released after the flash is erased thus preventing the host from sending the next command.
After the flash is erased and USIIFG flag is cleared releasing I2C bus, the host issues commands to program flash, 8 word (16 bytes) in one I2C transfer. After the last byte of the command is received and before the ACk bit is sent back to the master, the flash is programmed. After programming I2C bus is released, ready to receive the next segment of data.
What I have noticed is during I2C transfer the micro appears to jump to a reset vector around the time of a USI interrupt.
In the diagram above, P1.4 and P1.5 are toggled at the same inside an USI ISR when start condition is detected. P1.5 by itself is toggled as the first instruction after reset inside _c_int00() before the stack pointer is loaded. P1.4 is toggled as the first instruction inside my USI ISR and it is also toggled when the bits are successfully processed and USI is ready for the next transfer. In the middle of the diagram you can see P1.5 toggle by itself when indicates that my MCU started executing from a reset vector. About 0.1ms before that you can see line P1.4 toggle twice, first time when the USI isr begins to execute at the second time when the bit counter in USI controller is loaded to receive the next 8 bits. After the 8 bits arrive, no interrupt is generated and I2C bus is not held low. But instead, the MCU starts executing from reset vector. It is important to note that "reset" occurs during I2C transfer long before all 16 bytes of data are received and "flash write" is executed. Some times it occurs when receiving I2C address byte.
However, if MCU is programmed with only my bootloader (application address space 0xF800-FBFF is all 0xFFs), when "erase flash" command is received from the host, erasing does not executed because all bytes are already at 0xFF. After that, all I2C transfers to program flash occur without "resets".
Somehow, erasing flash causes USI interrupts (those interrupts occur much later) to misfire causing MCU to start from a reset vector. However, programming flash does not affect USI interrupts and the appplication is successfully loaded. One average, about 13 I2C transfers are succeed programming 13*16 = 208 bytes before a "restart" occurs resulting in failed I2C transfer (NACK received).
The watchdog is disabled right after SP is initialized. No other interrupts are enabled and NMI interrupt is pointing to a reset trap (infinite loop). What could cause the MCU to execute from a reset vector?
Thanks