#ifndef gimbalDef_h
#define gimbalDef_h

//	----------------------------------------------------------------------------
//  Byte align for Messaging
//	----------------------------------------------------------------------------

#if _MSC_VER 
__pragma( pack(push, 1) )
#else
#pragma pack(1)
#endif

//	----------------------------------------------------------------------------
//  GimbalDefs
//	----------------------------------------------------------------------------

const int HEADER = 0x1957;

#define NSAMP 256
#define NiAXES 2
#define NoAXES 2
#define NiAXES3 3
#define NLENS 3
#define NiFILT 5
#define kFreq 2000
#define IMU_BUF_BITS 11
#define IMU_BUF_COUNT 2048

//	------------------
//  message types
//	------------------

#define MSG_FIRST 0x10
enum{
	MSG_GYRO = MSG_FIRST,	// 0
	MSG_GYRO2,				// 1
	MSG_TUNINGS,			// 2
	MSG_PID_PAR,			// 3
	MSG_FILTER_PAR,			// 4
	MSG_CONTROLS,			// 5
	MSG_COMMAND,			// 6
	MSG_STATE,				// 7
	MSG_BW_PAR,				// 8
	MSG_BW_RES,				// 9
	MSG_OUTER_PAR,			// 10
	MSG_DB_CMD,				// 11
	MSG_UTIL,				// 12
	MSG_CONS_INPUT,			// 13
	MSG_LENS_CMD,			// 14
	MSG_LENS_FB,			// 15
	MSG_LAST
};

//	---------------------
//  msgHeader_t
//	---------------------

typedef struct {
	uint16_t header;
	uint16_t id;
	uint16_t cmd;
	uint16_t count;
	uint32_t len;
} msgHeader_t;

//	---------------------
//  msgTail_t
//	---------------------

typedef struct {
	int16_t checksum;
} msgTail_t;

//  ------------------
//  filter types
//  ------------------

#define FILT_STRINGS " None"," LagLead"," Notch"," Lowpass"
#define FILT_STRINGSx "None", "LagLead", "Notch", "Lowpass"

enum {
	FILTER_NONE,
	FILTER_LAGLEAD,
	FILTER_NOTCH,
	FILTER_LOWPASS,
	NUM_FILTER_TYPES
};

//  ------------------
//  backdrive types
//  ------------------

#define BD_STRINGS "Off","Step","Sine"

enum {
	BD_NONE = 0,
	BD_STEP,
	BD_SINE,
	NUM_BD_TYPES
};

//  ------------------
//  plot types
//  ------------------

#define PLOT_STRINGS " Gyro"," Command"," Joystick"," Angle"," Sine"," Drive"," Pwm"," Tach"," PwmOuter"
#define PLOT_STRINGSx "Gyro", "Command", "Joystick", "Angle", "Sine", "Drive", "Pwm", "Tach", "PwmOuter"

enum {
	PLOT_Gyro = 0,
	PLOT_Command,
	PLOT_Joystick,
	PLOT_Angle,
	PLOT_Sine, 
	PLOT_Drive, 
	PLOT_Pwm, 
	PLOT_Tach,
	PLOT_PwmOuter,
	NUM_PLOT_TYPES
};

//	---------------------
//  axisControls_t
//	---------------------

typedef struct {
	int32_t enable;
	int32_t remote;
	int32_t backdrive;
	int32_t jsNull;
	int32_t gyroNull;
	float desiredRate;
	float sinAmp;
	float sinFreq;
} axisControls_t;

//	---------------------
//  controls_t
//	---------------------

typedef struct {
	int32_t connect;
	int32_t standby;
	int32_t autonull;
	int32_t plotType;
	int32_t plotAxis;
	int32_t plotRaw;
	axisControls_t axis[NiAXES];
} controls_t;

//	---------------------
//  MSG_CONTROLS
//	---------------------

typedef struct {
	msgHeader_t	head;
	controls_t controls;
	msgTail_t tail;
} msgControls_t;

//	---------------------
//  analog_t
//	---------------------

typedef struct {
	float raw;
	float ofs;
	float val;
} analog_t;

//	---------------------
//  encoder_t
//	---------------------

typedef struct {
	int32_t count;
	int32_t indexed;
	float ofs;
	float val;
} encoder_t;

