My facts:
I have troubles with getting into a timer ISR although all related CCIE bits are at 0. The consequence is that the IV register of the timer interrupt is zero. My debug build falls into a trap function when the IV register has an unexpected value, such as 0.
The problem occurs when the main program is interrupted at this instruction:
TA0CCTL3 &= ~CCIE;
Protecting this instruction with interrupt disabling stops the issue.
My interpretaton:
Surely, this is a case of non atomic operation being interrupted. The setting / resetting of interrupt enable should be protected, it seems. I expected that googling this issue would give some results but I found nothing interesting.
The machine code and assembly for the instruction above looks like this:
C0B2 0010 0348 bic.w #0x10,&TA0CCTL3
, that is three words long.
5.5.1.5 of the MSP430x5xx family specification says that such an operation has:
length: 3
No of cycles: 5
It is not clear for me what different things are achieved in these different five cycles.
I understand that some of these 5 steps should be:
- load TA0CCTL3
- load 0x0010 or its bit-inverse.
- bit-AND with ~0x0010
- load the result back to TA0CCTL3
The interrupt must occur under one of these cycles, presumably under the loading back.
Before the loading back cycle, the interrupts are still enabled. The interrupt event occurs, so the PC is loaded with the ISR address. However the first instruction of the ISR is not executed before the end of the loading back cycle. That would explain why the program reaches ISR although all CCIE are disabled.
I would be ok with that, what I find very unpractical is that the IV register is reset to 0.
If I am correct in my interpretation, I can't see why I don't find info on the web. Is there an app note about this?
The current work arounds I can see:
- Protect the disabling of interrupts with CCIE by surrounding it with global interrupt disabling. Urk.
- Take 0 as an acceptible value for the IV register, but do nothing in the ISR. The interrupt event is lost. This is preferable in my case, but not all.
I would appreciate comments, either stating that I am correct or wrong in my interpretation of the issue.
Other smart comments are also welcome of course.