/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

#include <assert.h>
#include "os/mynewt.h"
#include "hal/hal_os_tick.h"
#include "nrf.h"
#include "mcu/cmsis_nvic.h"

/* The OS scheduler requires a low-frequency timer. */
#if MYNEWT_VAL(OS_SCHEDULING)       && \
    !MYNEWT_VAL(XTAL_32768)         && \
    !MYNEWT_VAL(XTAL_RC)            && \
    !MYNEWT_VAL(XTAL_32768_SYNTH)

    #error The OS scheduler requires a low-frequency timer; enable one of: XTAL_32768, XTAL_RC, or XTAL_32768_SYNTH
#endif

#define RTC_FREQ            32768       /* in Hz */
#define OS_TICK_TIMER       NRF_RTC1
#define OS_TICK_IRQ         RTC1_IRQn
#define OS_TICK_CMPREG      3   /* generate timer interrupt */
#define RTC_COMPARE_INT_MASK(ccreg) (1UL << ((ccreg) + 16))

struct hal_os_tick
{
    int ticks_per_ostick;
    os_time_t max_idle_ticks;
    uint32_t lastocmp;
};

struct hal_os_tick g_hal_os_tick;

/*
 * Implement (x - y) where the range of both 'x' and 'y' is limited to 24-bits.
 *
 * For example:
 *
 * sub24(0, 0xffffff) = 1
 * sub24(0xffffff, 0xfffffe) = 1
 * sub24(0xffffff, 0) = -1
 * sub24(0x7fffff, 0) = 8388607
 * sub24(0x800000, 0) = -8388608
 */
static inline int
sub24(uint32_t x, uint32_t y)
{
    int result;

    assert(x <= 0xffffff);
    assert(y <= 0xffffff);

    result = x - y;
    if (result & 0x800000) {
        return (result | 0xff800000);
    } else {
        return (result & 0x007fffff);
    }
}

static inline uint32_t
nrf52_os_tick_counter(void)
{
    return OS_TICK_TIMER->COUNTER;
}

static inline void
nrf52_os_tick_set_ocmp(uint32_t ocmp)
{
    int delta;
    uint32_t counter;

    OS_ASSERT_CRITICAL();
    while (1) {
        ocmp &= 0xffffff;
        OS_TICK_TIMER->CC[OS_TICK_CMPREG] = ocmp;
        counter = nrf52_os_tick_counter();
        /*
         * From nRF52 Product specification
         *
         * - If Counter is 'N' writing (N) or (N + 1) to CC register
         *   may not trigger a compare event.
         *
         * - If Counter is 'N' writing (N + 2) to CC register is guaranteed
         *   to trigger a compare event at 'N + 2'.
         */
        delta = sub24(ocmp, counter);
        if (delta > 2) {
            break;
        }
        ocmp += g_hal_os_tick.ticks_per_ostick;
    }
}

static void
nrf52_timer_handler(void)
{
    int delta;
    int ticks;
    os_sr_t sr;
    uint32_t counter;

    os_trace_isr_enter();
    OS_ENTER_CRITICAL(sr);

    /* Calculate elapsed ticks and advance OS time. */

    counter = nrf52_os_tick_counter();
    delta = sub24(counter, g_hal_os_tick.lastocmp);
    ticks = delta / g_hal_os_tick.ticks_per_ostick;
    os_time_advance(ticks);

    /* Clear timer interrupt */
    OS_TICK_TIMER->EVENTS_COMPARE[OS_TICK_CMPREG] = 0;

    /* Update the time associated with the most recent tick */
    g_hal_os_tick.lastocmp = (g_hal_os_tick.lastocmp +
        (ticks * g_hal_os_tick.ticks_per_ostick)) & 0xffffff;

    /* Update the output compare to interrupt at the next tick */
    nrf52_os_tick_set_ocmp(g_hal_os_tick.lastocmp + g_hal_os_tick.ticks_per_ostick);

    OS_EXIT_CRITICAL(sr);
    os_trace_isr_exit();
}

void
os_tick_idle(os_time_t ticks)
{
    uint32_t ocmp;

    OS_ASSERT_CRITICAL();

    if (ticks > 0) {
        /*
         * Enter tickless regime during long idle durations.
         */
        if (ticks > g_hal_os_tick.max_idle_ticks) {
            ticks = g_hal_os_tick.max_idle_ticks;
        }
        ocmp = g_hal_os_tick.lastocmp + (ticks*g_hal_os_tick.ticks_per_ostick);
        nrf52_os_tick_set_ocmp(ocmp);
    }

    __DSB();
    __WFI();

    if (ticks > 0) {
        /*
         * Update OS time before anything else when coming out of
         * the tickless regime.
         */
        nrf52_timer_handler();
    }
}

void
os_tick_init(uint32_t os_ticks_per_sec, int prio)
{
    uint32_t sr;

    assert(RTC_FREQ % os_ticks_per_sec == 0);

    g_hal_os_tick.lastocmp = 0;
    g_hal_os_tick.ticks_per_ostick = RTC_FREQ / os_ticks_per_sec;

    /*
     * The maximum number of OS ticks allowed to elapse during idle is
     * limited to 1/4th the number of timer ticks before the 24-bit counter
     * rolls over.
     */
    g_hal_os_tick.max_idle_ticks = (1UL << 22) / g_hal_os_tick.ticks_per_ostick;

    /* disable interrupts */
    OS_ENTER_CRITICAL(sr);

    /* Set isr in vector table and enable interrupt */
    NVIC_SetPriority(OS_TICK_IRQ, prio);
    NVIC_SetVector(OS_TICK_IRQ, (uint32_t)nrf52_timer_handler);
    NVIC_EnableIRQ(OS_TICK_IRQ);

    /*
     * Program the OS_TICK_TIMER to operate at 32KHz and trigger an output
     * compare interrupt at a rate of 'os_ticks_per_sec'.
     */
    OS_TICK_TIMER->TASKS_STOP = 1;
    OS_TICK_TIMER->TASKS_CLEAR = 1;

    OS_TICK_TIMER->EVTENCLR = 0xffffffff;
    OS_TICK_TIMER->INTENCLR = 0xffffffff;
    OS_TICK_TIMER->INTENSET = RTC_COMPARE_INT_MASK(OS_TICK_CMPREG);

    OS_TICK_TIMER->EVENTS_COMPARE[OS_TICK_CMPREG] = 0;
    OS_TICK_TIMER->CC[OS_TICK_CMPREG] = g_hal_os_tick.ticks_per_ostick;

    OS_TICK_TIMER->TASKS_START = 1;

    OS_EXIT_CRITICAL(sr);
}
