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.

het produced PWM skipping a period occasionally

Other Parts Discussed in Thread: HALCOGEN, TMS570LS0332, TMS570LS3137

Hi,

I am running CCS6 with Halcogen 4.1 and the TMS570LS0332.

 

I have Halcogen set up to produce a pwm on pin 0 with a 50% duty cycle and a 7 ms period.  This signal gets routed back into the Hercules (eventually through an emergency stop, right not it is directly connected) to pin 6.

 

I have a 1 ms loop that runs to check the signal integrity.  I use capGetSignal (so have cap0 mapped to pin 6) to verify the duty cycle and period, but because these don't update if there is no edge, I set up an edge interrupt on both edges (so edge0 to pin 6).  When I get the edge interrupt, I set a flag true.  In my 1ms loop, I check if I haven't gotten a true flag for over half of the period.  If I have, then my signal is still OK and I can read the duty cycle and period.  If I haven't, then I assume the signal has flatlined.

 

For the most part this works well.  However, every once in a while (a couple of seconds to over a minute) the pulse produced by the het skips a period (or two), I have a scope screen shot below.

 

What could cause the het to skip a period?

 

Green trace - This line gets toggled when the edge count is over half the period, since I'm not breaking the signal, it should always stay low (or high).

Red trace - toggles in the edge notification where I flag an edge is detected.  This should have the same period as the PWM, which it does.

Blue trace - toggles at the start of each loop of my 1 ms main loop.

Yellow trace - test point connected to pin 0 of the nhet. This should always have a signal with 50% duty cycle and 7 ms period.

First picture is normal operation.

 

