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.

puzzled about the pis_reg3.asm in Digital Motor Control Libraries

Other Parts Discussed in Thread: CONTROLSUITE

;=====================================================================================
; File name:        PID_REG3.ASM                    
;                   
; Originator: Digital Control Systems Group
;   Texas Instruments
;
; Description:  Digital PID controller with anti-windup correction              
;
;=====================================================================================
; History:
;-------------------------------------------------------------------------------------
; 02-08-2001 Release Rev 1.00
;================================================================================
; Applicability: F240,F241,C242,F243,F24xx.  (Peripheral Independent).
;================================================================================
; Routine Name: pid_reg3_calc                Type C Callable:; 
;  C prototype : void pid_reg3_calc(struct PIDREG3 *p);
;
;        The struct object is defined in the header file "pid_reg3.h" as follows:
;
; typedef struct {  int  pid_ref_reg3;    /* Input: Reference input (Q15) */
;      int  pid_fdb_reg3;    /* Input: Feedback input (Q15) */
;      int  e_reg3;   /* Variable: Error  (Q14)  */
;      int  Kp_reg3;   /* Parameter: Proportional gain (Q15) */
;      int  up_reg3;   /* Variable: Proportional output (Q14) */
;      int  ui_hi_reg3;  /* Variable: Integral output  (Q30)  */
;      int  ui_lo_reg3;  /* Variable: Integral output  (Q30)  */ 
;      int  ud_lo_reg3;  /* Variable: Derivative output  (Q30)  */ 
;      int  ud_hi_reg3;  /* Variable: Derivative output  (Q30)  */
;      int  uprsat_reg3;   /* Variable: Pre-saturated output (Q14) */
;      int  pid_out_max;  /* Parameter: Maximum output  (Q15)  */
;      int  pid_out_min;  /* Parameter: Minimum output  (Q15)  */
;      int  pid_out_reg3;    /* Output: PID output  (Q15)  */
;      int  saterr_reg3;  /* Variable: Saturated difference (Q14) */
;     (1) int  Ki_reg3;   /* Parameter: Integral gain  (Q31-16bit) */
;      int  Kc_reg3;   /* Parameter: Integral correction gain (Q15) */
;      int  Kd_reg3;   /* Parameter: Derivative gain  (Q14)  */
;      int  up1_reg3;  /* Variable: Previous proportional output (Q14) */
;        int  (*calc)();    /* Pointer to calculation function */
;     } PIDREG3;          
;    
;        Frame Usage Details:
;     step   |      a      |      b       |      c       |     d    
;____________|_____________|______________|______________|_____________
;     AR0    |             |              |     |    
;
;================================================================================
                .def        _pid_reg3_calc
;================================================================================
__pid_reg3_calc_framesize .set 0000h
;================================================================================
_pid_reg3_calc:
              ; Assume now ARP=AR1
      POPD *+         ; Keep return address
        SAR   AR0,*+        ; Keep old frame pointer (FP)
        SAR    AR1,*        ; Keep old stack pointer (SP)
        LARK   AR0,__pid_reg3_calc_framesize   ; Load AR0 with frame size 
        LAR    AR0,*0+,AR0       ; AR0->FP0 (new FP), ARP=AR0

;================================================================================
  SBRK #3  ; ARP=AR0, AR0->FR0-3 (1st argument)  
;----------------------------------------------------------------------------------
  LAR  AR2,* ; ARP=AR0, AR0->pid_ref_reg3, AR2->pid_ref_reg3
;----------------------------------------------------------------------------------
  ADRK #3  ; ARP=AR0, AR0->FR0, AR2->pid_ref_reg3
;----------------------------------------------------------------------------------
  MAR  *,AR2   ; ARP=AR2, AR0->FR0, AR2->pid_ref_reg3
;----------------------------------------------------------------------------------
  SETC  SXM  ; Turn sign extension mode on
      ; ARP=AR2, AR0->FR0, AR2->pid_ref_reg3
;----------------------------------------------------------------------------------
  SETC OVM  ; Set overflow mode
      ; ARP=AR2, AR0->FR0, AR2->pid_ref_reg3
;----------------------------------------------------------------------------------
   SPM     0       ; Reset product mode
            ; ARP=AR2, AR0->FR0, AR2->pid_ref_reg3
;----------------------------------------------------------------------------------
     LACC *+,15 ; ACC = pid_ref_reg3  (Q30)
         ; ARP=AR2, AR0->FR0, AR2->pid_fdb_reg3
;----------------------------------------------------------------------------------
      SUB  *+,15 ; ACC = pid_ref_reg3 - pid_fdb_reg3 (Q30)
         ; ARP=AR2, AR0->FR0, AR2->e_reg3
