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/TMS320F28054F: Migration of instaspin project from TMS320F28027 to TMS320F28054 microncontrollers

Part Number: TMS320F28054F
Other Parts Discussed in Thread: TMS320F28027, TMS320F28054, TMS320F28027F

Tool/software: Code Composer Studio

Dear all,

So far I have been working with my own TMS320F28027 HW design, on the basis on boostxldrv8301_revB development kit, in order to control a PMSM motor. Now, I have a new HW design which includes the TMS320F28054. The switches, buttons, SPI and so on are working fine, but not the PWM output, so the motor is not spinning. Watching the signals with an oscilloscope the PWM duty cycles is 50% and the frequency 30 KHz (which is right). If I modify the speed reference, nothing happens, the PWM doesn’t change.

Let me explain briefly what I did:

  1. Create different build configurations for both microcontrollers. If the program is loaded into the TMS320F28027, the motor spins.
  2. Redirect the currents, voltages and DC voltage (gAdcData) to the new ADCs.

ADC

TMS320F28027

TMS320F28054

IA

ADCINB1

ADCINB0

IB

ADCINB3        

ADCINB2

IC

ADCINB7

ADCINB3

VA

ADCINA3

ADCINA5

VB

ADCINA1

ADCINA2

VC

ADCINA0

ADCINA0

dcBus

ADCINA7

ADCINA7

 

3. Any change in the PWM configuration registers, so the outputs are the same for both micros.

Summarize, with the new HW and micro, the motor never spins. In the debugger, I can’t see any important variation on gAdcData or gPwmData.

 

