Exemple #1
0
int main(void)
{
	pmic_init();
	board_init();
	sysclk_init();
	sleepmgr_init();
	cpu_irq_enable();

	/* Enables the Timer defined in conf_example.h : TCE0 in this example */
	tc_enable(&TIMER_EXAMPLE);

	/* Configures the interrupt level of CCA and CCB modules : low */
	tc_set_cca_interrupt_level(&TIMER_EXAMPLE, TC_INT_LVL_LO);
	tc_set_ccb_interrupt_level(&TIMER_EXAMPLE, TC_INT_LVL_LO);

	/* Configures the waveform generator of this Timer mode in NORMAL mode */
	tc_set_wgm(&TIMER_EXAMPLE, TC_WG_NORMAL);

	/* Declares the interrupt functions which will be called when CCA and CCB
	interrupts will occur */
	tc_set_cca_interrupt_callback(&TIMER_EXAMPLE,
			example_cca_interrupt_callback);
	tc_set_ccb_interrupt_callback(&TIMER_EXAMPLE,
			example_ccb_interrupt_callback);

	/* Configures the Timer period*/
	tc_write_period(&TIMER_EXAMPLE, TIMER_EXAMPLE_PERIOD);

	/* Configures the CCA and CCB levels*/
	tc_write_cc(&TIMER_EXAMPLE, TC_CCA, TIMER_EXAMPLE_PERIOD/2);
	tc_write_cc(&TIMER_EXAMPLE, TC_CCB, TIMER_EXAMPLE_PERIOD/2);

	/* Enables the CCA and CCB channels*/
	tc_enable_cc_channels(&TIMER_EXAMPLE,TC_CCAEN);
	tc_enable_cc_channels(&TIMER_EXAMPLE,TC_CCAEN);

	/* Configures the waveform genertaor in Dual Slope mode and Top*/
	tc_set_wgm(&TIMER_EXAMPLE,TC_WG_DS_T);

	/* Enables and configures the deadtime of CCA and CCB outputs*/
	tc_awex_enable_cca_deadtime(&AWEXE);
	tc_awex_enable_ccb_deadtime(&AWEXE);
	tc_awex_set_dti_high(&AWEXE, TIMER_EXAMPLE_PERIOD/6);
	tc_awex_set_dti_low(&AWEXE, TIMER_EXAMPLE_PERIOD/6);

	/* Outputs CCA and CCB on Port E0 and E1*/
	tc_awex_set_output_override(&AWEXE, 0x03);

	tc_set_resolution(&TIMER_EXAMPLE, 10000);

	do {
		/* Go to sleep, everything is handled by interrupts. */
		sleepmgr_enter_sleep();
	} while (1);
}
Exemple #2
0
/**
 * \b avrInitSystemTickTimer
 *
 * Initialise the system tick timer. Uses the AVR's timer1 facility.
 *
 * @return None
 */
void avrInitSystemTickTimer ( void )
{
  /*
  * Unmask clock for TCC1
  */
  tc_enable(&TCC1);
  
  /*
  * Configure interrupts callback functions for CCA interrupt
  */
  tc_set_cca_interrupt_callback(&TCC1,
      cca_interrupt_callback);
      
  /*
  * Configure TC in normal mode, configure period, CCA
  * Enable CCA channel
  */
  tc_set_wgm(&TCC1, TC_WG_NORMAL);
  tc_write_period(&TCC1, AVR_CPU_HZ / 256 / SYSTEM_TICKS_PER_SEC);
  tc_write_cc(&TCC1, TC_CCA, AVR_CPU_HZ / 256 / SYSTEM_TICKS_PER_SEC / 2);
  tc_enable_cc_channels(&TCC1,(enum tc_cc_channel_mask_enable_t)(TC_CCAEN));
  
  /*
  * Enable TC interrupts (overflow, CCA and CCB)
  */
  tc_set_cca_interrupt_level(&TCC1, TC_CCAINTLVL_LO_gc);
  
  /*
  * Run TCC1 at AVR_CPU_HZ / 256
  */
  tc_write_clock_source(&TCC1, TC_CLKSEL_DIV256_gc);

}
Exemple #3
0
/**
 * \internal
 * \brief Initializes the timer counter used to generate a delay
 */
