Hello,
I have a problem with some FPU code running inside an ISR on F28335. I have one interrupt that can interrupt itself and ISR code that contains floating-point register comparisons. The problem is that sometimes comparisons dont work properly. If I disable interrupts (SETC INTM / CLRC INTM) around the code in question, the problem seems to disappear. I'm pretty confident my context storing and restoring is good, but I provide code here. Interrupts are globally disabled during context storing/restoring.
Context save:
ASP
PUSH AR1H:AR0H
PUSH XAR2
PUSH XAR3
PUSH XAR4
PUSH XAR5
PUSH XAR6
PUSH XAR7
PUSH XT
MOV32 *SP++, R0H
MOV32 *SP++, R1H
MOV32 *SP++, R2H
MOV32 *SP++, R3H
MOV32 *SP++, R4H
MOV32 *SP++, R5H
MOV32 *SP++, R6H
MOV32 *SP++, R7H
MOV32 *SP++, STF
MOV32 *SP++, STF
PUSH RB
Context restore:
POP RB
MOV32 STF, *--SP
MOV32 STF, *--SP
MOV32 R7H, *--SP
MOV32 R6H, *--SP
MOV32 R5H, *--SP
MOV32 R4H, *--SP
MOV32 R3H, *--SP
MOV32 R2H, *--SP
MOV32 R1H, *--SP
MOV32 R0H, *--SP
POP XT
POP XAR7
POP XAR6
POP XAR5
POP XAR4
POP XAR3
POP XAR2
POP AR1H:AR0H
NASP
The problematic code (part of the ISR) is:
MOVF32 R0H, #-6328.0
MOVF32 R1H, #16384.0
CMPF32 R1H, R0H
MOVST0 NF
BF $1, LT
MOV @OUT, #0
BF $2, UNC
$1
MOV @OUT, #-1
$2
The line "MOV @OUT, #-1" should never be reached however, if I put a brakepoint there, it catches the violation and contents of the involved registers at the brakepoint is:
STF 0x00000214 pointer hex NotEdited
R0H -6328.0 pointer float NotEdited
R1H 16384.0 pointer float NotEdited
ST0 00AB
So, although registers R0H and R1H are loaded properly and
R1H - R0H = 16384.0 - (-6328.0) = 22712 > 0
N flags in STF and ST0 are set.
If I than set the PC to line "CMPF32 R1H, R0H" and single-step the code, all works fine. My only guess is that interrupt happens between "CMPF32 R1H, R0H" and "MOVST0 NF" lines and corrupts STF. But how is that possible if STF is stored/restored with the rest of the context? Whether this problem happens or not depends on the amount of code on the ISR and interrupt period. This looks to me as if it is the question of where exactly the ISR interrupts itself.
Please help, I'm running out of ideas.
Kind regards,
Josip