#include <nrf.h>
#include "nrf_radio.h"
#include "string.h"
#include "nrf_gpio.h"
#include "RadioMsg.h"
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "nrf_drv_rtc.h"
#include "stdlib.h"
#include "nrf_log.h"
#include "nrf_log_ctrl.h"
#include "nrf_log_default_backends.h"
#include "nrf_drv_clock.h"




#define ADV_ACCESS_ADDRESS 0x8E89BED6
bool SetBLE_Channel(uint8_t BLE_Channel);
void SetScanFlag(bool Val);
uint8_t BLE_MAC_Buffer[6]  = {0};
static uint8_t	tx_packet[258];              /**< Packet to transmit. */							
static uint8_t	rx_packet[258];              /**< Packet to receive. */





bool get_ble_mac_address(uint8_t *mac_addr);
const nrf_drv_rtc_t rtc2 = NRF_DRV_RTC_INSTANCE(2); /**< Declaring an instance of nrf_drv_rtc for RTC0. */

// 广播 PDU
static uint8_t adv_pdu[] = {
    0x02, 0x13, // ADV_IND, Payload Length=19 (AdvA 6 + Flags 3 + Name 10)
    0xCA, 0xFE, 0xBA, 0xBE, 0x01, 0x02, // AdvA (random address)
    0x02, 0x01, 0x06, // Flags: LE General Discoverable, BR/EDR Not Supported
    0x09, 0x09, 'n', 'R', 'F', '5', '2', '8', '4', '0' // Name: nRF52840
};

bool tx_ready_flag = false;  // 任务里轮询/等待信号量
volatile bool radio_tx_complete = false;
volatile bool radio_rx_complete = false;
volatile bool is_scanning = false;
volatile bool is_get_loc_adv = false;
volatile bool need_tx = false;


// Radio 数据包配置
nrf_radio_packet_conf_t packet_conf = {
    .lflen      = 8,                              /**< Length on air of LENGTH field in number of bits. */
    .s0len      = 1,                              /**< Length on air of S0 field in number of bytes. */
    .s1len      = 0,                              /**< Length on air of S1 field in number of bits. */
#if defined(RADIO_PCNF0_S1INCL_Msk) || defined(__NRFX_DOXYGEN__)
    .s1incl     = false,                          /**< Include or exclude S1 field in RAM. */
#endif
#if defined(RADIO_PCNF0_CILEN_Msk) || defined(__NRFX_DOXYGEN__)
    .cilen      = 0,                              /**< Length of code indicator - long range. */
#endif
#if defined(RADIO_PCNF0_PLEN_Msk) || defined(__NRFX_DOXYGEN__)
   .plen        = NRF_RADIO_PREAMBLE_LENGTH_8BIT, /**< Length of preamble on air. Decision point: TASKS_START task. */
#endif
#if defined(RADIO_PCNF0_CRCINC_Msk) || defined(__NRFX_DOXYGEN__)
    .crcinc	    = false,                          /**< Indicates if LENGTH field contains CRC or not. */
#endif
#if defined(RADIO_PCNF0_TERMLEN_Msk) || defined(__NRFX_DOXYGEN__)
    .termlen    = 0,                              /**< Length of TERM field in Long Range operation. */
#endif
    .maxlen     = 255,                            /**< Maximum length of packet payload. */
    .statlen    = 0,                              /**< Static length in number of bytes. */
    .balen      = 3,                              /**< Base address length in number of bytes. */
    .big_endian = false,                          /**< On air endianness of packet. */
    .whiteen    = true                            /**< Enable or disable packet whitening. */
};




