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; }
/** * \internal * \brief Cleanup Function: Asynchronous event propagation. * * This function disables the RTC, clears the RTC COUNT register and * stops the timer (TC3). * * \param test Current test case. */ static void cleanup_asynchronous_event_test(const struct test_case *test) { rtc_count_disable(&rtc_inst); rtc_count_set_count(&rtc_inst, 0); tc_stop_counter(&tc_inst); events_release(&events); }
/*! * @brief Implements a delay of the length of the argument in econds * * @param[in] NULL * * @param[out] NULL * * @return NULL * */ void tc4_wait_for_msec (uint32_t msec) { /* Set the compare value */ tc_set_compare_value(&tc4_instance, TC_COMPARE_CAPTURE_CHANNEL_0, (msec *500)); /* start counting */ tc_start_counter(&tc4_instance); /* delay until required time is elapsed */ while (!tc4_callback_flag); /* stop the counter */ tc_stop_counter(&tc4_instance); /* reset the interrupt flag */ tc4_callback_flag = false; }
/** * \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; }
/*! * @brief Configures TC4 of the MCU * * @param[in] NULL * * @param[out] NULL * * @return NULL * */ void tc4_configure (void) { /* TC's configuration structure */ struct tc_config config_tc; /* Get TC configuration default */ tc_get_config_defaults(&config_tc); /* set TC GLCK */ config_tc.clock_source = GCLK_GENERATOR_1; /* Set the initial compare value */ config_tc.counter_16_bit.compare_capture_channel[TC_COMPARE_CAPTURE_CHANNEL_0] = 500; /* initialize TC4 with current configurations */ tc_init(&tc4_instance, TC4, &config_tc); /* enable the TC module */ tc_enable(&tc4_instance); /* Stop the counter */ tc_stop_counter(&tc4_instance); }
void platform_stop_bus_timer(void *timer_handle) { tc_stop_counter(&bus_tc_instance); }
void platform_delete_bus_timer(void *timer_handle) { tc_stop_counter(&bus_tc_instance); tc_reset(&bus_tc_instance); hw_timers[0].timer_usage = 0; }
/*! * @brief Stops TC6 counter * * @param[in] NULL * * @param[out] NULL * * @return NULL * */ void tc6_stop_counter (void) { tc_stop_counter(&tc6_instance); }
/* Timer 0 Initialization */ void timer_init(void) { struct tc_config conf_tc; struct tc_events conf_tc_events = {.generate_event_on_compare_channel[0] = 1}; tc_get_config_defaults(&conf_tc); conf_tc.clock_source = GCLK_GENERATOR_0; conf_tc.wave_generation = TC_WAVE_GENERATION_MATCH_FREQ; conf_tc.counter_16_bit.compare_capture_channel[0] = 0xFFFF; tc_init(&tc_inst, TC0, &conf_tc); tc_enable_events(&tc_inst, &conf_tc_events); tc_enable(&tc_inst); tc_stop_counter(&tc_inst); /* Enable TC0 match/capture channel 0 interrupt */ TC0->COUNT16.INTENSET.bit.MC0 = 1; /* Enable TC0 module interrupt */ NVIC_EnableIRQ(TC0_IRQn); } /* DAC Initialization */ void dac_initialize(void) { struct dac_config conf_dac; struct dac_events conf_dac_events = {.on_event_start_conversion = 1}; dac_get_config_defaults(&conf_dac); conf_dac.clock_source = GCLK_GENERATOR_3; conf_dac.reference = DAC_REFERENCE_INT1V; dac_init(&dac_inst, DAC, &conf_dac); dac_enable_events(&dac_inst, &conf_dac_events); dac_enable(&dac_inst); } /* Event System Initialization */ void evsys_init(void) { struct events_resource conf_event_resource; struct events_config conf_event; events_get_config_defaults(&conf_event); conf_event.edge_detect = EVENTS_EDGE_DETECT_NONE; conf_event.path = EVENTS_PATH_ASYNCHRONOUS; conf_event.generator = EVSYS_ID_GEN_TC0_MCX_0; events_allocate(&conf_event_resource, &conf_event); events_attach_user(&conf_event_resource, EVSYS_ID_USER_DAC_START); } /* Initialize the selected waveform buffer with output data */ void buffer_init(void) { #if WAVE_MODE==SINE_WAVE for (i = 0; i < DEGREES_PER_CYCLE; i++) { sine_wave_buf[i] = (uint16_t)(500 + (500*sin((double)i*DEGREE))); } #elif WAVE_MODE==SAW_TOOTH_WAVE for (i = 0; i < 256; i++) { sawtooth_wave_buf[i] = i*4; } #elif WAVE_MODE==TRIANGLE_WAVE for (i = 0; i < 128; i++) { triangle_wave_buf[i] = i*8; } for (i = 128; i < 256; i++) { triangle_wave_buf[i] = 1023 - (i*8); } #endif } /* Main function */ int main(void) { system_init(); timer_init(); dac_initialize(); evsys_init(); buffer_init(); /* Set the TC0 compare value corresponding to specified frequency */ #if WAVE_MODE==SINE_WAVE tc_set_compare_value(&tc_inst, 0, \ system_gclk_gen_get_hz(GCLK_GENERATOR_0)/(FREQUENCY*360)); #else tc_set_compare_value(&tc_inst, 0, \ system_gclk_gen_get_hz(GCLK_GENERATOR_0)/(FREQUENCY*256)); #endif /* Start TC0 timer */ tc_start_counter(&tc_inst); /* Enable global interrupt */ system_interrupt_enable_global(); while (true) { } }