//	---------------------
//  axisState_t
//	---------------------

typedef struct {
	analog_t js;
	analog_t gyro;
	analog_t trim;
	analog_t angle;
	analog_t tach;
	encoder_t enc;
	float jsfilt;
	float rateCommand;
	float r;
	float rE;
	float err;
	float erI;
	float drive;
	float current;
	float jitter;
	int32_t pwm;
	int32_t pwmOuter;
} axisState_t;

//	---------------------
//  gyroState_t
//	---------------------

typedef struct {
	int32_t frame;
	int32_t isrReg;
	int32_t isrReg2;
	int32_t bytes;
	int32_t noData;
	int32_t idReq;
	int32_t velReq;
	int32_t restartCount;
} gyroState_t;

//	---------------------
//  state_t
//	---------------------

typedef struct {
	gyroState_t gyro;
	axisState_t axis[NiAXES];
} state_t;

//	---------------------
//  msgDbcmd_t
//	---------------------

typedef struct {
	msgHeader_t	head;
	char data[4];
} msgDbcmd_t;

//	---------------------
//  MSG_STATE
//	---------------------

typedef struct {
	msgHeader_t	head;
	state_t state;
	msgTail_t tail;
} msgState_t;

//	---------------------
//  MSG_COMMAND
//	---------------------

enum{
	CMD_CONNECT = 10,
};

//	---------------------
//  command_t
//	---------------------

typedef struct {
	int32_t command;
	int32_t par1;
	int32_t par2;
	float fpar1;
	float fpar2;
} command_t;

//	---------------------
//  MSG_COMMAND
//	---------------------

typedef struct {
	msgHeader_t	head;
	command_t command;
	msgTail_t tail;
} msgCommand_t;

//	---------------------
//  MSG_GYRO
//	---------------------

typedef struct {
	msgHeader_t	head;
	float minval;
	float maxval;
	uint16_t samples[NSAMP];
	msgTail_t tail;
} msgGyroBuf_t;

//	---------------------
//  MSG_TUNINGS
//	--------------------

typedef struct
{
	float kP;
	float kI;
	float kD;
	float kILim;
	float kSpeed;
	float kT;
	float kC;
} pidPar_t;

typedef struct
{
	float kP;
	float kFF;
	float kTach;
} outerPar_t;

typedef struct
{
	int32_t ftype;
	float f1;
	float q;
} filterPar_t;

typedef struct
{
	msgHeader_t	head;
	pidPar_t pidP[NiAXES];
	filterPar_t filtP[NiAXES][NiFILT];
	outerPar_t outerP[NoAXES];
	msgTail_t tail;
} msgTunings_t;

//	---------------------
//  MSG_FILTER_PAR
//	---------------------

typedef struct {
	msgHeader_t	head;
	int32_t axis;
	int32_t ifilt;
	filterPar_t filtPar;
	msgTail_t tail;
} msgFilterPar_t;

//	---------------------
//  MSG_PID_PAR
//	---------------------

typedef struct {
	msgHeader_t	head;
	int32_t axis;
	pidPar_t pidPar;
	msgTail_t tail;
} msgPidPar_t;

//	---------------------
//  MSG_OUTER_PAR
//	---------------------

typedef struct {
	msgHeader_t	head;
	int32_t axis;
	outerPar_t outerPar;
	msgTail_t tail;
} msgOuterPar_t;

//	---------------------
//  msgSlavePwm_t
//	---------------------

typedef struct {
	uint8_t header;
	uint8_t bits;
	uint8_t yaw;
	uint8_t pit;
	uint8_t rol;
	uint8_t dom;
	uint8_t vsw;
	uint8_t sum;
} msgPwm_t;

//	---------------------
//  bwPar_t
//	---------------------

typedef struct {
	uint32_t start;
	uint32_t axis;
	uint32_t openloop;
	uint32_t opendrive;
	uint32_t shake;
	uint32_t numfreqs;
	float amplitude;
	float minfreq;
	float maxfreq;
} bwPar_t;

//	---------------------
//  bwRes_t
//	---------------------

#define NUMBW 60

typedef struct {
	uint32_t index;
	int32_t bwState;
	float drive;
	float output;
	float time;
	float cycles;
	float freq[NUMBW];
	float gain[NUMBW];
	float phase[NUMBW];
} bwRes_t;

