Ejemplo n.º 1
0
// Configure all of the LED ports as PWM outputs
void configure_LED_PWM(void)
{
	struct tcc_config config_tcc;
	tcc_get_config_defaults(&config_tcc, TCC0);
	config_tcc.counter.period = 0xFFFF;
	config_tcc.compare.wave_generation = TCC_WAVE_GENERATION_SINGLE_SLOPE_PWM;
	config_tcc.compare.match[0] = 0;
	config_tcc.compare.match[1] = 0;
	config_tcc.compare.match[2] = 0;
	config_tcc.compare.match[3] = 0;
	config_tcc.pins.enable_wave_out_pin[0] = true;
	config_tcc.pins.enable_wave_out_pin[1] = true;
	config_tcc.pins.enable_wave_out_pin[2] = true;
	config_tcc.pins.enable_wave_out_pin[3] = true;
	config_tcc.pins.wave_out_pin[0]        = PIN_PA21F_TCC0_WO7;
	config_tcc.pins.wave_out_pin[1]        = PIN_PA20F_TCC0_WO6;
	config_tcc.pins.wave_out_pin[2]        = PIN_PA15F_TCC0_WO5;
	config_tcc.pins.wave_out_pin[3]        = PIN_PA14F_TCC0_WO4;
	config_tcc.pins.wave_out_pin_mux[0]    = MUX_PA21F_TCC0_WO7;
	config_tcc.pins.wave_out_pin_mux[1]    = MUX_PA20F_TCC0_WO6;
	config_tcc.pins.wave_out_pin_mux[2]    = MUX_PA15F_TCC0_WO5;
	config_tcc.pins.wave_out_pin_mux[3]    = MUX_PA14F_TCC0_WO4;
	tcc_init(&tcc0, TCC0, &config_tcc);
	tcc_enable(&tcc0);

	
	tcc_get_config_defaults(&config_tcc, TCC1);
	config_tcc.counter.period = 0xFFFF;
	config_tcc.compare.wave_generation = TCC_WAVE_GENERATION_SINGLE_SLOPE_PWM;
	config_tcc.compare.match[0] = 0;
	config_tcc.compare.match[1] = 0;
	config_tcc.pins.enable_wave_out_pin[0] = true;
	config_tcc.pins.enable_wave_out_pin[1] = true;
	config_tcc.pins.wave_out_pin[0]        = PIN_PA06E_TCC1_WO0;
	config_tcc.pins.wave_out_pin[1]        = PIN_PA07E_TCC1_WO1;
	config_tcc.pins.wave_out_pin_mux[0]    = MUX_PA06E_TCC1_WO0;
	config_tcc.pins.wave_out_pin_mux[1]    = MUX_PA07E_TCC1_WO1;
	tcc_init(&tcc1, TCC1, &config_tcc);
	tcc_enable(&tcc1);


	tcc_get_config_defaults(&config_tcc, TCC2);
	config_tcc.counter.period = 0xFFFF;
	config_tcc.compare.wave_generation = TCC_WAVE_GENERATION_SINGLE_SLOPE_PWM;
	config_tcc.compare.match[0] = 0;
	config_tcc.compare.match[1] = 0;
	config_tcc.pins.enable_wave_out_pin[0] = true;
	config_tcc.pins.enable_wave_out_pin[1] = true;
	config_tcc.pins.wave_out_pin[0]        = PIN_PA16E_TCC2_WO0;
	config_tcc.pins.wave_out_pin[1]        = PIN_PA17E_TCC2_WO1;
	config_tcc.pins.wave_out_pin_mux[0]    = MUX_PA16E_TCC2_WO0;
	config_tcc.pins.wave_out_pin_mux[1]    = MUX_PA17E_TCC2_WO1;
	tcc_init(&tcc2, TCC2, &config_tcc);
	tcc_enable(&tcc2);
}
Ejemplo n.º 2
0
/**
 * \internal
 * \brief Test initializing and resetting TCC and reinitialize
 *
 * This test tests the software reset of a TCC by the use of the
 * tcc_reset().
 *
 * \param test Current test case.
 */
