Question about changing the PWM compare value - Cypress.com Forums http://www.cypress.com/? Re: Question about changing the PWM compare value http://www.cypress.com/?rID=71944 I have been bugged by the same kind of problem - about 7 years ago I did a project using PSoC 1, which I am now porting to PSoC 3 - I had solved the problem on the PSoC 1 but could not remember how I did.. After examining the original code I found that I fixed the problem with external glue logic which can be easily fitted in the PSoC 3..

On the original I used a SR latch, Compare output set the latch, TC reset it .. The output from the latch was glitch free - if a new compare value is written after the latch is set (after the compare output goes high) then whatever state the compare output goes to before TC is ignored.

I have not yet tested this with PSoC3 - I feel sure it will work in my application at least - and cannot see any reason it wont work as shown in attached .pdf.

 

 

]]>
Thu, 08 Nov 2012 15:06:14 -0600
Re: Question about changing the PWM compare value http://www.cypress.com/?rID=51831 Hmmm, actually there might be a documentation bug here.

The TRM (in section 27.3.4.3, subsection "On The Fly Duty Cycle Update", page 308 of revision E) says:

Support for multiple comparisons depends on the bit
CMP_BUFF in Configuration register CFG0. The following
describes the process:
■ When the CMP_BUFF is set to ‘1’; the updated comparator
value takes effect only after completion of the currently
running period. After the terminal count, the new
compare value is taken for further comparison. When
this mode is used, the PWM block detects only one compare
during a period.
■ When the CMP_BUFF is set to ‘0’; the updated comparator
value takes effect immediately even before the completion
of the current running period. This may result in
another toggling of the pin even before the completion of
current period, thus supporting multiple comparisons.

Of course, it's talking about the fixed function block. As nearly as I can tell by reading the generated C for my 16-bit fixed-function counter, this bit is set to 0? (It's certainly possible I misread it.)

It seems to me that the data sheet for the PWM component, quoted in my previous post, states that this bit is enabled. (You could argue it should be configurable.)

That still leaves open the question of whether the UDB implementation also supports this feature, and if so whether it is enabled by the component or not. Since the component datasheet seems to say that double-buffering is supported (without qualifying as to implementation) it seems that it should be?

There's more going on here than I first thought, it seems.

See also section 1.3.186, "TMR[0..3].CFG0 Configuration Register CFG0", page 297 of revision A in the PSoC 5 registers TRM.

]]>
Fri, 03 Jun 2011 09:28:55 -0600
Re: Question about changing the PWM compare value http://www.cypress.com/?rID=51793 What is meant by this sentence in the datasheet?

"The PWM outputs are double buffered to avoid glitches due to duty cycle
changes while running."

]]>
Thu, 02 Jun 2011 17:19:17 -0600
Re: Question about changing the PWM compare value http://www.cypress.com/?rID=51782 Doug,

 

One-shot Multi trigger mode is similar to a mono-stable multivibrator. This may eliminate many issues in your case.

]]>
Thu, 02 Jun 2011 06:30:27 -0600
Re: Question about changing the PWM compare value http://www.cypress.com/?rID=51779 Hmm, the DMA idea is a good one, but if i undestand properly it will only shorten the glitch.

I am sending one pulse every 2.5ms, but luckily for me each channel will either get a pulse between 500us and 2250us or no pulse at all. Now that I think about it overnight, I think I can see a clean solution. (Which I will write here in case it can help anyone else)

In the compare ISR:

  • let n be the index of the next channel
  • update the control register for the demux to select channel n
  • iff the next channel should receive no pulse at all, set the compare register to equal the period of the PWM generator (since it is in "Greater" compare mode, this will result in no pulse at all)

In the overflow ISR:

  • set the compare register equal to the pulse length required for the current channel (perhaps conditionally on whether it was already done, although it doesn't matter if you do it always)

I think this always works, assuming the following timing. The compare ISR must be serviced within (2500us pwm period - 2250us longest possible pulse) = 250us; this is necessary to ensure that we don't emit a pulse at all if channel n requires one and channel n + 1 mod 8 does not require one. The overflow ISR (or DMA) must be serviced within 500us, because otherwise if channel n has a longer pulse and channel n + 1 mod 8 has the shortest pulse, channel n + 1 will receive too long of a pulse.

I could make it even safer by having the hardware interrupt or hardware tc line latched into a flip flop, such that it is set from when the TC occurs until the FW (through another bit of the same control register used for the demux) clears it. This would be used to drive the kill input. The ISR can disable the PWM (clearing bit 7 of the control register stops the PWM clock, if I understand properly), do what it needs to do, possibly PWM_WriteCounter(0) if it discovers that it has arrived "late", and move on with life. Then the worst that can happen is a delay in starting to generate the next pulse, which doesn't hurt my application.

 

 

All of that would fix it, but I just discovered the run mode setting. One-shot multi-trigger with the trigger coming from an auto-clearing bit in a control register that the TC ISR sets, and I get the same outcome as above but with none of the nonsense! Light dawns.

]]>
Thu, 02 Jun 2011 06:03:34 -0600
Re: Question about changing the PWM compare value http://www.cypress.com/?rID=51775 Hi Doug McClean,

 

From the API Definition of PWM_1_WriteCompare1(compare), we can see that the compare value is updated immediately when the API is called.

It doesn't wait for the PWM counter to roll over.

 

void PWM_1_WriteCompare1(uint8 compare)
{
    #if(PWM_1_UsingFixedFunction)
        CY_SET_REG16(PWM_1_COMPARE1_LSB_PTR, (uint16)compare);
    #else
        CY_SET_REG8(PWM_1_COMPARE1_LSB_PTR, compare);
    #endif
}
 

One possible solution according to me would be to use a DMA channel which is triggered by the PWM's Terminal Count. The DMA transfers the Compare value stored in a memory location into the Compare Register of the PWM. It will consume less time than using an ISR to update the same.

 

 

]]>
Thu, 02 Jun 2011 05:10:06 -0600