Files
TencentOS-tiny/arch/risc-v/rv32i/gcc/port_c.c
2019-09-18 12:54:03 +08:00

50 lines
1.7 KiB
C

/*
* port_c.c
*
* Created on: Sep 9, 2019
* Author: ace
*/
#include "riscv_encoding.h"
#include <tos.h>
#define CLINT_CTRL_ADDR 0x2000000
#define CLINT_MSIP 0x0000
#define CLINT_MTIMECMP 0x4000
#define CLINT_MTIME 0xBFF8
__PORT__ void port_systick_config(uint32_t cycle_per_tick)
{
// it cost cpu read two times, first mtime_lo and then mtime_hi
// if mtime_lo == 0xFFFFFFFF and mtime_hi = 0 at first read
// then mtime_lo == 0 and mtime_hi = 1 at next read
// the result will be 0x1FFFFFFFF, not 0x100000000
uint64_t mtime = 0;
while(1) {
uint32_t mtime_hi = *(volatile uint32_t *)(CLINT_CTRL_ADDR + CLINT_MTIME + 4);
uint32_t mtime_lo = *(volatile uint32_t *)(CLINT_CTRL_ADDR + CLINT_MTIME + 0);
uint32_t mtime_hn = *(volatile uint32_t *)(CLINT_CTRL_ADDR + CLINT_MTIME + 4);
if(mtime_hi == mtime_hn) {
mtime += ((uint64_t)mtime_hi << 32) | mtime_lo;
break;
}
}
// just set mtime to mtimecmp does not accurately reflect the passage of time
// cause some time cost on the path to deal with the interrupt
// so, we need to to fix the value with a multiple of cycle_per_tick
uint64_t tick = mtime / cycle_per_tick;
uint64_t mtimecmp = (tick + 1) * cycle_per_tick;
// write to mtimecmp register
*(volatile uint32_t *)(CLINT_CTRL_ADDR + CLINT_MTIMECMP + 0) = 0xFFFFFFFF;
*(volatile uint32_t *)(CLINT_CTRL_ADDR + CLINT_MTIMECMP + 4) = 0xFFFFFFFF & (mtimecmp >> 32);
*(volatile uint32_t *)(CLINT_CTRL_ADDR + CLINT_MTIMECMP + 0) = 0xFFFFFFFF & (mtimecmp >> 0);
}
__PORT__ void port_systick_priority_set(uint32_t prio)
{
//NVIC_SetPriority(SysTick_IRQn, prio);
}