Part Number: LAUNCHXL-F28377S
Other Parts Discussed in Thread: C2000WARE
Tool/software: TI C/C++ Compiler
Hi
I have to regulate the output voltage of multiple H bridges that are driven through PWMs of a TMM320F28377S DSP. I'm using the TI DCL library version 2.01.0.
At first I wanted to use the assembly version of the PI controller ( DCL_runPI_C1 ) but I found it's not really working for me. Either I don't really know how to call a assembly function from C code or I have some of my compiler settings wrong. The problem is that the assembly function doesn't seem to save the register context properly. This is the assembler function copied from the DCL library. You can see that at some point it loads register AR1 with 0xA. This register is not saved in the context save at the beginning of the function.
The problem is that my calling C function uses XAR1 to hold an index into an array to save the calculated result of the assembly PI controller. This means that after returning from the assembly function the index is lost and always points to the wrong array element.
_DCL_runPI_C1: .asmfunc ; context save MOV32 *SP++, R4H MOV32 *SP++, R5H MOV32 *SP++, R6H ; servo error SUBF32 R4H, R0H, R1H ; R4H = v1 ; proportional path MOV32 R5H, *+XAR4[0] ; R5H = Kp MPYF32 R6H, R4H, R5H ; R6H = v2 ; integral path MOV32 R5H, *+XAR4[2] ; R5H = Ki MPYF32 R4H, R5H, R6H ; R4H = v3 MOV AR1, #0xA ; AR1 = 10 MOV32 R5H, *+XAR4[AR1] ; R5H = i6 MPYF32 R3H, R4H, R5H ; R3H = v8 MOV32 R4H, *+XAR4[4] ; R4H = i10 ADDF32 R5H, R4H, R3H ; R5H = v4 ZERO R1H ; R1H = 0.0f MOV32 *+XAR4[4], R5H ; save i10 ; control ADDF32 R0H, R5H, R6H ; R0H = v5 ADDF32 R5H, R1H, #1.0 ; R5H = 1.0f MOV32 R3H, *+XAR4[6] ; R3H = Umax MINF32 R0H, R3H ; if (v5 > Umax) R0H = Umax else R0H = v5 || MOV32 R5H, R1H ; R5H = 0.0f MOV AR0, #8 ; AR0 = 8 MOV32 R3H, *+XAR4[AR0] ; R3H = Umin MAXF32 R0H, R3H ; if (v5 < Umin) R0H = Umin else R0H = v5 || MOV32 R5H, R1H ; R5H = 0.0f ; anti-windup & context restore MOV32 R6H, *--SP, UNCF ; delay slot MOV32 *+XAR4[AR1], R5H ; save i6 MOV32 R5H, *--SP, UNCF MOV32 R4H, *--SP, UNCF LRETR .endasmfunc .end
void clcCalcControl(const uint16_t c, float ref, float fb)
{
float piContrOut;
piContrOut = DCL_runPI_C1(&piController[c], ref, fb);
control[c] = (ref + piContrOut) / ref;
}
If I add an MOVL *SP++, XAR1 to the beginning of the assembly function and MOVL XAR1, *--SP to the end it works fine.
Is this a bug in the assembly function or is this something I can work around by setting compiler options or optimization level?
Cheers,
Jens