OpenCores
URL https://opencores.org/ocsvn/light52/light52/trunk

Subversion Repositories light52

[/] [light52/] [trunk/] [test/] [irq_test/] [src/] [irq_test.a51] - Diff between revs 16 and 18

Show entire file | Details | Blame | View Log

Rev 16 Rev 18
Line 1... Line 1...
; irq_test.a51 -- First interrupt service test.
; irq_test.a51 -- Basic interrupt service test.
;
;
; This progam is only meant to work in the simulation test bench, because it
; This program is only meant to work in the simulation test bench, because it
; requires the external interrupt inputs to be wired to the P1 output port.
; requires the external interrupt inputs to be wired to the P1 output port.
; They are in the simulation test bench entity but not in the synthesizable
; They are in the simulation test bench entity but not in the synthesizable
; demo top entity.
; demo top entity.
;
;
; Its purpose is to demonstrate the working of the interrupt service logic. No
; Its purpose is to demonstrate the working of the interrupt service logic. No
; actual tests are performed (other than the co-simulation tests), only checks.
; actual tests are performed (other than the co-simulation tests), only checks.
;
;
 
; This program makes the following assumptions about the MCU configuration:
 
;
 
; 1.- Port line P1.0 is wired to external input EXTINT0.0
 
; 2.- The timer prescaler is set to 20us@50MHz.
 
;
 
; NOTE: I am aware that this code is perfectly hideous and nearly useless as a
 
; test bench; it will have to do for the time being. I can seldom find quality
 
; time for this project...
;-------------------------------------------------------------------------------
;-------------------------------------------------------------------------------
 
 
        ; Include the definitions for the light52 derivative
        ; Include the definitions for the light52 derivative
        $nomod51
        $nomod51
        $include (light52.mcu)
        $include (light52.mcu)
 
 
ext_irq_ctr     set     060h        ; Incremented by external irq routine
ext_irq_ctr     set     060h        ; Incremented by external irq routine
 
timer_irq_ctr   set     062h        ; Incremented by timer irq routine
 
uart_irq_ctr    set     063h        ; Incremented by uart irq routine
 
irq_test_code   set     064h        ; Selects the behavior of the irq routines
 
 
 
 
        ;-- Macros -------------------------------------------------------------
        ;-- Macros -------------------------------------------------------------
 
 
        ; putc: send character in A to console (UART)
        ; putc: send character in A to console (UART)
putc    macro   character
putc    macro   character
        local   putc_loop
        local   putc_loop
        mov     SBUF,character
        mov     SBUF,character
putc_loop:
putc_loop:
 
        ; This program will only ever run in the simulated environment, where
 
        ; UART transmission is instantaneous. No need to loop here.
        ;mov     a,SCON
        ;mov     a,SCON
        ;anl     a,#10h
        ;anl     a,#10h
        ;jz      putc_loop
        ;jz      putc_loop
        endm
        endm
 
 
Line 52... Line 65...
        ljmp    irq_wrong
        ljmp    irq_wrong
 
 
 
 
        ;-- Main test program --------------------------------------------------
        ;-- Main test program --------------------------------------------------
        org     30h
        org     30h
 
 
 
        ; Place a few utility routines here at the start so they are reachable
 
        ; by CJNE.
 
 
 
        ; Did not get expected IRQ: print failure message and block.
 
fail_expected:
 
        mov     DPTR,#text3
 
        call    puts
 
        mov     IE,#00h
 
        ajmp    $
 
 
 
        ; Got unexpected IRQ: print failure message and block.
 
fail_unexpected:
 
        mov     DPTR,#text1
 
        call    puts
 
        mov     IE,#00h
 
        ajmp    $
 
 
 
 
