/*
 * 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 <stdint.h>
#include <stddef.h>
#include <assert.h>
#include <stddef.h>
#include "syscfg/syscfg.h"
#include "os/os_cputime.h"
#include "controller/ble_phy.h"
#include "controller/ble_ll.h"
#include "controller/ble_ll_xcvr.h"

#ifdef BLE_XCVR_RFCLK
int
ble_ll_xcvr_rfclk_state(void)
{
    uint32_t expiry;

    if (g_ble_ll_data.ll_rfclk_state == BLE_RFCLK_STATE_ON) {
        expiry = g_ble_ll_data.ll_rfclk_start_time;
        if ((int32_t)(os_cputime_get32() - expiry) >
                g_ble_ll_data.ll_xtal_ticks) {
            g_ble_ll_data.ll_rfclk_state = BLE_RFCLK_STATE_SETTLED;
        }
    }
    return g_ble_ll_data.ll_rfclk_state;
}

void
ble_ll_xcvr_rfclk_enable(void)
{
    g_ble_ll_data.ll_rfclk_state = BLE_RFCLK_STATE_ON;
    ble_phy_rfclk_enable();
}

void
ble_ll_xcvr_rfclk_disable(void)
{
    ble_phy_rfclk_disable();
    g_ble_ll_data.ll_rfclk_state = BLE_RFCLK_STATE_OFF;
}

void
ble_ll_xcvr_rfclk_stop(void)
{
    os_cputime_timer_stop(&g_ble_ll_data.ll_rfclk_timer);
    ble_ll_xcvr_rfclk_disable();
}

uint32_t
ble_ll_xcvr_rfclk_time_till_settled(void)
{
    int32_t dt;
    uint32_t rc;

    rc = 0;
    if (g_ble_ll_data.ll_rfclk_state == BLE_RFCLK_STATE_ON) {
        dt = (int32_t)(os_cputime_get32() - g_ble_ll_data.ll_rfclk_start_time);
        BLE_LL_ASSERT(dt >= 0);
        if (dt < g_ble_ll_data.ll_xtal_ticks) {
            rc = g_ble_ll_data.ll_xtal_ticks - (uint32_t)dt;
        }
    }

    return rc;
}

/**
 * Called when the timer to turn on the RF CLOCK expires. This function checks
 * the state of the clock. If the clock is off, the clock is turned on.
 * Otherwise, we just exit.
 *
 * Context: Interrupt
 *
 * @param arg
 */
void
ble_ll_xcvr_rfclk_timer_exp(void *arg)
{
    if (g_ble_ll_data.ll_rfclk_state == BLE_RFCLK_STATE_OFF) {
        ble_ll_xcvr_rfclk_start_now(os_cputime_get32());
    }
}

/**
 * This API is used to turn on the rfclock without setting the cputime timer to
 * start the clock at some later point.
 *
 * NOTE: presumes that the state of the rf clock was checked prior to calling.
 *
 * @param now
 */
void
ble_ll_xcvr_rfclk_start_now(uint32_t now)
{
    ble_ll_xcvr_rfclk_enable();
    g_ble_ll_data.ll_rfclk_start_time = now;
}

/**
 * Starts the timer that will turn the rf clock on. The 'cputime' is
 * the time at which the clock needs to be settled.
 *
 * @param cputime   Time at which rfclock should be on and settled.
 */
void
ble_ll_xcvr_rfclk_timer_start(uint32_t cputime)
{
    /*
     * If we are currently in an advertising event or a connection event,
     * no need to start the cputime timer
     */
    if ((g_ble_ll_data.ll_state == BLE_LL_STATE_ADV) ||
        (g_ble_ll_data.ll_state == BLE_LL_STATE_CONNECTION)) {
        return;
    }

    /* Account for the settling time */
    cputime -= g_ble_ll_data.ll_xtal_ticks;

    /*
     * If the timer is on the list, we need to see if its expiry is before
     * 'cputime'. If the expiry is before, no need to do anything. If it
     * is after, we need to stop the timer and start at new time.
     */
    if (g_ble_ll_data.ll_rfclk_timer.link.tqe_prev != NULL) {
        if ((int32_t)(cputime - g_ble_ll_data.ll_rfclk_timer.expiry) >= 0) {
            return;
        }
        os_cputime_timer_stop(&g_ble_ll_data.ll_rfclk_timer);
    }
    os_cputime_timer_start(&g_ble_ll_data.ll_rfclk_timer, cputime);
}
#endif
