#include "adc_sim.h"

AdcSimHandle AdcSim;


void Simulate_ADC(SimStruct* S)
{
	real_T* IN = ssGetInputPortRealSignal(S, 0);

	adcMeasure(&AdcSim.Measure, IN, 0);

	adcConvert(&AdcSim.convertion, &AdcSim.udc1, AdcSim.Measure.udc1);
	adcConvert(&AdcSim.convertion, &AdcSim.udc2, AdcSim.Measure.udc2);
	adcConvert(&AdcSim.convertion, &AdcSim.ia1, AdcSim.Measure.ia1);
	adcConvert(&AdcSim.convertion, &AdcSim.ib1, AdcSim.Measure.ib1);
	adcConvert(&AdcSim.convertion, &AdcSim.ic1, AdcSim.Measure.ic1);
	adcConvert(&AdcSim.convertion, &AdcSim.ia2, AdcSim.Measure.ia2);
	adcConvert(&AdcSim.convertion, &AdcSim.ib2, AdcSim.Measure.ib2);
	adcConvert(&AdcSim.convertion, &AdcSim.ic2, AdcSim.Measure.ic2);
}

void Init_ADC_Simulation()
{
	adcInitConvertion(&AdcSim.convertion, NORMA_ACP, 2.5, 4096);
	adcInitMeasure(&AdcSim.udc1, K_LEM_ADC[0], R_ADC[0], DEFAULT_ZERO_ADC, UDC_SENS_MAX);
	adcInitMeasure(&AdcSim.udc2, K_LEM_ADC[1], R_ADC[1], DEFAULT_ZERO_ADC, UDC_SENS_MAX);
	adcInitMeasure(&AdcSim.ia1, K_LEM_ADC[2], R_ADC[2], DEFAULT_ZERO_ADC, IAC_SENS_MAX);
	adcInitMeasure(&AdcSim.ib1, K_LEM_ADC[3], R_ADC[3], DEFAULT_ZERO_ADC, IAC_SENS_MAX);
	adcInitMeasure(&AdcSim.ic1, K_LEM_ADC[4], R_ADC[4], DEFAULT_ZERO_ADC, IAC_SENS_MAX);
	adcInitMeasure(&AdcSim.ia2, K_LEM_ADC[5], R_ADC[5], DEFAULT_ZERO_ADC, IAC_SENS_MAX);
	adcInitMeasure(&AdcSim.ib2, K_LEM_ADC[6], R_ADC[6], DEFAULT_ZERO_ADC, IAC_SENS_MAX);
	adcInitMeasure(&AdcSim.ic2, K_LEM_ADC[7], R_ADC[7], DEFAULT_ZERO_ADC, IAC_SENS_MAX);

}

void adcInitConvertion(AdcConvertionHandle* hconv, int norma_adc, double adc_amplitude, int adc_bit_depth)
{
	hconv->norma_adc		= norma_adc;
	hconv->adc_amplitude	= adc_amplitude;
	hconv->adc_bit_depth	= adc_bit_depth;
}

void adcInitMeasure(AdcMeasureHandle* hmeasure, int k_lem_adc, int r_adc, int offset, double real_satur)
{
	hmeasure->k_lem_adc		= k_lem_adc;
	hmeasure->r_adc			= r_adc;
	hmeasure->offset		= offset;
	hmeasure->real_satur	= real_satur;
}

void adcMeasure(AdcRealMeasureHandle *hrmeasure, const real_T* u, int startind)
{
	hrmeasure->udc1 = u[startind++];
	hrmeasure->udc2 = u[startind++];
	hrmeasure->ia1 = u[startind++];
	hrmeasure->ib1 = u[startind++];
	hrmeasure->ic1 = u[startind++];
	hrmeasure->ia2 = u[startind++];
	hrmeasure->ib2 = u[startind++];
	hrmeasure->ic2 = u[startind++];
}

void adcConvert(AdcConvertionHandle* hconv, AdcMeasureHandle* hmeasure, double realMeasure)
{
	if (hmeasure->real_satur != 0)
	{
		if (realMeasure > hmeasure->real_satur)
			realMeasure = hmeasure->real_satur;
		else if (realMeasure < -hmeasure->real_satur)
			realMeasure = -hmeasure->real_satur;
	}

	hmeasure->adc_norm = realMeasure / hconv->norma_adc;
	//hmeasure->adc_val =
	//	(unsigned short)(realMeasure / hmeasure->k_lem_adc * hmeasure->r_adc / hconv->norma_adc / hconv->adc_amplitude * hconv->adc_bit_depth + (float)hmeasure->offset);
}