PLP: Timer and Button Interrupt Service Routine

2

So I'm having trouble figuring out how to trigger a Timer interrupt (Every 200 cycles) and a button interrupt. When I hit the button interrupt all it seems to do is temporarily pause the counter for a split second and then continue counting. Then it never registers another button interrupt no matter how often I click it on PLP. What the button interrupt is suppose to do is set the register $a1 to 1 (or a non zero number) which is suppose to reset the counter. The Timer interrupt is suppose to flash the LEDs on every 200 cycles and then off after another 200 cycles and so forth. The seven segment display code is already provided for so what it does is just count up from 0-9 then A-F, and then starts over with the 10s. So 11, 12, ... , 19, 1A, 1B, ... , 1F, 20, etc.

.org 0x10000000
li $sp, 0x10fffffc  # Stack pointer initialization
li $s0, sseg_lut    # Lookup table address used by sseg_display
lui $s1, 0xf070 # Interrupt controller register
lui $s2, 0xf0a0 # Seven segment display


# TODO: enable interrupts here:
# ************************************************************
# Interrupt Initialization
li $t2, 0b1011 #value used to enable the used interrupts
li $t4, 0b00000000 #value used to check if LEDs are off
li $t5, 0b11111111 #value used to check if LEDs are on
li $t6, 0xf0600000 #address of the Timer
li $t7, 0xC8 #number of cycles we want the timer interrupt to be triggered 
sw $t7, 0($t6) #Store value onto timer in order to trigger interrupt????????????????
li $t8, 0xf0200000 #address of LEDs
sw $t2, 0($s1) #set mask register to enable the used interrupts including Global Interrupt Enable 
li $iv, isr #interrupt vector 

# ************************************************************

main:
    jal sseg_display
    nop
    addiu $a0, $a0, 1
    beq $a1, $0, no_counter_reset
        nop
        move $a0, $0
        move $a1, $0
    no_counter_reset:
    j main
    nop


# TODO: add interrupt service routine here:
# ************************************************************
# Interrupt Service Routine

isr: 
    save
    li $t0, 0b0011 #value used to check for timer interrupt
    li $t1, 0b1001 #value used to check for button interrupt
    lw $i0, 0($t8) #check what is stored currently on LEDs
    lw $i1, 4($s1) #load what value is in the status register
    j mainISR
    nop
    mainISR:
        beq $i1, $t0, timerInterrupt #check if the interrupt was triggered by timer
        nop
        beq $i1, $t1, buttonInterrupt #check if interrupt was triggered by button
        nop
        timerInterrupt: 
            beq $t4, $i0, turnOnLEDs #If the LEDs are off, go to the loop to turn them on
            nop
            bne $t4, $i0, turnOffLEDs #If the LEDs are on, go to the loop to turn them off 
            nop
            turnOnLEDs:
                sw $t5, 0($t8) #Stores the value to the LEDs to turn them all on 
                li $i1, 0b1001 #Bits used to clear interrupt in status register 
                j endISR #Jump to the end of the isr 
                nop
            turnOffLEDs:
                sw $t4, 0($t8) #Stores the value to the LEDs to turn them all off 
                li $i1, 0b1001 #Bits used to clear interrup in status register 
                j endISR #Jump to the end of the isr 
                nop
        buttonInterrupt: 
            li $a1, 1 #Set $a1 to 1, per the instructions to reset counter 
            li $i1, 0b0011 #Bits used to clear interrupt in status register 
            j endISR #Jump to end of isr 
            nop
    j mainISR #possibly unnecessary isr loop 
    nop
    endISR:
        sw $i1, 4($s1) #clear handled interrupts
        lw $i1, 0($s1) #get the mask register
        ori $i1, $i1, 1 #set Global Interrupt Enable
        restore
        jr $ir
        sw $i1, 0($s1) #resets all interrupts

# ************************************************************
assembly
timer
mips
interrupt-handling
isr

1 Answer

0

The timer triggers when overflow occurs. It is 32 bit timer so when you go past value 0xffff ffff your isr will be called.

The way to do it for 0xC8 cycles is

li $t7,0xffff ffff
li $t8,0xC8
subu $t7,$t7,$t8
sw $t7,0($t6)
answered on Stack Overflow Apr 19, 2019 by manu datta

User contributions licensed under CC BY-SA 3.0