start:
start:
 
 
        ; Disable all interrupts.
        mov     IE,#00              ; Disable all interrupts...
        mov     IE,#00
        mov     IP,#01              ; ...and set EXTINT as high-priority.
 
        mov     irq_test_code,#00h  ; Tell irq routines to only inc the counters
 
 
 
 
        ;---- External interrupt test --------------------------------------
        ;---- External interrupt test --------------------------------------
 
 
 
        ; Basic interrupt test.
 
 
        ; We'll be asserting the external interrupt request line 0, making
        ; We'll be asserting the external interrupt request line 0, making
        ; sure the interrupt enable flags work properly. No other interrupt
        ; sure the interrupt enable flags work properly. No other interrupt
        ; will be asserted simultaneously or while in the interrupt service
        ; will be asserted simultaneously or while in the interrupt service
        ; routine.
        ; routine.
 
 
Line 82... Line 117...
        nop                         ; Wait a little...
        nop                         ; Wait a little...
        nop
        nop
        nop
        nop
        mov     a,ext_irq_ctr       ; ...and make sure the interrupt was NOT
        mov     a,ext_irq_ctr       ; ...and make sure the interrupt was NOT
        cjne    a,#00,fail_unexpected   ; serviced.
        cjne    a,#00,fail_unexpected   ; serviced.
        setb    EXTINT0.0           ; Clear timer IRQ flag
        setb    EXTINT0.0           ; Clear external IRQ flag
 
 
        ; Trigger external IRQ with external and global IRQ enabled
        ; Trigger external IRQ with external and global IRQ enabled
        mov     P1,#00h             ; Clear the external interrupt line...
        mov     P1,#00h             ; Clear the external interrupt line...
        mov     IE,#81h             ; ...before enabling interrupts globally.
        mov     IE,#81h             ; ...before enabling interrupts globally.
        mov     ext_irq_ctr,#00     ; Reset the interrupt counter...
        mov     ext_irq_ctr,#00     ; Reset the interrupt counter...
Line 94... Line 129...
        nop                         ; Give it some time to be acknowledged...
        nop                         ; Give it some time to be acknowledged...
        nop
        nop
        nop
        nop
        mov     a,ext_irq_ctr       ; ...and make sure it has been serviced.
        mov     a,ext_irq_ctr       ; ...and make sure it has been serviced.
        cjne    a,#01,fail_expected
        cjne    a,#01,fail_expected
        setb    EXTINT0.0          ; Clear timer IRQ flag
        setb    EXTINT0.0           ; Clear external IRQ flag
 
 
 
        ; Somewhat less basic interrupt test: priorities.
 
 
 
        ; Here we are going to use the test code byte (irq_test_code) to tell
 
        ; the interrupt routines what we want them to do. Since we only use two
 
        ; interrupt routines to test everything, each routine has to perform
 
        ; a few different roles.
 
        ; Basically we want to make sure that the irq priority rules hold:
 
        ;
 
        ; A.-Nothing can interrupt a high priority irq routine.
 
        ; B.- Only a high-priority irq can interrupt a low-priority irq.
 
        ; C.- Simultaneous irqs get ordered by their vector number.
 
        ;
 
        ; Rule C will NOT be tested in this program; and rules B and A get only
 
        ; the most basic of basic tests.
 
 
 
        ; Run test 1: Trigger another external interrupt while serving an
 
        ; external interrupt. Since both are high-priority, the timer interrupt
 
        ; should be ignored.
 
        mov     irq_test_code,#01h
 
        mov     P1,#00h             ; Clear the external interrupt line...
 
        mov     IE,#83h             ; ...before enabling interrupts globally.
 
        mov     ext_irq_ctr,#00     ; Reset the interrupt counter...
 
        mov     P1,#01h             ; ...and assert the external interrupt.
 
        nop                         ; Give it some time to be acknowledged...
 
        nop
 
        mov     a,ext_irq_ctr       ; ...and make sure it has been serviced.
 
        cjne    a,#01,fail_expected
 
        setb    EXTINT0.0           ; Clear external IRQ flag
 
 
 
        ; Run test 2: Trigger Timer interrupt while serving an external
 
        ; interrupt. Since the Timer irq is low-priority, it should be ignored.
 
        mov     irq_test_code,#02h
 
        mov     P1,#00h             ; Clear the external interrupt line...
 
        mov     IE,#83h             ; ...before enabling interrupts globally.
 
        mov     ext_irq_ctr,#00     ; Reset the interrupt counter...
 
        mov     P1,#01h             ; ...and assert the external interrupt.
 
        nop                         ; Give it some time to be acknowledged...
 
        nop
 
        mov     a,ext_irq_ctr       ; ...and make sure it has been serviced.
 
        cjne    a,#01,fail_expected
 
        setb    EXTINT0.0           ; Clear external IRQ flag
 
 
 
        ; Run test 3: Trigger interrupts within the timer interrupt service
 
        ; routine.
 
        mov     irq_test_code,#03h
 
        mov     timer_irq_ctr,#00h
 
        mov     P1,#00h             ; Clear the external interrupt line...
 
        mov     IE,#83h             ; ...before enabling interrupts globally.
 
        mov     ext_irq_ctr,#00     ; Reset the interrupt counter...
 
        mov     TSTAT,#01           ; Stop timer and clear timer interrupt...
 
        mov     TH,#00h             ; ...set counter = 000h...
 
        mov     TL,#00h             ;
 
        mov     TCH,#00h            ; ...and set Compare register = 0001h...
 
        mov     TCL,#01h            ;
 
        mov     TSTAT,#030h         ; ...then start counting.
 
 
 
        mov     r1,#95              ; Wait for the timer IRQ to trigger...
 
