/**************************************************************************
	Description: Функция вызывается один раз в начале выполнения
	программы и подготавливает данные необходимые для её работы.

	Автор: Улитовский Д.И.
	Дата последнего обновления: 2021.11.08
**************************************************************************/


#include "def.h"
#include "detcoeff.h"


void process_sgm_parameters(void);
short read_eeprom(void);
short test_param(void);


void detcoeff(void) {
	float Tci;
	float Tcf;
	float Tcs;
	float Km;

	// для сигнализации
	testParamFaultNo = 0;

	// чтение EEPROM
	// ( -> param[])
	eprom.readFaultNo = read_eeprom();
	if ( eprom.readFaultNo != 0 ) {
		faultNo = 1;
		state = STATE_SHUTDOWN;
	}
	else {
		// проверяем массив param[]
		testParamFaultNo = test_param();
		if ( testParamFaultNo != 0 ) {
			faultNo = 4;
			state = STATE_SHUTDOWN;
		}
		else {
			faultNo = 0;
			state = STATE_STOP;
		}
	}


	rf.PsiZ = (float)param[180]*0.001;//%*10 -> o.e.

	// смещения нуля датчиков, ед. АЦП
	offset.Ia1  = param[200];
	offset.Ib1  = param[201];
	offset.Ic1  = param[202];
	offset.Udc1 = param[203];
	offset.Ia2 = param[206];
	offset.Ib2 = param[207];
	offset.Ic2 = param[208];
	offset.Udc2 = param[209];

	// параметры АД
	sgmPar.Rs = (float)param[303]*1e-6;//мкОм -> Ом
	sgmPar.Lls = (float)param[304]*1e-7;//мкГн*10 -> Гн
	sgmPar.Rr = (float)param[305]*1e-6;//мкОм -> Ом
	sgmPar.Llr = (float)param[306]*1e-7;//мкГн*10 -> Гн
	sgmPar.Lm = (float)param[307]*1e-6;//мкГн -> Гн
	// получаем из параметров АД всякие вспомогательные величины
	process_sgm_parameters();

	// коэффициенты регуляторов Id и Iq
	// ... постоянная времени контура тока, с
	Tci = TY*3.8;
	cc.KpOrig = 0.01*sgmPar.SigmaLs/Tci*I_BAZ*U_2_Y;
	cc.Kp = cc.KpOrig*(float)param[210];
	cc.KiOrig = 0.01*(sgmPar.Rs + sgmPar.Rr*sgmPar.Kl*sgmPar.Kl)/Tci*I_BAZ*U_2_Y*TY;
	cc.Ki = cc.KiOrig*(float)param[211];

	// коэффициенты регулятора Psi
	// ... постоянная времени контура потока, с
	Tcf = 50e-3;
	cf.KpOrig = 0.01*sgmPar.KlInv/(sgmPar.Rr*Tcf)*PSI_BAZ/I_BAZ;
	cf.Kp = cf.KpOrig*(float)param[212];
	cf.KiOrig = 0.01/(sgmPar.Lm*Tcf)*PSI_BAZ/I_BAZ*TY*DECIM_PSI_WM_PM;
	cf.Ki = cf.KiOrig*(float)param[213];

	// коэффициенты регулятора N
	// ... постоянная времени контура скорости, с
	Tcs = 200e-3;
	// ... коэффициент для пересчёта тока в момент
	Km = 1.5*PP*sgmPar.Kl*PSI_BAZ*rf.PsiZ;
	csp.KpOrig = 0.01*J/(Km*Tcs)*WM_BAZ/I_BAZ;
	csp.Kp = csp.KpOrig*(float)param[214];
	csp.KiOrig = 0.01*J/(Km*Tcs*Tcs*5.)*WM_BAZ/I_BAZ*TY*DECIM_PSI_WM_PM;
	csp.Ki = csp.KiOrig*(float)param[215];

	// всякие уставки
	protect.IacMax = (short)(2047.*(float)param[220]*0.01);//% -> ед. АЦП
	protect.IacMin = -protect.IacMax;
	protect.UdcMax = (float)param[221]*0.01;//% -> o.e.
	IzLim = (float)param[222]*0.01;//% -> o.e.
	cf.IdLim = (float)param[223]*0.01;//% -> o.e.
	cf.IdLimNeg = cf.IdLim*(-0.4);
	csp.IqLim = (float)param[224]*0.01;//% -> o.e.
	csp.IqLimNeg = -csp.IqLim;
	protect.UdcMin = (float)param[225]*0.01;//% -> o.e.
	protect.WmMax = (float)param[226]*0.01;//% -> o.e.
	rf.WmNomPsi = (float)param[228]*0.01;//% -> o.e.
	rf.YlimPsi = (float)param[229]*0.01*Y_LIM;//% -> ед. счётчика таймера
	protect.TudcMin = (unsigned short)((float)param[231]*0.001/TY);
	protect.TwmMax = (unsigned short)((float)param[233]*0.001/TY);

	// для разных ЗИ
	rs.WlimIncr = 1.0*TY*DECIM_PSI_WM_PM/((float)param[244]*0.001);
	csp.IlimIncr = 1.0*TY*DECIM_PSI_WM_PM/((float)param[245]*0.001);
	rp.PlimIncr = 1.0*TY*DECIM_PSI_WM_PM/((float)param[248]*0.001);
	rf.PsizIncr = 1.0*TY*DECIM_PSI_WM_PM/2.0;

	// для коррекции
	KmeCorr = (float)param[269]*0.0001;//%*100 -> o.e.

	// для разных фильтров
	Kudc = (TY*10000.)/(float)param[285];
	if ( Kudc > 1.0 )
		Kudc = 1.0;
	Kwm = (TY*10000.)/(float)param[286];
	if ( Kwm > 1.0 )
		Kwm = 1.0;
	rs.Kwmz = (TY*DECIM_PSI_WM_PM*1000.)/(float)param[288];
	rf.Kpsiz = (TY*DECIM_PSI_WM_PM*1000.)/(float)param[289];
	Kme = (TY*1000.)/(float)param[290];
	rp.Kpmz = (TY*DECIM_PSI_WM_PM*1000.)/(float)param[292];
	out.K = TY/100e-3;

	// выдержки
	protect.Tdi24VSource = (unsigned short)(5.0/TY);

	// всё в исходное положение
	udc1 = 0;
	udc2 = 0;
	wmNf = 0;
	wm = 0;
	me = 0;
	out.udc1 = 0;
	out.udc2 = 0;
	out.iac1 = 0;
	out.iac2 = 0;
	out.wm = 0;
	out.me = 0;
	out.pm = 0;
	protect.tWmMax = 0;
	protect.tDI24VSource = 0;
	onceShutdown = 0;
	onceFaultReset = 0;
	stopPause = 1;
	mst.pzMode = 0;
	mst.faultReset = 0;
	mst.start = 0;
	mst.wmZz = 0;
	mst.pmZz = 0;
	mst.wmLim = 0;
	mst.pmLim = 0;
	mst.pIncrMaxTy = 0;
	mst.pDecrMaxTy = 0;
} //void detcoeff(void)