static void run_reset_test(const struct test_case *test)
{
	test_assert_true(test,
			tcc_init_success == true,
			"TCC initialization failed, skipping test");

	/* Configure TCC module and run test*/
	tcc_reset(&tcc_test0_module);
	tcc_get_config_defaults(&tcc_test0_config, CONF_TEST_TCC0);

	tcc_init(&tcc_test0_module, CONF_TEST_TCC0, &tcc_test0_config);
	tcc_enable(&tcc_test0_module);

	while (tcc_is_syncing(&tcc_test0_module)) {
		/* Synchronize enable */
	}

	test_assert_true(test,
			tcc_test0_module.hw->CTRLA.reg & TCC_CTRLA_ENABLE,
			"Failed first enable of TCC");

	/* Reset and test if both TCC modules are disabled after reset */
	tcc_reset(&tcc_test0_module);

	while (tcc_is_syncing(&tcc_test0_module)) {
		/* Synchronize reset */
	}

	test_assert_false(test,
			tcc_test0_module.hw->CTRLA.reg & TCC_CTRLA_ENABLE,
			"Failed reset of TCC TEST");
}
Ejemplo n.º 3
0
//! [setup]
static void configure_tcc(void)
{
	//! [setup_config]
	struct tcc_config config_tcc;
	//! [setup_config]
	//! [setup_config_defaults]
	tcc_get_config_defaults(&config_tcc, TCC0);
	//! [setup_config_defaults]

	//! [setup_change_config]
	config_tcc.counter.clock_source = GCLK_GENERATOR_1;
	config_tcc.counter.clock_prescaler = TCC_CLOCK_PRESCALER_DIV64;
	config_tcc.counter.period =   2000;
	config_tcc.compare.match[0] =  900;
	config_tcc.compare.match[1] =  930;
	config_tcc.compare.match[2] = 1100;
	config_tcc.compare.match[3] = 1250;
	//! [setup_change_config]

	//! [setup_set_config]
	tcc_init(&tcc_instance, TCC0, &config_tcc);
	//! [setup_set_config]

	//! [setup_enable]
	tcc_enable(&tcc_instance);
	//! [setup_enable]
}
Ejemplo n.º 4
0
//! [setup]
static void _configure_tcc(void)
{
	//! [setup_config]
	struct tcc_config config_tcc;
	//! [setup_config]
	//! [setup_config_defaults]
	tcc_get_config_defaults(&config_tcc, CONF_PWM_MODULE);
	//! [setup_config_defaults]

	//! [setup_change_config]
	config_tcc.counter.period = 0xFFFF;
	config_tcc.compare.wave_generation = TCC_WAVE_GENERATION_SINGLE_SLOPE_PWM;
	config_tcc.compare.match[CONF_PWM_CHANNEL] = (0xFFFF / 4);
	//! [setup_change_config]

	//! [setup_change_config_pwm]
	config_tcc.pins.enable_wave_out_pin[CONF_PWM_OUTPUT] = true;
	config_tcc.pins.wave_out_pin[CONF_PWM_OUTPUT]        = CONF_PWM_OUT_PIN;
	config_tcc.pins.wave_out_pin_mux[CONF_PWM_OUTPUT]    = CONF_PWM_OUT_MUX;
	//! [setup_change_config_pwm]

	//! [setup_set_config]
	tcc_init(&tcc_instance, CONF_PWM_MODULE, &config_tcc);
	//! [setup_set_config]

	//! [setup_enable]
	tcc_enable(&tcc_instance);
	//! [setup_enable]
}
Ejemplo n.º 5
0
/**
 * \internal
 * \brief Test of tcc_init() and tcc_get_config_defaults()
 *
 * This test is used to initialize the tccx_module structs and associate the
 * given hw module with the struct. This test should be run at the very
 * beginning of testing as other tests depend on the result of this test.
 */
static void run_init_test(const struct test_case *test)
{
	tcc_get_config_defaults(&tcc_test0_config, CONF_TEST_TCC0);
	enum status_code test1 = tcc_init(&tcc_test0_module, CONF_TEST_TCC0,
			&tcc_test0_config);

	tcc_get_config_defaults(&tcc_test1_config, CONF_TEST_TCC1);
	enum status_code test2 = tcc_init(&tcc_test1_module, CONF_TEST_TCC1,
			&tcc_test1_config);

	if ((test1 == STATUS_OK) && (test2 == STATUS_OK)) {
		tcc_init_success = true;
	}

	test_assert_true(test,
			(test2 == STATUS_OK) && (test1 == STATUS_OK),
			"Failed to initialize modules");
}
Ejemplo n.º 6
0
/**
 * \internal
 * \brief Test the callback API
 *
 * This test tests the callback API for the TCC. The TCC uses one-shot mode.
 *
 * \param test Current test case.
 */
static void run_callback_test(const struct test_case *test)
{
	test_assert_true(test,
			tcc_init_success == true,
			"TCC initialization failed, skipping test");

	test_assert_true(test,
			basic_functionality_test_passed == true,
			"Basic functionality test failed, skipping test");

	/* Setup TCC0 */
	tcc_reset(&tcc_test0_module);
	tcc_get_config_defaults(&tcc_test0_config, CONF_TEST_TCC0);

	tcc_test0_config.counter.period = 4000;
	tcc_test0_config.compare.wave_generation = TCC_WAVE_GENERATION_NORMAL_FREQ;
	tcc_test0_config.compare.match[TCC_MATCH_CAPTURE_CHANNEL_0] = 3990;

	tcc_init(&tcc_test0_module, CONF_TEST_TCC0, &tcc_test0_config);

	/* Setup callbacks */
	tcc_register_callback(&tcc_test0_module, tcc_callback_function,
			TCC_CALLBACK_CHANNEL_0);
	tcc_enable_callback(&tcc_test0_module, TCC_CALLBACK_CHANNEL_0);

	tcc_enable(&tcc_test0_module);

	while ((tcc_get_status(&tcc_test0_module) &
			TCC_STATUS_COUNT_OVERFLOW) == 0) {
		/* Wait for overflow of TCC1 */
	}

	tcc_disable(&tcc_test0_module);
	tcc_clear_status(&tcc_test0_module, TCC_STATUS_COUNT_OVERFLOW);

	test_assert_true(test,
			callback_function_entered == 1,
			"The callback has failed callback_function_entered = %d",
			(int)callback_function_entered);

	/* Test disable callback function */
	tcc_disable_callback(&tcc_test0_module, TCC_CALLBACK_CHANNEL_0);
	tcc_set_count_value(&tcc_test0_module, 0x00000000);

	tcc_enable(&tcc_test0_module);

	while (!(tcc_get_status(&tcc_test0_module) & TCC_STATUS_COUNT_OVERFLOW)) {
		/* Wait for overflow of TC1*/
	}

	/* Test tcc_disable() */
	tcc_disable(&tcc_test0_module);

	test_assert_true(test,
			callback_function_entered == 1,
			"Disabling the callback has failed");
}
Ejemplo n.º 7
0
//
//	TCC Configuration Function
static void tcc_configure_function(void){
	struct tcc_config config_tcc;	// Configuration structure
	
	tcc_get_config_defaults(&config_tcc, TCC0);	// Initialize with known values
	
		// Custom Counter Configuration
	config_tcc.counter.clock_source = GCLK_GENERATOR_0;
	config_tcc.counter.clock_prescaler = TCC_CLOCK_PRESCALER_DIV64;
	config_tcc.counter.period = 750000UL;
	
	tcc_init(&tcc_instance, TCC0, &config_tcc);	// Commit Counter Configuration
	tcc_enable(&tcc_instance);	// Enable this counter instance
}
Ejemplo n.º 8
0
void hitecServoInit(void)
{
	struct tcc_config config_tcc;
	tcc_get_config_defaults(&config_tcc, TCC0);
	config_tcc.counter.clock_source = GCLK_GENERATOR_3;
	config_tcc.counter.clock_prescaler = TCC_CLOCK_PRESCALER_DIV1;
	config_tcc.counter.period = HITECSERVO_TIME_PERIOD;
	config_tcc.compare.wave_generation = TCC_WAVE_GENERATION_SINGLE_SLOPE_PWM;
	config_tcc.pins.enable_wave_out_pin[6] = true;
	config_tcc.pins.wave_out_pin[6] = PIN_PB12F_TCC0_WO6 ;
	config_tcc.pins.wave_out_pin_mux[6] = MUX_PB12F_TCC0_WO6;
	tcc_init(&tcc_instance, TCC0, &config_tcc);
	tcc_enable(&tcc_instance);
}
Ejemplo n.º 9
0
/**
 * \brief Configure Timer module.
 */
