/*
 * Copyright (c) 2023 STMicroelectronics
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/irq.h>
#include <zephyr/kernel.h>
#include <zephyr/arch/cpu.h>
#include <zephyr/sys/util.h>
#include <zephyr/drivers/entropy.h>
#include <zephyr/logging/log.h>
#include <cmsis_core.h>

#include <linklayer_plat_local.h>

#include <stm32_ll_pwr.h>

#include "scm.h"

#define LOG_LEVEL CONFIG_SOC_LOG_LEVEL
LOG_MODULE_REGISTER(linklayer_plat);

#define RADIO_INTR_PRIO_HIGH_Z (RADIO_INTR_PRIO_HIGH + _IRQ_PRIO_OFFSET)
#define RADIO_INTR_PRIO_LOW_Z (RADIO_INTR_PRIO_LOW + _IRQ_PRIO_OFFSET)

/* 2.4GHz RADIO ISR callbacks */
typedef void (*radio_isr_cb_t) (void);

radio_isr_cb_t radio_callback;
radio_isr_cb_t low_isr_callback;

extern const struct device *rng_dev;

/* Radio critical sections */
volatile int32_t prio_high_isr_counter;
volatile int32_t prio_low_isr_counter;
volatile int32_t prio_sys_isr_counter;
volatile int32_t irq_counter;
volatile uint32_t local_basepri_value;

/* Radio SW low ISR global variable */
volatile uint8_t radio_sw_low_isr_is_running_high_prio;

void LINKLAYER_PLAT_ClockInit(void)
{
	LL_PWR_EnableBkUpAccess();

	/* Select LSE as Sleep CLK */
	__HAL_RCC_RADIOSLPTIM_CONFIG(RCC_RADIOSTCLKSOURCE_LSE);

	LL_PWR_DisableBkUpAccess();

	/* Enable AHB5ENR peripheral clock (bus CLK) */
	__HAL_RCC_RADIO_CLK_ENABLE();
}

void LINKLAYER_PLAT_DelayUs(uint32_t delay)
{
	k_busy_wait(delay);
}

void LINKLAYER_PLAT_WaitHclkRdy(void)
{
	while (HAL_RCCEx_GetRadioBusClockReadiness() != RCC_RADIO_BUS_CLOCK_READY) {
	}
}

void LINKLAYER_PLAT_AclkCtrl(uint8_t enable)
{
	LOG_DBG("enable: %d", enable);
	if (enable) {
		/* Enable RADIO baseband clock (active CLK) */
		HAL_RCCEx_EnableRadioBBClock();

		/* Polling on HSE32 activation */
		while (LL_RCC_HSE_IsReady() == 0) {
		}
	} else {
		/* Disable RADIO baseband clock (active CLK) */
		HAL_RCCEx_DisableRadioBBClock();
	}
}

void LINKLAYER_PLAT_GetRNG(uint8_t *ptr_rnd, uint32_t len)
{
	int ret;

	/* Read 32-bit random values from HW driver */
	ret = entropy_get_entropy_isr(rng_dev, (char *)ptr_rnd, len, 0);
	if (ret < 0) {
		LOG_ERR("Error: entropy_get_entropy failed: %d", ret);
	}
	LOG_DBG("n %d, val: %p", len, (void *)ptr_rnd);
}

void LINKLAYER_PLAT_SetupRadioIT(void (*intr_cb)())
{
	radio_callback = intr_cb;
}

void LINKLAYER_PLAT_SetupSwLowIT(void (*intr_cb)())
{
	low_isr_callback = intr_cb;
}

void radio_high_prio_isr(void)
{
	radio_callback();

	HAL_RCCEx_DisableRequestUponRadioWakeUpEvent();

	__ISB();

	ISR_DIRECT_PM();
}

void radio_low_prio_isr(void)
{
	irq_disable((IRQn_Type)RADIO_SW_LOW_INTR_NUM);

	low_isr_callback();

	/* Check if nested SW radio low interrupt has been requested*/
	if (radio_sw_low_isr_is_running_high_prio != 0) {
		NVIC_SetPriority((IRQn_Type) RADIO_SW_LOW_INTR_NUM, RADIO_INTR_PRIO_LOW);
		radio_sw_low_isr_is_running_high_prio = 0;
	}

	/* Re-enable SW radio low interrupt */
	irq_enable((IRQn_Type)RADIO_SW_LOW_INTR_NUM);

	ISR_DIRECT_PM();
}


void link_layer_register_isr(void)
{
	ARM_IRQ_DIRECT_DYNAMIC_CONNECT(RADIO_INTR_NUM, 0, 0, reschedule);

	/* Ensure the IRQ is disabled before enabling it at run time */
	irq_disable((IRQn_Type)RADIO_INTR_NUM);

	irq_connect_dynamic((IRQn_Type)RADIO_INTR_NUM, RADIO_INTR_PRIO_HIGH_Z,
			    (void (*)(const void *))radio_high_prio_isr, NULL, 0);

	irq_enable((IRQn_Type)RADIO_INTR_NUM);

	ARM_IRQ_DIRECT_DYNAMIC_CONNECT(RADIO_SW_LOW_INTR_NUM, 0, 0, reschedule);

	/* Ensure the IRQ is disabled before enabling it at run time */
	irq_disable((IRQn_Type)RADIO_SW_LOW_INTR_NUM);

	irq_connect_dynamic((IRQn_Type)RADIO_SW_LOW_INTR_NUM, RADIO_SW_LOW_INTR_PRIO,
			    (void (*)(const void *))radio_low_prio_isr, NULL, 0);

	irq_enable((IRQn_Type)RADIO_SW_LOW_INTR_NUM);
}