;----------------------------------------------------------------------------------
       SACH *  ; e_reg3 = pid_ref_reg3 - pid_fdb_reg3 (Q14)
         ; ARP=AR2, AR0->FR0, AR2->e_reg3
;----------------------------------------------------------------------------------
      LT  *+  ; TREG = e_reg3  (Q14)
          ; ARP=AR2, AR0->FR0, AR2->Kp_reg3  
;----------------------------------------------------------------------------------
       MPY  *+   ; PREG = Kp_reg3*e_reg3  (Q29)
          ; ARP=AR2, AR0->FR0, AR2->up_reg3
;----------------------------------------------------------------------------------
      PAC    ; ACC = Kp_reg3*e_reg3  (Q29)
          ; ARP=AR2, AR0->FR0, AR2->up_reg3        
;----------------------------------------------------------------------------------
    (2)  SACH *+,1 ; up_reg3 = Kp_reg3*e_reg3  (Q14)
          ; ARP=AR2, AR0->FR0, AR2->ui_hi_reg3  
;----------------------------------------------------------------------------------
       LACC *+,16 ; ACC = ui   (Q30)
           ; ARP=AR2, AR0->FR0, AR2->ui_lo_reg3
;----------------------------------------------------------------------------------
      ADDS *+  ; ACC = ui   (Q30)
          ; ARP=AR2, AR0->FR0, AR2->ud_lo_reg3 
;----------------------------------------------------------------------------------
       ADDS *+  ; ACC = ui + ud  (Q30)
           ; ARP=AR2, AR0->FR0, AR2->ud_hi_reg3  
;----------------------------------------------------------------------------------
       ADDH *  ; ACC = ui + ud  (Q30)
           ; ARP=AR2, AR0->FR0, AR2->ud_hi_reg3
;----------------------------------------------------------------------------------
     SBRK #4  ; ARP=AR2, AR0->FR0, AR2->up_reg3
;----------------------------------------------------------------------------------
  ADDH *  ; ACC = up + ui + ud  (Q30)
      ; ARP=AR2, AR0->FR0, AR2->up_reg3       
;----------------------------------------------------------------------------------
       ADRK #5  ; ARP=AR2, AR0->FR0, AR2->uprsat_reg3
;----------------------------------------------------------------------------------
  SACH *  ; uprsat_reg3 = up + ui + ud  (Q14)
      ; ARP=AR2, AR0->FR0, AR2->uprsat_reg3 
;----------------------------------------------------------------------------------
        LACC *+,16 ; ACC = uprsat_reg3   (Q14)
            ; ARP=AR2, AR0->FR0, AR2->pid_out_max
;----------------------------------------------------------------------------------
    SUB  *-,15 ; ACC = uprsat_reg3 - pid_out_max  (Q14)
            ; ARP=AR2, AR0->FR0, AR2->uprsat_reg3
;----------------------------------------------------------------------------------
       BCND SAT_MAX_REG3,GT ; Branch to SAT_MAX_REG3 if uprsat_reg3 > pid_out_max 
                       ; ARP=AR2, AR0->FR0, AR2->uprsat_reg3
;----------------------------------------------------------------------------------
      LACC *,16 ; ACC = uprsat_reg3   (Q14)
            ; ARP=AR2, AR0->FR0, AR2->uprsat_reg3
;----------------------------------------------------------------------------------
        ADRK #2  ; ARP=AR2, AR0->FR0, AR2->pid_out_min
;----------------------------------------------------------------------------------
      SUB  *,15 ; ACC = uprsat_reg3 - pid_out_min   (Q14)
            ; ARP=AR2, AR0->FR0, AR2->pid_out_min
;----------------------------------------------------------------------------------
  SBRK #2  ; ARP=AR2, AR0->FR0, AR2->uprsat_reg3
;----------------------------------------------------------------------------------
        BCND SAT_MIN_REG3,LT ; Branch to SAT_MIN_REG3 if uprsat_reg3 < pid_out_min 
                       ; ARP=AR2, AR0->FR0, AR2->uprsat_reg3      
;----------------------------------------------------------------------------------
       LACC *,16 ; ACC = uprsat_reg3   (Q30)
           ; ARP=AR2, AR0->FR0, AR2->uprsat_reg3
;----------------------------------------------------------------------------------
       ADRK #3  ; ARP=AR2, AR0->FR0, AR2->pid_out_reg3
;----------------------------------------------------------------------------------
     SACH *,1  ; pid_out_reg3 = uprsat_reg3   (Q15)
           ; ARP=AR2, AR0->FR0, AR2->pid_out_reg3
;----------------------------------------------------------------------------------
        B  UPDATE_REG3 ; ARP=AR2, AR0->FR0, AR2->pid_out_reg3 