static void configure_timer(void)
{
	/**
	 * Timer period is 1s = Prescaler(256) * Period(46875) / Clock(12Mhz).
	 */
	struct tcc_config tcc_conf;
	tcc_get_config_defaults(&tcc_conf, TCC0);
	tcc_conf.counter.period = 46875 * TIMER_CB_INTERVAL;
	tcc_conf.counter.clock_prescaler = TCC_CLOCK_PRESCALER_DIV256;

	tcc_init(&tempTccModule, TCC0, &tcc_conf);
	/* Register timer callback for the Request RSSI. */
	tcc_register_callback(&tempTccModule, timer_cb, TCC_CALLBACK_CHANNEL_3);
	tcc_enable(&tempTccModule);
}
Ejemplo n.º 10
0
//! [setup]
static void configure_tcc(void)
{
	//! [setup_config]
	struct tcc_config config_tcc;
	//! [setup_config]
	//! [setup_config_defaults]
	tcc_get_config_defaults(&config_tcc, CONF_PWM_MODULE);
	//! [setup_config_defaults]

	//! [setup_change_config]
	config_tcc.counter.period = 0xFFFF;
	config_tcc.compare.wave_generation = TCC_WAVE_GENERATION_SINGLE_SLOPE_PWM;
	config_tcc.compare.match[CONF_PWM_CHANNEL] = 0xFFFF;
	//! [setup_change_config]
	//! [setup_change_config_faults]
	config_tcc.wave_ext.recoverable_fault[CONF_PWM_CHANNEL].source =
			TCC_FAULT_SOURCE_ENABLE;
	config_tcc.wave_ext.recoverable_fault[CONF_PWM_CHANNEL].halt_action =
			TCC_FAULT_HALT_ACTION_SW_HALT;
	//! [setup_change_config_faults]
	//! [setup_change_config_pwm]
	config_tcc.pins.enable_wave_out_pin[CONF_PWM_OUTPUT] = true;
	config_tcc.pins.wave_out_pin[CONF_PWM_OUTPUT]        = CONF_PWM_OUT_PIN;
	config_tcc.pins.wave_out_pin_mux[CONF_PWM_OUTPUT]    = CONF_PWM_OUT_MUX;
	//! [setup_change_config_pwm]

	//! [setup_set_config]
	tcc_init(&tcc_instance, CONF_PWM_MODULE, &config_tcc);
	//! [setup_set_config]

	//! [setup_events]
	struct tcc_events events;
	memset(&events, 0, sizeof(struct tcc_events));
	//! [setup_events]

	//! [setup_change_events_faults]
	events.on_event_perform_channel_action[CONF_PWM_CHANNEL] = true;
	//! [setup_change_events_faults]

	//! [setup_events_enable]
	tcc_enable_events(&tcc_instance, &events);
	//! [setup_events_enable]

	//! [setup_enable]
	tcc_enable(&tcc_instance);
	//! [setup_enable]
}
Ejemplo n.º 11
0
/**
 * \internal
 * \brief Test basic functionality.
 *
 * This test tests the basic functionality for the TCC. It tests the following
 * functions:
 *  - tcc_get_count_value()
 *  - tcc_stop_counter()
 *  - tcc_set_count_value()
 *  - tcc_restart_counter()
 *
 * \param test Current test case.
 */
