#include <dsp.h>
#include "config.h"
#include "can.h"
#include "park.h"
#include "svgen.h"
#include "types.h"


#ifdef DEBUG
tPID *PIDptr; //Pointer to PID structure for gain adjustments in UARTRxInterrupt.c
volatile fractional *kCoeffs;  //Pointer to kCoeffs arrah for gain adjustments in UARTRxInterrupt.c
int raw = 0;
#endif

CalibrationConstants Cal;

volatile unsigned char CalibrationMode = 0;


volatile unsigned char I2C_State;
volatile char I2C_DeviceAddr;
volatile int I2C_RegisterAddr;
volatile unsigned char I2C_Data[EEPROM_PAGE_SIZE];
volatile int I2C_NumDataBytes;
volatile int I2C_data_ctr;

volatile char U1_inputBuf[U1_InputBufSize];
volatile unsigned int U1_BufCtr = 0;
volatile unsigned int U1_StringReceived = 0;

volatile unsigned char SPI1_DataOut[4] = {0x00, 0x00, 0x00, 0x00};
volatile unsigned char SPI2_DataOut[4] = {0x00, 0x00, 0x00, 0x00};

volatile signed int SC_Range;
volatile unsigned int SC_RangeCtr = 0; 
volatile signed int SC_Range_Max;
volatile signed int SC_Range_Min;
volatile signed int StopRange;
volatile signed int StopGain;
volatile signed int MaxRPMAdjustment;

volatile tParkParm ParkParm;
volatile tSVGenParm SVGenParm;

int qAngleOffset = DEFAULT_ANGLEOFFSET;
volatile int SlowRotatePosition = 0;

volatile fractional DisableCurrent;
volatile fractional SlowRotateCurrent;

volatile fractional CommandedCurrent = 0;
volatile fractional CommandedQuadratureCurrent = 0;
volatile fractional TargetQuadratureCurrent = 0;
volatile fractional TargetFluxCurrent = 0;

volatile unsigned int TorqueCmdTimeout;
volatile unsigned int TorqueCmdTimeout_ctr;

volatile unsigned int BiasCmdTimeout;
volatile unsigned int BiasCmdTimeout_ctr;

volatile fractional RPMRateLimit_ctsperinterpt;

volatile long VoltageConstant;


volatile int ShaftRotations = -80;

volatile fractional DistanceFromTargetCircle; //Positive Values means Vq/Vd is inside the target circle radius

volatile fractional kCoeffs_Id[] = {0, 0, 0};  //These are here for tuning purposes
volatile fractional kCoeffs_Iq[] = {0, 0, 0};  //They can go back to main.c after
volatile fractional kCoeffs_ShuntReg[] = {0, 0, 0};
volatile fractional kCoeffs_BattChargeILim[] = {0, 0, 0};
volatile fractional kCoeffs_BattDrawILim[] = {0, 0, 0};
volatile fractional kCoeffs_VqVdLim[] = {0, 0, 0};

tPID Id_PID;
tPID Iq_PID;
tPID ShuntReg_PID;
tPID BattChargeILim_PID;
tPID BattDrawILim_PID;
tPID VqVdLim_PID;

tGSAL Id_GSAL;
tGSAL Iq_GSAL;
tGSAL ShuntReg_GSAL;
tGSAL BattChargeILim_GSAL;
tGSAL BattDrawILim_GSAL;
tGSAL VqVdLim_GSAL;

volatile tCRSAL UserCommandedCurrent;
volatile tCRSAL BiasCurrent;
volatile tCRSAL TargetVoltage;
volatile tCRSAL MaxBattChargeCurrent;
volatile tCRSAL MaxBattDrawCurrent;
volatile tCRSAL ScaleIntegrationGain;
volatile tCRSAL GainScheduleRPMStdDevTarget;
volatile tCRSAL scale_factor;
volatile tCRSAL retract_factor;
volatile tCRSAL CAN_packet_rate;

unsigned int RPM_StdDev;

volatile fractional AbsoluteMaxTargetVoltage;
volatile fractional ShutdownVoltage;
volatile fractional MaxWindCurrent;


volatile fractional VoltageModification_BattCurrent = 0;  //Amount target voltage is reduced to limit battery charge current current.
volatile fractional VoltageModification_Limiter = 0;  //Amount target voltage is increased when the requested phase voltages (Vq/Vd) approach the unit circle.

volatile fractional IWindReduction_BattDraw_Mag = 0;  //Amount Winding Current Target is moved towards zero to limit battery draw current.
volatile fractional IWindReduction_VqVd_Mag = 0;  //Amount Winding Current Target is moved towards zero to limit VqVd excursion outside TargetCircle.

volatile fractional RPMs = 0;
volatile int RPMsValid = 0;

volatile POWER_CONVERTER_STATUS status;