static void main_delay_init(void)
{
	tc_enable(CONF_DELAY_TC);
	tc_set_wgm(CONF_DELAY_TC, TC_WG_NORMAL);
	tc_set_resolution(CONF_DELAY_TC, 1);
	tc_write_period(CONF_DELAY_TC, 0xFFFF);
}
void generator_qenc_enable(PORT_t *port, uint8_t pins_base,
		volatile void *timer, uint8_t revolution, uint32_t freq, bool dir )
{
#if XMEGA_E
	Assert((TC4_t *)timer == &TCC4);
#endif

	/* Store parameter in static global variable */
	generator_qenc_port = port;
	generator_qenc_pins_base = pins_base;
	generator_qenc_revolution = revolution;
	generator_qenc_timer = timer;

	/* Clear all pins on test port */
	port->DIRSET = QENC_PH0_PH90_INDEX_PINS << generator_qenc_pins_base;
	port->OUTCLR = QENC_PH0_PH90_INDEX_PINS << generator_qenc_pins_base;

	tc_enable(timer);
	tc_set_wgm(timer, TC_WG_NORMAL);

	generator_qenc_set_freq(freq);
	generator_qenc_set_direction(dir);

	/* Enable low level interrupt on CCA */
	tc_set_overflow_interrupt_level(timer, TC_INT_LVL_LO);

	/* Set interrupt callback function for CCA */
	tc_set_overflow_interrupt_callback(timer,
			generator_qenc_timer_ccaint_handler);
}
Exemple #5
0
/*! \brief  to initialiaze hw timer
 */
uint8_t tmr_init(void)
{
	uint8_t timer_multiplier;

	tc_enable(TIMER);

	tc_set_overflow_interrupt_callback(TIMER,
			(tc_callback_t)tc_ovf_callback);

	/*initialize timer in waveform generator - Normal mode */
	tc_set_wgm(TIMER, TC_WG_NORMAL);

	tc_write_period(TIMER, TIMER_PERIOD);
	/* select clock division as 1 */
	tc_write_clock_source(TIMER, TC_CLKSEL_DIV1_gc);

	tc_set_overflow_interrupt_level(TIMER, TC_INT_LVL_HI);

	tc_set_cca_interrupt_callback(TIMER, (tc_callback_t)tc_cca_callback);

	tc_enable_cc_channels(TIMER, TC_CCAEN);

	tc_set_cca_interrupt_level(TIMER, TC_INT_LVL_OFF);

	/* calculate how faster the timer with current clk freq compared to
	 * timer with 1Mhz */
	timer_multiplier = sysclk_get_peripheral_bus_hz(TIMER) / DEF_1MHZ;

	return timer_multiplier;
}
int main(void)
{
	pmic_init();
	board_init();
	sysclk_init();
	sleepmgr_init();

	cpu_irq_enable();

#if (BOARD == XMEGA_A3BU_XPLAINED)
	/* The status LED must be used as LED2, so we turn off
	 * the green led which is in the same packaging. */
	ioport_set_pin_high(LED3_GPIO);
#endif

	/*
	* Unmask clock for TIMER_EXAMPLE
	*/
	tc_enable(&TIMER_EXAMPLE);

	/*
	* Configure interrupts callback functions for TIMER_EXAMPLE
	* overflow interrupt, CCA interrupt and CCB interrupt
	*/
	tc_set_overflow_interrupt_callback(&TIMER_EXAMPLE,
			example_ovf_interrupt_callback);
	tc_set_cca_interrupt_callback(&TIMER_EXAMPLE,
			example_cca_interrupt_callback);
	tc_set_ccb_interrupt_callback(&TIMER_EXAMPLE,
			example_ccb_interrupt_callback);

	/*
	* Configure TC in normal mode, configure period, CCA and CCB
	* Enable both CCA and CCB channels
	*/

	tc_set_wgm(&TIMER_EXAMPLE, TC_WG_NORMAL);
	tc_write_period(&TIMER_EXAMPLE, TIMER_EXAMPLE_PERIOD);
	tc_write_cc(&TIMER_EXAMPLE, TC_CCA, TIMER_EXAMPLE_PERIOD / 2);
	tc_write_cc(&TIMER_EXAMPLE, TC_CCB, TIMER_EXAMPLE_PERIOD / 4);
	tc_enable_cc_channels(&TIMER_EXAMPLE,(enum tc_cc_channel_mask_enable_t)(TC_CCAEN | TC_CCBEN));

	/*
	* Enable TC interrupts (overflow, CCA and CCB)
	*/
	tc_set_overflow_interrupt_level(&TIMER_EXAMPLE, TC_INT_LVL_LO);
	tc_set_cca_interrupt_level(&TIMER_EXAMPLE, TC_INT_LVL_LO);
	tc_set_ccb_interrupt_level(&TIMER_EXAMPLE, TC_INT_LVL_LO);

	/*
	* Run TIMER_EXAMPLE at TIMER_EXAMPLE_PERIOD(31250Hz) resolution
	*/
	tc_set_resolution(&TIMER_EXAMPLE, TIMER_EXAMPLE_PERIOD);

	do {
		/* Go to sleep, everything is handled by interrupts. */
		sleepmgr_enter_sleep();
	} while (1);
}
Exemple #7
0
/**
 * Initialize trace
 */