static void run_basic_functionality_test(const struct test_case *test)
{
	test_assert_true(test,
			tcc_init_success == true,
			"TCC initialization failed, skipping test");

	/* Setup TCC0 */
	tcc_reset(&tcc_test0_module);
	tcc_get_config_defaults(&tcc_test0_config, CONF_TEST_TCC0);

	tcc_init(&tcc_test0_module, CONF_TEST_TCC0, &tcc_test0_config);
	tcc_enable(&tcc_test0_module);

	/* Test tcc_get_count_value() */
	uint32_t test_val0 = tcc_get_count_value(&tcc_test0_module);

	test_assert_true(test,
			test_val0 > 0,
			"The tcc_get_count_value() returned 0 expected larger value");

	/* Test tcc_stop_counter() */
	tcc_stop_counter(&tcc_test0_module);

	uint32_t test_val1 = tcc_get_count_value(&tcc_test0_module);
	uint32_t test_val2 = tcc_get_count_value(&tcc_test0_module);

	test_assert_true(test,
			test_val1 == test_val2,
			"The counter failed to stop");

	/* Test tcc_set_count_value() */
	tcc_set_count_value(&tcc_test0_module, 0x00FF);

	test_assert_true(test,
			tcc_get_count_value(&tcc_test0_module) == 0x00FF,
			"tcc_set_count_value() have failed");

	/* Test tcc_start_counter() */
	tcc_restart_counter(&tcc_test0_module);

	test_assert_true(test,
			tcc_get_count_value(&tcc_test0_module) > 0x00FF,
			"tcc_get_count_value() have failed");

	basic_functionality_test_passed = true;
}
Ejemplo n.º 12
0
//! [setup]
static void configure_tcc(void)
{
	//! [setup_config]
	struct tcc_config config_tcc;
	//! [setup_config]
	//! [setup_config_defaults]
	tcc_get_config_defaults(&config_tcc, CONF_PWM_MODULE);
	//! [setup_config_defaults]

	//! [setup_change_config]
	config_tcc.counter.period = 0xFFFF;
	config_tcc.compare.wave_generation = TCC_WAVE_GENERATION_SINGLE_SLOPE_PWM;
	config_tcc.compare.match[CONF_PWM_CHANNEL] = 0xFFFF;
	//! [setup_change_config]
	//! [setup_change_config_faults]
	config_tcc.wave_ext.non_recoverable_fault[0].output = TCC_FAULT_STATE_OUTPUT_1;
	//! [setup_change_config_faults]
	//! [setup_change_config_pwm]
	config_tcc.pins.enable_wave_out_pin[CONF_PWM_OUTPUT] = true;
	config_tcc.pins.wave_out_pin[CONF_PWM_OUTPUT]        = CONF_PWM_OUT_PIN;
	config_tcc.pins.wave_out_pin_mux[CONF_PWM_OUTPUT]    = CONF_PWM_OUT_MUX;
	//! [setup_change_config_pwm]

	//! [setup_set_config]
	tcc_init(&tcc_instance, CONF_PWM_MODULE, &config_tcc);
	//! [setup_set_config]

	//! [setup_events]
	struct tcc_events events;
	memset(&events, 0, sizeof(struct tcc_events));
	//! [setup_events]

	//! [setup_change_events_faults]
	events.on_input_event_perform_action[0] = true;
	events.input_config[0].modify_action = true;
	events.input_config[0].action = TCC_EVENT_ACTION_NON_RECOVERABLE_FAULT;
	//! [setup_change_events_faults]

	//! [setup_events_enable]
	tcc_enable_events(&tcc_instance, &events);
	//! [setup_events_enable]

	//! [setup_enable]
	tcc_enable(&tcc_instance);
	//! [setup_enable]
}
Ejemplo n.º 13
0
void init_pwm(int HWtimer,int pin0, int mux0, int pin1, int mux1){
	
	struct tcc_config config_tcc;
	tcc_get_config_defaults(&config_tcc, hw[HWtimer]);
	config_tcc.compare.wave_generation = TCC_WAVE_GENERATION_SINGLE_SLOPE_PWM;
	config_tcc.counter.period = 0xFFFF;

	if(pin0 != 0 && mux0 != 0){
		config_tcc.pins.enable_wave_out_pin[0] = true;
		config_tcc.pins.wave_out_pin[0] = pin0;
		config_tcc.pins.wave_out_pin_mux[0]  = mux0;
	}
	if(pin1 != 0 && mux0 != 0){
		config_tcc.pins.enable_wave_out_pin[1] = true;
		config_tcc.pins.wave_out_pin[1] = pin1;
		config_tcc.pins.wave_out_pin_mux[1]  = mux1;
	}

	tcc_init(&tcc_instance[HWtimer],  hw[HWtimer], &config_tcc);
	tcc_enable(&tcc_instance[HWtimer]);
}
Ejemplo n.º 14
0
void sw_timer_init(struct sw_timer_module *const module_inst, struct sw_timer_config *const config)
{
	struct tcc_config tcc_conf;
	struct tcc_module *tcc_module;
	Tcc *hw[] = TCC_INSTS;
	
	Assert(module_inst);
	Assert(config);
	Assert(config->tcc_dev < TCC_INST_NUM);
	Assert(config->tcc_callback_channel < TCC_NUM_CHANNELS);
	
	module_inst->accuracy = config->accuracy;
	
	/* Start the TCC module. */
	tcc_module = &module_inst->tcc_inst;
	tcc_get_config_defaults(&tcc_conf, hw[config->tcc_dev]);
	tcc_conf.counter.period = system_cpu_clock_get_hz() / (64 * 1000 / config->accuracy);
	tcc_conf.counter.clock_prescaler = TCC_CLOCK_PRESCALER_DIV64;
	tcc_init(tcc_module, hw[config->tcc_dev], &tcc_conf);
	tcc_register_callback(tcc_module, sw_timer_tcc_callback, config->tcc_callback_channel + TCC_CALLBACK_CHANNEL_0);
	tcc_enable_callback(tcc_module, config->tcc_callback_channel + TCC_CALLBACK_CHANNEL_0);
}
Ejemplo n.º 15
0
//! [setup]
static void configure_tcc(void)
{
	//! [setup_config]
	struct tcc_config config_tcc;
	//! [setup_config]
	//! [setup_config_defaults]
	tcc_get_config_defaults(&config_tcc, CONF_PWM_MODULE);
	//! [setup_config_defaults]

	//! [setup_change_config]
	config_tcc.counter.clock_prescaler = TCC_CLOCK_PRESCALER_DIV1024;
	config_tcc.counter.period = 8000;
	config_tcc.compare.wave_generation = TCC_WAVE_GENERATION_SINGLE_SLOPE_PWM;
	config_tcc.compare.match[CONF_PWM_CHANNEL] = (8000 / 4);
	//! [setup_change_config]

	//! [setup_change_config_pwm]
	config_tcc.pins.enable_wave_out_pin[CONF_PWM_OUTPUT] = true;
	config_tcc.pins.wave_out_pin[CONF_PWM_OUTPUT]        = CONF_PWM_OUT_PIN;
	config_tcc.pins.wave_out_pin_mux[CONF_PWM_OUTPUT]    = CONF_PWM_OUT_MUX;
	//! [setup_change_config_pwm]

	//! [setup_set_config]
	tcc_init(&tcc_instance, CONF_PWM_MODULE, &config_tcc);
	//! [setup_set_config]

	//! [setup_set_buffering]
	tcc_set_compare_value(&tcc_instance,
			(enum tcc_match_capture_channel)CONF_PWM_CHANNEL, 8000*3/4);
	tcc_enable_circular_buffer_compare(&tcc_instance,
			(enum tcc_match_capture_channel)CONF_PWM_CHANNEL);
	//! [setup_set_buffering]

	//! [setup_enable]
	tcc_enable(&tcc_instance);
	//! [setup_enable]
}
Ejemplo n.º 16
0
/**
 * \internal
 * \brief Test capture and compare
 *
 * This test uses TCC0 as a PWM generator (compare function). TCC1 will be set
 * to capture the signal from TCC0 to test the capture functionality.
 *
 * \param test Current test case.
 */
