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

using namespace hw;

/**** Private definitions ****/
/**** Private constants ****/
/**** Private variables ****/
/**** Private function declarations ****/

/**** Public function definitions ****/
hw::SafeAin::SafeAin(void)
{
	return;
}

hw::SafeAin::~SafeAin(void)
{
	return;
}

void hw::SafeAin::init(bsp::AnalogIn* ain_ch, util::VCounter* timer)
{
	this->ain_ch = ain_ch;
	this->timer = timer;
	
	this->under_treshold = 0;
	this->over_treshold = 0xFFFF;
	this->hold_time = 0;
	this->cooldown_time = 0;
	
	this->update_ain = 0;
	this->auto_reset = 0;
	
	this->warning = 0;
	this->fault = 0;
	
	this->last_read = 0;
	
	this->ts_state_chnage = 0;
}

void hw::SafeAin::process(void)
{
	// Update analog input
	if(this->update_ain) this->ain_ch->read();
	
	this->last_read = this->ain_ch->last_read;
	
	// Get current time
	uint16_t ts_now = this->timer->read();
	
	// Update over current and warning condition
	uint8_t is_outside = 0;
	if(this->last_read < this->under_treshold) is_outside = 1;
	if(this->last_read > this->over_treshold) is_outside = 1;
	
	// Note start time if new OC condition
	if(is_outside != this->warning) this->ts_state_chnage = ts_now;
	
	// Update warning
	this->warning = is_outside;
	
	// Calculate warning condition time
	uint16_t td = util::time_delta(this->ts_state_chnage, ts_now);
	uint32_t time_ms = this->timer->convert_ms(td);
	
	// Check for fault set
	if((this->fault==0)&&(time_ms > (uint32_t)this->hold_time))
	{
		this->fault = 1;
		return;
	};
	
	// Check if allowed auto reset
	if(this->auto_reset==0) return;
	
	// Check for fault reset
	if((this->fault!=0)&&(time_ms > (uint32_t)this->cooldown_time))
	{
		this->fault = 0;
		return;
	};
}

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