
#include <stdio.h>
#include <string.h>

#include <zephyr/types.h>
#include <zephyr/kernel.h>
#include <zephyr/logging/log.h>
#include <zephyr/drivers/counter.h>

#include "RTC.h"

LOG_MODULE_REGISTER(GRTC, LOG_LEVEL_DBG);

#define TICK_INTERVAL_SEC 1000000UL   // 1 秒
// static const struct device *grtc_dev = DEVICE_DT_GET(DT_NODELABEL(grtc));
const struct device *grtc_dev = DEVICE_DT_GET(DT_CHOSEN(nordic_nrf_grtc));

rtc_t   RTClock;
int64_t RTC_Offset = 0;

uint64_t user_get_grtc_count()
{
    uint32_t syscounterl_value, syscounterh_value, syscounterh;
    // uint64_t syscounter;
    uint8_t m = 0;
    do
    {
        syscounterl_value = NRF_GRTC->SYSCOUNTER[m].SYSCOUNTERL;
        syscounterh = NRF_GRTC->SYSCOUNTER[m].SYSCOUNTERH;
        syscounterh_value = ((syscounterh & GRTC_SYSCOUNTER_SYSCOUNTERH_VALUE_Msk) >> GRTC_SYSCOUNTER_SYSCOUNTERH_VALUE_Pos);
        if (((syscounterh & GRTC_SYSCOUNTER_SYSCOUNTERH_OVERFLOW_Msk) >> GRTC_SYSCOUNTER_SYSCOUNTERH_OVERFLOW_Pos) == GRTC_SYSCOUNTER_SYSCOUNTERH_OVERFLOW_Overflow)
        {
            syscounterh = syscounterh_value - 1;
        }
    } while (((syscounterh & GRTC_SYSCOUNTER_SYSCOUNTERH_BUSY_Msk) >> GRTC_SYSCOUNTER_SYSCOUNTERH_BUSY_Pos) != GRTC_SYSCOUNTER_SYSCOUNTERH_BUSY_Ready);
    return ((uint64_t)syscounterh_value << 32) + syscounterl_value;
}

// void RTCHandler(struct k_timer *dummy)
// {
//     RTClock.RTC_Counter = RTC_GetCounter();
// }

// K_TIMER_DEFINE(RTCUpdate, RTCHandler, NULL);

void Set1secAlarm(void);

static void grtc_alarm_callback(const struct device *dev,
                                uint8_t chan_id,
                                uint32_t ticks,
                                void *user_data)
{
    ARG_UNUSED(dev);
    ARG_UNUSED(chan_id);
    ARG_UNUSED(ticks);
    ARG_UNUSED(user_data);

    Set1secAlarm();
}

void Set1secAlarm(void)
{
    struct counter_alarm_cfg alarm_cfg = {
        .flags = COUNTER_ALARM_CFG_ABSOLUTE,
        .ticks = counter_ticks_to_us(grtc_dev, TICK_INTERVAL_SEC),
        .callback = grtc_alarm_callback,
    };
    counter_set_channel_alarm(grtc_dev, 0, &alarm_cfg);
}

int RTC_init(void)
{
    // k_timer_start(&RTCUpdate, K_MSEC(1000), K_MSEC(1000));

    if (!device_is_ready(grtc_dev)) 
    {
        LOG_ERR("GRTC device not ready");
        return -1;
    }

    counter_start(grtc_dev);
    /* 設定第一次 alarm */
    Set1secAlarm();
    return 0;
}

uint32_t RTC_GetCounter(void)
{
    uint64_t TmpRTCCount;
    TmpRTCCount = user_get_grtc_count() + RTC_Offset;
    return (uint32_t)(TmpRTCCount / 1000000);
}

void RTC_SetCounter(uint32_t CounterValue)
{
    int64_t TmpRTCCount;
    TmpRTCCount = CounterValue * 1000000;
    RTC_Offset = TmpRTCCount - user_get_grtc_count();
}

void prs_RTC(void)
{
    
}