/// Syntacore SCR* infra
///
/// @copyright (C) Syntacore 2015-2017. All rights reserved.
///
/// @brief RTC defs and inline funcs

#ifndef SCR_RTC_H
#define SCR_RTC_H

#include "arch.h"

#ifndef PLF_SYS_FREQ
#define PLF_SYS_FREQ                SYSTEM_CLOCK_FREQ
#endif

#ifndef PLF_RTC_TICK64
#define PLF_RTC_TICK64
#endif

#ifndef PLF_RTC_TIMEBASE
#ifdef RTC_HZ
#define PLF_RTC_TIMEBASE            RTC_HZ
#else
#define PLF_RTC_TIMEBASE            1000000
#endif
#endif

#if __riscv_xlen == 32
typedef uint32_t sys_tick32_t;
typedef uint64_t sys_tick64_t;
#ifdef PLF_RTC_TICK64
typedef sys_tick64_t sys_tick_t;
#else // PLF_RTC_TICK64
typedef sys_tick32_t sys_tick_t;
#endif
#else // __riscv_xlen == 32
typedef uint64_t sys_tick_t;
typedef uint64_t sys_tick32_t;
typedef uint64_t sys_tick64_t;
#endif // __riscv_xlen == 32

#define SCR_RTC_CTL                 (SCR_MTIMER_BASE_ADDR+0)
#define SCR_RTC_DIVIDER             (SCR_MTIMER_BASE_ADDR+4)
#define SCR_RTC_MTIME               (SCR_MTIMER_BASE_ADDR+8)
#define SCR_RTC_MTIMEH              (SCR_MTIMER_BASE_ADDR+12)
#define SCR_RTC_MTIMECMP            (SCR_MTIMER_BASE_ADDR+16)
#define SCR_RTC_MTIMECMPH           (SCR_MTIMER_BASE_ADDR+20)
#define SCR_RTC_CTL_EN              (1 << 0)
#define SCR_RTC_CTL_INTERNAL_SRC    (0 << 1)
#define SCR_RTC_CTL_EXTERNAL_SRC    (1 << 1)
#define SCR_RTC_CTL_SRC             SCR_RTC_CTL_INTERNAL_SRC

#if (PLF_RTC_TIMEBASE) > (PLF_SYS_FREQ)
#error PLF_RTC_TIMEBASE > PLF_SYS_FREQ
#endif
#define RTC_TIMEBASE_DIVISOR ((PLF_SYS_FREQ) / (PLF_RTC_TIMEBASE) - 1)

#if 0
sys_tick32_t rtc_current32(void);
sys_tick64_t rtc_current64(void);

#if __riscv_xlen == 32
#ifdef PLF_RTC_TICK64
#define now() rtc_current64()
#else // PLF_RTC_TICK64
#define now() rtc_current32()
#endif // PLF_RTC_TICK64
#else //  __riscv_xlen == 32
#define now() rtc_current64()
#endif // __riscv_xlen == 32

#else

#if __riscv_xlen == 32
#ifdef PLF_RTC_TICK64
#define now() (*(volatile uint64_t *)SCR_RTC_MTIME)
#else // PLF_RTC_TICK64
#define now() (*(volatile uint32_t *)SCR_RTC_MTIME)
#endif // PLF_RTC_TICK64
#else //  __riscv_xlen == 32
#define now() (*(volatile uint64_t *)SCR_RTC_MTIME)
#endif // __riscv_xlen == 32
#endif


long ticks2ms(sys_tick_t t);

sys_tick_t ms2ticks(long t);

void rtc_delay_us(unsigned us);

void scr_rtc_setcmp(uint64_t when);

void scr_rtc_init(void);

#define SCR_RTC_TIMER_ENABLE()      set_csr(mie,MIP_MTIP)
#define SCR_RTC_TIMER_DISABLE()     clear_csr(mie,MIP_MTIP)

void delay_ms(unsigned ms);

uint32_t now_seconds();


#endif // SCR_RTC_H