// Radio 初始化
void radio_init(void)
{	
	// 启动 HFCLK (16 MHz 外部晶振)
    NRF_CLOCK->EVENTS_HFCLKSTARTED = 0;
    NRF_CLOCK->TASKS_HFCLKSTART    = 1;
    while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0);

	
	if (get_ble_mac_address(BLE_MAC_Buffer) == true) {
		memcpy(&adv_pdu[2], BLE_MAC_Buffer, 6);
	}
    nrf_radio_mode_set(NRF_RADIO_MODE_BLE_1MBIT);
	
    nrf_radio_txpower_set(NRF_RADIO_TXPOWER_POS8DBM);
	
    nrf_radio_base0_set(ADV_ACCESS_ADDRESS << 8);
    nrf_radio_prefix0_set((ADV_ACCESS_ADDRESS >> 24) & 0xFF);
	
    nrf_radio_txaddress_set(0);
    nrf_radio_rxaddresses_set(RADIO_RXADDRESSES_ADDR0_Enabled);
	
    nrf_radio_crc_configure(RADIO_CRCCNF_LEN_Three, NRF_RADIO_CRC_ADDR_SKIP, 0x100065B);
    nrf_radio_crcinit_set(0x555555);
	
	nrf_radio_packet_configure(&packet_conf);
	
	SetBLE_Channel(37);
	
	nrf_radio_packetptr_set(rx_packet); // 设置接收缓冲区
	
	// SHORTS: 
    // 1) READY→START  (RX/TX ramp-up 后自动开始收/发)
    // 2) END→DISABLE  (一包结束自动关闭)
    // 3) DISABLED→RXEN (自动进入 RX 循环)
    nrf_radio_shorts_enable(NRF_RADIO_SHORT_ADDRESS_RSSISTART_MASK 
							| NRF_RADIO_SHORT_READY_START_MASK 
							| NRF_RADIO_SHORT_END_DISABLE_MASK);
	
    nrf_radio_int_enable(NRF_RADIO_INT_END_MASK | NRF_RADIO_INT_DISABLED_MASK);
    NVIC_SetPriority(RADIO_IRQn, 4);//freertos目前管理优先级是2
    NVIC_EnableIRQ(RADIO_IRQn);
	
	SetScanFlag(true);
	// 启动接收
    nrf_radio_task_trigger(NRF_RADIO_TASK_RXEN);
}

bool SetBLE_Channel(uint8_t BLE_Channel)
{
	uint16_t freq_mhz;
	
	// 检查信道编号是否有效
    if (BLE_Channel > 39) {
        return false;
    }
	
	// 广播信道特殊映射

    if (BLE_Channel == 37) { 
		freq_mhz =  2402; // 信道37: 2426 MHz	
	} else if (BLE_Channel == 38) {
		freq_mhz =  2426; // 信道38: 2478 MHz
	} else if (BLE_Channel == 39) {
		freq_mhz =  2480; // 信道39: 2480 MHz
	} else {
		if (BLE_Channel <=10 ) {
			freq_mhz = 2404 + 2 * BLE_Channel;
		} else if (BLE_Channel > 10 && BLE_Channel < 37) {
			freq_mhz = 2406 + 2 * BLE_Channel;
		}
	}
	nrf_radio_frequency_set(freq_mhz);
    nrf_radio_datawhiteiv_set(BLE_Channel);
	
	return true;
}

bool get_ble_mac_address(uint8_t *mac_addr)
{
    if (mac_addr == NULL) {
        return false;
    }
#if 1
    // 从FICR寄存器读取48位设备地址
    uint32_t addr_low = NRF_FICR->DEVICEADDR[0];  // 低32位
    uint32_t addr_high = NRF_FICR->DEVICEADDR[1]; // 高16位

    // 组合成48位MAC地址（6字节）
    mac_addr[0] = (uint8_t)(addr_low);        // LSB
    mac_addr[1] = (uint8_t)(addr_low >> 8);
    mac_addr[2] = (uint8_t)(addr_low >> 16);
    mac_addr[3] = (uint8_t)(addr_low >> 24);
    mac_addr[4] = (uint8_t)(addr_high);
    mac_addr[5] = (uint8_t)(addr_high >> 8);  // MSB

	// 设置为随机静态地址（最高两位为11）
    mac_addr[5] |= 0xC0; // 设置最高两位为11
#endif

    return true;
}

