ex01-timer.c (1599B)
1 // Copyright 2022, Brian Swetland <swetland@frotz.net> 2 // Licensed under the Apache License, Version 2.0 3 4 #include <hw/riscv.h> 5 #include <hw/context.h> 6 #include <hw/debug.h> 7 #include <hw/intrinsics.h> 8 9 #include <hw/platform.h> 10 #include <hw/litex.h> 11 12 #define timer_rd(a) io_rd32(TIMER0_BASE + LX_TIMER_ ## a) 13 #define timer_wr(a,v) io_wr32(TIMER0_BASE + LX_TIMER_ ## a, v) 14 15 void timer_init(void) { 16 // disable, clear pending irqs 17 timer_wr(EN, 0); 18 timer_wr(EV_PENDING, LX_TIMER_EVb_ZERO); 19 20 // set for repeating every 100ms 21 timer_wr(LOAD, 0); 22 timer_wr(RELOAD, 50000000/10); 23 24 // enable timer and timer wrap irq 25 timer_wr(EN, 1); 26 timer_wr(EV_ENABLE, LX_TIMER_EVb_ZERO); 27 } 28 29 volatile uint32_t ticks = 0; 30 31 void interrupt_handler(void) { 32 if (timer_rd(EV_PENDING)) { 33 timer_wr(EV_PENDING, LX_TIMER_EVb_ZERO); 34 ticks++; 35 } 36 } 37 38 void start(void) { 39 xprintf("Example 01 - Timer\n\n"); 40 41 // set trap vector to trap_entry() in trap-entry-single.S 42 // it will call exception_handler() or interrupt_handler() 43 csr_write(CSR_STVEC, (uintptr_t) trap_entry); 44 45 // enable timer0 irq 46 csr_set(CSR_S_INTC_ENABLE, TIMER0_IRQb); 47 48 // enable external interrupts 49 csr_set(CSR_SIE, INTb_SVC_EXTERN); 50 51 // enable interrupts 52 irq_enable(); 53 54 timer_init(); 55 56 while (1) { 57 uint32_t now = ticks; 58 xprintf("%02u:%02u.%1u\r", now/600, (now/10) % 60, now % 10); 59 60 // wait for ticks to change 61 while (now == ticks) ; 62 } 63 } 64 65 // if an exception occurs, dump register state and halt 66 void exception_handler(eframe_t *ef) { 67 xprintf("\n** SUPERVISOR EXCEPTION **\n"); 68 xprint_s_exception(ef); 69 xprintf("\nHALT\n"); 70 for (;;) ; 71 } 72