/*
 * Hardware configuration file for: TI2833x
 * Generated with                 : PLECS 4.9.2
 * Generated on                   : Mon Feb 17 15:19:25 2025
 */

/* HAL Includes */
#include "DSP_2_MOT.h"
#include "plx_hal.h"
#include "plx_dispatcher.h"
#include "pil.h"
#include "plx_sci.h"
#include "plx_ain.h"
#include "plx_power.h"
#include "plx_pwm.h"
#include "math.h"
#include "plx_dio.h"
#include "plx_qep.h"
#include "plx_spi.h"
#include "plx_canbus.h"

/* HAL Declarations */
void DeviceInit(Uint16 pllDiv);
void InitFlash();
void DSP28x_usDelay(long LoopCount);

// Clock configuration
#define SYSCLK_HZ 150000000L
#define LSPCLK_HZ (SYSCLK_HZ / 6l)
#define PLL_DIV 10
#define PLX_DELAY_US(A)  DSP28x_usDelay( \
                                        ((((long double) A * \
                                           1000.0L) / \
                                          6.666667L) - 9.0L) / 5.0L)

PIL_Obj_t PilObj;
PIL_Handle_t PilHandle = 0;
// external mode helper symbols
PIL_CONFIG_DEF(uint32_t, ExtMode_targetFloat_Size,
               sizeof(DSP_2_MOT_FloatType));
PIL_CONFIG_DEF(uint32_t, ExtMode_targetPointer_Size,
               sizeof(DSP_2_MOT_FloatType*));
PIL_CONFIG_DEF(uint32_t, ExtMode_sampleTime_Ptr,
               (uint32_t)&DSP_2_MOT_sampleTime);
PIL_CONFIG_DEF(uint32_t, ExtMode_checksum_Ptr, (uint32_t)&DSP_2_MOT_checksum);
#if defined(DSP_2_MOT_NumTunableParameters) && \
   (DSP_2_MOT_NumTunableParameters > 0)
PIL_CONFIG_DEF(uint32_t, ExtMode_P_Ptr, (uint32_t)&DSP_2_MOT_P);
PIL_CONFIG_DEF(uint32_t, ExtMode_P_Size,
               (uint32_t)DSP_2_MOT_NumTunableParameters);
#endif
#if defined(DSP_2_MOT_NumExtModeSignals) && (DSP_2_MOT_NumExtModeSignals > 0)
PIL_CONFIG_DEF(uint32_t, ExtMode_ExtModeSignals_Ptr,
               (uint32_t)&DSP_2_MOT_ExtModeSignals[0]);
PIL_CONFIG_DEF(uint32_t, ExtMode_ExtModeSignals_Size,
               (uint32_t)DSP_2_MOT_NumExtModeSignals);
#endif

#define CODE_GUID {0x09, 0x3c, 0x97, 0x5e, 0xdb, 0x2d, 0xb8, 0x40};
PIL_CONST_DEF(unsigned char, Guid[], CODE_GUID);
PIL_CONST_DEF(unsigned char, CompiledDate[], "02/17/2025 03:19 PM");
PIL_CONST_DEF(unsigned char, CompiledBy[], "PLECS Coder");
PIL_CONST_DEF(uint16_t, FrameworkVersion, PIL_FRAMEWORK_VERSION);
PIL_CONST_DEF(char, FirmwareDescription[], "TIC2000 Project (CPU0)");
PIL_CONST_DEF(uint16_t, StationAddress, 0);
PIL_CONST_DEF(uint32_t, BaudRate, 115200);
static void SciPoll(PIL_Handle_t aHandle)
{
   PLXHAL_SCI_handleBreak(0);

   while(PLXHAL_SCI_rxIsReady(0))
   {
      // assuming that there will be a "break" when FIFO is empty
      PIL_SERIAL_IN(aHandle, (int16) PLXHAL_SCI_getChar(0));
   }
   int16_t ch;
   if(!PLXHAL_SCI_txIsBusy(0))
   {
      if(PIL_SERIAL_OUT(aHandle, &ch))
      {
         PLXHAL_SCI_putChar(0, ch);
      }
   }
}

#pragma DATA_SECTION(ScopeBuffer, "scope")
uint16_t ScopeBuffer[1084] /*__attribute__((aligned(16)))*/;
extern void PIL_setAndConfigScopeBuffer(PIL_Handle_t aPilHandle,
                                        uint16_t* aBufPtr, uint16_t aBufSize,
                                        uint16_t aMaxTraceWidthInWords);
extern const char * const DSP_2_MOT_checksum;

