/*
 * Copyright (c) 2020 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <stdint.h>
#include <bluetooth/hci.h>

#include "util/util.h"
#include "util/memq.h"

#include "hal/cpu.h"
#include "hal/radio_df.h"

#include "pdu.h"

#include "lll.h"
#include "lll_df.h"
#include "lll_df_types.h"
#include "lll_df_internal.h"

#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BT_CTLR_DF_DEBUG_ENABLE)
#define LOG_MODULE_NAME bt_ctlr_lll_df
#include "common/log.h"
#include <soc.h>
#include "hal/debug.h"

/* @brief Function performs common steps for initialization and reset
 * of Direction Finding LLL module.
 *
 * @return	Zero in case of success, other value in case of failure.
 */
static int init_reset(void);

/* @brief Function performs Direction Finding initialization
 *
 * @return	Zero in case of success, other value in case of failure.
 */
int lll_df_init(void)
{
#if defined(CONFIG_BT_CTLR_DF_INIT_ANT_SEL_GPIOS)
	radio_df_ant_switching_gpios_cfg();
#endif /* CONFIG_BT_CTLR_DF_INIT_ANT_SEL_GPIOS */
	return init_reset();
}

/* @brief Function performs Direction Finding reset
 *
 * @return	Zero in case of success, other value in case of failure.
 */
int lll_df_reset(void)
{
	return init_reset();
}

/* @brief Function provides number of available antennas.
 *
 * The number of antenna is hardware defined and it is provided via devicetree.
 *
 * @return      Number of available antennas.
 */
uint8_t lll_df_ant_num_get(void)
{
	return radio_df_ant_num_get();
}

/* @brief Function initializes transmission of Constant Tone Extension.
 *
 * @param[in] type      Type of CTE: AoA, AoD 1us, AoD 2us
 * @param[in] length    Duration of CTE in 8us units
 * @param[in] ant_num   Number of antennas in switch pattern
 * @param[in] ant_ids   Antenna identifiers that create switch pattern.
 *
 * @Note Pay attention that first two antenna identifiers in a switch
 * pattern has special purpose. First one is used in guard period, second
 * in reference period. Actual switching is processed from third antenna.
 *
 * In case of AoA mode ant_num and ant_ids parameters are not used.
 */
void lll_df_conf_cte_tx_enable(uint8_t type, uint8_t length,
			       uint8_t ant_num, uint8_t *ant_ids)
{
	if (type == BT_HCI_LE_AOA_CTE) {
		radio_df_mode_set_aoa();
		radio_df_cte_tx_aoa_set(length);
	}
#if defined(CONFIG_BT_CTLR_DF_ANT_SWITCH_TX) || \
	defined(CONFIG_BT_CTLR_DF_ANT_SWITCH_RX)
	else {
		radio_df_mode_set_aod();

		if (type == BT_HCI_LE_AOD_CTE_1US) {
			radio_df_cte_tx_aod_2us_set(length);
		} else {
			radio_df_cte_tx_aod_4us_set(length);
		}

		radio_df_ant_switching_pin_sel_cfg();
		radio_df_ant_switch_pattern_clear();
		radio_df_ant_switch_pattern_set(ant_ids, ant_num);
	}
#endif /* CONFIG_BT_CTLR_DF_ANT_SWITCH_TX || CONFIG_BT_CTLR_DF_ANT_SWITCH_RX */
}

#if defined(CONFIG_BT_CTLR_DF_SCAN_CTE_RX)
struct lll_df_sync_cfg *lll_df_sync_cfg_alloc(struct lll_df_sync *df_cfg,
					      uint8_t *idx)
{
	uint8_t first, last;

	first = df_cfg->first;
	last = df_cfg->last;
	if (first == last) {
		last++;
		if (last == DOUBLE_BUFFER_SIZE) {
			last = 0U;
		}
	} else {
		uint8_t first_latest;

		df_cfg->last = first;
		cpu_dmb();
		first_latest = df_cfg->first;
		if (first_latest != first) {
			last++;
			if (last == DOUBLE_BUFFER_SIZE) {
				last = 0U;
			}
		}
	}

	*idx = last;

	return &df_cfg->cfg[last];
}

struct lll_df_sync_cfg *lll_df_sync_cfg_latest_get(struct lll_df_sync *df_cfg,
						   uint8_t *is_modified)
{
	uint8_t first;

	first = df_cfg->first;
	if (first != df_cfg->last) {
		uint8_t cfg_idx;

		cfg_idx = first;

		first += 1U;
		if (first == DOUBLE_BUFFER_SIZE) {
			first = 0U;
		}
		df_cfg->first = first;

		if (is_modified) {
			*is_modified = 1U;
		}

		df_cfg->cfg[cfg_idx].is_enabled = 0U; /* mark as disabled - not used anymore */
	}

	return &df_cfg->cfg[first];
}
#endif /* CONFIG_BT_CTLR_DF_SCAN_CTE_RX */

void lll_df_conf_cte_tx_disable(void)
{
	radio_df_reset();
}

#if defined(CONFIG_BT_CTLR_DF_SCAN_CTE_RX)
/* @brief Function initializes reception of Constant Tone Extension.
 *
 * @param[in] slot_duration     Switching and sampling slots duration (1us or 2us).
 * @param[in] ant_num           Number of antennas in switch pattern.
 * @param[in] ant_ids           Antenna identifiers that create switch pattern.
 *
 * In case of AoA mode ant_num and ant_ids parameters are not used.
 */
void lll_df_conf_cte_rx_enable(uint8_t slot_duration, uint8_t ant_num,
			       uint8_t *ant_ids)
{
	struct node_rx_iq_report *node_rx;

	/* ToDo change to appropriate HCI constant */
#if defined(CONFIG_BT_CTLR_DF_ANT_SWITCH_1US)
	if (slot_duration == 0x1) {
		radio_df_cte_rx_2us_switching();
	} else
#endif /* CONFIG_BT_CTLR_DF_ANT_SWITCH_1US */
	{
		radio_df_cte_rx_4us_switching();
	}

#if defined(CONFIG_BT_CTLR_DF_ANT_SWITCH_RX)
	radio_df_ant_switching_pin_sel_cfg();
	radio_df_ant_switch_pattern_clear();
	radio_df_ant_switch_pattern_set(ant_ids, ant_num);
#endif /* CONFIG_BT_CTLR_DF_ANT_SWITCH_RX */

	node_rx = ull_df_iq_report_alloc_peek(1);
	LL_ASSERT(node_rx);

	radio_df_iq_data_packet_set(node_rx->pdu, IQ_SAMPLE_TOTAL_CNT);
}
#endif /* CONFIG_BT_CTLR_DF_SCAN_CTE_RX */

static int init_reset(void)
{
	return 0;
}
