Solution - Setting up a UC3A PWM with sysclk and not pm

1 post / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It has taken me about 3 weeks to finally get this running.  Thanks to mikech for the final clue.

 

The attached code sets up a PWM using sysclk functions to setup the system/peripheral clocks rather than power manager.  Once the period is set, the duty cycle can be changed on the fly by calling a "pwm_update_local()" function.

 

My hope is that this will save anyone else trying to setup a UC3A PWM.

//conf_clock.h set cpu to 66 MHz
#ifndef CONF_CLOCK_H_INCLUDED
#define CONF_CLOCK_H_INCLUDED

#define CONFIG_SYSCLK_SOURCE        SYSCLK_SRC_PLL0

/* Fbus = Fsys / (2 ^ BUS_div) */
#define CONFIG_SYSCLK_CPU_DIV         0
#define CONFIG_SYSCLK_PBA_DIV         0
#define CONFIG_SYSCLK_PBB_DIV         0

#define CONFIG_USBCLK_SOURCE          USBCLK_SRC_PLL1

#define CONFIG_USBCLK_DIV             1

#define CONFIG_PLL0_SOURCE          PLL_SRC_OSC0
#define CONFIG_PLL0_MUL             16 //(48000000UL / BOARD_OSC0_HZ)
#define CONFIG_PLL0_DIV             2

#define CONFIG_PLL1_SOURCE            PLL_SRC_OSC0
#define CONFIG_PLL1_MUL               (48000000UL / BOARD_OSC0_HZ)
#define CONFIG_PLL1_DIV               1

#endif /* CONF_CLOCK_H_INCLUDED */
-----------------------------------------------------------
//user_board.h
#ifndef USER_BOARD_H
#define USER_BOARD_H

#include <conf_board.h>

/* Clock Speed */
#define APPLI_CPU_SPEED	66000000
#define APPLI_PBA_SPEED 66000000

/* These are documented in services/basic/clock/uc3b0_b1/osc.h */
#define BOARD_OSC0_HZ           12000000
#define BOARD_OSC0_STARTUP_US   17000
#define BOARD_OSC0_IS_XTAL      true
#define BOARD_OSC32_HZ          32768
#define BOARD_OSC32_STARTUP_US  71000
#define BOARD_OSC32_IS_XTAL     true
#define FOSC0					12000000

#define CLOCK_PBA_FREQ          66000000

#define FPR_PWM					AVR32_PIN_PB19
#define FPR_PWM_PIN             AVR32_PWM_0_PIN//AVR32_PWM_0_0_PIN
#define FPR_PWM_FUNCTION        AVR32_PWM_0_FUNCTION//AVR32_PWM_0_0_FUNCTION
#define FPR_PWM_CHANNEL_ID      0

void pmw_update_local(int duty);
void pwm_init_local(void);

#endif // USER_BOARD_H
--------------------------------------------------------------------------
//init.c
#include <asf.h>
#include <board.h>
#include <conf_board.h>
#include <pwm.h>
#include <sysclk.h>
#include <user_board.h>

void IO_Init(void);
void pwm_init_local(void);

void board_init(void)
{
		sysclk_init();
		gpio_local_init();
		delay_init(66000000UL);
		pwm_init_local();
		IO_Init();
}

void IO_Init(void)
{

-----------------------------------------------------------------
//main.c
	#include <asf.h>
	#include <delay.h>
	#include <pwm.h>
	#include <sysclk.h>
	#include <user_board.h>
unsigned int channel_id;

int main (void)
{
	int c;

	board_init();

	 pwm_opt_t pwm_opt;                                // PWM option config.
     avr32_pwm_channel_t pwm_channel = { .ccnt = 0 };  // One channel config.
	while (1)
	{  //test changing PWM duty
	   for (c=1;c<999;c++)
	   {

			pmw_update_local(c);   // Change the channel duty cycle
			delay_ms(10);           //delay between duty cycle changes
	   }
    }
}
------------------------------------------------------------------
//pwm_code.c
#include <asf.h>
#include <delay.h>
#include <pwm.h>
#include <sysclk.h>
#include <user_board.h>

unsigned int channel_id;

void pwm_init_local(void)
{
  pwm_opt_t pwm_opt;                                // PWM option config.
  avr32_pwm_channel_t pwm_channel = { .ccnt = 0 };  // One channel config.

  channel_id =FPR_PWM_CHANNEL_ID;
  gpio_enable_module_pin(FPR_PWM_PIN, FPR_PWM_FUNCTION);

  // PWM controller configuration.
  pwm_opt.diva = AVR32_PWM_DIVA_CLK_OFF;
  pwm_opt.divb = AVR32_PWM_DIVB_CLK_OFF;
  pwm_opt.prea = AVR32_PWM_PREA_MCK;
  pwm_opt.preb = AVR32_PWM_PREB_MCK;

  pwm_init(&pwm_opt);

  pwm_channel.CMR.calg = PWM_MODE_LEFT_ALIGNED;       // Channel mode.
  pwm_channel.CMR.cpol = PWM_POLARITY_LOW;            // Channel polarity.
  pwm_channel.CMR.cpd = 0;//PWM_UPDATE_DUTY;              // Update Duty Cycle
  pwm_channel.CMR.cpre =  AVR32_PWM_CPRE_MCK_DIV_4; //AVR32_PWM_CPRE_MCK_DIV_256;  // Channel prescaler.
  pwm_channel.cdty = 500;   // Channel duty cycle, should be < CPRD.
  pwm_channel.cprd = 1000;  // Channel period.
  pwm_channel.cupd = 0;   // Channel update not used here.

  pwm_channel_init(channel_id, &pwm_channel); // Set channel configuration to channel 0.

  pwm_start_channels(1 << channel_id);  // Start channel 0.
}

void pmw_update_local(int duty) //update the PWM duty cycle
{
	 pwm_opt_t pwm_opt;                                // PWM option config.
	 avr32_pwm_channel_t pwm_channel = { .ccnt = 0 };  // One channel config.

	 pwm_channel.CMR.cpre =  AVR32_PWM_CPRE_MCK_DIV_4; //AVR32_PWM_CPRE_MCK_DIV_256;  // Channel prescaler.

	 pwm_channel.cupd = duty;   // Channel duty cycle, should be < CPRD.
	 pwm_async_update_channel(channel_id,&pwm_channel);
}

 

Last Edited: Tue. May 16, 2017 - 11:01 AM