Я пытаюсь написать программу в сборке RIS C -V, чтобы плата HiFive1 проснулась с прерыванием по таймеру. Это моя процедура установки прерывания
.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
Я не слишком уверен, что я установил MTIMECMP правильно, я знаю, это 64-битная ячейка памяти. Я пытаюсь использовать это прерывание в качестве таймера задержки для мигающего светодиода (просто пытаюсь убедиться, что прерывание работает, прежде чем я перейду к написанию обработчика), вот моя программа setLED. (не все настройки регистра GPIO были выполнены ранее и, как известно, работают). У меня есть инструкция WFI перед каждой из функций ВКЛ и ВЫКЛ. Светодиод не горит, хотя в режиме отладки горит. Я думаю, что в LED он пропускает инструкцию WFI, как если бы прерывание было установлено.
.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