//	---------------------
//  MSG_BW_PAR
//	---------------------

typedef struct {
	msgHeader_t	head;
	bwPar_t bwPar;
	msgTail_t tail;
} msgBwPar_t;

//	---------------------
//  MSG_BW_RES
//	---------------------

typedef struct {
	msgHeader_t	head;
	bwRes_t bwRes;
	msgTail_t tail;
} msgBwRes_t;

//	---------------------
//  consInput
//	---------------------

typedef struct {
	int32_t buttons;
	int32_t enc1;
	int32_t enc2;
	int32_t enc3;
	float zoom;
	float focus;
	float iris;
	float jsx;
	float jsy;
	float jsz;
} consInput_t;

//	---------------------
//  MSG_CONS_INPUT
//	---------------------

typedef struct {
	msgHeader_t	head;
	consInput_t consInput;
	msgTail_t tail;
} msgConsInput_t;

//	---------------------
//  lensCommand
//	---------------------

typedef struct {
	float command;
} lensCommand_t;

//	---------------------
//  MSG_LENS_CMD
//	---------------------

typedef struct {
	msgHeader_t	head;
	lensCommand_t lensCommand[NLENS];
	msgTail_t tail;
} msgLensCommand_t;

//	---------------------
//  lensFeedback
//	---------------------

typedef struct {
	float pos;
	float err;
	float drive;
	int32_t pwm;
} lensFeedback_t;

//	---------------------
//  MSG_LENS_FB
//	---------------------

typedef struct {
	msgHeader_t	head;
	lensFeedback_t lensFeedback[NLENS];
	msgTail_t tail;
} msgLensFeedback_t;

//	---------------------
//  lensPar_t
//	---------------------

typedef struct {
	int32_t enable;
	float kP;
	float kI;
	float kPwm;
	float kPwmLim;
	float kPmin;
	float kPmax;
	float kSpan0;
	float kSpan1;
	int32_t pwmPin;
	int32_t dirPin;
} lensPar_t;

//	---------------------
//  lensState_t
//	---------------------

typedef struct {
	float command;
	int32_t ecount;
	int32_t aip;
	float span0;
	float span1;
	float kpos;
	float pos;
	float err;
	float drive;
	int32_t pwm;
} lensState_t;

//	---------------------
//  MESSAGE_LENGTH_CASES
//	---------------------

#define MESSAGE_LENGTH_CASES \
	case MSG_GYRO:			 return sizeof(msgGyroBuf_t);		\
	case MSG_GYRO2:			 return sizeof(msgGyroBuf_t);		\
	case MSG_TUNINGS:		 return sizeof(msgTunings_t);		\
	case MSG_PID_PAR:		 return sizeof(msgPidPar_t);		\
	case MSG_FILTER_PAR:	 return sizeof(msgFilterPar_t);		\
	case MSG_CONTROLS:		 return sizeof(msgControls_t);		\
	case MSG_COMMAND:		 return sizeof(command_t);			\
	case MSG_STATE:			 return sizeof(msgState_t);			\
	case MSG_BW_PAR:		 return sizeof(msgBwPar_t);			\
	case MSG_BW_RES:		 return sizeof(msgBwRes_t);			\
	case MSG_OUTER_PAR:		 return sizeof(msgOuterPar_t);		\
	case MSG_DB_CMD:		 return 0;							\
	case MSG_UTIL:			 return 0;							\
	case MSG_CONS_INPUT:	 return sizeof(msgConsInput_t);		\
	case MSG_LENS_CMD:		 return sizeof(msgLensCommand_t);	\
	case MSG_LENS_FB:		 return sizeof(msgLensFeedback_t);

//	---------------------
//  t1Data_t
//	---------------------

	typedef struct {
		uint8_t portb;
		uint8_t admux;
		uint8_t adcsra;
		uint8_t adcl;
		uint8_t adch;
		uint8_t nextmux;
	} t1Data_t;

//	----------------------------------------------------------------------------
//  Normal align
//	----------------------------------------------------------------------------

#pragma pack(1)
#if _MSC_VER
__pragma( pack(pop) )
#else
#pragma pack()
#endif

#endif
