- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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);
}
- Labels:
-
ispn:40045:1:0
-
l1:314:1:0
-
PSoC345LP
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks for sharing the code example for the community. appreciate your efforts.
Cheers
Praveen
Praveen
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
Pins
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