#ifndef _MC_CONFIG_H__
#define _MC_CONFIG_H__

#include "os/os_types.h"
#include "autogen_config.h"

#define CONFIG_MAX_GEARS 4
#define CONFIG_TEMP_PROT_NUM 3
#define CONFIG_GEAR_SPEED_TRQ_NUM 10
#define CONFIG_EBRK_LVL_NUM 10

typedef enum {
	PID_ID_ID,
	PID_IQ_ID,
	PID_Vel_ID,
	PID_VelLim_ID,
	PID_IDCLim_ID,
	PID_AutoHold_ID,
	PID_Max_ID,
	PID_EPM_ExtID,
}PID_id_t;

typedef struct
{
	u8 poles;
	float ld;
	float lq;
	float rs;
	float flux;
	float nor_pll_band;
	float epm_pll_band;
	float pos_pll_band;
	int vehicle_w;
	int wheel_c;
	float gear_ratio;
	u16	max_fw_id;
	u16 max_torque;
	s16 encoder_offset;
}mot_params_t;

typedef struct {
	float kp;
	float ki;
	float kd;
}pid_t;

typedef struct {
	s16 max_dc_vol;
	s16 min_dc_vol;
	s16 max_phase_curr;
	s16 max_torque;
	s16 max_rpm;
	s16 max_epm_rpm;
	s16 max_epm_torque;
	s16 max_epm_back_rpm;
	s16 max_epm_back_torque;
	s16 max_ebrk_torque;
	s16 max_idc;
	s16 max_autohold_torque;
	s16 dq_loop_bandwith;
	float thro_start_vol;
	float thro_end_vol;
	float thro_min_vol;
	float thro_max_vol;
	u16   thro_dec_time;
	pid_t pid[PID_Max_ID];
	pid_t epm_pid;
	u8    _pad[64];
}controller_t;

typedef struct {
	bool auto_hold;
	bool brk_shut_power;
	bool tcs_enable;
}settings_t;

typedef struct {
	s16 max_speed; //最大速度, rpm
	s16 max_torque;   //最大扭矩
	s16 max_idc;   //最大母线电流
	u16 zero_accl; //零速启动扭矩给定时间，防止翘头
	u16 accl_time; //加速的扭矩斜坡时间
	u8  torque[CONFIG_GEAR_SPEED_TRQ_NUM]; //1000, 2000, 3000... RPM 最大给定扭矩的百分比（最大扭矩的百分比）
}gear_t;

typedef struct {
	s16 enter_pointer;
	s16 exit_pointer;
	s16 limit_value;
}limiter_t;

typedef struct {
	s16 torque;
	u16 time;
}eng_reco_l_t;

typedef struct {
	float low;
	float high;
	float min_step;
	float normal_step;
}cross_zero_t;

typedef struct {
	u8 version;
	mot_params_t m;
	controller_t c;
	settings_t s;
	gear_t g_n[CONFIG_MAX_GEARS];
	gear_t g_l[CONFIG_MAX_GEARS];
	limiter_t p_mot[CONFIG_TEMP_PROT_NUM];
	limiter_t p_mos[CONFIG_TEMP_PROT_NUM];
	limiter_t p_vol;
	eng_reco_l_t e_r[CONFIG_EBRK_LVL_NUM];
	cross_zero_t cz;
	u16 crc;
}mc_config;

extern mc_config conf;
bool mc_conf_begin_recv(int len);
bool mc_conf_recv_data(u8 *buff, int offset, int len);
bool mc_conf_finish_recv(u16 crc);
bool mc_conf_begin_send(void);
int mc_conf_send_data(u8 *buff, int offset, int len);
int mc_conf_finish_send(u8 *buff);
void mc_conf_load(void);
void mc_conf_decode_configs(void);
int mc_conf_encode_configs(u8 *buff);
void mc_conf_save(void);
void mc_conf_set_pid(u8 id, pid_t *pid);
void mc_conf_get_pid(u8 id, pid_t *pid);
bool mc_conf_set_gear(u8 mode, u8 *data, int len);
int mc_conf_get_gear(u8 mode, u8 *data);
bool mc_conf_set_limter(u8 *data, int len);
int mc_conf_get_limter(u8 *data);
void mc_conf_init(void);
int mc_conf_decode_pid(pid_t *pid, u8 *buff);
int mc_conf_encode_pid(pid_t *pid, u8 *buff);
static mc_config *mc_conf(void) {
	return &conf;
}
#endif /* _MC_CONFIG_H__ */