static void run_capture_and_compare_test(const struct test_case *test)
{
	test_assert_true(test,
			tcc_init_success == true,
			"TCC initialization failed, skipping test");

	test_assert_true(test,
			callback_function_entered == 1,
			"The callback test has failed, skipping test");

	/* Configure TCC module for PWM generation */
	tcc_reset(&tcc_test0_module);
	tcc_get_config_defaults(&tcc_test0_config, CONF_TEST_TCC0);
	tcc_test0_config.counter.period = 0x03FF;
	tcc_test0_config.compare.wave_generation  =
			TCC_WAVE_GENERATION_SINGLE_SLOPE_PWM;
	tcc_test0_config.compare.match[TCC_MATCH_CAPTURE_CHANNEL_0]  = 0x01FF;

	/* Calculate the theoretical PWM frequency & duty */
	uint32_t frequency_output, duty_output;
	frequency_output = system_clock_source_get_hz(SYSTEM_CLOCK_SOURCE_OSC8M) / (0x03FF+1);

	/* This value is depend on the WaveGeneration Mode */
	duty_output = (uint32_t)(tcc_test0_config.compare.match[TCC_MATCH_CAPTURE_CHANNEL_0] * 100) /
			tcc_test0_config.counter.period;

	tcc_test0_config.pins.enable_wave_out_pin[TCC_MATCH_CAPTURE_CHANNEL_0] = true;
	tcc_test0_config.pins.wave_out_pin[TCC_MATCH_CAPTURE_CHANNEL_0]        = CONF_TEST_PIN_OUT;
	tcc_test0_config.pins.wave_out_pin_mux[TCC_MATCH_CAPTURE_CHANNEL_0]    = CONF_TEST_PIN_MUX;
	tcc_init(&tcc_test0_module, CONF_TEST_TCC0, &tcc_test0_config);

	tcc_register_callback(&tcc_test0_module, tcc_callback_function, TCC_CALLBACK_CHANNEL_0);
	tcc_enable_callback(&tcc_test0_module, TCC_CALLBACK_CHANNEL_0);

	/* Configure TCC module for capture */
	tcc_reset(&tcc_test1_module);
	tcc_get_config_defaults(&tcc_test1_config, CONF_TEST_TCC1);
	tcc_test1_config.counter.period          = 0xFFFF;
	tcc_test1_config.counter.clock_prescaler = TCC_CLOCK_PRESCALER_DIV1;
	tcc_test1_config.capture.channel_function[CONF_CAPTURE_CHAN_0] = TCC_CHANNEL_FUNCTION_CAPTURE;
	tcc_test1_config.capture.channel_function[CONF_CAPTURE_CHAN_1] = TCC_CHANNEL_FUNCTION_CAPTURE;

	tcc_init(&tcc_test1_module, CONF_TEST_TCC1, &tcc_test1_config);

	struct tcc_events tcc_events = {
		.on_input_event_perform_action[1] = true,
		.input_config[1].modify_action = true,
		.input_config[1].action = TCC_EVENT_ACTION_PERIOD_PULSE_WIDTH_CAPTURE
	};

	tcc_enable_events(&tcc_test1_module, &tcc_events);

	/* Configure external interrupt controller */
	struct extint_chan_conf extint_chan_config;
	extint_chan_config.gpio_pin            = CONF_EIC_PIN;
	extint_chan_config.gpio_pin_mux        = CONF_EIC_MUX;
	extint_chan_config.gpio_pin_pull       = EXTINT_PULL_UP;
	extint_chan_config.wake_if_sleeping    = false;
	extint_chan_config.filter_input_signal = false;
	extint_chan_config.detection_criteria  = EXTINT_DETECT_HIGH;
	extint_chan_set_config(CONF_EIC_CHAN, &extint_chan_config);

	/* Configure external interrupt module to be event generator */
	struct extint_events extint_event_conf;
	extint_event_conf.generate_event_on_detect[CONF_EIC_CHAN] = true;
	extint_enable_events(&extint_event_conf);

	/* Configure event system */
	struct events_resource event_res;

	/* Configure channel */
	struct events_config config;
	events_get_config_defaults(&config);
	config.generator      = CONF_EVENT_GENERATOR_ID;
	config.edge_detect    = EVENTS_EDGE_DETECT_NONE;
	config.path           = EVENTS_PATH_ASYNCHRONOUS;
	events_allocate(&event_res, &config);

	/* Configure user */
	events_attach_user(&event_res, CONF_EVENT_USED_ID);

	/* Enable TCC modules */
	tcc_enable(&tcc_test1_module);
	tcc_enable(&tcc_test0_module);

	uint16_t period_after_capture = 0;
	uint16_t pulse_width_after_capture = 0;
	uint32_t capture_frequency = 0;
	uint32_t capture_duty = 0;

	while (callback_function_entered < 4) {
		period_after_capture = tcc_get_capture_value(&tcc_test1_module,
				TCC_MATCH_CAPTURE_CHANNEL_0);
		pulse_width_after_capture = tcc_get_capture_value(&tcc_test1_module,
				TCC_MATCH_CAPTURE_CHANNEL_1);
	}

	if(period_after_capture != 0) {
		capture_frequency =
				system_clock_source_get_hz(SYSTEM_CLOCK_SOURCE_OSC8M) /
				period_after_capture;
		capture_duty = (uint32_t)(pulse_width_after_capture) * 100 /
				period_after_capture;
	}

	test_assert_true(test,
			(capture_frequency <= (frequency_output * (100 + CONF_TEST_TOLERANCE) / 100)) && \
			(capture_frequency >= (frequency_output * (100 - CONF_TEST_TOLERANCE) / 100)) && \
			(capture_duty <= (duty_output * (100 + CONF_TEST_TOLERANCE) / 100)) && \
			(capture_duty >= (duty_output * (100 - CONF_TEST_TOLERANCE) / 100)) \
			,"The result of Capture is wrong, captured frequency: %ldHz, captured duty: %ld%%",
			capture_frequency,
			capture_duty
			);
}

