PSoC4 PWM (bug) Glitch on Compare Reg Write

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
lock attach
Attachments are accessible only for community members.
UrPl_1236626
Level 4
Level 4
10 likes given First solution authored 50 replies posted

Hi,

In a PsoC4 project attached below we demonstrate a PWM compare register write bug.

It appears like if reg is written by the CPU at the same time as TC occurs pwm output is forced high for the entire period, and within the next cycle the latest compare value is in effect.

PWM_bug.png

We have tried combinations with RegSwap, which also appears buggy, at certain occasions it swapped immediately.

Looking forward to hearing you and your explanation and best work-around.

Kind regards,
Uros

0 Likes
1 Solution
lock attach
Attachments are accessible only for community members.
Ritwick_S
Moderator
Moderator
Moderator
100 solutions authored 25 likes received 250 sign-ins

Hi @UrPl_1236626 ,

 

Please find the attached project. In this project, I used the compare buffer register to change the compare value, and I used the OV signal for the switch event.  The compare value will be written to the buffer and this will be stored into the capture register on TC event, so the swap does not occur at "any time", it occurs at TC event.  This procedure will ensure that there is no glitch. 

 

Thanks,

Ritwick

View solution in original post

11 Replies
lock attach
Attachments are accessible only for community members.
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Hi,

According to your observation, updating the compare register at the same time of PWM's TC causes problem.

So I wondered if we can let PWM timer's TC interrupt update it's compare value?

Letting isr_PWM_UPDATE  update the msb_value and set flag (comp_updated)

isr_MSB_TC checks if comp_updated flag is set, and if if it's set,

update the compare value and clear the comp_updated flag.

I modified your project as below

schematic

001-schematic.JPG

main.c

#include <project.h>

static int32_t saw[128] = {0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16,
       17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33,
       34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
       51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 63, 62, 61,
       60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 44,
       43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27,
       26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10,
        9,  8,  7,  6,  5,  4,  3,  2,  1};


volatile int comp_updated = 0 ;
volatile uint32_t msb_value = 0 ;

CY_ISR(ISR_MSB_UPDATE)
{
    PWM_MSB_INTERRUPT_REQ_REG = PWM_MSB_INTR_MASK_TC ;
    if (comp_updated) {
        PWM_MSB_COMP_CAP_REG = msb_value ;
        comp_updated = 0 ;
    }
}

CY_ISR(ISR_SAW_GENERATOR) {
    static uint8_t tbl_idx = 0;

    PWM_UPDATE_INTERRUPT_REQ_REG = PWM_UPDATE_INTR_MASK_TC; // ClearInterrupt
    
    UPDATE_DR |= UPDATE_MASK ;    
    msb_value = saw[((tbl_idx++) & 127)];
    comp_updated = 1 ;
    UPDATE_DR &= ~UPDATE_MASK ;
/*    
    uint32_t msb = saw[((tbl_idx++) & 127)];
    UPDATE_DR |= UPDATE_MASK;
    PWM_MSB_COMP_CAP_REG = msb;
    UPDATE_DR &= ~UPDATE_MASK;
*/
}


/*----------------------------------------------------------*/
/* PSoC Start                                               */
/*----------------------------------------------------------*/

int main(void) {   
    PWM_MSB_Start();
    isr_MSB_TC_StartEx(ISR_MSB_UPDATE) ;
    PWM_UPDATE_Start();
    isr_PWM_UPDATE_StartEx(ISR_SAW_GENERATOR);
    PWM_UPDATE_WritePeriod(200);
    
    CyGlobalIntEnable;
    
    while (1) {  
        CyDelay(2000);  // Restart PWM update to achive different write time
        isr_PWM_UPDATE_Disable();
        CyDelay(500);
        isr_PWM_UPDATE_StartEx(ISR_SAW_GENERATOR);
    }
}

 

As I don't have a board with your device, I have not tested it.

So if it does not work, I'm sorry.

moto

0 Likes
UrPl_1236626
Level 4
Level 4
10 likes given First solution authored 50 replies posted

Hi Moto,

We cannot afford to have another interrupt at 750 kHz , our PSoC4 firmware is already running at almost 99%.

Nevertheless would be good to hear from Cypress, as if above bug indeed persist I would mark it as highly critical to all switching applications, as "glitching" at constant HIGH for a period would have severe effects to all DC/DC converters, ...

BR Uros

0 Likes
Len_CONSULTRON
Level 9
Level 9
Beta tester 500 solutions authored 1000 replies posted

Uros,

I downloaded your project and have reproduced the issue you have seen.

The issue is apparently known by Cypress.  That is why you need to use the Compare Swap feature.

I made the following changes to your project and was able to eliminate the "glitch".

Change the TopDesign

Len_CONSULTRON_0-1620353759448.png

Notice the "switch" and "Swap" parameters.

Len_CONSULTRON_0-1620354075271.png

Change ISR_SAW_GENERATOR

 

 

