1   ;;  EUSART test
2   ;;
3   ;;  The purpose of this program is to verify that gpsim's
4   ;; USART functions properly when configured as an EUSART.
5   ;; The USART module is used to loop
6   ;; characters back to the receiver testing  RCIF interupts.
7   ;;
8   ;;
9   ;;
10
11	list	p=18f2221
12	include <p18f2221.inc>
13	include <coff.inc>
14
15 CONFIG WDT=OFF
16 CONFIG MCLRE=ON, LPT1OSC=OFF, PBADEN=DIG, CCP2MX=RC1
17
18
19        errorlevel -302
20	radix dec
21
22BAUDHI  equ     ((100000/4)/48)-1
23BAUDLO  equ     129
24
25
26;----------------------------------------------------------------------
27; RAM Declarations
28
29
30;
31INT_VAR        UDATA   0x00
32w_temp          RES     1
33status_temp     RES     1
34pclath_temp     RES     1
35
36
37
38GPR_DAT        UDATA
39
40#define	RX_BUF_SIZE	0x10
41
42temp1		RES	1
43temp2		RES	1
44temp3		RES	1
45
46tx_ptr		RES	1
47
48rxLastByte	RES	1
49rxFlag		RES	1
50
51;----------------------------------------------------------------------
52;   ********************* RESET VECTOR LOCATION  ********************
53;----------------------------------------------------------------------
54RESET_VECTOR  CODE    0x000              ; processor reset vector
55        goto   start                     ; go to beginning of program
56
57
58
59;------------------------------------------------------------------------
60;
61;  Interrupt Vector
62;
63;------------------------------------------------------------------------
64
65INT_VECTOR   CODE    0x018               ; interrupt vector location
66
67	movwf	w_temp
68	swapf	STATUS,w
69	clrf	STATUS
70	movwf	status_temp
71	movf	PCLATH,w
72	movwf	pclath_temp
73	clrf	PCLATH
74
75	btfsc	INTCON,PEIE
76	 btfss	PIR1,RCIF
77	  goto	int_done
78
79;;;	Received a Character
80   .assert "rcreg == txreg, '*** FAILED p18f2221 sent character looped back'"
81	nop
82	movf	RCREG,W
83	movwf	rxLastByte
84	bsf	rxFlag,0
85
86int_done:
87	clrf	STATUS
88	movf	pclath_temp,w
89	movwf	PCLATH
90	swapf	status_temp,w
91	movwf	STATUS
92	swapf	w_temp,f
93	swapf	w_temp,w
94	retfie
95
96
97;; ----------------------------------------------------
98;;
99;;            start
100;;
101
102MAIN    CODE
103start
104
105   .sim ".frequency=10e6"
106   .sim "break c 0x100000"
107   .sim "module library libgpsim_modules"
108   .sim "module load usart U1"
109   .sim "p18f2221.xpos = 48"
110   .sim "p18f2221.ypos = 48"
111
112   .sim "node PIC_tx"
113   .sim "node PIC_rx"
114
115   ;; Tie the USART module to the PIC
116   .sim "attach PIC_tx portc6  U1.RXPIN"
117   .sim "attach PIC_rx portc7 U1.TXPIN"
118
119   ;; Set the USART module's Baud Rate
120
121   .sim "U1.txbaud = 4800"
122   .sim "U1.rxbaud = 4800"
123   .sim "U1.loop = true"
124   .sim "U1.xpos = 216"
125   .sim "U1.ypos = 168"
126
127	;; USART Initialization
128	;;
129	;; Turn on the high baud rate (BRGH), disable the transmitter,
130	;; disable synchronous mode.
131	;;
132
133	clrf	STATUS
134
135	bsf	PORTC,6         ;Make sure the TX line drives high when
136                                ;it is programmed as an output.
137
138	bsf	TRISC,7		;RX is an input
139;	bsf	TRISC,6		;TX EUSART sets pin direction
140
141	;; CSRC - clock source is a don't care
142	;; TX9  - 0 8-bit data
143	;; TXEN - 0 don't enable the transmitter.
144	;; SYNC - 0 Asynchronous
145	;; BRGH - 1 Select high baud rate divisor
146	;; TRMT - x read only
147	;; TX9D - 0 not used
148
149	movlw	(1<<BRGH)
150	movwf	TXSTA
151
152	movlw   BAUDLO  	;4800 baud at 10MHz clock.
153	movwf   SPBRG
154
155
156  .assert "(portc & 0x40) == 0x40, '*** FAILED: p18f2221 TX bit initilized as high'"
157	clrf	tx_ptr
158
159	;; Turn on the serial port
160	movlw	(1<<SPEN) | (1<<CREN)
161	movwf	RCSTA
162
163	movf	RCREG,w          ;Clear RCIF
164	bsf	INTCON,GIE
165	bsf	INTCON,PEIE
166
167	movf	RCREG,w          ;Clear RCIF
168	movf	RCREG,w          ;Clear RCIF
169
170	;; Test TXIF, RCIF bits of PIR1 are not writable
171
172	clrf	PIR1
173	bsf	PIR1,RCIF
174	bsf	PIR1,TXIF
175  .assert "pir1 == 0x00, '*** FAILED p18f2221 TXIF, RCIF not writable'"
176	nop
177
178	;; Enable the transmitter
179	bsf	TXSTA,TXEN
180  .assert "pir1 == 0x10, '*** FAILED p18f2221 TXIF should now be set'"
181
182	bsf	TXSTA,SENDB
183	clrf	TXREG
184	btfsc	TXSTA,SENDB
185	bra	$-2
186	bsf	PIE1,RCIE	; Enable Rx interrupts
187
188	;; Now Transmit some data and verify that it is transmitted correctly.
189
190	call	TransmitNextByte
191   .assert "U1.rx == 0x31, '*** FAILED p18f2221 sending 0x31'"
192	nop
193	call	TransmitNextByte
194   .assert "U1.rx == 0x32, '*** FAILED p18f2221 sending 0x32'"
195	nop
196	call	TransmitNextByte
197   .assert "U1.rx == 0x33, '*** FAILED p18f2221 sending 0x33'"
198	nop
199	call	TransmitNextByte
200   .assert "U1.rx == 0x34, '*** FAILED p18f2221 sending 0x34'"
201	nop
202
203        ;; Switch to 16-bit BRG mode
204        bsf     BAUDCON,BRG16
205        movlw   low(BAUDHI)
206        movwf   SPBRG
207        movlw   high(BAUDHI)
208        movwf   SPBRGH
209        rcall   delay
210
211	call	TransmitNextByte
212   .assert "U1.rx == 0x35, '*** FAILED p18f2221 sending 0x35'"
213	call	TransmitNextByte
214   .assert "U1.rx == 0x36, '*** FAILED p18f2221 sending 0x36'"
215	call	TransmitNextByte
216   .assert "U1.rx == 0x37, '*** FAILED p18f2221 sending 0x37'"
217	call	TransmitNextByte
218   .assert "U1.rx == 0x38, '*** FAILED p18f2221 sending 0x38'"
219	call	TransmitNextByte
220   .assert "U1.rx == 0x39, '*** FAILED p18f2221 sending 0x39'"
221	nop
222;
223; setup tmr0
224;
225        movlw  0xC5          ; Tmr0 internal clock prescaler 64
226        movwf  T0CON
227
228        btfss   PIR1,TXIF       ;Wait for TXREG ready for write
229         goto   $-1
230        clrf    TMR0L
231        movlw   0x55
232        movwf   TXREG
233
234        btfss   TXSTA,TRMT ;Wait 'til through transmitting
235         bra    $-2
236;
237;  At 9600 baud each bit takes 0.104 msec. TRMT will be low > 9 bits
238;  and < 10 bits or between 0.9375 and 1.041 msec.
239;  with oscillator at 20MHz and TMR0 / 64 expect between 73 and 81
240;  TMR0 cycles.
241
242	movf	TMR0L,W
243
244  .assert "tmr0 > 73 && tmr0 < 81, '*** FAILED p18f2221 baud rate'"
245	nop
246	clrf	rxFlag
247        call rx_loop
248
249        ; Disable interrupts because the following tests don't give good receive bytes
250        bcf     PIE1,RCIE
251
252        bsf     TXSTA,SENDB     ; request a break sequence
253        btfss   PORTC,6         ; Shouldn't happen just yet
254    .assert "'*** FAILED p18f2221 break sent too soon'"
255        nop
256
257        clrf    TMR0L
258        movlw   0x55
259        movwf   TXREG
260
261        rcall   delay
262
263        btfsc   PORTC,6         ; Should happen by now
264    .assert "'*** FAILED p18f2221 to send break'"
265        nop
266
267        btfss   PORTC,6         ; Wait for stop bit
268         bra    $-2
269;
270;  At 4800 baud each bit takes 0.208 msec. Output will be low for
271;  start + 12 bit times or 2.70 msec. With 10Mhz TMR0 / 64 is 106 TMR0 counts.
272
273	movf	TMR0L,W
274
275  .assert "tmr0 > 101 && tmr0 <= 111, '*** FAILED sync pulse'"
276	nop
277
278done:
279  .assert  "'*** PASSED E-Usart on 18F2221'"
280	goto $
281
282
283
284tx_message:
285	incf	tx_ptr,w
286	andlw	0x0f
287	movwf	tx_ptr
288        addlw   0x30
289        return
290
291
292delay:
293	decfsz	temp2,f
294	 bra    delay
295	return
296
297
298
299TransmitNextByte:
300	clrf	rxFlag
301	call	tx_message
302	btfss	PIR1,TXIF
303	 bra	$-2
304	movwf	TXREG
305        clrwdt
306
307rx_loop:
308
309	btfss	rxFlag,0
310	 bra	rx_loop
311
312
313	return
314
315	end
316