/*******************************************************************************
Copyright (c) 2014 released Microchip Technology Inc. All rights reserved.

Microchip licenses to you the right to use, modify, copy and distribute
Software only when embedded on a Microchip microcontroller or digital signal
controller that is integrated into your product or third party product
(pursuant to the sublicense terms in the accompanying license agreement).

You should refer to the license agreement accompanying this Software for
additional information regarding your rights and obligations.

SOFTWARE AND DOCUMENTATION ARE PROVIDED AS IS WITHOUT WARRANTY OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF
MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE.
IN NO EVENT SHALL MICROCHIP OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER
CONTRACT, NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR
OTHER LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES
INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR
CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT OF
SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES
(INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS.
*******************************************************************************/
#ifndef _USERPARAMS_H
#define _USERPARAMS_H

#ifdef __cplusplus  // Provide C++ Compatability
    extern "C" {
#endif
// *****************************************************************************
// *****************************************************************************
// Section: Included Files
// *****************************************************************************
// *****************************************************************************
#include <stdint.h>
#ifdef __XC16__  // See comments at the top of this header file
    #include <xc.h>
#endif // __XC16__

/************** Start-Up Parameters **************/

#define LOCKTIME_IN_SEC  0.25		/*Initial rotor lock time in seconds*/
/*Make sure LOCKTIMEINSEC*(1.0/LOOPTIMEINSEC)*/
/*is less than 65535.*/
#define OPEN_LOOP_TIME_IN_SEC 3.0	/* Open loop time in seconds. This is the time that
/* will take from stand still to closed loop.
/* Optimized to overcome the brake inertia.
/* (Magtrol AHB-3 brake inertia = 6.89 kg x cm2).*/
#define INITIAL_TORQUE	1.0		/* Initial Torque demand in Amps.
/* Enter initial torque demand in Amps using REFINAMPS()
/* macro. Maximum Value for reference is defined by
/* shunt resistor value and differential amplifier gain.
/* Use this equation to calculate maximum torque in
/* Amperes:
/*
/* Max REFINAMPS = (VDD/2)/(RSHUNT*DIFFAMPGAIN)
/*
/* For example:
/*
/* INVA_BUS_SHUNTRES_OHM = 0.015
/* DEVICE_VDD_VOLTS = 5
/* INVA_IBUS_AMP_GAIN   = 23.5
/*
/* Maximum torque reference in Amps is:
/*
/* (.015/2)/(.015*23.5) = 7.09 Amperes, or REFINAMPS(7.09)
*/

#define END_SPEED_OPEN_LOOP MIN_SPEED_IN_RPM

/* Values used to test Hurst Motor "NT Dynamo DMB0224C10002" at 24VDC input. Motor datasheet at www.hurstmfg.com*/
#define POLE_PAIRS      	5       /* Number of pole pairs*/
#define PHASE_RES		((float)2.03)	/* Phase resistance in Ohms.*/
#define PHASE_IND		((float)0.0023)/* Phase inductance in Henrys.*/
#define NOMINAL_SPEED_IN_RPM 2800	/* Make sure NOMINALSPEEDINRPM generates a MAXOMEGA < 1.0*/
/* Use this formula:
/* MAXOMEGA = NOMINALSPEEDINRPM*SPEEDLOOPTIME*POLEPAIRS*2/60
/* If MAXOMEGA > 1.0, reduce NOMINALSPEEDINRPM or execute
/* speed loop faster by reducing SpeedLoopTime.
/* Maximum position of POT will set a reference of
/* NOMINALSPEEDINRPM.*/
#define MIN_SPEED_IN_RPM	500	/* Minimum speed in RPM. Closed loop will operate at this */
/* speed. Open loop will transition to closed loop at
/* this minimum speed. Minimum POT position (CCW) will set
/* a speed reference of MIN_SPEED_IN_RPM */
#define FIELDWEAK_SPEED_RPM 5000 	/* Make sure FIELDWEAK_SPEED_RPM generates a MAXOMEGA < 1.0 */
/* Use this formula:
/* MAXOMEGA = FIELDWEAK_SPEED_RPM*SPEED_LOOPTIME*POLE_PAIRS*2/60
/* If MAXOMEGA > 1.0, reduce FIELDWEAK_SPEED_RPM or execute
/* speed loop faster by reducing SpeedLoopTime.
/* Maximum position of POT will set a reference of
/* FIELDWEAK_SPEED_RPM. */

/*************** Oscillator Parameters **************/

#define PLLIN		8000000		/* External Crystal or Clock Frequency (Hz) */
#define DESIRED_MIPS	70000000	/* Enter desired MIPS. If RTDM is used, copy */
/* this value to RTDM_FCY in RTDMUSER.h file */

/************** PWM and Control Timing Parameters **********/

#define PWMFREQUENCY_HZ	    20000  /*PWM Frequency in Hertz */
#define LOOPTIME_IN_SEC    0.00005  /* PWM Period = 1.0 / PWMFREQUENCY */
#define DEADTIME_MICROSEC  1        /* Specify dead time in micro seconds */
#define	BUT_POL_LOOP_TIME  0.100    /* Button polling loop period in sec */
#define SPEED_LOOP_FREQ    1000	   /* Speed loop Frequency in Hertz. This value must */
                                   /* be an integer to avoid pre-compiler error */

/************** Slide Mode Controller Parameters **********/

#define SMC_GAIN			0.85		/* Slide Mode Controller Gain (0.0 to 0.9999) */
#define MAX_LINEAR_SMC    0.005		/* If measured current - estimated current
/* is less than MAXLINEARSMC, the slide mode
/* Controller will have a linear behavior
/* instead of ON/OFF. Value from (0.0 to 0.9999) */
/*************** Hardware Parameters ****************/

#define UMAX 24         /* Maximum DC link voltage on inverter */
#define IPEAK 14      /* maximum current (peak to peak) that can be read by adc with the shunt/opamp settings above*/
/* Value of Shunt resistor (in Ohms)used for sensing Inverter A bus current */
#define INVA_BUS_SHUNTRES_OHM   0.015
    /* Specify gain of the Inverter A bus current amplifier */
#define INVA_IBUS_AMP_GAIN      23.5

/************** Real Time Data Monitor, RTDM *******************/

//#define RTDM		/* This definition enabled Real Time Data Monitor, UART interrupts */
/* to handle RTDM protocol, and array declarations for buffering
/* information in real time */

//#define DMCI_DEMO	/* Define this if a demo with DMCI is done. Start/stop of motor*/
/* and speed variation is done with DMCI instead of push button
/* and POT. Undefine "DMCI_DEMO" is user requires operating
/* this application with no DMCI*/

#ifdef RTDM
#define DATA_BUFFER_SIZE 400      /*Size in 16-bit Words*/
#define SNAPDELAY	10       /* In number of PWM Interrupts */
#define	SNAP1	    tPhaseCurrents.a
#define	SNAP2	    tPhaseCurrents.b
#define SNAP3	    tPhaseVoltages.a
#define SNAP4	    tPhaseVoltages.b
#endif


#define SPEED_DELAY 5 /* Delay for the speed ramp.*/
/* Necessary for the PI control to work properly at high speeds.*/

/*************** Optional Modes **************/
//#define TORQUEMODE
//#define ENVOLTRIPPLE

/************** PI Coefficients **************/

/******** D Control Loop Coefficients *******/
#define     DKP        Q15(0.05)
#define     DKI        Q15(0.005)
#define     DKC        Q15(0.99999)
#define     DOUTMAX    Q15(0.99999)

/******** Q Control Loop Coefficients *******/
#define     QKP        Q15(0.05)
#define     QKI        Q15(0.005)
#define     QKC        Q15(0.99999)
#define     QOUTMAX    Q15(0.99999)

/*** Velocity Control Loop Coefficients *****/
#define     WKP        Q15(0.1)
#define     WKI        Q15(0.005)
#define     WKC        Q15(0.99999)
#define     WOUTMAX    Q15(0.9)

/************** ADC Scaling **************/
/* Scaling constants: Determined by calibration or hardware design.*/
#define     DQK        Q15((OMEGA10 - OMEGA1)/2.0)	/* POT Scaling*/
#define     DQKA       Q15(0.5)	/* Current feedback software gain*/
#define     DQKB       Q15(0.5)	/* Current feedback software gain*/

/************** Field Weakening **************
/* Enter flux demand Amperes using REFINAMPS() macro. Maximum Value for
/* reference is defined by shunt resistor value and differential amplifier gain.
/* Use this equation to calculate maximum torque in Amperes:
/*
/* Max REFINAMPS = (VDD/2)/(RSHUNT*DIFFAMPGAIN)
/*
/* For example:
/*
/* INVA_BUS_SHUNTRES_OHM = 0.015
/* DEVICE_VDD_VOLTS = 5
/* INVA_IBUS_AMP_GAIN   = 23.5
/*
/* Maximum torque reference in Amps is:
/*
/* (5/2)/(.015*23.5) = 7.09 Amperes, or REFINAMPS(7.09)
/*
/* in order to have field weakening, this reference value should be negative,
/* so maximum value in this example is -7.09, or REFINAMPS(-7.09)*/


#define     DQKF_W0  REFINAMPS(0) /*3000*/
#define     DQKF_W1  REFINAMPS(-0.325) /*3166*/
#define     DQKF_W2  REFINAMPS(-0.45) /*3333*/
#define     DQKF_W3  REFINAMPS(-0.6) /*3500*/
#define     DQKF_W4  REFINAMPS(-0.9) /*3666*/
#define     DQKF_W5  REFINAMPS(-1) /*3833*/
#define     DQKF_W6  REFINAMPS(-1) /*4000*/
#define     DQKF_W7  REFINAMPS(-1) /*4166*/
#define     DQKF_W8  REFINAMPS(-1) /*4333*/
#define     DQKF_W9  REFINAMPS(-1) /*4500*/
#define     DQKF_W10  REFINAMPS(-1) /*4666*/
#define     DQKF_W11  REFINAMPS(-1) /*4833*/
#define     DQKF_W12  REFINAMPS(-1) /*5000*/
#define     DQKF_W13  REFINAMPS(-1) /*5166*/
#define     DQKF_W14  REFINAMPS(-1) /*5333*/
#define     DQKF_W15  REFINAMPS(-1) /*5500*/

/************** Derived Parameters ****************/



#define SPEED_LOOPTIME (1.0/SPEED_LOOP_FREQ) /* Speed Control Period */
#define IRP_PERCALC (uint16_t)(SPEED_LOOPTIME/LOOPTIME_IN_SEC)	/* PWM loops per velocity calculation */
/* PWM loops necessary for transitioning from open loop to closed loop */
#define TRANSITION_STEPS   IRP_PERCALC/4


#define LOCKTIME	(uint16_t)(LOCKTIME_IN_SEC*(1.0/LOOPTIME_IN_SEC))
/* Time it takes to ramp from zero to MINSPEEDINRPM. Time represented in seconds */
#define DELTA_STARTUP_RAMP	(uint16_t)(MIN_SPEED_IN_RPM*POLE_PAIRS*LOOPTIME_IN_SEC* \
							LOOPTIME_IN_SEC*65536*65536/(60*OPEN_LOOP_TIME_IN_SEC))
/*Number of control loops that must execute before the button routine is executed. */
#define	BUTPOLLOOPCNT	(uint16_t)(BUT_POL_LOOP_TIME/LOOPTIME_IN_SEC)
/* This pre-processor condition will generate an error if maximum speed is out of
/* range on Q15 when calculating Omega.*/
#if (FIELDWEAK_SPEED_RPM < NOMINAL_SPEED_IN_RPM)
#error FIELDWEAK_SPEED_RPM must be greater than NOMINAL_SPEED_IN_RPM for field weakening.
#error if application does not require Field Weakening, set FIELDWEAK_SPEED_RPM value
#error equal to NOMINAL_SPEED_IN_RPM
#else
#if ((FIELDWEAK_SPEED_RPM*POLE_PAIRS*2/(60*SPEED_LOOP_FREQ)) >= 1)
#error FIELDWEAK_SPEED_RPM will generate an Omega value greater than 1 which is the
#error maximum in Q15 format. Reduce FIELDWEAK_SPEED_RPM value, or increase speed
#error control loop frequency, SPEED_LOOP_FREQ
#endif
#endif

#endif