// 信道、接入地址、内容mac、
// 广播函数
bool SendLocRequestRadio(CurrentLocParaDef LocPara)
{
	uint16_t freq_mhz;
	uint32_t timeout = 100000;
	uint8_t BLE_Channel;
	
	uint8_t SendBuffer[50];
	
	BLE_Channel = LocPara.OOB_RxChannel;
	
	memset(SendBuffer, 0x00, sizeof(SendBuffer));
	
	
	
	// 检查信道编号是否有效
    if (BLE_Channel > 39) {
        return false;
    }
	
	// 广播信道特殊映射

    if (BLE_Channel == 37) { 
		freq_mhz =  2402; // 信道37: 2426 MHz	
	} else if (BLE_Channel == 38) {
		freq_mhz =  2426; // 信道38: 2478 MHz
	} else if (BLE_Channel == 39) {
		freq_mhz =  2480; // 信道39: 2480 MHz
	} else {
		if (BLE_Channel <=10 ) {
			freq_mhz = 2404 + 2 * BLE_Channel;
		} else if (BLE_Channel > 10 && BLE_Channel < 37) {
			freq_mhz = 2406 + 2 * BLE_Channel;
		}
	}

    // 确保发送前tx_packet包含adv_pdu
    memset(tx_packet, 0x00, sizeof(tx_packet));
    memcpy(tx_packet, &SendBuffer, sizeof(SendBuffer));
	
	//使用下发时隙内的信息修改
	nrf_radio_base0_set(LocPara.OOB_Address << 8);
    nrf_radio_prefix0_set((LocPara.OOB_Address >> 24) & 0xFF);
	
	nrf_radio_frequency_set(freq_mhz);
    nrf_radio_datawhiteiv_set(BLE_Channel);
	
	nrf_radio_packetptr_set(tx_packet); // 设置发送缓冲区
	
    radio_tx_complete = false;
    is_scanning = false;
	
    // 触发切换 (TXEN → READY → START → 发射)
    nrf_radio_task_trigger(NRF_RADIO_TASK_TXEN);

    while (!radio_tx_complete && timeout--) {
        __WFE();
    }
    if (timeout == 0) {
        return false;
    }
	
	// 发完后恢复 RX 循环
	memset(rx_packet, 0, sizeof(rx_packet));
    //设置DISABLED -> RXEN 快捷键
    nrf_radio_packetptr_set(rx_packet);
	
	SetBLE_Channel(37);
	//设置接入地址
	nrf_radio_base0_set(ADV_ACCESS_ADDRESS << 8);
    nrf_radio_prefix0_set((ADV_ACCESS_ADDRESS >> 24) & 0xFF);
	
	is_scanning = true;
	need_tx = false;
	
    nrf_radio_task_trigger(NRF_RADIO_TASK_RXEN);
	
    return true;
}




void SetScanFlag(bool Val)
{
	is_scanning = Val;
}

void ConfigModeDeInitRadioRx(void)
{
	nrf_radio_event_clear(NRF_RADIO_EVENT_END);
	nrf_radio_event_clear(NRF_RADIO_EVENT_DISABLED);
	
	nrf_radio_shorts_disable(NRF_RADIO_SHORT_DISABLED_RXEN_MASK);
	
	// 准备进入发送前，先清事件
	nrf_radio_event_clear(NRF_RADIO_EVENT_DISABLED);
	
	tx_ready_flag = false;
	
	// 触发 DISABLE
	nrf_radio_task_trigger(NRF_RADIO_TASK_DISABLE);

	// 等待 flag / 信号量
	while (!tx_ready_flag) { __WFE(); }
}

// 中断处理
void RADIO_IRQHandler(void)
{
	 uint32_t err_code;
	
    if (NRF_RADIO->EVENTS_END) {
        NRF_RADIO->EVENTS_END = 0;
        if (is_scanning) {
			if (NRF_RADIO->CRCSTATUS == 1) {
				need_tx = false;
			} else {
				need_tx = false;
			}
        } else {
            radio_tx_complete = true;
        }
    }
    if (NRF_RADIO->EVENTS_DISABLED) {
        NRF_RADIO->EVENTS_DISABLED = 0;
//        NVIC_ClearPendingIRQ(RADIO_IRQn);
		tx_ready_flag = true;
        if (need_tx == false && is_scanning == true)
        {
            nrf_radio_task_trigger(NRF_RADIO_TASK_RXEN);
        }
    }
}
