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.

TMS320F28027F: Speed Control of bldc motor using pwm signal as reference.

Part Number: TMS320F28027F
Other Parts Discussed in Thread: TMS320F28379D, DRV8301,

Hi everyone,

I'm trying to make a flight control board based on Ti products where I'll have a central controller which will give PWM signals (throttle) to my ESC's and the ESC's will in turn control the speed of the motor. For my central processor I've chosen tms320f28379d and for my ESC's I've chosen tms320f28027f which comes equipped with INSTA-SPIN FOC and drv8301 for driving my motors. I've added the following to my motoware 5b project to achieve my objective,

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 

This code was given in one of the tiduak documents. When i flashed this code on my processor, and tried to set the gMotorVars_enableSys variable to 1, for some reason the processor turns it back to 0. I also tried using this program with insta-spin universal gui but as soon as i hit run, the processor fails to identify the motor and the gui un-checks run. I also specified my motor type and motor parameters under the name my_motor but it didn't help. Please help me with this problem, I'm stuck on this since 3 weeks now also if there are any documents relevant to my predicament, kindly provide me with their links.

Regards.

  • 1. Did you use the GPIO5 as pwm for motor drive?
    2. What pwm frequency were you using for your project? It's not a good idea to use a eCAP interrupt to calculate the reference speed if the frequency of ISR for motor drive is very high, the eCAP ISR maybe cause overflow. You can read the eCAP register in PWM ISR and calculate the reference speed in background loop if the response is ok for you.

  • 1.Gpio 0,1,2,3,4,5 of tms320f28027f are being used for mosfets 1A,1B,2A,2B,3A,3B, which will drive the bldc motor. Gpio 19 was used to capture pwm

    2.The pwm signal given by tms320f28379d is given to tms320f28027f, it will then check the duty cycle of the pwm signal and depending on the % duty cycle, it will vary the speed of the motor. The reference pwm signal has a frequency of 500Hz, the minimum duty cycle is 1ms and maximum is 2ms. I tried putting the capture isr into the pwm isr, it still didnt work. When is connect the pwm signal to Gpio 19, it goes to a value of 4000 and remains constant.

  • 1. Did you configure the GPIO19 to a capture function since you were using GPIO19, not GPIO5.
    GPIO_setMode(obj->gpioHandle,GPIO_Number_19,GPIO_19_Mode_ECAP1)

    2. And add a eCAP setup functions as below in hal.c to call it in HAL_setParams().

    void HAL_setupCaps(HAL_Handle handle)
    {
    HAL_Obj *obj = (HAL_Obj *)handle;

    CAP_disableInt(obj->capHandle[0], CAP_Int_Type_All); // Disable all capture interrupts
    CAP_clearInt(obj->capHandle[0], CAP_Int_Type_All); // Clear all CAP interrupt flags
    CAP_disableCaptureLoad(obj->capHandle[0]); // Disable CAP1-CAP4 register loads
    CAP_disableTimestampCounter(obj->capHandle[0]); // Make sure the counter is stopped

    // Configure peripheral registers //
    CAP_setCapContinuous(obj->capHandle[0]); // Continous
    CAP_setStopWrap(obj->capHandle[0], CAP_Stop_Wrap_CEVT4); // Stop at 4 events

    CAP_setCapEvtPolarity(obj->capHandle[0], CAP_Event_1, CAP_Polarity_Rising); // Rising edge
    CAP_setCapEvtPolarity(obj->capHandle[0], CAP_Event_2, CAP_Polarity_Falling); // Falling edge
    CAP_setCapEvtPolarity(obj->capHandle[0], CAP_Event_3, CAP_Polarity_Rising); // Rising edge
    CAP_setCapEvtPolarity(obj->capHandle[0], CAP_Event_4, CAP_Polarity_Falling); // Falling edge

    CAP_setCapEvtReset(obj->capHandle[0], CAP_Event_1, CAP_Reset_Enable); // Difference operation
    CAP_setCapEvtReset(obj->capHandle[0], CAP_Event_2, CAP_Reset_Enable); // Difference operation
    CAP_setCapEvtReset(obj->capHandle[0], CAP_Event_3, CAP_Reset_Enable); // Difference operation
    CAP_setCapEvtReset(obj->capHandle[0], CAP_Event_4, CAP_Reset_Enable); // Difference operation

    CAP_enableSyncIn(obj->capHandle[0]); // Enable sync in
    CAP_setSyncOut(obj->capHandle[0], CAP_SyncOut_SyncIn); // Pass through

    CAP_enableTimestampCounter(obj->capHandle[0]); // Start Counter
    CAP_enableCaptureLoad(obj->capHandle[0]); // Enable CAP1-CAP4 register loads

    return;
    } // HAL_setupCaps() function

    3. And then you can use CAP_getCap1(obj->capHandle[0]), CAP_getCap2(obj->capHandle[0]), CAP_getCap3(obj->capHandle[0]) and CAP_getCap4(obj->capHandle[0]) to read the register to calculate the pwm duty in motor control ISR.