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 #2
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 #3
0
/** TC Callback function.
 */
static void tc_callback_to_counter(
		struct tc_module *const module_inst)
{
	static uint32_t count = 0;
	count ++;
	if(count%800 == 0){
		printf("The output is triggered by TC counter\r\n");
	}

	tc_set_count_value(module_inst,TC_COUNT_VALUE);
}
void tc_cc0_cb(struct tc_module *const module_inst)
{
	static uint16_t tc_count;
	tc_set_count_value(&tc_instance, 0);
	tc_count += 1;
	if (tc_count >= timeout_count)
	{
		tc_count = 0;
		if (timer_callback != NULL)
		{
			timer_callback();
		}
	}
}
Example #5
0
/**
 * \internal
 * \brief Test basic functionality.
 *
 * This test tests the basic functionality for the TC. It tests the following functions:
 *  - tc_get_count_value()
 *  - tc_stop_counter()
 *  - tc_set_count_value()
 *  - tc_start_counter()
 *
 * \param test Current test case.
 */
static void run_basic_functionality_test(const struct test_case *test)
{
	test_assert_true(test,
			tc_init_success == true,
			"TC initialization failed, skipping test");

	/* Setup TC0 */
	tc_reset(&tc_test0_module);
	tc_get_config_defaults(&tc_test0_config);

	tc_init(&tc_test0_module, CONF_TEST_TC0, &tc_test0_config);
	tc_enable(&tc_test0_module);

	/* Test tc_get_count_value() */
	uint32_t test_val0 = tc_get_count_value(&tc_test0_module);

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

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

	uint32_t test_val1 = tc_get_count_value(&tc_test0_module);
	uint32_t test_val2 = tc_get_count_value(&tc_test0_module);

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

	/* Test tc_set_count_value() */
	tc_set_count_value(&tc_test0_module, 0x00FF);

	test_assert_true(test,
			tc_get_count_value(&tc_test0_module) == 0x00FF,
			"tc_set_count_value() have failed");

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

	test_assert_true(test,
			tc_get_count_value(&tc_test0_module) > 0x00FF,
			"tc_get_count_value() have failed");

	basic_functionality_test_passed = true;
}
void platform_start_bus_timer(void *timer_handle, uint32_t ms)
{
	tc_set_count_value(&bus_tc_instance, (0xFFFFFFFF - (timer_count_per_ms * ms)));
	tc_start_counter(&bus_tc_instance);
}
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);
		}
	}
/*!
* @brief		Starts TC6 counter
*
* @param[in]	NULL
*
* @param[out]	NULL
*
* @return		NULL
*
*/
void tc6_start_counter (void)
{
	tc_set_count_value(&tc6_instance, TC6_COUNT_VALUE);
	tc_start_counter(&tc6_instance);
}