#include <stdint.h>
#include "main.h"
#include "nrf_drv_pwm.h"
#include "CIE1931.h"

#include "app_error.h"
#include "nrf_log.h"
#include "app_util_platform.h"

uint16_t PWM_outputs[16] = {0};

nrf_pwm_values_individual_t output_PWM[] = {
	{0x8000, 0x8000, 0x8000, 0x8000},
	{0x8000, 0x8000, 0x8000, 0x8000},
	{0x8000, 0x8000, 0x8000, 0x8000}
};
static nrf_drv_pwm_t m_pwm0 = NRF_DRV_PWM_INSTANCE(0);
static nrf_drv_pwm_t m_pwm1 = NRF_DRV_PWM_INSTANCE(1);
static nrf_drv_pwm_t m_pwm2 = NRF_DRV_PWM_INSTANCE(2);

void lights_off(void)
{
	for(int i = 0; i < 16; i++)
	{
		PWM_outputs[i] = 0;
	}
}
static void event_handler_PWM_0(nrf_drv_pwm_evt_type_t event_type)
{
	if (event_type == NRF_DRV_PWM_EVT_END_SEQ0 || event_type == NRF_DRV_PWM_EVT_END_SEQ1)
{
			output_PWM[0].channel_0 = PWM_outputs[0] | 0x8000;
			output_PWM[0].channel_1 = PWM_outputs[1] | 0x8000;
			output_PWM[0].channel_2 = PWM_outputs[2] | 0x8000;
			output_PWM[0].channel_3 = PWM_outputs[3] | 0x8000;
	}
}
static void event_handler_PWM_1(nrf_drv_pwm_evt_type_t event_type)
{
	if (event_type == NRF_DRV_PWM_EVT_END_SEQ0 || event_type == NRF_DRV_PWM_EVT_END_SEQ1)
{
			output_PWM[1].channel_0 = PWM_outputs[4] | 0x8000;
			output_PWM[1].channel_1 = PWM_outputs[5] | 0x8000;
			output_PWM[1].channel_2 = PWM_outputs[6] | 0x8000;
			output_PWM[1].channel_3 = PWM_outputs[7] | 0x8000;
	}
}
static void event_handler_PWM_2(nrf_drv_pwm_evt_type_t event_type)
{
	if (event_type == NRF_DRV_PWM_EVT_END_SEQ0 || event_type == NRF_DRV_PWM_EVT_END_SEQ1)
{
		output_PWM[2].channel_0 = PWM_outputs[8] | 0x8000;
		output_PWM[2].channel_1 = PWM_outputs[9] | 0x8000;
		output_PWM[2].channel_2 = PWM_outputs[10] | 0x8000;
		output_PWM[2].channel_3 = PWM_outputs[11];// | 0x8000;
	
//		/* Switch buffers */
//		/* Read new data */
//		if(DMX512_buffers.DMX512_write == DMX512_buffers.DMX512_read_prev)
//		{
//			DMX512_buffers.DMX512_read_prev = DMX512_buffers.DMX512_read;
//			DMX512_buffers.DMX512_read = DMX512_buffers.DMX512_write_prev;
//		}else if(DMX512_buffers.DMX512_read_prev == DMX512_buffers.DMX512_write_prev)
//		{
//			
//			DMX512_buffers.DMX512_read_prev = DMX512_buffers.DMX512_read;
//			DMX512_buffers.DMX512_read = DMX512_buffers.DMX512_write_prev;
//		}else
//		{
//			/* None of buffers contains complete newer DMX512 frame */
//		}
//		/* Join two bytes together */
//		for(int i = 0; i < (sizeof(PWM_outputs)/sizeof(PWM_outputs[0]))<<1; i+=2)
//		{
//			PWM_outputs[i>>1] = (uint16_t)((DMX512_buffers.DMX512_read[i]<<8) | (DMX512_buffers.DMX512_read[i+1]));
//			PWM_outputs[i>>1] = cie1931_compute(PWM_outputs[i>>1]);
//		}
	}
}

void init_PWM(void)
{
	uint32_t err_code;

	/* Common configuration for all PWM */
	nrf_drv_pwm_config_t config =
	{
		.output_pins = {NRF_DRV_PWM_PIN_NOT_USED},
		.irq_priority = APP_IRQ_PRIORITY_LOWEST,
		.base_clock   = NRF_PWM_CLK_4MHz,
		.count_mode   = NRF_PWM_MODE_UP,
		.top_value    = 32767,
		.load_mode    = NRF_PWM_LOAD_INDIVIDUAL,
		.step_mode    = NRF_PWM_STEP_AUTO
	};

	/* PWM0 */

	config.output_pins[0] = 0;
	config.output_pins[1] = 1;
	config.output_pins[2] = 2;
	config.output_pins[3] = 3;
	err_code = nrf_drv_pwm_init(&m_pwm0, &config, &event_handler_PWM_0);
	APP_ERROR_CHECK(err_code);

	nrf_pwm_sequence_t const pwm0_seq =
	{
		.values.p_individual = &output_PWM[0],
		.length              = NRF_PWM_CHANNEL_COUNT,
		.repeats             = 0,
		.end_delay           = 0
	};

	/* PWM1 */

	config.output_pins[0] = 4;
	config.output_pins[1] = 5;
	config.output_pins[2] = 6;
	config.output_pins[3] = 7;
	err_code = nrf_drv_pwm_init(&m_pwm1, &config, &event_handler_PWM_1);
	APP_ERROR_CHECK(err_code);

	nrf_pwm_sequence_t const pwm1_seq =
	{
		.values.p_individual = &output_PWM[1],
		.length          = NRF_PWM_CHANNEL_COUNT,
		.repeats         = 0,
		.end_delay       = 0
	};

	/* PWM2 */

	config.output_pins[0] = 8;
	config.output_pins[1] = 9;
	config.output_pins[2] = 10;
	config.output_pins[3] = 18;		// GREEN PCB LED
	err_code = nrf_drv_pwm_init(&m_pwm2, &config, &event_handler_PWM_2);
	APP_ERROR_CHECK(err_code);

	nrf_pwm_sequence_t const pwm2_seq =
	{
		.values.p_individual = &output_PWM[2],
		.length          = NRF_PWM_CHANNEL_COUNT,
		.repeats         = 0,
		.end_delay       = 0
	};

	/* START PWM generation */
	nrf_drv_pwm_simple_playback(&m_pwm0, &pwm0_seq, 1, \
								NRF_DRV_PWM_FLAG_LOOP | \
								NRF_DRV_PWM_FLAG_SIGNAL_END_SEQ0 | \
								NRF_DRV_PWM_FLAG_SIGNAL_END_SEQ1);
	nrf_drv_pwm_simple_playback(&m_pwm1, &pwm1_seq, 1, \
								NRF_DRV_PWM_FLAG_LOOP | \
								NRF_DRV_PWM_FLAG_SIGNAL_END_SEQ0 | \
								NRF_DRV_PWM_FLAG_SIGNAL_END_SEQ1);
	nrf_drv_pwm_simple_playback(&m_pwm2, &pwm2_seq, 1, \
								NRF_DRV_PWM_FLAG_LOOP | \
								NRF_DRV_PWM_FLAG_SIGNAL_END_SEQ0 | \
								NRF_DRV_PWM_FLAG_SIGNAL_END_SEQ1);
}