Second picture is where the error occurs.  You can see that the 1ms loop is running fine.  The green signal toggles each time the loop comes through because it hasn't seen an edge for over half the period.  See that the pwm out of the nhet skips two periods.

 

  • Hi David,

    I have forwarded your post to one of our N2HET experts and they should be able to help you out. In the mean time, can you tell us if there is any code in your main loop or in the interrupt routines that is accessing HET RAM? Also, do the missed edges occur at any regular frequency? i.e., every 20ms or every 1000 pulses, etc?

  • There is no other code that uses the HET RAM, only the pulse generation and monitoring, although it is worth mentioning that I have two pulses that I send out (different pins of course, at different periods) and I see the same behavior on both.  There are a few lines in the het that I  have configured as gio that are used to drive leds.

     

    The missed edges do not occur at a regular frequency.  Sometimes I see it twice within 50 or 100 ms, sometimes it goes over a minute without missing any.

  • Hello David,

      what is your het code to generate the PWM? Is it the CNT and ECMP?

  • I set all of the het (including pwm generation) through Halcogen, if I'm reading it right it is using PWCNT.  I attached the generated het.c file.

    1638.het.c

     

     I'm using PWM 0 and 1 (I have PWM 2 enabled, but am not using it at the moment).

  • Hello David,

      I will take a look and get back.  Once the het is running, I assume your application never writes to the HET RAM, right? 

      For a simple PWM you can actually use a CNT and ECMP pair. If your application is only creating two PWM outputs you just need two pairs of the CNT-ECMP.

  • Correct.  After initializing the het the only thing the application does is read from the het for the duty cycle and period (or write to the het registers for the I/O.)

    I've looked at using my own het program, and I have one written that generates pulses, I haven't checked to see if  it has the same error.  The reason I am using the halcogen generated code is that it *should* do what I need since in addition to generating the pulses I need to monitor the period and duty cycle and I generate an interrupt on each edge.  Since this can be done in halcogen it is easier than having all of the developers install the het ide and become familiar with it, halcogen is much more straightforward.

    Tomorrow I will try my own het program and see if I see the same behavior.

  • David,

      The HalcoGen het program is a more generic program to illustrate the capability of the het to generate PWM and perform input measurement. It does not cover all the available pins in the device. This is not to say that it should not work for the PWM you created. This is something I will look at tomorrow. The PWM generated by HAlcoGen utilizes PWCNT, djz, and two move64 instructions. When PWCNT and DJZ virtual counters are zeros they are reloaded with the pulse and period values using the two MOV64 instructions. I'm guessing maybe the move did not happen properly and  hence the PWCNT is not reloaded with the pulse value. 

      

  • Hello David,

      I tried to mimic your setup using HalCoGen. I use NHET1[8] to generate 7ms of PWM period. I route the PWM back to NHET1[0]  for input capture measurement. So far I'm unable to reproduce your result. Will look into it further. In the meantime please try to write your custom HET code. Suggestion will be to use the CNT/ECMP. Let me know if you see the same problem. 

  • Thanks for your help.

     

    I had previously written a het program that generates three pulses, captures the period and duty cycle, and branches for each pulse on the rising edge. Right now in my code I only monitor pwm 0. So I put that back in and  I see the same issue, scope capture and het code below.

    Yellow trace - direct from pin 0

    Blue trace - interrupt

    red trace - toggles when I miss a period.

     

     

    P1Start CNT    {  reg=A, irq=OFF, max= 17936 }
    P1End  	MCMP { en_pin_action=ON, order=REG_GE_DATA, pin=0, action=PULSEHI, reg=A, data=0x2308, hr_data=0x3 };
    P2Start CNT    {  reg=A, irq=OFF, max= 23061 }
    P2End  	MCMP { en_pin_action=ON, order=REG_GE_DATA, pin=2, action=PULSEHI, reg=A, data=0x2D0B, hr_data=0x1 };  
    P3Start CNT    {  reg=A, irq=OFF, max= 28186 }
    P3End  	MCMP { en_pin_action=ON, order=REG_GE_DATA, pin=4, action=PULSEHI, reg=A, data=0x370D, hr_data=0x3 }; 
    P1DC   PCNT { type=RISE2FALL, pin=6};
    P1PER   PCNT { type=RISE2RISE, pin=7};
    P2DC   PCNT { type=RISE2FALL,pin=8};
    P2PER   PCNT { type=RISE2RISE,pin=9};
    P3DC   PCNT { type=RISE2FALL,pin=10};
    P3PER   PCNT { type=RISE2RISE,pin=11}; 
    InterruptIfEdgeP1   BR { next=InterruptIfEdgeP2,cond_addr=InterruptIfEdgeP2,pin=6,event=BOTH,irq=ON};
    InterruptIfEdgeP2   BR { next=InterruptIfEdgeP3,cond_addr=InterruptIfEdgeP3,pin=8,event=BOTH,irq=ON};
    InterruptIfEdgeP3   BR { next=END,cond_addr=END,pin=10,event=BOTH,irq=ON};
    END   BR { next=P1Start,cond_addr=P1Start,event=NOCOND};
    

    I also did the program with just one PWM and had the same result.

     

    ; PWM, 3 channels with different PWM frequencies, using MCMP
    P1Start CNT    {  reg=A, irq=OFF, max= 17936 }
    P1End  	MCMP { en_pin_action=ON, order=REG_GE_DATA, pin=0, action=PULSEHI, reg=A, data=0x2308, hr_data=0x3 };
    P1DC   PCNT { type=RISE2FALL, pin=6};
    P1PER   PCNT { type=RISE2RISE, pin=7};
    InterruptIfEdgeP1   BR { next=END,cond_addr=END,pin=6,event=BOTH,irq=ON};
    END   BR { next=P1Start,cond_addr=P1Start,event=NOCOND};
    

  • Hello David,

      It is weird that every third PWM the MCMP did not reset the edge. Can you show me the machine code of the P1End MCMP instruction. I wonder if the conditional address of the P1End is causing the problem. Since you did not specify the cond_addr field for P1End, I don't know how the assembler will generate the condional address. Perhaps you can send me the entire machine code of the short program as shown below.

    ; PWM, 3 channels with different PWM frequencies, using MCMP
    P1Start CNT    {  reg=A, irq=OFF, max= 17936 }
    P1End  	MCMP { en_pin_action=ON, order=REG_GE_DATA, pin=0, action=PULSEHI, reg=A, data=0x2308, hr_data=0x3 };
    P1DC   PCNT { type=RISE2FALL, pin=6};
    P1PER   PCNT { type=RISE2RISE, pin=7};
    InterruptIfEdgeP1   BR { next=END,cond_addr=END,pin=6,event=BOTH,irq=ON};
    END   BR { next=P1Start,cond_addr=P1Start,event=NOCOND};
    
  • I think this is what you are asking for...if not let me know

     

  • David,

      The conditional address for MCMP is ok. Could you send me your het.c and het.h? I want to see if I can reproduce on my side.

      Also in HET IDE do you see the same problem on the waveform?

  • The files are attached.

    When you say in the het ide, do you mean in the simulator?  I haven't used it, I have only done this on actual hardware.

     

    6445.usr_het.c7635.usr_het.h

  • Hello David,

      I run your code and I'm measuring period of 25.4ms on the PWM using the scope. Whenever HET interrupts, I compare the duty cycle with the expected value and if it is not the same I toggle a GIO pin. I'm unable to see skipping PWM. However, I'm using the TMS570LS3137 device. But the NHET between LS04x and LS31x is pretty much the same as far as the PWM generation is concerned. Do you have a different board that you can try out? I'm not too sure if your application code makes a difference. Could you also send me your project that I can run identically?

  • In my experience with the het, if there are no edges, the duty cycle will not update, so it wouldn't show the error.  That is why I am counting edges in the first place.

     

    I've tried on two separate boards (they are custom boards, but both 0332).  I can try to reproduce it on the 1227 HDK I have.

     

    Do you have an 0332 you can try it on?

     

    I can send you my project, but it needs to be in a private conversation since it is proprietary.

     

    Thanks,

    David

  • David,

      I just added you as a friend. You can upload your project privately. Thanks.

  • Hi David,

      Now I'm seeing what you see after I set trigger on NHET1[16]. I don't know why the PWM is skipped. Will need to look into it. 

  • I'm glad you are able to reproduce it and it isn't just me!

     

    Thank you for all of the time you have spent on this.

     

    David

  • Hi David,

      I think it is caused by your below line. You are setting NHET1[16] to toggle LED but you should have used DSET instead of DOUT because using DOUT you override NHET1[0]. Try it and let me know. 

    {
    hetREG1->DOUT ^= led;
    }
    break;

  • Thank you! For now I have commented out the code to drive leds through the het, and I am not missing pulses from the pwm.

     

    Strangely, my code is still reporting that it is going over half of a period without seeing an edge, but the scope capture doesn't support this, so maybe there is something not quite right in my code.


    Thanks for your help.