diff --git a/tests/C/timer/compile.sh b/tests/C/timer/compile.sh new file mode 100644 index 0000000..5a1cd5b --- /dev/null +++ b/tests/C/timer/compile.sh @@ -0,0 +1,3 @@ +riscv32-unknown-elf-gcc -Wall -I. -O0 -static -march=rv32imac -mabi=ilp32 --specs=nosys.specs timer.c timerasm.S -o timer.elf +objcopy -Oihex timer.elf timer.hex +riscv32-unknown-elf-objdump timer.elf -d > dump diff --git a/tests/C/timer/timer.c b/tests/C/timer/timer.c index 42bed04..c64621d 100644 --- a/tests/C/timer/timer.c +++ b/tests/C/timer/timer.c @@ -1,10 +1,10 @@ #include -#define TIMER (*(uint64_t *)0x40004000) -#define TIMER_CMP (*(uint64_t *)0x40004008) -#define TRACE (*(unsigned char *)0x40000000) +#define TIMER (*(uint64_t volatile *)0x40004000) +#define TIMER_CMP (*(uint64_t volatile *)0x40004008) +#define TRACE (*(unsigned char volatile *)0x40000000) -volatile int ticks = 0; +volatile uint32_t ticks = 0; int _write(int file, const char *ptr, int len) { int x; @@ -17,20 +17,22 @@ int _write(int file, const char *ptr, int len) { } void timer_ISR() { - uint32_t timer_value; + volatile uint32_t timer_value; ticks++; - if (ticks < 10) { - timer_value = TIMER; - // timer is in nanoseconds, set to 1 ms. - // comparator value fixed to take into account number of instructions executed - TIMER_CMP = timer_value + 590; - } + + timer_value = TIMER; + + // timer is in nanoseconds, set to 1 ms. + // comparator value fixed to take into account number of instructions executed + TIMER_CMP = timer_value + 610; } void register_timer_isr() { - asm volatile("la t0, TIMER_CMP_INT \n csrw mtvec, t0"); - asm volatile("li t1, 0x888 \n csrw mie, t1"); + asm volatile("la t0, TIMER_CMP_INT"); + asm volatile("csrw mtvec, t0"); + asm volatile("li t1, 0x888"); + asm volatile("csrw mie, t1"); } int main(void) { @@ -43,14 +45,20 @@ int main(void) { start_time = TIMER; TIMER_CMP = start_time + 10000; printf("set timer to %ld ns\n", start_time + 10000); - + do { timer_value = TIMER; - } while (timer_value < start_time + 200000); + } while (timer_value < start_time + 2000000); printf("Timer: %ld ns\n", timer_value); printf("ticks: %ld\n", ticks); + + if (ticks > 2100) { + printf("Test OK!\n"); + } + + printf("Finish\n"); + asm volatile ("ecall"); return 0; - } diff --git a/tests/C/timer/timerasm.S b/tests/C/timer/timerasm.S index 98cb51c..378cf1a 100644 --- a/tests/C/timer/timerasm.S +++ b/tests/C/timer/timerasm.S @@ -8,7 +8,7 @@ #define LOAD lw #define REGBYTES 4 - +.align 2 TIMER_CMP_INT: /* store execution context on the stack (register content) */ addi sp, sp, -REGBYTES * 32 @@ -32,7 +32,7 @@ STORE x31, 30 * REGBYTES(sp) /* load interrupt/trap reason and call external C function to handle it */ csrr a0, mcause -jal timer_ISR +jal timer_ISR /* re-store the saved context */ LOAD x1, 0x0(sp) @@ -54,4 +54,3 @@ LOAD x30, 29 * REGBYTES(sp) LOAD x31, 30 * REGBYTES(sp) addi sp, sp, REGBYTES * 32 mret -