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.

TMS570LS1227: HET program

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

Hello, 

I am working on TMS 570 LS1227 and want to generate 2 duty cycles  in alternate fashion but it's not working 

I have  updated new  duty cycle through 'C' code for my basic HET program.

; PWM with synchronous duty cycle update at compare match event
L00 CNT     {  reg=A, irq=OFF, max= 100 }
L01 ECMP { next=L02,en_pin_action=ON,pin=2,action=PULSELO,reg=A,data=10,hr_data=0};
L02   BR { next=L00,cond_addr=L03,event=ZERO}; after completing 1 complete PWM cycle, it will go to next instruction
L03   MOV32 { next=L00,remote=L01,type=IMTOREG&REM,reg=NONE,data=80,hr_data=0};write new duty  cycle 1
----------------------------------------------------------------------------------------------------------------------------------------------------------
int main(void) { /* USER CODE BEGIN (3) */ int i ,j; hetInit(); while(1) { i=20; hetRAM1->Instruction[L03].Data = i << 7; // Change the duty cycle to 20% for (j=0;j<10000;j++); //delay till - writing new duty cycle and generation 1 complete cycle i=i+40; hetRAM1->Instruction[L03].Data = i << 7; // Change the duty cycle to 60% } /* USER CODE END */ return 0; }

-----------------------------------------------------------------------------------------------------------------------------------------------------

  O/P on oscilloscope - 

Is it the delay causing the error ? 

Regards,

Suyog

  • Yes the delay is a simple but crude way to update the duty cycle.

    And you need to have two delays, one after each update.

    There is very little time between line 15 executing and then line 11 executing again. Likely < 1 HET loop and very good chance that the duty cycle update on line 15 is very often missed (most of the time). You might get lucky sometimes but it will be infrequent.
  • Hello,

    I tried the same but it was of no use-

    int main(void)
    {
    /* USER CODE BEGIN (3) */
    	
    	
    	int i ,j;
    
    	hetInit();
    	while(1)
    		{
    			i=20;
    			hetRAM1->Instruction[L03].Data = i << 7; // Change the duty cycle to 20%
    			for (j=0;j<10000;j++); //delay till  - writing new duty cycle and generation 1 complete cycle
    			i=i+40;
    			hetRAM1->Instruction[L03].Data = i << 7; // Change the duty cycle to 60%
    			for (j=0;j<10000;j++);
    		}
    
    /* USER CODE END */
    
        return 0;
    }
    

    Do you have the  sample program for rewrite and update operation ?

    Can you tell me how to deal with delay ?

    Is there any way to read the current HET register value ?

    Can we add watch / breakpoint for HET register ?

    Regards,

    Suyog

  • You might need a longer delay for the longer duty cycle.

    The issue here is you are asynchronously writing to the compare 'buffer' register at hetRAM1->Instruction[L03].Data.
    If you over-write this before the ECMP occurs to copy the 'buffer' into the operating compare register, then the value in the interim
    will never result in anything you see on a pin.

    The HET has interrupt capability so that you can make your updates inside an ISR. And you can always 'poll' the interrupt status instead of
    taking an actual interrupt if you just want simple code like your delay loop code.
    I'd suggest trying that (enable the interrupt on the ECMP instruction and poll the status of the interrupt before writing to the hetRAM1->Instruction[L03].Data address. Also then make sure to clear the interrupt flag so you can repeat the process.
  • I'm newbie to MC programming. I'll get back to you once got clear.  Till what I understood ...

    While (1 )

    {

       if (Interrupt_flag ==  set )    // set = 0x2?

              {

                    write new duty cycle to data field  

                    Interrupt_flag = reset        

             }

    }

  • Basically that's correct.

    Always read the TRM chapter for any hardware registers though, especially as you learn about the hardware.

    The difference between a hardware register and just 'normal memory' is that the hardware register may be changed behind the scenes by something other than the CPU and that sometimes the hardware is designed differently than memory.

    For example you might find a register description that says 'to clear a bit, write a '1' to the bit' ... sounds opposite of what you expect but there is a good reason for this. You might also find registers where reading the register clears any bits that are set.

    Now for the HETFLG register if you look at the register description you will see:

    0 Read: No N2HET instruction with an interrupt has been reached since the flag was cleared.
    Write: No effect.

    1 Read: A N2HET instruction with an interrupt has been reached since the flag was cleared.
    Write: Clears the bit.

    So it's a write-1 to clear type register.

    Now another way to read if there are any interrupt flags set is by reading one of the offset registers like HETOFF1..
    But note the fine print there:
    Note: In any read operation mode, the corresponding flag (in the HETFLG) is also cleared. In Emulation
    mode the corresponding flag is not cleared.

    So there is a read-clear side effect that you need to be aware of if you read the 'equivalent' information from HETOFF1.

    Just trying to give examples of what to look for since you said MCU newbie... but you are on the right track.

    Best Regards,
    anthony
  • Hi Anthony,

    i'm struggeling with HETFLG in a TMS570LC4357.

    It is either always set or never.

    I assumed it to be reset automatically in void het1HighLevelInterrupt(void) when reading hetREG1->OFF1.

    From this thread I assume it is not reset on read when using the XDS100v2?

    It is not reset on read as well if I disconnect the USB cable of the eval board.

    If I reset it in ISR (writing 1 as described above)  i get the first Interrupt when setting LSB of hetREG1->GCR but never again.

    If I don't reset in ISR it is never reset and the ISR is entered every ~300ns.

    How can I detect if code in HETram is alive? In HET IDE it seems to work.

    Thanks in advance for any suggestion

    BR Olaf

  • Hi Olaf,

    You should first be aware that it is possible to configure the device so that HET continues to run while the CPU is halted (Continue on suspend).

    In this case you would continue to have HET request interrupts and it would probably look like you can never clear the interrupt flag; because in the time it takes CCS to read the memory and update the display again your HET program may have requested another interrupt.

    Reading hetREG1->OFF1 only clears 1 interrupt flag .. the highest priority. So if you have multiple HET instructions that are interrupting you would need to read hetREG1->OFF1 multiple times until it returns 0 in order to actually clear the interrupt request to the CPU.

    You can watch the HETADDR register and set CCS to update it's value automatically ... if you see it changing then you know HET is running. Alternatively you can check HETGCR; if bit 0 is set then the HET is running something. It may not be running what you think it should be ... but it is executing whatever is in the HET RAM whenever the TO bit is set.
  • Thanks Anthony,
    the "ignore suspend" is disabled in Halcogen. 
    The Nhet1_GlbCtrl reads
    0x00010001    IS unset, master set,  TO is set.

    But Nhet1_Addr is always 00000005

    after removing a breakpoint in HET IDE the adress is always

    Addr    pointer    0x000000D7    0xFFF7B808    
    but the HET program has 6 steps only (0..5)

    Nhet1_IntEnaSet
    00000018
    Nhet1_IntEnaClr
    00000018

    only one Interrupt is pending:

    Offst1    pointer    0x00000005    0xFFF7B80C    
    IntFlg    pointer    0x00000010    0xFFF7B828    

    The HET code seems to be stopped but the TO is still set?
    Best Regards
    Olaf

  • Solved!

    I lost lots of time with debugging strange and unexpected behaviour of my HET code. 
    In an act of desperation I decided to fill the remaining HET RAM with "protective" branch instructions to the first instruction:

    PROTECT1   BR { next=STARTEN_,cond_addr=STARTEN_,event=NOCOND};
    PROTECT2   BR { next=STARTEN_,cond_addr=STARTEN_,event=NOCOND};
    PROTECT3   BR { next=STARTEN_,cond_addr=STARTEN_,event=NOCOND};
    PROTECT4   BR { next=STARTEN_,cond_addr=STARTEN_,event=NOCOND};
    PROTECT5   BR { next=STARTEN_,cond_addr=STARTEN_,event=NOCOND};
    PROTECT6   BR { next=STARTEN_,cond_addr=STARTEN_,event=NOCOND};
    PROTECT7   BR { next=STARTEN_,cond_addr=STARTEN_,event=NOCOND};
    .....

    Now it works, I get HET interrupts, the IntFlgs are cleared as expected, the timing measured in oscilloscope is as expected.

    Question:
    What is the recommended initialization value for unused HET RAM to avoid strange behavior and to avoid parity errors in HET RAM?

    Suggestion:
    Insert an Initialization in auto generated code to fill unused parts of HET RAM with "safe" initialization values in
        void hetInit(void).
    The current initialization
        (void)memcpy((void*)hetRAM1, (void*)HET_INIT0_PST, sizeof(HET_INIT0_PST));
    is restricted to sizof (used-HETRAM). I found random numbers in the unused area before I did my own initialization. .

    Best Regards

    Olaf