uint16_t ScopeFlagCpuRemote;
#pragma DATA_SECTION(ScopeFlagCpuRemote, "scopeflag_remote")
#pragma RETAIN(ScopeFlagCpuRemote)
uint16_t ScopeFlagCpuThis;
#pragma DATA_SECTION(ScopeFlagCpuThis, "scopeflag_local")
#pragma RETAIN(ScopeFlagCpuThis)
PIL_SYMBOL_DEF(ScopeFlagCpuRemote, 0, 1.0, "");
PIL_SYMBOL_DEF(ScopeFlagCpuThis, 0, 1.0, "");
extern void PIL_setAndConfigureScopeIndicator(PIL_Handle_t aPilHandle,
                                              uint16_t* aIndicatorPtr);

PLX_SCI_Obj_t SciObjs[1];
PLX_SCI_Handle_t SciHandles[1];

uint16_t PLXHAL_SCI_getChar(int16_t aChannel)
{
   return PLX_SCI_getChar(SciHandles[aChannel]);
}

void PLXHAL_SCI_putChar(int16_t aChannel, uint16_t data)
{
   PLX_SCI_putChar(SciHandles[aChannel], data);
}

void PLXHAL_SCI_putStr(int16_t aChannel, uint16_t *str)
{
   for (int i = 0; i < strlen(str); i++)
   {
      PLXHAL_SCI_putChar(aChannel, str[i]);
   }
}

bool PLXHAL_SCI_rxIsReady(int16_t aChannel)
{
   return PLX_SCI_rxReady(SciHandles[aChannel]);
}

bool PLXHAL_SCI_txIsBusy(int16_t aChannel)
{
   return PLX_SCI_txIsBusy(SciHandles[aChannel]);
}

void PLXHAL_SCI_handleBreak(int16_t aChannel)
{
   if(PLX_SCI_breakOccurred(SciHandles[aChannel]))
   {
      PLX_SCI_reset(SciHandles[aChannel]);
   }
}

PLX_AIN_Handle_t AdcHandles[1];
PLX_AIN_Obj_t AdcObj[1];

float PLXHAL_ADC_getIn(uint16_t aHandle, uint16_t aChannel)
{
   return PLX_AIN_getInF(AdcHandles[aHandle], aChannel);
}

void PLXHAL_PWR_setEnableRequest(bool aEnable)
{
   PLX_PWR_setEnableRequest(aEnable);
   PLX_PWR_runFsm();
}
bool PLXHAL_PWR_isEnabled()
{
   return PLX_PWR_isEnabled();
}
void PLXHAL_PWR_syncdPwmEnable()
{
   PLX_PWR_syncdSwitchingEnable();
}
uint32_t PLXHAL_DISPR_getTimeStamp0()
{
   return DISPR_getTimeStamp0();
}

uint32_t PLXHAL_DISPR_getTimeStamp1()
{
   return DISPR_getTimeStamp1();
}

uint32_t PLXHAL_DISPR_getTimeStamp2()
{
   return DISPR_getTimeStamp2();
}

uint32_t PLXHAL_DISPR_getTimeStamp3()
{
   return DISPR_getTimeStamp3();
}

uint32_t PLXHAL_DISPR_getTimeStampB()
{
   return DISPR_getTimeStampB();
}

uint32_t PLXHAL_DISPR_getTimeStampD()
{
   return DISPR_getTimeStampD();
}

uint32_t PLXHAL_DISPR_getTimeStampP()
{
   return DISPR_getTimeStampP();
}

float PLXHAL_DISPR_getTask0LoadInPercent()
{
   return DISPR_getTask0LoadInPercent();
}

extern PLX_PWM_Handle_t EpwmHandles[];
// PWM Enable Functions
void PLXHAL_PWM_setToPassive(uint16_t aChannel)
{
   PLX_PWM_setOutToPassive(EpwmHandles[aChannel]);
}

void PLXHAL_PWM_setToOperational(uint16_t aChannel)
{
   PLX_PWM_setOutToOperational(EpwmHandles[aChannel]);
}

void PLXHAL_PWM_prepareSetOutToXTransition(uint16_t aHandle)
{
   PLX_PWM_prepareSetOutToXTransition(EpwmHandles[aHandle]);
}

// PWM Set Duty Cycle Function
void PLXHAL_PWM_setDuty(uint16_t aHandle, float aDuty)
{
   PLX_PWM_setPwmDuty(EpwmHandles[aHandle], aDuty);
}

