LPC1768 strange PWM failure - silicon bug?

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

LPC1768 strange PWM failure - silicon bug?

3,825 Views
tilmannreh
Contributor I

Hello,

I am using the LPC1768 in an application where a few DC motors are controlled using PWM signals. I am using the PWM peripheral in single edge mode on four of the PWM outputs, the frequency is 93.75 kHz (24 MHz PCLK, 8 bit PWM).

The motor speeds are updated every 12.5 ms for generating the required speed profiles. Basically, it all works very well.

However, every now and then the PWM outputs a static high signal for one PWM cycle (that leads to a small spike at the motor) or even a complete 12.5 ms update cycle (which causes a hard beat from the drive). The time between such failures varies between several tens of seconds and several tens of minutes (with constantly moving motor), so it's hard to trace... I am observing this only with one of the outputs (PWM1.2), however that may be caused by the fact that this motor is moving most of the time and the others only rarely. As far as I can tell, the failure happens only after the previous PWM output has been constanly low (match register is 0), and it appears to be depending on the exact time (regarding to the PWM timer) when the match register and LER bits are written (see at the last screenshot far below).

I am attaching a few screenshots.The yellow trace is a port toggling with every writing to MR2 and LER, the red trace is the PWM1.2 signal. Green and blue are motor voltages and not too useful at these timescales - I used them as trigger.

The following screen shows a single PWM cycle failure. The match value is being changed from 0 to 32. It can be seen that after the MR2/LER update, the PWM output stays high for one PWM cycle, then reverts to normal PWM operation with 32/256 duty cycle:

print00446 LPC1768 PWM-Spike.png

Here is an "update cycle" failure. The situation is the same, MR2 is changed from 0 to 32 - but this time, the PWM1.2 output stays high until MR2 is updated again 12.5 ms later (you can imagine that this causes a hard and loud bang from the drive):

print00447 LPC1768 PWM-Fehler.png

After the next update, the PWM output again stays high for one single PWM cycle before reverting to the correct duty cycle. This screenshot is just a zoomed part of the previous one, at the next update (12.5 ms):

print00448 Detail.png

For comparison, here is a screenshot of a normal, correct PWM update:

print00451 PWM-OK.png

Take care that the MR2/LER update occurs somewhere in the middle of the PWM timer cycle in this case. In the screenshots showing the two failure types (further above), it appears that the MR2/LER update is just hitting the internal PWM update process. Maybe that is causing these problems here. Of course these two timers/processes are asynchronous to each other, so this can happen at any time. Looking at the rather rare failure rate, it seems that the "critical time slot" for the update is rather small.

Finally, here is my PWM initialisation code:

  // PWM-Controller (PCLK 24 MHz):
  PWMTCR=PWMCR_RESET;     // reset & disable PWM
  PWMCTCR=0;            // Timer mode
  PWMPR=PWMPRE-1;              // set Prescaler  (PWMPRE is 1)
  PWMMCR=BIT(1);            // TC reset on MR0
  PWMPCR=BIT(9)|BIT(10)|BIT(11)|BIT(13);     // PWM 1,2,3,5 enable (single edge)
  PWMMR0=PWMCONST;            // PWM counter runs up to 256
  PWMMR1=0;
  PWMMR2=0;
  PWMMR3=0;
  PWMMR5=224;           // Set default outputs
  PWMLER=BIT(1)|BIT(2)|BIT(3)|BIT(5);
  PWMTCR=PWMCR_ENABLE|PWMCR_PWMENA;  // enable PWM

And this is the (only) code updating the match register:

static inline void SetVertPWM(uint16_t x) {

  PWMMR2=(x<256)?x:255; PWMLER|=BIT(2);

  FIO2->PIN^=P2_TEST2;  // toggle test output

  }

Thanks in advance for any help and advice,

Tilmann

Labels (2)
0 Kudos
8 Replies

2,791 Views
petrpazourek
Contributor I

I was using ORing in PWMLER and facing very similar issue. The 4th channel got stuck until next write into MR4 was performed, not only one period.

The datasheet in addition says that user software should not write ones to reserved bits of PWMLER, and a value read from a
reserved bits of PWMLER is not defined. So doing a simple ORing may cause writing ones into reserved bits.

