;; The purpose of this program is to test gpsim's ability to
;; simulate interrupts on the midrange core (specifically the 'f84).
list p=16f84 ; list directive to define processor
include <p16f84.inc> ; processor specific variable definitions
include <coff.inc> ; Grab some useful macros
;; Suppress warnings of using 'option' instruction.
errorlevel -224
__CONFIG _WDT_OFF
GPR_DATA UDATA
temp RES 1
temp1 RES 1
temp2 RES 1
temp3 RES 1
temp4 RES 1
temp5 RES 1
adr_cnt RES 1
data_cnt RES 1
failures RES 1
w_temp RES 1
status_temp RES 1
GLOBAL temp,temp1,temp2,temp3,temp4,temp5
GLOBAL start
;----------------------------------------------------------------------
; ********************* RESET VECTOR LOCATION ********************
;----------------------------------------------------------------------
RESET_VECTOR CODE 0x000 ; processor reset vector
movlw high start ; load upper byte of 'start' label
movwf PCLATH ; initialize PCLATH
goto start ; go to beginning of program
;------------------------------------------------------------------------
;
; Interrupt Vector
;
;------------------------------------------------------------------------
INT_VECTOR CODE 0x004 ; interrupt vector location
movwf w_temp
swapf STATUS,W
movwf status_temp
check_rbi:
btfsc INTCON,RBIF
btfss INTCON,RBIE
goto check_int
bsf temp5,1 ;Set a flag to indicate rb4-7 int occured
bcf INTCON,RBIF
check_int:
btfsc INTCON,INTF
btfss INTCON,INTE
goto check_t0
bsf temp5,0 ;Set a flag to indicate rb0 int occured
bcf INTCON,INTF
check_t0:
btfsc INTCON,T0IF
btfss INTCON,T0IE
goto exit_int
;; tmr0 has rolled over
bcf INTCON,T0IF ; Clear the pending interrupt
bsf temp1,0 ; Set a flag to indicate rollover
exit_int:
swapf status_temp,w
movwf STATUS
swapf w_temp,f
swapf w_temp,w
retfie
;----------------------------------------------------------------------
; ******************* MAIN CODE START LOCATION ******************
;----------------------------------------------------------------------
MAIN CODE
start
;; Assume no failures
clrf failures
;;
;; tmr0 test
;;
;; The following block of code tests tmr0 together with interrupts.
;; Each prescale value (0-7) is loaded into the timer. The software
;; waits until the interrupt due to tmr0 rollover occurs before
;; loading the new prescale value.
bsf INTCON,T0IE ;Enable TMR0 overflow interrupts
bsf INTCON,GIE ;Global interrupts
clrf temp1 ;Software flag used to monitor when the
;interrupt has been serviced.
clrw
test_tmr0:
option ;Assign new prescale value
btfss temp1,0 ;Wait for the interrupt to occur and
goto $-1 ;get serviced
clrf temp1 ;Clear flag for the next time
bsf STATUS,RP0
incf (OPTION_REG^0x80),W
bcf STATUS,RP0
andlw 0x7 ;Check the prescaler
skpz
goto test_tmr0
bcf INTCON,T0IE ;Disable tmr0 interrupts
;; Now check tmr0 with an external clock source
;;
;; It assumes that port b bit 0 is the stimulus.
;; This requires that the following gpsim commands be invoked:
;; gpsim> node new_test_node
;; gpsim> attach new_test_node porta4 portb0
bsf STATUS,RP0
bcf (TRISB ^ 0x80),0 ;portb bit 0 is an output
bcf STATUS,RP0
;; assign the prescaler to the wdt so that tmr0 counts every edge
;; select the clock source to be tocki
;; and capture low to high transitions (tose = 0)
movlw (1<<T0CS) | (1<<PSA)
; movlw (1<<T0CS) | (1<<PSA) | (1<<T0SE)
option
movlw 0xff
movwf temp2
movwf temp3
movwf temp4
bcf INTCON,T0IF ;not necessary..., but clear pending int.
bsf INTCON,T0IE ;Re-enable tmr0 interrupts
tmr0_l1:
bcf temp1,0 ;Interrupt flag
clrz
bcf PORTB,0
btfsc temp1,0
decf temp2,f ;Falling edge caused the interrupt
bcf temp1,0
bsf PORTB,0
btfsc temp1,0
decf temp3,f ;Rising edge caused the interrupt
;; if either temp2 or temp3 decremented to zero, then z will be set
skpz
goto tmr0_l1
incfsz temp4,f
goto test_inte
;; Now let's test external clocking with the falling edge
movlw (1<<T0CS) | (1<<PSA) | (1<<T0SE)
option
goto tmr0_l1
;; tmr0 test is done.
;;
;; inte test
;;
;; The following block of code tests the interrupt on
;; change for port b bit 0. It assumes that port a bit 4
;; is the stimulus. This requires that the following
;; gpsim commands be invoked:
;; gpsim> node new_test_node
;; gpsim> attach new_test_node porta4 portb0
;;
;; Also, recall that porta bit 4 is an open collector
;; output (it can't drive high). So to generate the
;; the logic highs, the portb weak pull-up resistors
;; need to be enabled.
test_inte:
bsf STATUS,RP0
bcf (TRISA ^ 0x80),4 ;Make porta bit 4 an output
bsf (TRISB ^ 0x80),0 ;and portb bit 0 an input
bcf (OPTION_REG^0x80),NOT_RBPU ;Enable the portb weak pull-ups
bsf (OPTION_REG^0x80),INTEDG ;Interrupt on rising edge
bcf STATUS,RP0
movlw 0xff
movwf temp1
movwf temp2
movwf temp3
movwf temp4
bcf PORTA,4
bcf INTCON,RBIF
bsf INTCON,INTE
;;
;; This routine toggles porta bit 4 with the hope of generating
;; an interrupt on portb bit 0.
;; temp1 counts the number of times an interrupt has occurred
;; temp2 counts the number of times the interrupt was due to
;; a rising edge.
inte_edgecount:
bcf temp5,0 ;Interrupt flag
clrz
bcf PORTA,4 ;Falling edge
btfsc temp5,0
decf temp2,f ;Falling edge caused the interrupt
bcf temp5,0
bsf PORTA,4 ;Rising edge
btfsc temp5,0
decf temp3,f ;Rising edge caused the interrupt
;; if either temp2 or temp3 decremented to zero, then z will be set
skpz
goto inte_edgecount
incfsz temp4,f
goto test_rbif
;; Now let's test the falling edge
bcf INTCON,INTE ;Disable inte interrupt
bcf PORTA,4
bcf INTCON,INTF
bsf STATUS,RP0
bcf (OPTION_REG^0x80),INTEDG ;Interrupt on falling edge
bcf STATUS,RP0
bsf INTCON,INTE
goto inte_edgecount
;;
;; test_rbif
;;
;; This next block tests the interrupt on change feature of
;; port b's I/O pins 4-7
;;
test_rbif
bcf INTCON,INTE ;Disable the rb0 interrupt
bsf STATUS,RP0
bsf (TRISA ^ 0x80),4 ;Porta bit 4 is now an input
bcf STATUS,RP0
clrf temp5 ;Interrupt flag
clrf temp1
movlw 0x10
movwf temp2
rbif_l1:
bcf INTCON,RBIE
movf temp2,w
tris PORTB
clrf PORTB
movf PORTB,W
clrf temp5 ;Interrupt flag
bcf INTCON,RBIF
bsf INTCON,RBIE
swapf temp2,w
movwf PORTB
btfsc temp5,1
iorwf temp1,f
.assert "(temp5 & 2) == 2"
clrc
rlf temp2,f
skpc
goto rbif_l1
done:
.assert "\"*** PASSED MidRange core interrupt test\""
goto $
failed:
.assert "\"*** FAILED MidRange core interrupt test\""
goto $
end
syntax highlighted by Code2HTML, v. 0.9.1