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.

NHET generating wrong PWM frequency?

Other Parts Discussed in Thread: HALCOGEN

Hi,

 

I'm using HALCoGen to setup a simple PWM output and am having problems getting the output frequency correct.  My requirement is 460.8kHz 50% duty cycle.  Some other system parameters are:

 

HCLK = VCLK = VCLK2 = 64MHz

hetREG->PFR->LRPFC = 4

hetREG->PFR->HRPFC = 0

 

HALCoGen settings for PWM:

Duty % = 50, actual calc = 1.250us

Period us = 2.17, actual calc = 2.250us

 

These settings achieve a 444.444 kHz signal on the output as predicted by HALCoGen.  The next lower setting for Period us will bump the actual calc down to 2.0 us, which would be a 500kHz signal.  So it seems like I need a smaller LRP to achieve a higher resolution of frequency.  If I set HALCoGen to use a 125ns Loop Time, it will drop the LRPFC setting to 3 from 4 and now my PWM frequency calc can change in 125ns increments.  So this will get me closer at 2.125us period (470.6kHz).  When I try the LRPFC setting of 3, then my PWM will not output correctly.  Instead, it outputs a constant logic high.

 

So my question is what's going on here to make the HET functionality break w/ the LRPFC setting of 3 rather than 4?  I suspect the answer has to do with the number of instructions in the HET program and how many cycles it takes to run to completion per loop cycle.  If this is correct, then can it be that the HALCoGen generated HET code is too long for my required LRPFC?  At the moment, all I need is 1 PWM, but we will need a 2 other timers at some point.  How can I get HALCoGen to generate a minimum set of code that meets my requirements?  There is a lot of code generated that is for channels that are not going to be used.  Please advise.

 

Thanks,

Marco

  • Marco,

    please don't take this the wrong way, but getting your hands dirty with HET assembly code would be one option.

    An indirect way of handling it may be with the frequency.

    Do you have flexibility to play with HCLK/VCLK frequencies? With the vast number of multiplier/divider configurations available in the PLL, you could get to 460.8kHz with your original HET code by just using different PLL settings.

    Regards,

    Abhishek

  • Abhishek,

     

    Thanks, and yes, I'm not above getting my hands dirty :)

     

    At this point I'm just trying to understand what the problem is.  Right now we have some power numbers that we are trying to hit, so increasing clocks might not be the best route for this.  I can generate some PWM assembly using the HET IDE and that just gives me 2 instructions in my HET RAM.  However, I have not gotten this to work yet and have not dug into the assembly language.

     

    What I'm really trying to understand is why the code works with LRPFC of 4, but changing it to 3 makes it not work.  Am I correct that it has to do with the number of instructions being programmed into the HET RAM?  My concern here is that I can get the PWM to run if I that's the only thing the HET is doing, but if I start adding code and more functionality, then it may "break" at some point and I will lose the accuracy needed of my PWM.

     

    Marco

  • I'm trying to get a PWM to work using the HET IDE to generate the assembly code.  For now, I have a working HALCoGen generated code set giving me a 444.4kHz PWM just fine.  I go into the HET IDE and tell it to insert a PWM signal with the same 444kHz config.  See screenshot attached.

     

     

    The code generated is this:

     

    ;PWM code for given HCLK frequency = 64MHz  ,PWM frequency = 0.4444MHz  ,duty cycle = 0.5% ,HETPFR value =0 is below:

    L00 CNT {reg=A, max=143, data=0}

    L01 ECMP {next=L00,hr_lr=HIGH,en_pin_action=ON,pin=10,action=PULSELO,reg=A,data=72,hr_data=0}

     

    I assembled it and then I can use the "Send to HALCoGen" option under the tools menu and it will update the het.c that HALCoGen previously generated and was working.  So the only thing that changed in het.c was the data that is to be written to HET RAM, and it now only contains a single PWM function.  Recompiling and running this version of the HET program does not function, it just outputs a zero.  What am I missing here?

     

    Thanks,

    Marco

  • Hi Marco Moreno,

    I guess because of the value 0 for HETPFR register your hr (high resolution) and lr (loop resolution) prescalers are set to 1. This means that your LRP in which the HET code for PWM generation must fit is too small (only one LRP=HRP=VCLK2 cycle). Try to use the same settings for HETPFR as in your first try, where you used only HALCoGen. Try it with 8 for the lr prescaler and 1 for hr prescaler. This would lead to 8 time slots (VCLK2 cycles) for the HET program, which should be enough for a simple PWM generation.

    Best regards,

    Gregor

  • Hello Marco Moreno,

    were you able to find the reason for the not working PWM output using HET IDE?

    If my suggestion did not help. Can you check whether the generated code from HET IDE matches the code generated by HALCoGen?

    Best Regards,

    Gregor

  • Gregor,

     

    Thanks for taking a look at this.  I am using the GHS toolchain, so there may have been a compiler incompatibility.  What I found was that HALCoGen generated het.h with:

     

    typedef volatile struct hetInstructionBase

    {

        unsigned Program;

        unsigned Control;

        unsigned Data;

        unsigned : 32U;

    } hetINSTRUCTION_t;

    and het.c from HALCoGen looks like:
    const hetINSTRUCTION_t hetPROGRAM[] =
    {
        {
            /* Program */
            0x00002C80U,
            /* Control */
            0x01FFFFFFU,
            /* Data */
            0xFFFFFF80U,
        },
        {
            /* Program */
            0x000055C0U,
            /* Control */
            (0x00004006U | (8U << 8U) | (0U << 3U)),
            /* Data */
            0x00000000U,
        },
    }
    So things are aligned and OK with this combo.  The HET IDE however outputs this into het.c:
    const hetINSTRUCTION_t hetPROGRAM[] =
    {
    0x00002C20
    , 0x00000022
    , 0x00000000
    , 0x00000000
    , 0x00004000
    , 0x00404118
    , 0x00000800
    , 0x00000000
    , 0x000014C0
    , 0x00006007
    , 0x00000000
    , 0x00000000
    };
    It turns out the compiler was inserting an extra 32-bit word after every 3 words.  So I worked around this by making this change in het.h:
    typedef volatile struct hetInstructionBase
    {
        unsigned Program;
        unsigned Control;
        unsigned Data;
        unsigned Blank;
        //unsigned : 32U;
    } hetINSTRUCTION_t;
    and things line up that way.  Not sure if this behavior exists in CCS, but this is what works in GHS.
    Marco

  • Marco,

    yes you are right. It is the same for CCS. You have to insert a dummy word, instead of the 'unsigned : 32U' statement. It is also the same for the NHET/N2HET which would be like this...

    instead of

    It seems that you have solved the problem by yourself, but if you would like to go the way of adapting the standard HET IDE program code for PWM, I can recommend you to have a look at this document.

    http://www.ti.com/general/docs/litabsmultiplefilelist.tsp?literatureNumber=spraba0b

    It describes how to calculate the values for the data/hr_data fields in order to get the correct PWM frequency and duty cycle.

    Best Regards,

    Gregor