
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
#include "sdk_common.h"
#include "nrf.h"
#include "nrf_esb.h"
#include "nrf_error.h"
#include "nrf_esb_error_codes.h"
#include "nrf_delay.h"
#include "nrf_gpio.h"
#include "boards.h"
#include "nrf_delay.h"
#include "app_util.h"
#include "app_timer.h"
#include "nrf_drv_gpiote.h"

#include "nrf_log.h"
#include "nrf_log_ctrl.h"
#include "nrf_log_default_backends.h"
#include "EsbProcess.h"

nrf_esb_config_t			nrf_esb_config	=	NRF_ESB_DEFAULT_CONFIG;
esb_packet_received_t		rx_callback;
nrf_esb_payload_t			tx_payload, rx_payload;
volatile	bool			radio_tx_busy = false, radio_started = false;

unsigned long	PacketSendCnt = 0;
unsigned long	PacketSendOKCnt = 0;
unsigned long	PacketSentNGCnt = 0;
unsigned long	PacketReceiveOKCnt = 0;
unsigned long	PacketReceiveNGCnt = 0;

extern	void nrf_esb_event_handler(nrf_esb_evt_t const * p_event);

void nrf_esb_event_handler(nrf_esb_evt_t const * p_event)
{
	switch (p_event->evt_id)
	{
		case NRF_ESB_EVENT_TX_SUCCESS:
			radio_tx_busy = false;
			nrf_esb_disable();
			nrf_esb_config.mode = NRF_ESB_MODE_PRX;
			nrf_esb_init(&nrf_esb_config);
			nrf_esb_start_rx();
			PacketSendOKCnt++;
			break;
		case NRF_ESB_EVENT_TX_FAILED:
			radio_tx_busy = false;
			PacketSentNGCnt++;
			break;
		case NRF_ESB_EVENT_RX_RECEIVED:
			if (nrf_esb_read_rx_payload(&rx_payload) == NRF_SUCCESS && rx_callback)
			{
				rx_callback(rx_payload.data, rx_payload.length);
			}
			break;
	}
}

uint32_t esb_init(uint16_t network_id, uint32_t Address_0, uint32_t Address_1, esb_packet_received_t esb_received_callback)
{
	uint32_t err_code;
	uint8_t base_addr_0[4] = {0xE7, 0xE7, 0xE7, 0xE7};
	uint8_t base_addr_1[4] = {0xC2, 0xC2, 0xC2, 0xC2};
	uint8_t addr_prefix[8] = {0xE7, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8 };

	nrf_esb_config.payload_length		   = EsbPacketLength;
	nrf_esb_config.tx_mode				  = NRF_ESB_TXMODE_AUTO;
	nrf_esb_config.protocol				 = NRF_ESB_PROTOCOL_ESB_DPL;
	nrf_esb_config.bitrate				  = NRF_ESB_BITRATE_2MBPS;
	nrf_esb_config.mode					 = NRF_ESB_MODE_PRX;
	nrf_esb_config.event_handler			= nrf_esb_event_handler;
	nrf_esb_config.selective_auto_ack	   = true;
#if 0
	base_addr_0[0] = (Address_0 >> 0) & 0xFF;
	base_addr_0[1] = (Address_0 >> 8) & 0xFF;
	base_addr_0[2] = (Address_0 >> 16) & 0xFF;
	base_addr_0[3] = (Address_0 >> 24) & 0xFF;
	base_addr_1[0] = (Address_1 >> 8) & 0xFF;
	base_addr_1[1] = (Address_1 >> 8) & 0xFF;
	base_addr_1[2] = (Address_1 >> 16) & 0xFF;
	base_addr_1[3] = (Address_1 >> 24) & 0xFF;
#endif
	err_code = nrf_esb_init(&nrf_esb_config);
	VERIFY_SUCCESS(err_code);

	err_code = nrf_esb_set_base_address_0(base_addr_0);
	VERIFY_SUCCESS(err_code);

	err_code = nrf_esb_set_base_address_1(base_addr_1);
	VERIFY_SUCCESS(err_code);

	err_code = nrf_esb_set_prefixes(addr_prefix, 8);
	VERIFY_SUCCESS(err_code);

	err_code = nrf_esb_set_rf_channel(network_id);
	VERIFY_SUCCESS(err_code);

	err_code = nrf_esb_start_rx();
	VERIFY_SUCCESS(err_code);

	rx_callback = esb_received_callback;

	radio_started = true;

	return err_code;
}

bool esb_packet_send(uint8_t *packet, uint32_t packet_length)
{
	if(radio_started)
	{
		while(radio_tx_busy);
		nrf_esb_stop_rx();
		nrf_esb_disable();
		nrf_esb_config.mode = NRF_ESB_MODE_PTX;
		nrf_esb_init(&nrf_esb_config);
		nrf_esb_start_tx();
		memcpy(tx_payload.data, packet, packet_length);
		tx_payload.length = packet_length;
		tx_payload.pipe = 0;
		tx_payload.noack = true;
		if(nrf_esb_write_payload(&tx_payload) == NRF_SUCCESS)
			radio_tx_busy = true;
		PacketSendCnt++;
		return true;
	}
	return false;
}