// PWM Set Dead Time Functions
void PLXHAL_PWM_setRisingDelay(uint16_t aChannel, float delay)
{
   uint16_t counts = (uint16_t)(fminf(65535.0f, delay * 7.500000e+07f));
   PLX_PWM_setDeadTimeCountsRising(EpwmHandles[aChannel], counts);
}

void PLXHAL_PWM_setFallingDelay(uint16_t aChannel, float delay)
{
   uint16_t counts = (uint16_t)(fminf(65535.0f, delay * 7.500000e+07f));
   PLX_PWM_setDeadTimeCountsFalling(EpwmHandles[aChannel], counts);
}

// PWM Set Sequence Functions
void PLXHAL_PWM_setSequence(uint16_t aChannel, uint16_t aSequence)
{
   PLX_PWM_setSequence(EpwmHandles[aChannel], aSequence);
}

void PLXHAL_PWM_setSequenceAq(uint16_t aChannel, uint32_t aSequenceAq)
{
   PLX_PWM_setSequenceAq(EpwmHandles[aChannel], aSequenceAq);
}

void PLXHAL_PWM_setDutyAB(uint16_t aHandle, float aDutyA, float aDutyB)
{
   PLX_PWM_setPwmDuty(EpwmHandles[aHandle], aDutyA);
   PLX_PWM_setPwmDutyB(EpwmHandles[aHandle], aDutyB);
}

void PLXHAL_PWM_setOverflowSocDelay(uint16_t aHandle, float aPhase)
{
   PLX_PWM_setPwmDutyCGreaterThanZero(EpwmHandles[aHandle], 1.0f - aPhase);
}

void PLXHAL_PWM_setUnderflowSocDelay(uint16_t aHandle, float aPhase)
{
   PLX_PWM_setPwmDutyCSmallerThanFull(EpwmHandles[aHandle], aPhase);
}

PLX_PWM_Handle_t EpwmHandles[3];
PLX_PWM_Obj_t EpwmObj[3];
PLX_DIO_Handle_t DinHandles[6];
PLX_DIO_Obj_t DinObj[6];
bool PLXHAL_DIO_get(uint16_t aHandle)
{
   return PLX_DIO_get(DinHandles[aHandle]);
}
PLX_DIO_Handle_t DoutHandles[13];
PLX_DIO_Obj_t DoutObj[13];

void PLXHAL_DIO_set(uint16_t aHandle, bool aVal)
{
   PLX_DIO_set(DoutHandles[aHandle], aVal);
}

PLX_QEP_Handle_t QepHandles[1];
PLX_QEP_Obj_t QepObj[1];
uint32_t PLXHAL_QEP_getCounter(uint16_t aChannel)
{
   return PLX_QEP_getPosCnt(QepHandles[aChannel]);
}
bool PLXHAL_QEP_getAndCearIndexFlag(uint16_t aChannel)
{
   return PLX_QEP_getAndClearIndexFlag(QepHandles[aChannel]);
}
uint32_t PLXHAL_QEP_getIndexLatchCounter(uint16_t aChannel)
{
   return PLX_QEP_getPosILatchCnt(QepHandles[aChannel]);
}
PLX_SPI_Handle_t SpiHandles[1];
PLX_SPI_Obj_t SpiObj[1];
uint16_t PLXHAL_SPI_getRxFifoLevel(int16_t aChannel)
{
   return PLX_SPI_getRxFifoLevel(SpiHandles[aChannel]);
}
bool PLXHAL_SPI_putWords(int16_t aChannel, uint16_t *aData, uint16_t aLen)
{
   return PLX_SPI_putWords(SpiHandles[aChannel], aData, aLen);
}
bool PLXHAL_SPI_getWords(int16_t aChannel, uint16_t *aData, uint16_t aLen)
{
   return PLX_SPI_getWords(SpiHandles[aChannel], aData, aLen);
}
bool PLXHAL_SPI_getAndResetRxOverrunFlag(int16_t aChannel)
{
   return PLX_SPI_getAndResetRxOverrunFlag(SpiHandles[aChannel]);
}
PLX_CANBUS_Handle_t CanHandles[1];
PLX_CANBUS_Obj_t CanObj[1];

bool PLXHAL_CAN_getMessage(uint16_t aChannel, uint16_t aMailBox,
                           unsigned char data[], unsigned char lenMax)
{
   return PLX_CANBUS_getMessage(CanHandles[aChannel], aMailBox, data, lenMax);
}

void PLXHAL_CAN_putMessage(uint16_t aChannel, uint16_t aMailBox,
                           unsigned char data[], unsigned char len)
{
   (void)PLX_CANBUS_putMessage(CanHandles[aChannel], aMailBox, data, len);
}

