I put constant values in the function instead of using the array and then killed power. Upon restart the constant values had been written to memory. That's how I make that claim.
The reason I asked is because this is no proof by itself the MCU is *fully* operational. It just means it's still able to execute this small piece of code properly enough. We'd need to see the compiled assembly code for the ISR, but using constants instead of reading a[] is likely to yield smaller code, and with no RAM access, so that *could* be one reason it appears to work in this case and not when you read the values from a[]. It could work just because the code is smaller and thus takes less time to execute, it could also be that the RAM content at this point is already borked.
So, just to make clear that just because something appears to work in some cases and not others, doesn't mean that there's nothing wrong when it does appear to work. This is a common trap actually. Generally speaking, as long as you haven't fully understood a "bug", even in cases where it appears to "work", there may still be something fishy lurking around. That's why "fixing" a bug without understanding it, which is unfortunately much too common, is rarely a good idea. It's a good recipe for the bug coming back at some point to haunt you.
With that said and set aside, with a 4V threshold, after reading the datasheet, it's rather unlikely to cause issues as the min operating voltage of this MCU is 1.8V, so you should have a large margin. That said, we don't know what frequency it runs at. I haven't read the DS thoroughly, but I doubt, for instance, that it can run at the max frequency at 1.8V, for instance. There's often a minimum voltage for a given operating frequency. So there's another information missing here.
Another missing info is how fast the supply voltage decreases when you get into this "low voltage" condition. Have you looked with a scope? Reason I ask is, for instance, if there's not enough bulk capacitance on the power rail, the voltage may drop so fast that from the moment it gets below 4V and the moment it gets below a safe operating voltage for the MCU, the ISR may not be done executing. That may not be what's happening here, but something to consider.
Another missing info (that your forgot to answer) is how you initialize the content of 'a[]'.
You showed its declaration ("unsigned char a[5];"), but not how its content is being populated. We can only guess it's being written to at run time, maybe somewhere in your main() function.
If there's not particular problem with any of the points I talked about above, this could be something else to investigate: if you declare a global arrray like this, it's going to be initiazed upon startup with all zero's (it's guaranteed by the C language, and is usually done by the startup code that executes before your main() function and calls it.) What that means is that, between the point where the MCU resets, and the point where you actually populate 'a[]' at run-time, it will contain only zero's. Now we may be on to something.
Have you enabled the BOR and/or LPBOR? If so... keep reading.
Then one possible scenario for what you see could be:
- Voltage drops below 4V => ISR gets called => a[] contains the 'right' values and they get properly written to EE, assuming voltage was still high enough to completion;
- Voltage keeps dropping, and the MCU resets due to a BOR or LPBOR condition;
- Voltage may bounce up a bit while the MCU resets, just because during reset the MCU will draw a lot less power;
- So the MCU may restart after the BOR, but at this point, if the voltage is still below 4V, the HLVD ISR will be called almost first thing BEFORE your code got a chance to initialize 'a[]'.
To check that, you may toggle another IO before and after the initialization of 'a[]'. Looking at this IO plus the IO that you toggle in the ISR with a scope will give you much more info than you currently have.