void hf_trace_init() {
    tc_enable(&TCC0);
    tc_set_overflow_interrupt_callback(&TCC0, tc_wrap);
    tc_set_wgm(&TCC0, TC_WG_NORMAL);
    tc_write_period(&TCC0, 65535);
    tc_set_overflow_interrupt_level(&TCC0, TC_INT_LVL_LO);
    tc_write_clock_source(&TCC0, TC_CLKSEL_DIV8_gc);
}
Exemple #8
0
void XBee_Init()
{
	tc_enable(&(XBEE_TIMER)); // timer used for callback functionality
	tc_set_overflow_interrupt_callback(&(XBEE_TIMER), SendTelemetry); // sets up a function to callback when it's time to run
	tc_set_wgm(&(XBEE_TIMER), TC_WG_NORMAL); // sets the waveform generation
	tc_write_period(&(XBEE_TIMER), XBEE_HZ);  // this should run at 2 HZ
	tc_set_overflow_interrupt_level(&(XBEE_TIMER), TC_INT_LVL_MED); // low priority 0x01
	tc_write_clock_source(&(XBEE_TIMER), TC_CLKSEL_DIV1024_gc); // set clock prescaler to 1024
}
Exemple #9
0
void init_MS5611_callback()
{
	tc_enable(&(MS5611_TIMER)); // timer used for callback functionality
	tc_set_overflow_interrupt_callback(&(MS5611_TIMER), ms5611_altitude); // sets up a function to callback when it's time to run
	tc_set_wgm(&(MS5611_TIMER), TC_WG_NORMAL); // sets the waveform generation
	tc_write_period(&(MS5611_TIMER), MS5611_HZ);
	tc_set_overflow_interrupt_level(&(MS5611_TIMER), TC_INT_LVL_LO); // medium priority 0x02
	tc_write_clock_source(&(MS5611_TIMER), TC_CLKSEL_DIV1024_gc); // set clock prescaler to 1024
}
void TimerD0_init(void)
{
	tc_write_clock_source(&TCD0,TC_CLKSEL_DIV256_gc);
	tc_set_wgm(&TCD0,TC_WG_NORMAL);
	tc_set_overflow_interrupt_level(&TCD0,TC_INT_LVL_MED);
	tc_write_period(&TCD0,TIMERD0_PER);
	tc_set_direction(&TCD0,TC_UP);
	tc_enable(&TCD0);
};
void TimerE1_init(void)
{
    tc_write_clock_source(&TCE1,TC_CLKSEL_DIV256_gc);
    tc_set_wgm(&TCE1,TC_WG_SS);
    tc_write_period(&TCE1,0x00FF);
    tc_set_direction(&TCE1,TC_UP);
    tc_enable_cc_channels(&TCE1,TC_CCAEN);
    tc_enable(&TCE1);
};
void TimerC0_init(void)
{
	tc_write_clock_source(&TCC0,TC_CLKSEL_DIV64_gc);//1
	tc_set_wgm(&TCC0,TC_WG_SS);
	tc_write_period(&TCC0,0x77);//0x01DFF
	tc_set_direction(&TCC0,TC_UP);
	tc_enable_cc_channels(&TCC0,TC_CCAEN);
	tc_enable_cc_channels(&TCC0,TC_CCBEN);
	tc_enable(&TCC0);
	tc_write_cc(&TCC0,TC_CCA,0x5D);
};
Exemple #13
0
void backlight_start_pwm()
{
	// Backlight PWM init
	// Unmask clock for TIMER_EXAMPLE
	tc_enable(&BACKLIGHT_TIMER);
	// Configure TC in PWM Single Slope PWM
	BACKLIGHTPORT.REMAP |= PORT_TC0B_bm;
	tc_set_wgm(&BACKLIGHT_TIMER, TC_WG_SS);
	backlight_set_pwm(0);
	tc_enable_cc_channels(&BACKLIGHT_TIMER,TC_CCBEN);
	// Run TC at 2MHz clock resolution
	tc_set_resolution(&BACKLIGHT_TIMER, BACKLIGHT_TIMER_FREQUENCY);
	backlight_set_pwm(BACKLIGHT_TIMER_COUNT);
}
Exemple #14
0
/** 
 * \brief This function initializes a delay timer.
 */
