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.

TMS570LC4357: Is this a legitimate HET program, HET start-up issues

Part Number: TMS570LC4357
Other Parts Discussed in Thread: HALCOGEN, TMS570LS1224

Various articles mention that the following HET instructions would generate two 1 PPS signals on HET1_4 and HET1_23, with LR of 1.6 microseconds...

L0 CNT { reg=A,max=624999,data=0};
L1 ECMP { hr_lr=LOW,en_pin_action=ON,pin=4,action=PULSEHI,reg=A,irq=ON,data=312500,hr_data=0};
L2 CNT { reg=B,max=624999,data=0};
L3 ECMP { hr_lr=LOW,en_pin_action=ON,pin=23,action=PULSEHI,reg=B,irq=ON,data=312500,hr_data=0};

However, I'm not seeing this happening reliably, as sometimes I see a nice 50% duty-cycle 1 sec clock and other times I see no clock or "random" (duty-cycle or period) clocks. This is after I just used CCS to download the image.  I actually have to power-cycle the Launchpad board to get the HET1 clocks started at all.

I suspect that regA and regB need to be explicitly initialized, or some such initialization is not happening.  hetInit() is always called in the same way.  The HET IDE shows all registers set to 0 on start-up, but I'm guessing this is either only in the simulator or some (real) "hardware" signal triggers it (on power-up?) rather than something done via hetInit().

