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.

PMSM sensorless example for F28335

Other Parts Discussed in Thread: TMS320F28335, CONTROLSUITE, CCSTUDIO

Are there any PMSM examples for the F283x series of controllers. I know there are some that exist for the F2808 and F2812.

Thanks.

  • Haven't seen anything on this topic specific to this device .. may be something coming up soon. In the mean time 280xx examples should work unless you are trying floating point option. Please check the memory map and appropriate header files and you should be almost there........

  • Thanks. The F28335 has floating point capability. I will have to change the headers.I think the examples should work if I change the MATH_TYPE flag from IQ_MATH to FLOAT_MATH. Could anyone verify this.

  • We have plans to release Delfino Floating Point versions of several DMC Systems next in Q2 next year to run on our new High Voltage ACI/PMSM/BLDC board that is about to be released.

    Also, for Piccolo and Delfino we are updating all of our DMC Libraries / Systems to use the macro optimizations as described here

    http://focus.ti.com/lit/an/spraak2/spraak2.pdf

    to increase performance.

    I've also attached an example of a migration one of our support guys did on the OLD (non-macro) version of the F280x ACI3_3 System to Delfino F2833x.  If you are in a hurry you can use this example to change any of the others.

    change the .txt extension to .zip.

  • Thanks Chris. The file has been deleted. Itried changing from txt to zip but get the following error.

    "Microsoft Forefront Security for Exchange Server removed a file since it was found to match a filter."


  • strange, let's see if a .zip goes through.

    F280xtoF2833xACI3_3dmcmigration.zip
  • make sure you right click and save as....

  • I can download it...but it's corrupted.

     

  • Argh. Let me get a new version, might be later today.

  • Third Time's the Charm?

    I talked to the apps guy for this, and the system isn't verified. In fact there are still some references to 100 MHz throughout that would need to be changed (clocking issues).  We didn't want to spend much time on it as we're modifying everything for the new optimizations and new hardware.

     

    ACI33_F2833x_modified.zip
  • Thanks. It worked this time. Hopefully a diff will help me make out the changes.

     

  • Hi,

    Does anybody have a more update version of a motor project for the F28335 (such as sensored/sensorless FOC)? I took a look at the attachment, and "not verified" is kind of an understatement. The project does not have the floating point compiler option turned on, so it's still using the IQ libraries.

    If anyone has any news on this, I would appreciate knowing.

    Thanks,

    Tim

  • If you need to use the Floating point hardware in the chip, you will need to use the f32 compiler switch which is --float_support=fpu32"

    Also, the IQ library is a big bunch of macros. You can force the IQ library to use the floating point macros by using #define MATH_TYPE FLOAT_MATH

    Remember that whenever you need to write to hardware registers, you will need to multiply by 32768. You can find more detail in section 3.10 in the IQmath_v15a doc.

     

     

  • Thanks for responding to my post.

    I have already done the points you mentioned. In addition, the fDMC_ml.L28 lib that is included from TI was built without the fpu32 option.

    Do you have a working project with the fpu32 option? I am trying to do the sensorless FOC project, but can't get the pid1_iq.Fdb to follow IqRef. Not quite sure what's wrong, but suspect it could be in the lib files.

    Tim

  • Hi Tim,

     There are three modules iq, id and speed which use the PID module. We have used the module here and it works ok. Make sure id is getting followed as it uses the same PID module.

    Did you modify pwm.MfuncC1 to:

    pwm.MfuncC1 = (int16)(32768 * svgen_dq1.Ta); etc

    Also, the clarke currents need to be modified to:

    clarke1.As = ((float)(adc1.Ch5Out)) /32768;   --> Adc channel depends on the one you are using.

    I'm sorry I'm unable to submit any files, but I can guide you on the work I've done.

  • Did you subtract the offset in the current by:

    offset / 65536

    Thanks,

    Tim

  • No, the offsets were left as they were, meaning no div by 65536.  We use a reference signal to zero any offsets on startup.

  • As a side note, the compiler might generate more efficient code if you use a multiply by 0.000030517578125   ( i.e. multiply by 1/32768)

    -Lori

  • I did the following in the current:

     

        clarke1.As=(float32)((AdcRegs.ADCRESULT0/32768.0L)-(0.55*2));

        clarke1.Bs=(float32)((AdcRegs.ADCRESULT1/32768.0L)-(0.549965*2));

    and still do not see the pid1_iq.Fdb catch up to pid1_iq.Ref, using same values for PID gains, except for P, P = 1.3.
    Tim

     

  •  Just as an update, the Delfino versions of the projects for the High Voltage Kit (PMSM and ACI FOC sensored/sensorless) are probably going to be pushed out to July/August.  We are pulling in the Motor Control (FOC) on CLA examples for the Dual Axis Kit into Q2 due to some other work that is happening in parallel.

    Sorry for the delay...we know there are a LOT of Floating Point & Motor Control users on this forum.

  • Hi bluehash,

    In my code, I already had the following:

    pwm.MfuncC1 = (int16)(32768 * svgen_dq1.Ta); etc

    clarke1.As=(float32)(((AdcRegs.ADCRESULT0/65536.0L)-(0.55))*2);

    I can run the Level2 build, which is open loop, but as soon as I try to use the PID, I cannot get the pid1_iq.Fdb to follow IqRef1. Tweaking the PID parameters values has not made any effect.

    I am not able to make pid1_iq.Ui anything other than saturation (0.5).

    Tim

     

  • Hi Chris

    We need the sensored FOC code examples for the TMS320F28335. Has TI released these examples yet?,

    Best Regards,

    Danny

     

  • Danny,

    Our team is working on this as we speak. We have Delfino working with just the fixed point code. We are now creating the appropriate floating point libraries.

    We are also working through some of the kit logistics. The Delfino controlCARDs available today have the serial comms built onto the card, so the GUI we provide with our controlSUITE kits will not work. You would have to cut a resistor.  Also, the Delfino cards do not have a boot switch, so if we flash an image it won't boot to flash. You can work around this by just being connected through JTAG.  

    We will be introducing a new Delfino controlCARD though that removes the built-in serial comms and adds the boot mode switch.

    But for the current versions we'll just document the work arounds.

    I expect we'll release a controlSUITE SW release by the end of June, maybe sooner :)

     

  • Hi Chris,

    Other than the changes you mentioned above, I should be able to adapt the Piccolo sample code for the Delfino control card, correct?

    I have build level 2 running with perfect sine waves for the phase voltages and current, but cannot run build level 3 with PID as mentioned in my posts above.

    Tim

  • Tim,

    what I would suggest if you need to make progress now is doing a clean port with the Piccolo fixed point code.  Make sure that works with Delfino (there are some changes to the ADC that certainly have to be taken into account, system CPU MHz, affect of that on PWM freq calcs) and THEN look at porting in the floating point features.  In fact, for the math you can just keep all the variables as IQ, and do a simple type=float definition to get them to run as floating point.  There will be some advantages to eventually moving over to some of the other FPU libs and any enhancements we make to the DMCLib for FPU.

     

  • Chris,

    OK thanks. Your suggestion is noted, but that seems to take several steps back, as I am already running build level 2. The ADC, PWM, volt calc, ipark, svgen, etc are already working for the software to run build level 2.

    Tim

  • Hi Chris,

    Last September we started the development of a sensored PMSM motor drive. While developing the hardware we wanted to start the firmware. We were encouraged by TI support to purchase the following hardware (which we did):

    1)     TMDS2MTRPFCKIT Dual Motor Control and PFC Developer's Kit 

    2)     Delfino F28335 controlCARD

    3)     A motor similar to the TMDS2MTRPFCKIT equipped with an incremental encoder.

     

    The idea was to use this combination to tailor various existing software examples as a start.

    Our hardware will be ready soon but firmware development starts now.

     

    I understand that the most convenient way would be to wait for TI to release the Delfino dedicated libraries but we have to make the motor run before June. Can you recommend the best way to start now using the development tools we purchased?

    Many thanks,

    Danny

  • Danny,

    Here is what I would do.

     

    TMDS2MTRPFCKIT + F28035 controlCARD that came with it.

    www.ti.com/controlsuite install (choose this kit)

    1. Verify operation with the motor that shipped 

    C:\ti\controlSUITE\development_kits\LVMultiAxis+PfcKit_v1.0\2xPM_Sensorless

    if you are using CCSv3.3 you should use SPRC922 (there is a new update of this coming (SW is done, merging it into the SPRC922 download and posting to the web) that uses our new DMC Lib optimizations - you should use it!)

    2. Verify operation with YOUR motor.  This will require you to make sure the encoder functions as expected, SW headers changed for your motor parameters, and you'll need to follow the guide on how to tune the PID loops.

    3. Move to the Delfino controlCARD.  I will try to get you an early version of the code we are using on our HVKit. Right now it's just fixed point IQMath, but it's set-up with all the correct ADC and PWM drivers. [Just to be clear, we are only releasing the Delfino SW tuned for the HV Kit, not this dual axis kit]

    4. Migrate to floating point functions. (this is where it can be tricky)

     

     

     

     


     

  • Hi Chris

    Thank you, I will follow your advice.

    By the way for a beginner do you recommend that I start with CCSv3.3 or with CCS 4 ?

    Danny

  • Danny,

    While we are supporting only CCSv4.x going forward, I think the consensus from this board would be to stay on CCSv3.3 if you can.  I don't think the SPRC I mentioned above will be released this week, but I have the SW. I can post it on a download site if you would like to get started right away.

     

  • Hi Chris,

    Yes please post it on the download site, this will help me move forward.

    Many thanks,

    Danny

  • Danny,

    Here you go.

    http://drop.io/new2xpmsmccs33

    You should probably rename

    C:\TI_F28xxx_SysSW\MotorCtrl+PfcKit\2xPM_Motors  and

    C:\TI_F28xxx_SysSW\MotorCtrl+PfcKit\~Docs

    to something like 2xPM_Motors_Old and ~Docs_Old

    and then extract this zip into C:\TI_F28xxx_SysSW\MotorCtrl+PfcKit

    it creates new 2xPM_Motors and a new ~Docs directories.

    Once we wrap this into the original SPRCxxx we'll give this new 2xPM_Motors a new directory name so it doesn't write over the original.

     

     

  • Hi Chris,

    If I am driving PWMs on side B, will I still be able to trigger ADCs off on that side only, for example, PWM1B? Or do I still need to start the trigger on PWM.A and let it cascade to PWM.B?

    Thanks,

    Tim

  • Tim,

    Are you asking about the dual axis kit?

    The way we did the SW was to have both axis run at the same frequency, and everything is triggered off a common ePWM1 timer.  You can certainly make these independent though.

    And the ePWM1 timer is running regardless of if we are outputting ePWM1a/b ePWM2a to the drive stage, so yes you can still run side B (ePWM3a/b 4a)

     

     

  • Hi Chris,

    My question was not limited to the dual axis kit, but ADC functionality in general.

    The dual axis kit uses ePWM1A to trigger the ADC, but would it be possible to trigger only off of ePWM1b, if instead of driving ePWM1a/b ePWM2a, ePWM1b/2b/3b is being driven?

    I'm guessing the HV kit with F28335 is doing something similar.

    Tim

  • Sure, you could do that.  The timer for ePWM1a and ePWM1b are the same though.

    You'll notice in both the HV and Dual Axis kit main code the ADC is initialized by

    ADC_MACRO

    This is  defined in the motor_control driver block f2803xileg_vdc.h

    #define ADC_MACRO() \

    \

     DELAY_US(ADC_usDELAY); \

        AdcRegs.ADCCTL1.all=ADC_RESET_FLAG; \

    asm(" NOP "); \

    asm(" NOP ");     \

    \

    EALLOW; \

    AdcRegs.ADCCTL1.bit.ADCBGPWD = 1; /* Power up band gap */ \

    \

    DELAY_US(ADC_usDELAY); /* Delay before powering up rest of ADC */ \

    \

    AdcRegs.ADCCTL1.bit.ADCREFSEL = 0; \

       AdcRegs.ADCCTL1.bit.ADCREFPWD = 1; /* Power up reference */ \

       AdcRegs.ADCCTL1.bit.ADCPWDN = 1; /* Power up rest of ADC */ \

    AdcRegs.ADCCTL1.bit.ADCENABLE = 1; /* Enable ADC */ \

    \

    asm(" RPT#100 || NOP"); \

    \

    AdcRegs.ADCCTL1.bit.INTPULSEPOS=1; \

    AdcRegs.ADCCTL1.bit.TEMPCONV=0; \

    \

    DELAY_US(ADC_usDELAY); \

    \

    /******* CHANNEL SELECT *******/ \

    \

    \

    AdcRegs.ADCSOC0CTL.bit.CHSEL = 12; /* ChSelect: ADC B4-> Phase A Current */ \

    AdcRegs.ADCSOC0CTL.bit.TRIGSEL  = 5; /* Set SOC0 start trigger on EPWM1A */ \

    AdcRegs.ADCSOC0CTL.bit.ACQPS = 6; /* Set SOC0 S/H Window to 6+1 ADC Clock Cycles */ \

    \

    AdcRegs.ADCSOC1CTL.bit.CHSEL = 14; /* ChSelect: ADC B6-> Phase B Current */ \

    AdcRegs.ADCSOC1CTL.bit.TRIGSEL  = 5; \

    AdcRegs.ADCSOC1CTL.bit.ACQPS = 6; \

    \

    AdcRegs.ADCSOC2CTL.bit.CHSEL = 1; /* ChSelect: ADC A1-> DC Bus Voltage */ \

    AdcRegs.ADCSOC2CTL.bit.TRIGSEL  = 5; \

    AdcRegs.ADCSOC2CTL.bit.ACQPS = 6; \

    \

    AdcRegs.ADCSOC3CTL.bit.CHSEL = 11; /* ChSelect: ADC B3-> V Phase A */ \

    AdcRegs.ADCSOC3CTL.bit.TRIGSEL = 5; \

    AdcRegs.ADCSOC3CTL.bit.ACQPS = 6; \

    \

    AdcRegs.ADCSOC4CTL.bit.CHSEL = 10; /* ChSelect: ADC B2-> V Phase B */ \

    AdcRegs.ADCSOC4CTL.bit.TRIGSEL  = 5; \

    AdcRegs.ADCSOC4CTL.bit.ACQPS = 6; \

    \

    AdcRegs.ADCSOC5CTL.bit.CHSEL = 9; /* ChSelect: ADC B1-> V Phase C */ \

    AdcRegs.ADCSOC5CTL.bit.TRIGSEL  = 5; \

    AdcRegs.ADCSOC5CTL.bit.ACQPS = 6; \

    \

    AdcRegs.ADCSOC6CTL.bit.CHSEL = 4;    /* ChSelect: ADC A4-> Low Side DC Bus Return Cur.*/ \

    AdcRegs.ADCSOC6CTL.bit.TRIGSEL = 5; \

    AdcRegs.ADCSOC6CTL.bit.ACQPS = 6; \

    \

              \

    EDIS; \

    \

    \

        /* Set up Event Trigger with CNT_zero enable for Time-base of EPWM1 */ \

        EPwm1Regs.ETSEL.bit.SOCAEN = 1;     /* Enable SOCA */ \

        EPwm1Regs.ETSEL.bit.SOCASEL = 1;    /* Enable CNT_zero event for SOCA */ \

        EPwm1Regs.ETPS.bit.SOCAPRD = 1;     /* Generate SOCA on the 1st event */ \

    EPwm1Regs.ETCLR.bit.SOCA = 1;       /* Clear SOCA flag */

     

    You can go change any of this that you like.

  • Hi Chris,

    Thanks for the response.

    Are you sure that's F28335 code? It looks like Piccolo code to me because the ADCs work differently.

    Personally, I find the Piccolo ADC implementation easier to work with and understand.

    Tim

  • Tim ,

     

    Try this instead (for HVDMC kit):

     


    #define CPU_CLOCK_SPEED      15.000L   // 10.000L for a 100MHz CPU clock speed
    #define ADC_usDELAY 50000L
    #define DELAY_US(A)  DSP28x_usDelay(((((long double) A * 1000.0L) / (long double)CPU_CLOCK_SPEED) - 9.0L) / 5.0L)

    extern void DSP28x_usDelay(unsigned long Count);


    #define ADC_MACRO()                                                                               
                                                                                                   
        EALLOW;                                                                                       
        SysCtrlRegs.PCLKCR0.bit.ADCENCLK = 1;                                                       
        ADC_cal();                                                                                   
        EDIS;                                                                                       
                                                                                                   
        AdcRegs.ADCTRL3.all = 0x00E0;  /* Power up bandgap/reference/ADC circuits*/                   
        DELAY_US(ADC_usDELAY);         /* Delay before converting ADC channels*/                   
                                                                                                   
         AdcRegs.ADCTRL1.bit.ACQ_PS = 6;                                                               
        AdcRegs.ADCTRL1.bit.CPS = 1;                                                               
        AdcRegs.ADCTRL3.bit.ADCCLKPS =  0;                                                           
        AdcRegs.ADCTRL1.bit.SEQ_CASC = 0;        /* 0x0 Dual Sequencer Mode, 0x1 Cascaded Mode*/   
        AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1 = 0x0;                                                       
        AdcRegs.ADCTRL2.bit.RST_SEQ1 = 0x1;                                                           
        AdcRegs.ADCTRL2.bit.RST_SEQ2 = 0x1;                                                           
        AdcRegs.ADCTRL2.bit.EPWM_SOCA_SEQ1=0x1; /* enable SOC from EPWMA trigger*/                 
        AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 12;    /* ChSelect: ADC B4-> Phase A Current */           
        AdcRegs.ADCCHSELSEQ1.bit.CONV01 = 14;    /* ChSelect: ADC B6-> Phase B Current */           
        AdcRegs.ADCCHSELSEQ1.bit.CONV02 = 1;    /* ChSelect: ADC A1-> DC Bus Voltage */               
        AdcRegs.ADCCHSELSEQ1.bit.CONV03 = 11;    /* ChSelect: ADC B3-> V Phase A */                   
        AdcRegs.ADCCHSELSEQ2.bit.CONV04 = 10;    /* ChSelect: ADC B2-> V Phase B */                   
        AdcRegs.ADCCHSELSEQ2.bit.CONV05 = 9;    /* ChSelect: ADC B1-> V Phase C */                   
        AdcRegs.ADCCHSELSEQ2.bit.CONV06 = 4;    /* ChSelect: ADC A4-> Low Side DC Bus Return Cur.*/   
        AdcRegs.ADCCHSELSEQ2.bit.CONV07 = 4;                                                       
        AdcRegs.ADCMAXCONV.bit.MAX_CONV1 = 7;                                                      
        EDIS;                                                                                       
                                                                                                   
        /* Set up Event Trigger with CNT_zero enable for Time-base of EPWM1 */                       
        EPwm1Regs.ETSEL.bit.SOCAEN = 1;     /* Enable SOCA */                                       
        EPwm1Regs.ETSEL.bit.SOCASEL = 1;    /* Enable CNT_zero event for SOCA */                   
        EPwm1Regs.ETPS.bit.SOCAPRD = 1;     /* Generate SOCA on the 1st event */                   
        EPwm1Regs.ETCLR.bit.SOCA = 1;       /* Clear SOCA flag */

     

        clarke1.As=((AdcMirror.ADCRESULT0)/4096.0L-offsetA)*2; // Phase A curr.

        clarke1.Bs=((AdcMirror.ADCRESULT1)/4096.0L-offsetB)*2; // Phase B curr.

        call clarke

     

     

    Regards

    Bilal

  • Tim,

    I didn't recall that you were using F28335. I was really just trying to explain where this set-up occurs in the code.

    Looks like Bilal posted the ADC config from F28335 for you (this is what will be included in the HV Delfino SW)

     

  • Hi Bill,

    My code is very similar to yours except I have 

        AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1 = 1;   // Enable SEQ1 interrupt (every EOS)

    to turn on and enable SEQ1 interrupt.

    But the interrupt is not triggering. When I was driving ePWM1a, the trigger worked fine. But I need to drive ePWM1b like the following:

     

        EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;

        EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;

        EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN;

        EPwm1Regs.AQCTLB.bit.CBU = AQ_SET;    // Set high when CTR = CMPB on UP-count

        EPwm1Regs.AQCTLB.bit.CBD = AQ_CLEAR;

    Is this possible?
    Tim

  • Hi Chris,

     

    I followed your recommendations, things work nicely on the Piccolo with the incremental encoder on the LVMultiAxis+PfcKit dev kit.

    I am now getting ready to change to the Delfino ControlCard and would be grateful if you could get me the early version of the code you are using on the HVKit as you previously mentioned.

     

    Best regards,

     

    Danny

     

  • Hi Chris,

    As I mentioned a couple of hours ago I am getting ready to plug in the F28335 ControlCard to the LVMultiAxis+PfcKit dev kit and convert my Piccolo code that is now operational to Delfino code.


    I suddenly remembered your previous comments (attached below) regarding some incompatibility of the Delfino ControlCard to the LVMultiAxis+PfcKit dev kit.
    Can you please post the required detailed hardware modification on the Delfino ControlCard so that we will not run into the problems you mentioned and run a smooth conversion process?  

    Regards,

    Danny

    Chris quote:

    “We are also working through some of the kit logistics.

    The Delfino controlCARDs available today have the serial comms built onto the card, so the GUI we provide with our controlSUITE kits will not work. You would have to cut a resistor.

    Also, the Delfino cards do not have a boot switch, so if we flash an image it won't boot to flash. You can work around this by just being connected through JTAG.”  

     

     

  • Danny,

    The issues with the Delfino controlCARD only effect us trying to support the out of box GUI and serial communications. For doing RAM Debug it will work fine with your kit.

     

  • Danny,

    I'm out of the office until Monday. Let me see if I can get you something early next week....or perhaps we'll just post it on the wiki.

     

  • Hi Chris,

    Ok, please send the samples as soon as you can, I really need them now.

    Regards,

    Danny

  • Danny,

    Person working on this had a family emergency.  As soon as I can get it from him I'll post a download link.

  • Hi Chris, Sorry about the personal emergency. After some efforts I managed to make the 28035 converted project code compile and show signs of life on the 28335. But the motor is not running yet, I can’t get the MainISR to run. I guess I have not converted one or more initializations somewhere. Any of the HV Sensored PMSM Delfino examples / other documents or tips you can extend will be greatly appreciated. Regards, Danny
  • Danny,

    I'm hoping to get you a working version on Thursday. It's not going to be be completely ported to floating point, but it will run on F28335 and give you something to hlep you debug.

  • Danny,

    http://drop.io/fxzixcj/asset/controlsuite-fpu-zip

    you probably want to extract to C:\ti

    it will create a \controlSUITE_FPU directory and there is a HVPMSM_Sensorless project

    For anyone downloading, recall this is a WORK IN PROGRESS.  Feel free to leave comments though.

     

  • Hi Chris,

    In the HVPMSM Sensored project, there is a CalibratedAngle variable in the QED module. Can you explain what that is and what's the best way to get the calibrated angle?

    Thanks,

    Tim