CY_ISR(ISR_SAW_GENERATOR) {
static uint8_t tbl_idx = 0;
  PWM_UPDATE_INTERRUPT_REQ_REG = PWM_UPDATE_INTR_MASK_TC; // ClearInterrupt
  uint32_t msb = saw[((tbl_idx++) & 127)];
  UPDATE_DR |= UPDATE_MASK;
  PWM_MSB_COMP_CAP_BUF_REG = msb;  /* Load the Compare Buffer for the swap */
  UPDATE_DR &= ~UPDATE_MASK;
}

 

 

Summary

In effect you are performing a HW Swap at the TC event of PWM_MSB.  Loading the Compare Buffer in the interrupt prepares PWM_MSB to be ready with the new value.

I made the above changes and the "glitch" disappeared.

Note:  The PWM_UPDATE can be used to trigger a DMA event to load the new  msb value into the Compare Buffer.  This way you can eliminate the ISR.

UPDATE:  This part has no DMA resources.  Oops!

Len
"Engineering is an Art. The Art of Compromise."
UrPl_1236626
Level 4
Level 4
10 likes given First solution authored 50 replies posted

Hi Len,

thank you for your suggestion.

We have found also swap register to be sometimes buggy, and writing to the registers from time to time performs an immediate swap. However that may not be seen in above case. DMA we do not have enough resources, other DMA is already consuming ~1.6 MB/s and with the CPU load, we cannot afford another DMA to update this PWM.

We have made a simple work-around with two synced PWMs which outputs are AND'ed together via Smart IO. In the interrupt both compare regs are written with the same value one after the other, as only one may theoretically be close to TC at a time.

When you say "The issue is apparently known by Cypress.", in which errata do you have that?
Because, if PSoC6 has the same TCPWM block it may be buggy too, didn't check yet, and this PWM glitch as mentioned is an extremely critical point to all MCU driven switchers (it may generate OC faults, etc.).

BR Uros

0 Likes

Uros,

When you say "The issue is apparently known by Cypress.", in which errata do you have that?
Because, if PSoC6 has the same TCPWM block it may be buggy too, didn't check yet, and this PWM glitch as mentioned is an extremely critical point to all MCU driven switchers (it may generate OC faults, etc.).

I know of no errata.   The reason I said "apparently" is the fact that they have this "swap" mechanism.  It is there to "fix" the issue you were seeing and to synchronize the Compare reg update to the TC.

Len
"Engineering is an Art. The Art of Compromise."
0 Likes

I do not think so.

Swapping has many other potential uses, which we also tried to use, as dithering (or LSB modulation) with the switch input and a PRS, to gain higher resolution, then as immediate reduction of pwm width on some external event (i.e. current threshold in DC/DC switchers), and many others...

However, unfortunately is buggy and cannot be used, as it makes unpredictable immediate writes on Compare Buf Reg write/update.

0 Likes

Uros,

If you were using a PSoC5, there is a WaveDAC8 component that allows you to create a triangle wave. 

Len
"Engineering is an Art. The Art of Compromise."
0 Likes
UrPl_1236626
Level 4
Level 4
10 likes given First solution authored 50 replies posted

Cypress,

any update on this topic?

0 Likes
HeGi_2497906
Level 5
Level 5
100 replies posted 50 replies posted 25 replies posted

I am having the exact same issue, we have four channels of PWM for Lighting and I get sporadic LED glitches, I have tried everything, including the buffer swap, which did not function properly.  I will be forwarding this to my Cypress reps, this needs to be addressed. 

0 Likes
HeGi_2497906
Level 5
Level 5
100 replies posted 50 replies posted 25 replies posted

Also, note the comment on the function for read compare, what does it mean "not 0x0" what does it return if it is zero?

/*******************************************************************************
* Function Name: PWM_1_ReadCompare
********************************************************************************
*
* Summary:
* Reads the compare register. Not applicable for Timer/Counter with Capture
* or in Quadrature Decoder modes.
* PSoC 4000 devices read the incremented compare register value in the
* Up counting mode (except 0xFFFFu), and the decremented value in the
* Down counting mode (except 0x0u).
*
* Parameters:
* None
*
* Return:
* Compare value
*
* Note:
* PSoC 4000 devices read the incremented compare register value in the
* Up counting mode (except 0xFFFFu), and the decremented value in the
* Down counting mode (except 0x0u).
*
*******************************************************************************/

0 Likes
lock attach
Attachments are accessible only for community members.
Ritwick_S
Moderator
Moderator
Moderator
100 solutions authored 25 likes received 250 sign-ins

Hi @UrPl_1236626 ,

 

Please find the attached project. In this project, I used the compare buffer register to change the compare value, and I used the OV signal for the switch event.  The compare value will be written to the buffer and this will be stored into the capture register on TC event, so the swap does not occur at "any time", it occurs at TC event.  This procedure will ensure that there is no glitch. 

 

Thanks,

Ritwick