Any insight would be highly appreciated.  Thanks.

  • This is the same old HET engine problem I've seen many times before, with minor differences in behavior.  Basically, Halcogen configuration for HET is messed up.  I am able to get out of this situation (only) by enabling PWM doing more or less the same thing, then disabling PWM.  The PWM mechanism apparently wires up something in Halcogen that gets the HET clock running properly on start-up.  When I disable PWM and go back to HET itself, that wiring stays in place and the HET engine starts up as would be expected.

    After some number of builds/runs, this behavior goes away and things go bad again.  It's possible something gets wired up in the hardware and stays there until some new image is loaded or some code wipes out that wiring.

    Sure would love to know what's going on, as this behavior is extremely scary when it's not well understood.

    Any help in figuring this out would be greatly appreciated.

    Thanks.

  • Looks like there's a nasty bug/limitation to the HET engine.  With the following instructions, one would expect L0+L1 to generate a 1 PPS clock on pin 4 and L2+L3 to generate another 1 PPS on pin 23.  Both clocks do get generated, but the one for pin 23 will disappear after some several seconds to many, many, minutes.  I've tried substituting reg=B with reg=T, and it seems to extend the failure point further, but the second clock will eventually fail.

    L0 CNT { reg=A,max=624999,data=0};
    L1 ECMP { next=L2,hr_lr=LOW,en_pin_action=ON,pin=4,action=PULSEHI,reg=A,irq=ON,data=312500,hr_data=0};
    L2 CNT { reg=B,max=624999,data=0};
    L3 ECMP { next=L0,hr_lr=LOW,en_pin_action=ON,pin=23,action=PULSEHI,reg=B,irq=ON,data=312500,hr_data=0};

    I don't think there's any work-around on this, but please let me know of other ideas/possibilities.

    Thanks.

  • Looks like the HET engine not starting up is related to the call to pwmStart(), when PWM is in use (rather than HET).  Somehow, pwmStart() leaves something "static" around so the HET engine gets to use it as a (unreliable) side benefit.

    A easy fix is to write a hetStart() function thus...

    // Same as pwmStart()
    void hetStart( hetRAMBASE_t * hetRAM, uint32 pwm)
    {
    hetRAM->Instruction[(pwm << 1U) + 41U].Control |= 0x00400000U;
    }

    and then call it right after hetInit()...

    hetInit();
    hetStart(hetRAM1, 0 /*pwm0*/);

    This ensures the HET (HET1) engine gets started.

  • Did you copy your code to HET RAM?

    The hetInit() generated by HALCOGen copies the HALCOGen HET code to HET RAM by default.

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

  • Hi,

    I would think the hetInit() did the memcpy().  As I mentioned, this was "erratic," in that the several HET(-only) builds after the one I used PWM would work fine, but at some point, the newer HET builds just don't do the start-up properly.

    If I added the hetStart() function (which is simply pwmInit()) explicitly, then the HET (HET1) start-up works fine (consistently).  The HET2 program seems to start up properly, consistently.

    Don't know why hetStart() was needed, but it's been working fine consistently for me.

    Thanks.

  • Oh, and I know the HET(-only) builds after the one I used PWM work fine because the HET-generated clock is "exact" whereas the PWM-generated clock is "approximate."  So, I know the HET program replaced the PWM program.

    Thanks.

  • I "think" I know why I experienced such oddball behavior.  I noticed that because I often do flash erase (Properties->Debug->Flash_Settings) to only erase "Necessary Sectors Only (for Program Load)," somehow the HET program doesn't load/start properly at times (after a while).  It seems that if I erase "Entire Flash," at least when a "new" (rather than "incrementally revised") project is introduced, then the HET program does start properly.  I can't say this definitively at this point, since this is just observation over a handful of times of flashing.  Even when the HET start failed before, using "Necessary Sectors Only," it was just sporadically/unpredictably.

    As i previously mentioned, I was able to "fix" my failed/stuck case by switching to using PWM/pwmInit() and then back to HET.  PWM does something HET doesn't do, but perhaps the full flash erase makes up for it.

    If anyone has more insight into the flash layout and execution sequence with respect to HET program loading and starting, please let me know if my observation has merit.

    Thank you very much.

  • When "necessary sectors only" is checked, are the flash sectors needed for program (in the map file) erased? and the new program loaded?

  • Is the correct device name selected in CCS project property?

    If LC43x board is used, but LS31x device is selected in CCS, selecting "necessary sectors only" option may not erased the all the sectors needed by the program.

    The size of 1st four sectors of flash on LS3137 is 32KB

    The size of 1st four sectors of flash on LC43x is 16KB.

    If your code size is 120KB, only 4 sectors are erased which is smaller than image size (64KB vs 120KB). 

  • The "Variant and core" is set to "TMS570LC43xx."

    Unfortunately, it seems fully erasing flash makes no difference.  I switched to always erasing "Entire Flash" yesterday and did not see any problems yesterday after many build/load cycles.  However, I'm seeing the problem (HET1 not running) again today.

    I had to go back to running my stand-alone project once and use it to run pwmStart() with relevant Halcogen PWM set ups, then going back to using HET.

    It's as if PWM does some non-volatile hardware changes on the board that the HET facilities subsequently makes use of.

    I really need to figure out how to get HET reliably loaded and run, as this PWM hack is not tenable.

    I don't know if erasing "Necessary Sectors only" erases every program sector, but subsequent runs are using newly compiled code.

    Thank you very much.

  • Hi Peter,

    The pwmStart() is to enable the pin action of the N2HET code generated by HALCOGen. If you use your own N2HET code (from HET IDE), the pwmStart() won't work.

    Selecting "Necessary Sectors only"  or "Entire Flash" doesn't affect the NHET code in NHET RAM. The NHET code is copied from flash to NHET RAM in hetInit():

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

  • Hi, QJ,

    Yes, I'm aware of the way pwmStart() and hetInit() works, having walked through them many times.

    Because the PWM set-up (doing hetInit() and pwmStart()) is able to do something to clear up the "hang" encountered by a pure-HET set-up, I'm thinking the fast-fix for this problem is just to take the code from a PWM set-up and execute it as a pre-init operation prior to the init operation.

    Hence, I created the hetPreInitHET1() function (from the hetInit() from PWM set-up) and run it just before the hetInit() function (from pure-HET set-up).  The HET-only set-up runs properly, and I hope the pre-init code will ensure that whatever caused any hang would go away.  Of course, if I did things the right way, I would narrow down exactly what in the pre-init code performs the un-hanging.  But, that takes time.

     So far, I've not seen any hangs, and hope the pre-init code fix actually works.

    Thank you very much.

  • To be honest, I am not very clear about your NHET code in NHET RAM, hetPreInitHET1() and modified hetInit(). Modified hetInit() means new hetInit() may not contains the memcpy(), prescaller config, etc.

    Hope your hetPreInitHET1() works as expected. 

  • Hi, QJ,

    I just want to clarify what my original problem was, and what my current quick-fix is (that seems to work).

    WIth my original HET set-up, where HET1 used a simple 2-line program to generate a 1PPS clock (a poor-man's signal generator for testing), in most cases, writing the image into the TMS570 chip and running it worked fine. The 1PPS clock was generated.  However, once in a while, that 1PPS clock didn't get generated and I couldn't figure out why, despite flashing the image many times.  Because I had originally used PWM to try to generate the 1 PPS clock (can't do exactly because of PWM parameter limitations), I went back to using PWM and was able to generate the (more or less) 1 PPS clock again.  I found that the PWM clock generation would "clear up" the problem with HET1 no longer generating (in subsequent pure-HET images).

    So, the observation/hypothesis is that the PWM Halcogen generated code does something the HET PWM Halcogen generated code does _not_ do.

    Then I guessed that perhaps it was an issue of partial verses complete flash erasing (for the pure-HET image), but experiments along this line showed flashing method made no difference.

    Hence, I tried a "quick-fix" consisting of pre-programming the hardware with the chunk of HET1 code from the PWM project's hetInit(), which I put in a hetPreInitHET1() function, prior to running the hetInit() from the pure-HET project.  The code in hetPreinitHET1() writes a whole bunch of registers and writes the PWM program into HET RAM.  The code in hetInit() then over-writes (some) of the pre-initted registers and the HET HET1 program into HET RAM.

    So far, the quick-fix has seemed to work, and I have not seen any new images running where HET1 stops being generated.

    It's highly likely that the the observation/hypothesis above is correct, and that something in the hetPreInintHET1() function touches some hardware that the (pure-HET) hetInit(), generated by Halcogen, should do.

    If I had the time, I should narrow down exactly what code (one or more register writes, or the PWM program copied to HET RAM) in hetPreInitHET1() prepares the subsequent pure-HET hetInit() to _always_ work (generate 1 PPS clock).  This search process is very tedious and time-consuming, since the original problem doesn't happen that often (but is incredibly annoying, and a show stopper, when it does).

    Thank you very much.

  • Your hetPreinitHET1() writes HAL generated code (PWM code) to NHET RAM, and hetInit() write your own code (PPS code) to NHET RAM which overwrites first 4 instructions of PWM code.

    Your PPS code:

    L0 CNT { reg=A,max=624999,data=0};
    L1 ECMP { next=L2,hr_lr=LOW,en_pin_action=ON,pin=4,action=PULSEHI,reg=A,irq=ON,data=312500,hr_data=0};
    L2 CNT { reg=B,max=624999,data=0};
    L3 ECMP { next=L0,hr_lr=LOW,en_pin_action=ON,pin=23,action=PULSEHI,reg=B,irq=ON,data=312500,hr_data=0};

    The first 4 instructions of PWM code are:

    L0 CNT

    L1 PWNT: PWM 0 -> Duty Cycle

    L2 DJZ: PWM 0 -> Period

    L3 PWNT: PWM 1 -> Duty Cycle 

    Because the next instruction of L3 instruction of PPS code is L0, the NHET micromachine only executes your PPS code. The remaining PWM code in NHET RAM doesn't affect the PPS execution.

  • Hi, QJ,

    Yes, I realize that the HET1 "overwrite" _should_ negate all the PWM hetInit() code.  I have not narrowed down the issue to the HET1 RAM contents or the HET1 registers that were pre-initialized.  I can't even say with absolute certainty that my problem has totally gone away, although I have not seen it recur since the fast-fix was added.

    My current HET1 program has gotten even smaller, only generating a 1 PPS on HET1 pin 23.

    L0 CNT { reg=A,max=624999,data=0};
    L1 ECMP { next=L0,hr_lr=LOW,en_pin_action=ON,pin=23,action=PULSEHI,reg=A,irq=OFF,data=312500,hr_data=0};

    The old HET1 program, generating 1 PPS on both pin 4 and pin 23 had some odd behavior in that the pin 23 PPS clock (second item) would die out after running for some number of seconds to minutes.  Since I didn't really have to have both pins going, I removed the code for the second clock, and didn't chase the problem any further.

    I will update you on further findings, especially if the problem happens again.  I will try to isolate the fix if/when I have time.

    Thank you very much.

  • Hi Peter,

    Is CPU trying to change the data field and control field of L1 instruction (ECMP) on the fly? If the data field of ECMP instruction is changed directly by CPU, one or more pulses can be missed.

    The MOV32 or MOV64 instruction is recommended to be used for changing the fields of other instructions.

  • Hi, QJ,

    No, the HET1 program is generating a fixed 1 PPS clock on pin 23, as shown in the 2-lines of code above.

    Just out of curiosity, I went back to the 4-lines program that generates 1 PPS on pins 4 and 23, and indeed it still fails to generate the second clock (L3 and L4).  This is an unrelated "bug."  When I went back to the 2-lines program, the 1 PPS on pin 23 appeared again.

    Note that the problematic behavior (alleviated by the quick fix) is not the output clock skipping a beat or two, but that it doesn't generate at all (probably because HET1 program doesn't run at all).

    I do have a HET2 program that generates a 5 mec clock that "auto-aligns" to an input 1 PPS clock, but that program runs properly, consistently.  That program does change the data in ECMP.

    Thank you very much.

  • I am not able to generate the problem with your 4-line PPS code running on HET IDE. My waveviewer is free eval-version, so I am not able to simulate your code for longer period of time.

  • Hi, QJ,

    Thank you very much for running the program in the simulator.  I am also using the free waveviewer and so can only see some 10+ msec of data.

    In any case, the problem is not (likely) with the simulation, but with running the program in real hardware.  If I can find some time, I will put just the 4 lines of HET code in some standalone project and see if things break.  One simple thing is to just set  irq=ON on L2 and L4 and pick up interrupts on the CPU

    BTW, I've also seen the HET1 (pin23) go "nuts," not generating a 1 PPS but some kind of higher-frequency noise when irq=ON, which caused debilitating interrupts to the CPU (to the extent that the project couldn't do anything).  So, I've had to keep HET1 interrupts masked off.

    I'll have to get back to this, since my quick-fix seems to be working well so far.

  • I run the PPS code on my launchpad (80 seconds), and did not see the issue:

    PPS code:

    L0 CNT { reg=A,max=624999,data=0};
    L1 ECMP { next=L2,hr_lr=LOW,en_pin_action=ON,pin=6,action=PULSEHI,reg=A,irq=ON,data=312500,hr_data=0};
    L2 CNT { reg=B,max=624999,data=0};
    L3 ECMP { next=L0,hr_lr=LOW,en_pin_action=ON,pin=9,action=PULSEHI,reg=B,irq=ON,data=312500,hr_data=0};

    BTW, I test the code on TMS570LS1224 launchpad:

    7331.het.c

  • IRQ is enabled in L1 and L3 (ECMP instructions).

    Pin 6 and pin 9 are used because those two signals are routed to header on LP board.

  • Hi, QJ,

    I have uploaded two projects to Protonmail.  One generates a single 1PPS clock on HET1_23 and the other generates two 1PPS clocks, on HET1_4 and HET1_23.  The first works as expected, printing to sciREG1 at 115200 2N1,  The second doesn't work, likely due to incessant HET1 interrupts, and no printing starts.

    site: www.protonmail.com

    user: shareuser1000@proton.me

    pass: password

    subj: HET1 1PPS projects, single and dual

    Thanks.

  • I uploaded another project consisting of the dual clock but calling hetPreInitHET1() prior to hetInit().  This project works fine, and output to sciREG1 indicates both clocks running.

    subj: HET1 1PPS project, dual with preInitFix

    Thanks.