void sha204h_timer_init(void)
{
	// Enable timer.
	tc_enable(DELAY_COUNTER);
	
	// Enable overflow interrupt
	tc_set_overflow_interrupt_level(DELAY_COUNTER, PMIC_LVL_LOW);
	
	// Configure TC in normal mode
	tc_set_wgm(DELAY_COUNTER, TC_WG_NORMAL);
	
	// Set call back function for timer interrupt.
	tc_set_overflow_interrupt_callback(DELAY_COUNTER, sha204h_timer_overflow_interrupt_callback);
}
Exemple #15
0
/**
 * \brief Initialize Timer/Counters used to simulate oven actuation signal
 *
 * TCC0 is set up to generate a dual variable frequency signal with dead-time
 * insertion using the AWEX module. This is similar to how heating elements are
 * actuated in real induction ovens. Its output is on pin C2 which is marked as
 * RXD on header J1.
 *
 * TCC1 is set up to capture a frequency signal via a pin change event using the
 * XMEGA Event System. Its input is pin C4 which is marked as SS on header J1.
 */
void main_init_tc(void)
{
    /* Set up timer for PWM output, used to actuate cooking element */
    tc_enable(&OVEN_FREQ_TC);

    /* Configures the waveform generator in Frequency generation mode */
    tc_set_wgm(&OVEN_FREQ_TC, TC_WG_FRQ);

    /* Configures the CCA level. This controls frequency generation */
    tc_write_cc(&OVEN_FREQ_TC, TC_CCA, FREQ_TIMER_PERIOD_INIT / 2);

    /* Enables and configures the deadtime of AWEX channel B outputs */
    tc_awex_enable_ccb_deadtime(&AWEXC);

    tc_awex_set_dti_high(&AWEXC, FREQ_TIMER_PERIOD_INIT / 4);
    tc_awex_set_dti_low(&AWEXC, FREQ_TIMER_PERIOD_INIT / 4);

    /* Output of AWEX channel B is on pins C2 and C3 */
    tc_awex_set_output_override(&AWEXC, 0x0C);

    /* Make sure that the output is initially turned off */
    tc_write_clock_source(&OVEN_FREQ_TC, TC_CLKSEL_OFF_gc);

    /* Set up timer for input capture for the simulation to read "real"
     * power
     */
    tc_enable(&OVEN_FREQ_CAPT_TC);
    /* Select Event Channel 1 as input to the timer, and perform frequency
     * capture.
     */
    tc_set_input_capture(&OVEN_FREQ_CAPT_TC, TC_EVSEL_CH1_gc,
                         TC_EVACT_FRQ_gc);
    /* Enable Capture Channel A */
    tc_enable_cc_channels(&OVEN_FREQ_CAPT_TC, TC_CCAEN);

    /* Make sure pin C4 is configured for input and sensing on rise and fall
     * and pin C2 is configured for output.
     */
    ioport_configure_pin(J1_PIN4, IOPORT_DIR_INPUT | IOPORT_BOTHEDGES);
    ioport_configure_pin(J1_PIN2, IOPORT_DIR_OUTPUT);

    /* Turn on power to the event system */
    PR.PRGEN &= ~PR_EVSYS_bm;
    /* Use pin C4 as input to Event Channel 1 */
    EVSYS.CH1MUX = EVSYS_CHMUX_PORTC_PIN4_gc;

    /* Turn on timer used for input capture */
    tc_write_clock_source(&OVEN_FREQ_CAPT_TC, TC_CLKSEL_DIV256_gc);
}
static void prvSetupTimerInterrupt(void) {
    // Use TCC0 as a tick counter. If this is to be changed, change ISR as well
    tc_enable(&TCC0);
    tc_set_wgm(&TCC0, TC_WG_NORMAL);

    // Select the clock source and prescale by 64
    tc_write_clock_source(&TCC0, TC_CLKSEL_DIV64_gc);

    //set period of counter
    tc_write_period(&TCC0, configCPU_CLOCK_HZ / configTICK_RATE_HZ / 64 - 1);

    //enable interrupt and set low level
    //tc_set_overflow_interrupt_callback(&TCC0, tickTimer);
    tc_set_overflow_interrupt_level(&TCC0, TC_INT_LVL_LO);

    cpu_irq_enable();
}
Exemple #17
0
uint8_t shutter_cont(double freq){
    tc_write_clock_source(&SHUTTER_TC, TC_CLKSEL_OFF_gc);
    if (freq > 30 || freq < 0.23842) {
        return 1;
    }

    else{
        tc_enable(&SHUTTER_TC);
        tc_set_wgm(&SHUTTER_TC, TC_WG_FRQ);
        tc_enable_cc_channels(&SHUTTER_TC, TC_CCBEN);
        
        tc_write_clock_source(&SHUTTER_TC, TC_CLKSEL_DIV64_gc);

        uint16_t temp_div = ceil((1/(2*freq))*F_CPU/65536);
        uint16_t divider = 0;
        
        if (temp_div <= 64){
            tc_write_clock_source(&SHUTTER_TC,TC_CLKSEL_DIV64_gc);
            divider = 64;
        }
        else if (temp_div <= 256){
            tc_write_clock_source(&SHUTTER_TC,TC_CLKSEL_DIV256_gc);
            divider = 256;
        }
        else if (temp_div <= 1024){
            tc_write_clock_source(&SHUTTER_TC,TC_CLKSEL_DIV1024_gc);
            divider = 1024;
        }
        else{
            printf("#ERR: Frequency/ADC rate is too low\n");
            return 0;
        }

        SHUTTER_TC.CCA = ((uint16_t)((F_CPU/divider)/(2*freq)))-1; //f=1/(2*(CCA+1)*f_clk)
    
        return 0;
    }
}
int main (void)
{
	sysclk_init();
	board_init();
	pmic_init();
	gfx_mono_init();
	adc_sensors_init();
	// Enable display backlight
	gpio_set_pin_high(NHD_C12832A1Z_BACKLIGHT);
	cpu_irq_enable();
	
	while(true){
		
		if(state==1){
			start_game();
			}else if(state==2){
			tc_enable(&TCC0);
			tc_set_overflow_interrupt_callback(&TCC0, sun_count);
			tc_set_wgm(&TCC0, TC_WG_NORMAL);
			tc_write_period(&TCC0, 13500);
			tc_set_overflow_interrupt_level(&TCC0, TC_INT_LVL_LO);
			tc_write_clock_source(&TCC0, TC_CLKSEL_DIV256_gc);
			
			tc_enable(&TCC1);
			tc_set_overflow_interrupt_callback(&TCC1, button_press);
			tc_set_wgm(&TCC1, TC_WG_NORMAL);
			tc_write_period(&TCC1, 62500);
			tc_set_overflow_interrupt_level(&TCC1, TC_INT_LVL_LO);
			tc_write_clock_source(&TCC1, TC_CLKSEL_DIV8_gc);
			
			gfx_mono_draw_string("SUN:   0", 0, 0, &sysfont);
			gfx_mono_draw_string(">", 0, cursor_position, &sysfont);
			gfx_mono_draw_string("Score:  0", 63, 0, &sysfont);
			
			randomPeta();
			
			char* score_string = NULL;
			uint16_t old_score = 0;
			
			for(j = 0; j <= 70; j++){
				
				if(sun_value > 10){
					
					lightsensor_measure();
					while (!lightsensor_data_is_ready()) {
						// Wait until the conversion is complete
					}
					if(lightsensor_get_raw_value() > 250){
						sun_value -= 10;
						sunBurst();
						gfx_mono_draw_filled_rect(12,8,114,24,GFX_PIXEL_CLR);
					}
				}
				

				if(score > old_score){
					sprintf(score_string, "%3d", score);
					gfx_mono_draw_string(score_string, 100, 0, &sysfont);
					old_score = score;
				}
				
				if(lose){
					state=3;
					break;
					}else if(zombie==0){
					state=4;
					break;
				}
				
				
				tampilkanPeta();
				tampilkanTembak();
				delay_ms(1000);
			}
			}else if(state==3){
			cpu_irq_disable();
			gfx_mono_draw_filled_rect(0,0,128,32,GFX_PIXEL_CLR);
			while(true){
				gfx_mono_draw_string("GAME OVER",36,8,&sysfont)	;
				gfx_mono_draw_string("You Lose",39,20,&sysfont)	;
			}
			}else if(state==4){
			cpu_irq_disable();
			gfx_mono_draw_filled_rect(0,0,128,32,GFX_PIXEL_CLR);
			while(true){
				gfx_mono_draw_string("GAME OVER",36,2,&sysfont)	;
				gfx_mono_draw_string("You Win",42,12,&sysfont)	;
				gfx_mono_draw_string("Score = ",30,22,&sysfont)	;
				char* score_string = NULL;
				sprintf(score_string, "%3d", score);
				gfx_mono_draw_string(score_string, 79, 22, &sysfont);
			}
		}
	}
	
}
Exemple #19
0
void shutter_cont_stop(void){
    tc_write_clock_source(&SHUTTER_TC, TC_CLKSEL_OFF_gc);
    tc_set_wgm(&SHUTTER_TC, TC_WG_NORMAL);
    tc_disable(&SHUTTER_TC);
    ioport_set_pin_level(SHUTTER_PIN, 0);
}
Exemple #20
0
/**
 * \brief Initialize PWM configuration struct and set correct I/O pin to output
 *
 * \param config Pointer to PWM configuration struct.
 * \param tc \ref pwm_tc_t "TC" to use for this PWM.
 * \param channel \ref pwm_channel_t "CC channel" to use for this PWM.
 * \param freq_hz Frequency to use for this PWM.
  */
