/*
 * Copyright (c) 2021 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
 */

#include <zephyr/kernel.h>
#include <zephyr/sys/printk.h>

#include <zephyr/bluetooth/bluetooth.h>
#include <zephyr/bluetooth/conn.h>
#include <zephyr/bluetooth/uuid.h>
#include <zephyr/bluetooth/hci.h>
#include <zephyr/pm/device.h>
#include <zephyr/device.h>

#include <zephyr/settings/settings.h>

#include <dk_buttons_and_leds.h>

#define NON_CONNECTABLE_ADV_IDX 0

#define NON_CONNECTABLE_DEVICE_NAME "BlueJoule"

static struct device const *uart_dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_console));

static struct bt_le_ext_adv *ext_adv[CONFIG_BT_EXT_ADV_MAX_ADV_SET];
static const struct bt_le_adv_param *non_connectable_adv_param =
	BT_LE_ADV_PARAM(BT_LE_ADV_OPT_SCANNABLE,
			1600, /* 1000 ms */
			1600, /* 1000 ms */
			NULL);

static const struct bt_data non_connectable_ad_data[] = {
	BT_DATA_BYTES(BT_DATA_FLAGS, BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR),
    BT_DATA_BYTES(BT_DATA_MANUFACTURER_DATA, 0xd3, 0x08, 0xff),
};

static const struct bt_data non_connectable_sd_data[] = {
	BT_DATA(BT_DATA_NAME_COMPLETE, NON_CONNECTABLE_DEVICE_NAME,
		sizeof(NON_CONNECTABLE_DEVICE_NAME) - 1),
};

static int advertising_set_create(struct bt_le_ext_adv **adv,
				  const struct bt_le_adv_param *param,
				  const struct bt_data *ad, size_t ad_len,
				  const struct bt_data *sd, size_t sd_len)
{
	int err;
	struct bt_le_ext_adv *adv_set;

	err = bt_le_ext_adv_create(param, NULL,
				   adv);
	if (err) {
		return err;
	}

	adv_set = *adv;

	printk("Created adv: %p\n", adv_set);

	err = bt_le_ext_adv_set_data(adv_set, ad, ad_len, sd, sd_len);
	if (err) {
		printk("Failed to set advertising data (err %d)\n", err);
		return err;
	}

	return bt_le_ext_adv_start(adv_set, BT_LE_EXT_ADV_START_DEFAULT);
}

static int non_connectable_adv_create(void)
{
	int err;

	err = advertising_set_create(&ext_adv[NON_CONNECTABLE_ADV_IDX], non_connectable_adv_param,
				     non_connectable_ad_data, ARRAY_SIZE(non_connectable_ad_data),
				     non_connectable_sd_data, ARRAY_SIZE(non_connectable_sd_data));
	if (err) {
		printk("Failed to create a non-connectable advertising set (err %d)\n", err);
	}

	return err;
}

#if 0
static void reg(const char* name, uint32_t addr) {
    uint32_t val = *((volatile uint32_t*)addr);
    printk("%s = ", name);
    printk("%d (%x)\n", val, val);
}
#endif

int main(void)
{
	int err;
#if IS_ENABLED(CONFIG_BOARD_NRF54L15DK)
	/* Allow RRAMC to go into poweroff mode during System on idle for lower power consumption at a penalty of 9us extra RRAM ready time */
	NRF_RRAMC->POWER.LOWPOWERCONFIG = (RRAMC_POWER_LOWPOWERCONFIG_MODE_PowerOff << RRAMC_POWER_LOWPOWERCONFIG_MODE_Pos);
#endif

//	printk("Starting Bluetooth multiple advertising sets example\n");
//
//	err = dk_leds_init();
//	if (err) {
//		printk("LEDs init failed (err %d)\n", err);
//		return 0;
//	}

    //// err = bt_enable(NULL);

//	if (err) {
//		printk("Bluetooth init failed (err %d)\n", err);
//		return 0;
//	}

//	printk("Bluetooth initialized\n");
	//// err = non_connectable_adv_create();
	//// if (err) {
	//// 	return 0;
	//// }

//	printk("Non-connectable advertising started\n");
#if 0
    reg("BASE0", 0x4000151C);
    reg("PREFIX0", 0x40001524);
    reg("PCNF0", 0x40001514);
    reg("PCNF1", 0x40001518);
    reg("CRCCNF", 0x40001534);
    reg("CRCPOLY", 0x40001538);
    reg("CRCINIT", 0x4000153C);
    reg("WHITEIV", 0x40001554);
    reg("SHORTS", 0x40001200);
    reg("INTEN", 0x40001304);
#endif
#if 0
    reg("XO.RUN", 0x5010e408);
    reg("XO.STAT", 0x5010e40c);
    reg("PLL.RUN", 0x5010e428);
    reg("PLL.STAT", 0x5010e42c);
// reg("", 0x5008ae2c);
    // reg("PREFIX0", 0x5008ae34);
    // reg("PCNF0", 0x5008ae20);
    // reg("PCNF1", 0x5008ae28);
    // reg("CRCCNF", 0x5008ae44);
    // reg("CRCPOLY", 0x5008ae48);
    // reg("CRCINIT", 0x5008ae4c);
    // reg("WHITE", 0x5008a540);
    // reg("SHORTS", 0x5008a400);
    // reg("INTEN0", 0x5008a488);
    // reg("INTEN1", 0x5008a4a8);
#endif

    // printk("LFCLKSTAT = 0x%08x\n", NRF_CLOCK->LFCLKSTAT);
    // printk("HFCLKSTAT = 0x%08x\n", NRF_CLOCK->HFCLKSTAT);
    // printk("DCDCEN    = 0x%08x\n", NRF_POWER->DCDCEN);


    int i;

    for (i = 0; i < 8; ++i) {
        printk("RAM[%d].POWER = 0x%08x\n", i, NRF_POWER->RAM[i].POWER);
    }

    printk("EE4 = 0x%08x\n", *(volatile uint32_t *)0x40000EE4);    


    k_msleep(100);
	/* Disable UART to reduce System ON idle current */
	err = pm_device_action_run(uart_dev, PM_DEVICE_ACTION_SUSPEND);
	if (err) {
//		printk("UART suspend failed. (err %d)\n", err);
		return 1;
	}

}

