/*
 * Copyright (c) 2016 Intel Corporation
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <device.h>
#include <devicetree.h>
#include <drivers/gpio.h>
#include <drivers/i2c.h>
#include <sys/printk.h>
#include <zephyr.h>



/* 1000 msec = 1 sec */
#define SLEEP_TIME_MS 10000

/* The devicetree node identifier for the "led0" alias. */
#define LED0_NODE DT_ALIAS(led0)

const struct device *led_dev;

#if DT_NODE_HAS_STATUS(LED0_NODE, okay)
#define LED0 DT_GPIO_LABEL(LED0_NODE, gpios)
#define PIN DT_GPIO_PIN(LED0_NODE, gpios)
#define FLAGS DT_GPIO_FLAGS(LED0_NODE, gpios)
#else
/* A build error here means your board isn't set up to blink an LED. */
#error "Unsupported board: led0 devicetree alias is not defined"
#define LED0 ""
#define PIN 0
#define FLAGS 0
#endif

////////////////////////////////////////////////////////////

// TWI Test Configuration

////////////////////////////////////////////////////////////

#define ECHO_WRITES true
#define MSG_EXCHANGE_CNT 5
#define INFINITE_MSG_EXCHANGE false
#define TWI_LOOPBACK false
// In non-loopback mode, the tx message is unchanged.
// In loopback mode the rx buffer acts as both the tx and rx buffer. The rx buffer is updated with each read.

////////////////////////////////////////////////////////////

// Adding TWI Functionality

////////////////////////////////////////////////////////////

#define TWI_BUFFER_SIZE 18
 
static const uint8_t readCommand[] = {0x03,0x00} ;
static const uint8_t dataReady[] = {0x02,0x02} ;
static const uint8_t triggerContinuousMeasurement[2] = {0x00,0x10} ;
static const uint8_t deactivateASC[] = {0x53, 0x06, 0x00, 0x00 } ;
static const uint8_t activateASC[2] = {0x53, 0x06 } ;
static const uint8_t getASC[] = {0x53, 0x06 } ;
static const uint8_t softRest[] = {0xD3,0x04} ;															
static const uint8_t framewareVersion[] = {0xD1,0x00} ;		 		

//5sec

static uint8_t i2c_rx_buffer [TWI_BUFFER_SIZE];

// TWI Master Setup

#define MY_TWIM DT_NODELABEL(i2c2)
const struct device *nrfx_twis_dev1;


