📄 adccalibrationdriver.asm
字号:
;;###########################################################################
;;
;; FILE: ADCcalibrationDriverUpdate.asm
;;
;; TITLE: ADC calibration driver.
;;
;;###########################################################################
;;
;; Ver | dd-mmm-yyyy | Who | Description of changes
;; =====|=============|=======|==============================================
;; 1.0 | 20 Jun 2003 | AT/SD | Original Release.
;; -----|-------------|-------|----------------------------------------------
;; 1.1 | 26 Nov 2004 | AT | Fixed Bug In ADCcalibrationInitADC function.
;; | | | Was incorrectly disabling ADC clock.
;;
;;###########################################################################
;;===========================================================================
;; CASM: void ADCcalibrationDriverUpdate(ADC_CALIBRATION_DRIVER_VARS *);
;;===========================================================================
;;
;; Algorithm: Calibration formula used is:
;;
;; ch(n) = ADCRESULTn*CalGain - CalOffset
;;
;; n = 0 to 15 channels
;;
;; CalGain = (RefHighIdealCount - RefLowIdealCount)
;; -----------------------------------------
;; (Avg_RefHighActualCount - Avg_RefLowActualCount)
;;
;; CalOffset = Avg_RefLowActualCount*CalGain - RefLowIdealCount
;;
;; A running weighted average is calculated for the reference inputs:
;;
;; Avg_RefHighActualCount = (Avg_RefHighActualCount*SAMPLES
;; + RefHighActualCount)/(SAMPLES+1)
;;
;; Avg_RefLowActualCount = (Avg_RefLowActualCount*SAMPLES
;; + RefLowActualCount)/(SAMPLES+1)
;;
;; On Entry: XAR4 -> struct {
;; Uint16 RefHighChAddr; // Channel Address For RefHigh
;; Uint16 RefLowChAddr; // Channel Address For RefLow
;; Uint16 Ch0Addr; // Channel 0 Address
;; Uint16 Avg_RefHighActualCount; // Average Actual RefHigh Count (Q4)
;; Uint16 Avg_RefLowActualCount; // Average Actual RefLow Count (Q4)
;; Uint16 RefHighIdealCount; // Ideal RefHigh Count (Q0)
;; Uint16 RefLowIdealCount; // Ideal RefLow Count (Q0)
;; Uint16 CalGain; // Calibration Gain (Q12)
;; Uint16 CalOffset; // Calibration Offset (Q0)
;; // Store Calibrated ADC Data (Q0):
;; // Simultaneous Sequential
;; // ============ ============
;; Uint16 ch0; // A0 A0
;; Uint16 ch1; // B0 A1
;; Uint16 ch2; // A1 A2
;; Uint16 ch3; // B1 A3
;; Uint16 ch4; // A2 A4
;; Uint16 ch5; // B2 A5
;; Uint16 ch6; // A3 A6
;; Uint16 ch7; // B3 A7
;; Uint16 ch8; // A4 B0
;; Uint16 ch9; // B4 B1
;; Uint16 ch10; // A5 B2
;; Uint16 ch11; // B5 B3
;; Uint16 ch12; // A6 B4
;; Uint16 ch13; // B6 B5
;; Uint16 ch14; // A7 B6
;; Uint16 ch15; // B7 B7
;; }ADC_CALIBRATION_DRIVER_VARS;
;;
;; Regs Used: ACC, P, XT, XAR4, XAR5, XAR6, XAR7
;;
;; On Exit: ACC = undefined
;;
;; Input data from ADC registers is MSB aligned (Q4)
;; When it is stored in structure, it is LSB aligned (Q0)
;;
;; Benchmark: 137 cycles (includes Parameter Passing, Call, Return)
;;
;;---------------------------------------------------------------------------
;
; Select Reference Values Averaging Parameters:
;
AVG_SHIFT .set 6 ; SHIFT = 1, 2, 3, 4, 5, 6
AVG_SAMPLES .set 63 ; SAMPLES = 2^SHIFT - 1
.global _ADCcalibrationDriverUpdate
.text
;; This function is called for all ADC interrupts:
;;
_ADCcalibrationDriverUpdate:
MOVL XAR5,*XAR4++ ; XAR5 -> RefHigh Channel Addr
MOVL XAR6,*XAR4++ ; XAR4 -> RefLow Channel Addr
MOVL XAR7,*XAR4++ ; XAR7 -> Channel 0 Addr
; XAR4 -> Avg_RefHighActualCount
MOV @T,#AVG_SAMPLES ; T = SAMPLES
MPYU P,T,*+XAR4[1] ; P = Avg_RefLowActualCount * SAMPLES
MOVU ACC,*XAR6 ; ACC = RefLowActualCount (Q4)
ADDL ACC,@P ; ACC = Avg_RefLowActualCount*SAMPLES + RefLowActualCount (Q4)
LSR64 ACC:P,#AVG_SHIFT ; ACC = Avg_RefLowActualCount*SAMPLES + RefLowActualCount (Q4)
MOV *+XAR4[1],AL ; Store New Avg_RefLowActualCount (Q4)
LSR AL,#4 ; ACC = Avg_RefLowActualCount (Q0)
MOVZ AR6,@AL ; AR6 = Avg_RefLowActualCount (Q0)
MPYU P,T,*XAR4 ; P = Avg_RefHighActualCount * SAMPLES
MOVU ACC,*XAR5 ; ACC = RefHighActualCount (Q4)
ADDL ACC,@P ; ACC = Avg_RefHighActualCount*SAMPLES + RefHighActualCount (Q4)
LSR64 ACC:P,#AVG_SHIFT ; ACC = Avg_RefHighActualCount*SAMPLES + RefHighActualCount (Q4)
MOV *XAR4++,AL ; Store New Avg_RefHighActualCount (Q4)
; XAR4 -> Avg_RefLowActualCount
SUB AL,*XAR4++ ; AL = Avg_RefHighActualCount - Avg_RefLowActualCount (Q4)
LSR AL,#3
MOVZ AR5,@AL ; AR5 = Avg_RefHighActualCount - Avg_RefLowActualCount (Q1)
; XAR4 -> RefHighIdealCount
MOV AH,*XAR4++ ; AH = RefHighIdealCount
SUB AH,*XAR4 ; AH = RefHighIdealCount - RefLowIdealCount
MOVB AL,#0 ; AL = 0
; XAR4 -> RefLowIdealCount
RPT #12
|| SUBCU ACC,@AR5
MOV T,@AL ; T = CalGain (Q12)
MPYU ACC,T,@AR6 ; ACC = Avg_RefLowActualCount*CalGain
SUB ACC,*XAR4++ << 12 ; ACC = Avg_RefLowActualCount*CalGain - RefLowIdealCount
MOVH @AR5,ACC << 4 ; AR5 = CalOffset (Q0)
; XAR4 -> CalGain
MOV *XAR4++,T ; Save CalGain
MOV *XAR4++,AR5 ; Save CalOffset
; XAR4 -> ch0
.loop 16 ; for ch0 to ch15 do:
MPYU ACC,T,*XAR7++ ; AH = ADCRESULTn*CalGain
SUB AH,@AR5 ; AH = ADCRESULTn*CalGain - CalOffset (Q0)
MOV *XAR4++,AH ; ch = ADCRESULTn*CalGain - CalOffset (Q0)
.endloop
LRETR
;;===========================================================================
;; No more.
;;===========================================================================
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -