/*
 * dbw.h
 *
 *  Created on: May 5, 2021
 *      Author: Dmitrijs
 */




#ifndef SRC_DBW_H_
#define SRC_DBW_H_


#define CONFIG_AGREEMENT_F				0x01
#define CONFIG_SENSORS_CALIBRATED_F		0x02
#define CONFIG_TESTMODE_F				0x04
#define CONFIG_SAFETY_FEATURES_F		0x08




#define DBW_STATUS0_READY_F				0x1
#define DBW_STATUS0_AGREEMENT_F			0x2
#define DBW_STATUS0_SENSOR_CAL_F		0x4
#define DBW_STATUS0_FAULT_F				0x8
#define DBW_STATUS0_CAN_MSDBW_F			0x10
#define DBW_STATUS0_CAN_RX_BCST_F		0x20
#define DBW_STATUS0_PWM_IDLE_F			0x40
#define DBW_STATUS0_GPI1_F				0x80
#define DBW_STATUS0_GPI2_F				0x100
#define DBW_STATUS0_GPO1_F				0x200
#define DBW_STATUS0_GPO2_F				0x400
#define DBW_STATUS0_PPSTPS_CAL_F		0x800
#define DBW_STATUS0_UNPROTECTED_F		0x1000
#define DBW_STATUS0_CONF_ERROR_F		0x2000
#define DBW_STATUS0_SENSOR_FAULT_F		0x4000

#define DBW_STATUS1_SAFETY_F			0x01


#define PPS2_CALC_OPTION_LINEAR			0
#define PPS2_CALC_OPTION_POLYNOMAL		1
#define TPS2_CALC_OPTION_LINEAR			0
#define TPS2_CALC_OPTION_POLYNOMAL		1

#define PPS2TPS_OPTION_CURVE			0
#define PPS2TPS_OPTION_MS3_CAN			1

#define IDLE_OPTION_NO_IDLE_INPUT		0
#define IDLE_OPTION_PWM_INPUT1			1
#define IDLE_OPTION_PWM_INPUT2			2
#define IDLE_OPTION_MS_CAN				3


#define MOTOR_PID_OPTION_STATIC			0
#define MOTOR_PID_OPTION_STATIC_FWRW	1
#define MOTOR_PID_OPTION_TABLE			2


typedef struct
{
uint8_t	 pps_calc_option;
uint8_t	 tps_calc_option;

uint16_t pps1_min;
uint16_t pps1_max;

uint16_t pps2_min;
uint16_t pps2_mid;
uint16_t pps2_mid_pct;
uint16_t pps2_max;

uint16_t tps1_min;
uint16_t tps1_max;

uint16_t tps2_min;
uint16_t tps2_mid;
uint16_t tps2_mid_pct;
uint16_t tps2_max;

uint8_t  pps2tps_option;
uint8_t  idle_input_option;

// pps to tps target curve
int16_t pps_bins[16];			//[0.1%]
int16_t tps_bins[16];			//[0.1%]

// Idle pps modifier curve. when Idle input is used. it modifies tps target
int16_t idle_input_bins[8];		//input pwm duty [0.1%]
int16_t idle_tps_adder_bins[8];	//tps target adder [0.1%]


uint16_t motor_pwm_fq;			// frequency in Hz
uint16_t motor_ctl_period;		// ctl_teriod in [100uS]
uint16_t motor_pid_option;		// PID static coefs, static coef, but different for forward and backward moving
								// 3D table

// PID COEFICIENTS for forward and reward
int16_t motor_fw_p;
int16_t motor_fw_i;
int16_t motor_fw_d;
int16_t motor_rw_p;
int16_t motor_rw_i;
int16_t motor_rw_d;

int16_t motor_p_tps_bins[16];
int16_t motor_p_error_bins[16];
int16_t motor_p_table[16][16];

//PID limmits
int16_t i_limmit;
int16_t motor_dc_max;
int16_t motor_dc_min;



//DC offset curve
int16_t tps_dc_tps_bins[16];			// tps bins [0.1%]
int16_t tps_dc_offset_bins[16]; // motor pwm offset [0.01%PWM]

//Battery voltage correction curve
uint16_t vbat_bins[8];			// battery voltage ADC bins []
int16_t motor_pwm_corr_bins[8]; // motor pwm correction [0.1%]

uint16_t pwm_deadtime;
uint16_t can_dbw_id;
uint16_t can_idle_base_id;
uint16_t config_bits;

uint16_t pps1_margin;
uint16_t pps2_margin;
int16_t pps_delta_margin;



uint16_t tps1_margin;
uint16_t tps2_margin;
uint16_t tps_delta_margin;

int16_t tps_error_margin1;
uint16_t tps_error_time1;

int16_t tps_error_margin2;
uint16_t tps_error_time2;


uint16_t can_dbw_poll_perod;

//enable tuning over CAN;
uint8_t can_ms29bit_id;
uint8_t can_ms29bit_options;


//broadcast my data
uint8_t can_bcst_data_enable;
uint8_t can_bcst_data_period;
uint16_t can_bcst_canid;




}config_t;

typedef struct
{
uint32_t clock;
uint16_t status0;
uint16_t status1;
uint16_t status2;
uint16_t status3;

uint16_t pps1_adc;
uint16_t pps2_adc;
uint16_t tps1_adc;
uint16_t tps2_adc;
uint16_t motor_current_adc;
uint16_t vbat_adc;

int16_t	pps1;
int16_t	pps2;
int16_t tps1;
int16_t tps2;
int16_t pps;
int16_t tps;
int16_t tps_error;
int16_t motor_pwm;
uint16_t idle_dc;
int16_t pps_delta;
int16_t tps_delta;
int16_t tps_target;
uint16_t vss;
uint16_t rpm;
}var_t;




#define PWM_STATUS_DEFAULT	0
#define PWM_STATUS_IDLE		1
#define PWM_STATUS_STARTED	2
#define PWM_STATUS_ERROR	3

#define PWM_STATE_POSITIVE_INACTIVE	0
#define PWM_STATE_POSITIVE_ACTIVE	1
#define PWM_STATE_NEGATIVE_INACTIVE	2
#define PWM_STATE_NEGATIVE_ACTIVE	3



typedef struct
{
 unsigned char status;
 unsigned char state;
 GPIO_TypeDef *pos_port;
 unsigned short pos_pin;
 GPIO_TypeDef *neg_port;
 unsigned short neg_pin;
 unsigned int period_ticks;
 unsigned int duty_ticks;
 signed int pwm;
 signed int pwm_t;
 signed int single_pulse;
}pwm_t;


extern volatile float pps1_gain, pps1_offset, pps2_gain, pps2_offset, tps1_gain, tps2_offset;
extern volatile uint16_t dbw_fast_process_timer, dbw_slow_process_timer;
void Apply_Sensor_Calibration(void);
int DBW_Process(void);
void DBW_Pwm_Init(void);
void DBW_Pwm_Set_Duty(signed int duty, pwm_t* ttl);
void TIM2_IRQHandler (void);
int intrp_1dstable(signed short x, unsigned char n, signed short * x_table, char sgn,signed short * z_table);
signed short intrp_1d_ss_table(signed short x, unsigned char n, signed short * x_table, char sgn, signed short * z_table);
unsigned int intrp_1d_uitable(unsigned int x, unsigned char nx, unsigned int * x_table, unsigned int * z_table);
void DBW_Init(void);
void DBW_Start(void);
void DBW_Stop(void);
void DBW_TPS_AutoCal(void);
void DBW_Read_sensors(void);


extern volatile pwm_t ttl1_pwm;
extern volatile unsigned short ctl_period;

extern volatile config_t config_ram;
extern volatile var_t var;
extern volatile config_t *config;
extern const config_t config_flash;
extern volatile int32_t vbat_corr, tps_slow_t, p_comp, i_comp, d_comp, tps_error_t, can_target, spring_preload, idle_adder;
extern volatile uint32_t ac_timer, ac_mode;







#endif /* SRC_DBW_H_ */
