This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CCS/DRV8301-69M-KIT: gMotorVars.CtrlState always remains in idle , not able to identify motor

Part Number: DRV8301-69M-KIT
Other Parts Discussed in Thread: MOTORWARE

Tool/software: Code Composer Studio

/* --COPYRIGHT--,BSD
 * Copyright (c) 2012, LineStream Technologies Incorporated
 * Copyright (c) 2012, Texas Instruments Incorporated
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * *  Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * *  Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
* *  Neither the names of Texas Instruments Incorporated, LineStream
 *    Technologies Incorporated, nor the names of its contributors may be
 *    used to endorse or promote products derived from this software without
 *    specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 * --/COPYRIGHT--*/
//! \file   solutions/instaspin_motion/src/proj_lab05d.c
//! \brief  InstaSPIN-MOTION SpinTAC Speed Controller
//!
//! (C) Copyright 2012, LineStream Technologies, Inc.
//! (C) Copyright 2011, Texas Instruments, Inc.

//! \defgroup PROJ_LAB05d PROJ_LAB05d
//@{

//! \defgroup PROJ_LAB05d_OVERVIEW Project Overview
//!
//! Running the SpinTAC Velocity Controller
//!

// **************************************************************************
// the includes

// system includes
#include <math.h>
#include "main.h"
//#include "DSP28x_Project.h"     // Device Headerfile and Examples Include File
//#include "stdio.h"
//#include "sw/drivers/can/src/32b/f28x/f2806x/can.h"

//#pragma DATA_SECTION(ECanaRegs,"ECanaRegsFile");

//volatile struct ECAN_REGS ECanaRegs;

//#pragma DATA_SECTION(ECanaMboxes,"ECanaMboxesFile");

//volatile struct ECAN_MBOXES ECanaMboxes;


#ifdef FLASH
#pragma CODE_SECTION(mainISR,"ramfuncs");
#endif

// Include header files used in the main function


// ************************************************************************
// the defines

#define LED_BLINK_FREQ_Hz   5


// **************************************************************************
// the globals

uint_least16_t gCounter_updateGlobals = 0;

bool Flag_Latch_softwareUpdate = true;

CTRL_Handle ctrlHandle;

HAL_Handle halHandle;

USER_Params gUserParams;

HAL_PwmData_t gPwmData = {_IQ(0.0), _IQ(0.0), _IQ(0.0)};

HAL_AdcData_t gAdcData;

_iq gMaxCurrentSlope = _IQ(0.0);



#ifdef FAST_ROM_V1p6
CTRL_Obj *controller_obj;
#else
CTRL_Obj ctrl;				//v1p7 format
#endif

ST_Obj st_obj;
ST_Handle stHandle;

uint16_t gLEDcnt = 0;

volatile MOTOR_Vars_t gMotorVars = MOTOR_Vars_INIT;

#ifdef FLASH
// Used for running BackGround in flash, and ISR in RAM
extern uint16_t *RamfuncsLoadStart, *RamfuncsLoadEnd, *RamfuncsRunStart;
#endif


#ifdef DRV8301_SPI
// Watch window interface to the 8301 SPI
DRV_SPI_8301_Vars_t gDrvSpi8301Vars;
#endif
#ifdef DRV8305_SPI
// Watch window interface to the 8305 SPI
DRV_SPI_8305_Vars_t gDrvSpi8305Vars;
#endif

_iq gFlux_pu_to_Wb_sf;

_iq gFlux_pu_to_VpHz_sf;

_iq gTorque_Ls_Id_Iq_pu_to_Nm_sf;

_iq gTorque_Flux_Iq_pu_to_Nm_sf;

// **************************************************************************
// In future declare variables over here
void InitECana(void);
void InitECanaGpio(void);
void spi_init(void);

void spi_fifo_init(void);
void delay(float n);

unsigned long spi_xmit(unsigned long  a);
Uint16 sdata=0x0000;  // s3end data
Uint16 rdata1=0;  // received data
Uint16 rdata2=0;
Uint16 rdata3=0;
Uint16 rdata4=0;
Uint16 rdata5=0;
Uint16 rdata6=0;
Uint32 byte7=0;
Uint32 fbyte3=0;
Uint16 fbyte4=0;
Uint32 fibyte3=0;
Uint32 fiibyte3=0;
Uint32 fibyte4=0;
Uint32 fibyte5=0;
long i;
//long loopcount=0;
//volatile struct ECAN_REGS ECanaShadow;
void main(void)
{

	//struct ECAN_REGS ECanaShadow;
    uint_least8_t estNumber = 0;

#ifdef FAST_ROM_V1p6
  uint_least8_t ctrlNumber = 0;
#endif

  // Only used if running from FLASH
  // Note that the variable FLASH is defined by the project
  #ifdef FLASH
  // Copy time critical code and Flash setup code to RAM
  // The RamfuncsLoadStart, RamfuncsLoadEnd, and RamfuncsRunStart
  // symbols are created by the linker. Refer to the linker files.
  memCopy((uint16_t *)&RamfuncsLoadStart,(uint16_t *)&RamfuncsLoadEnd,(uint16_t *)&RamfuncsRunStart);
  #endif

  // initialize the hardware abstraction layer
  halHandle = HAL_init(&hal,sizeof(hal));


  // check for errors in user parameters
  USER_checkForErrors(&gUserParams);


  // store user parameter error in global variable
  gMotorVars.UserErrorCode = USER_getErrorCode(&gUserParams);


  // do not allow code execution if there is a user parameter error
  if(gMotorVars.UserErrorCode != USER_ErrorCode_NoError)
    {
      for(;;)
        {
          gMotorVars.Flag_enableSys = false;
        }
    }


  // initialize the user parameters
  USER_setParams(&gUserParams);


  // set the hardware abstraction layer parameters
  HAL_setParams(halHandle,&gUserParams);


  // initialize the controller
#ifdef FAST_ROM_V1p6
  ctrlHandle = CTRL_initCtrl(ctrlNumber, estNumber);  		//v1p6 format (06xF and 06xM devices)
  controller_obj = (CTRL_Obj *)ctrlHandle;
#else
  ctrlHandle = CTRL_initCtrl(estNumber,&ctrl,sizeof(ctrl));	//v1p7 format default
#endif


  {
    CTRL_Version version;

    // get the version number
    CTRL_getVersion(ctrlHandle,&version);

    gMotorVars.CtrlVersion = version;
  }


  // set the default controller parameters
  CTRL_setParams(ctrlHandle,&gUserParams);


  // setup faults
  HAL_setupFaults(halHandle);


  // initialize the interrupt vector table
  HAL_initIntVectorTable(halHandle);


  // enable the ADC interrupts
  HAL_enableAdcInts(halHandle);


  // enable global interrupts
  HAL_enableGlobalInts(halHandle);


  // enable debug interrupts
  HAL_enableDebugInt(halHandle);


  // disable the PWM
  HAL_disablePwm(halHandle);


  // initialize the SpinTAC Components
  stHandle = ST_init(&st_obj, sizeof(st_obj));


  // setup the SpinTAC Components
  ST_setupVelCtl(stHandle);


#ifdef DRV8301_SPI
  // turn on the DRV8301 if present
  HAL_enableDrv(halHandle);
  // initialize the DRV8301 interface
  HAL_setupDrvSpi(halHandle,&gDrvSpi8301Vars);
#endif

#ifdef DRV8305_SPI
  // turn on the DRV8305 if present
  HAL_enableDrv(halHandle);
  // initialize the DRV8305 interface
  HAL_setupDrvSpi(halHandle,&gDrvSpi8305Vars);
#endif

  // enable DC bus compensation
    CTRL_setFlag_enableDcBusComp(ctrlHandle, true);


    // compute scaling factors for flux and torque calculations
    gFlux_pu_to_Wb_sf = USER_computeFlux_pu_to_Wb_sf();
    gFlux_pu_to_VpHz_sf = USER_computeFlux_pu_to_VpHz_sf();
    gTorque_Ls_Id_Iq_pu_to_Nm_sf = USER_computeTorque_Ls_Id_Iq_pu_to_Nm_sf();
    gTorque_Flux_Iq_pu_to_Nm_sf = USER_computeTorque_Flux_Iq_pu_to_Nm_sf();

    InitSysCtrl();



 // EALLOW;
  // InitECana();
 // InitECanaGpio();
  EALLOW;
  /* Write to the MSGID field  */


   //   ECanaMboxes.MBOX25.MSGID.all = 0x95555555;

 // EDIS;

  // Configure Mailbox under test as a Transmit mailbox

 // 	ECanaShadow.CANMD.all = ECanaRegs.CANMD.all;
  	//ECanaShadow.CANMD.bit.MD25 = 0;
  //	ECanaRegs.CANMD.all = ECanaShadow.CANMD.all;


  	// Enable Mailbox under test

  	//	ECanaShadow.CANME.all = ECanaRegs.CANME.all;
  	//	ECanaShadow.CANME.bit.ME25 = 1;
  	//	ECanaRegs.CANME.all = ECanaShadow.CANME.all;


  /* Write to DLC field in Message Control reg */

 // ECanaMboxes.MBOX25.MSGCTRL.bit.DLC = 8;








 void spi_init(void);

  for(;;)
  {
	  // Waiting for enable system flag to be set
	      while(!(gMotorVars.Flag_enableSys));

	      // Dis-able the Library internal PI.  Iq has no reference now
	      CTRL_setFlag_enableSpeedCtrl(ctrlHandle, false);

	      // loop while the enable system flag is true
	      while(gMotorVars.Flag_enableSys)
	        {
	          CTRL_Obj *obj = (CTRL_Obj *)ctrlHandle;
	          ST_Obj *stObj = (ST_Obj *)stHandle;

	          // increment counters
	          gCounter_updateGlobals++;

	          // enable/disable the use of motor parameters being loaded from user.h
	          CTRL_setFlag_enableUserMotorParams(ctrlHandle,gMotorVars.Flag_enableUserParams);

	          // enable/disable Rs recalibration during motor startup
	       //   EST_setFlag_enableRsRecalc(obj->estHandle,gMotorVars.Flag_enableRsRecalc);

	          // enable/disable automatic calculation of bias values
	          CTRL_setFlag_enableOffset(ctrlHandle,gMotorVars.Flag_enableOffsetcalc);


	          if(CTRL_isError(ctrlHandle))
	            {
	              // set the enable controller flag to false
	              CTRL_setFlag_enableCtrl(ctrlHandle,false);

	              // set the enable system flag to false
	              gMotorVars.Flag_enableSys = false;

	              // disable the PWM
	              HAL_disablePwm(halHandle);
	            }
	          else
	            {
	              // update the controller state
	              bool flag_ctrlStateChanged = CTRL_updateState(ctrlHandle);

	              // enable or disable the control
	              CTRL_setFlag_enableCtrl(ctrlHandle, gMotorVars.Flag_Run_Identify);

	              if(flag_ctrlStateChanged)
	                {
	                  CTRL_State_e ctrlState = CTRL_getState(ctrlHandle);

	                  if(ctrlState == CTRL_State_OffLine)
	                    {
	                      // enable the PWM
	                      HAL_enablePwm(halHandle);
	                    }
	                  else if(ctrlState == CTRL_State_OnLine)
	                    {
	                      if(gMotorVars.Flag_enableOffsetcalc == true)
	                      {
	                        // update the ADC bias values
	                        HAL_updateAdcBias(halHandle);
	                      }
	                      else
	                      {
	                        // set the current bias
	                        HAL_setBias(halHandle,HAL_SensorType_Current,0,_IQ(I_A_offset));
	                        HAL_setBias(halHandle,HAL_SensorType_Current,1,_IQ(I_B_offset));
	                        HAL_setBias(halHandle,HAL_SensorType_Current,2,_IQ(I_C_offset));

	                        // set the voltage bias
	                        HAL_setBias(halHandle,HAL_SensorType_Voltage,0,_IQ(V_A_offset));
	                        HAL_setBias(halHandle,HAL_SensorType_Voltage,1,_IQ(V_B_offset));
	                        HAL_setBias(halHandle,HAL_SensorType_Voltage,2,_IQ(V_C_offset));
	                      }

	                      // Return the bias value for currents
	                      gMotorVars.I_bias.value[0] = HAL_getBias(halHandle,HAL_SensorType_Current,0);
	                      gMotorVars.I_bias.value[1] = HAL_getBias(halHandle,HAL_SensorType_Current,1);
	                      gMotorVars.I_bias.value[2] = HAL_getBias(halHandle,HAL_SensorType_Current,2);

	                      // Return the bias value for voltages
	                      gMotorVars.V_bias.value[0] = HAL_getBias(halHandle,HAL_SensorType_Voltage,0);
	                      gMotorVars.V_bias.value[1] = HAL_getBias(halHandle,HAL_SensorType_Voltage,1);
	                      gMotorVars.V_bias.value[2] = HAL_getBias(halHandle,HAL_SensorType_Voltage,2);

	                      // enable the PWM
	                      HAL_enablePwm(halHandle);
	                    }
	                  else if(ctrlState == CTRL_State_Idle)
	                    {
	                      // disable the PWM
	                      HAL_disablePwm(halHandle);
	                      gMotorVars.Flag_Run_Identify = false;
	                    }

	                  if((CTRL_getFlag_enableUserMotorParams(ctrlHandle) == true) &&
	                    (ctrlState > CTRL_State_Idle) &&
	                    (gMotorVars.CtrlVersion.minor == 6))
	                    {
	                      // call this function to fix 1p6
	                      USER_softwareUpdate1p6(ctrlHandle);
	                    }

	                }
	            }


	          if(EST_isMotorIdentified(obj->estHandle))
	            {
	              // set the current ramp
	              EST_setMaxCurrentSlope_pu(obj->estHandle,gMaxCurrentSlope);
	              gMotorVars.Flag_MotorIdentified = true;

	              // set the speed reference
	              CTRL_setSpd_ref_krpm(ctrlHandle,gMotorVars.SpeedRef_krpm);

	              // set the speed acceleration
	              CTRL_setMaxAccel_pu(ctrlHandle,_IQmpy(MAX_ACCEL_KRPMPS_SF,gMotorVars.MaxAccel_krpmps));

	              // enable the SpinTAC Speed Controller
	              STVELCTL_setEnable(stObj->velCtlHandle, true);

	              if(EST_getState(obj->estHandle) != EST_State_OnLine)
	              {
	              	// if the estimator is not running, place SpinTAC into reset
	              	STVELCTL_setEnable(stObj->velCtlHandle, false);
	              }

	              if(Flag_Latch_softwareUpdate)
	              {
	                Flag_Latch_softwareUpdate = false;

	                USER_calcPIgains(ctrlHandle);

	                // initialize the watch window kp and ki current values with pre-calculated values
	                gMotorVars.Kp_Idq = CTRL_getKp(ctrlHandle,CTRL_Type_PID_Id);
	                gMotorVars.Ki_Idq = CTRL_getKi(ctrlHandle,CTRL_Type_PID_Id);

	                // initialize the watch window with maximum and minimum Iq reference
	                gMotorVars.SpinTAC.VelCtlOutputMax_A = _IQmpy(STVELCTL_getOutputMaximum(stObj->velCtlHandle), _IQ(USER_IQ_FULL_SCALE_CURRENT_A));
	                gMotorVars.SpinTAC.VelCtlOutputMin_A = _IQmpy(STVELCTL_getOutputMinimum(stObj->velCtlHandle), _IQ(USER_IQ_FULL_SCALE_CURRENT_A));
	              }

	            }
	          else
	            {
	              Flag_Latch_softwareUpdate = true;

	              // the estimator sets the maximum current slope during identification
	              gMaxCurrentSlope = EST_getMaxCurrentSlope_pu(obj->estHandle);
	            }


	          // when appropriate, update the global variables
	          if(gCounter_updateGlobals >= NUM_MAIN_TICKS_FOR_GLOBAL_VARIABLE_UPDATE)
	            {
	              // reset the counter
	              gCounter_updateGlobals = 0;

	              updateGlobalVariables_motor(ctrlHandle, stHandle);
	            }


	          // update Kp and Ki gains
	          updateKpKiGains(ctrlHandle);

	          // set the maximum and minimum values for Iq reference
	          STVELCTL_setOutputMaximums(stObj->velCtlHandle, _IQmpy(gMotorVars.SpinTAC.VelCtlOutputMax_A, _IQ(1.0/USER_IQ_FULL_SCALE_CURRENT_A)), _IQmpy(gMotorVars.SpinTAC.VelCtlOutputMin_A, _IQ(1.0/USER_IQ_FULL_SCALE_CURRENT_A)));

	          // enable/disable the forced angle
	          EST_setFlag_enableForceAngle(obj->estHandle,gMotorVars.Flag_enableForceAngle);

	          // enable or disable power warp
	          CTRL_setFlag_enablePowerWarp(ctrlHandle,gMotorVars.Flag_enablePowerWarp);

	  #ifdef DRV8301_SPI
	          HAL_writeDrvData(halHandle,&gDrvSpi8301Vars);

	          HAL_readDrvData(halHandle,&gDrvSpi8301Vars);
	  #endif
	  #ifdef DRV8305_SPI
	          HAL_writeDrvData(halHandle,&gDrvSpi8305Vars);

	          HAL_readDrvData(halHandle,&gDrvSpi8305Vars);
	  #endif
	        } // end of while(gFlag_enableSys) loop


	      // disable the PWM
	      HAL_disablePwm(halHandle);

	      // set the default controller parameters (Reset the control to re-identify the motor)
	      CTRL_setParams(ctrlHandle,&gUserParams);
	      gMotorVars.Flag_Run_Identify = false;

	      // setup the SpinTAC Components
	      ST_setupVelCtl(stHandle);







} // end of for(;;) loop
//  asm(" ESTOP0");
} // end of main() function


