/*****************************************************************************
 *   type.h:  Type definition Header file for NXP LPC2000/3000 Family 
 *   Microprocessors
 *
 *   Copyright(C) 2007, NXP Semiconductor
 *   All rights reserved.
 *
 *   History
 *   2007.09.01  ver 1.00    Preliminary version, first Release
 *
 ****************************************************************************
 * Software that is described herein is for illustrative purposes only
 * which provides customers with programming information regarding the
 * products. This software is supplied "AS IS" without any warranties.
 * NXP Semiconductors assumes no responsibility or liability for the
 * use of the software, conveys no license or title under any patent,
 * copyright, or mask work right to the product. NXP Semiconductors
 * reserves the right to make changes in the software without
 * notification. NXP Semiconductors also make no representation or
 * warranty that such application will be suitable for the specified
 * use without further testing or modification.
 *****************************************************************************/
 
#ifndef __TYPE_H__
#define __TYPE_H__

#ifndef NULL
#define NULL    ((void *)0)
#endif

#ifndef FALSE
#define FALSE   (0)
#endif

#ifndef TRUE
#define TRUE    (1)
#endif

#define ABS(value)	(value<0 ? -value : value)

typedef unsigned char  BYTE;
typedef unsigned short WORD;
typedef unsigned long  DWORD;
typedef unsigned int   BOOL;

// FULLSIZEINT = BYTE, WORD or DWORD	
// X [bits] = max value : 2^X >= MAX => 2^(X-1). A+=1 if variable is signed.
// Y [bits] = granularity : 1/(2^Y) >= GRAN => 1/(2^(Y-1))

//typedef union FIXEDX_Ytag 
//{
//	FULLSIZEINT full;
//	struct partX_Ytag 
//	{
// 		FULLSIZEINT integer: (X);
//		FULLSIZEINT fraction: (FULLSIZEINT-X);
//	} part;
//} FIXEDX_Y; 
//
// #define MULTX_Y(A,B) (FULLSIZEINT+1)(A.full*B.full+2^(Y-1))>>Y
// #define DIVX_Y(A,B) (FULLSIZEINT+1)((A.full<<(Y+1))/B.full)+1)/2 
// #define FIXED1_YCONST(int, fract) (FULLSIZEINT)((int<<Y) + ((fract + 1/(2^(Y+1)))*2^Y))
// #define FIXEDX_Y_TOFLOAT(F)	(float) F.part.fraction / 2^Y + (float) F.part.integer   

// FIXED POINT 6 bits integer 10 bits fraction
// Range -32 / 32 
// Granularity 0.000976563
typedef union F6_10tag 
{
	signed short full;
	struct partF6_10tag 
	{
		unsigned short fraction: 10;	// Y = 10
		signed short integer: 6;		// X = 6
	}part;
}F6_10;
#define MULT_F6_10(A,B) 		(((signed long)A.full*B.full+512)>>10)
#define MULT_F6_10s(A,B) 		(((signed long)A.full*B+512)>>10)
#define DIV_F6_10(A,B) 			(((((signed long)A.full<<11)/B.full)+1)/2)
#define DIV_F6_10s(A,B)			(((((signed long)A.full<<11)/B)+1)/2)
#define F6_10_CONST(f)	(f<0 ?  (((signed short)(f)<<10) - (((signed short)((f-0.00048828125)*1024))&0x3FF)) : (((signed short)(f)<<10) + (((signed short)((f+0.00048828125)*1024))&0x3FF)))
#define F6_10_TOFLOAT(F)		((float) F.part.fraction / 1024 + (float) F.part.integer) 

// FIXED POINT 22 bits integer 10 bits fraction
// Range -2097152 / 2097152 
// Granularity 0.000976563
typedef union F22_10tag 
{
	signed long full;
	struct partF22_10tag 
	{
		unsigned long fraction: 10;	// Y = 10
		signed long integer: 22;		// X = 22
	}part;
}F22_10;
#define MULT_F22_10(A,B) 			(((signed long long)A.full*B.full+512)>>10)
#define MULT_F22_10s(A,B) 			(((signed long long)A.full*B+512)>>10)
#define DIV_F22_10(A,B) 			(((((signed long long)A.full<<11)/B.full)+1)/2)
#define F22_10_CONST(f) 			(f<0 ? (((signed long)(f)<<10) - (((signed long)((f-0.00048828125)*1024))&0x3FF)) : (((signed long)(f)<<10) + (((signed long)((f+0.00048828125)*1024))&0x3FF)))
//#define F6_10_TOFLOAT(F)			((float) F.part.fraction / 1024 + (float) F.part.integer) 