Finally it helped me to save the PWMLER into temp variable, clearing the PWMLER, update the MR registers as needed and restoring the PWMLER back as necessary. Something like this:

static inline void SetVertPWM(uint16_t x) {

uint32_t ler = PWMLER & 0x7F;

PWMLER = 0; 
PWMMR2=(x<256)?x:255;
ler |=BIT(2);
PWMLER = ler;

}

0 Kudos

3,345 Views
ziemowitpodwyso
Contributor I

Hello,

I'm observing simillar issue when relatching 2 PWMs signal one after another. When duty cycle of one of them is zero and new value is provided, first cycle is fully on. Only happens when transition from zero duty cycle. Definitely something wrong with silicon.

Z.

0 Kudos

3,345 Views
tilmannreh
Contributor I

Hello Ziemowit,

thanks for the confirmation of that strange bug.

Unfortunately, there never was any response from NXP at all... :-(

Regards, Tilmann

0 Kudos

3,345 Views
marcprager
Contributor III

Hi Tilmann,

I'm using LPC175x for most of my projects so far and I've not experienced such troubles, yet.

Without going into to much detail, I'm not sure if this is, what you intended:

PWMLER|=BIT(2);

I never use a statement like this for the PWMLER.

I mean the '|' .-)

Since the you know what needs to get reloaded, you can as well use PWMLER=BIT(2).

Possibly, that's the reason, why I was lucky and you have bad luck. I guess the reading of PWMLER confuses the hardware?

So give it a try by replacing the bit setting by a simple write. Since the reload registers keep their contents, you can also

chose to reload all timing registers, even if you just changed MR2: PWMLER=0x1F (extreme approach).

0 Kudos

3,345 Views
tilmannreh
Contributor I

Hello Marc,

first results after always setting LER to 0x1F: There has not been a hard bang for a really long time now. It appears that this really does not happen any more.

However, there's still something wrong with the PWM output. Now it rarely happens that when changing the match register from (say) 32 to zero, the output becomes high for a single PWM cycle:

print00453.png

Obviously there's a "weak point" when you shouldn't write to the MR and/or LER register(s), and this appears as a bug to me.

Best regards,

Tilmann

0 Kudos

3,345 Views
marcprager
Contributor III

Interesting. With the simple write, we can rule out that the compiler did something wrong (like not properly honouring volatile, or something similar).

Now we should rule out, that your specific microcontroller is broken. You stated, that only one output is affected. Do you have an identical replacement system and tried that one?

Your findings upset me. In my system I use a pretty high match update rate - PWM frequency -  so perhaps I simply don't notice the deviation.

I attached my schematic (a simple dual stepper / EC-motor controller) and probably I can run your code on my system!? Attaching a low-pass filter and a suitably triggered scope should be easy.

Marc

0 Kudos

3,345 Views
tilmannreh
Contributor I

Hi Marc,

I have several identical boards that I can (and probably will) use to make the same detailed measurements.

Time permitted, I might create a small test case for verification. Using another timer at a slightly different rate than the PWM cycle time, one should be able to hit the weak point more often than in my real application where this happens more coincidentally...

I'm not suprised that I observe this failure only on that particular channel. It's the only channel that is used that extensively. The other channels generate a much more static output, and also due to their time constants I wouldn't even notice such a failure there.

Best regards,

Tilmann

0 Kudos

3,345 Views
tilmannreh
Contributor I

Hello Marc,

thanks for your answer.

ORing bit 2 into PWMLER is fully on purpose. Unfortunately, you can also reset a pending LER bit by writing a 0 to it - and if the latch update has not yet been processed, it will never happen then. The other PWM channels are set by other processes, and when setting a single other bit there the LER bit of this process maybe reset, so the update is missed here (and vice versa). This also does not happen too often (the PWM cycle time is about 10 µs), but before I used ORing I had problems with missing PWM updates indeed. (This register appears misconstructed to me - it should rather behave like a "set only" register, similar to FIOxSET.)

Simply setting all LER bits for every update is worth a try. I'll report later.

However, from the reference manual, there should not be any side effects when reading PWMLER first. It also does not mention any critical moment for updating MR/LER.

Best regards,

Tilmann

0 Kudos