1;
2;
3; Copyright (c) 2013 Roy Rankin
4;
5; This file is part of the gpsim regression tests
6;
7; This library is free software; you can redistribute it and/or
8; modify it under the terms of the GNU Lesser General Public
9; License as published by the Free Software Foundation; either
10; version 2.1 of the License, or (at your option) any later version.
11;
12; This library is distributed in the hope that it will be useful,
13; but WITHOUT ANY WARRANTY; without even the implied warranty of
14; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15; Lesser General Public License for more details.
16;
17; You should have received a copy of the GNU Lesser General Public
18; License along with this library; if not, see
19; <http://www.gnu.org/licenses/lgpl-2.1.html>.
20
21	list	p=16f1823
22        include <p16f1823.inc>
23        include <coff.inc>
24
25
26	;; The purpose of this program is to test gpsim's ability to
27	;; simulate a pic 16f1823.
28	;; Specifically, SPI
29
30        errorlevel -302
31
32; Printf Command
33.command macro x
34  .direct "C", x
35  endm
36
37  __CONFIG _CONFIG2, _PLLEN_OFF
38
39#define SDO_PORT PORTC,2
40#define SDI_PORT PORTC,1
41#define SCK_PORT PORTC,0
42#define SS_PORT PORTC,3
43
44#define SDO_TRIS TRISC,2
45#define SDI_TRIS TRISC,1
46#define SCK_TRIS TRISC,0
47#define SS_TRIS TRISC,3
48
49#define DRV_CLOCK PORTA,1
50#define DRV_CLOCK_TRIS TRISA,1
51
52
53;----------------------------------------------------------------------
54;----------------------------------------------------------------------
55GPR_DATA                UDATA_SHR
56
57w_temp RES  1
58status_temp RES  1
59loopcnt	RES	1
60
61
62
63;----------------------------------------------------------------------
64;   ********************* RESET VECTOR LOCATION  ********************
65;----------------------------------------------------------------------
66RESET_VECTOR  CODE    0x000              ; processor reset vector
67        movlp  high  start               ; load upper byte of 'start' label
68        goto   start                     ; go to beginning of program
69
70	;;
71	;; Interrupt
72	;;
73INT_VECTOR   CODE    0x004               ; interrupt vector location
74	movwf	w_temp
75	swapf	STATUS,W
76	movwf	status_temp
77
78        btfss   PIE1,SSP1IF
79        goto    check	                ; other Interrupts
80;        bsf     _TIME_OUT_              ; MUST set this Flag
81        bcf     PIE1,SSP1IF
82
83
84check:
85	swapf	status_temp,w
86	movwf	STATUS
87	swapf	w_temp,F
88	swapf	w_temp,W
89	retfie
90
91
92
93;----------------------------------------------------------------------
94;   ******************* MAIN CODE START LOCATION  ******************
95;----------------------------------------------------------------------
96MAIN    CODE
97start:
98
99   .sim "module lib libgpsim_modules"
100   .sim "module load pu pu1"
101   .sim "module load pu pu2"
102   .sim "module load not not"
103;   .sim "p16f88.xpos = 132."
104;   .sim "p16f88.ypos = 96."
105
106   .sim "not.xpos=264."
107   .sim "not.ypos=180."
108
109   .sim "pu1.xpos=252."
110   .sim "pu1.ypos=96."
111
112   .sim "pu2.xpos=264."
113   .sim "pu2.ypos=252."
114
115   .sim "node ss"
116   .sim "attach ss portc3 porta2"	; Not SS
117   .sim "node sck"
118   .sim "attach sck portc0 porta1 pu1.pin"	; SCK
119   .sim "node sdo"
120   .sim "attach sdo not.in0 portc2 pu2.pin"
121   .sim "node sdi"
122   .sim "attach sdi portc1 not.out"
123
124    BANKSEL	ANSELA
125    clrf	ANSELA
126    clrf	ANSELC
127    BANKSEL	OSCCON
128    movlw	(0xe<<3)|3	; set internal RC to 8 Mhz
129    movwf	OSCCON
130    BANKSEL	TRISC
131    bcf		SDO_TRIS	; SDO
132    bcf		SCK_TRIS	; SCK
133    movlw	0xff
134    BANKSEL	SSPSTAT
135    movwf	SSPSTAT
136  .assert "ssp1stat == 0xC0, 'SPI sspstat only SMP, CKE writable'"
137    nop
138    clrf	SSPSTAT
139
140
141;
142;  	Test SPI Master mode
143;
144    movlw	0x21	; SSPEN | SPI master Fosc/16
145    movwf	SSPCON1
146    movlw	0xab
147    movwf	SSPBUF
148    BANKSEL	PIR1
149    bcf		PIR1,SSP1IF
150
151loop:
152    btfss	PIR1,SSP1IF
153    goto	loop
154
155  .assert "(ssp1stat & 1) == 1, 'FAILED MSSP SPI Master BF not set'"
156    nop
157    BANKSEL	SSPBUF
158    movf	SSPBUF,W
159  .assert "(ssp1stat & 1) == 0, 'FAILED MSSP SPI Master BF not cleared'"
160    nop
161  .assert "W == 0x54, 'FAILED MSSP SPI Master wrong data'"
162    nop
163
164;
165;	TEST SPI Slave mode with SS
166;
167    clrf	SSPCON1
168    BANKSEL	TRISC
169    bcf		DRV_CLOCK_TRIS 	; external SCK drive
170    bsf		SCK_TRIS	; SCK
171    bsf		SS_TRIS 	; SS
172    BANKSEL	PORTA
173    bcf		DRV_CLOCK
174    bcf		PIR1,SSP1IF
175    banksel	SSPCON1
176    movlw	0x24	; SSPEN | SPI slave mode SS enable
177    movwf	SSPCON1
178    movlw	0xab
179    movwf	SSPBUF
180    BANKSEL	PORTA
181    bsf		DRV_CLOCK
182    bcf		DRV_CLOCK
183    BANKSEL	SSPBUF
184    movwf	SSPBUF	; test WCOL set
185  .assert "(ssp1con & 0x80) == 0x80, 'FAILED MSSP SPI WCOL set'"
186    nop
187    bcf		SSPCON1,WCOL	; clear WCOL bit
188  .assert "(ssp1con & 0x80) == 0x00, 'FAILED MSSP SPI WCOL was cleared'"
189    nop
190    clrf	loopcnt
191    BANKSEL	PORTA
192loop2:
193    incf	loopcnt,F
194    bsf		DRV_CLOCK
195    bcf		DRV_CLOCK
196    btfss	PIR1,SSP1IF
197    goto	loop2
198
199    BANKSEL	SSPBUF
200    movf	SSPBUF,W
201  .assert "W == 0x54, 'FAILED MSSP SPI Slave data'"
202    nop
203;
204;	Test Slave receive overrun
205;
206   movlw	0x10
207   movwf	loopcnt
208   BANKSEL	PORTA
209loop4:
210    bsf		DRV_CLOCK
211    bcf		DRV_CLOCK
212    decfsz	loopcnt,F
213    goto	loop4
214  .assert "(ssp1con & 0x40) == 0x40, 'FAILED MSSP SPI SSPOV'"
215    nop
216
217;
218;  	Test SPI Master mode TMR2
219;
220    BANKSEL	SSPCON1
221    clrf	SSPCON1
222    BANKSEL	TRISA
223    bsf		DRV_CLOCK_TRIS	; external SCK drive off
224    bcf		SCK_TRIS	; SCK output
225    BANKSEL	PR2
226    movlw	0x1
227    movwf	PR2
228    clrf	TMR2
229    movlw	0x3C	; prescale = 1 postscale 16
230    movwf	T2CON
231
232    bcf		PIR1,SSP1IF
233    BANKSEL	SSPCON1
234    movlw	0x23	; SSPEN | SPI master TMR2
235    movwf	SSPCON1
236    movlw	0xab
237    movwf	SSPBUF
238
239    BANKSEL	PIR1
240loop3:
241    btfss	PIR1,SSP1IF
242    goto	loop3
243
244  .assert "(ssp1stat & 1) == 1, 'FAILED MSSP SPI Master TMR2, BF not set'"
245    nop
246    BANKSEL	SSPBUF
247    movf	SSPBUF,W
248  .assert "(ssp1stat & 1) == 0, 'FAILED MSSP SPI Master TMR2, BF not cleared'"
249    nop
250  .assert "W == 0x54, 'FAILED MSSP SPI Master TMR2 wrong data'"
251    nop
252
253;
254;  	Test SPI Master mode with different clock phasing
255;
256    movlw	0x31	; SSPEN | SPI master Fosc/16 / CKP=1
257    movwf	SSPCON1
258    bsf         SSPSTAT,CKE     ; Delayed clock phasing
259    movlw	0xc9
260    movwf	SSPBUF
261    BANKSEL	PIR1
262    bcf		PIR1,SSP1IF
263
264loop5:
265    btfss	PIR1,SSP1IF
266    goto	loop5
267
268  .assert "(ssp1stat & 1) == 1, 'FAILED MSSP SPI Master BF not set'"
269    nop
270    BANKSEL	SSPBUF
271    movf	SSPBUF,W
272  .assert "(ssp1stat & 1) == 0, 'FAILED MSSP SPI Master BF not cleared'"
273    nop
274  .assert "W == 0x36, 'FAILED MSSP SPI Master (CKP) wrong data'"
275    nop
276
277
278;
279;  	Test SPI Master mode with BOEN set (MSSP1)
280;
281    bsf		SSPCON3,BOEN
282    movlw	0x3
283    movwf	SSPADD		; Fosc/16 (sspadd+1)*4
284    movlw	(1<<SSPEN)|0x0a	; SSPEN | SPI master Fosc/4*(spadd+1)
285    ;movlw	(1<<SSPEN)|0x01	; SSPEN | SPI master Fosc/4*(spadd+1)
286    movwf	SSPCON1
287    bcf         SSPSTAT,CKE     ; Delayed clock phasing
288    movlw	0xc9
289    movwf	SSPBUF
290    BANKSEL	PIR1
291    bcf		PIR1,SSP1IF
292
293    btfss	PIR1,SSP1IF
294    goto	$-1
295
296  .assert "(ssp1stat & 1) == 0, 'FAILED MSSP SPI Master BF not set BOEN=1'"
297    nop
298    BANKSEL	SSPBUF
299    movf	SSPBUF,W
300  .assert "W == 0x36, 'FAILED MSSP SPI Master sspadd (CKP) wrong data'"
301    nop
302
303
304
305  .assert "'*** PASSED 16f1823 MSSP SPI test'"
306    nop
307
308    goto $
309
310	end
311