loop_001:
 
        nop
 
        nop
 
        nop
 
        nop
 
        nop
 
        nop
 
        nop
 
        nop
 
        djnz    r1,loop_001         ; ...then make sure the timer irq has
 
        mov     a,timer_irq_ctr     ; been triggered.
 
        cjne    a,#01h,fail_expected_irq_bridge
 
 
        ; End of irq test, print message and continue
        ; End of irq test, print message and continue
        mov     DPTR,#text2
        mov     DPTR,#text2
        call    puts
        call    puts
 
 
Line 107... Line 212...
 
 
        ; All we will do here is make sure the counter changes at the right
        ; All we will do here is make sure the counter changes at the right
        ; time, i.e. 20us after being started. We will NOT test the full
        ; time, i.e. 20us after being started. We will NOT test the full
        ; functionality of the timer (not in this version of the test).
        ; functionality of the timer (not in this version of the test).
 
 
 
        ; Note that the irq tests above already assume the timer works... this
 
        ; test is somewhat redundant.
 
 
        mov     IE,#000h            ; Disable all interrupts...
        mov     IE,#000h            ; Disable all interrupts...
                                    ; ...and put timer in
                                    ; ...and put timer in
        mov     TSTAT,#00           ; Stop timer...
        mov     TSTAT,#00           ; Stop timer...
        mov     TH,#00              ; ...set counter = 0...
        mov     TH,#00              ; ...set counter = 0...
        mov     TL,#00              ;
        mov     TL,#00              ;
Line 145... Line 253...
        call    puts
        call    puts
 
 
        ;-- End of test program, enter single-instruction endless loop
        ;-- End of test program, enter single-instruction endless loop
quit:   ajmp    $
quit:   ajmp    $
 
 
 
fail_expected_irq_bridge:
 
        jmp     fail_expected_irq
 
 
fail_timer_error:
fail_timer_error:
        mov     DPTR,#text4
        mov     DPTR,#text4
        call    puts
        call    puts
        mov     IE,#00h
        mov     IE,#00h
        ajmp    $
        ajmp    $
 
 
 
 
        ; Did not get expected IRQ: print failure message and block.
 
fail_expected:
 
        mov     DPTR,#text3
 
        call    puts
 
        mov     IE,#00h
 
        ajmp    $
 
 
 
        ; Got unexpected IRQ: print failure message and block.
 
