title: RISC-V interrupts, setting up MTIMECMP
body: <p>I am trying to write a program in RISC-V assembly for HiFive1 board to wake up with timer interrupt 
  This is my interrupt setup routine</p>
  
  <pre><code>.section .text
  .align 2
  .globl setupINTERRUPT
  
  .equ MTIMECMP, 0x2004000
  
  
  setupINTERRUPT:
      addi sp, sp, -16                # allocate a stack frame, moves the stack up by 16 bits
      sw ra, 12(sp)                   # save return adress on stack
  
      li t0, 0x8                     # time interval at which to triger the interrupt
      li t1, MTIMECMP                 # MTIMECMP register of the CLINT memmory map
      sw t0, 0(t1)                    # store the interval in MTIMECMP memory location
  
      li t0, 0x800                      # make a mask for 3rd bit
      csrrs t1, mstatus, t0           # use CRS READ/SET instruction to set 3rd bit using previously defined mask
  
      li t0, 0x3                      # make a mask for 0th and 1st bit
      csrrc t1, mtvec, t0             # use CSR READ/CLEAR instruction to clear 0th and 1st bit
  
      li t0, 0x80                     # make a mask for 7th bit
      csrrs t1, mie, t0               # set 7th bit for MACHINE TIMER INTERRUPT ENABLE 
  
      lw ra, 12(sp)                   # restore the return address
      addi sp, sp, 16                 # dealocating stack frame
      ret 
  </code></pre>
  
  <p>I am not too sure if im setting the MTIMECMP correctly, i know its a 64 bit memory location. 
  I am trying to use this interrupt as a delay timer for a blinking LED (just trying to make sure the interrupt works before i move onto writing a handler)
  here is my setLED program. (not that all the GPIO register setup was done previously and is known to work). I have WFI instruction before each of the ON and OFF functions. The LED doesn't light up, even though in the debug mode it does. I think in LED it skips the WFI instruction as if the interrupt was asserted.  </p>
  
  <pre><code>.section .text
  .align 2
  .globl setLED 
  #include "memoryMap.inc"
  #include "GPIO.inc"
  .equ NOERROR,  0x0
  .equ ERROR,    0x1
  .equ LEDON,    0x1
  
  # which LED to set comes into register a0
  # desired On/Off state comes into a1
  
  setLED:
      addi sp, sp, -16          # allocate a stack frame, moves the stack up by 16 bits
      sw ra, 12(sp)             # save return adress on stack
  
      li t0, GPIO_CTRL_ADDR           # load GPIO adress 
      lw t1, GPIO_OUTPUT_VAL(t0)      # get the current value of the pins
  
      beqz a1, ledOff                 # Branch off to turn off led if a1 requests it
      li t2, LEDON                    # load up valued of LEDON into temp register
      beq a1, t2, ledOn               # branch if on requested
      li a0, ERROR                    # we got a bad status request, return an error
      j exit
  
  ledOn:
      wfi
      xor t1, t1, a0                  # doing xor to only change the value of requested LED
      sw t1, GPIO_OUTPUT_VAL(t0)      # write the new output value to GPIO out
      li a0, NOERROR                  # no error
      j exit 
  
  ledOff:
      wfi
      xor a0, a0, 0xffffffff          # invert everything so that all bits are one except the LED we are turning off
      and t1, t1, a0                  # and a0 and t1 to get the LED we want to turn off
      sw t1, GPIO_OUTPUT_VAL(t0)      # write the new output value
      li a0, NOERROR
  
  
  exit:
      lw ra, 12(sp)                   # restore the return address
      addi sp, sp, 16                 # dealocating stack frame
      ret 
  </code></pre>