// Вычисляет из параметров АД всякие вспомогательные величины
void process_sgm_parameters(void) {
	// полная индуктивность фазы статора, Гн
	sgmPar.Ls = sgmPar.Lm + sgmPar.Lls;
	// полная индуктивность фазы ротора, Гн
	sgmPar.Lr = sgmPar.Lm + sgmPar.Llr;
	// всяко-разно
	sgmPar.SigmaLs = (1. - sgmPar.Lm*sgmPar.Lm/(sgmPar.Ls*sgmPar.Lr))*sgmPar.Ls;
	sgmPar.LmInv = 1.0/sgmPar.Lm;
	sgmPar.LrInv = 1.0/sgmPar.Lr;
	sgmPar.Kl = sgmPar.Lm*sgmPar.LrInv;
	sgmPar.KlInv = 1.0/sgmPar.Kl;
	sgmPar.Tr = sgmPar.Lr/sgmPar.Rr;
	sgmPar.TrInv = sgmPar.Rr*sgmPar.LrInv;
} //void process_sgm_parameters(void)



// Читает PAR_NUMBER параметров из EEPROM и сохраняет в массиве param[]
// ( -> param[])
short read_eeprom(void) {
	return 0;
}



// Проверяет допустимость значений параметров, полученных из EEPROM
// (в param.c у параметров д.б. те же границы допустимых значений!)
short test_param(void) {
	if ( param[180] > 2000 )					return 180;//rf.PsiZ

	if ( (param[200]<1748) || (param[200]>2348) )	return 200;//offset.Ia1
	if ( (param[201]<1748) || (param[201]>2348) )	return 201;//offset.Ib1
	if ( (param[202]<1748) || (param[202]>2348) )	return 202;//offset.Ic1
	if ( (param[203]<1748) || (param[203]>2348) )	return 203;//offset.Udc1
	if ( (param[206]<1748) || (param[206]>2348) )	return 206;//offset.Ia2
	if ( (param[207]<1748) || (param[207]>2348) )	return 207;//offset.Ib2
	if ( (param[208]<1748) || (param[208]>2348) )	return 208;//offset.Ic2
	if ( (param[209]<1748) || (param[209]>2348) )	return 209;//offset.Udc2

	if ( param[210] > 5000 )					return 210;//cc.Kp
	if ( param[211] > 5000 )					return 211;//cc.Ki
	if ( param[212] > 5000 )					return 212;//cf.Kp
	if ( param[213] > 5000 )					return 213;//cf.Ki
	if ( param[214] > 5000 )					return 214;//csp.Kp
	if ( param[215] > 5000 )					return 215;//csp.Ki

	if ( param[220] > 99 )						return 220;//protect.IacMax
	if ( param[221] > 136 )						return 221;//protect.UdcMax
	if ( param[222] > 200 )						return 222;//IzLim
	if ( param[223] > 200 )						return 223;//cf.IdLim
	if ( param[224] > 200 )						return 224;//csp.IqLim
	if ( param[225] > 110 )						return 225;//protect.UdcMin
	if ( param[226] > 200 )						return 226;//protect.WmMax
	if ( param[228] > 200 )						return 228;//rf.WmNomPsi
	if ( param[229] > 101 )						return 229;//rf.YlimPsi
	if ( (param[231]<1) || (param[231]>8500) )	return 231;//protect.TudcMin
	if ( (param[233]<1) || (param[233]>8500) )	return 233;//protect.TwmMax

	if ( param[244] < 1 )						return 244;//rs.WlimIncr
	if ( param[245] < 1 )						return 245;//csp.IlimIncr
	if ( param[248] < 1 )						return 248;//rp.PlimIncr

	if ( (param[269]<5000) || (param[269]>20000) )	return 269;//KmeCorr

	if ( (param[285]<1) || (param[285]>20000) )	return 285;//Kudc
	if ( (param[286]<1) || (param[286]>20000) )	return 286;//Kwm
	if ( (param[288]<1) || (param[288]>20000) )	return 288;//rs.Kwmz
	if ( (param[289]<1) || (param[289]>20000) )	return 289;//rf.Kpsiz
	if ( (param[290]<1) || (param[290]>20000) )	return 290;//Kme
	if ( (param[292]<1) || (param[292]>20000) )	return 292;//rp.Kpmz

	return 0;
} //short test_param(void)
