This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Compiler/LAUNCHXL-F28377S: Issue with DCL PI controller assembly version C1

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