;**************************************************************
;;MC68HCS12 assembly code
;Program name:	hcs12atd.asm
;Origin:	page 417 of textbook by Cady & Sibigtroth
;modified: 	22 September 2005 by Jianjian Song
;modified(again): 10/5/2005 Anthony Varner
;Purpose:	Convert an analog signal on Channel 4 (PAD4 on Pin 9) and 
;		Scan mode is enabled to get a continuous reading. PAD4 is analog input
; by default once it is selected. Never use DDRAD to set PAD4 to be input.
; It would make PAD4 draw a huge amount of current.
;9-26-2005  --
; single channel and single conversion did not work. 
; Single channel and multiple conversion works fine.
;10-5-2005
; Multiple channel on PAD4 and PAD6 returns to integers VoltA, VoltB
;10-26-5 now inlcudes code for printing to HyperTerminal converted into
;an interupt routine 
;**************************************************************

; export symbols
        XDEF atd  ; START can be referenced from other files
        XDEF voltA,voltB    ; we use export 'START' as symbol.
        nolist
        INCLUDE 'mc9s12c32.inc'
        list
; general constants
NLOOP:	EQU 	122	; 200 loops for 100 msec
RESOLUTION:	EQU	192	; 5000mv/256=19.5 mV
;AFFC - Fast clear
;AWAI -	A/D wait mode 
;ASCIE - SCF interrupt enable
; AD Mode: DJM=1 for Right justfied and DSGN=0 for unsigned, SCAN=0 for single mode conversion; 
;		MULT=1 for 8 conversions on channel 4
;  CC,CB, CA= 100 to choose analog channel 4
ATDMODE:	EQU	%10010000
Wait_Time: EQU 49999

DataSec: SECTION
voltA: DS.B 2
voltB: DS.B 2           

CodeSec: SECTION
atd:
	PSHX
	LDX	#Wait_Time
  JSR NOP_WAIT
  PULX

	PSHX
	LDX	#Wait_Time
  JSR NOP_WAIT
  PULX
  
; Enable the timer. A/D will not work if timer is off
;	BSET	TSCR1,mTSCR1_TEN  ; at 0x46
;Making PAD4 pin an input will make the pin draw a lot of more current. Never do this.
;  BCLR DDRAD,mDDRAD_DDRAD4  ; at 0272 make PAD4 input at 0x270
	BSET	ATDCTL2,mATDCTL2_ADPU	;  Power up the A/D

; wait for A/D converter to be ready for 100 microsec

	PSHX
	LDX	#NLOOP	; 200 loops for
  JSR NOP_WAIT
  PULX

; Normal flag clearing, run in WAIT mode, no interrupts
	BCLR	ATDCTL2,mATDCTL2_AFFC|mATDCTL2_AWAI|mATDCTL2_ASCIE  ;at 0x82
	; one conversion per sequence
	BCLR	ATDCTL3,mATDCTL3_S4C  ;at 0x83
;	BSET	ATDCTL3,mATDCTL3_S1C  ;at 0x83
; Select 2 clock sample time and divide by 12 prescaler.
	BCLR	ATDCTL4,mATDCTL4_SMP0|mATDCTL4_SMP1	; Select 2 conversion clock periods
	BSET	ATDCTL4,mATDCTL4_PRS0	; divide by 12 conversion freq
	BSET	ATDCTL4,mATDCTL4_PRS2	; divide by 12 conversion freq
	BSET  ATDCTL4,mATDCTL4_SRES8  ; select 8 bit resolution ; at 0x84
convert:
  LDAA  #ATDMODE
	STAA ATDCTL5		; Start the conversion by writing to ATDCTL5 at 0x85

spin:	BRCLR	ATDSTAT1,mATDSTAT1_CCF5,spin	; wait for conversion to complete at 0x8B
  BSET  ATDSTAT1, mATDSTAT1_CCF5 ; clear flag
	CLRA		; set A=0

	LDAB	ATDDR5L	; get 8-bt value from Channel 4 at 0x99F, which was how the module worked.
	LDY	#RESOLUTION	; convert to 0.1 mV
	EMUL	;multiply (D)x(Y)=Y:D to obtain mV
	LDX	#10
	IDIV	; D/X = X remainder in D to get ones digit in mv in D
	STX voltA
	
spin2:	BRCLR	ATDSTAT1,mATDSTAT1_CCF7,spin2	; wait for conversion to complete at 0x8B
  BSET  ATDSTAT1, mATDSTAT1_CCF7 ; clear flag
	CLRA		; set A=0

	LDAB	ATDDR7L	; get 8-bt value from Channel 6 at 0x99F, which was how the module worked.
	LDY	#RESOLUTION	; convert to 0.1 mV
	EMUL	;multiply (D)x(Y)=Y:D to obtain mV
	LDX	#10
	IDIV	; D/X = X remainder in D to get ones digit in mv in D
	STX voltB
	
	PSHX
	LDX	#Wait_Time
  JSR NOP_WAIT
  PULX
  
  PSHX
	LDX	#Wait_Time
  JSR NOP_WAIT
  PULX
  
;DONE:	BRA convert
  RTS
  

NOP_WAIT: PSHX

delay:	  NOP
          NOP
          NOP 
          DBNE	A,delay
           
EXIT_NOP: PULX 
          RTS