void PLXHAL_CAN_setBusOn(uint16_t aChannel, bool aBusOn)
{
   PLX_CANBUS_setBusOn(CanHandles[aChannel], aBusOn);
}

bool PLXHAL_CAN_getIsBusOn(uint16_t aChannel)
{
   return PLX_CANBUS_isBusOn(CanHandles[aChannel]);
}

bool PLXHAL_CAN_getIsErrorActive(uint16_t aChannel)
{
   return PLX_CANBUS_isErrorActive(CanHandles[aChannel]);
}

void PIL_setErrorMessage(PIL_Handle_t aPilHandle, const char* aMessage);
extern const char * DSP_2_MOT_errorStatus;

static void PanicCallback()
{
   PLX_PWR_emergencyOff();
}

extern PIL_Handle_t PilHandle;
DISPR_TaskObj_t TaskObj[1];
extern void DSP_2_MOT_step();
extern void DSP_2_MOT_enableTasksInterrupt();
extern void DSP_2_MOT_syncTimers();
static void Tasks(bool aInit, void * const aParam)
{
   if(DSP_2_MOT_errorStatus)
   {
      PIL_setErrorMessage(PilHandle, DSP_2_MOT_errorStatus);
      return;
   }
   if(aInit)
   {
      DSP_2_MOT_enableTasksInterrupt();
   }
   else
   {
      DSP_2_MOT_step();
   }
}


interrupt void DSP_2_MOT_baseTaskInterrupt(void)
{
   PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
   IER |= M_INT1;
   if (CpuTimer0Regs.TCR.bit.TIF == 1)
   {
      CpuTimer0Regs.TCR.bit.TIF = 1;    // clear interrupt flag
      AdcRegs.ADCTRL2.bit.SOC_SEQ1 = 1;   // trigger ADC by software
      // don't dispatch yet - wait for ADC interrupt
      return;
   }
   else
   {
      AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1;    // clear interrupt flag
      AdcRegs.ADCTRL2.bit.RST_SEQ1 = 1;    // reset sequencer
   }

   DISPR_dispatch();
}


/* Interrupt Enable Code */
void DSP_2_MOT_enableTasksInterrupt(void)
{
   IER |= M_INT1;
}

/* Timer Synchronization Code */
void DSP_2_MOT_syncTimers(void)
{
   SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1;  // start all the timers synced

   CpuTimer0Regs.TCR.bit.TSS = 0;
}

