1	list    p=18f26k22               ; list directive to define processor
2	include <p18f26k22.inc>          ; processor specific variable definitions
3        include <coff.inc>              ; Grab some useful macros
4
5.command macro x
6  .direct "C", x
7  endm
8
9;----------------------------------------------------------------------
10;----------------------------------------------------------------------
11GPR_DATA                UDATA 0
12temp            RES     1
13temp1           RES     1
14temp2           RES     1
15failures        RES     1
16
17a2dIntFlag	RES	1  ;LSB is set when an A2D interrupt occurs
18
19  GLOBAL done
20  GLOBAL a2dIntFlag
21
22  CONFIG MCLRE=INTMCLR
23
24;------------------------------------------------------------------------
25STARTUP    CODE	0
26
27	bra	Start
28
29;------------------------------------------------------------------------
30;
31;  Interrupt Vector
32;
33;------------------------------------------------------------------------
34
35INT_VECTOR   CODE    0x008               ; interrupt vector location
36
37
38check_TMR0_interrupt:
39
40	btfsc	PIR1,ADIF	;If A2D int flag is not set
41	 btfsc	PIE1,ADIE	;Or the interrupt is not enabled
42	goto a2dint
43
44  .assert "'FAIL 18F26k22 unexpected interrupt'"
45	nop
46	RETFIE 1		; Then leave
47
48;;	An A/D interrupt has occurred
49a2dint:
50	bsf	a2dIntFlag,0	;Set a flag to indicate we got the int.
51	bcf	PIR1,ADIF	;Clear the a/d interrupt
52
53ExitInterrupt:
54	RETFIE	1
55
56
57;----------------------------------------------------------------------
58;   ******************* MAIN CODE START LOCATION  ******************
59;----------------------------------------------------------------------
60MAIN    CODE
61
62    .sim "p18f26k22.xpos = 192"
63    .sim "p18f26k22.ypos = 48"
64
65
66   .sim "module library libgpsim_modules"
67   ; Use a pullup resistor as a voltage source
68   .sim "module load pullup V1"
69   .sim "V1.resistance = 100.0"
70   .sim "V1.xpos = 48"
71   .sim "V1.ypos = 24"
72
73   .sim "module load pullup V2"
74   .sim "V2.resistance = 100.0"
75   .sim "V2.xpos = 48"
76   .sim "V2.ypos = 204"
77
78   ; V3 and na1 required for A/D to see voltage bug ?
79   ; RRR 5/06
80   .sim "module load pullup V3"
81   .sim "V3.resistance = 10e6"
82   .sim "V3.xpos = 48"
83   .sim "V3.ypos = 120"
84
85   .sim "node na0"
86   .sim "attach na0 V1.pin porta0"
87   .sim "node na1"
88   .sim "attach na1  V3.pin porta1"
89   .sim "node na3"
90   .sim "attach na3 V2.pin porta3"
91
92
93Start:
94
95
96    ; RA0 is an Analog Input.
97    ; RA1 - RA5 are all configured as outputs.
98    ;
99    ; Use VDD and VSS for Voltage references.
100    ;
101    ; AN0 is the only analog input
102    ; ADCS = 110   == FOSC/64
103    ; ADFM = 0     == 6 LSB of ADRESL are 0.
104    ;
105	BANKSEL ANSELA
106	movlw	0x01	; RA0 analog
107	movwf	ANSELA
108	clrf	TRISA
109	MOVLW	0xff
110	movwf	PORTA
111	movf	PORTA,W
112
113	MOVLW	1<<RA0
114	MOVWF	TRISA
115
116	MOVLW	0	; ADC ref = Vdd,Vss
117	MOVWF	ADCON1
118        MOVLW	(1<<ADCS1) | (1<<ADCS2)
119	MOVWF	ADCON2
120	MOVLW	(1<<ADON)
121	MOVWF	ADCON0
122
123	BSF	INTCON,GIE	;Global interrupts
124	BSF	INTCON,PEIE	;Peripheral interrupts
125	BSF	PIE1,ADIE	;A2D interrupts
126
127	RCALL	Convert
128	nop
129
130  .assert "adresh == 0xff, 'FALIED 18F26k22 a2d AN0=5V'"
131	nop
132
133        ;; The next test consists of misusing the A/D converter.
134        ;; TRISA is configured such that the I/O pins are digital outputs.
135        ;; Normally you want them to be configued as inputs. According to
136        ;; the data sheet, the A/D converter will measure the voltage produced
137        ;; by the digital I/O output:    either 0 volts or 5 volts (or Vdd).
138        ;; [I wonder if this would be a useful way of measuring the power supply        ;; level in the event that there's an external reference connected to
139        ;; an3?]
140
141
142;  .command "V1.resistance=1e6"
143
144        movlw   0
145        movwf   TRISA           ;Make the I/O's digital outputs
146        movwf   PORTA           ;Drive the digital I/O's low
147	movlw	0xff
148        movwf   ANSELA          ;Configure porta to be completely analog
149	bsf	ADCON0,CHS0	;Use AN1
150
151
152	RCALL	Convert
153
154  .assert "adresh == 0x00, 'FAILED 18F26k22 Digital low'"
155	nop
156
157	movlw	0x02
158	movwf	PORTA		; drive bit 1 high
159
160	RCALL	Convert
161
162  .assert "adresh == 0xff, 'FAILED 18F26k22 Digital high'"
163	nop
164
165        movlw   0xff
166        movwf   TRISA           ;Make the I/O's inputs
167	bcf	ADCON0,CHS0	;Use AN0
168
169  .command "V1.voltage=1.0"
170
171        rcall    Convert
172
173   .assert "adresh == 0x33, 'FAILED 18F26k22 AN0=1V'"
174        nop
175
176  .command "V2.voltage=2.0"
177	bsf	ADCON1,PVCFG0	; RA3 is Vref
178        rcall    Convert
179
180   .assert "adresh == 0x80, 'FAILED 18F26k22 AN0=1V Vref+=2V'"
181        nop
182
183	bsf	VREFCON0,FVREN
184	btfss	VREFCON0,FVRST
185	goto	$-2
186	movlw	0x7d
187	movwf	ADCON0		; read Vref 1.024
188	rcall	Convert
189	nop
190   .assert "adresh == 0x83, 'FAILED 18F26k22 FVR=1.024V Vref+=2V'"
191        nop
192
193done:
194  .assert  "'*** PASSED 18F26k22 a2d test'"
195        bra     $
196
197
198Convert:
199	BCF	a2dIntFlag,0	;Clear interrupt handshake flag
200
201	BSF	ADCON0,GO
202
203LWait:
204	BTFSS	a2dIntFlag,0	;Wait for the interrupt to set the flag
205	 bra	LWait
206
207	MOVF	ADRESH,W		;Read the high 8-bits of the result
208
209	RETURN
210
211        end
212