Dynamic change of TCPWM compare value

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.
KaKo_4074056
Level 4
Level 4
Distributor - Marubun (Japan)
First like given First solution authored 25 replies posted

Hi,

This sample program is run on CY8CKIT-149 (PSoC 4100S Plus). This is a sample that dynamically modifies the duty cycle of TCPWM. According to Arch TRM, it's recommended that you don't modify the compare register directly, swap it for the value via compare buffer register. The actual timing of swapping is when TC event occurs while swap is enabled. In this sample, TC event is generated by software trigger. The compare value of TCPWM for LED output changes at 1 second intervals.

Please refer to

- PSoC4100S/4100S Plus Arch TRM (Doc No. 002-10621) : 18.3.4.2 How It Works

- PSoC4 TCPWM Component Datasheet (Doc No. 002-10078)

    PWM_Start();

    PWM_WritePeriod(65535u);

    PWM_WriteCompare(10000u);

    PWM_WriteCompareBuf(60000u);

    PWM_SetCompareSwap(1u);   

    for(;;)

    {

        CyDelay(1000);

        PWM_TriggerCommand(PWM_MASK, PWM_CMD_CAPTURE);

    }

0 Likes
3 Replies
Praveen
Community Manager
Community Manager
Community Manager
25 solutions authored 10 likes given 5 likes given

Thanks for sharing the code example for the community. appreciate your efforts.

Cheers

Praveen

Cheers
Praveen
HeGi_2497906
Level 5
Level 5
100 replies posted 50 replies posted 25 replies posted

Unfortunately, I was unable to get this to function.  First off, using the CyDelay as the trigger is not a good idea as Cydelays are blocking, so unless your code does nothing else, this will not work.   Sets a bad example for others, set up systick in your example and implement a 1 sec timer, much clearer real world example.

Second, this is my code example and image of the compare buffer, and the CompareBuf never swaps, why is that?  You can clearly see the value to be written in CC_Buf but after the instruction has executed the CC never changes, I get the TC interrupt, yet the compare value never changes?  What have I missed here?

HeGi_2497906_1-1626350240844.pngHeGi_2497906_2-1626350304486.png

 

 

 

 

0 Likes
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,

First of all, I'm not the author of this CE, but a colleague of him.

Since I have not tried this functionality, I gave it a try.

Meantime, as I have detached the wings from my CY8CKIT-149, I used the user LED1 (P3.4)

and modified the schematic as below.

Schematic

001-schematic.JPG

Pins

002-Pins.JPG

main.c

#include "project.h"

volatile int pit_flag = 0 ;
volatile uint32_t pit_count = 0 ;
uint32_t pit_interval_ms = 1000 ; // flag each 1 sec
#define PWM1_PERIOD (65535u)
#define PWM1_PATTERN1 (10000u)
#define PWM1_PATTERN2 (60000u)

CY_ISR(SysTick_ISR)
{
    pit_count++ ;
    if (pit_count >= pit_interval_ms) {
        pit_flag = 1 ;
        pit_count = 0 ;
    }
}

int find_empty_slot(void)
{
    int result = -1 ;
    uint32_t i ;
    for (i = 0 ; i < CY_SYS_SYST_NUM_OF_CALLBACKS ; i++ ) {
        if (CySysTickGetCallback(i) == NULL) {
            result = i ;
            break ;
        }
    }
    return(result) ;
}

void init_systick(void)
{
    int sys_tick_slot = 0 ;
    
    sys_tick_slot = find_empty_slot() ;
    if (sys_tick_slot < 0) {
        while(1) { } /* halting here */
    } else {
        CySysTickStart() ;
        CySysTickSetCallback(sys_tick_slot, SysTick_ISR) ;
    }
    
    CySysTickStart();
}

void init_pwm(void)
{
    PWM_Start() ;
    PWM_WritePeriod(PWM1_PERIOD);
    PWM_WriteCompare(PWM1_PATTERN1);
    PWM_WriteCompareBuf(PWM1_PATTERN2);
    PWM_SetCompareSwap(1u);    
}

void init_hardware(void)
{
    CyGlobalIntEnable; /* Enable global interrupts. */    
    
    init_pwm() ;
    
    init_systick() ;
}
    
int main(void)
{
    init_hardware() ;
    
    for(;;)
    {
        if (pit_flag) {
            pit_flag = 0 ;
            PWM_TriggerCommand(PWM_MASK, PWM_CMD_CAPTURE) ;
        }
    }
}

With these modification, the program seems to be working OK.

Just like you, I tried some other patterns to switch the buffer but anything without PWM_TriggerCommand() failed.

Although the parameter PWM_CM_CAPTURE sounds odd, when I grepped PWM_TriggerCommand(),

there was the following line

* - PWM_CMD_CAPTURE - Trigger Capture/Switch command

So, the command PWM_TriggerCommand(PWM_MAS, PWM_CMD_CAPTURE) seems to order the PWM to "Switch" in this case.

I wonder if  this command can be used to trigger compareSwap for you.

moto

 

 

0 Likes