#include "User_data_types.h"

//General control variables
float Go;
int	Go_flag;
int State;
int cnt=0, counter=0, counter2=0, cnt3=0;
int Ctrl_type, i, j, kk;

//Acquisition channels and feedback
Xabc isabc;
Xalphabeta isab;
Xin input,offset_in;
float vdc;
float offset_current_a, offset_current_b, offset_current_c;

// Inverter's parameters of Transistors and Diodes 
XCompPar TR_par, D_par;
Xabc v_error_voltage_drop, v_error_deadtime, v_error;
float enable_voltage_drop, enable_deadtime;

//speed feedback
float theta_r, theta_r_filt, theta_encoder, enc_offset, threshold, accelerazione;
Xsc SinCos_r, SinCos_r_old, SinCos_r_elt, SinCos_r_elt_old;

//Protection variables
int pwm_stop;

//Reference and open-loop variables
Xabc vsabc_ref, vsabc, duty_abc, duty_km1;
Xalphabeta vsab_ref, vsab;
Xdq vsdq_ref, vsdq_ref_ffw, vsdq, isdq_ref , isdq;
float v0, k, flux_nom, volt_nom;
XPIRegPars  id_par, iq_par, sp_par;
XPIRegVars  id_var, iq_var, sp_var;

// motor parameters
float Rs, SigmaLs, inv_Kr, Lm, TauR, inv_TauR;

// Bandwidth
float fbi , wbi , fbw , wbw , fbtheta , wbtheta;

// FOC :
Xalphabeta_amp lambdaS, lambdaR_old, lambdaR;
Xdq lambdaR_rotor;
Xsc SinCos_FOC;

// Indirect FOC
float theta_slip, theta_est, theta_IndirectFOC;
Xsc SinCos_IndirectFOC;

// flux observer
float g;
Xalphabeta_amp lambdaS_VIpole, lambdaR_VIpole; 
Xsc SinCos_VIpole, SinCos_VIpole_old;
float omega_slip, omega_elet_est, omega_mec_est, omega_mec_est_filt;

// I-omega
Xalphabeta_amp lambdaR_Iw_old, lambdaR_Iw;
//Xalphabeta dlambdaR_Iw;
Xsc SinCos_Iw;

// I-theta
Xdq isab_rotor, lambdaR_Itheta_rotor; // sarebbero su assi fissi di statore ma per poter utilizzare _rot e _invrot serve definirli come dq
Xalphabeta_amp lambdaR_Itheta;
Xsc SinCos_Itheta;

// VI-theta
Xalphabeta_amp lambdaS_VIpole_theta , lambdaR_VI_theta;
Xsc SinCos_VI_theta;

// VI-omega
Xalphabeta_amp lambdaS_VIpole_w, lambdaR_VI_w;
Xsc SinCos_VI_w;

// Sensorless
Xalphabeta isab_est, esab_est;
Xalphabeta_amp lambdaS_Sensorless, lambdaR_Sensorless;
Xsc SinCos_Sensorless;
float omega_slip_est, omega_elt_est, omega_r_est, omega_r_est_filt ;
float K_filtro_Sensorless , cut_off_freq_Sensorless;

//Mechanical variables
float omega_ref_in, omega_ref_ramp, n_ref_ramp, accel, theta_ref;
Xsc SinCos_ref, SinCos_FOC, SinCos_dq;

float tmp, tmp1, tmp2, tmp3;
float n_ref_in, omega_r_filt, omega_r, n_encoder, n_encoder_filt ;
float theta_r_teorica;
float T_ref, Tlim;
float sin_old, cos_old; 

// Speed Filter 
float cut_off_freq;
float K_filtro, K_filter;

//PLL
float omega_PLL, fb_PLL, wb_PLL, damping;
Xsc theta_PLL;
XPIRegVars PLL_var;
XPIRegPars PLL_par;

//HF position detect 
float theta_hf, theta0_HF;


float position_kp;
float theta_ref_commissioning, enc_theta_r_teorica, omega_ref_ramp_commissioning, slip; 
Xsc	SinCos_ref_commissioning, SinCos_ref_commissioning_old;


// Prova compensazione theta_r
float coseno, seno, coseno_old, seno_old;
float delta, freq, electrical_turns, turns;
float revolution_samples, samples_min , samples_max;
int sample_index;
int valid_data_count; 
#define LUT_SAMPLES 1200                           // dipende a che velocità si vuole creare la LUT durante il commisisoning, a 10 Hz occorrono circa 1015 punti. Se vuoi girarlo a mano metti almeno 4000 punti 
float theta_encoder_valid[LUT_SAMPLES];   				 // NB: l'inizializzazione di questi vettori richiede tanta memoria dunque occorre limitare il più possibile il numero di punti di questi array o potrebbe andare in errore il sistema perchè richeidi troppa memoria 
float theta_r_ideal[LUT_SAMPLES];
float THETA_R_LUT[LUT_SAMPLES];
int decimation_factor, read_counter, not_enough_LUT_SAMPLES;
float xi,x0,y0,x1,y1;
int idx = -1;
float THETA_MIN_v2, THETA_MAX_v2, DTHETA_v2, INV_DTHETA_v2, theta_r_v2;
#define TRUE          1
#define FALSE         0
int recording = FALSE;
int LUT_GENERATION = FALSE;
int LUT_COMPLETE = FALSE;
int LUT_ERROR = FALSE;
int TURNS_DONE = FALSE;
int RECORDING_COMPLETE = FALSE;
int computational_time;
float THETA_MIN, THETA_MAX, DTHETA, INV_DTHETA;
float theta_encoder_old, delta_theta, margin;
int sawtooth_increasing;
int first_reset_found = FALSE, second_reset_found = FALSE, third_reset_found = FALSE;

// per impostare velocità sinusoidale o trapezia
float amplitude, desired_offset, wave_offset, wave_freq, wt;
int holdCounter, holdCounter2, rampUpComplete, rampDownComplete, HOLD_TIME;
float temp;
int LUT_VECTOR_POSITIVE = FALSE;

float position_error, omega_posloop, theta_desired, fbp, wbp, position_ki, proporzionale, integrativo, theta_voluta;
Xsc SinCos_desired;

float K_filter_Sensorless;
int speed_request;

#ifdef SIM
float Reset,  BlueBTN;
#endif