void pwm_init(struct pwm_config *config, enum pwm_tc_t tc,
              enum pwm_channel_t channel, uint16_t freq_hz)
{
    /* Number of channels for this TC */
    uint8_t num_chan = 0;
    UNUSED(num_chan);

    /* Set TC and correct I/O pin to output */
    /*
     * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
     */
    switch (tc) {
#if defined(TCC0)
    case PWM_TCC0:
        config->tc = &TCC0;
        PORTC.DIR |= (1 << (channel-1));
        num_chan = 4;
        break;
#endif
#if defined(TCC1)
    case PWM_TCC1:
        config->tc = &TCC1;
        PORTC.DIR |= (1 << (channel+3));
        num_chan = 2;
        break;
#endif
#if defined(TCD0)
    case PWM_TCD0:
        config->tc = &TCD0;
        PORTD.DIR |= (1 << (channel-1));
        num_chan = 4;
        break;
#endif
#if defined(TCD1)
    case PWM_TCD1:
        config->tc = &TCD1;
        PORTD.DIR |= (1 << (channel+3));
        num_chan = 2;
        break;
#endif

#if defined(TCE0)
    case PWM_TCE0:
        config->tc = &TCE0;
        PORTE.DIR |= (1 << (channel-1));
        num_chan = 4;
        break;
#endif
#if defined(TCE1)
    case PWM_TCE1:
        config->tc = &TCE1;
        PORTE.DIR |= (1 << (channel+3));
        num_chan = 2;
        break;
#endif

#if defined(TCF0)
    case PWM_TCF0:
        config->tc = &TCF0;
        PORTF.DIR |= (1 << (channel-1));
        num_chan = 4;
        break;
#endif
#if defined(TCF1)
    case PWM_TCF1:
        config->tc = &TCF1;
        PORTF.DIR |= (1 << (channel+3));
        num_chan = 2;
        break;
#endif
    default:
        Assert(false);
        break;
    }

    /* Make sure we are not given a channel number larger
       than this TC can handle */
    Assert(channel <= num_chan);
    config->channel = channel;

    /* Set the correct cc_mask */
    switch (channel) {
    case PWM_CH_A:
        config->cc_mask = TC_CCAEN;
        break;
    case PWM_CH_B:
        config->cc_mask = TC_CCBEN;
        break;
    case PWM_CH_C:
        config->cc_mask = TC_CCCEN;
        break;
    case PWM_CH_D:
        config->cc_mask = TC_CCDEN;
        break;
    default:
        Assert(false);
        break;
    }

    /* Enable peripheral clock for this TC */
    tc_enable(config->tc);

    /* Set this TC's waveform generator in single slope mode */
    tc_set_wgm(config->tc, TC_WG_SS);

    /* Default values (disable TC and set minimum period)*/
    config->period = 0;
    config->clk_sel = PWM_CLK_OFF;
    tc_write_clock_source(config->tc, PWM_CLK_OFF);

    /* Set the PWM frequency */
    pwm_set_frequency(config, freq_hz);
}