fail_unexpected:
 
        mov     DPTR,#text1
 
        call    puts
 
        mov     IE,#00h
 
        ajmp    $
 
 
 
        ; End of the test code. Now let's define a few utility routines.
        ; End of the test code. Now let's define a few utility routines.
 
 
;-- puts: output to UART a zero-terminated string at DPTR ----------------------
;-- puts: output to UART a zero-terminated string at DPTR ----------------------
puts:
puts:
        mov     r0,#00h
        mov     r0,#00h
Line 183... Line 278...
        putc    a
        putc    a
        sjmp    puts_loop
        sjmp    puts_loop
puts_done:
puts_done:
        ret
        ret
 
 
;-- irq_timer: interrupt routine for timer -------------------------------------
;-- irq_ext: interrupt routine for external irq lines --------------------------
; Note we don't bother to preserve any registers.
; Note we don't bother to preserve any registers.
irq_ext:
irq_ext:
        mov     P1,#00h             ; Remove the external interrupt request
        mov     P1,#00h             ; Remove the external interrupt request
        mov     EXTINT0,#0ffh       ; Clear all external IRQ flags
        mov     EXTINT0,#0ffh       ; Clear all external IRQ flags
        inc     ext_irq_ctr         ; Increment irq counter
        inc     ext_irq_ctr         ; Increment irq counter
 
        ; Ok, now check the test code byte to see what we have to do here.
 
        mov     a,irq_test_code
 
        cjne    a,#00h,irq_ext_0
 
 
 
        ; Test 0: Just increment irq counter (already done).
        mov     DPTR,#text0         ; Print IRQ message...
        mov     DPTR,#text0         ; Print IRQ message...
        call    puts
        call    puts
        reti                        ; ...and quit
        reti                        ; ...and quit
 
 
 
irq_ext_0:
 
        cjne    a,#02h,irq_ext_1
 
        ; Test 2: Trigger timer interrupt while in the service routine.
 
        ; Verify that low-priority interrupts get ignored while in the service
 
        ; routine of a high-priority interrupt.
 
        mov     timer_irq_ctr,#00h
 
        mov     TSTAT,#01           ; Stop timer and clear timer interrupt...
 
        mov     TH,#00h             ; ...set counter = 000h...
 
        mov     TL,#00h             ;
 
        mov     TCH,#00h            ; ...and set Compare register = 0001h.
 
        mov     TCL,#01h            ;
 
        mov     IE,#82h             ; Enable timer interrupt...
 
        mov     TSTAT,#030h         ; ...and start counting.
 
 
 
        mov     r0,#95               ; Wait for the timer interrupt to trigger...
 
irq_ext_test0_loop0:
 
        nop
 
        nop
 
        nop
 
        nop
 
        nop
 
        nop
 
        nop
 
        nop
 
        djnz    r0,irq_ext_test0_loop0  ; ...the make sure the timer irq has
 
        mov     a,timer_irq_ctr         ; NOT triggered.
 
        cjne    a,#00h,fail_unexpected_irq
 
        reti
 
 
 
irq_ext_1:
 
        cjne    a,#01h,irq_ext_2
 
 
 
        ; Test 1: Trigger external interrupt while in the service routine.
 
        ; Verify that high-priority interrupts get ignored while in the service
 
        ; routine of another high-priority interrupt.
 
        mov     ext_irq_ctr,#00h
 
        mov     irq_test_code,#00h
 
        mov     IE,#81h                 ; ...enable the UART irq...
 
        mov     P1,#01h                 ; ...and trigger it
 
 
 
        mov     r0,#10                  ; Give time for the irq to trigger...
 
irq_ext_test2_loop0:
 
        nop
 
        djnz    r0,irq_ext_test2_loop0  ; ...the make sure the Timer irq has
 
        mov     a,ext_irq_ctr           ; NOT triggered.
 
        cjne    a,#00h,fail_unexpected_irq
 
        reti
 
 
 
