#include <soc/bpmp.h>
#include <soc/irq.h>
#include <soc/timer.h>
#include <soc/t210.h>
#include <utils/types.h>
#define EXCP_TYPE_ADDR 0x4003FFF8
#define EXCP_TYPE_WDT 0x544457
#define USE_RTC_TIMER
u32 get_tmr_s()
{
(void)RTC(APBDEV_RTC_MILLI_SECONDS);
return (u32)RTC(APBDEV_RTC_SECONDS);
}
u32 get_tmr_ms()
{
return (u32)(RTC(APBDEV_RTC_MILLI_SECONDS) + (RTC(APBDEV_RTC_SHADOW_SECONDS) * 1000));
}
u32 get_tmr_us()
{
return (u32)TMR(TIMERUS_CNTR_1US);
}
void msleep(u32 ms)
{
#ifdef USE_RTC_TIMER
u32 start = (u32)RTC(APBDEV_RTC_MILLI_SECONDS) + (RTC(APBDEV_RTC_SHADOW_SECONDS) * 1000);
while (((u32)(RTC(APBDEV_RTC_MILLI_SECONDS) + (RTC(APBDEV_RTC_SHADOW_SECONDS) * 1000)) - start) <= ms)
;
#else
bpmp_msleep(ms);
#endif
}
void usleep(u32 us)
{
#ifdef USE_RTC_TIMER
u32 start = (u32)TMR(TIMERUS_CNTR_1US);
if ((start + us) < start)
bpmp_usleep(us);
else
while ((u32)(TMR(TIMERUS_CNTR_1US) - start) <= us)
;
#else
bpmp_usleep(us);
#endif
}
void __attribute__((target("arm"))) isleep(u32 is)
{
asm volatile( "0:" "SUBS %[is_cnt], #1;" "BGT 0b;" : [is_cnt] "+r" (is));
}
void timer_usleep(u32 us)
{
TMR(TIMER_TMR8_TMR_PTV) = TIMER_EN | us;
irq_wait_event(IRQ_TMR8);
TMR(TIMER_TMR8_TMR_PCR) = TIMER_INTR_CLR;
}
void watchdog_start(u32 us, u32 mode)
{
TMR(TIMER_WDT4_UNLOCK_PATTERN) = TIMER_MAGIC_PTRN;
TMR(TIMER_TMR9_TMR_PTV) = TIMER_EN | TIMER_PER_EN | us;
TMR(TIMER_WDT4_CONFIG) = TIMER_SRC(9) | TIMER_PER(1) | mode;
TMR(TIMER_WDT4_COMMAND) = TIMER_START_CNT;
}
void watchdog_end()
{
TMR(TIMER_TMR9_TMR_PTV) = 0;
TMR(TIMER_WDT4_UNLOCK_PATTERN) = TIMER_MAGIC_PTRN;
TMR(TIMER_WDT4_COMMAND) = TIMER_START_CNT;
TMR(TIMER_WDT4_COMMAND) = TIMER_CNT_DISABLE;
TMR(TIMER_TMR9_TMR_PCR) = TIMER_INTR_CLR;
}
void watchdog_handle()
{
watchdog_end();
*(u32 *)EXCP_TYPE_ADDR = EXCP_TYPE_WDT;
}
bool watchdog_fired()
{
return (*(u32 *)EXCP_TYPE_ADDR == EXCP_TYPE_WDT);
}