4

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

.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 

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.

.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 
Ivan
  • 123
  • 1
  • 5
  • `MTIMECMP` is compared with `MTIME`. So you will need to change your initialization of `MTIMECMP` to something that amounts to `MTIMECMP = MTIME + delta`. These registers are 64 bits, so there are a few details to look out for. See "The RISC-V Instruction Set Manual, Volume II: Privileged Architecture, Document Version 1.12-draft", paragraph 3.1.10. Good luck! – Baard Jan 10 '20 at 18:43
  • 1
    How would I work with these 64 bit registers? – Ivan Jan 12 '20 at 00:15
  • Does this answer your question? [How to use risc-v timer for accurate timing generation](https://stackoverflow.com/questions/67824221/how-to-use-risc-v-timer-for-accurate-timing-generation) – Erik Eidt Feb 06 '22 at 19:29

0 Answers0