void LINKLAYER_PLAT_TriggerSwLowIT(uint8_t priority)
{
	uint8_t low_isr_priority = RADIO_INTR_PRIO_LOW_Z;

	LOG_DBG("Priotity: %d", priority);

	/* Check if a SW low interrupt as already been raised.
	 * Nested call far radio low isr are not supported
	 **/

	if (NVIC_GetActive(RADIO_SW_LOW_INTR_NUM) == 0) {
		/* No nested SW low ISR, default behavior */

		if (priority == 0) {
			low_isr_priority = RADIO_SW_LOW_INTR_PRIO;
		}

		NVIC_SetPriority((IRQn_Type)RADIO_SW_LOW_INTR_NUM, low_isr_priority);
	} else {
		/* Nested call detected */
		/* No change for SW radio low interrupt priority for the moment */

		if (priority != 0) {
			/* At the end of current SW radio low ISR, this pending SW
			 * low interrupt will run with RADIO_INTR_PRIO_LOW_Z priority
			 **/
			radio_sw_low_isr_is_running_high_prio = 1;
		}
	}

	NVIC_SetPendingIRQ((IRQn_Type)RADIO_SW_LOW_INTR_NUM);
}

void LINKLAYER_PLAT_EnableIRQ(void)
{
	irq_counter = MAX(0, irq_counter - 1);

	if (irq_counter == 0) {
		__enable_irq();
	}
}

void LINKLAYER_PLAT_DisableIRQ(void)
{
	__disable_irq();

	irq_counter++;
}

void LINKLAYER_PLAT_Assert(uint8_t condition)
{
	__ASSERT_NO_MSG(condition);
}

void LINKLAYER_PLAT_EnableSpecificIRQ(uint8_t isr_type)
{

	LOG_DBG("isr_type: %d", isr_type);

	if ((isr_type & LL_HIGH_ISR_ONLY) != 0) {
		prio_high_isr_counter--;
		if (prio_high_isr_counter == 0) {
			irq_enable(RADIO_INTR_NUM);
		}
	}

	if ((isr_type & LL_LOW_ISR_ONLY) != 0) {
		prio_low_isr_counter--;
		if (prio_low_isr_counter == 0) {
			irq_enable(RADIO_SW_LOW_INTR_NUM);
		}
	}

	if ((isr_type & SYS_LOW_ISR) != 0) {
		prio_sys_isr_counter--;
		if (prio_sys_isr_counter == 0) {
			__set_BASEPRI(local_basepri_value);
		}
	}
}

void LINKLAYER_PLAT_DisableSpecificIRQ(uint8_t isr_type)
{

	LOG_DBG("isr_type: %d", isr_type);

	if ((isr_type & LL_HIGH_ISR_ONLY) != 0) {
		prio_high_isr_counter++;
		if (prio_high_isr_counter == 1) {
			irq_disable(RADIO_INTR_NUM);
		}
	}

	if ((isr_type & LL_LOW_ISR_ONLY) != 0) {
		prio_low_isr_counter++;
		if (prio_low_isr_counter == 1) {
			irq_disable(RADIO_SW_LOW_INTR_NUM);
		}
	}

	if ((isr_type & SYS_LOW_ISR) != 0) {
		prio_sys_isr_counter++;
		if (prio_sys_isr_counter == 1) {
			local_basepri_value = __get_BASEPRI();
			__set_BASEPRI_MAX(RADIO_INTR_PRIO_LOW_Z << 4);
		}
	}
}

void LINKLAYER_PLAT_EnableRadioIT(void)
{
	irq_enable((IRQn_Type)RADIO_INTR_NUM);
}

void LINKLAYER_PLAT_DisableRadioIT(void)
{
	irq_disable((IRQn_Type)RADIO_INTR_NUM);
}

void LINKLAYER_PLAT_StartRadioEvt(void)
{
	__HAL_RCC_RADIO_CLK_SLEEP_ENABLE();

	NVIC_SetPriority(RADIO_INTR_NUM, RADIO_INTR_PRIO_HIGH_Z);

	scm_notifyradiostate(SCM_RADIO_ACTIVE);
}

void LINKLAYER_PLAT_StopRadioEvt(void)
{
	__HAL_RCC_RADIO_CLK_SLEEP_DISABLE();

	NVIC_SetPriority(RADIO_INTR_NUM, RADIO_INTR_PRIO_LOW_Z);

	scm_notifyradiostate(SCM_RADIO_NOT_ACTIVE);
}

void LINKLAYER_PLAT_RequestTemperature(void) {}

void LINKLAYER_PLAT_SCHLDR_TIMING_UPDATE_NOT(Evnt_timing_t *p_evnt_timing) {}

void LINKLAYER_PLAT_EnableOSContextSwitch(void) {}

void LINKLAYER_PLAT_DisableOSContextSwitch(void) {}
