infineon4engineers Facebook

infineon@google+ Google+

infineon@linkedin linkedin

infineon4engi@twitter twitter

infineon@youtube youtube

+ Reply to Thread
Results 1 to 3 of 3

Thread: CCU8 PWM Generation

  1. #1
    New Member New Member Dark Sorrow is on a distinguished road
    Join Date
    Feb 2017
    Posts
    3
    Points
    25

    CCU8 PWM Generation

    I am developing my code on XMC4500 Relax Kit using Dave 4.4.2
    I am trying to get an PWM output on P0.5 of frequency 57kHz at duty cycle of 50% using CCU80
    I am unable to get any output on oscilloscope however when I run APNOTE_CCU8_USECASE1 the system operates seamlessly.

    Code:
    #include <stdint.h>
    #include <stdbool.h>
    #include <xmc_scu.h>
    #include <xmc_ccu8.h>
    #include <xmc_gpio.h>
    #include <xmc_common.h>
    
    
    #define TICKS_PER_SECOND	1000
    #define PWM_PIN_PRI			P0_5
    #define PWM_MODULE_PRI		CCU80
    #define PWM_SLICE_PRI		CCU80_CC80
    #define PWM_SLICE_PRI_NUM	0U
    
    /**
    
     * @brief main() - Application entry point
     *
     * <b>Details of function</b><br>
     * This routine is the application entry point. It is invoked by the device startup code. 
     */
    
    void clockInit(void);
    void gpioInit(void);
    void pwm_init(void);
    void pwm_calculate_compare_period(void);
    
    static volatile uint16_t 	ticks = 0;
    static const uint16_t		pwm_total_period = 2104;
    static volatile uint8_t		duty_cycle = 50;
    static volatile uint16_t	pwm_compare_period = 0;
    
    int main(void)
    {
    
      /* Placeholder for user application code. The while loop below can be replaced with user application code. */
    
    	clockInit();
    	pwm_init();
    
    	SysTick_Config(SystemCoreClock / TICKS_PER_SECOND);
    
    	while(1U)
    	{
    
    	}
    }
    
    //120MHz - External Crystal (12MHz), PLL, FCPU -> 120MHz, FCCU -> 120MHz, FSYS -> 120MHz, Fperipheral -> 120MHz
    void clockInit(void)
    {		const XMC_SCU_CLOCK_CONFIG_t clock_config = {
    		.enable_oschp = true,
    		.enable_osculp = false,
    		.calibration_mode = XMC_SCU_CLOCK_FOFI_CALIBRATION_MODE_AUTOMATIC,
    		.fstdby_clksrc = XMC_SCU_HIB_STDBYCLKSRC_OSI,
    		.fsys_clksrc = XMC_SCU_CLOCK_SYSCLKSRC_PLL,
    		.fccu_clkdiv = 1U,
    		.fcpu_clkdiv = 1U,
    		.fperipheral_clkdiv = 1U,
    		.fsys_clkdiv = 1U,
    	//Formula for P, N, K2 on Page->506 and Table for standard values on Page->507 of reference manual
    		.syspll_config.clksrc = XMC_SCU_CLOCK_SYSPLLCLKSRC_OSCHP,
    		.syspll_config.mode = XMC_SCU_CLOCK_SYSPLL_MODE_NORMAL,
    		.syspll_config.p_div = 2U,
    		.syspll_config.k_div = 4U,
    		.syspll_config.n_div = 80U
    	};
    
    	XMC_SCU_CLOCK_Init(&clock_config);
    
    }
    
    void gpioInit(void)
    {
    	//Configure P0_5 for PWM Output
    	XMC_GPIO_CONFIG_t gpio_config_pwm = {
    		.mode = P0_5_AF_CCU80_OUT00,
    		.output_level = XMC_GPIO_OUTPUT_LEVEL_LOW,
    		.output_strength = XMC_GPIO_OUTPUT_STRENGTH_STRONG_SHARP_EDGE
    	};
    	XMC_GPIO_Init(PWM_PIN_PRI, &gpio_config_pwm);
    }
    
    void pwm_init(void)
    {
    	XMC_CCU8_SLICE_COMPARE_CONFIG_t pwm_slice_config = {
    		.asymmetric_pwm = 0U,
    		.dither_duty_cycle = 0U,
    		.dither_limit = 0U,
    		.dither_timer_period = 0U,
    		.float_limit = 0U,
    		.invert_out0 = 0U,
    		.invert_out1 = 1U,
    		.invert_out2 = 0U,
    		.invert_out3 = 1U,
    		.mcm_ch1_enable = (uint32_t) false,
    		.mcm_ch2_enable = (uint32_t) false,
    		.monoshot = (uint32_t) false,
    		.passive_level_out0 = XMC_CCU8_SLICE_OUTPUT_PASSIVE_LEVEL_LOW,
    		.passive_level_out1 = XMC_CCU8_SLICE_OUTPUT_PASSIVE_LEVEL_LOW,
    		.passive_level_out2 = XMC_CCU8_SLICE_OUTPUT_PASSIVE_LEVEL_LOW,
    		.passive_level_out3 = XMC_CCU8_SLICE_OUTPUT_PASSIVE_LEVEL_LOW,
    		.prescaler_initval = 0U,
    		.prescaler_mode = XMC_CCU8_SLICE_PRESCALER_MODE_NORMAL,
    		.shadow_xfer_clear = 0U,
    		.slice_status = XMC_CCU8_SLICE_STATUS_CHANNEL_1,
    		.timer_concatenation = false,
    		.timer_mode = XMC_CCU8_SLICE_TIMER_COUNT_MODE_EA
    	};
    
    	XMC_CCU8_Init(PWM_MODULE_PRI, XMC_CCU8_SLICE_MCMS_ACTION_TRANSFER_PR_CR);
    
    	XMC_CCU8_StartPrescaler(PWM_MODULE_PRI);
    
    	XMC_CCU8_SetModuleClock(PWM_MODULE_PRI, XMC_CCU8_CLOCK_SCU);
    
    	XMC_CCU8_SLICE_CompareInit(PWM_SLICE_PRI, &pwm_slice_config);
    
    	XMC_CCU8_SLICE_SetTimerPeriodMatch(PWM_SLICE_PRI, pwm_total_period);
    
    	pwm_calculate_compare_period();
    
    	XMC_CCU8_SLICE_SetTimerCompareMatch(PWM_SLICE_PRI, XMC_CCU8_SLICE_COMPARE_CHANNEL_1, pwm_compare_period);
    
    	XMC_CCU8_EnableShadowTransfer(PWM_MODULE_PRI, XMC_CCU8_SHADOW_TRANSFER_SLICE_0);
    
    	XMC_CCU8_SLICE_EnableEvent(PWM_SLICE_PRI, XMC_CCU8_SLICE_IRQ_ID_PERIOD_MATCH);
    
    	XMC_CCU8_SLICE_SetInterruptNode(PWM_SLICE_PRI, XMC_CCU8_SLICE_IRQ_ID_PERIOD_MATCH, XMC_CCU8_SLICE_SR_ID_0);
    
    	NVIC_SetPriority(CCU80_0_IRQn, 63U);
    
    	NVIC_EnableIRQ(CCU80_0_IRQn);
    
    	gpioInit();
    
    	XMC_CCU8_EnableClock(PWM_MODULE_PRI, PWM_SLICE_PRI_NUM);
    
    	XMC_CCU8_SLICE_StartTimer(PWM_SLICE_PRI);
    
    
    }
    
    inline void pwm_calculate_compare_period(void)
    {
    	pwm_compare_period = (uint16_t) ((1-((float)duty_cycle / 100)) * (pwm_total_period+1));
    }
    
    void SysTick_Handler(void)
    {
    	if(++ticks >= 5000)
    	{
    
    	}
    }
    
    void CCU80_0_IRQHandler(void)
    {
    	XMC_CCU8_SLICE_ClearEvent(PWM_SLICE_PRI, XMC_CCU8_SLICE_IRQ_ID_PERIOD_MATCH);
    	XMC_CCU8_SLICE_SetTimerCompareMatchChannel1(PWM_SLICE_PRI, pwm_compare_period);
    	XMC_CCU8_EnableShadowTransfer(PWM_MODULE_PRI, XMC_CCU8_SHADOW_TRANSFER_SLICE_0);
    }

  2. #2
    Advanced Advanced
    Infineon Employee
    Infineon Employee
    DRubeša will become famous soon enough
    Join Date
    Jul 2016
    Location
    München
    Posts
    196
    Points
    855.625
    Hi,

    there is an issue in the following line:

    Code:
    .mode = P0_5_AF_CCU80_OUT00,
    it´s seems that is replaced by the wrong macro...I will check with the colleagues is this a bug on our side or usage of a wrong type on your side :P

    But for now, just change the previously line of code to this:

    Code:
    .mode = XMC_GPIO_MODE_OUTPUT_PUSH_PULL_ALT3,
    and everything will work like a charm.

    P.S. I check this issue with macro one more time and from XMCLib point of view it´s fine; there is a "XMC_GPIO_IsModeValid" function to check if the mode is valid and option "XMC_GPIO_MODE_OUTPUT_ALT3" (the value that corresponds to P0_5_AF_CCU80_OUT00) is not an valid input. So either you take a look what is the alternate function used for your use case or you can do something like this:

    Code:
    .mode = P0_5_AF_CCU80_OUT00 | XMC_GPIO_MODE_OUTPUT_PUSH_PULL,
    Now the compiler will do its job and combine the wanted pin with the appropriate alternate function and wanted mode (in this case push-pull output).

    Best regards,
    Deni
    Last edited by DRubeša; May 30th, 2018 at 09:41 AM. Reason: Clarification regarding wrong .mode parameter usage
    The views expressed here are my personal opinions, have not been reviewed or authorized by Infineon and do not necessarily represent the views of Infineon.

  3. #3
    New Member New Member Dark Sorrow is on a distinguished road
    Join Date
    Feb 2017
    Posts
    3
    Points
    25
    Thanks the advice, my issue has been resolved.

+ Reply to Thread

Tags for this Thread

Disclaimer

All content and materials on this site are provided “as is“. Infineon makes no warranties or representations with regard to this content and these materials of any kind, whether express or implied, including without limitation, warranties or representations of merchantability, fitness for a particular purpose, title and non-infringement of any third party intellectual property right. No license, whether express or implied, is granted by Infineon. Use of the information on this site may require a license from a third party, or a license from Infineon.


Infineon accepts no liability for the content and materials on this site being accurate, complete or up- to-date or for the contents of external links. Infineon distances itself expressly from the contents of the linked pages, over the structure of which Infineon has no control.


Content on this site may contain or be subject to specific guidelines or limitations on use. All postings and use of the content on this site are subject to the Usage Terms of the site; third parties using this content agree to abide by any limitations or guidelines and to comply with the Usage Terms of this site. Infineon reserves the right to make corrections, deletions, modifications, enhancements, improvements and other changes to the content and materials, its products, programs and services at any time or to move or discontinue any content, products, programs, or services without notice.