1 2 list p=16f871 3 include <p16f871.inc> 4 include <coff.inc> 5 6 __CONFIG _WDT_OFF 7 8 9 ;; The purpose of this program is to test gpsim's ability to simulate 10 ;; the Parallel Slave port (PSP) functionality. 11 ;; 12 ;; Portb and portd form the PSP bus and porta pins 0, 1, and 2 13 ;; drive the, active low, bus control signals RD, WR and CS respectively 14 15 16 errorlevel -302 17 18; Printf Command 19.command macro x 20 .direct "C", x 21 endm 22 23;---------------------------------------------------------------------- 24;---------------------------------------------------------------------- 25GPR_DATA UDATA_SHR 26 27x RES 1 28t1 RES 1 29t2 RES 1 30avg_lo RES 1 31avg_hi RES 1 32w_temp RES 1 33status_temp RES 1 34 35 36;---------------------------------------------------------------------- 37; ********************* RESET VECTOR LOCATION ******************** 38;---------------------------------------------------------------------- 39RESET_VECTOR CODE 0x000 ; processor reset vector 40 movlw high start ; load upper byte of 'start' label 41 movwf PCLATH ; initialize PCLATH 42 goto start ; go to beginning of program 43 44 ;; 45 ;; Interrupt 46 ;; 47INT_VECTOR CODE 0x004 ; interrupt vector location 48 movwf w_temp 49 swapf STATUS,W 50 movwf status_temp 51 52 bcf STATUS,RP0 ;bank 0 53 54 btfsc PIR1,PSPIF 55 goto done 56 57 .assert "'FAILED 16F871 unexpected interupt'" 58 nop 59check: 60 swapf status_temp,w 61 movwf STATUS 62 swapf w_temp,F 63 swapf w_temp,W 64 retfie 65 66 67 68;---------------------------------------------------------------------- 69; ******************* MAIN CODE START LOCATION ****************** 70;---------------------------------------------------------------------- 71MAIN CODE 72start: 73 74 .sim "node pspRD" 75 .sim "attach pspRD porta0 porte0" 76 .sim "node pspWR" 77 .sim "attach pspWR porta1 porte1" 78 .sim "node pspCS" 79 .sim "attach pspCS porta2 porte2" 80 .sim "node p0" 81 .sim "attach p0 portb0 portd0" 82 .sim "node p1" 83 .sim "attach p1 portb1 portd1" 84 .sim "node p2" 85 .sim "attach p2 portb2 portd2" 86 .sim "node p3" 87 .sim "attach p3 portb3 portd3" 88 .sim "node p4" 89 .sim "attach p4 portb4 portd4" 90 .sim "node p5" 91 .sim "attach p5 portb5 portd5" 92 .sim "node p6" 93 .sim "attach p6 portb6 portd6" 94 .sim "node p7" 95 .sim "attach p7 portb7 portd7" 96 97; 98; The test relies on porta being digital I/O, and porte being PSP, so it's 99; necessary to disable all ADC channels 100 bsf STATUS,RP0 ; bank 1 101 movlw 0x07 102 movwf ADCON1 103 bcf STATUS,RP0 ; bank 0 104 105 106; 107; First test portd operates in normal mode 108 109 bsf STATUS,RP0 ; bank 1 110 clrf TRISD ; PortD output 111 bcf STATUS,RP0 ; bank 0 112 movlw 0x55 113 movwf PORTD 114 .assert "portd == 0x55, 'FAILED, Portd put value OK'" 115 nop 116 .assert "portb == 0x55, 'FAILED, Portd drives Portb'" 117 nop 118 movf PORTD,W ; check read Portd 119 .assert "W == 0x55, 'FAILED, Read portd OK'" 120 nop 121 bsf STATUS,RP0 ; bank 1 122 clrf TRISB ; PortB output 123 movlw 0xff 124 movwf TRISD ; PortD input 125 bcf STATUS,RP0 ; bank 0 126 movwf PORTB 127 .assert "portd == 0xff, 'FAILED, Read portd as input'" 128 nop 129 130 131; 132; Now test PSP in bus RD mode 133; 134 movlw 0x07 ; set bits high 135 movwf PORTA 136 bsf STATUS,RP0 ; bank 1 137 movlw 0xff 138 movwf TRISB 139 movlw 0xf8 140 movwf TRISA 141 movlw 0x17 142 movwf TRISE 143 bcf STATUS,RP0 ; bank 0 144 movlw 0xf0 145 movwf PORTD ; Output should not change in PSP mode 146 .assert "(trise & 0xe0) == 0x40, 'FAILED, OBF set on portd write'" 147 nop 148 .assert "portb != 0xf0, 'FAILED, Output not changed'" 149 nop 150 bcf PORTA,0 ; Drive RD low to put data on bus 151 bcf PORTA,2 ; Drive CS low to select 152 .assert "(trise & 0xe0) == 0x00, 'FAILED, OBF cleared on PSP RD'" 153 nop 154 .assert "portb == 0xf0, 'FAILED, Output on bus'" 155 nop 156 .assert "(pir1 & 0x80) == 0, 'FAILED, PSPIF not set until RD off'" 157 nop 158 bsf PORTA,0 ; Turn off RD 159 .assert "(pir1 & 0x80) == 0x80, 'FAILED, PSPIF set for RD'" 160 nop 161; 162; test PSP WR function 163; 164 bsf STATUS,RP0 ; bank 1 165 clrf TRISB ; set B as output 166 bcf STATUS,RP0 ; bank 0 167 movlw 0x0f 168 movwf PORTB ; drive bus 169 bcf PORTA,1 ; Turn on WR (CS already on) 170 .assert "(trise & 0xe0) == 0x00, 'FAILED, IBF not set yet'" 171 nop 172 bsf PORTA,2 ; Turn off CS 173 .assert "(trise & 0xe0) == 0x80, 'FAILED, IBF now set'" 174 nop 175 movf PORTD,W 176 .assert "W == 0x0f, 'FAILED, Value read from bus'" 177 nop 178 .assert "(trise & 0xe0) == 0x00, 'FAILED, IBF cleared on read of portd'" 179 nop 180 bcf PORTA,2 ; Turn on CS 181 bsf PORTA,2 ; Turn off CS 182 bcf PORTA,2 ; Turn on CS 183 bsf PORTA,2 ; Turn off CS 184 .assert "(trise & 0xe0) == 0xa0, 'FAILED, IBF, IBOV both set '" 185 nop 186 187 bsf STATUS,RP0 ; bank 1 188 movlw 0x17 189 movwf TRISE ; set B as output 190 .assert "(trise & 0xe0) == 0x80, 'FAILED, IBOV cleared, but not IBF '" 191 nop 192 movlw 0x07 ; turn off PSP 193 movwf TRISE ; set B as output 194 .assert "(trise & 0xf0) == 0x00, 'FAILED, IBF & PSPMODE claered'" 195 nop 196; 197; test interupts 198; 199 movlw 0x17 200 movwf TRISE 201 bsf PIE1,PSPIE 202 movlw 0xc0 203 movwf INTCON ; Enable interupts 204 bcf STATUS,RP0 ; bank 0 205 206 bcf PIR1,PSPIF 207 bcf PORTA,2 ; Turn on CS 208 bsf PORTA,2 ; Turn off CS 209 .assert "'FAILED, interrupt'" 210 nop 211 goto $-1 212 213 214 215done: 216 .assert "'*** PASSED 16F871 PSP test'" 217 218 goto $-1 219 220 221 end 222