static void twim_init(void)
{
	int config_result = false;
 

	nrfx_twis_dev1 = device_get_binding(DT_LABEL(MY_TWIM));
	printk("\n\nI2C Slave: Device driver not found.\n");
	if (nrfx_twis_dev1 == NULL)
	{
		printk("\n\nI2C Slave: Device driver not found.\n");
	}
	else
	{
		printk("\nI2C device 1: %s\n", DT_PROP(DT_NODELABEL(twis_device1), label));

		config_result = i2c_configure(nrfx_twis_dev1, I2C_SPEED_SET(I2C_SPEED_FAST) | I2C_MODE_MASTER);

		if (!config_result)
		{
			printk("I2C Master: Slave ADDR: 0x%x SCL: %d, SDA: %d, CLK(Hz): %u\n\n",
				   DT_REG_ADDR(DT_NODELABEL(twis_device1)),
				   DT_PROP(MY_TWIM, scl_pin),
				   DT_PROP(MY_TWIM, sda_pin),
				   DT_PROP(MY_TWIM, clock_frequency));
		}
		else
			printk("\n\nI2C: Configuration error code: %d\n", config_result);
			
	}
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// TWI Master Write
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
void twi_write_tst()
{
	int rtn_code = 0;
	uint8_t incr = 0;
     

	if (nrfx_twis_dev1 != NULL)
	{
		 printk("\nTWIM TX/writing.");
	 
		  // write repeated default message
			rtn_code = i2c_write(nrfx_twis_dev1, activateASC ,2, DT_REG_ADDR(DT_NODELABEL(twis_device1)));
		 	printk("\nTWIM TX/writing ----->        rtn_code: %d",rtn_code);
	 
		if (ECHO_WRITES && (rtn_code == 0))
		{/* 
			printk("\nTWIM TX:");
			while (incr < 2)
				printk("| 0x%.2x |", buffur[incr++]);
			printk("\n"); */
		} // rtn_code == 0

		if (rtn_code)
		{
			printk("twi return code %u\n\n", rtn_code);
		}
	}
	else // twis_dev1 == NULL
		printk("TWIS device is not initialized correctly.\n");
} 

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Checking if data is ready or not 
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////

uint8_t getReadyStatus(void)
{	

	// printk("\n GETTING READY STATUS!! ");
	int rtn_code = 0;
	uint8_t incr = 0;


	if (nrfx_twis_dev1 != NULL)
	{
		// printk("\nTWIM TX/writing.");
	 
		  // write repeated default message
			rtn_code = i2c_write(nrfx_twis_dev1, dataReady , 2 , DT_REG_ADDR(DT_NODELABEL(twis_device1)));
		 	 // printk("\nTWIM TX/writing  /dataReady/ -----> rtn_code: %d",rtn_code);
	 
		/* if (ECHO_WRITES && (rtn_code == 0))
		{
			printk("\nTWIM TX:");
			while (incr < 2)
				printk("|  %d  |", dataReady[incr++]);
			printk("\n");
		} // rtn_code == 0
 */
		/* if (rtn_code)
		{
			printk("twi return code %u\n\n", rtn_code);
		} */
	}
	else // twis_dev1 == NULL
	//	printk("TWIS device is not initialized correctly.\n");

    rtn_code = 0;
	incr = 0;
	k_msleep(5);	
	if (nrfx_twis_dev1 != NULL)
	{
		
	//	printk("\nTWIM RX/reading -->");
		rtn_code = i2c_read(nrfx_twis_dev1, i2c_rx_buffer, sizeof(i2c_rx_buffer), DT_REG_ADDR( DT_NODELABEL(twis_device1) ) );
		

		/* print the result */

		if (rtn_code == 0)
		{
	/* 		printk("TWIM RX:");
			while (incr < TWI_BUFFER_SIZE)
			{
				printk(" | %d  | ", i2c_rx_buffer[incr++]);
			};
			printk("\n");
			 */
			 
		}

		if (rtn_code)  printk("twi return code %u\n\n", rtn_code);
	}
	else // twim_dev1 == NULL
		printk("TWI is not initialized correctly.\n");

return i2c_rx_buffer[1] ;

} 

void twi_read_tst(void)
{
	int rtn_code = 0;
	uint8_t incr = 0;

	if (nrfx_twis_dev1 != NULL)
	{
		
		printk("\nTWIM RX/reading -->");
		rtn_code = i2c_read(nrfx_twis_dev1, i2c_rx_buffer, sizeof(i2c_rx_buffer), DT_REG_ADDR( DT_NODELABEL(twis_device1) ) );
		

		/* print the result */

		if (rtn_code == 0)
		{
			printk("TWIM RX:");
			while (incr < TWI_BUFFER_SIZE)
			{
				printk(" | 0x%.2x  | ", i2c_rx_buffer[incr++]);
			};
			printk("\n");
		}

		if (rtn_code)  printk("twi return code %u\n\n", rtn_code);
	}
	else // twim_dev1 == NULL
		printk("TWI is not initialized correctly.\n");
}

void main(void)
{
	uint16_t twi_test_cnt = MSG_EXCHANGE_CNT;
	bool led_is_on = true;
	uint32_t ret;

	led_dev = device_get_binding(LED0);
	if (led_dev == NULL)
	{
		return;
	}

	ret = gpio_pin_configure(led_dev, PIN, GPIO_OUTPUT_ACTIVE | FLAGS);
	if (ret < 0)
	{
		return;
	}

	twim_init();
	k_msleep(2000);
	i2c_write(nrfx_twis_dev1,softRest,2,DT_REG_ADDR(DT_NODELABEL(twis_device1)) )	;
	k_msleep(2000);

	int rtn_code = 5;
	int	incr = 0 ;
	i2c_write(nrfx_twis_dev1,triggerContinuousMeasurement,2,DT_REG_ADDR(DT_NODELABEL(twis_device1)) )	;
	k_msleep(2000);
	i2c_write(nrfx_twis_dev1,activateASC,2,DT_REG_ADDR(DT_NODELABEL(twis_device1)) );
	k_msleep(2000);
	i2c_write(nrfx_twis_dev1,dataReady,2,DT_REG_ADDR(DT_NODELABEL(twis_device1)) );
	k_msleep(2000);
	i2c_read(nrfx_twis_dev1, i2c_rx_buffer, sizeof(i2c_rx_buffer), DT_REG_ADDR( DT_NODELABEL(twis_device1) ) );
 	while (1)
	{

		gpio_pin_set(led_dev, PIN, (int)led_is_on);
		led_is_on = !led_is_on;

		if ((twi_test_cnt) || (INFINITE_MSG_EXCHANGE))
		{		
			incr = 0 ;
			// i2c_write_read(nrfx_twis_dev1, DT_REG_ADDR(DT_NODELABEL(twis_device1)),readCommand,2,i2c_rx_buffer,18);
			i2c_write(nrfx_twis_dev1,readCommand,2,DT_REG_ADDR(DT_NODELABEL(twis_device1)) );
			i2c_read(nrfx_twis_dev1, i2c_rx_buffer, sizeof(i2c_rx_buffer), DT_REG_ADDR( DT_NODELABEL(twis_device1) ) );
 			while (incr < 18)
			printk("| 0x%.2x |", i2c_rx_buffer[incr++]);
			printk("\n"); 
			
			
		}
		k_msleep(10000);
	}
}