cancel
Showing results for 
Search instead for 
Did you mean: 

PSoC 4 MCU

UrPl_1236626
New Contributor II

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
7 Replies
MotooTanaka
Esteemed Contributor

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
New Contributor II

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
Honored Contributor II

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
New Contributor II

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
Len_CONSULTRON
Honored Contributor II

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
UrPl_1236626
New Contributor II

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
Len_CONSULTRON
Honored Contributor II

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