📄 dac.asm
字号:
;;************************************************************************
;;
;; DAC.asm (from dac9.asm user module template)
;; Rev A, 2002 Jul 18
;;
;; Assembler source for 9-bit Switched Capacitor DAC API
;;
;; Copyright (c) Cypress MicroSystems 2002. All Rights Reserved.
;;
;;************************************************************************
export DAC_Start
export _DAC_Start
export DAC_SetPower
export _DAC_SetPower
export DAC_WriteBlind
export _DAC_WriteBlind
export DAC_WriteBlind2B
export _DAC_WriteBlind2B
export DAC_WriteStall
export _DAC_WriteStall
export DAC_WriteStall2B
export _DAC_WriteStall2B
export DAC_Stop
export _DAC_Stop
;; -----------------------------------------------------------------
;; Register Definitions
;; -----------------------------------------------------------------
;;
;; Uses 2 Switched Cap Blocks, LSB and MSB, configured as shown below.
;; This API depends on knowing the exact personalization of CR0
;; and CR3 bitfields for time efficiency.
;;
;; * For a Mask/Val pair this simply indicates that the value is
;; determined by the user either through config-time parameteriza-
;; tion or run-time manipulation.
;;
;; Setting for output=AGND to OBUS when LSB in ASA10 and MSB in ASB20:
;; LSB.CR0=80 MSB.CR0=80
;; LSB.CR1=40 MSB.CR1=81
;; LSB.CR2=20 MSB.CR2=A0
;; LSB.CR3=33 MSB.CR3=3B
;;
;; BIT FIELD Mask/Val Function
;; ----------------- -------- --------------------
;; LSB.CR0.FCap 80/1 Feedback cap size 32
;; LSB.CR0.ClockPhase 40/0 Normal phase
;; LSB.CR0.ASign 20/* User parameter
;; LSB.CR0.ACap 1F/* User parameter
;;
;; LSB.CR1.ACMux E0/2 (SCA) A:VRef High, C:Don't Care
;; LSB.CR1.BCap 1F/0 Prune B-input branch
;;
;; LSB.CR2.AnalogBus 80/* User Parameter: Output Bus Enable
;; LSB.CR2.CmpBus 40/0 Comparator Bus Disabled
;; LSB.CR2.AutoZero 20/1 Auto-Zero enabled on internal Phi 1
;; LSB.CR2.CCap 1F/0 Prune C-input branch
;;
;; LSB.CR3.ARefSelect C0/0 Use AGND (to invert)
;; LSB.CR3.FSW1 20/1 Feedback Cap Used
;; LSB.CR3.FSW0 10/1 Feedback Cap Grounded for AZ
;; LSB.CR3.BMux 0C/0 (SCA) Don't Care - this branch pruned
;; LSB.CR3.PWR 03/* User Parameter: Power; default=OFF
;;
;; MSB.CR0.FCap 80/1 Feedback cap size 32
;; MSB.CR0.ClockPhase 40/0 Normal phase
;; MSB.CR0.ASign 20/* User parameter
;; MSB.CR0.ACap 1F/* User parameter
;;
;; MSB.CR1.AMux E0/4 (SCB) VRef High
;; MSB.CR1.BCap 1F/1 Subrange LSB block output by BCap/FCap (1/32)
;;
;; MSB.CR2.AnalogBus 80/* User Parameter: Output Bus Enable
;; MSB.CR2.CmpBus 40/0 Comparator Bus Disable
;; MSB.CR2.AutoZero 20/1 Auto-Zero enabled on internal Phi 1
;; MSB.CR2.CCap 1F/0 Prune C-input branch
;;
;; MSB.CR3.ARefSelect C0/0 Use AGND (to invert)
;; MSB.CR3.FSW1 20/1 Feedback Cap Used
;; MSB.CR3.FSW2 10/1 Feedback Cap Grounded for AZ
;; MSB.CR3.BSW 08/0 (SCB) why is this cont time instead of phi2??
;; MSB.CR3.BMux 04/? (SCB) LSB block output; determined by placement
;; MSB.CR3.PWR 03/* User Parameter: Power, default=OFF
include "DAC.inc"
include "m8c.inc"
iOFFSET: equ 255 ; Conversion term for offset binary to 2's C
bPWRMASK: equ 03h ; Power bitfield in Switched Cap CR3 reg
bCR3: equ 30h ; Except for power bits, CR3 always looks like
; this regardless of SC block type or location.
bSMMASK: equ 3Fh ; Sign and Magnitude bits mask
bSIGNMASK: equ 20h ; Sign bit mask
bMAGMASK: equ 1Fh ; Magnitude bits mask
bHIGHBITS: equ 80h ; Setting for FCap and ClockPhase
bHBMASK: equ C0h ; Mask for FCap and ClockPhase
;;---------------------------
macro Stall
;;---------------------------
mov reg[ASY_CR], 1
endm
;;---------------------------
macro UnStall
;;---------------------------
mov reg[ASY_CR], 0
endm
;;-------------------------------------------------------------------------
;; Start: Applies power setting to the module's analog PSoC blocks.
;; INPUTS: A contains the power setting 0=Off, 1=Low, 2=Med, 3=Full.
;; OUTUTS: None.
;;-------------------------------------------------------------------------
DAC_Start:
_DAC_Start:
DAC_SetPower:
_DAC_SetPower:
and A, bPWRMASK ; trim input to bits of interest
mov X, SP ; Set stack frame pointer
push A
;; read CR3 registers, modify power bits & write back
mov A, reg[DAC_MSB_CR3]
and a, ~bPWRMASK ; clear old setting
or A, [X] ; set power in MSB register image
mov reg[DAC_MSB_CR3], A
mov A, reg[DAC_LSB_CR3]
and a, ~bPWRMASK ; clear old setting
or A, [X] ; set power in LSB register image
mov reg[DAC_LSB_CR3], A
pop A
ret
;;---------------------------------------------------------------------------
;; WriteBlind
;;
;; Modify the DAC's update value without worrying about the clocks.
;; Lowest overhead, but may cause glitches on the output.
;;
;; INPUTS: A contains the update value if data format is offset binary or
;; For offset binary format: A contains the low byte; X the high byte.
;; For twos complement format: A contains the low byte; X the high byte.
;; For two-byte sign-and-magnitude format:
;; A contains the LSB as 00smmmmm; X contains the MSB as 00tmmm00,
;; where t=s\ (the inverted sign).
;;
;; OUTPUTS: Analog output voltage reflects input value
;;---------------------------------------------------------------------------
DAC_WriteBlind:
_DAC_WriteBlind:
IF DAC_OFFSETBINARY
;; Data is an unsigned byte value in [0..510] (511 unique values).
;; Following converts it to 2's complement:
sub A, iOFFSET
swap A, X ; A <- upper, X <- lower
sbb A, 0
swap A, X ; A <- lower, X <- upper
ENDIF
IF DAC_OFFSETBINARY | DAC_TWOSCOMPLEMENT
swap A, X ; A <- upper, X <- lower
push A ; Save Sign on stack 1
; Sign is either FFh or 00h
dec A ; set or clear Carry Flag
; A is now FEh(CF=0) or FFh(CF=1)
mov A,X ; MSB: 76543210
jc DAC9_WriteBlind_dont_cpl_positive_mag
cpl A ; change negative magnitude to positive
DAC9_WriteBlind_dont_cpl_positive_mag:
push A ; MSB: 76543210 (mag) 2
asr A ; MSB: 77654321
asr A ; MSB: 77765432
asr A ; MSB: 77776543
and A,bMAGMASK ; MSB: 00076543
mov X,SP
and [X-2],bSIGNMASK
or A,[X-2] ; MSB: 00s76543
mov X,A ; MSB
pop A ; LSB: 76543210 (mag) 1
push X ; MSB 2
asl A ; LSB: 65432100
asl A ; LSB: 54321000
and A,bMAGMASK ; LSB: 00021000
mov X,SP
or A,[X-2] ; LSB: 00s21000
xor A,bSIGNMASK ; LSB: 00t21000
; LSB in A
pop X ; MSB in X 1
ENDIF
; IF DAC_SIGNANDMAGNITUDE
or A,bHIGHBITS ; LSB: 10t21000
swap A,X ; LSB in X, MSB in A
or A,bHIGHBITS ; MSB: 10s76543
mov reg[DAC_MSB_CR0],A
mov A,X ; LSB in A
mov reg[DAC_LSB_CR0],A
pop A ; stack cleanup 0
; ENDIF
ret
DAC_WriteBlind2B:
_DAC_WriteBlind2B:
or A,bHIGHBITS ; LSB: 10t21000
swap A,X ; LSB in X, MSB in A
or A,bHIGHBITS ; MSB: 10s76543
mov reg[DAC_MSB_CR0],A
mov A,X ; LSB in A
mov reg[DAC_LSB_CR0],A
ret
;;---------------------------------------------------------------------------
;; WriteStall
;;
;; Modify the DAC's update value, stalling the CPU if necessary.
;; This routine should be used with faster analog clocks or when the
;; effect of prolonging interrupt latencies can be safely tolerated.
;;
;; INPUTS: A contains the update value if data format is offset binary or
;; For offset binary format: A contains the low byte; X the high byte.
;; For twos complement format: A contains the low byte; X the high byte.
;; For two-byte sign-and-magnitude format:
;; A contains the LSB as 00smmmmm; X contains the MSB as 00tmmm00,
;; where t=s\ (the inverted sign).
;;
;; OUTPUTS: Analog output voltage reflects input value
;;---------------------------------------------------------------------------
DAC_WriteStall:
_DAC_WriteStall:
IF DAC_OFFSETBINARY
;; Data is an unsigned byte value in [0..510] (511 unique values).
;; Following converts it to 2's complement:
sub A, iOFFSET
swap A, X ; A <- upper, X <- lower
sbb A, 0
swap A, X ; A <- lower, X <- upper
ENDIF
IF DAC_OFFSETBINARY | DAC_TWOSCOMPLEMENT
swap A, X ; A <- upper, X <- lower
push A ; Save Sign on stack 1
; Sign is either FFh or 00h
dec A ; set or clear Carry Flag
; A is now FEh(CF=0) or FFh(CF=1)
mov A,X ; MSB: 76543210
jc DAC9_WriteStall_dont_cpl_positive_mag
cpl A ; change negative magnitude to positive
DAC9_WriteStall_dont_cpl_positive_mag:
push A ; MSB: 76543210 (mag) 2
asr A ; MSB: 77654321
asr A ; MSB: 77765432
asr A ; MSB: 77776543
and A,bMAGMASK ; MSB: 00076543
mov X,SP
and [X-2],bSIGNMASK
or A,[X-2] ; MSB: 00s76543
mov X,A ; MSB
pop A ; LSB: 76543210 (mag) 1
push X ; MSB 2
asl A ; LSB: 65432100
asl A ; LSB: 54321000
and A,bMAGMASK ; LSB: 00021000
mov X,SP
or A,[X-2] ; LSB: 00s21000
xor A,bSIGNMASK ; LSB: 00t21000
; LSB in A
pop X ; MSB in X 1
ENDIF
; IF DAC_SIGNANDMAGNITUDE
or A,bHIGHBITS ; LSB: 10t21000
swap A,X ; LSB in X, MSB in A
or A,bHIGHBITS ; MSB: 10s76543
M8C_Stall
mov reg[DAC_MSB_CR0],A
M8C_Unstall
mov A,X ; LSB in A
mov reg[DAC_LSB_CR0],A
pop A ; stack cleanup 0
; ENDIF
ret
DAC_WriteStall2B:
_DAC_WriteStall2B:
or A,bHIGHBITS ; LSB: 10t21000
swap A,X ; LSB in X, MSB in A
or A,bHIGHBITS ; MSB: 10s76543
M8C_Stall
mov reg[DAC_MSB_CR0],A
M8C_Unstall
mov A,X ; LSB in A
mov reg[DAC_LSB_CR0],A
ret
;;-------------------------------------------------------------------------
;; Stop: Cuts power to the user module.
;; INPUTS: None
;; OUTPUTS: None
;;-------------------------------------------------------------------------
DAC_Stop:
_DAC_Stop:
and reg[DAC_MSB_CR3], ~bPWRMASK
and reg[DAC_LSB_CR3], ~bPWRMASK
ret
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -