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/DRV8305-Q1EVM: Example code for PWM IN?

Part Number: DRV8305-Q1EVM
Other Parts Discussed in Thread: MOTORWARE, C2000WARE,

Tool/software: Code Composer Studio

Hi All,

I'd like to use the PWM IN line on the DRV8305-Q1EVM to control the KRPM reference.  I can't find any example code to get it up and running, and I'm not finding a ton of documentation on motorware as a whole.  Am I missing something?  In the past I've tried stubbing in C2000ware code, but the libraries don't play particularly nicely.

Thanks in advance,

Brian

  • Hi Brian,

    "I'd like to use the PWM IN line on the DRV8305-Q1EVM to control the KRPM reference." What do you mean by this? 1 x , 3 x or 6 x PWM IN line?
  • Hi Rick,

    You'll see in the schematic that there is a line labeled "PWM IN".  I'm assuming that's for a PWM input control line for throttle.  Is that a false assumption?

    Thanks,

    Brian

  • Hi Rick,

    It looks like there's an app note called tiduak1.pdf that describes what I'm looking to do.  Has anyone ported that to the q1evm?  I've tried to do my own port and thus far it's not working-- looks like the ecap interrupt isn't firing.  I've pasted my changes from a modified lab 3b below.  Any thoughts?

    Objective:  Map code changes from tiduak1.pdf prop drive demo project onto DRV8305-q1evm
    ==============================


    For each project, add this to the .project file:

    <link>
                <name>cap.c</name>
                <type>1</type>
                <locationURI>MW_INSTALL_DIR/sw/drivers/timer/src/32b/f28x/f2802x/cap.c</locationURI>
            </link>








    1.  HAL.C:
    ~line 986
     //NOTE: BK MODDED THIS:
      // Unused (PWM_IN)
      //GPIO_setMode(obj->gpioHandle,GPIO_Number_5,GPIO_5_Mode_GeneralPurpose);
      GPIO_setMode(obj->gpioHandle,GPIO_Number_5,GPIO_5_Mode_ECAP1);
     
     2.  Hal_obj.H
    line 43 #include "sw/drivers/adc/src/32b/f28x/f2802x/cap.h"

    line 135:
    typedef struct _HAL_Obj_
    {
      ADC_Handle    adcHandle;        //!< the ADC handle
     
      CAP_Handle    capHandle;          //!< The eCap handle-- bk added

      CLK_Handle    clkHandle;        //!< the clock handle
     
     3.  Hal.c

     line 608
      //bk added:
      obj->capHandle = CAP_init((void *)CAP1_BASE_ADDR,sizeof(CAP_Obj));


      //Setup ISR.

      Add to hal.h:

      line 1304:
      //! \brief Setup the ECAP
    //! \param[in] handle         The hardware abstraction layer (HAL) handle
    void HAL_setupeCAP(HAL_Handle handle);

    hal.c:
    line 1350:

    //BK Added below:
    // ECAP
    void HAL_setupeCAP(HAL_Handle handle)
    {
        HAL_Obj *obj = (HAL_Obj *) handle;

        CAP_setModeCap(obj->capHandle); // set mode to CAP

        //Disables counter synchronization
        CAP_disableSyncIn(obj->capHandle);

        //Sets the capture event polarity
        CAP_setCapEvtPolarity(obj->capHandle, CAP_Event_1, CAP_Polarity_Rising);

        //Sets the capture event polarity
        CAP_setCapEvtPolarity(obj->capHandle, CAP_Event_2, CAP_Polarity_Falling);

        //Sets the capture event counter reset configuration
        CAP_setCapEvtReset(obj->capHandle, CAP_Event_1, CAP_Reset_Disable);

        //Sets the capture event counter reset configuration (reset counting here)
        CAP_setCapEvtReset(obj->capHandle, CAP_Event_2, CAP_Reset_Enable);

        // continous timer
        CAP_setCapContinuous(obj->capHandle);

        //Set the stop/wrap mode to 2 events
        CAP_setStopWrap(obj->capHandle, CAP_Stop_Wrap_CEVT2);

        //Enables loading of CAP1-4 on capture event
        CAP_enableCaptureLoad(obj->capHandle);

        // Enables Time Stamp counter to running
        CAP_enableTimestampCounter(obj->capHandle);

        //Enables capture (CAP) interrupt source
        CAP_enableInt(obj->capHandle, CAP_Int_Type_CEVT2);

        // enable eCAP interrupt
        PIE_enableInt(obj->pieHandle, PIE_GroupNumber_4, PIE_InterruptSource_ECAP1);

        // enable CPU ECAP Group interrupts
        CPU_enableInt(obj->cpuHandle, CPU_IntNumber_4);

        return;
    } // end of HAL_setupCAP() function


    line1082:
     CLK_enableEcap1Clock(obj->clkHandle);


     hal.c:


    //BK added:
     line 160
    //ecap
    extern interrupt void ecapISR(void);

    hal.h:
    line 487


      //BK Added:
      //ecap:
     static inline void HAL_initIntVectorTable(HAL_Handle handle)
    ...
      //BK Added:
      //ecap:
      pie->ECAP1_INT = &ecapISR;

      DISABLE_PROTECTED_REGISTER_WRITE_MODE;

      return;
      main lab file:

    line (top)

    // bk added:
    #define SPEED_BASE_KRPM     7.7  // Max motor speed for DJI E300 920 Kv at 11 V

    _iq gSpeedRef_duty = _IQ(0.0);   // Speed reference from external controller

    uint32_t gSpeedRef_Ok = 0;       // Safety check for speed reference signal


    In update global variables:


      //BK ADDED:
        gMotorVars.SpeedRef_krpm = gSpeedRef_duty * SPEED_BASE_KRPM;


    Line (Main isr)

    // Check if speed reference signal is active
      // If more than 2000 service routine cycles pass without signal, disable motor
      if (gSpeedRef_Ok++ > 2000)
      {
          gSpeedRef_duty = _IQ(0);
          gMotorVars.Flag_Run_Identify = 0;
          gSpeedRef_Ok = 0;
      }





    Line (bottom)

      __interrupt void ecapISR(void)
    {
        // Clear capture (CAP) interrupt flags
        CAP_clearInt(halHandle->capHandle, CAP_Int_Type_All);

        // Compute the PWM high period (rising edge to falling edge)
        uint32_t PwmDuty = (uint32_t) CAP_getCap2(halHandle->capHandle) - (uint32_t) CAP_getCap1(halHandle->capHandle);

        // Assign the appropriate speed command, combine 0-5% and 95-100%
        // 0-100% speed is proportional to 1-2ms high period
        // 60MHz * 2ms = 120000

        // 0-1%
        if (PwmDuty <= 61000)
        {
            gSpeedRef_Ok = 0;
            gSpeedRef_duty = _IQ(0);
            gMotorVars.Flag_Run_Identify = 0;
        }
        // 1-99%
        if ((PwmDuty > 61000) && (PwmDuty < 119000))
        {
            gSpeedRef_Ok = 0;
            gSpeedRef_duty = _IQdiv(PwmDuty - 60000, 60000);
            gMotorVars.Flag_Run_Identify = 1;
        }
        // 99-100%
        else if (PwmDuty >= 119000)
        {
            gSpeedRef_Ok = 0;
            gSpeedRef_duty = _IQ(1.0);
            gMotorVars.Flag_Run_Identify = 1;
        }
        // Catch all
        else
        {
            gSpeedRef_duty = _IQ(0);
            gMotorVars.Flag_Run_Identify = 0;
        }

        // Clears an interrupt defined by group number
        PIE_clearInt(halHandle->pieHandle, PIE_GroupNumber_4);
    }  // end of ecapISR() function

  • Hi Brian,

    Our C2000 experts have been contacted.
  • Brian,

    let's start by checking the eCAP's interrupt configuration during run time.

    Take a look at "Figure 76. Overview: Multiplexing of Interrupts Using the PIE Block" in the Systems Control and Interrupt Reference Guide, each of these gates need to be enabled to allow the interrupt to reach the C28 core. What are the values of these registers? 

    It's probably good to check if you have any flags in the eCAP's corresponding IFR.

    Regards,
    Cody