;----------------------------------------------------------------------------------
SAT_MAX_REG3            ; ARP=AR2, AR0->FR0, AR2->uprsat_reg3
;----------------------------------------------------------------------------------
       ADRK #1  ; ARP=AR2, AR0->FR0, AR2->pid_out_max
;----------------------------------------------------------------------------------
       LACC *  ; ACC = pid_out_max   (Q15)
           ; ARP=AR2, AR0->FR0, AR2->pid_out_max
;----------------------------------------------------------------------------------
      ADRK #2  ; ARP=AR2, AR0->FR0, AR2->pid_out_reg3
;----------------------------------------------------------------------------------
     SACL *  ; pid_out_reg3 = pid_out_max   (Q15)
           ; ARP=AR2, AR0->FR0, AR2->pid_out_reg3
;----------------------------------------------------------------------------------
        B  UPDATE_REG3 ; ARP=AR2, AR0->FR0, AR2->pid_out_reg3 
;----------------------------------------------------------------------------------
SAT_MIN_REG3            ; ARP=AR2, AR0->FR0, AR2->uprsat_reg3
;----------------------------------------------------------------------------------
       ADRK #2  ; ARP=AR2, AR0->FR0, AR2->pid_out_min
;----------------------------------------------------------------------------------
       LACC *+  ; ACC = pid_out_min   (Q15)
           ; ARP=AR2, AR0->FR0, AR2->pid_out_reg3
;----------------------------------------------------------------------------------
     SACL *  ; pid_out_reg3 = pid_out_min   (Q15)
           ; ARP=AR2, AR0->FR0, AR2->pid_out_reg3
;----------------------------------------------------------------------------------
UPDATE_REG3    ; ARP=AR2, AR0->FR0, AR2->pid_out_reg3 
;----------------------------------------------------------------------------------
       LACC *,15 ; ACC = pid_out_reg3   (Q30)
           ; ARP=AR2, AR0->FR0, AR2->pid_out_reg3
;----------------------------------------------------------------------------------
       SBRK #3  ; ARP=AR2, AR0->FR0, AR2->uprsat_reg3
;----------------------------------------------------------------------------------
       SUB  *,16 ; ACC = pid_out_reg3 - uprsat_reg3  (Q30)
           ; ARP=AR2, AR0->FR0, AR2->uprsat_reg3
;----------------------------------------------------------------------------------
        ADRK #4  ; ARP=AR2, AR0->FR0, AR2->saterr_reg3
;----------------------------------------------------------------------------------
       SACH *+  ; saterr_reg3 = pid_out_reg3 - uprsat_reg3  (Q14)
           ; ARP=AR2, AR0->FR0, AR2->Ki_reg3
;----------------------------------------------------------------------------------
       SPM  3  ; Set right shifted 6 bit
           ; ARP=AR2, AR0->FR0, AR2->Ki_reg3
;----------------------------------------------------------------------------------
    (3) LT  *  ; TREG = Ki   (Q31-16 bit)
         ; ARP=AR2, AR0->FR0, AR2->Ki_reg3   
;----------------------------------------------------------------------------------
      SBRK #10  ; ARP=AR2, AR0->FR0, AR2->up_reg3
;----------------------------------------------------------------------------------
      (4)MPY  *  ; PREG = Ki*up   (Q38)
          ; ARP=AR2, AR0->FR0, AR2->up_reg3 
;----------------------------------------------------------------------------------
        PAC    ; ACC = Ki*up   (Q32)
          ; ARP=AR2, AR0->FR0, AR2->up_reg3 
;----------------------------------------------------------------------------------
      SFR    ; ACC = Ki*up   (Q31)
          ; ARP=AR2, AR0->FR0, AR2->up_reg3 
;----------------------------------------------------------------------------------
      SFR    ; ACC = Ki*up   (Q30)
          ; ARP=AR2, AR0->FR0, AR2->up_reg3 
;----------------------------------------------------------------------------------
      SPM  1  ; Set left shifted 1 bit
           ; ARP=AR2, AR0->FR0, AR2->up_reg3
;----------------------------------------------------------------------------------
      ADRK #11  ; ARP=AR2, AR0->FR0, AR2->Kc_reg3
;----------------------------------------------------------------------------------
      LT  *  ; TREG = Kc  (Q15)
          ; ARP=AR2, AR0->FR0, AR2->Kc_reg3  
;----------------------------------------------------------------------------------
       SBRK #2  ; ARP=AR2, AR0->FR0, AR2->saterr_reg3
;----------------------------------------------------------------------------------
      MPY  *  ; PREG = Kc*saterr_reg3   (Q29)
          ; ARP=AR2, AR0->FR0, AR2->saterr_reg3 
;----------------------------------------------------------------------------------
       APAC   ; ACC = Ki*up + Kc*(pid_out_reg3-uprsat_reg3)  (Q30)
          ; ARP=AR2, AR0->FR0, AR2->saterr_reg3
