#include <stdio.h>
#include <string.h>
#include "main.h"

#include "nrf_gpio.h"
#include "app_util_platform.h"
#include "app_error.h"
//#include "bsp.h"
//#include "app_timer.h"
#include "nrf_drv_clock.h"
#include "nrf_delay.h"
#include "nrf_log.h"
#include "nrf_log_ctrl.h"
#include "app_timer.h"

#include "ble_imp.h"
#include "pwm.h"
#include "uart_DMX.h"

#include "ble_dmx_service_c.h"

bool DIP_state[3] = {false};
uint8_t DIP_code = 0;
uint16_t light_outputs[8][16];

void init_gpio( void )
{
	/* EXT ports pins */
	nrf_gpio_cfg_output(15);
	nrf_gpio_cfg_output(16);
	nrf_gpio_cfg_output(17);
	nrf_gpio_cfg_output(18);

	nrf_gpio_cfg_output(28);
	nrf_gpio_cfg_output(29);
	nrf_gpio_cfg_output(30);
	nrf_gpio_cfg_output(31);
	
	/* DIP pins */
	nrf_gpio_cfg_input(19,NRF_GPIO_PIN_NOPULL);
	nrf_gpio_cfg_input(20,NRF_GPIO_PIN_NOPULL);
	nrf_gpio_cfg_input(22,NRF_GPIO_PIN_NOPULL);

	/* Button */
	nrf_gpio_cfg_input(25,NRF_GPIO_PIN_NOPULL);

	/* Sampling DIP */
	DIP_state[0] = !nrf_gpio_pin_read(22);
	DIP_state[1] = !nrf_gpio_pin_read(20);
	DIP_state[2] = !nrf_gpio_pin_read(19);

	DIP_code = DIP_state[0] | (DIP_state[1]<<1) | (DIP_state[2]<<2);
}
void check_DMX_data(void)
{
	for(uint8_t receiver = 0; receiver < 8; receiver++)
	{
		for(uint8_t channel = 0; channel < 16; channel++)
		{
			/* MSB first */
			uint16_t channel_data = (uint16_t)((DMX512_buffers.read[(((receiver<<4)+channel)<<1)+1]<<8) | (DMX512_buffers.read[(((receiver<<4)+channel)<<1)+2]));
			if(light_outputs[receiver][channel] != channel_data)
			{
				light_outputs[receiver][channel] = channel_data;
				DMX_channel_send(receiver, channel, light_outputs[receiver][channel]);
			}
		}
		
	}
}
void check_DMX_group_data(void)
{
	bool group[2] = {false};
	for(uint8_t receiver = 0; receiver < 8; receiver++)
	{
		for(uint8_t channel = 0; channel < 8; channel++)
		{
			/* MSB first */
			uint16_t channel_data = (uint16_t)((DMX512_buffers.read[(((receiver<<4)+channel)<<1)+1]<<8) | (DMX512_buffers.read[(((receiver<<4)+channel)<<1)+2]));
			if(light_outputs[receiver][channel] != channel_data)
			{
				light_outputs[receiver][channel] = channel_data;
				group[0] = true;
			}
		}
		for(uint8_t channel = 8; channel < 16; channel++)
		{
			/* MSB first */
			uint16_t channel_data = (uint16_t)((DMX512_buffers.read[(((receiver<<4)+channel)<<1)+1]<<8) | (DMX512_buffers.read[(((receiver<<4)+channel)<<1)+2]));
			if(light_outputs[receiver][channel] != channel_data)
			{
				light_outputs[receiver][channel] = channel_data;
				group[1] = true;
			}
		}
		if(group[0])
		{
			DMX_channel_group_send(receiver, 0, &light_outputs[receiver][0]);
		}
		if(group[1])
		{
			DMX_channel_group_send(receiver, 1, &light_outputs[receiver][8]);
		}
		group[0] = false;
		group[1] = false;
	}
}
int main(void)
{
	ret_code_t err_code;

	err_code = NRF_LOG_INIT(NULL);
	APP_ERROR_CHECK(err_code);

	init_gpio();
	init_PWM();
	init_UART(DIP_state[2], DIP_state[1]);
	init_BLE();

	while (true)
	{
		/* Read new data */
		if(DMX512_buffers.write_prev != DMX512_buffers.read)
		{
			DMX512_buffers.read_prev = DMX512_buffers.read;
			DMX512_buffers.read = DMX512_buffers.write_prev;
			check_DMX_group_data();
		}else
		{
			/* None of buffers contains complete newer DMX512 frame */
		}
		
//		uint32_t err_code = sd_app_evt_wait();
//		APP_ERROR_CHECK(err_code);
	}
}

void app_error_fault_handler(uint32_t id, uint32_t pc, uint32_t info)
{
	NRF_LOG_ERROR("Fatal\r\n");
	NRF_LOG_FINAL_FLUSH();
	// On assert, the system can only recover with a reset.
	NVIC_SystemReset();
}

/** @} */
