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.

TMS570LS3137: PWM high resolution configuration

Part Number: TMS570LS3137
Other Parts Discussed in Thread: HALCOGEN

Tool/software:

Hi

I did some new detailed test and I saw a problem regarding  the PWM generation 

Even thoug I change the DATA value on the hetRAM1->Instruction[(PWM_CH2 << 1U) + 41U].Data

for the duty configuration, I don't see any change in the PWM output if the DATA change is less of 10.

In this my test programm, the duty configuration is written as DATA reading in loopback the value setted

on the variable AN1.


Data value on pwmchannel 0 = 4672

PWM1=500 AN1=2087

Data value on pwmchannel 0 = 4662

PWM1=499 AN1=2087

Data value on pwmchannel 0 = 4653

PWM1=498 AN1=2087

Data value on pwmchannel 0 = 4644

PWM1=497 AN1=2087


Data value on pwmchannel 0 = 4626

PWM1=495 AN1=2087


Data value on pwmchannel 0 = 4617

PWM1=494 AN1=2087

Data value on pwmchannel 0 = 4608

PWM1=493 AN1=2087

and finally writing 4599, the PWM output channel change reading 2145


Data value on pwmchannel 0 = 4599

PWM1=492 AN1=2145

Any suggestion?

Thanks

  • Hi

    It seems high resolution does not work for PWM in my configuration

    I tried to set bit8 of program register but without success

    Any suggestions?

    Thanks

    Fabio

  • Hi Fabio,

    Is it possible to share your code for quick debug at my end? Even you can send it through private message.

    --
    Thanks & regards,

    Jagadish.

  • HI

    I'm afraid is too complicated ..... I would create a simple project only with pwm ....

    I'm using this confiugration for PWM0

    /* MOV64: PWM 0 -> Duty Cycle Update
    * - Instruction = 41
    * - Next instruction = 42
    * - Conditional next instruction = 2
    * - Interrupt = 1
    * - Pin = 4
    */
    {
    /* Program */
    0x00054301U, // low resolution 0x00054201U,
    /* Control */
    (0x00004007U | (uint32)((uint32)1U << 22U) | (uint32)((uint32)4U << 8U) | (uint32)((uint32)3U << 3U)),
    /* Data */
    4736U,
    /* Reserved */
    0x00000000U
    },
    /* MOV64: PWM 0 -> Period Update
    * - Instruction = 42
    * - Next instruction = 3
    * - Conditional next instruction = 41
    * - Interrupt = 2
    * - Pin = na
    */
    {
    /* Program */
    0x00006302U, // low resolution 0x00006202U,
    /* Control */
    (0x00052007U),
    /* Data */
    8960U,
    /* Reserved */
    0x00000000U
    },

    with these function to manage the configuration

    void pwmSetDuty(hetRAMBASE_t * hetRAM, uint32 pwm, float pwmDuty)
    {
    uint32 action;
    uint32 pwmPolarity =0U;
    uint32 pwmPeriod = hetRAM->Instruction[(pwm << 1U) + 42U].Data + 128U;
    pwmPeriod = pwmPeriod >> 7U;

    if(hetRAM == hetRAM1)
    {
    pwmPolarity = s_het1pwmPolarity[pwm];
    }
    else
    {
    }
    if (pwmDuty == 0U)
    {
    action = (pwmPolarity == 3U) ? 0U : 2U;
    }
    else if (pwmDuty >= 100U)
    {
    action = (pwmPolarity == 3U) ? 2U : 0U;
    }
    else
    {
    action = pwmPolarity;
    }

    hetRAM->Instruction[(pwm << 1U) + 41U].Control = ((hetRAM->Instruction[(pwm << 1U) + 41U].Control) & (~(uint32)(0x00000018U))) | (action << 3U);
    // hetRAM->Instruction[(pwm << 1U) + 41U].Data = (((pwmPeriod * pwmDuty) / 100U) << 7U) + 128U;
    hetRAM->Instruction[(pwm << 1U) + 41U].Data = ((uint16_t)((pwmPeriod * pwmDuty * 128) / 100U)) + 128U;
    }

    void pwmSetSignal(hetRAMBASE_t * hetRAM, uint32 pwm, hetSIGNAL_t signal)
    {
    uint32 action;
    uint32 pwmPolarity = 0U;
    float64 pwmPeriod = 0.0F;

    if(hetRAM == hetRAM1)
    {
    pwmPeriod = (signal.period * 1000.0F) / 1422.222F;
    pwmPolarity = s_het1pwmPolarity[pwm];
    }
    else
    {
    }
    if (signal.duty == 0U)
    {
    action = (pwmPolarity == 3U) ? 0U : 2U;
    }
    else if (signal.duty >= 100U)
    {
    action = (pwmPolarity == 3U) ? 2U : 0U;
    }
    else
    {
    action = pwmPolarity;
    }

    hetRAM->Instruction[(pwm << 1U) + 41U].Control = ((hetRAM->Instruction[(pwm << 1U) + 41U].Control) & (~(uint32)(0x00000018U))) | (action << 3U);
    hetRAM->Instruction[(pwm << 1U) + 41U].Data = ((((uint32)pwmPeriod * signal.duty) / 100U) << 7U ) + 128U;
    hetRAM->Instruction[(pwm << 1U) + 42U].Data = ((uint32)pwmPeriod << 7U) - 128U;

    }

    The output value change only if the data value written is greater from the previous value of about 70 and not every time changing the value of about 9 or 10

    Thanks

    Fabio

  • Hi Fabio,

    Just now i verified your code and values you are changing, however this behavior is expected.

    The reason is this:

    Actually, we can do the PWM resolutions with two clocks. One is loop resolution and other one is high resolution.

    The HALCoGen will generate the code with loop resolution only, that means HR data (lower 7 bits) will be ignored only higher 25bit data will be considered.

    For example, if you consider your case 

    I think you are trying to generate the 60us period and 30us duty cycle by default:

    If your loop resolution is 853.333nS

    Period count will be calculated as required period(60us) divided by one loop resolution period (853.333ns), which is equal to the ~70. And similarly, duty cycle count will be 30us/853.33ns and which is equal to the ~37.

    This is means that to generate 60us period i should copy this 70 to the higher 25-bit field of the data in the DJZ instruction (Because DJZ instruction is used for period generation in the HET code).

    So, if you did 7bit left shift to the 70 then the value becomes 8960, as you can see this is the value we are moving into the data field in your code by default, right?

    /* Program */
    0x00006302U, // low resolution 0x00006202U,
    /* Control */
    (0x00052007U),
    /* Data */
    8960U,
    /* Reserved */
    0x00000000U
    },

    Similarly, to generate the 30us duty cycle period i should copy the 3to the higher 25-bit field of the data in the PWCNT instruction (Because PWCNT instruction is used for period generation in the HET code).

    So, if you did 7bit left shift to the 37 then the value becomes 4736, as you can see this is the value we are moving into the data field in your code by default, right?

    {
    /* Program */
    0x00054301U, // low resolution 0x00054201U,
    /* Control */
    (0x00004007U | (uint32)((uint32)1U << 22U) | (uint32)((uint32)4U << 8U) | (uint32)((uint32)3U << 3U)),
    /* Data */
    4736U,
    /* Reserved */
    0x00000000U
    },

    So, the conclusion is that if we use loop resolution then we can't change the PWM wave form with less than loop period (i.e. 853.333nS in our case). We can only make the minimum change of at least 853.333ns only.

    If you want to make the less than 853.333ns, then we should use High resolution instead of loop resolution. And this high-resolution code will not be possible with HALCoGen by default.

    Either we should manually make the changes in the HALCoGen generated code or else we should generate our custom code using HET IDE.

    Unfortunately, i don't have any direct available example to provide you. Can you please refer TRM and try on your own for high resolution? If you stuck with implementation anywhere then i will provide you support for rectifying.

    --
    Thanks & regards,
    Jagadish.

  • Hi

    thanks for you very detailed explanation.

    Unfortunately I don't know if really I neded high resolution because onestly I don't know which is the frequency requested (now I'm workinfìg with this default configuration for init

    pwm_signal.period = (float64) 100;;
    pwm_signal.duty = (uint32) 50; 
    pwmSetSignal(hetRAM1,(uint32)PWM_CH1, pwm_signal);
    pwmSetSignal(hetRAM1,(uint32)PWM_CH2, pwm_signal);
    pwmSetSignal(hetRAM1,(uint32)PWM_CH3, pwm_signal);
    pwmSetSignal(hetRAM1,(uint32)PWM_CH4, pwm_signal);

    het_enable();

    het_setpin((uint32)pwm_channel_pattern[1]);//PWM1 pin b24
    pwmStart( hetRAM1, (uint32)PWM_CH1);

    het_setpin((uint32)pwm_channel_pattern[2]);//PWM2 pin c24
    pwmStart( hetRAM1, (uint32)PWM_CH2);

    het_setpin((uint32)pwm_channel_pattern[3]);//PWM3 pin b25
    pwmStart( hetRAM1, (uint32)PWM_CH3);

    het_setpin((uint32)pwm_channel_pattern[4]);//PWM4 pin c25
    pwmStart( hetRAM1, (uint32)PWM_CH4);

    For manual modifications about high resolution in het.c files ....are the modifications complicates?

    Thanks

    Fabio

  • Hi tried to use HET_IDE but I was not able to generate C code :-(

  • Hi Fabio,

    Unfortunately I don't know if really I neded high resolution because onestly I don't know which is the frequency requested (now I'm workinfìg with this default configuration for init

    If you don't need less than 1us resolution, then the existing example will be good to go.

    But if you want to generate the period or duty cycle with less than 1us change also then we should need to go for High Frequency resolution instead of loop resolution.

    If you want high frequency resolution example, then i will create it one for you.

    --
    Thanks & regards,
    Jagadish.

  • Hi

    I will check the PWM frequency but I'm afraid I need high resolution feature works.

    If it is not too hard or waste of time for you to have an example or indicate the changes to be made to have HR work, thank you in advance

  • Hi Fabio,

    If you want to change HR for only duty cycle, then you don't need to do complete code change, instead of you can just enable the HR in the PWCNT instruction which is used for duty cycle generation.

    If you reset the hr_lr bit like using below function:

    void EnableHRforDutyCycle ( hetRAMBASE_t * hetRAM, uint32 pwm)
    {
        hetRAM->Instruction[(pwm << 1U) + 1U].Program  &= (~0x00000100U);  /*Enabling HR for Duty Cycle*/
    }

    If you did this then you can change the least 7-bit data also.

    Data value on pwmchannel 0 = 4672

    PWM1=500 AN1=2087

    Data value on pwmchannel 0 = 4662

    PWM1=499 AN1=2087

    Data value on pwmchannel 0 = 4653

    PWM1=498 AN1=2087

    Data value on pwmchannel 0 = 4644

    PWM1=497 AN1=2087


    Data value on pwmchannel 0 = 4626

    PWM1=495 AN1=2087

    After doing this modification you see the changes in duty cycle for above values also.

    --
    Thanks & regards,
    Jagadish.

  • Hi

    I already trried setting manually by debugger and also by code but without success....it seems misdinh something else.....but i will tra agli on Monday.

    Thanks

  • Hi Fabio,

    I will test and provide a example project ASAP.

    --
    Thanks & regards,
    Jagadish.

  • Hi Fabio,

    I am not getting time to create example now, I will suggest you one simple method, just refer below thread

    (+) TMS570LS3137: When the coprocessor is used to output PWM, the waveform is inaccurate - Arm-based microcontrollers forum - Arm-based microcontrollers - TI E2E support forums

    As you can see the customer is generating PWM using only 4 instructions:

    You can do the same process to generate the PWM.

    Once you did this, we no need to keep the Loop resolution as 855ns.

    Each instruction will execute with 1/75Mhz right so we can just reduce the loop resolution to the 60ns (for 4 instructions), 

    Now this means our resolutions comes down to the 60ns from 855ns, so that means we can make the changes in the PWM generation with resolution of 60ns as well.

    --

    Thanks & regards,
    Jagadish.

  • Hi

    I'm afraid I didn't understood ..but I know I need a 10KHz PWM with resolution in thousandths so xx.y% where y has to be significat

    Thanks

    Fabio

  • Hi Fabio,

    If we bring down loop resolution to 60ns, then if we generate 10Khz signal with 60nS loop resolution then the lowest duty cycle that can be possible will be 0.06% (60ns*100/100uS).

    And this would be only possible through HET IDE because there we can generate PWM with 4 instructions only, whereas in HET IDE even if need 1 PWM also it will generate 58 instructions.

    And you can also find PWM example codes directly in HET IDE help section:

    So please refer those examples and try to generate PWM from HET IDE.

    --
    Thanks & regards,
    Jagadish.

  • Hi Jagadish

    how can I generate C code from HET IDE_

    I never used it before

    Thanks

    Fabio

  • and this my actual het.c5086.het.c

  • Hi Fabio,

    I created an example project with 10Khz (100us period) frequency and 50% duty cycle, using HET IDE.

    PWM_HET_IDE_LS3137.zip

    In this project i only used 4 instructions for PWM generation on N2HET1[1] (V2 pin of the controller):

    As i am using only 4 instructions, it will take only 44ns to execute them and i configured 88.889ns as loop resolution to give some buffer for execution.

    So, each data count int PWCNT or DJZ instruction will represent the 88.889ns. So, we can get the resolution of waveform with 88.889ns. I mean each data count will change the 88.889ns in output waveform.

    Example:

    1. Output Duty cycle for value is 562:

    TON = 49.9us and Tperiod =100us

    2. Now i increased the Duty cycle value by 1 that means 563:

    TON = 50us and Period = 100us

    3. Now i increased the Duty cycle value by 1 that means 564:

    TON = 50.1us and Period = 100us

    Now as you can see each change in the data value is affecting the waveform by ~0.1us(100ns).

    Use this project and build your application as below, remember if you want to generate two PWM waveforms then again you should need to increase the loop resolution.

    --
    Thanks & regards,
    Jagadish.

  • Hi Jagadish

    many thanks :-)

    I will try as soon as possible 

    Yes, I nees two PWM channles.

    Thanks&Regards

    FAbio

  • Hi Fabio,

    Yes, I nees two PWM channles.

    I would suggest you verify this output and if it as per your requirements then try to write code for two PWM's int he similar way as i did.

    I would create a project if you stuck at anywhere.

    --
    Thanks & regards,
    Jagadish.

  • I will try 

    many thanks

    Fabio

  • Hi Jagadish

    I tried to understand how your modification can be integrated in my code.

    I found these two main topic in het.c

    1) you call your program 

        (void)memcpy((void*)hetRAM1, (void*)HET_INIT0_PST, sizeof(HET_INIT0_PST));

    instead of my

        (void)memcpy((void *)hetRAM1, (const void *)het1PROGRAM, sizeof(het1PROGRAM));

    Can I use your program because it concerns only PWM and my program is unuseless? Or in my program there are some configurations that can create not working features in my applications?

    2) the other big issue is to use 88.889F instead of 1422.222F in PWM calculation. Can I substitute directly that value or I have also to modify some clock configuration?

    Other differnces seem to be need just to pin configurations so I keep my ones.

    Thanks

    Fabio

  • Hi Fabio,

    1) you call your program 

        (void)memcpy((void*)hetRAM1, (void*)HET_INIT0_PST, sizeof(HET_INIT0_PST));

    instead of my

        (void)memcpy((void *)hetRAM1, (const void *)het1PROGRAM, sizeof(het1PROGRAM));

    Actually, my program was generated from HET IDE instead of HALCoGen:

    HET_IDE IDE, configuration, compiler or debugger | TI.com

    My code is kind of custom code instead of default code from HALCoGen. The default HET code from HALCoGen have lot of instructions because it can perform lot of operations like PWM generation, edge interrupts and PWM capturing etc, so it have lot of code around 58 instructions that is the reason why it is taking more loop time. So to make it simplify and to reduce the loop time i generated custom code from HET IDE to reduce the loop resolution and to increase the overall resolution.

    Yes you are correct either you can use HALCoGen code or else you can use this custom code. You can not use both of them at a time.

    2) the other big issue is to use 88.889F instead of 1422.222F in PWM calculation. Can I substitute directly that value or I have also to modify some clock configuration?

    You cannot replace the PWM value directly, you should need to change the entire HET Code.

    Please open HALCoGen IDE and verify the below highlighted section in my project:

    Here i am directly giving the .h and .c files related to HET which were originally generated from HET IDE. These files have the simplified code that i mentioned earlier.

    --
    Thanks & regards,
    Jagadish.

  • Hi Javadish

    Yes you are correct either you can use HALCoGen code or else you can use this custom code. You can not use both of them at a time.

    I will try your program first and the default after because I'm afraid to loss something in my final application using only your simplified code for PWM

    Please open HALCoGen IDE and verify the below highlighted section in my project

    unfortunately I haven't my HaslCoGen initial project but I'm working only with generated C code

    You cannot replace the PWM value directly, you should need to change the entire HET Code.

    I will proceed with the same philosophy using first your het.c and het.h and then my ones also because I need the same hardware configuration to have the PWM output in the same pins as mine

    I will let you know something I suppose in September

    Thanks

    Fabio

  • Hi Javadish,

    I did some test and directly substituted het.c and het.h does not work anything ... probably I need to configure GPIO correctly.

    So I tried to integrate your program insted of mine in my project but also does not work anything.

    So I tried to integrate the your het.c code (mainly the calculation with 88.889F instead of 1422.222F and also tihis configuration

    /** - Setup prescaler values
    * - Loop prescaler
    * - High prescaler
    */
    hetREG1->PFR = (uint32)((uint32) 3U << 8U)       /* before was 7U */
    | ((uint32) 0U);

    setting manually the hr_lr bit in the Instruction register ....

    and something is moving better :-)

    Tomorrow I will check better all modification and result ... but I'm asking you a confirmation about hr_lr bit.

    You wrote some reply ago ,....

    In addiction I set the hr_lr bit with

    void EnableHRforDutyCycle ( hetRAMBASE_t * hetRAM, uint32 pwm)
    {
    hetRAM->Instruction[(pwm << 1U) + 1U].Program &= (~0x00000100U); /*Enabling HR for Duty Cycle*/
    }

    but in RM I see the hr_lr bit has to be setted equal 1 fo enable the high resolution .... is that correct?

    Many thanks

    Fabio

  • Hi Fabio,

    but in RM I see the hr_lr bit has to be setted equal 1 fo enable the high resolution .... is that correct?

    Yes correct, if we set hr_lr bit then instruction will use HR data for high resolution. Here i didn't enable this bit because, we already have very less code size and our loop resolution is very less, in this because it is not necessary to use HR data and as we have very less loop resolution right so we can get enough high resolution in our output waveform.

    --
    Thanks & regards,
    Jagadish.

  • Hi Javadish

    even though I set the hr_lr bit equal 1, the 7 LSB of Data are not considered .... I need some other configuration to use those 7 bits?

    Thanks

    Fabio

  • Hi Fabio,

    even though I set the hr_lr bit equal 1, the 7 LSB of Data are not considered .... I need some other configuration to use those 7 bits?

    I will test and provide you an example for High resolution as soon as possible.

    --
    Thanks & regards,
    Jagadish.

  • Hi Jagadish

    thanks.

    But now my PWM is good enough .... it would be only to know why I'm not able to work with high resolution.

    Thanks

    FAbio

  • Hi Fabio,

    But now my PWM is good enough .... it would be only to know why I'm not able to work with high resolution.

    I would like to clarify one thing, using the HR bit data will be depends on the lr factor.

    For example, if we configure lr factor as 8 as highlighted below:

    The data bits 3 to 0 in the HR data will not get considered for calculations, like as mentioned below.

    For more details refer the TRM,

    And also only highlighted below five instructions will support the HR data and for remaining instructions HR data will not be considered.

    And also, it is not possible to toggle the both the edges of the pulse with HR data only one of the edge can be toggled with the HR data based on the type of instruction we are using.

    If you try according to above inputs, then you might use the HR data.

    --
    Thanks & regards,
    Jagadish.

  • Hi Javadish

    I'm thinking I'm in your second hypothesis.

    The final PWM behavior is very precise setting:

    1) HRPFC = 0x8 (I'm not able to manage the HR data)

    2) pwmPeriod = (100 * 1000.0F) / 100.0F;

    in pwmSetSignal and     hetRAM->Instruction[(pwm << 1U) + 42U].Data = (uint32_t)(pwmPeriod*128) - 128U;

    3) hetRAM->Instruction[(pwm << 1U) + 41U].Data = ((uint32_t)((pwmPeriod * pwmDuty * 128) / 1000U)) + 128U;

    in pwmSetDuty

    Many thanks

    FAbio

  • Hi Fabio,

    I am checking this by creating one example at my end.

    I will provide my updates on this as soon as possible.

    --
    Thanks & regards,
    Jagadish.

  • Hi Fabio,

    I found something,

    Actually, the issue is only occurring for PWM0. I mean only for PWM0 high resolution data is not working, for all other PWM's it is working fine.

    For example:

    I created a project to generate the 4 PWM's, they are from PWM0 to PWM3 like as shown below:

    Case-1 (Testing duty cycle with loop resolution):

    By default, hr_lr bit for all the PWM's are set, that means PWM's are generating with only loop resolution:

    Verify the 8th bit hr_lr for all the PWCNT instructions for all the four PWM's:

    And here is the output i got for above configuration:

    I got all the PWM's with 51.21us of duty cycle period.

    Case-2 (Testing duty cycle with High resolution):

    Now, to test with high resolution first i am clearing the hr_lr bit for all the PWM's:

    Now i cleared the 8th bit in program instruction for all the PWM's to enable the high resolution.

    Now i also enabled the all the bits in the HR data to create the high-resolution delay:

    Before change:

    After change:

    After these changes here is my output PWM waveforms:

    As you can see the TON period for PWM0 was not changed but all other PWM's (PWM1 to PWM3) the TON period was increased. So high resolution is working for all other PWM's except PWM0. I don't know exactly why the high resolution is not working for PWM0, even though i did same configurations for all the PWM's.

    Maybe it should be a silicon issue, as of now you can try other PWM's and i will log this issue for design team.

    I am attaching my code for your reference:

    PWM_N2HET_LC4357.zip

    Please test it on your end and let me know the status.

    --
    Thanks & regards,
    Jagadish.

  • Hi Fabio,

    I hope above code solved the problem, and i will log the issue related to the PWM0 internally to the development team or else at least we try to include it in errata.

    --
    Thanks & regards,
    Jagadish.