;----------------------------------------------------------------------------------
      SBRK #7  ; ARP=AR2, AR0->FR0, AR2->ui_lo_reg3  
;----------------------------------------------------------------------------------
     ADDS *-  ; ACC = ui + Ki*up + Kc*(pid_out_reg3-uprsat_reg3)  (Q30)
          ; ARP=AR2, AR0->FR0, AR2->ui_hi_reg3
;----------------------------------------------------------------------------------
     ADDH *+  ; ACC = ui + Ki*up + Kc*(pid_out_reg3-uprsat_reg3)  (Q30)
          ; ARP=AR2, AR0->FR0, AR2->ui_lo_reg3 
;----------------------------------------------------------------------------------
     SACL *-  ; ui = ui + Ki*up + Kc*(pid_out_reg3-uprsat_reg3)  (Q30)
          ; ARP=AR2, AR0->FR0, AR2->ui_hi_reg3   
;----------------------------------------------------------------------------------
      SACH *  ; ui = ui + Ki*up + Kc*(pid_out_reg3-uprsat_reg3)  (Q30)
          ; ARP=AR2, AR0->FR0, AR2->ui_hi_reg3    
;----------------------------------------------------------------------------------
     ADRK #11  ; ARP=AR2, AR0->FR0, AR2->Kd_reg3 
;----------------------------------------------------------------------------------
      LT  *  ; TREG = Kd   (Q14)
          ; ARP=AR2, AR0->FR0, AR2->Kd_reg3 
;----------------------------------------------------------------------------------
        SBRK #12  ; ARP=AR2, AR0->FR0, AR2->up_reg3
;----------------------------------------------------------------------------------
     MPY  *  ; PREG = Kd*up  (Q28)
         ; ARP=AR2, AR0->FR0, AR2->up_reg3
;----------------------------------------------------------------------------------
      PAC    ; ACC = Kd*up  (Q29)
         ; ARP=AR2, AR0->FR0, AR2->up_reg3 
;----------------------------------------------------------------------------------
     ADRK #13  ; ARP=AR2, AR0->FR0, AR2->up1_reg3
;----------------------------------------------------------------------------------
     MPY  *  ; PREG = Kd*up1  (Q28)
         ; ARP=AR2, AR0->FR0, AR2->up1_reg3 
;----------------------------------------------------------------------------------
      SPAC         ; ACC = Kd*up - Kd*up1  (Q29)
         ; ARP=AR2, AR0->FR0, AR2->up1_reg3 
;----------------------------------------------------------------------------------
      SBRK #10  ; ARP=AR2, AR0->FR0, AR2->ud_lo_reg3 
;----------------------------------------------------------------------------------
     SACL *+,1 ; ud_lo_reg3 = Kd*up - Kd*up1  (Q30)
         ; ARP=AR2, AR0->FR0, AR2->ud_hi_reg3 
;----------------------------------------------------------------------------------
     SACH *,1  ; ud_hi_reg3 = Kd*up - Kd*up1  (Q30)
         ; ARP=AR2, AR0->FR0, AR2->ud_hi_reg3 
;----------------------------------------------------------------------------------
  SBRK #4  ; ARP=AR2, AR0->FR0, AR2->up_reg3
;----------------------------------------------------------------------------------
     LACC *  ; ACC = up_reg3  (Q14)
         ; ARP=AR2, AR0->FR0, AR2->up_reg3 
;----------------------------------------------------------------------------------
      ADRK #13  ; ARP=AR2, AR0->FR0, AR2->up1_reg3  
;----------------------------------------------------------------------------------
        SACL *,AR1 ; up1_reg3 = up_reg3  (Q14)
         ; ARP=AR2, AR0->FR0, AR2->up1_reg3, ARP=AR1 
;----------------------------------------------------------------------------------
_pid_reg3_calc_exit:
        ;; MAR     *,AR1   ; can be removed if this condition is met on
                        ; every path to this code. (i.e., ARP=AR1 here)

  SPM     0      
        CLRC OVM
        CLRC SXM

     SBRK  #(__pid_reg3_calc_framesize+1)
        LAR   AR0,*-
        PSHD *
       
        RET

 

MY question

The code above is obtained from TMS320C2000™ Microcontroller Digital Motor Control Libraries.and the PID_reg3.asm is a part of the library which is implented by ASM language.my qustion is focused on the yellow colour parts.

1.  in yellow part (1),my question is :how does a 16-bit data express Q31 format date

2. in yellow part (2)(3)(4),my question is :(2)and(3)show Ki is a Q31 format date and  up(or up_reg3) is a Q14 format date;if they multiply,then the product should be  a Q45 (Q31+Q14) format date.but the yellow part  (4) show the product is a Q38 format date. why?

Looking forward to your answers.

Thanks for your help.