irq_ext_2:
 
        ; Code byte irq_test_code not used; ignored.
 
        reti
 
 
 
 
 
;-- irq_timer: interrupt routine for timer -------------------------------------
 
; Note we don't bother to preserve any registers.
irq_timer:
irq_timer:
 
        ; Check the test code to see what we have to do here.
 
        mov     a,irq_test_code
 
        cjne    a,#03,irq_timer_0
 
 
 
        ; Test code 3: interrupts within timer irq service routine.
 
 
 
        ; Trigger external interrupt within this irq service routine and make
 
        ; sure it gets serviced.
 
        mov     ext_irq_ctr,#00h
 
        mov     irq_test_code,#00h
 
        mov     IE,#81h                 ; ...enable the UART irq...
 
        mov     P1,#01h                 ; ...and trigger it
 
 
 
        mov     r0,#10                  ; Give time for the irq to trigger...
 
irq_timer_test3_loop0:
 
        nop
 
        djnz    r0,irq_timer_test3_loop0  ; ...the make sure the Timer irq has
 
        mov     a,ext_irq_ctr           ; NOT triggered.
 
        cjne    a,#01h,fail_expected_irq
 
 
 
        ; Ok, now re-trigger the timer interrupt within the timer service
 
        ; interrupt and make sure the new interrupt is not serviced.
 
        mov     irq_test_code,#00h
 
        mov     timer_irq_ctr,#00h
 
        mov     TSTAT,#01           ; Stop timer and clear timer interrupt...
 
        mov     TH,#00h             ; ...set counter = 000h...
 
        mov     TL,#00h             ;
 
        mov     TCH,#00h            ; ...and set Compare register = 0001h...
 
        mov     TCL,#01h            ;
 
        mov     TSTAT,#030h         ; ...then start counting.
 
 
 
        mov     r1,#95              ; Wait for the timer IRQ to trigger...
 
irq_timer_test3_loop1:
 
        nop
 
        nop
 
        nop
 
        nop
 
        nop
 
        nop
 
        nop
 
        nop
 
        djnz    r1,irq_timer_test3_loop1 ; ...then make sure the timer irq has
 
        mov     a,timer_irq_ctr     ; been ignored.
 
        cjne    a,#00h,fail_unexpected_irq
 
 
 
        inc     timer_irq_ctr       ; Increment timer interrupt counter...
 
        mov     TSTAT,#01           ; Stop timer and clear timer interrupt.
 
 
 
        reti
 
 
 
 
 
irq_timer_0:
 
        ; Test code 0: increment irq counter.
 
        ; Just increment the timer irq counter and quit.
 
        inc     timer_irq_ctr       ; Increment timer interrupt counter...
 
        mov     TSTAT,#01           ; Stop timer and clear timer interrupt.
 
        reti                        ; ...and quit.
 
 
irq_wrong:
irq_wrong:
        ajmp    irq_wrong
        ajmp    irq_wrong
 
 
 
        ; Utility functions -- error messages to console, etc.
 
 
 
        ; Got unexpected IRQ: print failure message and block.
 
fail_unexpected_irq:
 
        mov     DPTR,#text1
 
        call    puts
 
        mov     IE,#00h
 
        ajmp    $
 
 
 
        ; Did not get expected IRQ: print failure message and block.
 
fail_expected_irq:
 
        mov     DPTR,#text3
 
        call    puts
 
        mov     IE,#00h
 
        ajmp    $
 
 
        ; End of the utility routines. Define constant data and we're done.
        ; End of the utility routines. Define constant data and we're done.
 
 
text0:  db      '',13,10,00h,00h
text0:  db      '',13,10,00h,00h
text1:  db      'Unexpected IRQ',13,10,00h,00h
text1:  db      'Unexpected IRQ',13,10,00h,00h
text2:  db      'IRQ test finished, no errors',13,10,0
text2:  db      'IRQ test finished, no errors',13,10,0

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.