Thank you in advance, any help will be appreciate.

  • Hi,

    to clarify...I didn't modify any PGA register
  • Hi Masky,

    I will be looking into this issue for you. I understand you are working on the boostxldrv8301_revB development kit.

    Are you using a TI example software or your own software?

    Regards,
    Kris
  • Hi Kris,

    I'm working with my own HW and  SW. With the old microcontroller (TMS320F28027F), I was working with my own HW and SW too, but both designs were on the basis of boostxldrv8301_revB and LaunchpadXL.

    Now, with the new HW, I only did a few changes on hal and gpios modules, but the motor never spins. In these days I did more test:

    1. I verified the V adc channels and those are OK.
    2. In the mainISR interrupt, if I fix the PWM duty cycle before call to the HAL_writePwmData, the PWM output are changed OK. 

    I guess the problem could be in the CTRL_run function, so the SVGEN_RUN returns a bad duty cycle, but I'm completely loss:-(.

    Thank you for your help.

  • Masky,

    Thank you for the extra information.

    Are you able to post the following:

    - Your PWM initialization code
    - The change you make in Main ISR which fixes the issue
    - The relevant portions from HAL_writePwmData

    Have you tried creating variables and recording the values that HAL_writePwmData is using when the code isn't working?  It would be good to see what is actually being written, as it does sound like incorrect values or possibly bad shadow-active load timing.


    Thanks,
    Kris

  • Hi Kris,

    to clarify, the issue was not fixed. I only checked that HAL_writePwmData works as intended. So, below the information you ask for:

    • PWM initialization code.
    void HAL_setupPwms(HAL_Handle handle,
                       const uint_least16_t systemFreq_MHz,
                       const float_t pwmPeriod_usec,
                       const uint_least16_t numPwmTicksPerIsrTick)
    {
      HAL_Obj   *obj = (HAL_Obj *)handle;
      uint16_t   halfPeriod_cycles = (uint16_t)((float_t)systemFreq_MHz*pwmPeriod_usec) >> 1;
      uint_least8_t    cnt;
    
    
      // turns off the outputs of the EPWM peripherals which will put the power switches
      // into a high impedance state.
      PWM_setOneShotTrip(obj->pwmHandle[PWM_Number_1]);
      PWM_setOneShotTrip(obj->pwmHandle[PWM_Number_2]);
      PWM_setOneShotTrip(obj->pwmHandle[PWM_Number_3]);
    
      for(cnt=0;cnt<3;cnt++)
        {
          // setup the Time-Base Control Register (TBCTL)
          PWM_setCounterMode(obj->pwmHandle[cnt],PWM_CounterMode_UpDown);
          PWM_disableCounterLoad(obj->pwmHandle[cnt]);
          PWM_setPeriodLoad(obj->pwmHandle[cnt],PWM_PeriodLoad_Immediate);
          PWM_setSyncMode(obj->pwmHandle[cnt],PWM_SyncMode_EPWMxSYNC);
          PWM_setHighSpeedClkDiv(obj->pwmHandle[cnt],PWM_HspClkDiv_by_1);
          PWM_setClkDiv(obj->pwmHandle[cnt],PWM_ClkDiv_by_1);
          PWM_setPhaseDir(obj->pwmHandle[cnt],PWM_PhaseDir_CountUp);
          PWM_setRunMode(obj->pwmHandle[cnt],PWM_RunMode_FreeRun);
    
          // setup the Timer-Based Phase Register (TBPHS)
          PWM_setPhase(obj->pwmHandle[cnt],0);
    
          // setup the Time-Base Counter Register (TBCTR)
          PWM_setCount(obj->pwmHandle[cnt],0);
    
          // setup the Time-Base Period Register (TBPRD)
          // set to zero initially
          PWM_setPeriod(obj->pwmHandle[cnt],0);
    
          // setup the Counter-Compare Control Register (CMPCTL)
          PWM_setLoadMode_CmpA(obj->pwmHandle[cnt],PWM_LoadMode_Zero);
          PWM_setLoadMode_CmpB(obj->pwmHandle[cnt],PWM_LoadMode_Zero);
          PWM_setShadowMode_CmpA(obj->pwmHandle[cnt],PWM_ShadowMode_Shadow);
          PWM_setShadowMode_CmpB(obj->pwmHandle[cnt],PWM_ShadowMode_Immediate);
    
          // setup the Action-Qualifier Output A Register (AQCTLA) 
          PWM_setActionQual_CntUp_CmpA_PwmA(obj->pwmHandle[cnt],PWM_ActionQual_Set);
          PWM_setActionQual_CntDown_CmpA_PwmA(obj->pwmHandle[cnt],PWM_ActionQual_Clear);
    
          // setup the Dead-Band Generator Control Register (DBCTL)
          PWM_setDeadBandOutputMode(obj->pwmHandle[cnt],PWM_DeadBandOutputMode_EPWMxA_Rising_EPWMxB_Falling);
          PWM_setDeadBandPolarity(obj->pwmHandle[cnt],PWM_DeadBandPolarity_EPWMxB_Inverted);
    
          // setup the Dead-Band Rising Edge Delay Register (DBRED)
          PWM_setDeadBandRisingEdgeDelay(obj->pwmHandle[cnt],HAL_PWM_DBRED_CNT);
    
          // setup the Dead-Band Falling Edge Delay Register (DBFED)
          PWM_setDeadBandFallingEdgeDelay(obj->pwmHandle[cnt],HAL_PWM_DBFED_CNT);
          // setup the PWM-Chopper Control Register (PCCTL)
          PWM_disableChopping(obj->pwmHandle[cnt]);
    
          // setup the Trip Zone Select Register (TZSEL)
          PWM_disableTripZones(obj->pwmHandle[cnt]);
        }
    
    
      // setup the Event Trigger Selection Register (ETSEL)
      PWM_disableInt(obj->pwmHandle[PWM_Number_1]);
      PWM_setSocAPulseSrc(obj->pwmHandle[PWM_Number_1],PWM_SocPulseSrc_CounterEqualZero);
      PWM_enableSocAPulse(obj->pwmHandle[PWM_Number_1]);
      
    
      // setup the Event Trigger Prescale Register (ETPS)
      if(numPwmTicksPerIsrTick == 3)
        {
          PWM_setIntPeriod(obj->pwmHandle[PWM_Number_1],PWM_IntPeriod_ThirdEvent);
          PWM_setSocAPeriod(obj->pwmHandle[PWM_Number_1],PWM_SocPeriod_ThirdEvent);
        }
      else if(numPwmTicksPerIsrTick == 2)
        {
          PWM_setIntPeriod(obj->pwmHandle[PWM_Number_1],PWM_IntPeriod_SecondEvent);
          PWM_setSocAPeriod(obj->pwmHandle[PWM_Number_1],PWM_SocPeriod_SecondEvent);
        }
      else
        {
          PWM_setIntPeriod(obj->pwmHandle[PWM_Number_1],PWM_IntPeriod_FirstEvent);
          PWM_setSocAPeriod(obj->pwmHandle[PWM_Number_1],PWM_SocPeriod_FirstEvent);
        }
    
    
      // setup the Event Trigger Clear Register (ETCLR)
      PWM_clearIntFlag(obj->pwmHandle[PWM_Number_1]);
      PWM_clearSocAFlag(obj->pwmHandle[PWM_Number_1]);
    
      // 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 HAL_setupPwms() function

    • Main ISR code. In comments the lines to fix the duty cycle.
    interrupt void mainISR(void)
    {
    
    	if(ThyCnt) ThyCnt--;
    
      // acknowledge the ADC interrupt
      HAL_acqAdcInt(halHandle,ADC_IntNumber_1);
    
      // convert the ADC data
      HAL_readAdcData(halHandle,&gAdcData);
    
      // run the controller
      CTRL_run(ctrlHandle,halHandle,&gAdcData,&gPwmData);
    
    // write the PWM compare values
    //  gPwmData.Tabc.value[0]=PWM0;
    //  gPwmData.Tabc.value[1]=PWM1;
    //  gPwmData.Tabc.value[2]=PWM2;
      HAL_writePwmData(halHandle,&gPwmData);
    
      calcPosRel(ctrlHandle);					// calcula angulo recorrid0 _IQ20
    
      // setup the controller
      CTRL_setup(ctrlHandle);
    
      return;
    } // end of mainISR() function

    • Finally, the HAL_writePwmData.
    //! \brief     Writes PWM data to the PWM comparators for motor control
    //! \param[in] handle    The hardware abstraction layer (HAL) handle
    //! \param[in] pPwmData  The pointer to the PWM data
    static inline void HAL_writePwmData(HAL_Handle handle,HAL_PwmData_t *pPwmData)
    {
      uint_least8_t cnt;
      HAL_Obj *obj = (HAL_Obj *)handle;
      PWM_Obj *pwm;
      _iq period;
      _iq pwmData_sat;
      _iq pwmData_sat_dc;
      _iq value;
      uint16_t value_sat;
    
      for(cnt=0;cnt<3;cnt++)
        {
          pwm = (PWM_Obj *)obj->pwmHandle[cnt];
          period = (_iq)pwm->TBPRD;
          pwmData_sat = _IQsat(pPwmData->Tabc.value[cnt],_IQ(1.0),_IQ(-1.0));
          pwmData_sat_dc = _IQmpy(pwmData_sat + _IQ(1.0), _IQ(0.5));
          value = _IQmpy(pwmData_sat_dc, period);
          value_sat = (uint16_t)_IQsat(value, period, _IQ(0.0));
    
          // write the PWM data
          PWM_write_CmpA(obj->pwmHandle[cnt],value_sat);
        }
    
      return;
    } // end of HAL_writePwmData() function

  • Sorry to write again. I did a double check, if I change the PWM duty cycle, gAdcData works as intented (so the adc HW is ok and the PWM initialization code too), but not in the opposite direction, I mean, if gAdcData are fixed, the PWM output never changes. I have no idea but I guess something happen with the controller, maybe I'm wrong.

    Any help will be appreciate.
  • Sorry, the problem has been solved (there was an error on the cmd file). Thank you.