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

Subversion Repositories light52

[/] [light52/] [trunk/] [test/] [irq_test/] [src/] [irq_test.a51] - Rev 16

Go to most recent revision | Compare with Previous | Blame | View Log

; irq_test.a51 -- First interrupt service test.
;
; This progam 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.
; They are in the simulation test bench entity but not in the synthesizable
; demo top entity.
;
; 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.
;
;-------------------------------------------------------------------------------

        ; Include the definitions for the light52 derivative
        $nomod51
        $include (light52.mcu)
        
ext_irq_ctr     set     060h        ; Incremented by external irq routine

    
        ;-- Macros -------------------------------------------------------------

        ; putc: send character in A to console (UART)
putc    macro   character
        local   putc_loop
        mov     SBUF,character
putc_loop:
        ;mov     a,SCON
        ;anl     a,#10h
        ;jz      putc_loop
        endm
        
        ; put_crlf: send CR+LF to console
put_crlf macro
        putc    #13
        putc    #10
        endm
    
    
        ;-- Reset & interrupt vectors ------------------------------------------

        org     00h
        ljmp    start               ;
        org     03h
        ljmp    irq_ext
        org     0bh
        ljmp    irq_timer
        org     13h
        ljmp    irq_wrong
        org     1bh
        ljmp    irq_wrong
        org     23h
        ljmp    irq_wrong


        ;-- Main test program --------------------------------------------------
        org     30h
start:

        ; Disable all interrupts.
        mov     IE,#00

        
        ;---- External interrupt test --------------------------------------
        
        ; We'll be asserting the external interrupt request line 0, making
        ; sure the interrupt enable flags work properly. No other interrupt
        ; will be asserted simultaneously or while in the interrupt service
        ; routine.
        
        ; Trigger external IRQ with IRQs disabled, it should be ignored.
        mov     P1,#01h             ; Assert external interrupt line 0...
        nop                         ; ...give the CPU some time to acknowledge
        nop                         ; the interrupt...
        nop
        mov     a,ext_irq_ctr       ; ...and then make sure it hasn't.
        cjne    a,#00,fail_unexpected
        setb    EXTINT0.0           ; Clear external IRQ flag

        ; Trigger timer IRQ with external IRQ enabled but global IE disabled
        mov     IE,#01h             ; Enable external interrupt...
        mov     P1,#01h             ; ...and assert interrupt line.
        nop                         ; Wait a little...
        nop
        nop
        mov     a,ext_irq_ctr       ; ...and make sure the interrupt was NOT
        cjne    a,#00,fail_unexpected   ; serviced.
        setb    EXTINT0.0           ; Clear timer IRQ flag

        ; Trigger external IRQ with external and global IRQ enabled
        mov     P1,#00h             ; Clear the external interrupt line...
        mov     IE,#81h             ; ...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
        nop
        mov     a,ext_irq_ctr       ; ...and make sure it has been serviced.
        cjne    a,#01,fail_expected
        setb    EXTINT0.0          ; Clear timer IRQ flag

        ; End of irq test, print message and continue
        mov     DPTR,#text2
        call    puts

        ;---- Timer test ---------------------------------------------------
        ; Assume the prescaler is set for a 20us count period.
        
        ; 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
        ; functionality of the timer (not in this version of the test).
        
        mov     IE,#000h            ; Disable all interrupts...
                                    ; ...and put timer in
        mov     TSTAT,#00           ; Stop timer...
        mov     TH,#00              ; ...set counter = 0...
        mov     TL,#00              ;
        mov     TCH,#0c3h           ; ...and set Compare register = 50000.
        mov     TCL,#050h           ; (50000 counts = 1 second)
        mov     TSTAT,#030h         ; Start counting.

        ; Ok, now wait for a little less than 20us and make sure TH:TL has not
        ; changed yet.
        mov     r0,#95              ; We need to wait for 950 clock cycles...
loop0:                              ; ...and this is a 10-clock loop
        nop
        djnz    r0,loop0
        mov     a,TH
        cjne    a,#000h,fail_timer_error
        mov     a,TL
        cjne    a,#000h,fail_timer_error
        
        ; Now wait for another 100 clock cycles and make sure TH:TL has already
        ; changed.
        mov     r0,#10              ; We need to wait for 100 clock cycles...
loop1:                              ; ...and this is a 10-clock loop
        nop
        djnz    r0,loop1
        mov     a,TH
        cjne    a,#000h,fail_timer_error
        mov     a,TL
        cjne    a,#001h,fail_timer_error

        ; End of timer test, print message and continue
        mov     DPTR,#text5
        call    puts

        ;-- End of test program, enter single-instruction endless loop
quit:   ajmp    $


fail_timer_error:
        mov     DPTR,#text4
        call    puts
        mov     IE,#00h
        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.

;-- puts: output to UART a zero-terminated string at DPTR ----------------------
puts:
        mov     r0,#00h
puts_loop:
        mov     a,r0
        inc     r0
        movc    a,@a+DPTR
        jz      puts_done

        putc    a
        sjmp    puts_loop
puts_done:
        ret

;-- irq_timer: interrupt routine for timer -------------------------------------
; Note we don't bother to preserve any registers.
irq_ext:
        mov     P1,#00h             ; Remove the external interrupt request
        mov     EXTINT0,#0ffh       ; Clear all external IRQ flags
        inc     ext_irq_ctr         ; Increment irq counter
        mov     DPTR,#text0         ; Print IRQ message...
        call    puts
        reti                        ; ...and quit
        
irq_timer:
irq_wrong:
        ajmp    irq_wrong

        ; End of the utility routines. Define constant data and we're done.

text0:  db      '<External irq>',13,10,00h,00h
text1:  db      'Unexpected IRQ',13,10,00h,00h
text2:  db      'IRQ test finished, no errors',13,10,0
text3:  db      'Missing IRQ',13,10,0
text4:  db      'Timer error',13,10,0
text5:  db      'Timer test finished, no errors',13,10,0
    
        end

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

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