/**
 * \internal
 * \brief Test Recoverable Fault (FAULTn)
 *
 * This test uses TCC0 as a PWM generator (compare function).
 * EXTINT will be used to route fault input to TCC0.
 *
 * \param test Current test case.
 */
static void run_faultn_test(const struct test_case *test)
{
	test_assert_true(test,
			tcc_init_success == true,
			"TCC initialization failed, skipping test");

	/* Configure TCC module for PWM generation with fault */
	tcc_reset(&tcc_test0_module);
	tcc_get_config_defaults(&tcc_test0_config, CONF_TEST_TCC0);
	tcc_test0_config.counter.period = 0x03FF;
	tcc_test0_config.compare.wave_generation  =
			TCC_WAVE_GENERATION_SINGLE_SLOPE_PWM;
	tcc_test0_config.compare.match[TCC_MATCH_CAPTURE_CHANNEL_0]  = 0x01FF;
	tcc_test0_config.wave_ext.recoverable_fault[TCC_MATCH_CAPTURE_CHANNEL_0].source = TCC_FAULT_SOURCE_ENABLE;
	tcc_test0_config.wave_ext.recoverable_fault[TCC_MATCH_CAPTURE_CHANNEL_0].halt_action = TCC_FAULT_HALT_ACTION_SW_HALT;
	tcc_init(&tcc_test0_module, CONF_TEST_TCC0, &tcc_test0_config);
	/* Configure TCC events for recoverable fault input */
	struct tcc_events tcc_test_events;
	memset(&tcc_test_events, 0, sizeof(struct tcc_events));
	tcc_test_events.on_event_perform_channel_action[TCC_MATCH_CAPTURE_CHANNEL_0] = true;
	tcc_enable_events(&tcc_test0_module, &tcc_test_events);
	tcc_enable(&tcc_test0_module);

	/* Configure IO pin to generate fault */
	struct port_config config_pin;
	port_get_config_defaults(&config_pin);
	config_pin.direction = PORT_PIN_DIR_OUTPUT;
	port_pin_set_config(CONF_TEST_PIN_OUT, &config_pin);
	port_pin_set_output_level(CONF_TEST_PIN_OUT, true);

	/* Configure EIC to capture fault input */
	struct extint_chan_conf config;
	extint_chan_get_config_defaults(&config);
	config.filter_input_signal = true;
	config.detection_criteria  = EXTINT_DETECT_BOTH;
	config.gpio_pin     = CONF_EIC_PIN;
	config.gpio_pin_mux = CONF_EIC_MUX;
	extint_chan_set_config(CONF_EIC_CHAN, &config);

	struct extint_events extint_test_events;
	memset(&extint_test_events, 0, sizeof(struct extint_events));
	extint_test_events.generate_event_on_detect[CONF_EIC_CHAN] = true;
	extint_enable_events(&extint_test_events);

	/* Configure EVENTs to route fault input */
	struct events_resource event_resource;
	struct events_config event_config;
	events_get_config_defaults(&event_config);
	event_config.generator = CONF_EVENT_GENERATOR_ID;
	event_config.path      = EVENTS_PATH_ASYNCHRONOUS;
	events_allocate(&event_resource, &event_config);
	events_attach_user(&event_resource, CONF_EVENT_USER_ID_FAULTn);

	/* Clear halt status */
	tcc_clear_status(&tcc_test0_module,
			TCC_STATUS_RECOVERABLE_FAULT_PRESENT(0) |
			TCC_STATUS_RECOVERABLE_FAULT_OCCUR(0));

	uint32_t test_val1 = tcc_get_count_value(&tcc_test0_module);
	uint32_t test_val2 = tcc_get_count_value(&tcc_test0_module);

	/* Check TCC is running */
	test_assert_true(test,
			test_val1 != test_val2,
			"The counter failed to stop on recoverable fault");

	/* Set fault */
	port_pin_set_output_level(CONF_TEST_PIN_OUT, false);

	/* Check fault state */
	test_assert_true(test,
			TCC_STATUS_RECOVERABLE_FAULT_OCCUR(0) &
					tcc_get_status(&tcc_test0_module),
			"The counter failed to detect recoverable fault");

	/* Check TCC is running */
	test_val1 = tcc_get_count_value(&tcc_test0_module);
	test_val2 = tcc_get_count_value(&tcc_test0_module);
	test_assert_true(test,
			test_val1 == test_val2,
			"The counter failed to stop on recoverable fault");
}
Ejemplo n.º 17
0
/**
 * \internal
 * \brief Test Non-Recoverable Fault (FAULTx)
 *
 * This test uses TCC0 as a PWM generator (compare function).
 * EXTINT will be used to route fault input to TCC0.
 *
 * \param test Current test case.
 */