interrupt void mainISR(void)
{

  static uint16_t stCnt = 0;

  // toggle status LED
  if(++gLEDcnt >= (uint_least32_t)(USER_ISR_FREQ_Hz / LED_BLINK_FREQ_Hz))
  {
    HAL_toggleLed(halHandle,(GPIO_Number_e)HAL_Gpio_LED2);
    gLEDcnt = 0;
  }


  // acknowledge the ADC interrupt
  HAL_acqAdcInt(halHandle,ADC_IntNumber_1);


  // convert the ADC data
  HAL_readAdcData(halHandle,&gAdcData);


  // Run the SpinTAC Components
  if(stCnt++ >= ISR_TICKS_PER_SPINTAC_TICK) {
	  ST_runVelCtl(stHandle, ctrlHandle);
	  stCnt = 1;
  }



  // run the controller
  CTRL_run(ctrlHandle,halHandle,&gAdcData,&gPwmData);


  // write the PWM compare values
  HAL_writePwmData(halHandle,&gPwmData);


  // setup the controller
  CTRL_setup(ctrlHandle);
  // Transmit data

        spi_xmit(sdata);
         // Wait until data is received
         while(SpiaRegs.SPIFFRX.bit.RXFFST !=1) { }

        // while(SpiaRegs.SPISTS.bit.INT_FLAG !=1) { }
         // Check against sent data
         rdata1 = SpiaRegs.SPIRXBUF ;
         delay(10);
         spi_xmit(sdata);
              // Wait until data is received
         while(SpiaRegs.SPIFFRX.bit.RXFFST !=1) { }
              //while(SpiaRegs.SPISTS.bit.INT_FLAG !=1) { }
              // Check against sent data
         rdata2 = SpiaRegs.SPIRXBUF  ;
         delay(10);
         spi_xmit(sdata);
              // Wait until data is received
         while(SpiaRegs.SPIFFRX.bit.RXFFST !=1) { }
              //while(SpiaRegs.SPISTS.bit.INT_FLAG !=1) { }
              // Check against sent data
         rdata3 = SpiaRegs.SPIRXBUF ;
         delay(10);
         spi_xmit(sdata);
                   // Wait until data is received
         while(SpiaRegs.SPIFFRX.bit.RXFFST !=1) { }
                   //while(SpiaRegs.SPISTS.bit.INT_FLAG !=1) { }
                   // Check against sent data
         rdata4 = SpiaRegs.SPIRXBUF;
         delay(10);
         spi_xmit(sdata);
                        // Wait until data is received
         while(SpiaRegs.SPIFFRX.bit.RXFFST !=1) { }
                        //while(SpiaRegs.SPISTS.bit.INT_FLAG !=1) { }
                        // Check against sent data
         rdata5 = SpiaRegs.SPIRXBUF ;
         delay(10);
         spi_xmit(sdata);
                             // Wait until data is received
         while(SpiaRegs.SPIFFRX.bit.RXFFST !=1) { }
                             //while(SpiaRegs.SPISTS.bit.INT_FLAG !=1) { }
                             // Check against sent data
         rdata6 = SpiaRegs.SPIRXBUF ;
         delay(10);
                                   fbyte3  = rdata3 & 0x03;
                                   fibyte3 = fbyte3<< 0x08;
                                   fiibyte3= fibyte3<<0x08;
                                   fbyte4  = rdata4<< 0x08;
                                   fibyte4 = fiibyte3 | fbyte4;
                                   fibyte5 = (rdata5 | fibyte4);
                                   byte7   = (fibyte5*360)/262144;// position data


                               //    ECanaMboxes.MBOX25.MDL.all = byte7;
                               //    ECanaMboxes.MBOX25.MDH.all = 0x00000000;




  return;
} // end of mainISR() function
asm(" ESTOP0");


void spi_init()
{
	SpiaRegs.SPICCR.all =0x0007;	             // Reset on, rising edge, 16-bit char bits
	SpiaRegs.SPICTL.all =0x0007;    		     // Enable master mode, normal phase,
                                                 // enable talk, and SPI int disabled.
	SpiaRegs.SPIBRR =0X0004;
    SpiaRegs.SPICCR.all =0x00C7;		         // Relinquish SPI from Reset
    SpiaRegs.SPIPRI.bit.FREE = 1;                // Set so breakpoints don't disturb xmission


}

/*void InitECanaGpio(void)
{
   EALLOW;

/* Enable internal pull-up for the selected CAN pins */
// Pull-ups can be enabled or disabled by the user.
// This will enable the pullups for the specified pins.
// Comment out other unwanted lines.

   /*GpioCtrlRegs.GPAPUD.bit.GPIO30 = 0;     // Enable pull-up for GPIO30 (CANRXA)
   GpioCtrlRegs.GPAPUD.bit.GPIO31 = 0;     // Enable pull-up for GPIO31 (CANTXA)

/* Set qualification for selected CAN pins to asynch only */
// Inputs are synchronized to SYSCLKOUT by default.
// This will select asynch (no qualification) for the selected pins.

 /*   GpioCtrlRegs.GPAQSEL2.bit.GPIO30 = 3;   // Asynch qual for GPIO30 (CANRXA)
    GpioCtrlRegs.GPAQSEL2.bit.GPIO31 = 3;   // Asynch qual for GPIO31 (CANTXA)
/* Configure eCAN-A pins using GPIO regs*/
// This specifies which of the possible GPIO pins will be eCAN functional pins.

 /*   GpioCtrlRegs.GPAMUX2.bit.GPIO30 = 1;    // Configure GPIO30 for CANRXA operation
    GpioCtrlRegs.GPAMUX2.bit.GPIO31 = 1;    // Configure GPIO31 for CANTXA operation

    EDIS;
}
void InitECana(void)        // Initialize eCAN-A module
{

/* Create a shadow register structure for the CAN control registers. This is
 needed, since only 32-bit access is allowed to these registers. 16-bit access
 to these registers could potentially corrupt the register contents or return
 false data. */

/*	struct ECAN_REGS ECanaShadow;

    EALLOW;     // EALLOW enables access to protected bits

/* Configure eCAN RX and TX pins for CAN operation using eCAN regs*/

 /*   ECanaShadow.CANTIOC.all = ECanaRegs.CANTIOC.all;
    ECanaShadow.CANTIOC.bit.TXFUNC = 1;
    ECanaRegs.CANTIOC.all = ECanaShadow.CANTIOC.all;

    ECanaShadow.CANRIOC.all = ECanaRegs.CANRIOC.all;
    ECanaShadow.CANRIOC.bit.RXFUNC = 1;
    ECanaRegs.CANRIOC.all = ECanaShadow.CANRIOC.all;

/* Configure eCAN for HECC mode - (reqd to access mailboxes 16 thru 31) */
                                    // HECC mode also enables time-stamping feature

/*    ECanaShadow.CANMC.all = ECanaRegs.CANMC.all;
    ECanaShadow.CANMC.bit.SCB = 1;
    ECanaRegs.CANMC.all = ECanaShadow.CANMC.all;

/* Initialize all bits of 'Message Control Register' to zero */
// Some bits of MSGCTRL register come up in an unknown state. For proper operation,
// all bits (including reserved bits) of MSGCTRL must be initialized to zero

  /*  ECanaMboxes.MBOX0.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX1.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX2.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX3.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX4.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX5.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX6.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX7.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX8.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX9.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX10.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX11.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX12.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX13.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX14.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX15.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX16.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX17.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX18.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX19.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX20.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX21.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX22.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX23.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX24.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX25.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX26.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX27.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX28.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX29.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX30.MSGCTRL.all = 0x00000000;
    ECanaMboxes.MBOX31.MSGCTRL.all = 0x00000000;

// TAn, RMPn, GIFn bits are all zero upon reset and are cleared again
//  as a matter of precaution.

    ECanaRegs.CANTA.all = 0xFFFFFFFF;   /* Clear all TAn bits */

 /*   ECanaRegs.CANRMP.all = 0xFFFFFFFF;  /* Clear all RMPn bits */

 /*   ECanaRegs.CANGIF0.all = 0xFFFFFFFF; /* Clear all interrupt flag bits */
/*    ECanaRegs.CANGIF1.all = 0xFFFFFFFF;

/* Configure bit timing parameters for eCANA*/

 /*   ECanaShadow.CANMC.all = ECanaRegs.CANMC.all;
    ECanaShadow.CANMC.bit.CCR = 1 ;            // Set CCR = 1
    ECanaRegs.CANMC.all = ECanaShadow.CANMC.all;

    // Wait until the CPU has been granted permission to change the configuration registers
    do
    {
      ECanaShadow.CANES.all = ECanaRegs.CANES.all;
    } while(ECanaShadow.CANES.bit.CCE != 1 );       // Wait for CCE bit to be set..

    ECanaShadow.CANBTC.all = 0;
    /* The following block is for 80 MHz SYSCLKOUT. (40 MHz CAN module clock Bit rate = 1 Mbps
       See Note at end of file. */
    //ECanaShadow.CANBTC.all =  0x000503BD;   // 500k
 /*   ECanaShadow.CANBTC.bit.BRPREG = 1;
    ECanaShadow.CANBTC.bit.TSEG2REG = 2;//4
    ECanaShadow.CANBTC.bit.TSEG1REG = 10;//13

    ECanaShadow.CANBTC.bit.SAM = 0;
   // ECanaShadow.CANME.bit.SJW = 4;
    ECanaRegs.CANBTC.all = ECanaShadow.CANBTC.all;

    ECanaShadow.CANMC.all = ECanaRegs.CANMC.all;
    ECanaShadow.CANMC.bit.CCR = 0 ;            // Set CCR = 0
    ECanaRegs.CANMC.all = ECanaShadow.CANMC.all;

    // Wait until the CPU no longer has permission to change the configuration registers
    do
    {
      ECanaShadow.CANES.all = ECanaRegs.CANES.all;
    } while(ECanaShadow.CANES.bit.CCE != 0 );       // Wait for CCE bit to be  cleared..

/* Disable all Mailboxes  */
   /* ECanaRegs.CANME.all = 0;        // Required before writing the MSGIDs

    EDIS;
}*/

void spi_fifo_init()
{
// Initialize SPI FIFO registers
    SpiaRegs.SPIFFTX.all=0xE040;
    SpiaRegs.SPIFFRX.all=0x2044;
    SpiaRegs.SPIFFCT.all=0x0;
}
void delay(float n)
{
   short      i;
    for (i = 0; i < n; i++) {}
}
unsigned long spi_xmit(unsigned long a)
{
   SpiaRegs.SPITXBUF=a<<8;
    return a;
}
void updateGlobalVariables_motor(CTRL_Handle handle, ST_Handle sthandle)
{
  CTRL_Obj *obj = (CTRL_Obj *)handle;
  ST_Obj *stObj = (ST_Obj *)sthandle;


  // get the speed estimate
  gMotorVars.Speed_krpm = EST_getSpeed_krpm(obj->estHandle);

  // get the real time speed reference coming out of the speed trajectory generator
  gMotorVars.SpeedTraj_krpm = _IQmpy(CTRL_getSpd_int_ref_pu(handle),EST_get_pu_to_krpm_sf(obj->estHandle));

  // get the torque estimate
  gMotorVars.Torque_Nm = USER_computeTorque_Nm(handle, gTorque_Flux_Iq_pu_to_Nm_sf, gTorque_Ls_Id_Iq_pu_to_Nm_sf);

  // get the magnetizing current
  gMotorVars.MagnCurr_A = EST_getIdRated(obj->estHandle);

  // get the rotor resistance
  gMotorVars.Rr_Ohm = EST_getRr_Ohm(obj->estHandle);

  // get the stator resistance
  gMotorVars.Rs_Ohm = EST_getRs_Ohm(obj->estHandle);

  // get the stator inductance in the direct coordinate direction
  gMotorVars.Lsd_H = EST_getLs_d_H(obj->estHandle);

  // get the stator inductance in the quadrature coordinate direction
  gMotorVars.Lsq_H = EST_getLs_q_H(obj->estHandle);

  // get the flux in V/Hz in floating point
  gMotorVars.Flux_VpHz = EST_getFlux_VpHz(obj->estHandle);

  // get the flux in Wb in fixed point
  gMotorVars.Flux_Wb = USER_computeFlux(handle, gFlux_pu_to_Wb_sf);

  // get the controller state
  gMotorVars.CtrlState = CTRL_getState(handle);

  // get the estimator state
  gMotorVars.EstState = EST_getState(obj->estHandle);

  // Get the DC buss voltage
  gMotorVars.VdcBus_kV = _IQmpy(gAdcData.dcBus,_IQ(USER_IQ_FULL_SCALE_VOLTAGE_V/1000.0));

  // get the Iq reference from the speed controller
  gMotorVars.IqRef_A = _IQmpy(STVELCTL_getTorqueReference(stObj->velCtlHandle), _IQ(USER_IQ_FULL_SCALE_CURRENT_A));

  // gets the Velocity Controller status
  gMotorVars.SpinTAC.VelCtlStatus = STVELCTL_getStatus(stObj->velCtlHandle);

  // get the inertia setting
  gMotorVars.SpinTAC.InertiaEstimate_Aperkrpm = _IQmpy(STVELCTL_getInertia(stObj->velCtlHandle), _IQ(ST_SPEED_PU_PER_KRPM * USER_IQ_FULL_SCALE_CURRENT_A));

  // get the friction setting
  gMotorVars.SpinTAC.FrictionEstimate_Aperkrpm = _IQmpy(STVELCTL_getFriction(stObj->velCtlHandle), _IQ(ST_SPEED_PU_PER_KRPM * USER_IQ_FULL_SCALE_CURRENT_A));

  // get the Velocity Controller error
  gMotorVars.SpinTAC.VelCtlErrorID = STVELCTL_getErrorID(stObj->velCtlHandle);

  return;
} // end of updateGlobalVariables_motor() function


void updateKpKiGains(CTRL_Handle handle)
{
  if((gMotorVars.CtrlState == CTRL_State_OnLine) && (gMotorVars.Flag_MotorIdentified == true) && (Flag_Latch_softwareUpdate == false))
    {
      // set the kp and ki speed values from the watch window
      CTRL_setKp(handle,CTRL_Type_PID_spd,gMotorVars.Kp_spd);
      CTRL_setKi(handle,CTRL_Type_PID_spd,gMotorVars.Ki_spd);

      // set the kp and ki current values for Id and Iq from the watch window
      CTRL_setKp(handle,CTRL_Type_PID_Id,gMotorVars.Kp_Idq);
      CTRL_setKi(handle,CTRL_Type_PID_Id,gMotorVars.Ki_Idq);
      CTRL_setKp(handle,CTRL_Type_PID_Iq,gMotorVars.Kp_Idq);
      CTRL_setKi(handle,CTRL_Type_PID_Iq,gMotorVars.Ki_Idq);
	}

  return;
} // end of updateKpKiGains() function


void ST_runVelCtl(ST_Handle handle, CTRL_Handle ctrlHandle)
{

    _iq speedFeedback, iqReference;
    ST_Obj *stObj = (ST_Obj *)handle;
    CTRL_Obj *ctrlObj = (CTRL_Obj *)ctrlHandle;

    // Get the mechanical speed in pu
    speedFeedback = EST_getFm_pu(ctrlObj->estHandle);

	// Run the SpinTAC Controller
	// Note that the library internal ramp generator is used to set the speed reference
    STVELCTL_setVelocityReference(stObj->velCtlHandle, TRAJ_getIntValue(ctrlObj->trajHandle_spd));
	STVELCTL_setAccelerationReference(stObj->velCtlHandle, _IQ(0.0));	// Internal ramp generator does not provide Acceleration Reference
	STVELCTL_setVelocityFeedback(stObj->velCtlHandle, speedFeedback);
	STVELCTL_run(stObj->velCtlHandle);

	// select SpinTAC Velocity Controller
	iqReference = STVELCTL_getTorqueReference(stObj->velCtlHandle);

	// Set the Iq reference that came out of SpinTAC Velocity Control
	CTRL_setIq_ref_pu(ctrlHandle, iqReference);
}


