/**** Includes ****/
#include "../utils/utils.h"
#include "dccd_hw.h"

using namespace hw;

/**** Private definitions ****/
/**** Private constants ****/
/**** Private variables ****/
/**** Private function declarations ****/
/**** Public function definitions ****/
dccd::DccdHw::DccdHw(void)
{
	return;
}

dccd::DccdHw::~DccdHw(void)
{
	return;
}

void dccd::DccdHw::init(dccdHwCfg_t* cfg)
{
	bsp::Board::boardCfg_t board_cfg;
	
	board_cfg.pwm_f_khz = cfg->pwm_f_khz;
	board_cfg.od_common_is_pwm = 1;
	
	this->board_hw.init(&board_cfg);
	
	this->counter.init(0xFFFF, 900);
	
	this->out_voltage.init(&(this->board_hw.out_voltage), &(this->counter));
	this->out_voltage.under_treshold = 0;
	this->out_voltage.over_treshold = 9000;
	this->out_voltage.hold_time = 1000;
	this->out_voltage.cooldown_time = 0;
	this->out_voltage.update_ain = 0;
	this->out_voltage.auto_reset = 1;
	
	this->out_current.init(&(this->board_hw.out_current), &(this->counter));
	this->out_current.under_treshold = 0;
	this->out_current.over_treshold = 6000;
	this->out_current.hold_time = 200;
	this->out_current.cooldown_time = 1000;
	this->out_current.update_ain = 0;
	this->out_current.auto_reset = 1;
	
	this->battery_voltage.init(&(this->board_hw.battery_voltage), &(this->counter));
	this->battery_voltage.under_treshold = 9000;
	this->battery_voltage.over_treshold = 18000;
	this->battery_voltage.hold_time = 1000;
	this->battery_voltage.cooldown_time = 0;
	this->battery_voltage.update_ain = 0;
	this->battery_voltage.auto_reset = 1;
	this->battery_voltage.last_read = 12000;
	
	this->battery_current.init(&(this->board_hw.battery_current), &(this->counter));
	this->battery_current.under_treshold = 0;
	this->battery_current.over_treshold = 8000;
	this->battery_current.hold_time = 200;
	this->battery_current.cooldown_time = 1000;
	this->battery_current.update_ain = 0;
	this->battery_current.auto_reset = 1;
	
	this->btn_up.init(&(this->board_hw.din4), 0, &(this->counter), 10);
	this->btn_up.update_din = 0;
	
	this->btn_down.init(&(this->board_hw.din3), 0, &(this->counter), 10);
	this->btn_down.update_din = 0;
	
	this->btn_mode.init(&(this->board_hw.din1), 0, &(this->counter), 10);
	this->btn_mode.update_din = 0;
	
	this->handbrake.init(&(this->board_hw.hvdin3), 0, &(this->counter), 10);
	this->handbrake.update_din = 0;
	
	this->brakes.init(&(this->board_hw.hvdin2), 1, &(this->counter), 10);
	this->brakes.update_din = 0;
	
	this->dimm.init(&(this->board_hw.hvdin1), 1, &(this->counter), 10);
	this->dimm.update_din = 0;
	
	this->pot.init(&(this->board_hw.ain2), 500, 4500);
	this->pot.update_ain = 0;
	
	this->outdriver.init(&(this->board_hw.out_pwm), &(this->board_hw.out_low));
	
	hw::LedDisplay::doutCfg_t dsp_cfg;
	dsp_cfg.led0_dout_ch = &(this->board_hw.od1);
	dsp_cfg.led1_dout_ch = &(this->board_hw.od2);
	dsp_cfg.led2_dout_ch = &(this->board_hw.od3);
	dsp_cfg.led3_dout_ch = &(this->board_hw.od4);
	dsp_cfg.led4_dout_ch = &(this->board_hw.od5);
	dsp_cfg.led5_dout_ch = &(this->board_hw.od6);
	
	this->display.init(&dsp_cfg, 0, &(this->counter), &(this->board_hw.od_pwm));
	
	// Apply configuration
	if(cfg->handbrake_pull_up)
	{
		this->board_hw.hvdin3_pull.write(1);
	}
	else this->board_hw.hvdin3_pull.write(0);
	
	if(cfg->speed_hall)
	{
		this->board_hw.freq_pull.write(1);
	}
	else this->board_hw.freq_pull.write(0);
	
	// Set initial output states
	this->outdriver.write((uint16_t)0);
	this->outdriver.enable();
	
	this->display.write_backlight(100);
	this->display.write(0x00);
}

void dccd::DccdHw::read(void)
{
	// Update low level inputs
	this->board_hw.read();
	
	this->counter.increment();
	
	this->out_voltage.process();
	this->out_current.process();
	this->battery_voltage.process();
	this->battery_current.process();
	
	this->btn_up.process();
	this->btn_down.process();
	this->btn_mode.process();
	this->handbrake.process();
	this->brakes.process();
	this->dimm.process();
	
	this->pot.read();
}

/**** Private function definitions ***/