static void run_faultx_test(const struct test_case *test)
{
	test_assert_true(test,
	tcc_init_success == true,
	"TCC initialization failed, skipping test");

	/* Configure TCC module for PWM generation with fault */
	tcc_reset(&tcc_test0_module);
	tcc_get_config_defaults(&tcc_test0_config, CONF_TEST_TCC0);
	tcc_test0_config.counter.period = 0x03FF;
	tcc_test0_config.compare.wave_generation  =
	TCC_WAVE_GENERATION_SINGLE_SLOPE_PWM;
	tcc_test0_config.compare.match[TCC_MATCH_CAPTURE_CHANNEL_0]  = 0x01FF;
	tcc_test0_config.wave_ext.non_recoverable_fault[TCC_WAVE_OUTPUT_0].output = TCC_FAULT_STATE_OUTPUT_1;
	tcc_init(&tcc_test0_module, CONF_TEST_TCC0, &tcc_test0_config);
	/* Configure TCC events for non-recoverable fault input */
	struct tcc_events tcc_test_events;
	memset(&tcc_test_events, 0, sizeof(struct tcc_events));
	tcc_test_events.on_input_event_perform_action[0] = true;
	tcc_test_events.input_config[0].modify_action = true;
	tcc_test_events.input_config[0].action = TCC_EVENT_ACTION_NON_RECOVERABLE_FAULT;
	tcc_enable_events(&tcc_test0_module, &tcc_test_events);
	tcc_enable(&tcc_test0_module);

	/* Configure IO pin to generate fault */
	struct port_config config_pin;
	port_get_config_defaults(&config_pin);
	config_pin.direction = PORT_PIN_DIR_OUTPUT;
	port_pin_set_config(CONF_TEST_PIN_OUT, &config_pin);
	port_pin_set_output_level(CONF_TEST_PIN_OUT, true);

	/* Configure EIC to capture fault input */
	struct extint_chan_conf config;
	extint_chan_get_config_defaults(&config);
	config.filter_input_signal = true;
	config.detection_criteria  = EXTINT_DETECT_BOTH;
	config.gpio_pin     = CONF_EIC_PIN;
	config.gpio_pin_mux = CONF_EIC_MUX;
	extint_chan_set_config(CONF_EIC_CHAN, &config);

	struct extint_events extint_test_events;
	memset(&extint_test_events, 0, sizeof(struct extint_events));
	extint_test_events.generate_event_on_detect[CONF_EIC_CHAN] = true;
	extint_enable_events(&extint_test_events);

	/* Configure EVENTs to route fault input */
	struct events_resource event_resource;
	struct events_config event_config;
	events_get_config_defaults(&event_config);
	event_config.generator = CONF_EVENT_GENERATOR_ID;
	event_config.path      = EVENTS_PATH_ASYNCHRONOUS;
	events_allocate(&event_resource, &event_config);
	events_attach_user(&event_resource, CONF_EVENT_USER_ID_FAULTx);

	/* Clear halt status */
	tcc_clear_status(&tcc_test0_module,
			TCC_STATUS_NON_RECOVERABLE_FAULT_PRESENT(0) |
			TCC_STATUS_NON_RECOVERABLE_FAULT_OCCUR(0));

	uint32_t test_val1 = tcc_get_count_value(&tcc_test0_module);
	uint32_t test_val2 = tcc_get_count_value(&tcc_test0_module);

	/* Check TCC is running */
	test_assert_true(test,
			test_val1 != test_val2,
			"The counter failed to stop on non-recoverable fault");

	/* Set fault */
	port_pin_set_output_level(CONF_TEST_PIN_OUT, false);

	/* Check fault state */
	test_assert_true(test,
				TCC_STATUS_NON_RECOVERABLE_FAULT_OCCUR(0) &
						tcc_get_status(&tcc_test0_module),
				"The counter failed to detect non-recoverable fault");

	/* Check TCC is running */
	test_val1 = tcc_get_count_value(&tcc_test0_module);
	test_val2 = tcc_get_count_value(&tcc_test0_module);
	test_assert_true(test,
			test_val1 == test_val2,
			"The counter failed to stop on non-recoverable fault");
}
Ejemplo n.º 18
0
static void configure_tcc_ramp2c_mode(void)
{
	struct tcc_config config_tcc;
	
	delay_init();
	tcc_get_config_defaults(&config_tcc, TCC0);
	
	/* Set up output pins */
	/* CC2 will be included to generate ramp output WO[0] in RAMP2C mode*/
	config_tcc.pins.enable_wave_out_pin[0] = true;
	config_tcc.pins.wave_out_pin[0]        = PIN_PA04E_TCC0_WO0;
	config_tcc.pins.wave_out_pin_mux[0]    = MUX_PA04E_TCC0_WO0;
	
	/* CC1 will be included to generate ramp output WO[1] RAMP2C mode */	
	config_tcc.pins.enable_wave_out_pin[1] = true;
	config_tcc.pins.wave_out_pin[1]        = PIN_PA09E_TCC0_WO1;
	config_tcc.pins.wave_out_pin_mux[1]    = MUX_PA09E_TCC0_WO1;
		

	/* Generator 1 as clock source */
	config_tcc.counter.clock_source    = GLCK_SOURCE;
	config_tcc.counter.clock_prescaler = TCC_CLOCK_DIVIDER;	
	
	/* Set up initial period */	
	config_tcc.counter.period = PER_Value;
	
	/* set CC0 */
	/* CC0 will act as ramp A top in RAMP2C mode */
	config_tcc.compare.match[0] = CC0_Value;		
	
	/* set compare reg CC1 & CC2 in RAMP2C mode */
	config_tcc.compare.match[1] = CC1_Value;
	config_tcc.compare.match[2] = CC2_Value;		

	/* Set up polarity output ramp */
	config_tcc.compare.wave_polarity[1] = 1;
	config_tcc.compare.wave_polarity[2] = 1;	
	
	/* Normal PWM in RAMP2 mode */
	config_tcc.compare.wave_generation = TCC_WAVE_GENERATION_SINGLE_SLOPE_PWM;
	config_tcc.compare.wave_ramp       = TCC_RAMP_RAMP2;

#if (ENABLE_FAULT_BALNKING == true)	
	
	/* Set up recoverable fault A on virtual pulse */
	config_tcc.wave_ext.recoverable_fault[0].qualification   = true;
	config_tcc.wave_ext.recoverable_fault[0].source          = TCC_FAULT_SOURCE_ENABLE;
	config_tcc.wave_ext.recoverable_fault[0].restart         = true;
	config_tcc.wave_ext.recoverable_fault[0].blanking_cycles = 10;
	config_tcc.wave_ext.recoverable_fault[0].blanking        = TCC_FAULT_BLANKING_RISING_EDGE;
	
	/* Set up recoverable fault A on on WO */
	config_tcc.wave_ext.recoverable_fault[1].qualification   = true;
	config_tcc.wave_ext.recoverable_fault[1].source          = TCC_FAULT_SOURCE_ENABLE;
	config_tcc.wave_ext.recoverable_fault[1].restart         = true;
	config_tcc.wave_ext.recoverable_fault[1].blanking_cycles = 10;
	config_tcc.wave_ext.recoverable_fault[1].blanking        = TCC_FAULT_BLANKING_RISING_EDGE;
	
#endif
	
	/* Initialize with given configuration */
	tcc_init(&tcc_inst, TCC0, &config_tcc);

	/* RAMP2C mode */
	while(TCC0->SYNCBUSY.reg & TCC_SYNCBUSY_WAVE);
	TCC0->WAVE.bit.RAMP = TCC_WAVEB_RAMPB_RAMP2C_Val;
	while(TCC0->SYNCBUSY.reg & TCC_SYNCBUSY_WAVE);	
	
	
#if (ENABLE_FAULT_BALNKING == true)		

	/* set fault blanking prescaler*/
	tcc_inst.hw->FCTRLA.reg |= 1 << BLANKPRESC;
	tcc_inst.hw->FCTRLB.reg |= 1 << BLANKPRESC;

	/* Enable recoverable fault event */
	struct tcc_events events;
	memset(&events, 0, sizeof(struct tcc_events));
	
	events.on_event_perform_channel_action[0] = true;
	events.on_event_perform_channel_action[1] = true;
	tcc_enable_events(&tcc_inst, &events);
	
#endif

	/* Enable TCC */
	tcc_enable(&tcc_inst);
}
Ejemplo n.º 19
0
//! [setup]
static void configure_tcc(void)
{
	//! [setup_config]
	struct tcc_config config_tcc;
	//! [setup_config]
	//! [setup_config_defaults]
	tcc_get_config_defaults(&config_tcc, CONF_PWM_MODULE);
	//! [setup_config_defaults]

	//! [setup_change_config]
	config_tcc.counter.period = 0x1000;
	config_tcc.compare.channel_function[CONF_TCC_CAPTURE_CHANNEL] =
			TCC_CHANNEL_FUNCTION_CAPTURE;
	config_tcc.compare.wave_generation = TCC_WAVE_GENERATION_SINGLE_SLOPE_PWM;
	config_tcc.compare.wave_polarity[CONF_PWM_CHANNEL] = TCC_WAVE_POLARITY_0;
	config_tcc.compare.match[CONF_PWM_CHANNEL] = compare_values[2];
	//! [setup_change_config]

	//! [setup_change_config_pwm]
	config_tcc.pins.enable_wave_out_pin[CONF_PWM_OUTPUT] = true;
	config_tcc.pins.wave_out_pin[CONF_PWM_OUTPUT]        = CONF_PWM_OUT_PIN;
	config_tcc.pins.wave_out_pin_mux[CONF_PWM_OUTPUT]    = CONF_PWM_OUT_MUX;
	//! [setup_change_config_pwm]

	//! [setup_set_config]
	tcc_init(&tcc_instance, CONF_PWM_MODULE, &config_tcc);
	//! [setup_set_config]

	//! [setup_events]
	struct tcc_events events_tcc = {
		.input_config[0].modify_action = false,
		.input_config[1].modify_action = false,
		.output_config.modify_generation_selection = false,
		.generate_event_on_channel[CONF_PWM_CHANNEL] = true,
		.on_event_perform_channel_action[CONF_TCC_CAPTURE_CHANNEL] = true
	};
	tcc_enable_events(&tcc_instance, &events_tcc);
	//! [setup_events]

	//! [setup_event_sys]
	config_event_for_capture();
	//! [setup_event_sys]

	//! [setup_dma]
	config_dma_for_capture();
	config_dma_for_wave();
	//! [setup_dma]

	//! [setup_enable]
	tcc_enable(&tcc_instance);
	//! [setup_enable]
}
//! [setup]

int main(void)
{
	system_init();

	//! [setup_init]
	configure_tcc();
	//! [setup_init]

//! [main]
	//! [main_loop]
	while (true) {
		/* Infinite loop */
	}
	//! [main_loop]
//! [main]
}