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); } }
/** * \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"); }
/** 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 us_ticker_disable_interrupt(void) { /* Disable the callback */ tc_disable_callback(&us_ticker_module, TC_CALLBACK_CC_CHANNEL0); NVIC_DisableIRQ(TICKER_COUNTER_IRQn); }
/*! \brief to disable compare interrupt */ void tmr_disable_cc_interrupt(void) { tc_disable_callback(&module_inst, TC_CALLBACK_CC_CHANNEL0); }
/*! \brief to disable overflow interrupt */ void tmr_disable_ovf_interrupt(void) { tc_disable_callback(&module_inst, TC_CALLBACK_OVERFLOW); }
void hw_timer_stop(void) { tc_disable_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); } }