unsigned int BufferA[INNERFILTERSAMPLES*NUMAIO] __attribute__((space(dma),aligned(64)));
unsigned int BufferB[INNERFILTERSAMPLES*NUMAIO] __attribute__((space(dma),aligned(64)));

unsigned int Buffer2A[INNERFILTERSAMPLES*NUMAIO] __attribute__((space(dma),aligned(64)));
unsigned int Buffer2B[INNERFILTERSAMPLES*NUMAIO] __attribute__((space(dma),aligned(64)));

unsigned int SPIBufferA[2] __attribute__((space(dma)));
unsigned int SPIBufferB[2] __attribute__((space(dma)));

unsigned int ECAN1MSGBUF[ECAN1_MSG_BUF_LENGTH][8] __attribute__((space(dma),aligned(ECAN1_MSG_BUF_LENGTH*16)));
//unsigned int BufferCAN1TX[CAN1TXBUFFSIZE] __attribute__((space(dma)));

volatile int SPI_OuterSampleCtr = 0;
volatile int ADC_OuterSampleCtr = 0;
volatile int ADC2_OuterSampleCtr = 0;
volatile int ReportingFilterCtr = 0;


//These variables contain the raw samples, possibly several per PWM update rate if INNERFILTERSAMPLES > 1
volatile fractional VBus_ADC[INNERFILTERSAMPLES];
volatile fractional IBatt_ADC[INNERFILTERSAMPLES];
volatile fractional DiffPress_ADC[INNERFILTERSAMPLES];
volatile fractional AuxTorque_ADC[INNERFILTERSAMPLES];

//These variables are versions of the samples stored at the PWM rate, for variables sampled by the ADC at a higher rate, (*_ADC variables above), these results are filtered versions of those higher rate samples.
volatile fractional QuadratureCurrentSamples[OUTERFILTERSAMPLES];
volatile fractional FluxCurrentSamples[OUTERFILTERSAMPLES];
volatile fractional DiffPressSamples[OUTERFILTERSAMPLES];
volatile fractional AuxTorqueSamples[OUTERFILTERSAMPLES];
volatile fractional VBusSamples[OUTERFILTERSAMPLES];
volatile fractional IBattSamples[OUTERFILTERSAMPLES];
volatile fractional LoadDCSamples[OUTERFILTERSAMPLES];
volatile fractional LoadDumpCurrentSamples[OUTERFILTERSAMPLES];

//These variables are the results of the 1kHz filtering operation.
volatile fractional QuadratureCurrent[REPORTINGFILTERSAMPLES];  // Quadrature Current Filtered to ~1kHz
volatile fractional FluxCurrent[REPORTINGFILTERSAMPLES];  // Quadrature Current Filtered to ~1kHz
volatile fractional VBus[REPORTINGFILTERSAMPLES];  // VBus Current Filtered to ~1kHz
volatile fractional IBatt[REPORTINGFILTERSAMPLES];  // IBatt Current Filtered to ~1kHz
volatile fractional Load_DC[REPORTINGFILTERSAMPLES];  // Load Dump Duty Cycle Current Filtered to ~1kHz
volatile fractional RPM[REPORTINGFILTERSAMPLES];  // RPM measurement Filtered to ~1kHz (1cnt = 0.5RPM)
volatile fractional LoadDumpCurrent[REPORTINGFILTERSAMPLES];
volatile fractional DiffPress[REPORTINGFILTERSAMPLES];  // Differential Pressuer measurement Filtered to ~1kHz (1cnt = 0.5RPM)
volatile fractional AuxTorque[REPORTINGFILTERSAMPLES];  // Aux Torque measurement Filtered to ~1kHz (1cnt = 0.5RPM)


volatile fractional R_QuadratureCurrent;
volatile fractional R_VBus;
volatile fractional R_IBatt;
volatile fractional R_Load_DC;
volatile fractional R_RPM;
volatile fractional R_LoadDumpCurrent;
volatile fractional R_DiffPress;
volatile fractional R_AuxTorque;

volatile int halls;

CANmsg message[ECAN1_NUM_TX_BUFFERS];  //One message structure for each buffer

int TargetCircleRadius = PRELIMITER_TARGETCIRCLERADIUS;
    
int EncoderStatus =  NO_ENCODER_SYNC_HAS_OCCURED; //  INDEX_PULSE_SEEN; //

volatile signed int PhaseA_Curr;
volatile signed int PhaseB_Curr;
volatile int CurrMeasStatus = 0x0008;  //Set as compete so it starts the first time.

volatile fractional BridgeDisableCurrent;
volatile fractional BridgeDisableRPM;


volatile int iTemp1 = 0;
volatile int iTemp2 = 0;
volatile int iTemp3 = 0;
volatile int iTemp4 = 0;
volatile float fTemp1 = 0.0;
long lTemp1;
long lTemp2;
long lTemp3;
long lTemp4;

volatile unsigned long eeprom_timer;


#ifdef DEBUG
volatile float f_time;
#endif