// FIXED POINT 16 bits integer 16 bits fraction
// Range -32768 - 32767
// Granularity 0.0000152588
typedef union F16_16tag 
{
	signed long full;
	struct partF16_16tag 
	{
		unsigned long fraction: 16;	// Y = 16
		signed long integer: 	16;	// X = 16
	}part;
}F16_16;
#define MULT_F16_16(A,B) 			(((signed long long)A.full*B.full+32768)>>16)
#define MULT_F16_16s(A,B) 			(((signed long long)A.full*B+32768)>>16)
#define DIV_F16_16(A,B) 			(((((signed long long)A.full<<17)/B.full)+1)/2)
#define DIV_F16_16s(A,B) 			(((((signed long long)A.full<<17)/B)+1)/2)
#define F16_16_CONST(f) 			(f<0 ? (((signed long)(f)<<16) - (((signed long)((f-0.0000076294)*65536))&0xFFFF)) : (((signed long)(f)<<16) + (((signed long)((f+0.0000076294)*65536))&0xFFFF)))

typedef union _BITS
{
	unsigned char value;
	struct _bits
	{
		unsigned char bit0:1;
		unsigned char bit1:1;
		unsigned char bit2:1;
		unsigned char bit3:1;
		unsigned char bit4:1;
		unsigned char bit5:1;
		unsigned char bit6:1;
		unsigned char bit7:1;
	}bits;
}BITS;
							
typedef struct _PARAM_STRUCT {
	WORD saved;			// Indicates wheter values have been saved in EEPROM
	WORD currentOffset;	// Offset for current measurement
	
	F6_10 Q_SP;			// SetPoint Q
	F6_10 D_SP;			// SetPoint D
	
	F6_10 Q_Kp;			// VQ Kp
	F6_10 Q_Ki;			// VQ Ki
	
	F6_10 D_Kp;			// VD PI const Kp
	F6_10 D_Ki;			// VD PI const Ki	 	
	
	F6_10 speed_Kp;		// Speed Kp
	F6_10 speed_Ki;		// Speed Ki
	
	F6_10 speed_Kd;		// Speed Kd
	F6_10 speed_SP;		// Speed setpoint
	   	
	F16_16 G;    			// Virtual motor algorithm constant
	F16_16 F;    			// Virtual motor algorithm constant
	F16_16 K_smc;     		// Sliding control gain 
	F16_16 smc_max_err; 	// Maximum current error for linear SMC 
	F16_16 Cflt_omega;  	// Filter coefficient for Omega  

	DWORD empty[64-11];		//EEPROM_PAGE_SIZE - 11
}PARAM_STRUCT;

