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.

TMS320F28379D: TMS320F28379D

Part Number: TMS320F28379D

Hello Sir/Madam, 

I am trying to write on " EQep1Regs.QCLR.bit.IEL", but unable to write. 

With below lines 

if (lsw==0) {
EQep1Regs.QPOSCNT=0; // Reset position cnt.
EQep1Regs.QCLR.bit.IEL = 1;

}

It makes the POSCNT = 0, when lsw = 0,  but doesn't write on EQepRegs. I am not able to understand what i am missing to initialize. 

The motor works perfectly fine when lsw = 1 or 2. 

I am using PWM interrupt 1, 2, 3 for generation of PWM signals and PWM4 for interrupt for control logic. There are no other interrupts in my code. I have modified "HVPM_Sensored.c"   according  to my requirement (in terms of generation of PWM signals, rest is same as the original). 

Thanking you in advance. 

  • Sorry, I would say the index event latch register does not set. I am sorry to use word write.
  • Is it in 28379D, I have to use "EQep1Regs.QEPCTL.bit.IEL" instead of " EQep1Regs.QCLR.bit.IEL".

    But I am also confused for these lines "n some applications, it may not be desirable to reset the position counter on every index event and instead it may be required to operate the position counter in full 32-bit mode (QEPCTL[PCRM] = 01 and QEPCTL[PCRM] = 10 modes)." in manual of the mentioned device. As for me PCRM is 0.

    And using this EQep1Regs.QEPCTL.bit.IEL, it sets to 1 but flag doesn't set to 1. why ?

    Kindly help.
  • EQep1Regs.QCLR.bit.IEL = 1 will just clear the IEL flag in the QFLG register. The bits in QCLR are labeled as "R=0/W=1" in the manual, meaning they always read zero which is why you didn't see the value change.

    You are correct that EQep1Regs.QEPCTL.bit.IEL is the correct place to configure the index latch settings. It doesn't really have anything to do with the EQep1Regs.QFLG.bit.IEL bit though. It just determines when QPOSILAT has the position counter value latched into it.

    If you cause a rising edge on the index pin, do you see QFLG get set? Or if you're trying to just force the flag to go high, there's a QFRC register for that? I'm not sure I understand what you're trying to do with the index flag. Could you elaborate?

    Whitney

  • Thank you sir for your reply.

     I understood about QCLR.

    I am trying to Calibrate encoder as mentioned in  "HVPM_sensored" example of development kits. I am working on 28379D and "EQep1Regs.QFLG.bit.IEL" does not set to 1, and hence I am not able to obtain "qep1.CalibratedAngle".  

    Note: I am not using HVPM_sensored file, rather I am trying to understand the same  and implement in 28379D.  

    Thanks in advance. 

    // ------------------------------------------------------------------------------
    //    Detect calibration angle (optional) and call the QEP module
    // ------------------------------------------------------------------------------
           if (lsw==0) {EQep1Regs.QPOSCNT=0; EQep1Regs.QCLR.bit.IEL = 1;} // Reset position cnt.
           if ((EQep1Regs.QFLG.bit.IEL==1) && Init_IFlag==0)              // Check the first index occurrence
              {qep1.CalibratedAngle= EQep1Regs.QPOSILAT; Init_IFlag++;}   // Keep the latched position
           if (lsw!=0) QEP_MACRO(1,qep1);"
  • I would like to know the reason that why that flag does not sets for me?
    What are the checks that I should follow. Meanwhile, I am also reading manual but its not very much clear to me.

    Thanks.
  • Dear sir , As you mentioned Using QFRC I am able to set "EQep1Regs.QFLG.bit.IEL" to 1. But, the QPOSCNT value is not latching inside " QPOSILAT" register.  But, I can see in watch window "EQep1Regs.QEPCTL.bit.IEL" as 1. how is that possisble?

    In the initialization, qep1.CalibratedAngle = 1000 ; 

    but after the flag sets to 1, it goes to 0 as QPOSILAT has 0 value. 

        
    __interrupt void epwm4_isr(void)
    {
    //THE OTHER CODE IS SAME AS EXAMPLE OF "HVPM_SENSORED"
       if (lsw==0) {EQep1Regs.QPOSCNT=0; EQep1Regs.QCLR.bit.IEL = 1;} // Reset position cnt.
           if ((EQep1Regs.QFLG.bit.IEL==1) && Init_IFlag==0)              // Check the first index occurrence
              {qep1.CalibratedAngle= EQep1Regs.QPOSILAT; Init_IFlag++;}   // Keep the latched position
           if (lsw!=0) QEP_MACRO(1,qep1);
    //THEN THERE IS PWM REGISTERS FOR PWM ACTIONS 
               EQep1Regs.QFRC.bit.IEL = 1; 
               EPwm4Regs.ETCLR.bit.INT = 1;
               //
               // Acknowledge this interrupt to receive more interrupts from group 3
               //
              PieCtrlRegs.PIEACK.all = PIEACK_GROUP3;
    }
    Thank you.
  • So, because of QFRC, the flag sets, but i think the problem still retains as POSILAT does not work and I don not know what is the problem.

    Kindly help.
  • I suspect QFRC just sets the flag--I don't think it has the same behavior as a true index event on the index pin, so I'm not very surprised it doesn't cause the latch.

    Do you have something connected on the index pin that is toggling it? Have you confirmed that your GPIO configuration that selects which pin functions as the index pin is correct?

    Whitney

  • Hi

    yes I get the point that QFRC will not work as true index event.

    1. There 5 output pins (connected)of  encoder of motor model EMJ-04APB22. So, all of them together I have connected to QEPA of 28379D.

    So, I do not think anything toggling.

    2. As I mentioned earlier, when I close loop,  speed and current both, motor works fine, but without calibrated angle.

    To calibrate the angle, I want the Index event latch interrupt flag to set. 

    3. Another thing I tried to use  "Eqep_pos_speed.c" example without making any changes in it. when I rotate motor, Index event latch interrupt flag does not set. 

    Below are my GPIO settings.

    void InitEQep1Gpio(void)
    {
        EALLOW;
    
        //
        // Disable internal pull-up for the selected output pins
        // for reduced power consumption
        // Pull-ups can be enabled or disabled by the user.
    
        GpioCtrlRegs.GPAPUD.bit.GPIO20 = 1;    // Disable pull-up on GPIO20 (EQEP1A)
        GpioCtrlRegs.GPAPUD.bit.GPIO21 = 1;    // Disable pull-up on GPIO21 (EQEP1B)
    //    GpioCtrlRegs.GPAPUD.bit.GPIO22 = 1;    // Disable pull-up on GPIO22 (EQEP1S)
        GpioCtrlRegs.GPAPUD.bit.GPIO23 = 1;    // Disable pull-up on GPIO23 (EQEP1I)
        //
        // Synchronize inputs to SYSCLK
        // Synchronization can be enabled or disabled by the user.
        // Comment out other unwanted lines.
        //
    
        GpioCtrlRegs.GPAQSEL2.bit.GPIO20 = 0;   // Sync GPIO20 to SYSCLK  (EQEP1A)
        GpioCtrlRegs.GPAQSEL2.bit.GPIO21 = 0;   // Sync GPIO21 to SYSCLK  (EQEP1B)
    //    GpioCtrlRegs.GPAQSEL2.bit.GPIO22 = 0;   // Sync GPIO22 to SYSCLK  (EQEP1S)
        GpioCtrlRegs.GPAQSEL2.bit.GPIO23 = 0;   // Sync GPIO23 to SYSCLK  (EQEP1I)
        //
        // Configure EQEP-1 pins using GPIO regs
        // This specifies which of the possible GPIO pins will be EQEP1 functional
        // pins.
    
        GpioCtrlRegs.GPAMUX2.bit.GPIO20 = 1;    // Configure GPIO20 as EQEP1A
        GpioCtrlRegs.GPAMUX2.bit.GPIO21 = 1;    // Configure GPIO21 as EQEP1B
    //    GpioCtrlRegs.GPAMUX2.bit.GPIO22 = 1;    // Configure GPIO22 as EQEP1S
        GpioCtrlRegs.GPAMUX2.bit.GPIO23 = 1;    // Configure GPIO23 as EQEP1I
        EDIS;
    }
    

  • By toggling, I meant is there an index pulse occurring on the index pin that will cause the latch and set the interrupt flag? How have you configured QEPCTL.IEL?

    Your GPIO settings seem to be okay. It probably isn't causing an issue but it's safest to write 0 to the GPAGMUX2 bits before writing to GPAMUX.

    Whitney
  • // ------------------------------------------------------------------------------
    //    Detect calibration angle (optional) and call the QEP module
    // ------------------------------------------------------------------------------
    
          EQep1Regs.QEPCTL.bit.IEL = 1;
    
           if (lsw==0) {EQep1Regs.QPOSCNT=0; EQep1Regs.QCLR.bit.IEL = 1;} // Reset position cnt.
    
           if ((EQep1Regs.QFLG.bit.IEL==1) && Init_IFlag==0)              // Check the first index occurrence
              {qep1.CalibratedAngle= EQep1Regs.QPOSILAT; Init_IFlag++;}   // Keep the latched position
    
           if (lsw!=0) QEP_MACRO(1,qep1);
    

    Thank you sir for your prompt reply.

    To avoid the doubt of index pulse if it exists or not, I used another DSP of my colleague " Docking-stn EMU-USB" and build the example " HVPM_sensored", flag sets perfectly. so that means Index event exist. Also, I checked with oscilloscope that 

    Also I am using same settings and code of HVPM_Sensored, then why not in 28379D ?

    I did not have QEPCTL.IEL configured before, but after you mentioned I tried to configured inside interrupt as below, but still Index event latch interrupt flag did not set. 

    what is your suggestion about this " Another thing I tried to use  "Eqep_pos_speed.c" example without making any changes in it. when I rotate motor, Index event latch interrupt flag does not set for 28379D" ? 

    Thank you for suggestiong of GPIO, I will take care of it.

  • I am using HVPM_sensored for 28379D, So, for speed calculation also I am using QEP_MACRO and its file name is "f2803xqep.h".
    when I compile this for 28379D, compiler does not give any error, but, can this be a problem, that flag does not set?

    Kindly guide me.
    -Vidhi
  • So not even the eqep_pos_speed.c example works on your board? You made all the hardware connections noted in the example's description? What board are you using? A controlCARD? LaunchPad? Your own board?

    Whitney
  • No, the example also does not work. I am using TMS320F28379D. The external connections are as mentioned in header of example file.
  • Do the other EQEP pins appear to be working? Is it just index that isn't working?

    I'm not sure which board you're using and what you have pinned out, but would it be possible to try using other GPIO (like GPIO13, GPIO53, or GPIO99) as the index pin instead, just in case there's something wrong with your GPIO23 connection?

    Whitney
  • I am using TMSF28379D LaunchPad. There exist an index pulse and also A, B, QPOSCNT is increasing as expected, so other pins are working fine. I also tried to write on GPIO as per your suggesttion. 
    The below is my control logic, which is same as HVPM_sensored example. I tried to change " QEP_MACRO(1,qep1)" to " QEP_MACRO(2,qep1)", but compiler gives me an error of " subscript out of range". So, I could not test QEPB of 28379D.

    __interrupt void epwm4_isr(void) { EPwm4TimerIntCount++; // ------------------------------------------------------------------------------ // Connect inputs of the RMP module and call the ramp control macro // ------------------------------------------------------------------------------ if(lsw==0)rc1.TargetValue = 0; else rc1.TargetValue = SpeedRef; RC_MACRO(rc1) // ------------------------------------------------------------------------------ // Connect inputs of the RAMP GEN module and call the ramp generator macro // ------------------------------------------------------------------------------ rg1.Freq = rc1.SetpointValue; RG_MACRO(rg1) //=================== current measurement============================// AdcaRegs.ADCSOCFRC1.all = 0x000F; //phase a current AdccRegs.ADCSOCFRC1.all = 0x000F; //phase c current clarke1.As = _IQmpy2(_IQ12toIQ(AdcaResultRegs.ADCRESULT0)-offsetA); // Phase A curr. clarke1.Cs = _IQmpy2(_IQ12toIQ(AdccResultRegs.ADCRESULT0)-offsetC); // Phase C curr. CLARKE_MACRO(clarke1) // ------------------------------------------------------------------------------ // Connect inputs of the PARK module and call the park trans. macro // ------------------------------------------------------------------------------ park1.Alpha = clarke1.Alpha; park1.Beta = clarke1.Beta; if(lsw==0) park1.Angle = 0; else if(lsw==1) park1.Angle = rg1.Out; else park1.Angle = qep1.ElecTheta;//;qep_posspeed.theta_elec park1.Sine = _IQsinPU(park1.Angle); park1.Cosine = _IQcosPU(park1.Angle); PARK_MACRO(park1) Theta = _IQtoF(qep1.ElecTheta); // x= sin(Theta) ; // ------------------------------------------------------------------------------ // Connect inputs of the PI module and call the PID speed controller macro // ------------------------------------------------------------------------------ if (SpeedLoopCount==SpeedLoopPrescaler) { pi_spd.Ref = rc1.SetpointValue; pi_spd.Fbk = speed1.Speed; //qep_posspeed.Speed_pr; PI_MACRO(pi_spd); SpeedLoopCount=1; } else SpeedLoopCount++; if(lsw!=2) {pi_spd.ui=0; pi_spd.i1=0;} SPEED = _IQtoF(pi_spd.Out); // ------------------------------------------------------------------------------ // Connect inputs of the PI module and call the PID IQ controller macro // ------------------------------------------------------------------------------ if(lsw==0) pi_iq.Ref = 0; else if(lsw==1) pi_iq.Ref = IqRef; else pi_iq.Ref = pi_spd.Out; pi_iq.Fbk = park1.Qs; PI_MACRO(pi_iq) i_q = _IQtoF(pi_iq.Out); // ------------------------------------------------------------------------------ // Connect inputs of the PI module and call the PID ID controller macro // ------------------------------------------------------------------------------ if(lsw==0) pi_id.Ref = _IQ(0.05); else pi_id.Ref = IdRef; pi_id.Fbk = park1.Ds; PI_MACRO(pi_id) i_d = _IQtoF(pi_id.Out); // ------------------------------------------------------------------------------ // Connect inputs of the INV_PARK module and call the inverse park trans. macro // ------------------------------------------------------------------------------ ipark1.Ds = pi_id.Out; ipark1.Qs = pi_iq.Out; ipark1.Sine=park1.Sine; ipark1.Cosine=park1.Cosine; IPARK_MACRO(ipark1) // ------------------------------------------------------------------------------ // Detect calibration angle (optional) and call the QEP module // ------------------------------------------------------------------------------ if (lsw==0) {EQep1Regs.QPOSCNT=0; EQep1Regs.QCLR.bit.IEL = 1;} // Reset position cnt. if ((EQep1Regs.QFLG.bit.IEL==1) && Init_IFlag==0) // Check the first index occurrence {qep1.CalibratedAngle= EQep1Regs.QPOSILAT; Init_IFlag++;} // Keep the latched position if (lsw!=0) QEP_MACRO(1,qep1); // ------------------------------------------------------------------------------ // Connect inputs of the SPEED_FR module and call the speed calculation macro // ------------------------------------------------------------------------------ speed1.ElecTheta = _IQ24toIQ((int32)qep1.ElecTheta); speed1.DirectionQep = (int32)(qep1.DirectionQep); SPEED_FR_MACRO(speed1) // ------------------------------------------------------------------------------ // Connect inputs of the SVGEN_DQ module and call the space-vector gen. macro // ------------------------------------------------------------------------------ svgen1.Ualpha = ipark1.Alpha; svgen1.Ubeta = ipark1.Beta; SVGENDQ_MACRO(svgen1) // ------------------------------------------------------------------------------ // Connect inputs of the PWM_DRV module and call the PWM signal generation macro // ------------------------------------------------------------------------------ Ta = _IQtoF(svgen1.Ta); Tb = _IQtoF(svgen1.Tb); Tc = _IQtoF(svgen1.Tc); EPwm1Regs.CMPA.bit.CMPA = (Uint16)(((Ta/2)+0.5)*EPwm1Regs.TBPRD); EPwm2Regs.CMPA.bit.CMPA = (Uint16)(((Tb/2)+0.5)*EPwm2Regs.TBPRD); EPwm3Regs.CMPA.bit.CMPA = (Uint16)(((Tc/2)+0.5)*EPwm3Regs.TBPRD); // EQep1Regs.QFRC.bit.IEL = 1; if (EPwm4TimerIntCount>=5000) { offsetA= _IQmpy(K1,offsetA)+_IQmpy(K2,_IQ12toIQ(AdcaResultRegs.ADCRESULT0)); //Phase A offset // offsetB= _IQmpy(K1,offsetB)+_IQmpy(K2,_IQ12toIQ(AdcResult.ADCRESULT2)); //Phase B offset offsetC= _IQmpy(K1,offsetC)+_IQmpy(K2,_IQ12toIQ(AdccResultRegs.ADCRESULT0)); //Phase C offset } EPwm4Regs.ETCLR.bit.INT = 1; // // Acknowledge this interrupt to receive more interrupts from group 3 // PieCtrlRegs.PIEACK.all = PIEACK_GROUP3; }
    I do not understand, if there is a problem with interrupt priority or what else to check. Because, I am using PWM4 as an interrupt for control logic.
    Thanks

    -Vidhi

  • hi Whitney,

    If I want to use QEPB of TMS28379D Launchpad, What shall I change in " QEP_MACRO(1,qep1) "?
    If I make it 2 instead of 1 like this " QEP_MACRO(2,qep1);" it gives me " warning #177-D: subscript out of range", means it has fewer elements, but which elements?
    If I write " QEP_MACRO(1,qep2);" then QPOSCNT doesn't change.

    Thanks
  • Find the table of EQEP addresses into which QEP_MACRO indexes and see if it has EQep2Regs in it (I found it my Ctrl+Clicking on QEP_MACRO and then again on *eQEP). If it doesn't, try adding it. Then you should be able to do QEP_MACRO(2,qep1) without the warning.

    // Used to indirectly access eQEP module
    volatile struct EQEP_REGS *eQEP[] = 
                                      { &EQep1Regs,
                                        &EQep1Regs,
                                        &EQep2Regs
                                      };

    Whitney

  • How is your debug going? Have you resolved this issue?

    Whitney
  • No, I don't know what is wrong with flag, but, now
    I am generating an external interrupt through index pulse coming from encoder and then in an interrupt I extract the value of POSCNT in qep1.Calibratedangle.
    I hope this method is correct.

    IEL flag is used only for calibration according to my understanding. if IEL flag is not, then for speed measurement is not the problem. right ?


    Vidhi