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.

Automotive 60W Brushless DC (BLDC) Motor Drive

Other Parts Discussed in Thread: MOTORWARE, DRV8301

hello:

I use TI offer

"Automotive 60W Brushless DC (BLDC) Motor Drive"

schematic and PCB  product  demo board .

I want to know : Can i use motorware labs program download to F28027f direct   or need edit labs then download?

there are" pwm in" and "pwm out" terminal is different contor with motorware program , where can i download the" TI 60W brushless DC motor drive" orignal program?

  • yanzhen,

    yes, you can use MotorWare projects.  you will have to create a custom set of hal.c/hal.h files for this hardware.  This is actually something that I know has been done by the group who made this design so I will see if they can post the files.

  • Here are the source files we used during design evaluation:

    drv_obj.h

    drv.h

    drv.c
    /* --COPYRIGHT--,BSD
     * 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/drv8301_027_ref/f28x/f2802xF/src/drv.c
    //! \brief Contains the various functions related to the DRV object (everything outside the CTRL system) 
    //!
    //! (C) Copyright 2011, Texas Instruments, Inc.
    
    
    // **************************************************************************
    // the includes
    
    // drivers
    
    // modules
    
    // platforms
    #include "drv.h"
    #include "user.h"
    #include "drv_obj.h"
    
    #ifdef FLASH
    #pragma CODE_SECTION(DRV_setupFlash,"ramfuncs");
    #endif
    
    // **************************************************************************
    // the defines
    
    
    // **************************************************************************
    // the globals
    
    DRV_Obj drv;
    
    
    // **************************************************************************
    // the functions
    
    void DRV_cal(DRV_Handle handle)
    {
      DRV_Obj *obj = (DRV_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
      DRV_AdcOffsetSelfCal(handle);
    
      // run oscillator compensation
      DRV_OscTempComp(handle);
    
      // disable the ADC clock
      CLK_disableAdcClock(obj->clkHandle);
    
      return;
    } // end of DRV_cal() function
    
    
    void DRV_OscTempComp(DRV_Handle handle)
    {
      DRV_Obj *obj = (DRV_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);
    
      DRV_osc1Comp(handle, Temperature);
    
      DRV_osc2Comp(handle, Temperature);
    
      return;
    } // end of DRV_OscTempComp() function
    
    
    void DRV_osc1Comp(DRV_Handle handle, const int16_t sensorSample)
    {
    	int16_t compOscFineTrim;
    	DRV_Obj *obj = (DRV_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, DRV_getOscTrimValue(getOsc1CoarseTrim(), compOscFineTrim));
    
        DISABLE_PROTECTED_REGISTER_WRITE_MODE;
    
        return;
    } // end of DRV_osc1Comp() function
    
    
    void DRV_osc2Comp(DRV_Handle handle, const int16_t sensorSample)
    {
    	int16_t compOscFineTrim;
    	DRV_Obj *obj = (DRV_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, DRV_getOscTrimValue(getOsc2CoarseTrim(), compOscFineTrim));
    
        DISABLE_PROTECTED_REGISTER_WRITE_MODE;
    
        return;
    } // end of DRV_osc2Comp() function
    
    
    uint16_t DRV_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 DRV_getOscTrimValue() function
    
    
    void DRV_AdcOffsetSelfCal(DRV_Handle handle)
    {
      DRV_Obj *obj = (DRV_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);
    
      // 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
      DRV_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 = DRV_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 DRV_AdcOffsetSelfCal() function
    
    
    void DRV_AdcCalChanSelect(DRV_Handle handle, const ADC_SocChanNumber_e chanNumber)
    {
      DRV_Obj *obj = (DRV_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 DRV_AdcCalChanSelect() function
    
    
    uint16_t DRV_AdcCalConversion(DRV_Handle handle)
    {
      DRV_Obj *obj = (DRV_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(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;
    
      //return the average
      return(Mean);
    } // end of DRV_AdcCalConversion() function
    
    
    void DRV_disableWdog(DRV_Handle drvHandle)
    {
      DRV_Obj *drv = (DRV_Obj *)drvHandle;
    
    
      WDOG_disable(drv->wdogHandle);
    
    
      return;
    } // end of DRV_disableWdog() function
    
    
    void DRV_disableGlobalInts(DRV_Handle handle)
    {
      DRV_Obj *obj = (DRV_Obj *)handle;
    
    
      CPU_disableGlobalInts(obj->cpuHandle);
    
      return;
    } // end of DRV_disableGlobalInts() function
    
    
    void DRV_enableAdcInts(DRV_Handle handle)
    {
      DRV_Obj *obj = (DRV_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 DRV_enableAdcInts() function
    
    
    void DRV_enableDebugInt(DRV_Handle handle)
    {
      DRV_Obj *obj = (DRV_Obj *)handle;
    
    
      CPU_enableDebugInt(obj->cpuHandle);
    
      return;
    } // end of DRV_enableDebugInt() function
    
    
    void DRV_enable8301(DRV_Handle handle)
    {
      DRV_Obj *obj = (DRV_Obj *)handle;
    
      GATE_enable(obj->gateHandle);
    
      return;
    }  // end of DRV_enable8301() function
    
    
    void DRV_enableGlobalInts(DRV_Handle handle)
    {
      DRV_Obj *obj = (DRV_Obj *)handle;
    
    
      CPU_enableGlobalInts(obj->cpuHandle);
    
      return;
    } // end of DRV_enableGlobalInts() function
    
    
    void DRV_enablePwmInt(DRV_Handle handle)
    {
      DRV_Obj *obj = (DRV_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 DRV_enablePwmInt() function
    
    
    void DRV_setupFaults(DRV_Handle handle)
    {
      DRV_Obj *obj = (DRV_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);
    
          // Clear any spurious fault
          PWM_clearOneShotTrip(obj->pwmHandle[cnt]);
        }
    
      return;
    } // end of DRV_setupFaults() function
    
    
    DRV_Handle DRV_init(void *pMemory,const size_t numBytes)
    {
      uint_least8_t cnt;
      DRV_Handle handle;
      DRV_Obj *obj;
    
    
      if(numBytes < sizeof(DRV_Obj))
        return((DRV_Handle)NULL);
    
    
      // assign the handle
      handle = (DRV_Handle)pMemory;
    
    
      // assign the object
      obj = (DRV_Obj *)handle;
    
    
      // initialize the watchdog driver
      obj->wdogHandle = WDOG_init((void *)WDOG_BASE_ADDR,sizeof(WDOG_Obj));
    
    
      // disable watchdog
      DRV_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 SPIA handle
      obj->spiAHandle = SPI_init((void *)SPIA_BASE_ADDR,sizeof(SPI_Obj));
    
    
      // initialize PWM handle
      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 power handle
      obj->pwrHandle = PWR_init((void *)PWR_BASE_ADDR,sizeof(PWR_Obj));
    
    
      // initialize timer drivers
      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->gateHandle = GATE_init(&obj->gate,sizeof(obj->gate));
    
    
      return(handle);
    } // end of DRV_init() function
    
    
    void DRV_setParams(DRV_Handle handle,const USER_Params *pUserParams)
    {
      uint_least8_t cnt;
      DRV_Obj *obj = (DRV_Obj *)handle;
      _iq beta_lp_pu = _IQ(pUserParams->offsetPole_rps/(float_t)pUserParams->ctrlFreq_Hz);
    
    
      DRV_setNumCurrentSensors(handle,pUserParams->numCurrentSensors);
      DRV_setNumVoltageSensors(handle,pUserParams->numVoltageSensors);
    
    
      for(cnt=0;cnt<DRV_getNumCurrentSensors(handle);cnt++)
        {
          DRV_setOffsetBeta_lp_pu(handle,DRV_SensorType_Current,cnt,beta_lp_pu);
          DRV_setOffsetInitCond(handle,DRV_SensorType_Current,cnt,_IQ(0.0));
          DRV_setOffsetValue(handle,DRV_SensorType_Current,cnt,_IQ(0.0));
        }
    
    
      for(cnt=0;cnt<DRV_getNumVoltageSensors(handle);cnt++)
        {
          DRV_setOffsetBeta_lp_pu(handle,DRV_SensorType_Voltage,cnt,beta_lp_pu);
          DRV_setOffsetInitCond(handle,DRV_SensorType_Voltage,cnt,_IQ(0.0));
          DRV_setOffsetValue(handle,DRV_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
      DRV_setupClks(handle);
    
    
      // Setup the PLL
      DRV_setupPll(handle,PLL_ClkFreq_60_MHz);
    
    
      // setup the PIE
      DRV_setupPie(handle);
    
    
      // run the device calibration
      DRV_cal(handle);
    
    
      // setup the peripheral clocks
      DRV_setupPeripheralClks(handle);
    
    
      // setup the GPIOs
      DRV_setupGpios(handle);
    
    
      // setup the flash
      DRV_setupFlash(handle);
    
    
      // setup the ADCs
      DRV_setupAdcs(handle);
    
    
      // setup the PWMs
      DRV_setupPwms(handle,
                    pUserParams->systemFreq_MHz,
                    pUserParams->pwmPeriod_usec,
                    USER_NUM_PWM_TICKS_PER_ISR_TICK);
    
    
      // setup the spiA
      DRV_setupSpiA(handle);
    
    
    
    
      // setup the timers
      DRV_setupTimers(handle,
                      pUserParams->systemFreq_MHz);
    
    
      // setup the drv8301 interface
      DRV_setupGate(handle);
    
    
      // set the default current bias
     {
       uint_least8_t cnt;
       _iq bias = _IQ12mpy(ADC_dataBias,_IQ(pUserParams->current_sf));
       
       for(cnt=0;cnt<DRV_getNumCurrentSensors(handle);cnt++)
         {
           DRV_setBias(handle,DRV_SensorType_Current,cnt,bias);
         }
     }
    
    
      //  set the current scale factor
     {
       _iq current_sf = _IQ(pUserParams->current_sf);
    
      DRV_setCurrentScaleFactor(handle,current_sf);
     }
    
    
      // set the default voltage bias
     {
       uint_least8_t cnt;
       _iq bias = _IQ(0.0);
       
       for(cnt=0;cnt<DRV_getNumVoltageSensors(handle);cnt++)
         {
           DRV_setBias(handle,DRV_SensorType_Voltage,cnt,bias);
         }
     }
    
    
      //  set the voltage scale factor
     {
       _iq voltage_sf = _IQ(pUserParams->voltage_sf);
    
      DRV_setVoltageScaleFactor(handle,voltage_sf);
     }
    
     return;
    } // end of DRV_setParams() function
    
    
    void DRV_setupAdcs(DRV_Handle handle)
    {
      DRV_Obj *obj = (DRV_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_Ext);
    
    
      // enable the ADC reference buffers
      ADC_enableRefBuffers(obj->adcHandle);
    
    
      // 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 internal (A5)
      ADC_setTempSensorSrc(obj->adcHandle,ADC_TempSensorSrc_Int);
    
    
      // 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 drv8301_027_ref
      // sample the first sample twice due to errata sprz342f
      //drv8301_027_ref
      //  ADC-A0	ADC_REF
      //  ADC-A1	IA-FB 				x
      //  ADC-A2	AIO2 mode (LED)
      //  ADC-A3	IC-FB				x
      //  ADC-A4	AIO4 mode (U5 OUT)
      //  ADC-A5	internal temp sensor
      //  ADC-A6	IC-FB
      //  ADC-A7	ADC-Vhb2 (phase B) 	x
      //  ADC-B0	not available on 027
      //  ADC-B1	IB-FB 				x
      //  ADC-B2	VDCBUS				x
      //  ADC-B3	IA-FB
      //  ADC-B4	ADC-Vhb3 (phase C)	x
      //  ADC-B5	not available on 027
      //  ADC-B6	IB-FB
      //  ADC-B7	ADC-Vhb1 (phase A) 	x
    
    
      ADC_setSocChanNumber(obj->adcHandle,ADC_SocNumber_0,ADC_SocChanNumber_A1);
      ADC_setSocTrigSrc(obj->adcHandle,ADC_SocNumber_0,ADC_SocTrigSrc_EPWM1_ADCSOCA);
      ADC_setSocSampleDelay(obj->adcHandle,ADC_SocNumber_0,ADC_SocSampleDelay_7_cycles);
    
      ADC_setSocChanNumber(obj->adcHandle,ADC_SocNumber_1,ADC_SocChanNumber_A1);
      ADC_setSocTrigSrc(obj->adcHandle,ADC_SocNumber_1,ADC_SocTrigSrc_EPWM1_ADCSOCA);
      ADC_setSocSampleDelay(obj->adcHandle,ADC_SocNumber_1,ADC_SocSampleDelay_7_cycles);
    
      ADC_setSocChanNumber(obj->adcHandle,ADC_SocNumber_2,ADC_SocChanNumber_B1);
      ADC_setSocTrigSrc(obj->adcHandle,ADC_SocNumber_2,ADC_SocTrigSrc_EPWM1_ADCSOCA);
      ADC_setSocSampleDelay(obj->adcHandle,ADC_SocNumber_2,ADC_SocSampleDelay_7_cycles);
    
      ADC_setSocChanNumber(obj->adcHandle,ADC_SocNumber_3,ADC_SocChanNumber_A3);
      ADC_setSocTrigSrc(obj->adcHandle,ADC_SocNumber_3,ADC_SocTrigSrc_EPWM1_ADCSOCA);
      ADC_setSocSampleDelay(obj->adcHandle,ADC_SocNumber_3,ADC_SocSampleDelay_7_cycles);
    
      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_7_cycles);
    
      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_7_cycles);
    
      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_7_cycles);
    
      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_7_cycles);
    
      return;
    } // end of DRV_setupAdcs() function
    
    
    void DRV_setupClks(DRV_Handle handle)
    {
      DRV_Obj *obj = (DRV_Obj *)handle;
    
    
      // enable internal oscillator 1
      CLK_enableOsc1(obj->clkHandle);
    
      // 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 oscillator source
      CLK_setOscSrc(obj->clkHandle,CLK_OscSrc_Internal);
    
      // set the low speed clock prescaler
      CLK_setLowSpdPreScaler(obj->clkHandle,CLK_LowSpdPreScaler_SysClkOut_by_4);
    
      // set the clock out prescaler
      CLK_setClkOutPreScaler(obj->clkHandle,CLK_ClkOutPreScaler_SysClkOut_by_1);
    
      return;
    } // end of DRV_setupClks() function
    
    
    void DRV_setupFlash(DRV_Handle handle)
    {
      DRV_Obj *obj = (DRV_Obj *)handle;
    
    
      FLASH_enablePipelineMode(obj->flashHandle);
    
      FLASH_setNumPagedReadWaitStates(obj->flashHandle,FLASH_NumPagedWaitStates_2);
    
      FLASH_setNumRandomReadWaitStates(obj->flashHandle,FLASH_NumRandomWaitStates_2);
    
      FLASH_setOtpWaitStates(obj->flashHandle,FLASH_NumOtpWaitStates_3);
    
      FLASH_setStandbyWaitCount(obj->flashHandle,FLASH_STANDBY_WAIT_COUNT_DEFAULT);
    
      FLASH_setActiveWaitCount(obj->flashHandle,FLASH_ACTIVE_WAIT_COUNT_DEFAULT);
    
      return;
    } // DRV_setupFlash() function
    
    
    void DRV_setupGate(DRV_Handle handle)
    {
      DRV_Obj *obj = (DRV_Obj *)handle;
    
      GATE_setSpiHandle(obj->gateHandle,obj->spiAHandle);
      GATE_setGpioHandle(obj->gateHandle,obj->gpioHandle);
      GATE_setGpioNumber(obj->gateHandle,GPIO_Number_32);	//EN_GATE
    } // DRV_setupGate() function
    
    
    void DRV_setupGpios(DRV_Handle handle)
    {
      DRV_Obj *obj = (DRV_Obj *)handle;
    
    
      //drv8301_027_ref
      // 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);
    
      // EPWM4A = PWM_Out (communications)
      GPIO_setMode(obj->gpioHandle,GPIO_Number_6,GPIO_6_Mode_EPWM4A);
    
      // SCIRXDA
      GPIO_setMode(obj->gpioHandle,GPIO_Number_7,GPIO_7_Mode_SCIRXDA);
    
      // SCITXDA
      GPIO_setMode(obj->gpioHandle,GPIO_Number_12,GPIO_12_Mode_SCITXDA);
    
      // SPI-SIMO or OCTWn
      GPIO_setMode(obj->gpioHandle,GPIO_Number_16,GPIO_16_Mode_SPISIMOA);
    
      // SPI-SOMI or FAULTn
      GPIO_setMode(obj->gpioHandle,GPIO_Number_17,GPIO_17_Mode_SPISOMIA);
    
      // SPI-CLK or SPI-SIMO
      GPIO_setMode(obj->gpioHandle,GPIO_Number_18,GPIO_18_Mode_SPICLKA);
    
      // SPI-STE or SDI
      GPIO_setMode(obj->gpioHandle,GPIO_Number_19,GPIO_19_Mode_GeneralPurpose);
      GPIO_setLow(obj->gpioHandle,GPIO_Number_19);
      GPIO_setDirection(obj->gpioHandle,GPIO_Number_19,GPIO_Direction_Output);
    
      // GPIO-28 (Fault)
      GPIO_setMode(obj->gpioHandle,GPIO_Number_28,GPIO_28_Mode_GeneralPurpose);
    
      // PWM_IN (communications, use XINT on edge)
      GPIO_setMode(obj->gpioHandle,GPIO_Number_29,GPIO_29_Mode_GeneralPurpose);
    
      // EN_GATE
      GPIO_setMode(obj->gpioHandle,GPIO_Number_32,GPIO_32_Mode_GeneralPurpose);
      GPIO_setLow(obj->gpioHandle,GPIO_Number_32);
      GPIO_setDirection(obj->gpioHandle,GPIO_Number_32,GPIO_Direction_Output);
    
      // OCTW
      GPIO_setMode(obj->gpioHandle,GPIO_Number_33,GPIO_33_Mode_GeneralPurpose);
    
      // PWRGD
      GPIO_setMode(obj->gpioHandle,GPIO_Number_34,GPIO_34_Mode_GeneralPurpose);
    
      // 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);
    
      return;
    }  // end of DRV_setupGpios() function
    
    
    void DRV_setupPie(DRV_Handle handle)
    {
      DRV_Obj *obj = (DRV_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 DRV_setupPie() function
    
    
    void DRV_setupPeripheralClks(DRV_Handle handle)
    {
      DRV_Obj *obj = (DRV_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_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_disableHrPwmClock(obj->clkHandle);
    
      CLK_disableI2cClock(obj->clkHandle);
    
      CLK_enableSciaClock(obj->clkHandle);
    
      CLK_enableSpiaClock(obj->clkHandle);
      
      CLK_enableTbClockSync(obj->clkHandle);
    
      return;
    } // end of DRV_setupPeripheralClks() function
    
    
    void DRV_setupPll(DRV_Handle handle,const PLL_ClkFreq_e clkFreq)
    {
      DRV_Obj *obj = (DRV_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 DRV_setupPll() function
    
    
    void DRV_setupPwms(DRV_Handle handle,
                       const uint_least16_t systemFreq_MHz,
                       const float_t pwmPeriod_usec,
                       const uint_least16_t numPwmTicksPerIsrTick)
    {
      DRV_Obj   *obj = (DRV_Obj *)handle;
      uint16_t   halfPeriod_cycles = (uint16_t)((float_t)systemFreq_MHz*pwmPeriod_usec) >> 1;
      uint_least8_t    cnt;
    
    
      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],DRV_PWM_DBRED_CNT);
    
          // setup the Dead-Band Falling Edge Delay Register (DBFED)
          PWM_setDeadBandFallingEdgeDelay(obj->pwmHandle[cnt],DRV_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]);
    
      // first step to synchronize the pwms
      CLK_disableTbClockSync(obj->clkHandle);
    
      // 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 DRV_setupPwms() function
    
    
    void DRV_setupSpiA(DRV_Handle handle)
    {
      DRV_Obj   *obj = (DRV_Obj *)handle;
    
      SPI_reset(obj->spiAHandle);
      SPI_setMode(obj->spiAHandle,SPI_Mode_Master);
      SPI_setClkPolarity(obj->spiAHandle,SPI_ClkPolarity_OutputRisingEdge_InputFallingEdge);
      SPI_enableTx(obj->spiAHandle);
      SPI_enableTxFifoEnh(obj->spiAHandle);
      SPI_enableTxFifo(obj->spiAHandle);
      SPI_setTxDelay(obj->spiAHandle,0x0010);
      SPI_setBaudRate(obj->spiAHandle,(SPI_BaudRate_e)(0x0001));
      SPI_setCharLength(obj->spiAHandle,SPI_CharLength_16_Bits);
      SPI_setSuspend(obj->spiAHandle,SPI_TxSuspend_free);
      SPI_enable(obj->spiAHandle);
    
      return;
    }  // end of DRV_setupSpiA() function
    void DRV_setupTimers(DRV_Handle handle,const uint_least16_t systemFreq_MHz)
    {
      DRV_Obj  *obj = (DRV_Obj *)handle;
      uint32_t  timerPeriod_cnts = ((uint32_t)systemFreq_MHz * 1000000) - 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_cnts);
      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_cnts);
      TIMER_setPreScaler(obj->timerHandle[1],0);
    
      // use timer 2 for general purpose
      TIMER_setDecimationFactor(obj->timerHandle[2],0);
      TIMER_setEmulationMode(obj->timerHandle[2],TIMER_EmulationMode_StopAtZero);
      TIMER_setPeriod(obj->timerHandle[2],timerPeriod_cnts);
      TIMER_setPreScaler(obj->timerHandle[2],0);
    
      return;
    }  // end of DRV_setupTimers() function
    
    
    void DRV_8301_SpiInterface(DRV_Handle handle,DRV_SPI_8301_Vars_t *Spi_8301_Vars)
    {
      DRV_Obj  *obj = (DRV_Obj *)handle;
      GATE_RegName_e  drvRegName;
      uint16_t drvDataNew;
    
    
      if(Spi_8301_Vars->SndCmd)
      {
        // Update Control Register 1
        drvRegName = GATE_RegName_Control_1;
        drvDataNew = Spi_8301_Vars->Ctrl_Reg_1.GATE_CURRENT |  \
                     Spi_8301_Vars->Ctrl_Reg_1.GATE_RESET   |  \
                     Spi_8301_Vars->Ctrl_Reg_1.PWM_MODE     |  \
                     Spi_8301_Vars->Ctrl_Reg_1.OC_MODE      |  \
                     Spi_8301_Vars->Ctrl_Reg_1.OC_ADJ_SET;
        GATE_writeData(obj->gateHandle,drvRegName,drvDataNew);
    
        // Update Control Register 2
        drvRegName = GATE_RegName_Control_2;
        drvDataNew = Spi_8301_Vars->Ctrl_Reg_2.OCTW_SET      |  \
                     Spi_8301_Vars->Ctrl_Reg_2.GAIN          |  \
                     Spi_8301_Vars->Ctrl_Reg_2.DC_CAL_CH1p2  |  \
                     Spi_8301_Vars->Ctrl_Reg_2.OC_TOFF;
        GATE_writeData(obj->gateHandle,drvRegName,drvDataNew);
    
        Spi_8301_Vars->SndCmd = false;
      }
    
      if(Spi_8301_Vars->RcvCmd)
      {
        // Update Status Register 1
        drvRegName = GATE_RegName_Status_1;
        drvDataNew = GATE_readData(obj->gateHandle,drvRegName);
        Spi_8301_Vars->Stat_Reg_1.FAULT = (bool)(drvDataNew & (uint16_t)GATE_STATUS1_FAULT_BITS);
        Spi_8301_Vars->Stat_Reg_1.GVDD_UV = (bool)(drvDataNew & (uint16_t)GATE_STATUS1_GVDD_UV_BITS);
        Spi_8301_Vars->Stat_Reg_1.PVDD_UV = (bool)(drvDataNew & (uint16_t)GATE_STATUS1_PVDD_UV_BITS);
        Spi_8301_Vars->Stat_Reg_1.OTSD = (bool)(drvDataNew & (uint16_t)GATE_STATUS1_OTSD_BITS);
        Spi_8301_Vars->Stat_Reg_1.OTW = (bool)(drvDataNew & (uint16_t)GATE_STATUS1_OTW_BITS);
        Spi_8301_Vars->Stat_Reg_1.FETHA_OC = (bool)(drvDataNew & (uint16_t)GATE_STATUS1_FETHA_OC_BITS);
        Spi_8301_Vars->Stat_Reg_1.FETLA_OC = (bool)(drvDataNew & (uint16_t)GATE_STATUS1_FETLA_OC_BITS);
        Spi_8301_Vars->Stat_Reg_1.FETHB_OC = (bool)(drvDataNew & (uint16_t)GATE_STATUS1_FETHB_OC_BITS);
        Spi_8301_Vars->Stat_Reg_1.FETLB_OC = (bool)(drvDataNew & (uint16_t)GATE_STATUS1_FETLB_OC_BITS);
        Spi_8301_Vars->Stat_Reg_1.FETHC_OC = (bool)(drvDataNew & (uint16_t)GATE_STATUS1_FETHC_OC_BITS);
        Spi_8301_Vars->Stat_Reg_1.FETLC_OC = (bool)(drvDataNew & (uint16_t)GATE_STATUS1_FETLC_OC_BITS);
    
        // Update Status Register 2
        drvRegName = GATE_RegName_Status_2;
        drvDataNew = GATE_readData(obj->gateHandle,drvRegName);
        Spi_8301_Vars->Stat_Reg_2.GVDD_OV = (bool)(drvDataNew & (uint16_t)GATE_STATUS2_GVDD_OV_BITS);
        Spi_8301_Vars->Stat_Reg_2.DeviceID = (uint16_t)(drvDataNew & (uint16_t)GATE_STATUS2_ID_BITS);
    
        // Update Control Register 1
        drvRegName = GATE_RegName_Control_1;
        drvDataNew = GATE_readData(obj->gateHandle,drvRegName);
        Spi_8301_Vars->Ctrl_Reg_1.GATE_CURRENT = (GATE_PeakCurrent_e)(drvDataNew & (uint16_t)GATE_CTRL1_GATE_CURRENT_BITS);
        Spi_8301_Vars->Ctrl_Reg_1.GATE_RESET = (GATE_Reset_e)(drvDataNew & (uint16_t)GATE_CTRL1_GATE_RESET_BITS);
        Spi_8301_Vars->Ctrl_Reg_1.PWM_MODE = (GATE_PwmMode_e)(drvDataNew & (uint16_t)GATE_CTRL1_PWM_MODE_BITS);
        Spi_8301_Vars->Ctrl_Reg_1.OC_MODE = (GATE_OcMode_e)(drvDataNew & (uint16_t)GATE_CTRL1_OC_MODE_BITS);
        Spi_8301_Vars->Ctrl_Reg_1.OC_ADJ_SET = (GATE_VdsLevel_e)(drvDataNew & (uint16_t)GATE_CTRL1_OC_ADJ_SET_BITS);
    
        // Update Control Register 2
        drvRegName = GATE_RegName_Control_2;
        drvDataNew = GATE_readData(obj->gateHandle,drvRegName);
        Spi_8301_Vars->Ctrl_Reg_2.OCTW_SET = (GATE_OcTwMode_e)(drvDataNew & (uint16_t)GATE_CTRL2_OCTW_SET_BITS);
        Spi_8301_Vars->Ctrl_Reg_2.GAIN = (GATE_ShuntAmpGain_e)(drvDataNew & (uint16_t)GATE_CTRL2_GAIN_BITS);
        Spi_8301_Vars->Ctrl_Reg_2.DC_CAL_CH1p2 = (GATE_DcCalMode_e)(drvDataNew & (uint16_t)(GATE_CTRL2_DC_CAL_1_BITS | GATE_CTRL2_DC_CAL_2_BITS));
        Spi_8301_Vars->Ctrl_Reg_2.OC_TOFF = (GATE_OcOffTimeMode_e)(drvDataNew & (uint16_t)GATE_CTRL2_OC_TOFF_BITS);
    
        Spi_8301_Vars->RcvCmd = false;
      }
    }
    
    
    void DRV_8301_SpiInterface_init(DRV_Handle handle,DRV_SPI_8301_Vars_t *Spi_8301_Vars)
    {
      DRV_Obj  *obj = (DRV_Obj *)handle;
      GATE_RegName_e  drvRegName;
      uint16_t drvDataNew;
      uint16_t n;
    
    
      // Update Control Register 1
      drvRegName = GATE_RegName_Control_1;
      drvDataNew = (GATE_PeakCurrent_1p70_A   | \
                    GATE_Reset_Normal         | \
                    GATE_PwmMode_Six_Inputs   | \
                    GATE_OcMode_CurrentLimit  | \
                    GATE_VdsLevel_0p730_V);
      GATE_writeData(obj->gateHandle,drvRegName,drvDataNew);
    
      // Update Control Register 2
      drvRegName = GATE_RegName_Control_2;
      drvDataNew = (GATE_OcTwMode_Both        | \
                    GATE_ShuntAmpGain_10VpV   | \
                    GATE_DcCalMode_Ch1_Load   | \
                    GATE_DcCalMode_Ch2_Load   | \
                    GATE_OcOffTimeMode_Normal);
      GATE_writeData(obj->gateHandle,drvRegName,drvDataNew);
    
    
      Spi_8301_Vars->SndCmd = false;
      Spi_8301_Vars->RcvCmd = false;
    
    
      // Wait for the DRV8301 registers to update
      for(n=0;n<200;n++)
        asm(" NOP");
    
    
      // Update Status Register 1
      drvRegName = GATE_RegName_Status_1;
      drvDataNew = GATE_readData(obj->gateHandle,drvRegName);
      Spi_8301_Vars->Stat_Reg_1.FAULT = (bool)(drvDataNew & (uint16_t)GATE_STATUS1_FAULT_BITS);
      Spi_8301_Vars->Stat_Reg_1.GVDD_UV = (bool)(drvDataNew & (uint16_t)GATE_STATUS1_GVDD_UV_BITS);
      Spi_8301_Vars->Stat_Reg_1.PVDD_UV = (bool)(drvDataNew & (uint16_t)GATE_STATUS1_PVDD_UV_BITS);
      Spi_8301_Vars->Stat_Reg_1.OTSD = (bool)(drvDataNew & (uint16_t)GATE_STATUS1_OTSD_BITS);
      Spi_8301_Vars->Stat_Reg_1.OTW = (bool)(drvDataNew & (uint16_t)GATE_STATUS1_OTW_BITS);
      Spi_8301_Vars->Stat_Reg_1.FETHA_OC = (bool)(drvDataNew & (uint16_t)GATE_STATUS1_FETHA_OC_BITS);
      Spi_8301_Vars->Stat_Reg_1.FETLA_OC = (bool)(drvDataNew & (uint16_t)GATE_STATUS1_FETLA_OC_BITS);
      Spi_8301_Vars->Stat_Reg_1.FETHB_OC = (bool)(drvDataNew & (uint16_t)GATE_STATUS1_FETHB_OC_BITS);
      Spi_8301_Vars->Stat_Reg_1.FETLB_OC = (bool)(drvDataNew & (uint16_t)GATE_STATUS1_FETLB_OC_BITS);
      Spi_8301_Vars->Stat_Reg_1.FETHC_OC = (bool)(drvDataNew & (uint16_t)GATE_STATUS1_FETHC_OC_BITS);
      Spi_8301_Vars->Stat_Reg_1.FETLC_OC = (bool)(drvDataNew & (uint16_t)GATE_STATUS1_FETLC_OC_BITS);
    
      // Update Status Register 2
      drvRegName = GATE_RegName_Status_2;
      drvDataNew = GATE_readData(obj->gateHandle,drvRegName);
      Spi_8301_Vars->Stat_Reg_2.GVDD_OV = (bool)(drvDataNew & (uint16_t)GATE_STATUS2_GVDD_OV_BITS);
      Spi_8301_Vars->Stat_Reg_2.DeviceID = (uint16_t)(drvDataNew & (uint16_t)GATE_STATUS2_ID_BITS);
    
      // Update Control Register 1
      drvRegName = GATE_RegName_Control_1;
      drvDataNew = GATE_readData(obj->gateHandle,drvRegName);
      Spi_8301_Vars->Ctrl_Reg_1.GATE_CURRENT = (GATE_PeakCurrent_e)(drvDataNew & (uint16_t)GATE_CTRL1_GATE_CURRENT_BITS);
      Spi_8301_Vars->Ctrl_Reg_1.GATE_RESET = (GATE_Reset_e)(drvDataNew & (uint16_t)GATE_CTRL1_GATE_RESET_BITS);
      Spi_8301_Vars->Ctrl_Reg_1.PWM_MODE = (GATE_PwmMode_e)(drvDataNew & (uint16_t)GATE_CTRL1_PWM_MODE_BITS);
      Spi_8301_Vars->Ctrl_Reg_1.OC_MODE = (GATE_OcMode_e)(drvDataNew & (uint16_t)GATE_CTRL1_OC_MODE_BITS);
      Spi_8301_Vars->Ctrl_Reg_1.OC_ADJ_SET = (GATE_VdsLevel_e)(drvDataNew & (uint16_t)GATE_CTRL1_OC_ADJ_SET_BITS);
    
      // Update Control Register 2
      drvRegName = GATE_RegName_Control_2;
      drvDataNew = GATE_readData(obj->gateHandle,drvRegName);
      Spi_8301_Vars->Ctrl_Reg_2.OCTW_SET = (GATE_OcTwMode_e)(drvDataNew & (uint16_t)GATE_CTRL2_OCTW_SET_BITS);
      Spi_8301_Vars->Ctrl_Reg_2.GAIN = (GATE_ShuntAmpGain_e)(drvDataNew & (uint16_t)GATE_CTRL2_GAIN_BITS);
      Spi_8301_Vars->Ctrl_Reg_2.DC_CAL_CH1p2 = (GATE_DcCalMode_e)(drvDataNew & (uint16_t)(GATE_CTRL2_DC_CAL_1_BITS | GATE_CTRL2_DC_CAL_2_BITS));
      Spi_8301_Vars->Ctrl_Reg_2.OC_TOFF = (GATE_OcOffTimeMode_e)(drvDataNew & (uint16_t)GATE_CTRL2_OC_TOFF_BITS);
    
      return;
    }
    
    // end of file
    

  • thank you ! thank you! thank you!

    chris &  clark

  • hi: chris  and clark

    thanks your code .

    another question :

    1:this 60W bldc board use a ADC port  as I/O ,  and control a LED  (follow red code). how can I configure ADC as AIO port? I didn't see datasheet say this .

     //configure the SOCs for drv8301_027_ref
      // sample the first sample twice due to errata sprz342f
      //drv8301_027_ref
      //  ADC-A0 ADC_REF
      //  ADC-A1 IA-FB     x
      //  ADC-A2 AIO2 mode (LED)
      //  ADC-A3 IC-FB    x
      //  ADC-A4 AIO4 mode (U5 OUT)
      //  ADC-A5 internal temp sensor
      //  ADC-A6 IC-FB
      //  ADC-A7 ADC-Vhb2 (phase B)  x
      //  ADC-B0 not available on 027
      //  ADC-B1 IB-FB     x
      //  ADC-B2 VDCBUS    x
      //  ADC-B3 IA-FB
      //  ADC-B4 ADC-Vhb3 (phase C) x
      //  ADC-B5 not available on 027
      //  ADC-B6 IB-FB
      //  ADC-B7 ADC-Vhb1 (phase A)  x

    2: This board's JTAG port I want as gerneral I/O port  ,  because this board I want it sensor and sensorless  BLDC.  JTAG port will change to HALL sensor  input.

    but how can I configure this ?  how can I option when IN or OUT ?

    follow is configure now:

      // JTAG
      GPIO_setMode(obj->gpioHandle,GPIO_Number_35,GPIO_35_Mode_JTAG_TDI);//how can i  JTAG as generalpurpose I/O
      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);

     

  • thanks

    I know do it now.
  • hi:

    clark:

    there is a question: in your drv.c 

    void DRV_setupGate(DRV_Handle handle)
    {
      DRV_Obj *obj = (DRV_Obj *)handle;

      GATE_setSpiHandle(obj->gateHandle,obj->spiAHandle);
      GATE_setGpioHandle(obj->gateHandle,obj->gpioHandle);
      GATE_setGpioNumber(obj->gateHandle,GPIO_Number_32); //EN_GATE different
    } // DRV_setupGate() function

    in motorware 15 , hal .c  , there isnot this function.   when I add this function into hal.c  .    but cannot compily , 

    because I didn't fid  "#include "sw/drivers/gate/drv8301/src/32b/f28x/f2806x/gate.h"  "   in motorware 15.  can you post it ?

  • DRV is replaced by HAL

    the same function is included:

    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

    sw/drivers/gate/drv8301/src/32b/f28x/f2806x/gate.h

     is replaced by sw\drivers\drvic\drv8301\src\32b\f28x\f2806x\drv8301.h

  • hi:  Chris

    in 60W BLDC's  hardware  ,there is a "IN_PWM" signal input GPIO_29 .   how deal with this "IN_PWM"   ?  and what is it for?   can it option the speed of motor?

    thanks you!