Example #1
0
/*! \brief  to initialize hw timer
 */
uint8_t tmr_init(void)
{
	uint8_t timer_multiplier;
	tc_get_config_defaults(&timer_config);
	#ifdef ENABLE_SLEEP
	if(sys_sleep == true)
	{
		timer_config.clock_source = GCLK_GENERATOR_1;
		timer_config.clock_prescaler = TC_CLOCK_PRESCALER_DIV2;
		timer_config.run_in_standby=true;
	}
	#endif
	timer_config.counter_16_bit.compare_capture_channel[0] = TIMER_PERIOD;
	tc_init(&module_inst, TIMER, &timer_config);
	tc_register_callback(&module_inst, tc_ovf_callback, TC_CALLBACK_OVERFLOW);
	tc_register_callback(&module_inst, tc_cca_callback, TC_CALLBACK_CC_CHANNEL0);
	tc_enable_callback(&module_inst, TC_CALLBACK_OVERFLOW);
	tc_enable_callback(&module_inst, TC_CALLBACK_CC_CHANNEL0);

	tc_enable(&module_inst);
	/* calculate how faster the timer with current clk freq compared to timer with 1Mhz */
	#ifdef ENABLE_SLEEP
	if(sys_sleep ==true)
	{
		timer_multiplier = system_gclk_gen_get_hz(1) / 2000000;
	}
	else
	{
	timer_multiplier = system_gclk_gen_get_hz(0) / DEF_1MHZ;
	}
    #else
	timer_multiplier = system_gclk_gen_get_hz(0) / DEF_1MHZ;
	#endif
	return timer_multiplier;
}
Example #2
0
/*---------------------------------------------------------------------------*/
void
clock_init(void)
{
#define TIMER_PERIOD  UINT16_MAX
#define TIMER         TC3

    struct tc_config cfg;
    tc_get_config_defaults(&cfg);

    cfg.clock_source = GCLK_GENERATOR_5;
    cfg.clock_prescaler = TC_CLOCK_PRESCALER_DIV1;
    cfg.run_in_standby = false;

    cfg.counter_16_bit.compare_capture_channel[0] = TIMER_PERIOD;
    tc_init(&tc_instance, TIMER, &cfg);
    /*  tc_register_callback(&tc_instance, clock_irq_callback, TC_CALLBACK_OVERFLOW);*/
    tc_register_callback(&tc_instance, clock_irq_callback, TC_CALLBACK_CC_CHANNEL0);
    /*  tc_register_callback(&tc_instance, clock_irq_callback, TC_CALLBACK_CC_CHANNEL1);
        tc_register_callback(&tc_instance, clock_irq_callback, TC_CALLBACK_ERROR);*/
    /*  tc_enable_callback(&tc_instance, TC_CALLBACK_OVERFLOW);*/
    tc_enable_callback(&tc_instance, TC_CALLBACK_CC_CHANNEL0);
    /*  tc_enable_callback(&tc_instance, TC_CALLBACK_CC_CHANNEL1);
        tc_enable_callback(&tc_instance, TC_CALLBACK_ERROR);*/

    tc_enable(&tc_instance);


}
void *platform_configure_timer(platform_hw_timer_callback_t bus_tc_cb_ptr)
{
	struct tc_config timer_config;
	
	system_interrupt_enter_critical_section();
	if (hw_timers[0].timer_usage == 0)
	{
		hw_timers[0].timer_usage = 1;
		platform_cc1_cb = bus_tc_cb_ptr;

		tc_get_config_defaults(&timer_config);
		timer_config.clock_prescaler		= TC_CLOCK_PRESCALER_DIV1;
		timer_config.oneshot				= true;
		timer_config.counter_size			= TC_COUNTER_SIZE_32BIT;
		timer_config.count_direction		= TC_COUNT_DIRECTION_UP;
		tc_init(&bus_tc_instance, CONF_BUS_TC_MODULE, &timer_config);
		timer_count_per_ms = ((system_gclk_gen_get_hz(timer_config.clock_source)) /1000);
		tc_set_count_value(&bus_tc_instance, 0);
		tc_enable(&bus_tc_instance);
		tc_stop_counter(&bus_tc_instance);
		tc_register_callback(&bus_tc_instance, tc_cc1_cb,
		TC_CALLBACK_OVERFLOW);
		tc_enable_callback(&bus_tc_instance, TC_CALLBACK_OVERFLOW);
		
		hw_timers[0].timer_frequency = (system_gclk_gen_get_hz(timer_config.clock_source));
		hw_timers[0].timer_instance = bus_tc_instance;
		system_interrupt_leave_critical_section();
		return (&hw_timers[0]);
	}
	system_interrupt_leave_critical_section();
	return NULL;
}
Example #4
0
void configure_tc_callbacks(void)
{

	tc_register_callback(&tc_instance, tc_callback_overflow, TC_CALLBACK_OVERFLOW);

	tc_enable_callback(&tc_instance, TC_CALLBACK_OVERFLOW);

}
Example #5
0
/** Registers TC callback function with the  driver.
 */