typedef volatile struct _FOC_STRUCT {
	volatile DWORD sync;			// Synchronisation bytes for UART
	
	volatile WORD size;				// size of this structure
	volatile BITS status;		
	volatile BYTE mode;
	
	volatile DWORD deviceID[2];		// double DWORD DeviceID
	
	volatile WORD alpha;			// Measured / calculated stator angle
	volatile WORD adcVal[2];		// ADC values measured
	volatile WORD currentOffset;	// Offset for current measurement
	
	volatile WORD adcPoint[2];		// ADC start offset from t=0
	
	volatile BYTE adcSeq[3];		// ADC sequence
	volatile BYTE temp;				// temperature 
	
	volatile BYTE busy;				// FOC busy
	volatile BYTE sector;			// Current SVPWM sector
	volatile WORD pwm[3];			// PWM values from space vector
	
	volatile WORD mACT[6];			// Match activate registers for PWM 
	
	volatile WORD mDACT[6];			// Match de-activate registers for PWM  
	
	volatile F6_10 I[3];			// Reconstructed Ia, Ib & Ic	
   	volatile F6_10 Ialpha;			// Calculated Ia in dynamic reference frame
   	
	volatile F6_10 Ibeta;			// Calculated Ib in dynamic reference frame
   	volatile F6_10 Id;				// Calculated Id in static reference frame
   	
	volatile F6_10 Iq;				// Calculated Iq in static reference frame
   	volatile F6_10 Vd;				// Regulated PI output d in static reference frame
   	
	volatile F6_10 Vq;				// Regulated PI output q in static reference frame
   	volatile F6_10 Valpha;			// Regulated PI output alpha in dynamic reference frame
   	
	volatile F6_10 Vbeta;			// Regulated PI output beta in dynamic reference frame
	volatile F6_10 Vr1;				// Vref1 from inverse park
	
	volatile F6_10 Vr2;				// Vref2 from inverse park
	volatile F6_10 Vr3;				// Vref3 from inverse park
	
	volatile F22_10 Q_err;			// Q error
	volatile F22_10 Q_int;			// Q integrated error
	volatile F22_10 D_err;			// D error
	volatile F22_10 D_int;			// D integrated error
	
	volatile F6_10 Q_SP;			// SetPoint Q
	volatile F6_10 D_SP;			// SetPoint D

	volatile F6_10 Q_Kp;			// VQ Kp
	volatile F6_10 Q_Ki;			// VQ Ki
	
	volatile F6_10 D_Kp;			// VD PI const Kp
	volatile F6_10 D_Ki;			// VD PI const Ki	 	
		
	volatile F22_10 speed_err;		// Speed error
	volatile F22_10 speed_int;		// Speed integrated error 
	volatile F22_10 speed_der; 		// Speed derrivated error
	volatile F22_10 speed_prev_err;	// Speed previous error value
	
	volatile F6_10 empty;			// 
	volatile F6_10 speed;			// Speed : Fixed point 32  == 32768 RPM

	volatile F6_10 speed_Kp;		// Speed Kp
	volatile F6_10 speed_Ki;		// Speed Ki
	volatile F6_10 speed_Kd;		// Speed Kd
	volatile F6_10 speed_SP;		// Speed setpoint
	volatile F6_10 alphaCalc;
	volatile F6_10 alphaEst;

	volatile F16_16  F16_16_Valpha;   	// Voltage on alpha axis
	volatile F16_16  F16_16_Vbeta;   	// Input: Stationary beta-axis stator voltage 

	volatile F16_16  F16_16_Ialpha; 	// Current on alpha axis 
	volatile F16_16  F16_16_Ibeta;  	// Current on beta axis  

	volatile F16_16  bemf_alpha;   		// BEMF voltage on alpha axis 
	volatile F16_16  bemf_alpha_flt;	// Filtered BEMF voltage on alpha axis

	volatile F16_16  bemf_beta;  		// BEMF voltage on beta axis 
	volatile F16_16  bemf_beta_flt;		// Filtered BEMF voltage on beta axis 

	volatile F16_16  z_alpha;      		// SMC correction factor z on alpha axis 
	volatile F16_16  z_beta;      		// SMC correction factor z on beta axis
		
	volatile F16_16  Ialpha_est;   		// Estimated current on alpha axis
	volatile F16_16  Ibeta_est;    		// Estimated current on beta axis 
	
	volatile F16_16  Ialpha_err; 		// Current estimation error on alpha axis
	volatile F16_16  Ibeta_err;  		// Current estimation error on beta axis               
		
	volatile F16_16  K_smc;     		// Sliding Mode Controller gain 
	volatile F16_16  smc_max_err; 		// Maximum error of SMC 
		
	volatile F16_16  G;    				// Virtual motor algorithm constant
	volatile F16_16  F;    				// Virtual motor algorithm constant
	
	volatile F16_16  Cflt_smc;       	// Slide mode controller filter coefficientficient 
	volatile F16_16  Cflt_omega;  		// Filter coefficientficient for Omega filtered calc
	
	volatile F16_16  omega;     		// Estimated rotor speed
	volatile F16_16  omega_flt; 		// Filtered estimated rotor speed
	
	volatile F16_16  theta;				// Estimated rotor angle 
	volatile F16_16  theta_offset;		// Theta compensation 
	
	volatile F16_16  test1;   			// test1&2 can be used for debugging F16_16 fixed point
	volatile F16_16  test2;				
	volatile F22_10  test3;				// test3&4 can be used for debugging F22_10 fixed point
	volatile F22_10  test4;
	
}FOC_STRUCT;


#define enabled 		status.bits.bit0	
#define speedEnabled 	status.bits.bit1	
#define uartBusy 		status.bits.bit2

#endif  /* __TYPE_H__ */