/* Background tasks */
void DSP_2_MOT_background(void)
{

}
/* HAL Initialization Code */
static bool HalInitialized = false;
void DSP_2_MOT_initHal()
{
   if(HalInitialized == true)
   {
      return;
   }
   HalInitialized = true;
   // Pre init code
   DeviceInit(PLL_DIV);
   InitFlash();
   // set cpu timers to same clock as ePWM (SYSCLK/2)
   CpuTimer0Regs.TPR.all = 1;
   CpuTimer1Regs.TPR.all = 1;
   CpuTimer2Regs.TPR.all = 1;
   EALLOW;
   SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0;  // stop all the TB clocks
   EDIS;

   PilHandle = PIL_init(&PilObj, sizeof(PilObj));
   PIL_setGuid(PilHandle, PIL_GUID_PTR);
   PIL_setChecksum(PilHandle, DSP_2_MOT_checksum);
   PIL_setAndConfigScopeBuffer(PilHandle, (uint16_t *)&ScopeBuffer, 1084, 42);
   PIL_setAndConfigureScopeIndicator(PilHandle, &ScopeFlagCpuThis);
   PIL_setNodeAddress(PilHandle, PIL_D_StationAddress);

   PIL_setSerialComCallback(PilHandle, (PIL_CommCallbackPtr_t)SciPoll);
   {
      for(int i=0; i < 1; i++)
      {
         SciHandles[i] =
            PLX_SCI_init(&SciObjs[i],
                         sizeof(SciObjs[i]));
      }
   }

   PLX_SCI_configureViaPinSet(SciHandles[0], 0, 25000000);
   (void)PLX_SCI_setupPort(SciHandles[0], 115200);
   PLX_PWR_configureTZGpio(1, 12);
   {
      PLX_AIN_sinit(150000000);

      for (int i = 0; i < 1; i++)
      {
         AdcHandles[i] = PLX_AIN_init(&AdcObj[i], sizeof(AdcObj[i]));
      }
   }


   // configure ADC A
   {
      PLX_AIN_AdcParams_t params;
      PLX_AIN_setDefaultAdcParams(&params, 0, 3.000000, 0);
      params.ADCTRL1.bit.ACQ_PS = 0;
      PLX_AIN_configure(AdcHandles[0], (PLX_AIN_Unit_t)0, &params);
   }
   // configure SOC1 of ADC-A to measure ADCIN0
   {
      PLX_AIN_ChannelParams_t params;
      PLX_AIN_setDefaultChannelParams(&params);
      params.scale =  2.820000000e+01f;
      params.offset = -4.230000000e+01f;

      params.trigsel = 1;
      PLX_AIN_setupChannel(AdcHandles[0], 0, 0, &params);
   }

   // configure SOC2 of ADC-A to measure ADCIN1
   {
      PLX_AIN_ChannelParams_t params;
      PLX_AIN_setDefaultChannelParams(&params);
      params.scale =  2.820000000e+01f;
      params.offset = -4.230000000e+01f;

      params.trigsel = 1;
      PLX_AIN_setupChannel(AdcHandles[0], 1, 1, &params);
   }

   // configure SOC3 of ADC-A to measure ADCIN2
   {
      PLX_AIN_ChannelParams_t params;
      PLX_AIN_setDefaultChannelParams(&params);
      params.scale =  2.820000000e+01f;
      params.offset = -4.230000000e+01f;

      params.trigsel = 1;
      PLX_AIN_setupChannel(AdcHandles[0], 2, 2, &params);
   }

   // configure SOC4 of ADC-A to measure ADCIN3
   {
      PLX_AIN_ChannelParams_t params;
      PLX_AIN_setDefaultChannelParams(&params);
      params.scale =  2.666666667e+02f;
      params.offset = 0.000000000e+00f;

      params.trigsel = 1;
      PLX_AIN_setupChannel(AdcHandles[0], 3, 3, &params);
   }

   // configure SOC5 of ADC-A to measure ADCIN14
   {
      PLX_AIN_ChannelParams_t params;
      PLX_AIN_setDefaultChannelParams(&params);
      params.scale =  2.666666667e+02f;
      params.offset = 0.000000000e+00f;

      params.trigsel = 1;
      PLX_AIN_setupChannel(AdcHandles[0], 4, 14, &params);
   }

   // configure SOC6 of ADC-A to measure ADCIN4
   {
      PLX_AIN_ChannelParams_t params;
      PLX_AIN_setDefaultChannelParams(&params);
      params.scale =  1.000000000e+00f;
      params.offset = 0.000000000e+00f;

      params.trigsel = 1;
      PLX_AIN_setupChannel(AdcHandles[0], 5, 4, &params);
   }

   // configure SOC7 of ADC-A to measure ADCIN12
   {
      PLX_AIN_ChannelParams_t params;
      PLX_AIN_setDefaultChannelParams(&params);
      params.scale =  6.666666667e+00f;
      params.offset = -1.000000000e+01f;

      params.trigsel = 1;
      PLX_AIN_setupChannel(AdcHandles[0], 6, 12, &params);
   }

   // configure SOC8 of ADC-A to measure ADCIN13
   {
      PLX_AIN_ChannelParams_t params;
      PLX_AIN_setDefaultChannelParams(&params);
      params.scale =  6.666666667e+00f;
      params.offset = -1.000000000e+01f;

      params.trigsel = 1;
      PLX_AIN_setupChannel(AdcHandles[0], 7, 13, &params);
   }

   // configure SOC9 of ADC-A to measure ADCIN7
   {
      PLX_AIN_ChannelParams_t params;
      PLX_AIN_setDefaultChannelParams(&params);
      params.scale =  1.000000000e+00f;
      params.offset = 0.000000000e+00f;

      params.trigsel = 1;
      PLX_AIN_setupChannel(AdcHandles[0], 8, 7, &params);
   }

   {
      PLX_PWR_sinit();
      PLX_DIO_sinit();
      static PLX_DIO_Obj_t doutObj;
      PLX_DIO_Handle_t doutHandle = PLX_DIO_init(&doutObj, sizeof(doutObj));
      PLX_DIO_OutputProperties_t props = {
         0
      };
      props.enableInvert = true;
      PLX_DIO_configureOut(doutHandle, 49, &props);
      PLX_PWR_configure(doutHandle, 10000);
   }
   PLX_PWM_sinit();
   for (int i = 0; i < 3; i++)
   {
      EpwmHandles[i] = PLX_PWM_init(&EpwmObj[i], sizeof(EpwmObj[i]));
   }

   // configure PWM1 at 5000.0 Hz in triangle mode
   //
   {
      PLX_PWM_Params_t params;
      PLX_PWM_setDefaultParams(&params);
      params.outMode = PLX_PWM_OUTPUT_MODE_DUAL;
      params.reg.TBPRD = 7500;
      params.reg.TBCTL.bit.CTRMODE = 2;

      params.reg.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO_PRD;
      // active state is low
      params.reg.DBCTL.bit.POLSEL = 1; // DB_ACTV_LOC
      // enable deadtime insertion
      params.reg.DBCTL.bit.OUT_MODE = 3; // DB_FULL_ENABLE
      params.reg.DBCTL.bit.IN_MODE = 0; // DBA_ALL
      // TZ settings
      params.reg.TZSEL.bit.CBC1 = 0;
      params.reg.TZSEL.bit.OSHT1 = 1;
      params.reg.TZSEL.bit.CBC2 = 0;
      params.reg.TZSEL.bit.OSHT2 = 0;
      params.reg.TZSEL.bit.CBC3 = 0;
      params.reg.TZSEL.bit.OSHT3 = 0;
      // force high when tripped
      params.reg.TZCTL.bit.TZA = 1;
      params.reg.TZCTL.bit.TZB = 1;
      PLX_PWM_configure(EpwmHandles[0], 1, &params);
      // configure deadtime to 2.000000e-06/2.000000e-06 seconds (rising/falling)
      PLX_PWM_setDeadTimeCounts(EpwmHandles[0], 150, 150);

      // PWM sequence starting with active state
      PLX_PWM_setSequence(EpwmHandles[0], 1);


   }
   // configure PWM2 at 5000.0 Hz in triangle mode
   //
   {
      PLX_PWM_Params_t params;
      PLX_PWM_setDefaultParams(&params);
      params.outMode = PLX_PWM_OUTPUT_MODE_DUAL;
      params.reg.TBPRD = 7500;
      params.reg.TBCTL.bit.CTRMODE = 2;

      params.reg.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO_PRD;
      // active state is low
      params.reg.DBCTL.bit.POLSEL = 1; // DB_ACTV_LOC
      // enable deadtime insertion
      params.reg.DBCTL.bit.OUT_MODE = 3; // DB_FULL_ENABLE
      params.reg.DBCTL.bit.IN_MODE = 0; // DBA_ALL
      // TZ settings
      params.reg.TZSEL.bit.CBC1 = 0;
      params.reg.TZSEL.bit.OSHT1 = 1;
      params.reg.TZSEL.bit.CBC2 = 0;
      params.reg.TZSEL.bit.OSHT2 = 0;
      params.reg.TZSEL.bit.CBC3 = 0;
      params.reg.TZSEL.bit.OSHT3 = 0;
      // force high when tripped
      params.reg.TZCTL.bit.TZA = 1;
      params.reg.TZCTL.bit.TZB = 1;
      PLX_PWM_configure(EpwmHandles[1], 2, &params);
      // configure deadtime to 2.000000e-06/2.000000e-06 seconds (rising/falling)
      PLX_PWM_setDeadTimeCounts(EpwmHandles[1], 150, 150);

      // PWM sequence starting with active state
      PLX_PWM_setSequence(EpwmHandles[1], 1);


   }
   // configure PWM3 at 5000.0 Hz in triangle mode
   //
   {
      PLX_PWM_Params_t params;
      PLX_PWM_setDefaultParams(&params);
      params.outMode = PLX_PWM_OUTPUT_MODE_DUAL;
      params.reg.TBPRD = 7500;
      params.reg.TBCTL.bit.CTRMODE = 2;

      params.reg.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO_PRD;
      // active state is low
      params.reg.DBCTL.bit.POLSEL = 1; // DB_ACTV_LOC
      // enable deadtime insertion
      params.reg.DBCTL.bit.OUT_MODE = 3; // DB_FULL_ENABLE
      params.reg.DBCTL.bit.IN_MODE = 0; // DBA_ALL
      // TZ settings
      params.reg.TZSEL.bit.CBC1 = 0;
      params.reg.TZSEL.bit.OSHT1 = 1;
      params.reg.TZSEL.bit.CBC2 = 0;
      params.reg.TZSEL.bit.OSHT2 = 0;
      params.reg.TZSEL.bit.CBC3 = 0;
      params.reg.TZSEL.bit.OSHT3 = 0;
      // force high when tripped
      params.reg.TZCTL.bit.TZA = 1;
      params.reg.TZCTL.bit.TZB = 1;
      PLX_PWM_configure(EpwmHandles[2], 3, &params);
      // configure deadtime to 2.000000e-06/2.000000e-06 seconds (rising/falling)
      PLX_PWM_setDeadTimeCounts(EpwmHandles[2], 150, 150);

      // PWM sequence starting with active state
      PLX_PWM_setSequence(EpwmHandles[2], 1);


   }
   PLX_DIO_sinit();
   for (int i = 0; i < 6; i++)
   {
      DinHandles[i] = PLX_DIO_init(&DinObj[i], sizeof(DinObj[i]));
   }

   {
      PLX_DIO_InputProperties_t props = {
         0
      };
      props.type = PLX_DIO_NOPULL;
      props.enableInvert = false;
      PLX_DIO_configureIn(DinHandles[1], 22, &props);
   }
   {
      PLX_DIO_InputProperties_t props = {
         0
      };
      props.type = PLX_DIO_NOPULL;
      props.enableInvert = false;
      PLX_DIO_configureIn(DinHandles[2], 14, &props);
   }
   {
      PLX_DIO_InputProperties_t props = {
         0
      };
      props.type = PLX_DIO_NOPULL;
      props.enableInvert = false;
      PLX_DIO_configureIn(DinHandles[3], 15, &props);
   }
   {
      PLX_DIO_InputProperties_t props = {
         0
      };
      props.type = PLX_DIO_NOPULL;
      props.enableInvert = false;
      PLX_DIO_configureIn(DinHandles[4], 26, &props);
   }
   {
      PLX_DIO_InputProperties_t props = {
         0
      };
      props.type = PLX_DIO_NOPULL;
      props.enableInvert = false;
      PLX_DIO_configureIn(DinHandles[5], 27, &props);
   }
   {
      PLX_DIO_InputProperties_t props = {
         0
      };
      props.type = PLX_DIO_NOPULL;
      props.enableInvert = false;
      PLX_DIO_configureIn(DinHandles[0], 48, &props);
   }
   PLX_DIO_sinit();
   for (int i = 0; i < 13; i++)
   {
      DoutHandles[i] = PLX_DIO_init(&DoutObj[i], sizeof(DoutObj[i]));
   }

   {
      PLX_DIO_OutputProperties_t props = {
         0
      };
      props.type = PLX_DIO_PUSHPULL;
      props.enableInvert = false;
      PLX_DIO_configureOut(DoutHandles[1], 59,  &props);
   }

   {
      PLX_DIO_OutputProperties_t props = {
         0
      };
      props.type = PLX_DIO_PUSHPULL;
      props.enableInvert = false;
      PLX_DIO_configureOut(DoutHandles[2], 34,  &props);
   }

   {
      PLX_DIO_OutputProperties_t props = {
         0
      };
      props.type = PLX_DIO_PUSHPULL;
      props.enableInvert = false;
      PLX_DIO_configureOut(DoutHandles[3], 63,  &props);
   }

   {
      PLX_DIO_OutputProperties_t props = {
         0
      };
      props.type = PLX_DIO_PUSHPULL;
      props.enableInvert = false;
      PLX_DIO_configureOut(DoutHandles[4], 10,  &props);
   }

   {
      PLX_DIO_OutputProperties_t props = {
         0
      };
      props.type = PLX_DIO_PUSHPULL;
      props.enableInvert = false;
      PLX_DIO_configureOut(DoutHandles[5], 11,  &props);
   }

   {
      PLX_DIO_OutputProperties_t props = {
         0
      };
      props.type = PLX_DIO_PUSHPULL;
      props.enableInvert = false;
      PLX_DIO_configureOut(DoutHandles[6], 6,  &props);
   }

   {
      PLX_DIO_OutputProperties_t props = {
         0
      };
      props.type = PLX_DIO_PUSHPULL;
      props.enableInvert = false;
      PLX_DIO_configureOut(DoutHandles[7], 7,  &props);
   }

   {
      PLX_DIO_OutputProperties_t props = {
         0
      };
      props.type = PLX_DIO_PUSHPULL;
      props.enableInvert = false;
      PLX_DIO_configureOut(DoutHandles[8], 8,  &props);
   }

   {
      PLX_DIO_OutputProperties_t props = {
         0
      };
      props.type = PLX_DIO_PUSHPULL;
      props.enableInvert = false;
      PLX_DIO_configureOut(DoutHandles[9], 9,  &props);
   }

   {
      PLX_DIO_OutputProperties_t props = {
         0
      };
      props.type = PLX_DIO_PUSHPULL;
      props.enableInvert = false;
      PLX_DIO_configureOut(DoutHandles[10], 60,  &props);
   }

   {
      PLX_DIO_OutputProperties_t props = {
         0
      };
      props.type = PLX_DIO_PUSHPULL;
      props.enableInvert = false;
      PLX_DIO_configureOut(DoutHandles[11], 61,  &props);
   }

   {
      PLX_DIO_OutputProperties_t props = {
         0
      };
      props.type = PLX_DIO_PUSHPULL;
      props.enableInvert = false;
      PLX_DIO_configureOut(DoutHandles[0], 13,  &props);
   }

   {
      PLX_DIO_OutputProperties_t props = {
         0
      };
      props.type = PLX_DIO_PUSHPULL;
      props.enableInvert = false;
      PLX_DIO_configureOut(DoutHandles[12], 19,  &props);
   }

   PLX_QEP_sinit();
   for (int i = 0; i < 1; i++)
   {
      QepHandles[i] = PLX_QEP_init(&QepObj[i], sizeof(QepObj[i]));
   }

   // configure QEP1 for pinset [A=GPIO20, B=GPIO21, I=GPIO23]
   {
      PLX_QEP_Params_t params;
      PLX_QEP_setDefaultParams(&params);
      params.QPOSMAX = 4095;
      params.QEPCTL.bit.PCRM = 1; // operate QEP in reset on max counter mode
      PLX_QEP_configureWithPins(QepHandles[0], 1, 20, 21, 23, &params);
   }

   {
      CpuTimer0Regs.TCR.bit.TSS = 1; // stop timer
      CpuTimer0Regs.TPRH.all = 0;
      CpuTimer0Regs.PRD.all = 7500 - 1;
      CpuTimer0Regs.TCR.bit.TRB = 1; // reload period
      CpuTimer0Regs.TCR.bit.TIE = 1; // enable trigger to SOC/interrupt

   }
   PLX_SPI_sinit();
   for (int i = 0; i < 1; i++)
   {
      SpiHandles[i] = PLX_SPI_init(&SpiObj[i], sizeof(SpiObj[i]));
   }

   // configure SPI-A
   {
      PLX_SPI_Params_t params;
      params.SPICHAR = 16;
      params.CLKPOLARITY = 1;
      params.CLKPHASE = 1;
      params.BAUDRATE = 6250000;
      params.CONTROLLERPERIPHERAL = 1;
      PLX_SPI_configure(SpiHandles[0], PLX_SPI_SPI_A, LSPCLK_HZ);
      PLX_SPI_setupPortViaPinSet(SpiHandles[0], 10, &params);
   }
   for (int i = 0; i < 1; i++)
   {
      CanHandles[i] = PLX_CANBUS_init(&CanObj[i], sizeof(CanObj[i]));
   }

   // Configure CAN A at 250000 Bit/s, with sampling at 60.0%
   {
      PLX_CANBUS_Params_t params;
      params.tseg1 = 8;
      params.tseg2 = 6;
      params.sjw = 4;
      params.sam = 0;
      params.brp = 20;
      params.autoBusOn = 1;
      PLX_CANBUS_configureViaPinSet(CanHandles[0], PLX_CANBUS_CAN_A, 0,
                                    &params);
      (void)PLX_CANBUS_setupMailbox(CanHandles[0], 1, 0, 5, 0, 8);
      (void)PLX_CANBUS_setupMailbox(CanHandles[0], 0, 1, 4, 0, 8);
   }
   DISPR_sinit();
   DISPR_configure((uint32_t)(7500), PilHandle, &TaskObj[0],
                   sizeof(TaskObj)/sizeof(DISPR_TaskObj_t));
   DISPR_registerIdleTask(&DSP_2_MOT_background);
   DISPR_registerSyncCallback(&DSP_2_MOT_syncTimers);
   DISPR_setPowerupDelay(10);
   DISPR_registerPanicCallback(&PanicCallback);
   {
      static int taskId = 0;
      // Task 0 at 1.000000e+04 Hz
      DISPR_registerTask(0, &Tasks, 7500L, (void *)&taskId);
   }
   EALLOW;
   AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1 = 1;       // enable SEQ1 interrupt (every EOS)
   PieVectTable.ADCINT = DSP_2_MOT_baseTaskInterrupt;
   PieVectTable.TINT0 = DSP_2_MOT_baseTaskInterrupt;      // interrupt for calling ADC s/w trigger
   EDIS;
   PieCtrlRegs.PIEIER1.bit.INTx7 = 1;
   PieCtrlRegs.PIEIER1.bit.INTx6 = 1;
   PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;


   // Post init code (for modules that depend on other modules)

   PLX_PWR_registerPwmChannel(EpwmHandles[0]);
   PLX_PWR_registerPwmChannel(EpwmHandles[1]);
   PLX_PWR_registerPwmChannel(EpwmHandles[2]);
}