static void configure_tc_callbacks(void)
{
	tc_register_callback(
			&tc_instance,
			tc_callback_to_counter,
			TC_CALLBACK_OVERFLOW);
	tc_enable_callback(&tc_instance, TC_CALLBACK_OVERFLOW);
}
void Adafruit_ZeroTimer::setCallback(boolean enable, tc_callback cb_type, tc_callback_t callback_func) {
  if (enable) {
    tc_register_callback(&tc_instance, callback_func, cb_type);
    tc_enable_callback(&tc_instance, cb_type);
  } else {
    tc_disable_callback(&tc_instance, cb_type);
  }
}
Example #7
0
/**
 * \internal
 * \brief Test the callback API
 *
 * This test tests the callback API for the TC. The TC uses one-shot mode.
 *
 * \param test Current test case.
 */
static void run_callback_test(const struct test_case *test)
{
	test_assert_true(test,
			tc_init_success == true,
			"TC initialization failed, skipping test");

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

	/* Setup TC0 */
	tc_reset(&tc_test0_module);
	tc_get_config_defaults(&tc_test0_config);
	tc_test0_config.wave_generation                       = TC_WAVE_GENERATION_MATCH_PWM;
	tc_test0_config.counter_16_bit.compare_capture_channel\
		[TC_COMPARE_CAPTURE_CHANNEL_0]                    = 0x03FF;
	tc_test0_config.counter_16_bit.compare_capture_channel\
		[TC_COMPARE_CAPTURE_CHANNEL_1]                    = 0x03FA;


	tc_init(&tc_test0_module, CONF_TEST_TC0, &tc_test0_config);

	/* Setup callbacks */
	tc_register_callback(&tc_test0_module, tc_callback_function, TC_CALLBACK_CC_CHANNEL1);
	tc_enable_callback(&tc_test0_module, TC_CALLBACK_CC_CHANNEL1);

	tc_enable(&tc_test0_module);

	while ((tc_get_status(&tc_test0_module) & TC_STATUS_COUNT_OVERFLOW) == 0) {
		/* Wait for overflow of TC1*/
	}

	tc_disable(&tc_test0_module);
	tc_clear_status(&tc_test0_module, TC_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 */
	tc_disable_callback(&tc_test0_module, TC_CALLBACK_CC_CHANNEL1);
	tc_set_count_value(&tc_test0_module, 0x00000000);

	tc_enable(&tc_test0_module);

	while ((tc_get_status(&tc_test0_module) & TC_STATUS_COUNT_OVERFLOW) == 0) {
		/* Wait for overflow of TC1*/
	}

	/* Test tc_disable() */
	tc_disable(&tc_test0_module);

	test_assert_true(test,
			callback_function_entered == 1,
			"Disabling the callback has failed");
}
Example #8
0
static void configure_tc3_callbacks(void)
{
    //! [setup_register_callback]
    tc_register_callback(&tc3_instance,(tc_callback_t)_TC3_Handler,TC_CALLBACK_CC_CHANNEL0);
    //! [setup_register_callback]

    //! [setup_enable_callback]
    tc_enable_callback(&tc3_instance, TC_CALLBACK_CC_CHANNEL0);
    //! [setup_enable_callback]
}
/** Callback run when a XOSC32K crystal failure is detected.
 *
 *  \param[in]  instance  Timer instance that triggered the failure
 *                        (\ref CONF_TC_OSC32K)
 */
static void xosc32k_fail_callback(
		struct tc_module *instance)
{
	/* Turn on the oscillator OK callback, turn off the fail callback */
	tc_enable_callback(&tc_xosc32k, TC_CALLBACK_CC_CHANNEL0);
	tc_disable_callback(&tc_osc32k, TC_CALLBACK_CC_CHANNEL0);

	/* Crystal failed - switch DFLL to OSC32K */
	init_dfll((enum system_clock_source)GCLK_GENERATOR_OSC32K);
	port_pin_set_output_level(LED_0_PIN, LED_0_INACTIVE);
}
void configure_tc_callbacks(void)
{
	//! [setup_register_callback]
	tc_register_callback(
			&tc_instance,
			tc_callback_to_change_duty_cycle,
			TC_CALLBACK_CC_CHANNEL0);
	//! [setup_register_callback]

	//! [setup_enable_callback]
	tc_enable_callback(&tc_instance, TC_CALLBACK_CC_CHANNEL0);
	//! [setup_enable_callback]
}
Example #11
0
void sys_init_timing(void)
{
	struct tc_config config_tc;
	tc_get_config_defaults(&config_tc);

	config_tc.counter_size    = TC_COUNTER_SIZE_16BIT;
	config_tc.wave_generation = TC_WAVE_GENERATION_MATCH_FREQ;
	config_tc.counter_16_bit.compare_capture_channel[0] = 0x5DC0;
	config_tc.clock_source = GCLK_GENERATOR_0;
	config_tc.clock_prescaler = TC_CLOCK_PRESCALER_DIV2;

	tc_init(&tc_instance, TIMER, &config_tc);
	tc_enable(&tc_instance);
	tc_register_callback(&tc_instance, tc_callback, TC_CALLBACK_CC_CHANNEL0);
	tc_enable_callback(&tc_instance, TC_CALLBACK_CC_CHANNEL0);

	/* Enable system interrupts. */
	system_interrupt_enable_global();
}
void us_ticker_set_interrupt(timestamp_t timestamp)
{
    uint32_t cur_time;
    int32_t delta;

    cur_time = us_ticker_read();
    delta = (int32_t)((uint32_t)timestamp - cur_time);
    if (delta < 0) {
        /* Event already occurred in past */
        us_ticker_irq_handler();
        return;
    }

    NVIC_DisableIRQ(TICKER_COUNTER_IRQn);
    NVIC_SetVector(TICKER_COUNTER_IRQn, (uint32_t)TICKER_COUNTER_Handlr);

    /* Enable the callback */
    tc_enable_callback(&us_ticker_module, TC_CALLBACK_CC_CHANNEL0);
    tc_set_compare_value(&us_ticker_module, TC_COMPARE_CAPTURE_CHANNEL_0, (uint32_t)timestamp);

    NVIC_EnableIRQ(TICKER_COUNTER_IRQn);
}
/* 
 * \brief Initialize and start timer for tick
 *
 * Function that sets up a timer to use for os tick. The same timer is also
 * used as the sleep timer.
 * The timer runs at 48MHz, i.e. with no prescaler on GCLK0. Wavegen function
 * Match Frequency is chosen to reload the count register on every CC0 match.
 * 8 bit counter mode must not be chosen.
 * The function is weakly defined in freeRTOS, and redefined here.
 */
void vPortSetupTimerInterrupt(void)
{
	// Struct for configuring TC
	struct tc_config tcconf;
	// Set up configuration values
	tc_get_config_defaults(&tcconf);
	tcconf.counter_size    = TC_COUNTER_SIZE_32BIT;
	tcconf.run_in_standby  = true;
	tcconf.clock_prescaler = TC_CLOCK_PRESCALER_DIV1;
	tcconf.wave_generation = TC_WAVE_GENERATION_MATCH_FREQ;

	// Initialize the TC
	tc_init(&tc, TICK_TC, &tcconf);

	// Register and enable callback for freeRTOS tick handler
	tc_register_callback(&tc, (tc_callback_t) xPortSysTickHandler, TC_CALLBACK_CC_CHANNEL0);
	tc_enable_callback(&tc, TC_CALLBACK_CC_CHANNEL0);

	// Set top value equal to one os tick
	tc_set_top_value(&tc, TIMER_RELOAD_VALUE_ONE_TICK);

	// Enable the timer
	tc_enable(&tc);
}
Example #14
0
/** Initializes the XOSC32K crystal failure detector, and starts it.
 *
 *  \param[in]  ok_callback    Callback function to run upon XOSC32K operational
 *  \param[in]  fail_callback  Callback function to run upon XOSC32K failure
 */
static void init_xosc32k_fail_detector(
		const tc_callback_t ok_callback,
		const tc_callback_t fail_callback)
{
	/* TC pairs share the same clock, ensure reference and crystal timers use
	 * different clocks */
	Assert(Abs(_tc_get_inst_index(CONF_TC_OSC32K) -
			_tc_get_inst_index(CONF_TC_XOSC32K)) >= 2);

	/* The crystal detection cycle count must be less than the reference cycle
	 * count, so that the reference timer is periodically reset before expiry */
	Assert(CRYSTAL_RESET_CYCLES < CRYSTAL_FAIL_CYCLES);

	/* Must use different clock generators for the crystal and reference, must
	 * not be CPU generator 0 */
	Assert(GCLK_GENERATOR_XOSC32K != GCLK_GENERATOR_OSC32K);
	Assert(GCLK_GENERATOR_XOSC32K != GCLK_GENERATOR_0);
	Assert(GCLK_GENERATOR_OSC32K  != GCLK_GENERATOR_0);

	/* Configure and enable the XOSC32K GCLK generator */
	struct system_gclk_gen_config xosc32k_gen_conf;
	system_gclk_gen_get_config_defaults(&xosc32k_gen_conf);
	xosc32k_gen_conf.source_clock = SYSTEM_CLOCK_SOURCE_XOSC32K;
	system_gclk_gen_set_config(GCLK_GENERATOR_XOSC32K, &xosc32k_gen_conf);
	system_gclk_gen_enable(GCLK_GENERATOR_XOSC32K);

	/* Configure and enable the reference clock GCLK generator */
	struct system_gclk_gen_config ref_gen_conf;
	system_gclk_gen_get_config_defaults(&ref_gen_conf);
	ref_gen_conf.source_clock = SYSTEM_CLOCK_SOURCE_OSC32K;
	system_gclk_gen_set_config(GCLK_GENERATOR_OSC32K, &ref_gen_conf);
	system_gclk_gen_enable(GCLK_GENERATOR_OSC32K);

	/* Set up crystal counter - when target count elapses, trigger event */
	struct tc_config tc_xosc32k_conf;
	tc_get_config_defaults(&tc_xosc32k_conf);
	tc_xosc32k_conf.clock_source = GCLK_GENERATOR_XOSC32K;
	tc_xosc32k_conf.counter_16_bit.compare_capture_channel[0] =
			CRYSTAL_RESET_CYCLES;
	tc_xosc32k_conf.wave_generation = TC_WAVE_GENERATION_MATCH_FREQ;
	tc_init(&tc_xosc32k, CONF_TC_XOSC32K, &tc_xosc32k_conf);

	/* Set up reference counter - when event received, restart */
	struct tc_config tc_osc32k_conf;
	tc_get_config_defaults(&tc_osc32k_conf);
	tc_osc32k_conf.clock_source = GCLK_GENERATOR_OSC32K;
	tc_osc32k_conf.counter_16_bit.compare_capture_channel[0] =
			CRYSTAL_FAIL_CYCLES;
	tc_osc32k_conf.wave_generation = TC_WAVE_GENERATION_MATCH_FREQ;
	tc_init(&tc_osc32k, CONF_TC_OSC32K, &tc_osc32k_conf);

	/* Configure event channel and link it to the xosc32k counter */
	struct events_config config;
	struct events_resource event;
	events_get_config_defaults(&config);
	config.edge_detect  = EVENTS_EDGE_DETECT_NONE;
	config.generator    = CONF_EVENT_GENERATOR_ID;
	config.path         = EVENTS_PATH_ASYNCHRONOUS;
	events_allocate(&event, &config);
	/* Configure event user and link it to the osc32k counter */
	events_attach_user(&event, CONF_EVENT_USED_ID);

	/* Enable event generation for crystal counter */
	struct tc_events tc_xosc32k_events = { .generate_event_on_overflow = true };
	tc_enable_events(&tc_xosc32k, &tc_xosc32k_events);

	/* Enable event reception for reference counter */
	struct tc_events tc_osc32k_events = { .on_event_perform_action = true };
	tc_osc32k_events.event_action = TC_EVENT_ACTION_RETRIGGER;
	tc_enable_events(&tc_osc32k, &tc_osc32k_events);

	/* Enable overflow callback for the crystal counter - if crystal count
	 * has been reached, crystal is operational */
	tc_register_callback(&tc_xosc32k, ok_callback, TC_CALLBACK_CC_CHANNEL0);
	tc_enable_callback(&tc_xosc32k, TC_CALLBACK_CC_CHANNEL0);

	/* Enable compare callback for the reference counter - if reference count
	 * has been reached, crystal has failed */
	tc_register_callback(&tc_osc32k, fail_callback, TC_CALLBACK_CC_CHANNEL0);
	tc_enable_callback(&tc_osc32k, TC_CALLBACK_CC_CHANNEL0);

	/* Start both crystal and reference counters */
	tc_enable(&tc_xosc32k);
	tc_enable(&tc_osc32k);
}

/** Main application entry point. */
int main(void)
{
	system_init();

	system_flash_set_waitstates(2);

	init_osc32k();
	init_xosc32k();
	init_xosc32k_fail_detector(
			xosc32k_ok_callback, xosc32k_fail_callback);

#if ENABLE_CPU_CLOCK_OUT == true
	/* Configure a GPIO pin as the CPU clock output */
	struct system_pinmux_config clk_out_pin;
	system_pinmux_get_config_defaults(&clk_out_pin);
	clk_out_pin.direction    = SYSTEM_PINMUX_PIN_DIR_OUTPUT;
	clk_out_pin.mux_position = CONF_CLOCK_PIN_MUX;
	system_pinmux_pin_set_config(CONF_CLOCK_PIN_OUT, &clk_out_pin);
#endif

	for (;;) {
		static bool old_run_osc = true;
		bool new_run_osc =
				(port_pin_get_input_level(BUTTON_0_PIN) == BUTTON_0_INACTIVE);

		/* Check if the XOSC32K needs to be started or stopped when the board
		 * button is pressed or released */
		if (new_run_osc != old_run_osc) {
			if (new_run_osc) {
				system_clock_source_enable(SYSTEM_CLOCK_SOURCE_XOSC32K);
				while(!system_clock_source_is_ready(
						SYSTEM_CLOCK_SOURCE_XOSC32K));
			}
			else {
				system_clock_source_disable(SYSTEM_CLOCK_SOURCE_XOSC32K);
			}

			old_run_osc = new_run_osc;
		}
	}
}
/*!
* @brief		Configures TC6 callback register
*
* @param[in]	NULL
*
* @param[out]	NULL
*
* @return		NULL
*
*/
void tc6_configure_callbacks(void)
{
	tc_register_callback(&tc6_instance, tc6_callback, TC_CALLBACK_OVERFLOW);
	//tc6_callback_flag = false;
	tc_enable_callback(&tc6_instance, TC_CALLBACK_OVERFLOW);
}
Example #16
0
/**
 * \internal
 * \brief Test capture and compare
 *
 * This test uses TC module 0 as a PWM generator (compare function).
 * TC module 1 will be set to capture the signal from TC module 0 to test the capture
 * functionality.
 *
 * \param test Current test case.
 */
static void run_16bit_capture_and_compare_test(const struct test_case *test)
{
	test_assert_true(test,
			tc_init_success == true,
			"TC initialization failed, skipping test");

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

	/* Configure 16-bit TC module for PWM generation */
	tc_reset(&tc_test0_module);
	tc_get_config_defaults(&tc_test0_config);
	tc_test0_config.wave_generation  = TC_WAVE_GENERATION_MATCH_PWM;
	tc_test0_config.counter_16_bit.compare_capture_channel[TC_COMPARE_CAPTURE_CHANNEL_0]  = 0x03FF;
	tc_test0_config.counter_16_bit.compare_capture_channel[TC_COMPARE_CAPTURE_CHANNEL_1]  = 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)(tc_test0_config.counter_16_bit.compare_capture_channel[TC_COMPARE_CAPTURE_CHANNEL_1]) * 100 \
					/ tc_test0_config.counter_16_bit.compare_capture_channel[TC_COMPARE_CAPTURE_CHANNEL_0];

	tc_test0_config.pwm_channel[TC_COMPARE_CAPTURE_CHANNEL_1].enabled = true;
	tc_test0_config.pwm_channel[TC_COMPARE_CAPTURE_CHANNEL_1].pin_out = CONF_TEST_PIN_OUT;
	tc_test0_config.pwm_channel[TC_COMPARE_CAPTURE_CHANNEL_1].pin_mux = CONF_TEST_PIN_MUX;
	tc_init(&tc_test0_module, CONF_TEST_TC0, &tc_test0_config);

	tc_register_callback(&tc_test0_module, tc_callback_function, TC_CALLBACK_CC_CHANNEL0);
	tc_enable_callback(&tc_test0_module, TC_CALLBACK_CC_CHANNEL0);

	/* Configure 16-bit TC module for capture */
	tc_reset(&tc_test1_module);
	tc_get_config_defaults(&tc_test1_config);
	tc_test1_config.clock_prescaler              = TC_CLOCK_PRESCALER_DIV1;
	tc_test1_config.enable_capture_on_channel[CONF_CAPTURE_CHAN_0] = true;
	tc_test1_config.enable_capture_on_channel[CONF_CAPTURE_CHAN_1] = true;

	tc_init(&tc_test1_module, CONF_TEST_TC1, &tc_test1_config);

	struct tc_events tc_events = { .on_event_perform_action = true,
								.event_action = TC_EVENT_ACTION_PPW,};

	tc_enable_events(&tc_test1_module, &tc_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(0, &extint_chan_config);

	/* Configure external interrupt module to be event generator */
	struct extint_events extint_event_conf;
	extint_event_conf.generate_event_on_detect[0] = 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 TC modules */
	tc_enable(&tc_test1_module);
	tc_enable(&tc_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 = tc_get_capture_value(&tc_test1_module,
				TC_COMPARE_CAPTURE_CHANNEL_0);
		pulse_width_after_capture = tc_get_capture_value(&tc_test1_module,
				TC_COMPARE_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
			);
}

/**
 * \brief Initialize the USART for unit test
 *
 * Initializes the SERCOM USART used for sending the unit test status to the
 * computer via the EDBG CDC gateway.
 */
static void cdc_uart_init(void)
{
	struct usart_config usart_conf;

	/* Configure USART for unit test output */
	usart_get_config_defaults(&usart_conf);
	usart_conf.mux_setting = CONF_STDIO_MUX_SETTING;
	usart_conf.pinmux_pad0 = CONF_STDIO_PINMUX_PAD0;
	usart_conf.pinmux_pad1 = CONF_STDIO_PINMUX_PAD1;
	usart_conf.pinmux_pad2 = CONF_STDIO_PINMUX_PAD2;
	usart_conf.pinmux_pad3 = CONF_STDIO_PINMUX_PAD3;
	usart_conf.baudrate    = CONF_STDIO_BAUDRATE;

	stdio_serial_init(&cdc_uart_module, CONF_STDIO_USART, &usart_conf);
	usart_enable(&cdc_uart_module);
}

/**
 * \brief Run TC unit tests
 *
 * Initializes the system and serial output, then sets up the TC unit test
 * suite and runs it.
 */
int main(void)
{
	system_init();
	cdc_uart_init();

	/* Define Test Cases */
	DEFINE_TEST_CASE(init_test, NULL,
			run_init_test, NULL,
			"Initialize tc_xmodules");

	DEFINE_TEST_CASE(basic_functionality_test, NULL,
			run_basic_functionality_test, NULL,
			"test start stop and getters and setters");

	DEFINE_TEST_CASE(callback_test, NULL,
			run_callback_test, NULL,
			"test callback API");

	DEFINE_TEST_CASE(reset_32bit_master_test, NULL,
			run_reset_32bit_master_test, NULL,
			"Setup, reset and reinitialize TC modules of a 32-bit TC");


	DEFINE_TEST_CASE(capture_and_compare_test, NULL,
			run_16bit_capture_and_compare_test, NULL,
			"Test capture and compare");

	/* Put test case addresses in an array */
	DEFINE_TEST_ARRAY(tc_tests) = {
		&init_test,
		&basic_functionality_test,
		&callback_test,
		&reset_32bit_master_test,
		&capture_and_compare_test,
	};

	/* Define the test suite */
	DEFINE_TEST_SUITE(tc_suite, tc_tests,
			"SAM TC driver test suite");

	/* Run all tests in the suite*/
	test_suite_run(&tc_suite);

	tc_reset(&tc_test0_module);
	tc_reset(&tc_test1_module);

	while (true) {
		/* Intentionally left empty */
	}
}
Example #17
0
/*! \brief  to enable compare interrupt
 */
void tmr_enable_cc_interrupt(void)
{
	tc_enable_callback(&module_inst, TC_CALLBACK_CC_CHANNEL0);
}
Example #18
0
/*! \brief  to disable overflow interrupt
 */
void tmr_enable_ovf_interrupt(void)
{
	tc_enable_callback(&module_inst, TC_CALLBACK_OVERFLOW);
}
/*!
* @brief		Configures TC4 callback register
*
* @param[in]	NULL
*
* @param[out]	NULL
*
* @return		NULL
*
*/
void tc4_configure_callbacks (void)
{
	tc_register_callback(&tc4_instance, tc4_callback, TC_CALLBACK_CC_CHANNEL0);
	tc4_callback_flag = false;
	tc_enable_callback(&tc4_instance, TC_CALLBACK_CC_CHANNEL0);
}
void hw_timer_start(uint32_t timer_val)
{
	timeout_count = timer_val;
	tc_set_count_value(&tc_instance, 0);
	tc_enable_callback(&tc_instance, TC_CALLBACK_CC_CHANNEL0);
}
/*
 * \brief Configure sleep timer and sleep
 *
 * Function to configure timer for sleep, and calculate time slept.
 */ 
void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime )
{
	// Are we running tickless now?
	if (!tickless_enable) return;

	// Reconfigure the timer to act as sleep timer
	tc_disable_callback(&tc, TC_CALLBACK_CC_CHANNEL0);
	tc_unregister_callback(&tc, TC_CALLBACK_CC_CHANNEL0);
	tc_register_callback(&tc, empty_callback, TC_CALLBACK_CC_CHANNEL0);
	tc_enable_callback(&tc, TC_CALLBACK_CC_CHANNEL0);

	// Check that the offset is not greater than the range of the timer
	if (xExpectedIdleTime > TIMER_MAX_POSSIBLE_SUPPRESSED_TICKS)
	{
		xExpectedIdleTime = TIMER_MAX_POSSIBLE_SUPPRESSED_TICKS;
	}

	// Set sleep time, -1 because we want to wake up before the last tick
	tc_set_top_value(&tc, (xExpectedIdleTime - 1) * TIMER_RELOAD_VALUE_ONE_TICK);

	// Clear overflow interrupt flag
	tc.hw->COUNT32.INTFLAG.bit.OVF = 1;

	// Check if we still should sleep
	if (eTaskConfirmSleepModeStatus() == eAbortSleep)
	{
		// Reset the timer to act as SysTick
		tc_disable_callback(&tc, TC_CALLBACK_CC_CHANNEL0);
		tc_unregister_callback(&tc, TC_CALLBACK_CC_CHANNEL0);
		tc_register_callback(&tc, (tc_callback_t) xPortSysTickHandler, TC_CALLBACK_CC_CHANNEL0);
		tc_enable_callback(&tc, TC_CALLBACK_CC_CHANNEL0);
		tc_set_top_value(&tc, TIMER_RELOAD_VALUE_ONE_TICK);
	}
	else
	{
		if (xExpectedIdleTime > 0)
		{
			// Data sync barrier before sleep
			__asm volatile ("dsb");
			// Go to sleep
			__asm volatile ("wfi");

			// If OVF interrupt flag is set, we know the timer has wrapped
			if (tc.hw->COUNT32.INTFLAG.bit.OVF)
			{
				vTaskStepTick(xExpectedIdleTime - 1);
			}
			// We do not know how long we've slept
			else
			{
				// Calculate from Counter how long we've slept
				// Reset counter to less than one os tick
				// This might result in a tiny drift in time.
				uint32_t count_val = tc_get_count_value(&tc);
				vTaskStepTick(count_val / TIMER_RELOAD_VALUE_ONE_TICK);
				tc_set_count_value(&tc, count_val % TIMER_RELOAD_VALUE_ONE_TICK);
			}
		}
		// Reset the timer to act as SysTick
		tc_disable_callback(&tc, TC_CALLBACK_CC_CHANNEL0);
		tc_unregister_callback(&tc, TC_CALLBACK_CC_CHANNEL0);
		tc_register_callback(&tc, (tc_callback_t) xPortSysTickHandler, TC_CALLBACK_CC_CHANNEL0);
		tc_enable_callback(&tc, TC_CALLBACK_CC_CHANNEL0);
		tc_set_top_value(&tc, TIMER_RELOAD_VALUE_ONE_TICK);

		// Make sure that the counter hasn't passed the CC before callback was registered
		if ( tc_get_count_value(&tc) > TIMER_RELOAD_VALUE_ONE_TICK )
		{
			// If so, reload count value, and step one tick */
			tc_set_count_value(&tc, tc_get_count_value(&tc) % TIMER_RELOAD_VALUE_ONE_TICK);
			vTaskStepTick(1);
		}
	}