//@} //defgroup
// end of file

  • Ayushi,

    Thank you for creating a post. However, I think it will be very challenging to adequately support you with what you have shared. Generally, just posting code is not going to be beneficial to you or us in supporting you. It looks like this might even just be the entire lab file from Motorware? If you are going to include that much code, it would be much better to attach the code as a file attachment to the post.

    Please see the following link for asking new questions on e2e. e2e.ti.com/.../1156.04-how-to-post-a-new-question-on-e2e Providing detailed summaries of your issue, including debug steps you have tried, any specific details that you do not understand, or any specific questions you have will be more beneficial than just dumping code and saying that it doesn't work, while asking us to fix it. We are here to help you debug your issues, not to just solve them for you.

    I will notify our motor team to help you, but it would be much easier if you can reply with additional information along with any questions you have.

    Thanks,
    Mark
  • /* --COPYRIGHT--,BSD
     * Copyright (c) 2012, LineStream Technologies Incorporated
     * Copyright (c) 2012, Texas Instruments Incorporated
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions
     * are met:
     *
     * *  Redistributions of source code must retain the above copyright
     *    notice, this list of conditions and the following disclaimer.
     *
     * *  Redistributions in binary form must reproduce the above copyright
     *    notice, this list of conditions and the following disclaimer in the
     *    documentation and/or other materials provided with the distribution.
     *
    * *  Neither the names of Texas Instruments Incorporated, LineStream
     *    Technologies Incorporated, nor the names of its contributors may be
     *    used to endorse or promote products derived from this software without
     *    specific prior written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
     * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     * --/COPYRIGHT--*/
    //! \file   solutions/instaspin_motion/src/proj_lab05d.c
    //! \brief  InstaSPIN-MOTION SpinTAC Speed Controller
    //!
    //! (C) Copyright 2012, LineStream Technologies, Inc.
    //! (C) Copyright 2011, Texas Instruments, Inc.
    
    //! \defgroup PROJ_LAB05d PROJ_LAB05d
    //@{
    
    //! \defgroup PROJ_LAB05d_OVERVIEW Project Overview
    //!
    //! Running the SpinTAC Velocity Controller
    //!
    
    // **************************************************************************
    // the includes
    
    // system includes
    #include <math.h>
    #include "main.h"
    //#include "DSP28x_Project.h"     // Device Headerfile and Examples Include File
    //#include "stdio.h"
    //#include "sw/drivers/can/src/32b/f28x/f2806x/can.h"
    
    //#pragma DATA_SECTION(ECanaRegs,"ECanaRegsFile");
    
    //volatile struct ECAN_REGS ECanaRegs;
    
    //#pragma DATA_SECTION(ECanaMboxes,"ECanaMboxesFile");
    
    //volatile struct ECAN_MBOXES ECanaMboxes;
    
    
    #ifdef FLASH
    #pragma CODE_SECTION(mainISR,"ramfuncs");
    #endif
    
    // Include header files used in the main function
    
    
    // ************************************************************************
    // the defines
    
    #define LED_BLINK_FREQ_Hz   5
    
    
    // **************************************************************************
    // the globals
    
    uint_least16_t gCounter_updateGlobals = 0;
    
    bool Flag_Latch_softwareUpdate = true;
    
    CTRL_Handle ctrlHandle;
    
    HAL_Handle halHandle;
    
    USER_Params gUserParams;
    
    HAL_PwmData_t gPwmData = {_IQ(0.0), _IQ(0.0), _IQ(0.0)};
    
    HAL_AdcData_t gAdcData;
    
    _iq gMaxCurrentSlope = _IQ(0.0);
    
    
    
    #ifdef FAST_ROM_V1p6
    CTRL_Obj *controller_obj;
    #else
    CTRL_Obj ctrl;				//v1p7 format
    #endif
    
    ST_Obj st_obj;
    ST_Handle stHandle;
    
    uint16_t gLEDcnt = 0;
    
    volatile MOTOR_Vars_t gMotorVars = MOTOR_Vars_INIT;
    
    #ifdef FLASH
    // Used for running BackGround in flash, and ISR in RAM
    extern uint16_t *RamfuncsLoadStart, *RamfuncsLoadEnd, *RamfuncsRunStart;
    #endif
    
    
    #ifdef DRV8301_SPI
    // Watch window interface to the 8301 SPI
    DRV_SPI_8301_Vars_t gDrvSpi8301Vars;
    #endif
    #ifdef DRV8305_SPI
    // Watch window interface to the 8305 SPI
    DRV_SPI_8305_Vars_t gDrvSpi8305Vars;
    #endif
    
    _iq gFlux_pu_to_Wb_sf;
    
    _iq gFlux_pu_to_VpHz_sf;
    
    _iq gTorque_Ls_Id_Iq_pu_to_Nm_sf;
    
    _iq gTorque_Flux_Iq_pu_to_Nm_sf;
    
    // **************************************************************************
    // In future declare variables over here
    void InitECana(void);
    void InitECanaGpio(void);
    void spi_init(void);
    
    void spi_fifo_init(void);
    void delay(float n);
    
    unsigned long spi_xmit(unsigned long  a);
    Uint16 sdata=0x0000;  // s3end data
    Uint16 rdata1=0;  // received data
    Uint16 rdata2=0;
    Uint16 rdata3=0;
    Uint16 rdata4=0;
    Uint16 rdata5=0;
    Uint16 rdata6=0;
    Uint32 byte7=0;
    Uint32 fbyte3=0;
    Uint16 fbyte4=0;
    Uint32 fibyte3=0;
    Uint32 fiibyte3=0;
    Uint32 fibyte4=0;
    Uint32 fibyte5=0;
    long i;
    //long loopcount=0;
    //volatile struct ECAN_REGS ECanaShadow;
    void main(void)
    {
    
    	//struct ECAN_REGS ECanaShadow;
        uint_least8_t estNumber = 0;
    
    #ifdef FAST_ROM_V1p6
      uint_least8_t ctrlNumber = 0;
    #endif
    
      // Only used if running from FLASH
      // Note that the variable FLASH is defined by the project
      #ifdef FLASH
      // Copy time critical code and Flash setup code to RAM
      // The RamfuncsLoadStart, RamfuncsLoadEnd, and RamfuncsRunStart
      // symbols are created by the linker. Refer to the linker files.
      memCopy((uint16_t *)&RamfuncsLoadStart,(uint16_t *)&RamfuncsLoadEnd,(uint16_t *)&RamfuncsRunStart);
      #endif
    
      // initialize the hardware abstraction layer
      halHandle = HAL_init(&hal,sizeof(hal));
    
    
      // check for errors in user parameters
      USER_checkForErrors(&gUserParams);
    
    
      // store user parameter error in global variable
      gMotorVars.UserErrorCode = USER_getErrorCode(&gUserParams);
    
    
      // do not allow code execution if there is a user parameter error
      if(gMotorVars.UserErrorCode != USER_ErrorCode_NoError)
        {
          for(;;)
            {
              gMotorVars.Flag_enableSys = false;
            }
        }
    
    
      // initialize the user parameters
      USER_setParams(&gUserParams);
    
    
      // set the hardware abstraction layer parameters
      HAL_setParams(halHandle,&gUserParams);
    
    
      // initialize the controller
    #ifdef FAST_ROM_V1p6
      ctrlHandle = CTRL_initCtrl(ctrlNumber, estNumber);  		//v1p6 format (06xF and 06xM devices)
      controller_obj = (CTRL_Obj *)ctrlHandle;
    #else
      ctrlHandle = CTRL_initCtrl(estNumber,&ctrl,sizeof(ctrl));	//v1p7 format default
    #endif
    
    
      {
        CTRL_Version version;
    
        // get the version number
        CTRL_getVersion(ctrlHandle,&version);
    
        gMotorVars.CtrlVersion = version;
      }
    
    
      // set the default controller parameters
      CTRL_setParams(ctrlHandle,&gUserParams);
    
    
      // setup faults
      HAL_setupFaults(halHandle);
    
    
      // initialize the interrupt vector table
      HAL_initIntVectorTable(halHandle);
    
    
      // enable the ADC interrupts
      HAL_enableAdcInts(halHandle);
    
    
      // enable global interrupts
      HAL_enableGlobalInts(halHandle);
    
    
      // enable debug interrupts
      HAL_enableDebugInt(halHandle);
    
    
      // disable the PWM
      HAL_disablePwm(halHandle);
    
    
      // initialize the SpinTAC Components
      stHandle = ST_init(&st_obj, sizeof(st_obj));
    
    
      // setup the SpinTAC Components
      ST_setupVelCtl(stHandle);
    
    
    #ifdef DRV8301_SPI
      // turn on the DRV8301 if present
      HAL_enableDrv(halHandle);
      // initialize the DRV8301 interface
      HAL_setupDrvSpi(halHandle,&gDrvSpi8301Vars);
    #endif
    
    #ifdef DRV8305_SPI
      // turn on the DRV8305 if present
      HAL_enableDrv(halHandle);
      // initialize the DRV8305 interface
      HAL_setupDrvSpi(halHandle,&gDrvSpi8305Vars);
    #endif
    
      // enable DC bus compensation
        CTRL_setFlag_enableDcBusComp(ctrlHandle, true);
    
    
        // compute scaling factors for flux and torque calculations
        gFlux_pu_to_Wb_sf = USER_computeFlux_pu_to_Wb_sf();
        gFlux_pu_to_VpHz_sf = USER_computeFlux_pu_to_VpHz_sf();
        gTorque_Ls_Id_Iq_pu_to_Nm_sf = USER_computeTorque_Ls_Id_Iq_pu_to_Nm_sf();
        gTorque_Flux_Iq_pu_to_Nm_sf = USER_computeTorque_Flux_Iq_pu_to_Nm_sf();
    
        InitSysCtrl();
    
    
    
     // EALLOW;
      // InitECana();
     // InitECanaGpio();
      EALLOW;
      /* Write to the MSGID field  */
    
    
       //   ECanaMboxes.MBOX25.MSGID.all = 0x95555555;
    
     // EDIS;
    
      // Configure Mailbox under test as a Transmit mailbox
    
     // 	ECanaShadow.CANMD.all = ECanaRegs.CANMD.all;
      	//ECanaShadow.CANMD.bit.MD25 = 0;
      //	ECanaRegs.CANMD.all = ECanaShadow.CANMD.all;
    
    
      	// Enable Mailbox under test
    
      	//	ECanaShadow.CANME.all = ECanaRegs.CANME.all;
      	//	ECanaShadow.CANME.bit.ME25 = 1;
      	//	ECanaRegs.CANME.all = ECanaShadow.CANME.all;
    
    
      /* Write to DLC field in Message Control reg */
    
     // ECanaMboxes.MBOX25.MSGCTRL.bit.DLC = 8;
    
    
    
    
    
    
    
    
     void spi_init(void);
    
      for(;;)
      {
    	  // Waiting for enable system flag to be set
    	      while(!(gMotorVars.Flag_enableSys));
    
    	      // Dis-able the Library internal PI.  Iq has no reference now
    	      CTRL_setFlag_enableSpeedCtrl(ctrlHandle, false);
    
    	      // loop while the enable system flag is true
    	      while(gMotorVars.Flag_enableSys)
    	        {
    	          CTRL_Obj *obj = (CTRL_Obj *)ctrlHandle;
    	          ST_Obj *stObj = (ST_Obj *)stHandle;
    
    	          // increment counters
    	          gCounter_updateGlobals++;
    
    	          // enable/disable the use of motor parameters being loaded from user.h
    	          CTRL_setFlag_enableUserMotorParams(ctrlHandle,gMotorVars.Flag_enableUserParams);
    
    	          // enable/disable Rs recalibration during motor startup
    	       //   EST_setFlag_enableRsRecalc(obj->estHandle,gMotorVars.Flag_enableRsRecalc);
    
    	          // enable/disable automatic calculation of bias values
    	          CTRL_setFlag_enableOffset(ctrlHandle,gMotorVars.Flag_enableOffsetcalc);
    
    
    	          if(CTRL_isError(ctrlHandle))
    	            {
    	              // set the enable controller flag to false
    	              CTRL_setFlag_enableCtrl(ctrlHandle,false);
    
    	              // set the enable system flag to false
    	              gMotorVars.Flag_enableSys = false;
    
    	              // disable the PWM
    	              HAL_disablePwm(halHandle);
    	            }
    	          else
    	            {
    	              // update the controller state
    	              bool flag_ctrlStateChanged = CTRL_updateState(ctrlHandle);
    
    	              // enable or disable the control
    	              CTRL_setFlag_enableCtrl(ctrlHandle, gMotorVars.Flag_Run_Identify);
    
    	              if(flag_ctrlStateChanged)
    	                {
    	                  CTRL_State_e ctrlState = CTRL_getState(ctrlHandle);
    
    	                  if(ctrlState == CTRL_State_OffLine)
    	                    {
    	                      // enable the PWM
    	                      HAL_enablePwm(halHandle);
    	                    }
    	                  else if(ctrlState == CTRL_State_OnLine)
    	                    {
    	                      if(gMotorVars.Flag_enableOffsetcalc == true)
    	                      {
    	                        // update the ADC bias values
    	                        HAL_updateAdcBias(halHandle);
    	                      }
    	                      else
    	                      {
    	                        // set the current bias
    	                        HAL_setBias(halHandle,HAL_SensorType_Current,0,_IQ(I_A_offset));
    	                        HAL_setBias(halHandle,HAL_SensorType_Current,1,_IQ(I_B_offset));
    	                        HAL_setBias(halHandle,HAL_SensorType_Current,2,_IQ(I_C_offset));
    
    	                        // set the voltage bias
    	                        HAL_setBias(halHandle,HAL_SensorType_Voltage,0,_IQ(V_A_offset));
    	                        HAL_setBias(halHandle,HAL_SensorType_Voltage,1,_IQ(V_B_offset));
    	                        HAL_setBias(halHandle,HAL_SensorType_Voltage,2,_IQ(V_C_offset));
    	                      }
    
    	                      // Return the bias value for currents
    	                      gMotorVars.I_bias.value[0] = HAL_getBias(halHandle,HAL_SensorType_Current,0);
    	                      gMotorVars.I_bias.value[1] = HAL_getBias(halHandle,HAL_SensorType_Current,1);
    	                      gMotorVars.I_bias.value[2] = HAL_getBias(halHandle,HAL_SensorType_Current,2);
    
    	                      // Return the bias value for voltages
    	                      gMotorVars.V_bias.value[0] = HAL_getBias(halHandle,HAL_SensorType_Voltage,0);
    	                      gMotorVars.V_bias.value[1] = HAL_getBias(halHandle,HAL_SensorType_Voltage,1);
    	                      gMotorVars.V_bias.value[2] = HAL_getBias(halHandle,HAL_SensorType_Voltage,2);
    
    	                      // enable the PWM
    	                      HAL_enablePwm(halHandle);
    	                    }
    	                  else if(ctrlState == CTRL_State_Idle)
    	                    {
    	                      // disable the PWM
    	                      HAL_disablePwm(halHandle);
    	                      gMotorVars.Flag_Run_Identify = false;
    	                    }
    
    	                  if((CTRL_getFlag_enableUserMotorParams(ctrlHandle) == true) &&
    	                    (ctrlState > CTRL_State_Idle) &&
    	                    (gMotorVars.CtrlVersion.minor == 6))
    	                    {
    	                      // call this function to fix 1p6
    	                      USER_softwareUpdate1p6(ctrlHandle);
    	                    }
    
    	                }
    	            }
    
    
    	          if(EST_isMotorIdentified(obj->estHandle))
    	            {
    	              // set the current ramp
    	              EST_setMaxCurrentSlope_pu(obj->estHandle,gMaxCurrentSlope);
    	              gMotorVars.Flag_MotorIdentified = true;
    
    	              // set the speed reference
    	              CTRL_setSpd_ref_krpm(ctrlHandle,gMotorVars.SpeedRef_krpm);
    
    	              // set the speed acceleration
    	              CTRL_setMaxAccel_pu(ctrlHandle,_IQmpy(MAX_ACCEL_KRPMPS_SF,gMotorVars.MaxAccel_krpmps));
    
    	              // enable the SpinTAC Speed Controller
    	              STVELCTL_setEnable(stObj->velCtlHandle, true);
    
    	              if(EST_getState(obj->estHandle) != EST_State_OnLine)
    	              {
    	              	// if the estimator is not running, place SpinTAC into reset
    	              	STVELCTL_setEnable(stObj->velCtlHandle, false);
    	              }
    
    	              if(Flag_Latch_softwareUpdate)
    	              {
    	                Flag_Latch_softwareUpdate = false;
    
    	                USER_calcPIgains(ctrlHandle);
    
    	                // initialize the watch window kp and ki current values with pre-calculated values
    	                gMotorVars.Kp_Idq = CTRL_getKp(ctrlHandle,CTRL_Type_PID_Id);
    	                gMotorVars.Ki_Idq = CTRL_getKi(ctrlHandle,CTRL_Type_PID_Id);
    
    	                // initialize the watch window with maximum and minimum Iq reference
    	                gMotorVars.SpinTAC.VelCtlOutputMax_A = _IQmpy(STVELCTL_getOutputMaximum(stObj->velCtlHandle), _IQ(USER_IQ_FULL_SCALE_CURRENT_A));
    	                gMotorVars.SpinTAC.VelCtlOutputMin_A = _IQmpy(STVELCTL_getOutputMinimum(stObj->velCtlHandle), _IQ(USER_IQ_FULL_SCALE_CURRENT_A));
    	              }
    
    	            }
    	          else
    	            {
    	              Flag_Latch_softwareUpdate = true;
    
    	              // the estimator sets the maximum current slope during identification
    	              gMaxCurrentSlope = EST_getMaxCurrentSlope_pu(obj->estHandle);
    	            }
    
    
    	          // when appropriate, update the global variables
    	          if(gCounter_updateGlobals >= NUM_MAIN_TICKS_FOR_GLOBAL_VARIABLE_UPDATE)
    	            {
    	              // reset the counter
    	              gCounter_updateGlobals = 0;
    
    	              updateGlobalVariables_motor(ctrlHandle, stHandle);
    	            }
    
    
    	          // update Kp and Ki gains
    	          updateKpKiGains(ctrlHandle);
    
    	          // set the maximum and minimum values for Iq reference
    	          STVELCTL_setOutputMaximums(stObj->velCtlHandle, _IQmpy(gMotorVars.SpinTAC.VelCtlOutputMax_A, _IQ(1.0/USER_IQ_FULL_SCALE_CURRENT_A)), _IQmpy(gMotorVars.SpinTAC.VelCtlOutputMin_A, _IQ(1.0/USER_IQ_FULL_SCALE_CURRENT_A)));
    
    	          // enable/disable the forced angle
    	          EST_setFlag_enableForceAngle(obj->estHandle,gMotorVars.Flag_enableForceAngle);
    
    	          // enable or disable power warp
    	          CTRL_setFlag_enablePowerWarp(ctrlHandle,gMotorVars.Flag_enablePowerWarp);
    
    	  #ifdef DRV8301_SPI
    	          HAL_writeDrvData(halHandle,&gDrvSpi8301Vars);
    
    	          HAL_readDrvData(halHandle,&gDrvSpi8301Vars);
    	  #endif
    	  #ifdef DRV8305_SPI
    	          HAL_writeDrvData(halHandle,&gDrvSpi8305Vars);
    
    	          HAL_readDrvData(halHandle,&gDrvSpi8305Vars);
    	  #endif
    	        } // end of while(gFlag_enableSys) loop
    
    
    	      // disable the PWM
    	      HAL_disablePwm(halHandle);
    
    	      // set the default controller parameters (Reset the control to re-identify the motor)
    	      CTRL_setParams(ctrlHandle,&gUserParams);
    	      gMotorVars.Flag_Run_Identify = false;
    
    	      // setup the SpinTAC Components
    	      ST_setupVelCtl(stHandle);
    
    
    
    
    
    
    
    } // end of for(;;) loop
    //  asm(" ESTOP0");
    } // end of main() function
    
    
    interrupt void mainISR(void)
    {
    
      static uint16_t stCnt = 0;
    
      // toggle status LED
      if(++gLEDcnt >= (uint_least32_t)(USER_ISR_FREQ_Hz / LED_BLINK_FREQ_Hz))
      {
        HAL_toggleLed(halHandle,(GPIO_Number_e)HAL_Gpio_LED2);
        gLEDcnt = 0;
      }
    
    
      // acknowledge the ADC interrupt
      HAL_acqAdcInt(halHandle,ADC_IntNumber_1);
    
    
      // convert the ADC data
      HAL_readAdcData(halHandle,&gAdcData);
    
    
      // Run the SpinTAC Components
      if(stCnt++ >= ISR_TICKS_PER_SPINTAC_TICK) {
    	  ST_runVelCtl(stHandle, ctrlHandle);
    	  stCnt = 1;
      }
    
    
    
      // run the controller
      CTRL_run(ctrlHandle,halHandle,&gAdcData,&gPwmData);
    
    
      // write the PWM compare values
      HAL_writePwmData(halHandle,&gPwmData);
    
    
      // setup the controller
      CTRL_setup(ctrlHandle);
      // Transmit data
    
            spi_xmit(sdata);
             // Wait until data is received
             while(SpiaRegs.SPIFFRX.bit.RXFFST !=1) { }
    
            // while(SpiaRegs.SPISTS.bit.INT_FLAG !=1) { }
             // Check against sent data
             rdata1 = SpiaRegs.SPIRXBUF ;
             delay(10);
             spi_xmit(sdata);
                  // Wait until data is received
             while(SpiaRegs.SPIFFRX.bit.RXFFST !=1) { }
                  //while(SpiaRegs.SPISTS.bit.INT_FLAG !=1) { }
                  // Check against sent data
             rdata2 = SpiaRegs.SPIRXBUF  ;
             delay(10);
             spi_xmit(sdata);
                  // Wait until data is received
             while(SpiaRegs.SPIFFRX.bit.RXFFST !=1) { }
                  //while(SpiaRegs.SPISTS.bit.INT_FLAG !=1) { }
                  // Check against sent data
             rdata3 = SpiaRegs.SPIRXBUF ;
             delay(10);
             spi_xmit(sdata);
                       // Wait until data is received
             while(SpiaRegs.SPIFFRX.bit.RXFFST !=1) { }
                       //while(SpiaRegs.SPISTS.bit.INT_FLAG !=1) { }
                       // Check against sent data
             rdata4 = SpiaRegs.SPIRXBUF;
             delay(10);
             spi_xmit(sdata);
                            // Wait until data is received
             while(SpiaRegs.SPIFFRX.bit.RXFFST !=1) { }
                            //while(SpiaRegs.SPISTS.bit.INT_FLAG !=1) { }
                            // Check against sent data
             rdata5 = SpiaRegs.SPIRXBUF ;
             delay(10);
             spi_xmit(sdata);
                                 // Wait until data is received
             while(SpiaRegs.SPIFFRX.bit.RXFFST !=1) { }
                                 //while(SpiaRegs.SPISTS.bit.INT_FLAG !=1) { }
                                 // Check against sent data
             rdata6 = SpiaRegs.SPIRXBUF ;
             delay(10);
                                       fbyte3  = rdata3 & 0x03;
                                       fibyte3 = fbyte3<< 0x08;
                                       fiibyte3= fibyte3<<0x08;
                                       fbyte4  = rdata4<< 0x08;
                                       fibyte4 = fiibyte3 | fbyte4;
                                       fibyte5 = (rdata5 | fibyte4);
                                       byte7   = (fibyte5*360)/262144;// position data
    
    
                                   //    ECanaMboxes.MBOX25.MDL.all = byte7;
                                   //    ECanaMboxes.MBOX25.MDH.all = 0x00000000;
    
    
    
    
      return;
    } // end of mainISR() function
    asm(" ESTOP0");
    
    
    void spi_init()
    {
    	SpiaRegs.SPICCR.all =0x0007;	             // Reset on, rising edge, 16-bit char bits
    	SpiaRegs.SPICTL.all =0x0007;    		     // Enable master mode, normal phase,
                                                     // enable talk, and SPI int disabled.
    	SpiaRegs.SPIBRR =0X0004;
        SpiaRegs.SPICCR.all =0x00C7;		         // Relinquish SPI from Reset
        SpiaRegs.SPIPRI.bit.FREE = 1;                // Set so breakpoints don't disturb xmission
    
    
    }
    
    /*void InitECanaGpio(void)
    {
       EALLOW;
    
    /* Enable internal pull-up for the selected CAN pins */
    // Pull-ups can be enabled or disabled by the user.
    // This will enable the pullups for the specified pins.
    // Comment out other unwanted lines.
    
       /*GpioCtrlRegs.GPAPUD.bit.GPIO30 = 0;     // Enable pull-up for GPIO30 (CANRXA)
       GpioCtrlRegs.GPAPUD.bit.GPIO31 = 0;     // Enable pull-up for GPIO31 (CANTXA)
    
    /* Set qualification for selected CAN pins to asynch only */
    // Inputs are synchronized to SYSCLKOUT by default.
    // This will select asynch (no qualification) for the selected pins.
    
     /*   GpioCtrlRegs.GPAQSEL2.bit.GPIO30 = 3;   // Asynch qual for GPIO30 (CANRXA)
        GpioCtrlRegs.GPAQSEL2.bit.GPIO31 = 3;   // Asynch qual for GPIO31 (CANTXA)
    /* Configure eCAN-A pins using GPIO regs*/
    // This specifies which of the possible GPIO pins will be eCAN functional pins.
    
     /*   GpioCtrlRegs.GPAMUX2.bit.GPIO30 = 1;    // Configure GPIO30 for CANRXA operation
        GpioCtrlRegs.GPAMUX2.bit.GPIO31 = 1;    // Configure GPIO31 for CANTXA operation
    
        EDIS;
    }
    void InitECana(void)        // Initialize eCAN-A module
    {
    
    /* Create a shadow register structure for the CAN control registers. This is
     needed, since only 32-bit access is allowed to these registers. 16-bit access
     to these registers could potentially corrupt the register contents or return
     false data. */
    
    /*	struct ECAN_REGS ECanaShadow;
    
        EALLOW;     // EALLOW enables access to protected bits
    
    /* Configure eCAN RX and TX pins for CAN operation using eCAN regs*/
    
     /*   ECanaShadow.CANTIOC.all = ECanaRegs.CANTIOC.all;
        ECanaShadow.CANTIOC.bit.TXFUNC = 1;
        ECanaRegs.CANTIOC.all = ECanaShadow.CANTIOC.all;
    
        ECanaShadow.CANRIOC.all = ECanaRegs.CANRIOC.all;
        ECanaShadow.CANRIOC.bit.RXFUNC = 1;
        ECanaRegs.CANRIOC.all = ECanaShadow.CANRIOC.all;
    
    /* Configure eCAN for HECC mode - (reqd to access mailboxes 16 thru 31) */
                                        // HECC mode also enables time-stamping feature
    
    /*    ECanaShadow.CANMC.all = ECanaRegs.CANMC.all;
        ECanaShadow.CANMC.bit.SCB = 1;
        ECanaRegs.CANMC.all = ECanaShadow.CANMC.all;
    
    /* Initialize all bits of 'Message Control Register' to zero */
    // Some bits of MSGCTRL register come up in an unknown state. For proper operation,
    // all bits (including reserved bits) of MSGCTRL must be initialized to zero
    
      /*  ECanaMboxes.MBOX0.MSGCTRL.all = 0x00000000;
        ECanaMboxes.MBOX1.MSGCTRL.all = 0x00000000;
        ECanaMboxes.MBOX2.MSGCTRL.all = 0x00000000;
        ECanaMboxes.MBOX3.MSGCTRL.all = 0x00000000;
        ECanaMboxes.MBOX4.MSGCTRL.all = 0x00000000;
        ECanaMboxes.MBOX5.MSGCTRL.all = 0x00000000;
        ECanaMboxes.MBOX6.MSGCTRL.all = 0x00000000;
        ECanaMboxes.MBOX7.MSGCTRL.all = 0x00000000;
        ECanaMboxes.MBOX8.MSGCTRL.all = 0x00000000;
        ECanaMboxes.MBOX9.MSGCTRL.all = 0x00000000;
        ECanaMboxes.MBOX10.MSGCTRL.all = 0x00000000;
        ECanaMboxes.MBOX11.MSGCTRL.all = 0x00000000;
        ECanaMboxes.MBOX12.MSGCTRL.all = 0x00000000;
        ECanaMboxes.MBOX13.MSGCTRL.all = 0x00000000;
        ECanaMboxes.MBOX14.MSGCTRL.all = 0x00000000;
        ECanaMboxes.MBOX15.MSGCTRL.all = 0x00000000;
        ECanaMboxes.MBOX16.MSGCTRL.all = 0x00000000;
        ECanaMboxes.MBOX17.MSGCTRL.all = 0x00000000;
        ECanaMboxes.MBOX18.MSGCTRL.all = 0x00000000;
        ECanaMboxes.MBOX19.MSGCTRL.all = 0x00000000;
        ECanaMboxes.MBOX20.MSGCTRL.all = 0x00000000;
        ECanaMboxes.MBOX21.MSGCTRL.all = 0x00000000;
        ECanaMboxes.MBOX22.MSGCTRL.all = 0x00000000;
        ECanaMboxes.MBOX23.MSGCTRL.all = 0x00000000;
        ECanaMboxes.MBOX24.MSGCTRL.all = 0x00000000;
        ECanaMboxes.MBOX25.MSGCTRL.all = 0x00000000;
        ECanaMboxes.MBOX26.MSGCTRL.all = 0x00000000;
        ECanaMboxes.MBOX27.MSGCTRL.all = 0x00000000;
        ECanaMboxes.MBOX28.MSGCTRL.all = 0x00000000;
        ECanaMboxes.MBOX29.MSGCTRL.all = 0x00000000;
        ECanaMboxes.MBOX30.MSGCTRL.all = 0x00000000;
        ECanaMboxes.MBOX31.MSGCTRL.all = 0x00000000;
    
    // TAn, RMPn, GIFn bits are all zero upon reset and are cleared again
    //  as a matter of precaution.
    
        ECanaRegs.CANTA.all = 0xFFFFFFFF;   /* Clear all TAn bits */
    
     /*   ECanaRegs.CANRMP.all = 0xFFFFFFFF;  /* Clear all RMPn bits */
    
     /*   ECanaRegs.CANGIF0.all = 0xFFFFFFFF; /* Clear all interrupt flag bits */
    /*    ECanaRegs.CANGIF1.all = 0xFFFFFFFF;
    
    /* Configure bit timing parameters for eCANA*/
    
     /*   ECanaShadow.CANMC.all = ECanaRegs.CANMC.all;
        ECanaShadow.CANMC.bit.CCR = 1 ;            // Set CCR = 1
        ECanaRegs.CANMC.all = ECanaShadow.CANMC.all;
    
        // Wait until the CPU has been granted permission to change the configuration registers
        do
        {
          ECanaShadow.CANES.all = ECanaRegs.CANES.all;
        } while(ECanaShadow.CANES.bit.CCE != 1 );       // Wait for CCE bit to be set..
    
        ECanaShadow.CANBTC.all = 0;
        /* The following block is for 80 MHz SYSCLKOUT. (40 MHz CAN module clock Bit rate = 1 Mbps
           See Note at end of file. */
        //ECanaShadow.CANBTC.all =  0x000503BD;   // 500k
     /*   ECanaShadow.CANBTC.bit.BRPREG = 1;
        ECanaShadow.CANBTC.bit.TSEG2REG = 2;//4
        ECanaShadow.CANBTC.bit.TSEG1REG = 10;//13
    
        ECanaShadow.CANBTC.bit.SAM = 0;
       // ECanaShadow.CANME.bit.SJW = 4;
        ECanaRegs.CANBTC.all = ECanaShadow.CANBTC.all;
    
        ECanaShadow.CANMC.all = ECanaRegs.CANMC.all;
        ECanaShadow.CANMC.bit.CCR = 0 ;            // Set CCR = 0
        ECanaRegs.CANMC.all = ECanaShadow.CANMC.all;
    
        // Wait until the CPU no longer has permission to change the configuration registers
        do
        {
          ECanaShadow.CANES.all = ECanaRegs.CANES.all;
        } while(ECanaShadow.CANES.bit.CCE != 0 );       // Wait for CCE bit to be  cleared..
    
    /* Disable all Mailboxes  */
       /* ECanaRegs.CANME.all = 0;        // Required before writing the MSGIDs
    
        EDIS;
    }*/
    
    void spi_fifo_init()
    {
    // Initialize SPI FIFO registers
        SpiaRegs.SPIFFTX.all=0xE040;
        SpiaRegs.SPIFFRX.all=0x2044;
        SpiaRegs.SPIFFCT.all=0x0;
    }
    void delay(float n)
    {
       short      i;
        for (i = 0; i < n; i++) {}
    }
    unsigned long spi_xmit(unsigned long a)
    {
       SpiaRegs.SPITXBUF=a<<8;
        return a;
    }
    void updateGlobalVariables_motor(CTRL_Handle handle, ST_Handle sthandle)
    {
      CTRL_Obj *obj = (CTRL_Obj *)handle;
      ST_Obj *stObj = (ST_Obj *)sthandle;
    
    
      // get the speed estimate
      gMotorVars.Speed_krpm = EST_getSpeed_krpm(obj->estHandle);
    
      // get the real time speed reference coming out of the speed trajectory generator
      gMotorVars.SpeedTraj_krpm = _IQmpy(CTRL_getSpd_int_ref_pu(handle),EST_get_pu_to_krpm_sf(obj->estHandle));
    
      // get the torque estimate
      gMotorVars.Torque_Nm = USER_computeTorque_Nm(handle, gTorque_Flux_Iq_pu_to_Nm_sf, gTorque_Ls_Id_Iq_pu_to_Nm_sf);
    
      // get the magnetizing current
      gMotorVars.MagnCurr_A = EST_getIdRated(obj->estHandle);
    
      // get the rotor resistance
      gMotorVars.Rr_Ohm = EST_getRr_Ohm(obj->estHandle);
    
      // get the stator resistance
      gMotorVars.Rs_Ohm = EST_getRs_Ohm(obj->estHandle);
    
      // get the stator inductance in the direct coordinate direction
      gMotorVars.Lsd_H = EST_getLs_d_H(obj->estHandle);
    
      // get the stator inductance in the quadrature coordinate direction
      gMotorVars.Lsq_H = EST_getLs_q_H(obj->estHandle);
    
      // get the flux in V/Hz in floating point
      gMotorVars.Flux_VpHz = EST_getFlux_VpHz(obj->estHandle);
    
      // get the flux in Wb in fixed point
      gMotorVars.Flux_Wb = USER_computeFlux(handle, gFlux_pu_to_Wb_sf);
    
      // get the controller state
      gMotorVars.CtrlState = CTRL_getState(handle);
    
      // get the estimator state
      gMotorVars.EstState = EST_getState(obj->estHandle);
    
      // Get the DC buss voltage
      gMotorVars.VdcBus_kV = _IQmpy(gAdcData.dcBus,_IQ(USER_IQ_FULL_SCALE_VOLTAGE_V/1000.0));
    
      // get the Iq reference from the speed controller
      gMotorVars.IqRef_A = _IQmpy(STVELCTL_getTorqueReference(stObj->velCtlHandle), _IQ(USER_IQ_FULL_SCALE_CURRENT_A));
    
      // gets the Velocity Controller status
      gMotorVars.SpinTAC.VelCtlStatus = STVELCTL_getStatus(stObj->velCtlHandle);
    
      // get the inertia setting
      gMotorVars.SpinTAC.InertiaEstimate_Aperkrpm = _IQmpy(STVELCTL_getInertia(stObj->velCtlHandle), _IQ(ST_SPEED_PU_PER_KRPM * USER_IQ_FULL_SCALE_CURRENT_A));
    
      // get the friction setting
      gMotorVars.SpinTAC.FrictionEstimate_Aperkrpm = _IQmpy(STVELCTL_getFriction(stObj->velCtlHandle), _IQ(ST_SPEED_PU_PER_KRPM * USER_IQ_FULL_SCALE_CURRENT_A));
    
      // get the Velocity Controller error
      gMotorVars.SpinTAC.VelCtlErrorID = STVELCTL_getErrorID(stObj->velCtlHandle);
    
      return;
    } // end of updateGlobalVariables_motor() function
    
    
    void updateKpKiGains(CTRL_Handle handle)
    {
      if((gMotorVars.CtrlState == CTRL_State_OnLine) && (gMotorVars.Flag_MotorIdentified == true) && (Flag_Latch_softwareUpdate == false))
        {
          // set the kp and ki speed values from the watch window
          CTRL_setKp(handle,CTRL_Type_PID_spd,gMotorVars.Kp_spd);
          CTRL_setKi(handle,CTRL_Type_PID_spd,gMotorVars.Ki_spd);
    
          // set the kp and ki current values for Id and Iq from the watch window
          CTRL_setKp(handle,CTRL_Type_PID_Id,gMotorVars.Kp_Idq);
          CTRL_setKi(handle,CTRL_Type_PID_Id,gMotorVars.Ki_Idq);
          CTRL_setKp(handle,CTRL_Type_PID_Iq,gMotorVars.Kp_Idq);
          CTRL_setKi(handle,CTRL_Type_PID_Iq,gMotorVars.Ki_Idq);
    	}
    
      return;
    } // end of updateKpKiGains() function
    
    
    void ST_runVelCtl(ST_Handle handle, CTRL_Handle ctrlHandle)
    {
    
        _iq speedFeedback, iqReference;
        ST_Obj *stObj = (ST_Obj *)handle;
        CTRL_Obj *ctrlObj = (CTRL_Obj *)ctrlHandle;
    
        // Get the mechanical speed in pu
        speedFeedback = EST_getFm_pu(ctrlObj->estHandle);
    
    	// Run the SpinTAC Controller
    	// Note that the library internal ramp generator is used to set the speed reference
        STVELCTL_setVelocityReference(stObj->velCtlHandle, TRAJ_getIntValue(ctrlObj->trajHandle_spd));
    	STVELCTL_setAccelerationReference(stObj->velCtlHandle, _IQ(0.0));	// Internal ramp generator does not provide Acceleration Reference
    	STVELCTL_setVelocityFeedback(stObj->velCtlHandle, speedFeedback);
    	STVELCTL_run(stObj->velCtlHandle);
    
    	// select SpinTAC Velocity Controller
    	iqReference = STVELCTL_getTorqueReference(stObj->velCtlHandle);
    
    	// Set the Iq reference that came out of SpinTAC Velocity Control
    	CTRL_setIq_ref_pu(ctrlHandle, iqReference);
    }
    
    
    //@} //defgroup
    // end of file
    

  • This is lab05d from Instaspin , I have tested SPI and CAN by including in the same code.
    Right now in the attached file I have commented out CAN code , so it can be easily debug.
    Initially I was able to identify motor and control speed with this lab before adding CAN communication code.

    Problem I am facing is gmotorVars. CtrlState always remains Idle .
    I tried to debug and noticed that it doesnot work beyond

    int_least8_t lShift = ceil(log(obj->motorParams.Ls_d_H/(Ls_coarse_max*fullScaleInductance))/log(2.0));

    in USER_softwareUpdate1p6(ctrlHandle); function
  • /* --COPYRIGHT--,BSDhghhhfh
     * Copyright (c) 2012, Texas Instruments Incorporated
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions
     * are met:
     *
     * *  Redistributions of source code must retain the above copyright
     *    notice, this list of conditions and the following disclaimer.
     *
     * *  Redistributions in binary form must reproduce the above copyright
     *    notice, this list of conditions and the following disclaimer in the
     *    documentation and/or other materials provided with the distribution.
     *
     * *  Neither the name of Texas Instruments Incorporated nor the names of
     *    its contributors may be used to endorse or promote products derived
     *    from this software without specific prior written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
     * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     * --/COPYRIGHT--*/
    //! \file   solutions/instaspin_foc/boards/drv8301kit_revD/f28x/f2806xF/src/hal.c
    //! \brief Contains the various functions related to the HAL object (everything outside the CTRL system) 
    //!
    //! (C) Copyright 2011, Texas Instruments, Inc.
    
    
    // **************************************************************************
    // the includes
    
    // drivers
    
    // modules
    
    // platforms
    #include "hal.h"
    #include "sw/solutions/instaspin_motion/boards/drv8301kit_revD/f28x/f2806xM/src/user.h"
    #include "hal_obj.h"
    #include "F2806x_Device.h"
    //#include "F2806x_ECan.h"
    //#include"can.h"
    #ifdef FLASH
    #pragma CODE_SECTION(HAL_setupFlash,"ramfuncs");
    #endif
    
    // **************************************************************************
    // the defines
    
    #define US_TO_CNT(A) ((((long double) A * (long double)USER_SYSTEM_FREQ_MHz) - 9.0L) / 5.0L)
    
    // **************************************************************************
    // the globals
    
    HAL_Obj hal;
    
    
    // **************************************************************************
    // the functions
    
    void HAL_cal(HAL_Handle handle)
    {
      HAL_Obj *obj = (HAL_Obj *)handle;
    
    
      // enable the ADC clock
      CLK_enableAdcClock(obj->clkHandle);
    
    
      // Run the Device_cal() function
      // This function copies the ADC and oscillator calibration values from TI reserved
      // OTP into the appropriate trim registers
      // This boot ROM automatically calls this function to calibrate the interal 
      // oscillators and ADC with device specific calibration data.
      // If the boot ROM is bypassed by Code Composer Studio during the development process,
      // then the calibration must be initialized by the application
      ENABLE_PROTECTED_REGISTER_WRITE_MODE;
      (*Device_cal)();
      DISABLE_PROTECTED_REGISTER_WRITE_MODE;
    
      // run offsets calibration in user's memory
      HAL_AdcOffsetSelfCal(handle);
    
      // run oscillator compensation
      HAL_OscTempComp(handle);
    
      // disable the ADC clock
      CLK_disableAdcClock(obj->clkHandle);
    
      return;
    } // end of HAL_cal() function
    
    
    void HAL_OscTempComp(HAL_Handle handle)
    {
      HAL_Obj *obj = (HAL_Obj *)handle;
      uint16_t Temperature;
    
      // disable the ADCs
      ADC_disable(obj->adcHandle);
    
      // power up the bandgap circuit
      ADC_enableBandGap(obj->adcHandle);
    
      // set the ADC voltage reference source to internal
      ADC_setVoltRefSrc(obj->adcHandle,ADC_VoltageRefSrc_Int);
    
      // enable the ADC reference buffers
      ADC_enableRefBuffers(obj->adcHandle);
    
      // Set main clock scaling factor (max45MHz clock for the ADC module)
      ADC_setDivideSelect(obj->adcHandle,ADC_DivideSelect_ClkIn_by_2);
    
      // power up the ADCs
      ADC_powerUp(obj->adcHandle);
    
      // enable the ADCs
      ADC_enable(obj->adcHandle);
    
      // enable non-overlap mode
      ADC_enableNoOverlapMode(obj->adcHandle);
    
      // connect channel A5 internally to the temperature sensor
      ADC_setTempSensorSrc(obj->adcHandle, ADC_TempSensorSrc_Int);
    
      // set SOC0 channel select to ADCINA5
      ADC_setSocChanNumber(obj->adcHandle, ADC_SocNumber_0, ADC_SocChanNumber_A5);
    
      // set SOC0 acquisition period to 26 ADCCLK
      ADC_setSocSampleDelay(obj->adcHandle, ADC_SocNumber_0, ADC_SocSampleDelay_64_cycles);
    
      // connect ADCINT1 to EOC0
      ADC_setIntSrc(obj->adcHandle, ADC_IntNumber_1, ADC_IntSrc_EOC0);
    
      // clear ADCINT1 flag
      ADC_clearIntFlag(obj->adcHandle, ADC_IntNumber_1);
    
      // enable ADCINT1
      ADC_enableInt(obj->adcHandle, ADC_IntNumber_1);
    
      // force start of conversion on SOC0
      ADC_setSocFrc(obj->adcHandle, ADC_SocFrc_0);
    
      // wait for end of conversion
      while (ADC_getIntFlag(obj->adcHandle, ADC_IntNumber_1) == 0){}
    
      // clear ADCINT1 flag
      ADC_clearIntFlag(obj->adcHandle, ADC_IntNumber_1);
    
      Temperature = ADC_readResult(obj->adcHandle, ADC_ResultNumber_0);
    
      HAL_osc1Comp(handle, Temperature);
    
      HAL_osc2Comp(handle, Temperature);
    
      return;
    } // end of HAL_OscTempComp() function
    
    
    void HAL_osc1Comp(HAL_Handle handle, const int16_t sensorSample)
    {
    	int16_t compOscFineTrim;
    	HAL_Obj *obj = (HAL_Obj *)handle;
    
    	ENABLE_PROTECTED_REGISTER_WRITE_MODE;
    
        compOscFineTrim = ((sensorSample - getRefTempOffset())*(int32_t)getOsc1FineTrimSlope()
                          + OSC_POSTRIM_OFF + FP_ROUND )/FP_SCALE + getOsc1FineTrimOffset() - OSC_POSTRIM;
    
        if(compOscFineTrim > 31)
          {
            compOscFineTrim = 31;
          }
    	else if(compOscFineTrim < -31)
          {
            compOscFineTrim = -31;
          }
    
        OSC_setTrim(obj->oscHandle, OSC_Number_1, HAL_getOscTrimValue(getOsc1CoarseTrim(), compOscFineTrim));
    
        DISABLE_PROTECTED_REGISTER_WRITE_MODE;
    
        return;
    } // end of HAL_osc1Comp() function
    
    
    void HAL_osc2Comp(HAL_Handle handle, const int16_t sensorSample)
    {
    	int16_t compOscFineTrim;
    	HAL_Obj *obj = (HAL_Obj *)handle;
    
    	ENABLE_PROTECTED_REGISTER_WRITE_MODE;
    
        compOscFineTrim = ((sensorSample - getRefTempOffset())*(int32_t)getOsc2FineTrimSlope()
                          + OSC_POSTRIM_OFF + FP_ROUND )/FP_SCALE + getOsc2FineTrimOffset() - OSC_POSTRIM;
    
        if(compOscFineTrim > 31)
          {
            compOscFineTrim = 31;
          }
    	else if(compOscFineTrim < -31)
          {
            compOscFineTrim = -31;
          }
    
        OSC_setTrim(obj->oscHandle, OSC_Number_2, HAL_getOscTrimValue(getOsc2CoarseTrim(), compOscFineTrim));
    
        DISABLE_PROTECTED_REGISTER_WRITE_MODE;
    
        return;
    } // end of HAL_osc2Comp() function
    
    
    uint16_t HAL_getOscTrimValue(int16_t coarse, int16_t fine)
    {
      uint16_t regValue = 0;
    
      if(fine < 0)
        {
          regValue = ((-fine) | 0x20) << 9;
        }
      else
        {
          regValue = fine << 9;
        }
    
      if(coarse < 0)
        {
          regValue |= ((-coarse) | 0x80);
        }
      else
        {
          regValue |= coarse;
        }
    
      return regValue;
    } // end of HAL_getOscTrimValue() function
    
    
    void HAL_AdcOffsetSelfCal(HAL_Handle handle)
    {
      HAL_Obj *obj = (HAL_Obj *)handle;
      uint16_t AdcConvMean;
    
      // disable the ADCs
      ADC_disable(obj->adcHandle);
    
      // power up the bandgap circuit
      ADC_enableBandGap(obj->adcHandle);
    
      // set the ADC voltage reference source to internal
      ADC_setVoltRefSrc(obj->adcHandle,ADC_VoltageRefSrc_Int);
    
      // enable the ADC reference buffers
      ADC_enableRefBuffers(obj->adcHandle);
    
      // Set main clock scaling factor (max45MHz clock for the ADC module)
      ADC_setDivideSelect(obj->adcHandle,ADC_DivideSelect_ClkIn_by_2);
    
      // power up the ADCs
      ADC_powerUp(obj->adcHandle);
    
      // enable the ADCs
      ADC_enable(obj->adcHandle);
    
      //Select VREFLO internal connection on B5
      ADC_enableVoltRefLoConv(obj->adcHandle);
    
      //Select channel B5 for all SOC
      HAL_AdcCalChanSelect(handle, ADC_SocChanNumber_B5);
    
      //Apply artificial offset (+80) to account for a negative offset that may reside in the ADC core
      ADC_setOffTrim(obj->adcHandle, 80);
    
      //Capture ADC conversion on VREFLO
      AdcConvMean = HAL_AdcCalConversion(handle);
    
      //Set offtrim register with new value (i.e remove artical offset (+80) and create a two's compliment of the offset error)
      ADC_setOffTrim(obj->adcHandle, 80 - AdcConvMean);
    
      //Select external ADCIN5 input pin on B5
      ADC_disableVoltRefLoConv(obj->adcHandle);
    
      return;
    } // end of HAL_AdcOffsetSelfCal() function
    
    
    void HAL_AdcCalChanSelect(HAL_Handle handle, const ADC_SocChanNumber_e chanNumber)
    {
      HAL_Obj *obj = (HAL_Obj *)handle;
    
      ADC_setSocChanNumber(obj->adcHandle,ADC_SocNumber_0,chanNumber);
      ADC_setSocChanNumber(obj->adcHandle,ADC_SocNumber_1,chanNumber);
      ADC_setSocChanNumber(obj->adcHandle,ADC_SocNumber_2,chanNumber);
      ADC_setSocChanNumber(obj->adcHandle,ADC_SocNumber_3,chanNumber);
      ADC_setSocChanNumber(obj->adcHandle,ADC_SocNumber_4,chanNumber);
      ADC_setSocChanNumber(obj->adcHandle,ADC_SocNumber_5,chanNumber);
      ADC_setSocChanNumber(obj->adcHandle,ADC_SocNumber_6,chanNumber);
      ADC_setSocChanNumber(obj->adcHandle,ADC_SocNumber_7,chanNumber);
      ADC_setSocChanNumber(obj->adcHandle,ADC_SocNumber_8,chanNumber);
      ADC_setSocChanNumber(obj->adcHandle,ADC_SocNumber_9,chanNumber);
      ADC_setSocChanNumber(obj->adcHandle,ADC_SocNumber_10,chanNumber);
      ADC_setSocChanNumber(obj->adcHandle,ADC_SocNumber_11,chanNumber);
      ADC_setSocChanNumber(obj->adcHandle,ADC_SocNumber_12,chanNumber);
      ADC_setSocChanNumber(obj->adcHandle,ADC_SocNumber_13,chanNumber);
      ADC_setSocChanNumber(obj->adcHandle,ADC_SocNumber_14,chanNumber);
      ADC_setSocChanNumber(obj->adcHandle,ADC_SocNumber_15,chanNumber);
    
      return;
    } // end of HAL_AdcCalChanSelect() function
    
    
    uint16_t HAL_AdcCalConversion(HAL_Handle handle)
    {
      HAL_Obj *obj = (HAL_Obj *)handle;
      uint16_t index, SampleSize, Mean;
      uint32_t Sum;
      ADC_SocSampleDelay_e ACQPS_Value;
    
      index       = 0;     //initialize index to 0
      SampleSize  = 256;   //set sample size to 256 (**NOTE: Sample size must be multiples of 2^x where is an integer >= 4)
      Sum         = 0;     //set sum to 0
      Mean        = 999;   //initialize mean to known value
    
      //Set the ADC sample window to the desired value (Sample window = ACQPS + 1)
      ACQPS_Value = ADC_SocSampleDelay_7_cycles;
    
      ADC_setSocSampleDelay(obj->adcHandle,ADC_SocNumber_0,ACQPS_Value);
      ADC_setSocSampleDelay(obj->adcHandle,ADC_SocNumber_1,ACQPS_Value);
      ADC_setSocSampleDelay(obj->adcHandle,ADC_SocNumber_2,ACQPS_Value);
      ADC_setSocSampleDelay(obj->adcHandle,ADC_SocNumber_3,ACQPS_Value);
      ADC_setSocSampleDelay(obj->adcHandle,ADC_SocNumber_4,ACQPS_Value);
      ADC_setSocSampleDelay(obj->adcHandle,ADC_SocNumber_5,ACQPS_Value);
      ADC_setSocSampleDelay(obj->adcHandle,ADC_SocNumber_6,ACQPS_Value);
      ADC_setSocSampleDelay(obj->adcHandle,ADC_SocNumber_7,ACQPS_Value);
      ADC_setSocSampleDelay(obj->adcHandle,ADC_SocNumber_8,ACQPS_Value);
      ADC_setSocSampleDelay(obj->adcHandle,ADC_SocNumber_9,ACQPS_Value);
      ADC_setSocSampleDelay(obj->adcHandle,ADC_SocNumber_10,ACQPS_Value);
      ADC_setSocSampleDelay(obj->adcHandle,ADC_SocNumber_11,ACQPS_Value);
      ADC_setSocSampleDelay(obj->adcHandle,ADC_SocNumber_12,ACQPS_Value);
      ADC_setSocSampleDelay(obj->adcHandle,ADC_SocNumber_13,ACQPS_Value);
      ADC_setSocSampleDelay(obj->adcHandle,ADC_SocNumber_14,ACQPS_Value);
      ADC_setSocSampleDelay(obj->adcHandle,ADC_SocNumber_15,ACQPS_Value);
    
      // Enabled ADCINT1 and ADCINT2
      ADC_enableInt(obj->adcHandle, ADC_IntNumber_1);
      ADC_enableInt(obj->adcHandle, ADC_IntNumber_2);
    
      // Disable continuous sampling for ADCINT1 and ADCINT2
      ADC_setIntMode(obj->adcHandle, ADC_IntNumber_1, ADC_IntMode_EOC);
      ADC_setIntMode(obj->adcHandle, ADC_IntNumber_2, ADC_IntMode_EOC);
    
      //ADCINTs trigger at end of conversion
      ADC_setIntPulseGenMode(obj->adcHandle, ADC_IntPulseGenMode_Prior);
    
      // Setup ADCINT1 and ADCINT2 trigger source
      ADC_setIntSrc(obj->adcHandle, ADC_IntNumber_1, ADC_IntSrc_EOC6);
      ADC_setIntSrc(obj->adcHandle, ADC_IntNumber_2, ADC_IntSrc_EOC14);
    
      // Setup each SOC's ADCINT trigger source
      ADC_setupSocTrigSrc(obj->adcHandle, ADC_SocNumber_0, ADC_Int2TriggersSOC);
      ADC_setupSocTrigSrc(obj->adcHandle, ADC_SocNumber_1, ADC_Int2TriggersSOC);
      ADC_setupSocTrigSrc(obj->adcHandle, ADC_SocNumber_2, ADC_Int2TriggersSOC);
      ADC_setupSocTrigSrc(obj->adcHandle, ADC_SocNumber_3, ADC_Int2TriggersSOC);
      ADC_setupSocTrigSrc(obj->adcHandle, ADC_SocNumber_4, ADC_Int2TriggersSOC);
      ADC_setupSocTrigSrc(obj->adcHandle, ADC_SocNumber_5, ADC_Int2TriggersSOC);
      ADC_setupSocTrigSrc(obj->adcHandle, ADC_SocNumber_6, ADC_Int2TriggersSOC);
      ADC_setupSocTrigSrc(obj->adcHandle, ADC_SocNumber_7, ADC_Int2TriggersSOC);
      ADC_setupSocTrigSrc(obj->adcHandle, ADC_SocNumber_8, ADC_Int1TriggersSOC);
      ADC_setupSocTrigSrc(obj->adcHandle, ADC_SocNumber_9, ADC_Int1TriggersSOC);
      ADC_setupSocTrigSrc(obj->adcHandle, ADC_SocNumber_10, ADC_Int1TriggersSOC);
      ADC_setupSocTrigSrc(obj->adcHandle, ADC_SocNumber_11, ADC_Int1TriggersSOC);
      ADC_setupSocTrigSrc(obj->adcHandle, ADC_SocNumber_12, ADC_Int1TriggersSOC);
      ADC_setupSocTrigSrc(obj->adcHandle, ADC_SocNumber_13, ADC_Int1TriggersSOC);
      ADC_setupSocTrigSrc(obj->adcHandle, ADC_SocNumber_14, ADC_Int1TriggersSOC);
      ADC_setupSocTrigSrc(obj->adcHandle, ADC_SocNumber_15, ADC_Int1TriggersSOC);
    
      // Delay before converting ADC channels
      usDelay(US_TO_CNT(ADC_DELAY_usec));
    
      ADC_setSocFrcWord(obj->adcHandle, 0x00FF);
    
      while( index < SampleSize )
        {
          //Wait for ADCINT1 to trigger, then add ADCRESULT0-7 registers to sum
          while (ADC_getIntFlag(obj->adcHandle, ADC_IntNumber_1) == 0){}
    
          //Must clear ADCINT1 flag since INT1CONT = 0
          ADC_clearIntFlag(obj->adcHandle, ADC_IntNumber_1);
    
          Sum += ADC_readResult(obj->adcHandle, ADC_ResultNumber_0);
          Sum += ADC_readResult(obj->adcHandle, ADC_ResultNumber_1);
          Sum += ADC_readResult(obj->adcHandle, ADC_ResultNumber_2);
          Sum += ADC_readResult(obj->adcHandle, ADC_ResultNumber_3);
          Sum += ADC_readResult(obj->adcHandle, ADC_ResultNumber_4);
          Sum += ADC_readResult(obj->adcHandle, ADC_ResultNumber_5);
          Sum += ADC_readResult(obj->adcHandle, ADC_ResultNumber_6);
          Sum += ADC_readResult(obj->adcHandle, ADC_ResultNumber_7);
    
          //Wait for ADCINT2 to trigger, then add ADCRESULT8-15 registers to sum
          while (ADC_getIntFlag(obj->adcHandle, ADC_IntNumber_2) == 0){}
    
          //Must clear ADCINT2 flag since INT2CONT = 0
          ADC_clearIntFlag(obj->adcHandle, ADC_IntNumber_2);
    
          Sum += ADC_readResult(obj->adcHandle, ADC_ResultNumber_8);
          Sum += ADC_readResult(obj->adcHandle, ADC_ResultNumber_9);
          Sum += ADC_readResult(obj->adcHandle, ADC_ResultNumber_10);
          Sum += ADC_readResult(obj->adcHandle, ADC_ResultNumber_11);
          Sum += ADC_readResult(obj->adcHandle, ADC_ResultNumber_12);
          Sum += ADC_readResult(obj->adcHandle, ADC_ResultNumber_13);
          Sum += ADC_readResult(obj->adcHandle, ADC_ResultNumber_14);
          Sum += ADC_readResult(obj->adcHandle, ADC_ResultNumber_15);
    
          index+=16;
    
      } // end data collection
    
      //Disable ADCINT1 and ADCINT2 to STOP the ping-pong sampling
      ADC_disableInt(obj->adcHandle, ADC_IntNumber_1);
      ADC_disableInt(obj->adcHandle, ADC_IntNumber_2);
    
      //Calculate average ADC sample value
      Mean = Sum / SampleSize;
    
      // Clear start of conversion trigger
      ADC_setupSocTrigSrc(obj->adcHandle, ADC_SocNumber_0, ADC_NoIntTriggersSOC);
      ADC_setupSocTrigSrc(obj->adcHandle, ADC_SocNumber_1, ADC_NoIntTriggersSOC);
      ADC_setupSocTrigSrc(obj->adcHandle, ADC_SocNumber_2, ADC_NoIntTriggersSOC);
      ADC_setupSocTrigSrc(obj->adcHandle, ADC_SocNumber_3, ADC_NoIntTriggersSOC);
      ADC_setupSocTrigSrc(obj->adcHandle, ADC_SocNumber_4, ADC_NoIntTriggersSOC);
      ADC_setupSocTrigSrc(obj->adcHandle, ADC_SocNumber_5, ADC_NoIntTriggersSOC);
      ADC_setupSocTrigSrc(obj->adcHandle, ADC_SocNumber_6, ADC_NoIntTriggersSOC);
      ADC_setupSocTrigSrc(obj->adcHandle, ADC_SocNumber_7, ADC_NoIntTriggersSOC);
      ADC_setupSocTrigSrc(obj->adcHandle, ADC_SocNumber_8, ADC_NoIntTriggersSOC);
      ADC_setupSocTrigSrc(obj->adcHandle, ADC_SocNumber_9, ADC_NoIntTriggersSOC);
      ADC_setupSocTrigSrc(obj->adcHandle, ADC_SocNumber_10, ADC_NoIntTriggersSOC);
      ADC_setupSocTrigSrc(obj->adcHandle, ADC_SocNumber_11, ADC_NoIntTriggersSOC);
      ADC_setupSocTrigSrc(obj->adcHandle, ADC_SocNumber_12, ADC_NoIntTriggersSOC);
      ADC_setupSocTrigSrc(obj->adcHandle, ADC_SocNumber_13, ADC_NoIntTriggersSOC);
      ADC_setupSocTrigSrc(obj->adcHandle, ADC_SocNumber_14, ADC_NoIntTriggersSOC);
      ADC_setupSocTrigSrc(obj->adcHandle, ADC_SocNumber_15, ADC_NoIntTriggersSOC);
    
      //return the average
      return(Mean);
    } // end of HAL_AdcCalConversion() function
    
    
    void HAL_disableWdog(HAL_Handle halHandle)
    {
      HAL_Obj *hal = (HAL_Obj *)halHandle;
    
    
      WDOG_disable(hal->wdogHandle);
    
    
      return;
    } // end of HAL_disableWdog() function
    
    
    void HAL_disableGlobalInts(HAL_Handle handle)
    {
      HAL_Obj *obj = (HAL_Obj *)handle;
    
    
      CPU_disableGlobalInts(obj->cpuHandle);
    
      return;
    } // end of HAL_disableGlobalInts() function
    
    
    void HAL_enableAdcInts(HAL_Handle handle)
    {
      HAL_Obj *obj = (HAL_Obj *)handle;
    
    
      // enable the PIE interrupts associated with the ADC interrupts
      PIE_enableAdcInt(obj->pieHandle,ADC_IntNumber_1);
    
    
      // enable the ADC interrupts
      ADC_enableInt(obj->adcHandle,ADC_IntNumber_1);
    
    
      // enable the cpu interrupt for ADC interrupts
      CPU_enableInt(obj->cpuHandle,CPU_IntNumber_10);
    
      return;
    } // end of HAL_enableAdcInts() function
    
    
    void HAL_enableDebugInt(HAL_Handle handle)
    {
      HAL_Obj *obj = (HAL_Obj *)handle;
    
    
      CPU_enableDebugInt(obj->cpuHandle);
    
      return;
    } // end of HAL_enableDebugInt() function
    
    
    void HAL_enableDrv(HAL_Handle handle)
    {
      HAL_Obj *obj = (HAL_Obj *)handle;
    
      DRV8301_enable(obj->drv8301Handle);
    
      return;
    }  // end of HAL_enableDrv() function
    
    
    void HAL_enableGlobalInts(HAL_Handle handle)
    {
      HAL_Obj *obj = (HAL_Obj *)handle;
    
    
      CPU_enableGlobalInts(obj->cpuHandle);
    
      return;
    } // end of HAL_enableGlobalInts() function
    
    
    void HAL_enablePwmInt(HAL_Handle handle)
    {
      HAL_Obj *obj = (HAL_Obj *)handle;
    
    
      PIE_enablePwmInt(obj->pieHandle,PWM_Number_1);
    
    
      // enable the interrupt
      PWM_enableInt(obj->pwmHandle[PWM_Number_1]);
    
    
      // enable the cpu interrupt for EPWM1_INT
      CPU_enableInt(obj->cpuHandle,CPU_IntNumber_3);
    
      return;
    } // end of HAL_enablePwmInt() function
    
    
    void HAL_enableTimer0Int(HAL_Handle handle)
    {
      HAL_Obj *obj = (HAL_Obj *)handle;
    
    
      PIE_enableTimer0Int(obj->pieHandle);
    
    
      // enable the interrupt
      TIMER_enableInt(obj->timerHandle[0]);
    
    
      // enable the cpu interrupt for TINT0
      CPU_enableInt(obj->cpuHandle,CPU_IntNumber_1);
    
      return;
    } // end of HAL_enablePwmInt() function
    
    
    void HAL_setupFaults(HAL_Handle handle)
    {
      HAL_Obj *obj = (HAL_Obj *)handle;
      uint_least8_t cnt;
    
    
      // Configure Trip Mechanism for the Motor control software
      // -Cycle by cycle trip on CPU halt
      // -One shot fault trip zone
      // These trips need to be repeated for EPWM1 ,2 & 3
      for(cnt=0;cnt<3;cnt++)
        {
          PWM_enableTripZoneSrc(obj->pwmHandle[cnt],PWM_TripZoneSrc_CycleByCycle_TZ6_NOT);
    
          PWM_enableTripZoneSrc(obj->pwmHandle[cnt],PWM_TripZoneSrc_CycleByCycle_TZ3_NOT);
    
          PWM_enableTripZoneSrc(obj->pwmHandle[cnt],PWM_TripZoneSrc_CycleByCycle_TZ2_NOT);
    
          // What do we want the OST/CBC events to do?
          // TZA events can force EPWMxA
          // TZB events can force EPWMxB
    
          PWM_setTripZoneState_TZA(obj->pwmHandle[cnt],PWM_TripZoneState_EPWM_Low);
          PWM_setTripZoneState_TZB(obj->pwmHandle[cnt],PWM_TripZoneState_EPWM_Low);
        }
    
      return;
    } // end of HAL_setupFaults() function
    
    
    HAL_Handle HAL_init(void *pMemory,const size_t numBytes)
    {
      uint_least8_t cnt;
      HAL_Handle handle;
      HAL_Obj *obj;
    
    
      if(numBytes < sizeof(HAL_Obj))
        return((HAL_Handle)NULL);
    
    
      // assign the handle
      handle = (HAL_Handle)pMemory;
    
    
      // assign the object
      obj = (HAL_Obj *)handle;
    
    
      // initialize the watchdog driver
      obj->wdogHandle = WDOG_init((void *)WDOG_BASE_ADDR,sizeof(WDOG_Obj));
    
    
      // disable watchdog
      HAL_disableWdog(handle);
    
    
      // initialize the ADC
      obj->adcHandle = ADC_init((void *)ADC_BASE_ADDR,sizeof(ADC_Obj));
    
    
      // initialize the clock handle
      obj->clkHandle = CLK_init((void *)CLK_BASE_ADDR,sizeof(CLK_Obj));
    
    
      // initialize the CPU handle
      obj->cpuHandle = CPU_init(&cpu,sizeof(cpu));
    
    
      // initialize the FLASH handle
      obj->flashHandle = FLASH_init((void *)FLASH_BASE_ADDR,sizeof(FLASH_Obj));
    
    
      // initialize the GPIO handle
      obj->gpioHandle = GPIO_init((void *)GPIO_BASE_ADDR,sizeof(GPIO_Obj));
    
    
      // initialize the current offset estimator handles
      for(cnt=0;cnt<USER_NUM_CURRENT_SENSORS;cnt++)
        {
          obj->offsetHandle_I[cnt] = OFFSET_init(&obj->offset_I[cnt],sizeof(obj->offset_I[cnt]));
        }
    
    
      // initialize the voltage offset estimator handles
      for(cnt=0;cnt<USER_NUM_VOLTAGE_SENSORS;cnt++)
        {
          obj->offsetHandle_V[cnt] = OFFSET_init(&obj->offset_V[cnt],sizeof(obj->offset_V[cnt]));
        }
    
    
      // initialize the oscillator handle
      obj->oscHandle = OSC_init((void *)OSC_BASE_ADDR,sizeof(OSC_Obj));
    
    
      // initialize the PIE handle
      obj->pieHandle = PIE_init((void *)PIE_BASE_ADDR,sizeof(PIE_Obj));
    
    
      // initialize the PLL handle
      obj->pllHandle = PLL_init((void *)PLL_BASE_ADDR,sizeof(PLL_Obj));
    
    
      // initialize the SPI handles
      obj->spiAHandle = SPI_init((void *)SPIA_BASE_ADDR,sizeof(SPI_Obj));
      obj->spiBHandle = SPI_init((void *)SPIB_BASE_ADDR,sizeof(SPI_Obj));
    
    
      // initialize PWM handles
      obj->pwmHandle[0] = PWM_init((void *)PWM_ePWM1_BASE_ADDR,sizeof(PWM_Obj));
      obj->pwmHandle[1] = PWM_init((void *)PWM_ePWM2_BASE_ADDR,sizeof(PWM_Obj));
      obj->pwmHandle[2] = PWM_init((void *)PWM_ePWM3_BASE_ADDR,sizeof(PWM_Obj));
    
    
      // initialize PWM DAC handles
      obj->pwmDacHandle[0] = PWMDAC_init((void *)PWM_ePWM6_BASE_ADDR,sizeof(PWM_Obj));
      obj->pwmDacHandle[1] = PWMDAC_init((void *)PWM_ePWM5_BASE_ADDR,sizeof(PWM_Obj));
      obj->pwmDacHandle[2] = PWMDAC_init((void *)PWM_ePWM4_BASE_ADDR,sizeof(PWM_Obj));
    
    
      // initialize power handle
      obj->pwrHandle = PWR_init((void *)PWR_BASE_ADDR,sizeof(PWR_Obj));
    
    
      // initialize timer handles
      obj->timerHandle[0] = TIMER_init((void *)TIMER0_BASE_ADDR,sizeof(TIMER_Obj));
      obj->timerHandle[1] = TIMER_init((void *)TIMER1_BASE_ADDR,sizeof(TIMER_Obj));
      obj->timerHandle[2] = TIMER_init((void *)TIMER2_BASE_ADDR,sizeof(TIMER_Obj));
    
    
      // initialize drv8301 interface
      obj->drv8301Handle = DRV8301_init(&obj->drv8301,sizeof(obj->drv8301));
    
    
    #ifdef QEP
      // initialize QEP driver
      obj->qepHandle[0] = QEP_init((void*)QEP1_BASE_ADDR,sizeof(QEP_Obj));
    #endif
    
      //obj->ecanaHandle = InitECana();
      return(handle);
    } // end of HAL_init() function
    
    //
    void HAL_setParams(HAL_Handle handle,const USER_Params *pUserParams)
    {
      uint_least8_t cnt;
      HAL_Obj *obj = (HAL_Obj *)handle;
      _iq beta_lp_pu = _IQ(pUserParams->offsetPole_rps/(float_t)pUserParams->ctrlFreq_Hz);
    
    
      HAL_setNumCurrentSensors(handle,pUserParams->numCurrentSensors);
      HAL_setNumVoltageSensors(handle,pUserParams->numVoltageSensors);
    
    
      for(cnt=0;cnt<HAL_getNumCurrentSensors(handle);cnt++)
        {
          HAL_setOffsetBeta_lp_pu(handle,HAL_SensorType_Current,cnt,beta_lp_pu);
          HAL_setOffsetInitCond(handle,HAL_SensorType_Current,cnt,_IQ(0.0));
          HAL_setOffsetValue(handle,HAL_SensorType_Current,cnt,_IQ(0.0));
        }
    
    
      for(cnt=0;cnt<HAL_getNumVoltageSensors(handle);cnt++)
        {
          HAL_setOffsetBeta_lp_pu(handle,HAL_SensorType_Voltage,cnt,beta_lp_pu);
          HAL_setOffsetInitCond(handle,HAL_SensorType_Voltage,cnt,_IQ(0.0));
          HAL_setOffsetValue(handle,HAL_SensorType_Voltage,cnt,_IQ(0.0));
        }
    
    
      // disable global interrupts
      CPU_disableGlobalInts(obj->cpuHandle);
    
    
      // disable cpu interrupts
      CPU_disableInts(obj->cpuHandle);
    
    
      // clear cpu interrupt flags
      CPU_clearIntFlags(obj->cpuHandle);
    
    
      // setup the clocks
      HAL_setupClks(handle);
    
    
      // Setup the PLL
      HAL_setupPll(handle,PLL_ClkFreq_90_MHz);
    
    
      // setup the PIE
      HAL_setupPie(handle);
    
    
      // run the device calibration
      HAL_cal(handle);
    
    
      // setup the peripheral clocks
      HAL_setupPeripheralClks(handle);
    
    
      // setup the GPIOs
      HAL_setupGpios(handle);
    
    
      // setup the flash
      HAL_setupFlash(handle);
    
    
      // setup the ADCs
      HAL_setupAdcs(handle);
    
      // setup eCAN
    //  HAL_setupECAN(handle);
    
      // setup the PWMs
      HAL_setupPwms(handle,
                    (float_t)pUserParams->systemFreq_MHz,
                    pUserParams->pwmPeriod_usec,
                    USER_NUM_PWM_TICKS_PER_ISR_TICK);
    
    #ifdef QEP
      // setup the QEP
      HAL_setupQEP(handle,HAL_Qep_QEP1);
    #endif
    
      // setup ecana
      //HAL_setupECAN(handle);
      // setup the spiA
      HAL_setupSpiA(handle);
    
    
      // setup the spiB
      HAL_setupSpiB(handle);
    
    
      // setup the PWM DACs
      HAL_setupPwmDacs(handle);
    
    
      // setup the timers
      HAL_setupTimers(handle,
                      (float_t)pUserParams->systemFreq_MHz);
    
    
      // setup the drv8301 interface
      HAL_setupGate(handle);
    
    
      // set the default current bias
     {
       uint_least8_t cnt;
       _iq bias = _IQ12mpy(ADC_dataBias,_IQ(pUserParams->current_sf));
       
       for(cnt=0;cnt<HAL_getNumCurrentSensors(handle);cnt++)
         {
           HAL_setBias(handle,HAL_SensorType_Current,cnt,bias);
         }
     }
    
    
      //  set the current scale factor
     {
       _iq current_sf = _IQ(pUserParams->current_sf);
    
      HAL_setCurrentScaleFactor(handle,current_sf);
     }
    
    
      // set the default voltage bias
     {
       uint_least8_t cnt;
       _iq bias = _IQ(0.0);
       
       for(cnt=0;cnt<HAL_getNumVoltageSensors(handle);cnt++)
         {
           HAL_setBias(handle,HAL_SensorType_Voltage,cnt,bias);
         }
     }
    
    
      //  set the voltage scale factor
     {
       _iq voltage_sf = _IQ(pUserParams->voltage_sf);
    
      HAL_setVoltageScaleFactor(handle,voltage_sf);
     }
    
     return;
    } // end of HAL_setParams() function
    
    
    void HAL_setupAdcs(HAL_Handle handle)
    {
      HAL_Obj *obj = (HAL_Obj *)handle;
    
    
      // disable the ADCs
      ADC_disable(obj->adcHandle);
    
    
      // power up the bandgap circuit
      ADC_enableBandGap(obj->adcHandle);
    
    
      // set the ADC voltage reference source to internal 
      ADC_setVoltRefSrc(obj->adcHandle,ADC_VoltageRefSrc_Int);
    
    
      // enable the ADC reference buffers
      ADC_enableRefBuffers(obj->adcHandle);
    
    
      // Set main clock scaling factor (max45MHz clock for the ADC module)
      ADC_setDivideSelect(obj->adcHandle,ADC_DivideSelect_ClkIn_by_2);
    
    
      // power up the ADCs
      ADC_powerUp(obj->adcHandle);
    
    
      // enable the ADCs
      ADC_enable(obj->adcHandle);
    
    
      // set the ADC interrupt pulse generation to prior
      ADC_setIntPulseGenMode(obj->adcHandle,ADC_IntPulseGenMode_Prior);
    
    
      // set the temperature sensor source to external
      ADC_setTempSensorSrc(obj->adcHandle,ADC_TempSensorSrc_Ext);
    
    
      // configure the interrupt sources
      ADC_disableInt(obj->adcHandle,ADC_IntNumber_1);
      ADC_setIntMode(obj->adcHandle,ADC_IntNumber_1,ADC_IntMode_ClearFlag);
      ADC_setIntSrc(obj->adcHandle,ADC_IntNumber_1,ADC_IntSrc_EOC7);
    
    
      //configure the SOCs for drv8301kit_revD
      // EXT IA-FB
      ADC_setSocChanNumber(obj->adcHandle,ADC_SocNumber_0,ADC_SocChanNumber_A6);
      ADC_setSocTrigSrc(obj->adcHandle,ADC_SocNumber_0,ADC_SocTrigSrc_EPWM1_ADCSOCA);
      ADC_setSocSampleDelay(obj->adcHandle,ADC_SocNumber_0,ADC_SocSampleDelay_9_cycles);
    
      // EXT IA-FB
      // Duplicate conversion due to ADC Initial Conversion bug (SPRZ342)
      ADC_setSocChanNumber(obj->adcHandle,ADC_SocNumber_1,ADC_SocChanNumber_A6);
      ADC_setSocTrigSrc(obj->adcHandle,ADC_SocNumber_1,ADC_SocTrigSrc_EPWM1_ADCSOCA);
      ADC_setSocSampleDelay(obj->adcHandle,ADC_SocNumber_1,ADC_SocSampleDelay_9_cycles);
    
      // EXT IB-FB
      ADC_setSocChanNumber(obj->adcHandle,ADC_SocNumber_2,ADC_SocChanNumber_B6);
      ADC_setSocTrigSrc(obj->adcHandle,ADC_SocNumber_2,ADC_SocTrigSrc_EPWM1_ADCSOCA);
      ADC_setSocSampleDelay(obj->adcHandle,ADC_SocNumber_2,ADC_SocSampleDelay_9_cycles);
    
      // EXT IC-FB
      ADC_setSocChanNumber(obj->adcHandle,ADC_SocNumber_3,ADC_SocChanNumber_A0);
      ADC_setSocTrigSrc(obj->adcHandle,ADC_SocNumber_3,ADC_SocTrigSrc_EPWM1_ADCSOCA);
      ADC_setSocSampleDelay(obj->adcHandle,ADC_SocNumber_3,ADC_SocSampleDelay_9_cycles);
    
      // ADC-Vhb1
      ADC_setSocChanNumber(obj->adcHandle,ADC_SocNumber_4,ADC_SocChanNumber_B7);
      ADC_setSocTrigSrc(obj->adcHandle,ADC_SocNumber_4,ADC_SocTrigSrc_EPWM1_ADCSOCA);
      ADC_setSocSampleDelay(obj->adcHandle,ADC_SocNumber_4,ADC_SocSampleDelay_9_cycles);
    
      // ADC-Vhb2
      ADC_setSocChanNumber(obj->adcHandle,ADC_SocNumber_5,ADC_SocChanNumber_A7);
      ADC_setSocTrigSrc(obj->adcHandle,ADC_SocNumber_5,ADC_SocTrigSrc_EPWM1_ADCSOCA);
      ADC_setSocSampleDelay(obj->adcHandle,ADC_SocNumber_5,ADC_SocSampleDelay_9_cycles);
    
      // ADC-Vhb3
      ADC_setSocChanNumber(obj->adcHandle,ADC_SocNumber_6,ADC_SocChanNumber_B4);
      ADC_setSocTrigSrc(obj->adcHandle,ADC_SocNumber_6,ADC_SocTrigSrc_EPWM1_ADCSOCA);
      ADC_setSocSampleDelay(obj->adcHandle,ADC_SocNumber_6,ADC_SocSampleDelay_9_cycles);
    
      // VDCBUS
      ADC_setSocChanNumber(obj->adcHandle,ADC_SocNumber_7,ADC_SocChanNumber_B2);
      ADC_setSocTrigSrc(obj->adcHandle,ADC_SocNumber_7,ADC_SocTrigSrc_EPWM1_ADCSOCA);
      ADC_setSocSampleDelay(obj->adcHandle,ADC_SocNumber_7,ADC_SocSampleDelay_9_cycles);
    
      return;
    } // end of HAL_setupAdcs() function
    
    
    void HAL_setupClks(HAL_Handle handle)
    {
      HAL_Obj *obj = (HAL_Obj *)handle;
    
    
      // enable internal oscillator 1
      CLK_enableOsc1(obj->clkHandle);
    
      // set the oscillator source
      CLK_setOscSrc(obj->clkHandle,CLK_OscSrc_Internal);
    
      // disable the external clock in
      CLK_disableClkIn(obj->clkHandle);
    
      // disable the crystal oscillator
      CLK_disableCrystalOsc(obj->clkHandle);
    
      // disable oscillator 2
      CLK_disableOsc2(obj->clkHandle);
    
      // set the low speed clock prescaler
      CLK_setLowSpdPreScaler(obj->clkHandle,CLK_LowSpdPreScaler_SysClkOut_by_1);
    
      // set the clock out prescaler
      CLK_setClkOutPreScaler(obj->clkHandle,CLK_ClkOutPreScaler_SysClkOut_by_1);
    
      return;
    } // end of HAL_setupClks() function
    
    
    void HAL_setupFlash(HAL_Handle handle)
    {
      HAL_Obj *obj = (HAL_Obj *)handle;
    
    
      FLASH_enablePipelineMode(obj->flashHandle);
    
      FLASH_setNumPagedReadWaitStates(obj->flashHandle,FLASH_NumPagedWaitStates_3);
    
      FLASH_setNumRandomReadWaitStates(obj->flashHandle,FLASH_NumRandomWaitStates_3);
    
      FLASH_setOtpWaitStates(obj->flashHandle,FLASH_NumOtpWaitStates_5);
    
      FLASH_setStandbyWaitCount(obj->flashHandle,FLASH_STANDBY_WAIT_COUNT_DEFAULT);
    
      FLASH_setActiveWaitCount(obj->flashHandle,FLASH_ACTIVE_WAIT_COUNT_DEFAULT);
    
      return;
    } // HAL_setupFlash() function
    
    
    void HAL_setupGate(HAL_Handle handle)
    {
      HAL_Obj *obj = (HAL_Obj *)handle;
    
      DRV8301_setSpiHandle(obj->drv8301Handle,obj->spiBHandle);
      DRV8301_setGpioHandle(obj->drv8301Handle,obj->gpioHandle);
      DRV8301_setGpioNumber(obj->drv8301Handle,GPIO_Number_51);
      
      return;
    } // HAL_setupGate() function
    
    
    void HAL_setupGpios(HAL_Handle handle)
    {
      HAL_Obj *obj = (HAL_Obj *)handle;
    
    
      // PWM1
      GPIO_setMode(obj->gpioHandle,GPIO_Number_0,GPIO_0_Mode_EPWM1A);
    
      // PWM2
      GPIO_setMode(obj->gpioHandle,GPIO_Number_1,GPIO_1_Mode_EPWM1B);
    
      // PWM3
      GPIO_setMode(obj->gpioHandle,GPIO_Number_2,GPIO_2_Mode_EPWM2A);
    
      // PWM4
      GPIO_setMode(obj->gpioHandle,GPIO_Number_3,GPIO_3_Mode_EPWM2B);
    
      // PWM5
      GPIO_setMode(obj->gpioHandle,GPIO_Number_4,GPIO_4_Mode_EPWM3A);
    
      // PWM6
      GPIO_setMode(obj->gpioHandle,GPIO_Number_5,GPIO_5_Mode_EPWM3B);
    
      // PWM-DAC4
      GPIO_setMode(obj->gpioHandle,GPIO_Number_6,GPIO_6_Mode_EPWM4A);
    
      // Push Button SW2
      GPIO_setMode(obj->gpioHandle,GPIO_Number_7,GPIO_7_Mode_GeneralPurpose);
      GPIO_setDirection(obj->gpioHandle,GPIO_Number_7,GPIO_Direction_Input);
    
      // ADCSOCAO_NOT or PWM-DAC3
      GPIO_setMode(obj->gpioHandle,GPIO_Number_8,GPIO_8_Mode_EPWM5A);
    
      // Push Button SW1
      GPIO_setMode(obj->gpioHandle,GPIO_Number_9,GPIO_9_Mode_GeneralPurpose);
    
      // PWM-DAC1
      GPIO_setMode(obj->gpioHandle,GPIO_Number_10,GPIO_10_Mode_EPWM6A);
    
      // PWM-DAC2
      GPIO_setMode(obj->gpioHandle,GPIO_Number_11,GPIO_11_Mode_EPWM6B);
    
      // DRV8301-LED1
      GPIO_setMode(obj->gpioHandle,GPIO_Number_12,GPIO_12_Mode_GeneralPurpose);
    
      // OCTWn
      GPIO_setMode(obj->gpioHandle,GPIO_Number_13,GPIO_13_Mode_TZ2_NOT);
    
      // FAULTn
      GPIO_setMode(obj->gpioHandle,GPIO_Number_14,GPIO_14_Mode_TZ3_NOT);
    
      // LED2
      GPIO_setMode(obj->gpioHandle,GPIO_Number_15,GPIO_15_Mode_GeneralPurpose);
    
      // Set Qualification Period for GPIO16-23, 5*2*(1/90MHz) = 0.11us
      GPIO_setQualificationPeriod(obj->gpioHandle,GPIO_Number_16,5);
    
      // SPI-SIMO
      GPIO_setMode(obj->gpioHandle,GPIO_Number_16,GPIO_16_Mode_SPISIMOA);
      GPIO_setPullup(obj->gpioHandle,GPIO_Number_16, GPIO_Pullup_Enable);
    
      // SPI-SOMI
      GPIO_setMode(obj->gpioHandle,GPIO_Number_17,GPIO_17_Mode_SPISOMIA);
      GPIO_setPullup(obj->gpioHandle,GPIO_Number_17, GPIO_Pullup_Enable);
    
      // SPI-CLK
      GPIO_setMode(obj->gpioHandle,GPIO_Number_18,GPIO_18_Mode_SPICLKA);
      GPIO_setPullup(obj->gpioHandle,GPIO_Number_18, GPIO_Pullup_Enable);
    
      // SPI-STE
      GPIO_setMode(obj->gpioHandle,GPIO_Number_19,GPIO_19_Mode_SPISTEA_NOT);
      GPIO_setPullup(obj->gpioHandle,GPIO_Number_19, GPIO_Pullup_Enable);
    
          GpioCtrlRegs.GPAQSEL2.bit.GPIO16 = 3; // Asynch input GPIO16 (SPISIMOA)
          GpioCtrlRegs.GPAQSEL2.bit.GPIO17 = 3; // Asynch input GPIO17 (SPISOMIA)
          GpioCtrlRegs.GPAQSEL2.bit.GPIO18 = 3; // Asynch input GPIO18 (SPICLKA)
          GpioCtrlRegs.GPAQSEL2.bit.GPIO19 = 3; // Asynch input GPIO19 (SPISTEA)
    
    #ifdef QEP
      // EQEPA
      GPIO_setMode(obj->gpioHandle,GPIO_Number_20,GPIO_20_Mode_EQEP1A);
      GPIO_setQualification(obj->gpioHandle,GPIO_Number_20,GPIO_Qual_Sample_3);
    
      // EQEPB
      GPIO_setMode(obj->gpioHandle,GPIO_Number_21,GPIO_21_Mode_EQEP1B);
      GPIO_setQualification(obj->gpioHandle,GPIO_Number_21,GPIO_Qual_Sample_3);
    
      // STATUS
      GPIO_setMode(obj->gpioHandle,GPIO_Number_22,GPIO_22_Mode_GeneralPurpose);
    
      // EQEP1I
      GPIO_setMode(obj->gpioHandle,GPIO_Number_23,GPIO_23_Mode_EQEP1I);
      GPIO_setQualification(obj->gpioHandle,GPIO_Number_23,GPIO_Qual_Sample_3);
    #else
      // EQEPA
      GPIO_setMode(obj->gpioHandle,GPIO_Number_20,GPIO_20_Mode_GeneralPurpose);
    
      // EQEPB
      GPIO_setMode(obj->gpioHandle,GPIO_Number_21,GPIO_21_Mode_GeneralPurpose);
    
      // STATUS
      GPIO_setMode(obj->gpioHandle,GPIO_Number_22,GPIO_22_Mode_GeneralPurpose);
    
      // EQEP1I
      GPIO_setMode(obj->gpioHandle,GPIO_Number_23,GPIO_23_Mode_GeneralPurpose);
    #endif
    
      // SPI SIMO B
      GPIO_setMode(obj->gpioHandle,GPIO_Number_24,GPIO_24_Mode_SPISIMOB);
    
      // SPI SOMI B
      GPIO_setMode(obj->gpioHandle,GPIO_Number_25,GPIO_25_Mode_SPISOMIB);
    
      // SPI CLK B
      GPIO_setMode(obj->gpioHandle,GPIO_Number_26,GPIO_26_Mode_SPICLKB);
    
      // SPI CSn B
      GPIO_setMode(obj->gpioHandle,GPIO_Number_27,GPIO_27_Mode_SPISTEB_NOT);
    
      // No Connection
      GPIO_setMode(obj->gpioHandle,GPIO_Number_28,GPIO_28_Mode_GeneralPurpose);
    
      // No Connection
      GPIO_setMode(obj->gpioHandle,GPIO_Number_29,GPIO_29_Mode_GeneralPurpose);
    
      // No Connection
      GPIO_setMode(obj->gpioHandle,GPIO_Number_30,GPIO_30_Mode_CANRXA);
      //GPIO_setPullup(obj->gpioHandle,GPIO_Number_30, GPIO_Pullup_Enable);
      //GpioCtrlRegs.GPAQSEL2.bit.GPIO30 = 3;
    
      // ControlCARD LED2
      GPIO_setMode(obj->gpioHandle,GPIO_Number_31,GPIO_31_Mode_CANTXA);
      //GPIO_setPullup(obj->gpioHandle,GPIO_Number_31, GPIO_Pullup_Enable);
      //GpioCtrlRegs.GPAQSEL2.bit.GPIO31 = 3;
    
      // No Connection
      GPIO_setMode(obj->gpioHandle,GPIO_Number_32,GPIO_32_Mode_GeneralPurpose);
    
      // No Connection
      GPIO_setMode(obj->gpioHandle,GPIO_Number_33,GPIO_33_Mode_GeneralPurpose);
    
      // ControlCARD LED3
      GPIO_setMode(obj->gpioHandle,GPIO_Number_34,GPIO_34_Mode_GeneralPurpose);
      GPIO_setLow(obj->gpioHandle,GPIO_Number_34);
      GPIO_setDirection(obj->gpioHandle,GPIO_Number_34,GPIO_Direction_Output);
    
      // JTAG
      GPIO_setMode(obj->gpioHandle,GPIO_Number_35,GPIO_35_Mode_JTAG_TDI);
      GPIO_setMode(obj->gpioHandle,GPIO_Number_36,GPIO_36_Mode_JTAG_TMS);
      GPIO_setMode(obj->gpioHandle,GPIO_Number_37,GPIO_37_Mode_JTAG_TDO);
      GPIO_setMode(obj->gpioHandle,GPIO_Number_38,GPIO_38_Mode_JTAG_TCK);
    
      // DRV8301 Enable
      GPIO_setMode(obj->gpioHandle,GPIO_Number_39,GPIO_39_Mode_GeneralPurpose);
    
      // CAP1
      GPIO_setMode(obj->gpioHandle,GPIO_Number_40,GPIO_40_Mode_GeneralPurpose);
      GPIO_setDirection(obj->gpioHandle,GPIO_Number_40,GPIO_Direction_Input);
    
      // CAP2
      GPIO_setMode(obj->gpioHandle,GPIO_Number_41,GPIO_41_Mode_GeneralPurpose);
      GPIO_setDirection(obj->gpioHandle,GPIO_Number_41,GPIO_Direction_Input);
    
      // CAP3
      GPIO_setMode(obj->gpioHandle,GPIO_Number_42,GPIO_42_Mode_GeneralPurpose);
      GPIO_setDirection(obj->gpioHandle,GPIO_Number_42,GPIO_Direction_Input);
    
      // DC_CAL
      GPIO_setMode(obj->gpioHandle,GPIO_Number_43,GPIO_43_Mode_GeneralPurpose);
    
      // No Connection
      GPIO_setMode(obj->gpioHandle,GPIO_Number_44,GPIO_44_Mode_GeneralPurpose);
    
      // No Connection
      GPIO_setMode(obj->gpioHandle,GPIO_Number_50,GPIO_50_Mode_GeneralPurpose);
    
      // DRV8301 Enable
      GPIO_setMode(obj->gpioHandle,GPIO_Number_51,GPIO_51_Mode_GeneralPurpose);
      GPIO_setLow(obj->gpioHandle,GPIO_Number_51);
      GPIO_setDirection(obj->gpioHandle,GPIO_Number_51,GPIO_Direction_Output);
    
      // No Connection
      GPIO_setMode(obj->gpioHandle,GPIO_Number_52,GPIO_52_Mode_GeneralPurpose);
    
      // No Connection
      GPIO_setMode(obj->gpioHandle,GPIO_Number_53,GPIO_53_Mode_GeneralPurpose);
    
      // No Connection
      GPIO_setMode(obj->gpioHandle,GPIO_Number_54,GPIO_54_Mode_GeneralPurpose);
    
      // No Connection
      GPIO_setMode(obj->gpioHandle,GPIO_Number_55,GPIO_55_Mode_GeneralPurpose);
    
      // No Connection
      GPIO_setMode(obj->gpioHandle,GPIO_Number_56,GPIO_56_Mode_GeneralPurpose);
    
      // No Connection
      GPIO_setMode(obj->gpioHandle,GPIO_Number_57,GPIO_57_Mode_GeneralPurpose);
    
      // No Connection
      GPIO_setMode(obj->gpioHandle,GPIO_Number_58,GPIO_58_Mode_GeneralPurpose);
    
      return;
    }  // end of HAL_setupGpios() function
    
    
    void HAL_setupPie(HAL_Handle handle)
    {
      HAL_Obj *obj = (HAL_Obj *)handle;
    
    
      PIE_disable(obj->pieHandle);
    
      PIE_disableAllInts(obj->pieHandle);
    
      PIE_clearAllInts(obj->pieHandle);
    
      PIE_clearAllFlags(obj->pieHandle);
    
      PIE_setDefaultIntVectorTable(obj->pieHandle);
    
      PIE_enable(obj->pieHandle);
    
      return;
    } // end of HAL_setupPie() function
    
    
    void HAL_setupPeripheralClks(HAL_Handle handle)
    {
      HAL_Obj *obj = (HAL_Obj *)handle;
    
    
      CLK_enableAdcClock(obj->clkHandle);
    
      CLK_enableCompClock(obj->clkHandle,CLK_CompNumber_1);
      CLK_enableCompClock(obj->clkHandle,CLK_CompNumber_2);
      CLK_enableCompClock(obj->clkHandle,CLK_CompNumber_3);
    
      CLK_enableEcap1Clock(obj->clkHandle);
    
     CLK_enableEcanaClock(obj->clkHandle);
    
    #ifdef QEP
      CLK_enableEqep1Clock(obj->clkHandle);
      CLK_enableEqep2Clock(obj->clkHandle);
    #endif
    
      CLK_enablePwmClock(obj->clkHandle,PWM_Number_1);
      CLK_enablePwmClock(obj->clkHandle,PWM_Number_2);
      CLK_enablePwmClock(obj->clkHandle,PWM_Number_3);
      CLK_enablePwmClock(obj->clkHandle,PWM_Number_4);
      CLK_enablePwmClock(obj->clkHandle,PWM_Number_5);
      CLK_enablePwmClock(obj->clkHandle,PWM_Number_6);
      CLK_enablePwmClock(obj->clkHandle,PWM_Number_7);
    
      CLK_disableHrPwmClock(obj->clkHandle);
    
      CLK_disableI2cClock(obj->clkHandle);
    
      CLK_disableLinAClock(obj->clkHandle);
    
      CLK_disableClaClock(obj->clkHandle);
    
      CLK_enableSciaClock(obj->clkHandle);
    
      CLK_enableSpiaClock(obj->clkHandle);
      CLK_enableSpibClock(obj->clkHandle);
      
      CLK_enableTbClockSync(obj->clkHandle);
    
      //Modified for enabling ecana
    
      //CLK_enableEcanaClock(obj->clkHandle);
    
      CLK_enableEcanaClock(obj->clkHandle);
    
    
      return;
    } // end of HAL_setupPeripheralClks() function
    
    
    void HAL_setupPll(HAL_Handle handle,const PLL_ClkFreq_e clkFreq)
    {
      HAL_Obj *obj = (HAL_Obj *)handle;
    
    
      // make sure PLL is not running in limp mode
      if(PLL_getClkStatus(obj->pllHandle) != PLL_ClkStatus_Normal)
        {
          // reset the clock detect
          PLL_resetClkDetect(obj->pllHandle);
    
          // ???????
          asm("        ESTOP0");
        }
    
    
      // Divide Select must be ClkIn/4 before the clock rate can be changed
      if(PLL_getDivideSelect(obj->pllHandle) != PLL_DivideSelect_ClkIn_by_4)
        {
          PLL_setDivideSelect(obj->pllHandle,PLL_DivideSelect_ClkIn_by_4);
        }
    
    
      if(PLL_getClkFreq(obj->pllHandle) != clkFreq)
        {
          // disable the clock detect
          PLL_disableClkDetect(obj->pllHandle);
    
          // set the clock rate
          PLL_setClkFreq(obj->pllHandle,clkFreq);
        }
    
    
      // wait until locked
      while(PLL_getLockStatus(obj->pllHandle) != PLL_LockStatus_Done) {}
    
    
      // enable the clock detect
      PLL_enableClkDetect(obj->pllHandle);
    
    
      // set divide select to ClkIn/2 to get desired clock rate
      // NOTE: clock must be locked before setting this register
      PLL_setDivideSelect(obj->pllHandle,PLL_DivideSelect_ClkIn_by_2);
    
      return;
    } // end of HAL_setupPll() function
    
    
    void HAL_setupPwms(HAL_Handle handle,
                       const float_t systemFreq_MHz,
                       const float_t pwmPeriod_usec,
                       const uint_least16_t numPwmTicksPerIsrTick)
    {
      HAL_Obj   *obj = (HAL_Obj *)handle;
      uint16_t   halfPeriod_cycles = (uint16_t)(systemFreq_MHz*pwmPeriod_usec) >> 1;
      uint_least8_t    cnt;
    
    
      // turns off the outputs of the EPWM peripherals which will put the power switches
      // into a high impedance state.
      PWM_setOneShotTrip(obj->pwmHandle[PWM_Number_1]);
      PWM_setOneShotTrip(obj->pwmHandle[PWM_Number_2]);
      PWM_setOneShotTrip(obj->pwmHandle[PWM_Number_3]);
      // first step to synchronize the pwms
      CLK_disableTbClockSync(obj->clkHandle);
    
      for(cnt=0;cnt<3;cnt++)
        {
          // setup the Time-Base Control Register (TBCTL)
          PWM_setCounterMode(obj->pwmHandle[cnt],PWM_CounterMode_UpDown);
          PWM_disableCounterLoad(obj->pwmHandle[cnt]);
          PWM_setPeriodLoad(obj->pwmHandle[cnt],PWM_PeriodLoad_Immediate);
          PWM_setSyncMode(obj->pwmHandle[cnt],PWM_SyncMode_EPWMxSYNC);
          PWM_setHighSpeedClkDiv(obj->pwmHandle[cnt],PWM_HspClkDiv_by_1);
          PWM_setClkDiv(obj->pwmHandle[cnt],PWM_ClkDiv_by_1);
          PWM_setPhaseDir(obj->pwmHandle[cnt],PWM_PhaseDir_CountUp);
          PWM_setRunMode(obj->pwmHandle[cnt],PWM_RunMode_FreeRun);
    
          // setup the Timer-Based Phase Register (TBPHS)
          PWM_setPhase(obj->pwmHandle[cnt],0);
    
          // setup the Time-Base Counter Register (TBCTR)
          PWM_setCount(obj->pwmHandle[cnt],0);
    
          // setup the Time-Base Period Register (TBPRD)
          // set to zero initially
          PWM_setPeriod(obj->pwmHandle[cnt],0);
    
          // setup the Counter-Compare Control Register (CMPCTL)
          PWM_setLoadMode_CmpA(obj->pwmHandle[cnt],PWM_LoadMode_Zero);
          PWM_setLoadMode_CmpB(obj->pwmHandle[cnt],PWM_LoadMode_Zero);
          PWM_setShadowMode_CmpA(obj->pwmHandle[cnt],PWM_ShadowMode_Shadow);
          PWM_setShadowMode_CmpB(obj->pwmHandle[cnt],PWM_ShadowMode_Immediate);
    
          // setup the Action-Qualifier Output A Register (AQCTLA) 
          PWM_setActionQual_CntUp_CmpA_PwmA(obj->pwmHandle[cnt],PWM_ActionQual_Set);
          PWM_setActionQual_CntDown_CmpA_PwmA(obj->pwmHandle[cnt],PWM_ActionQual_Clear);
    
          // setup the Dead-Band Generator Control Register (DBCTL)
          PWM_setDeadBandOutputMode(obj->pwmHandle[cnt],PWM_DeadBandOutputMode_EPWMxA_Rising_EPWMxB_Falling);
          PWM_setDeadBandPolarity(obj->pwmHandle[cnt],PWM_DeadBandPolarity_EPWMxB_Inverted);
    
          // setup the Dead-Band Rising Edge Delay Register (DBRED)
          PWM_setDeadBandRisingEdgeDelay(obj->pwmHandle[cnt],HAL_PWM_DBRED_CNT);
    
          // setup the Dead-Band Falling Edge Delay Register (DBFED)
          PWM_setDeadBandFallingEdgeDelay(obj->pwmHandle[cnt],HAL_PWM_DBFED_CNT);
          // setup the PWM-Chopper Control Register (PCCTL)
          PWM_disableChopping(obj->pwmHandle[cnt]);
    
          // setup the Trip Zone Select Register (TZSEL)
          PWM_disableTripZones(obj->pwmHandle[cnt]);
        }
    
    
      // setup the Event Trigger Selection Register (ETSEL)
      PWM_disableInt(obj->pwmHandle[PWM_Number_1]);
      PWM_setSocAPulseSrc(obj->pwmHandle[PWM_Number_1],PWM_SocPulseSrc_CounterEqualZero);
      PWM_enableSocAPulse(obj->pwmHandle[PWM_Number_1]);
      
    
      // setup the Event Trigger Prescale Register (ETPS)
      if(numPwmTicksPerIsrTick == 3)
        {
          PWM_setIntPeriod(obj->pwmHandle[PWM_Number_1],PWM_IntPeriod_ThirdEvent);
          PWM_setSocAPeriod(obj->pwmHandle[PWM_Number_1],PWM_SocPeriod_ThirdEvent);
        }
      else if(numPwmTicksPerIsrTick == 2)
        {
          PWM_setIntPeriod(obj->pwmHandle[PWM_Number_1],PWM_IntPeriod_SecondEvent);
          PWM_setSocAPeriod(obj->pwmHandle[PWM_Number_1],PWM_SocPeriod_SecondEvent);
        }
      else
        {
          PWM_setIntPeriod(obj->pwmHandle[PWM_Number_1],PWM_IntPeriod_FirstEvent);
          PWM_setSocAPeriod(obj->pwmHandle[PWM_Number_1],PWM_SocPeriod_FirstEvent);
        }
    
    
      // setup the Event Trigger Clear Register (ETCLR)
      PWM_clearIntFlag(obj->pwmHandle[PWM_Number_1]);
      PWM_clearSocAFlag(obj->pwmHandle[PWM_Number_1]);
    
    
      // since the PWM is configured as an up/down counter, the period register is set to one-half 
      // of the desired PWM period
      PWM_setPeriod(obj->pwmHandle[PWM_Number_1],halfPeriod_cycles);
      PWM_setPeriod(obj->pwmHandle[PWM_Number_2],halfPeriod_cycles);
      PWM_setPeriod(obj->pwmHandle[PWM_Number_3],halfPeriod_cycles);
    
      // last step to synchronize the pwms
      CLK_enableTbClockSync(obj->clkHandle);
    
      return;
    }  // end of HAL_setupPwms() function
    
    #ifdef QEP
    void HAL_setupQEP(HAL_Handle handle,HAL_QepSelect_e qep)
    {
      HAL_Obj   *obj = (HAL_Obj *)handle;
    
    
      // hold the counter in reset
      QEP_reset_counter(obj->qepHandle[qep]);
    
      // set the QPOSINIT register
      QEP_set_posn_init_count(obj->qepHandle[qep], 0);
    
      // disable all interrupts
      QEP_disable_all_interrupts(obj->qepHandle[qep]);
    
      // clear the interrupt flags
      QEP_clear_all_interrupt_flags(obj->qepHandle[qep]);
    
      // clear the position counter
      QEP_clear_posn_counter(obj->qepHandle[qep]);
    
      // setup the max position
      QEP_set_max_posn_count(obj->qepHandle[qep], (4*USER_MOTOR_ENCODER_LINES)-1);
    
      // setup the QDECCTL register
      QEP_set_QEP_source(obj->qepHandle[qep], QEP_Qsrc_Quad_Count_Mode);
      QEP_disable_sync_out(obj->qepHandle[qep]);
      QEP_set_swap_quad_inputs(obj->qepHandle[qep], QEP_Swap_Not_Swapped);
      QEP_disable_gate_index(obj->qepHandle[qep]);
      QEP_set_ext_clock_rate(obj->qepHandle[qep], QEP_Xcr_2x_Res);
      QEP_set_A_polarity(obj->qepHandle[qep], QEP_Qap_No_Effect);
      QEP_set_B_polarity(obj->qepHandle[qep], QEP_Qbp_No_Effect);
      QEP_set_index_polarity(obj->qepHandle[qep], QEP_Qip_No_Effect);
    
      // setup the QEPCTL register
      QEP_set_emu_control(obj->qepHandle[qep], QEPCTL_Freesoft_Unaffected_Halt);
      QEP_set_posn_count_reset_mode(obj->qepHandle[qep], QEPCTL_Pcrm_Max_Reset);
      QEP_set_strobe_event_init(obj->qepHandle[qep], QEPCTL_Sei_Nothing);
      QEP_set_index_event_init(obj->qepHandle[qep], QEPCTL_Iei_Nothing);
      QEP_set_index_event_latch(obj->qepHandle[qep], QEPCTL_Iel_Rising_Edge);
      QEP_set_soft_init(obj->qepHandle[qep], QEPCTL_Swi_Nothing);
      QEP_disable_unit_timer(obj->qepHandle[qep]);
      QEP_disable_watchdog(obj->qepHandle[qep]);
    
      // setup the QPOSCTL register
      QEP_disable_posn_compare(obj->qepHandle[qep]);
    
      // setup the QCAPCTL register
      QEP_disable_capture(obj->qepHandle[qep]);
    
      // renable the position counter
      QEP_enable_counter(obj->qepHandle[qep]);
    
    
      return;
    }
    #endif
    //void HAL_setupECAN(HAL_Handle handle){
    	//HAL_Obj *obj = (HAL_Obj *)handle;
    
    //	ECAN_setTXIO(obj->ecanaHandle);
    //	ECAN_setRXIO(obj->ecanaHandle);
    //	ECAN_setSCCmode(obj->ecanaHandle);
    //	ECAN_Mode(obj->ecanaHandle, eCANmode);
     //   ECAN_disableAllMailbox(obj->ecanaHandle);
    //	ECAN_clearMSGCTRL(obj->ecanaHandle);
     //   ECAN_clearCANTA(obj->ecanaHandle);
    //	ECAN_clearCANRMP(obj->ecanaHandle);
    //	ECAN_clearCANGIF0(obj->ecanaHandle);
    //	ECAN_clearCANGIF1(obj->ecanaHandle);
     //   ECAN_setBitrate(obj->ecanaHandle, Bitrate_1M); // 90 MHz SYSCLKOUT. 45 MHz CAN module clock Bit rate = 500 Kbps
    
    //}
    
    
    void HAL_setupSpiA(HAL_Handle handle)
    {
      HAL_Obj   *obj = (HAL_Obj *)handle;
    
      SPI_reset(obj->spiAHandle);
      SPI_setClkPolarity(obj->spiAHandle,SPI_ClkPolarity_OutputFallingEdge_InputRisingEdge);
      SPI_disableLoopBack(obj->spiAHandle);
      SPI_setCharLength(obj->spiAHandle,SPI_CharLength_8_Bits);
    
      SPI_setMode(obj->spiAHandle,SPI_Mode_Master);
      SPI_setClkPhase(obj->spiAHandle,SPI_ClkPhase_Normal);
      SPI_enableTx(obj->spiAHandle);
    
      SPI_enableChannels(obj->spiAHandle);
      SPI_enableTxFifoEnh(obj->spiAHandle);
      SPI_enableTxFifo(obj->spiAHandle);
      SPI_setTxDelay(obj->spiAHandle,0);
      SPI_clearTxFifoInt(obj->spiAHandle);
      SPI_enableRxFifo(obj->spiAHandle);
    
      SPI_setBaudRate(obj->spiAHandle,(SPI_BaudRate_e)(0x0004));
      SPI_setSuspend(obj->spiAHandle,SPI_TxSuspend_free);
      SPI_enable(obj->spiAHandle);
    
      return;
    }  // end of HAL_setupSpiA() function
    
    
    void HAL_setupSpiB(HAL_Handle handle)
    {
      HAL_Obj   *obj = (HAL_Obj *)handle;
    
      SPI_reset(obj->spiBHandle);
      SPI_setMode(obj->spiBHandle,SPI_Mode_Master);
      SPI_setClkPolarity(obj->spiBHandle,SPI_ClkPolarity_OutputRisingEdge_InputFallingEdge);
      SPI_enableTx(obj->spiBHandle);
      SPI_enableTxFifoEnh(obj->spiBHandle);
      SPI_enableTxFifo(obj->spiBHandle);
      SPI_setTxDelay(obj->spiBHandle,0x0018);
      SPI_setBaudRate(obj->spiBHandle,(SPI_BaudRate_e)(0x000d));
      SPI_setCharLength(obj->spiBHandle,SPI_CharLength_16_Bits);
      SPI_setSuspend(obj->spiBHandle,SPI_TxSuspend_free);
      SPI_enable(obj->spiBHandle);
    
      return;
    }  // end of HAL_setupSpiB() function
    
    
    void HAL_setupPwmDacs(HAL_Handle handle)
    {
      HAL_Obj *obj = (HAL_Obj *)handle;
      uint16_t halfPeriod_cycles = 512;       // 3000->10kHz, 1500->20kHz, 1000-> 30kHz, 500->60kHz
      uint_least8_t    cnt;
    
    
      for(cnt=0;cnt<3;cnt++)
      {
        // initialize the Time-Base Control Register (TBCTL)
        PWMDAC_setCounterMode(obj->pwmDacHandle[cnt],PWM_CounterMode_UpDown);
        PWMDAC_disableCounterLoad(obj->pwmDacHandle[cnt]);
        PWMDAC_setPeriodLoad(obj->pwmDacHandle[cnt],PWM_PeriodLoad_Immediate);
        PWMDAC_setSyncMode(obj->pwmDacHandle[cnt],PWM_SyncMode_EPWMxSYNC);
        PWMDAC_setHighSpeedClkDiv(obj->pwmDacHandle[cnt],PWM_HspClkDiv_by_1);
        PWMDAC_setClkDiv(obj->pwmDacHandle[cnt],PWM_ClkDiv_by_1);
        PWMDAC_setPhaseDir(obj->pwmDacHandle[cnt],PWM_PhaseDir_CountUp);
        PWMDAC_setRunMode(obj->pwmDacHandle[cnt],PWM_RunMode_FreeRun);
    
        // initialize the Timer-Based Phase Register (TBPHS)
        PWMDAC_setPhase(obj->pwmDacHandle[cnt],0);
    
        // setup the Time-Base Counter Register (TBCTR)
        PWMDAC_setCount(obj->pwmDacHandle[cnt],0);
    
        // Initialize the Time-Base Period Register (TBPRD)
        // set to zero initially
        PWMDAC_setPeriod(obj->pwmDacHandle[cnt],0);
    
        // initialize the Counter-Compare Control Register (CMPCTL)
        PWMDAC_setLoadMode_CmpA(obj->pwmDacHandle[cnt],PWM_LoadMode_Zero);
        PWMDAC_setLoadMode_CmpB(obj->pwmDacHandle[cnt],PWM_LoadMode_Zero);
        PWMDAC_setShadowMode_CmpA(obj->pwmDacHandle[cnt],PWM_ShadowMode_Shadow);
        PWMDAC_setShadowMode_CmpB(obj->pwmDacHandle[cnt],PWM_ShadowMode_Shadow);
    
        // Initialize the Action-Qualifier Output A Register (AQCTLA)
        PWMDAC_setActionQual_CntUp_CmpA_PwmA(obj->pwmDacHandle[cnt],PWM_ActionQual_Clear);
        PWMDAC_setActionQual_CntDown_CmpA_PwmA(obj->pwmDacHandle[cnt],PWM_ActionQual_Set);
    
        // account for EPWM6B
        if(cnt == 0)
        {
          PWMDAC_setActionQual_CntUp_CmpB_PwmB(obj->pwmDacHandle[cnt],PWM_ActionQual_Clear);
          PWMDAC_setActionQual_CntDown_CmpB_PwmB(obj->pwmDacHandle[cnt],PWM_ActionQual_Set);
        }
    
        // Initialize the Dead-Band Control Register (DBCTL)
        PWMDAC_disableDeadBand(obj->pwmDacHandle[cnt]);
    
        // Initialize the PWM-Chopper Control Register (PCCTL)
        PWMDAC_disableChopping(obj->pwmDacHandle[cnt]);
    
        // Initialize the Trip-Zone Control Register (TZSEL)
        PWMDAC_disableTripZones(obj->pwmDacHandle[cnt]);
    
        // Initialize the Trip-Zone Control Register (TZCTL)
        PWMDAC_setTripZoneState_TZA(obj->pwmDacHandle[cnt],PWM_TripZoneState_HighImp);
        PWMDAC_setTripZoneState_TZB(obj->pwmDacHandle[cnt],PWM_TripZoneState_HighImp);
        PWMDAC_setTripZoneState_DCAEVT1(obj->pwmDacHandle[cnt],PWM_TripZoneState_HighImp);
        PWMDAC_setTripZoneState_DCAEVT2(obj->pwmDacHandle[cnt],PWM_TripZoneState_HighImp);
        PWMDAC_setTripZoneState_DCBEVT1(obj->pwmDacHandle[cnt],PWM_TripZoneState_HighImp);
      }
    
      // since the PWM is configured as an up/down counter, the period register is set to one-half 
      // of the desired PWM period
      PWMDAC_setPeriod(obj->pwmDacHandle[PWMDAC_Number_1],halfPeriod_cycles);   // Set period for both DAC1 and DAC2
      PWMDAC_setPeriod(obj->pwmDacHandle[PWMDAC_Number_2],halfPeriod_cycles);
      PWMDAC_setPeriod(obj->pwmDacHandle[PWMDAC_Number_3],halfPeriod_cycles);
    
      return;
    }  // end of HAL_setupPwmDacs() function
    
    
    void HAL_setupTimers(HAL_Handle handle,const float_t systemFreq_MHz)
    {
      HAL_Obj  *obj = (HAL_Obj *)handle;
      uint32_t  timerPeriod_0p5ms = (uint32_t)(systemFreq_MHz * (float_t)500.0) - 1;
      uint32_t  timerPeriod_10ms = (uint32_t)(systemFreq_MHz * (float_t)10000.0) - 1;
    
      // use timer 0 for frequency diagnostics
      TIMER_setDecimationFactor(obj->timerHandle[0],0);
      TIMER_setEmulationMode(obj->timerHandle[0],TIMER_EmulationMode_RunFree);
      TIMER_setPeriod(obj->timerHandle[0],timerPeriod_0p5ms);
      TIMER_setPreScaler(obj->timerHandle[0],0);
    
      // use timer 1 for CPU usage diagnostics
      TIMER_setDecimationFactor(obj->timerHandle[1],0);
      TIMER_setEmulationMode(obj->timerHandle[1],TIMER_EmulationMode_RunFree);
      TIMER_setPeriod(obj->timerHandle[1],timerPeriod_10ms);
      TIMER_setPreScaler(obj->timerHandle[1],0);
    
      // use timer 2 for CPU time diagnostics
      TIMER_setDecimationFactor(obj->timerHandle[2],0);
      TIMER_setEmulationMode(obj->timerHandle[2],TIMER_EmulationMode_RunFree);
      TIMER_setPeriod(obj->timerHandle[2],0xFFFFFFFF);
      TIMER_setPreScaler(obj->timerHandle[2],0);
    
      return;
    }  // end of HAL_setupTimers() function
    
    
    void HAL_writeDrvData(HAL_Handle handle, DRV_SPI_8301_Vars_t *Spi_8301_Vars)
    {
      HAL_Obj  *obj = (HAL_Obj *)handle;
    
      DRV8301_writeData(obj->drv8301Handle,Spi_8301_Vars);
      
      return;
    }  // end of HAL_writeDrvData() function
    
    
    void HAL_readDrvData(HAL_Handle handle, DRV_SPI_8301_Vars_t *Spi_8301_Vars)
    {
      HAL_Obj  *obj = (HAL_Obj *)handle;
    
      DRV8301_readData(obj->drv8301Handle,Spi_8301_Vars);
      
      return;
    }  // end of HAL_readDrvData() function
    
    
    void HAL_setupDrvSpi(HAL_Handle handle, DRV_SPI_8301_Vars_t *Spi_8301_Vars)
    {
      HAL_Obj  *obj = (HAL_Obj *)handle;
    
      DRV8301_setupSpi(obj->drv8301Handle,Spi_8301_Vars);
    
      return;
    }  // end of HAL_setupDrvSpi() function
    
    
    void HAL_setDacParameters(HAL_Handle handle, HAL_DacData_t *pDacData)
    {
    	HAL_Obj *obj = (HAL_Obj *)handle;
    
    	pDacData->PeriodMax = PWMDAC_getPeriod(obj->pwmDacHandle[PWMDAC_Number_1]);
    
    	pDacData->offset[0] = _IQ(0.5);
    	pDacData->offset[1] = _IQ(0.5);
    	pDacData->offset[2] = _IQ(0.0);
    	pDacData->offset[3] = _IQ(0.0);
    
    	pDacData->gain[0] = _IQ(1.0);
    	pDacData->gain[1] = _IQ(1.0);
    	pDacData->gain[2] = _IQ(1.0);
    	pDacData->gain[3] = _IQ(1.0);
    
    	return;
    }	//end of HAL_setDacParameters() function
    
    // end of file
    

  • Do I understand correctly that you are trying to perform motor ID in lab5d? Or inertia ID?

    Sean
  • No Motor Identification is already done. I want to do speed control but Motor state remains idle and motor doesnot rotate with SpeedRefv value
  • Are you able to run the un-modified lab5d?

    Also, I would recommend that you don't put the SPI communication in the mainISR, you want the mainISR to run completely aside from any communications protocol for the best performance. This will become easier to manage if you instantiate another ISR for comms, you will find it easier to debug this way

    Sean
  • Issue is resolved.

    USER_SYSTEM_FREQ_MHz was accidentally set to wrong value.

    Thanks,
    Ayushi