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; }
/*! \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; }
/** * \brief Initialize the delay driver. * * This must be called during start up to initialize the delay routine with * the current used main clock. It must run any time the main CPU clock is changed. */ void delay_init(void) { cycles_per_ms = system_gclk_gen_get_hz(0); cycles_per_ms /= 1000; cycles_per_us = cycles_per_ms / 1000; SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk; }
void time_tick_init(void) { g_ms_ticks = 0; /* Configure systick */ if (SysTick_Config(system_gclk_gen_get_hz(0) / TICK_MS)) { Assert(false); } }
int main(void) { system_init(); /*Configure system tick to generate periodic interrupts */ SysTick_Config(system_gclk_gen_get_hz(GCLK_GENERATOR_0)); config_led(); while (true) { } }
void us_ticker_init(void) { uint32_t cycles_per_us; uint32_t prescaler = 0; struct tc_config config_tc; enum status_code ret_status; if (us_ticker_inited) return; us_ticker_inited = 1; if (g_sys_init == 0) { system_init(); g_sys_init = 1; } tc_get_config_defaults(&config_tc); cycles_per_us = system_gclk_gen_get_hz(config_tc.clock_source) / 1000000; MBED_ASSERT(cycles_per_us > 0); /*while((cycles_per_us & 1) == 0 && prescaler <= 10) { cycles_per_us = cycles_per_us >> 1; prescaler++; }*/ while((cycles_per_us > 1) && (prescaler <= 10)) { cycles_per_us = cycles_per_us >> 1; prescaler++; } if (prescaler >= 9) { prescaler = 7; } else if (prescaler >= 7) { prescaler = 6; } else if (prescaler >= 5) { prescaler = 5; } config_tc.clock_prescaler = TC_CTRLA_PRESCALER(prescaler); config_tc.counter_size = TC_COUNTER_SIZE_32BIT; config_tc.run_in_standby = true; config_tc.counter_32_bit.value = 0; config_tc.counter_32_bit.compare_capture_channel[TC_COMPARE_CAPTURE_CHANNEL_0] = 0xFFFFFFFF; config_tc.counter_32_bit.compare_capture_channel[TC_COMPARE_CAPTURE_CHANNEL_1] = 0xFFFFFFFF; /* Initialize the timer */ ret_status = tc_init(&us_ticker_module, TICKER_COUNTER_uS, &config_tc); MBED_ASSERT(ret_status == STATUS_OK); /* Register callback function */ tc_register_callback(&us_ticker_module, (tc_callback_t)us_ticker_irq_handler_internal, TC_CALLBACK_CC_CHANNEL0); /* Enable the timer module */ tc_enable(&us_ticker_module); }
/** * \brief Retrieves the clock frequency of a Generic Clock channel. * * Determines the clock frequency (in Hz) of a specified Generic Clock * channel, used as a source to a device peripheral module. * * \param[in] channel Generic Clock Channel index * * \return The frequency of the generic clock channel, in Hz. */ uint32_t system_gclk_chan_get_hz( const uint8_t channel) { uint8_t gen_id; system_interrupt_enter_critical_section(); /* Select the requested generic clock channel */ gen_id = GCLK->PCHCTRL[channel].bit.GEN; system_interrupt_leave_critical_section(); /* Return the clock speed of the associated GCLK generator */ return system_gclk_gen_get_hz(gen_id); }
/** * \brief Initializes a hardware FREQM module instance. * * Enables the clock and initializes the FREQM module, based on the given * configuration values. * * \param[in,out] module_inst Pointer to the software module instance struct * \param[in] hw Pointer to the FREQM hardware module * \param[in] config Pointer to the FREQM configuration options struct * * \return Status of the initialization procedure. * * \retval STATUS_OK The module was initialized successfully */ enum status_code freqm_init( struct freqm_module *const module_inst, Freqm *const hw, struct freqm_config *const config) { /* Sanity check arguments */ Assert(module_inst); Assert(hw); Assert(config); Assert(config->ref_clock_circles); /* Initialize device instance */ module_inst->hw = hw; /* Turn on the digital interface clock */ system_apb_clock_set_mask(SYSTEM_CLOCK_APB_APBA, MCLK_APBAMASK_FREQM); /* Set up the GCLK for the module */ struct system_gclk_chan_config gclk_chan_conf; system_gclk_chan_get_config_defaults(&gclk_chan_conf); gclk_chan_conf.source_generator = config->msr_clock_source; system_gclk_chan_set_config(FREQM_GCLK_ID_MSR, &gclk_chan_conf); system_gclk_chan_enable(FREQM_GCLK_ID_MSR); gclk_chan_conf.source_generator = config->ref_clock_source; system_gclk_chan_set_config(FREQM_GCLK_ID_REF, &gclk_chan_conf); system_gclk_chan_enable(FREQM_GCLK_ID_REF); module_inst->ref_clock_freq = system_gclk_gen_get_hz(config->ref_clock_source); /* Perform a software reset */ hw->CTRLA.reg = FREQM_CTRLA_SWRST; while (freqm_is_syncing()) { /* Wait for all hardware modules to complete synchronization */ } /* Initialize the FREQM with new configurations */ hw->CFGA.reg = config->ref_clock_circles; #if FREQM_CALLBACK_MODE == true /* Initialize parameters */ for (uint8_t i = 0; i < FREQM_CALLBACK_N; i++) { module_inst->callback[i] = NULL; } /* Register this instance for callbacks*/ _freqm_instance = module_inst; #endif return STATUS_OK; }
int main(void) { system_init(); cph_millis_init(); cph_stdio_init(); TRACE("DECAWAVE CPH \r\n"); TRACE(SOFTWARE_VER_STRING); TRACE("\r\n"); uint32_t f = system_gclk_gen_get_hz(0); TRACE("CPU FREQ: %lu\r\n", f); // Blink LED for 5 seconds for (int i = 0; i < (5 * 4); i++) { port_pin_set_output_level(LED_PIN, false); cph_millis_delay(125); port_pin_set_output_level(LED_PIN, true); cph_millis_delay(125); } // init cph_deca //#ifdef ANCHOR // anchor_init(); //#else // tag_init(); //#endif ss_twr_init(); // blocks system_interrupt_enable_global(); uint32_t count = 0; uint32_t timestamp = cph_get_millis(); uint32_t elapsed = 0; while (1) { cph_deca_run(); elapsed = (cph_get_millis() - timestamp); if (elapsed > 5000) { timestamp = cph_get_millis(); cph_deca_print_status(count++); } } }
int main(void) { system_init(); cph_millis_init(); cph_stdio_init(); uint32_t f = system_gclk_gen_get_hz(0); printf("CPU FREQ: %lu\r\n", f); system_interrupt_enable_global(); decawave_run(); // while (1) { // printf("HELLO\r\n"); // port_pin_toggle_output_level(LED_PIN); // cph_millis_delay(500); // } }
/** * \brief Configures the DAC in event triggered mode. * * Configures the DAC to use the module's default configuration, with output * channel mode configured for event triggered conversions. * * \param dev_inst Pointer to the DAC module software instance to initialize */ static void configure_dac(struct dac_module *dac_module) { struct dac_config config; struct dac_chan_config channel_config; /* Get the DAC default configuration */ dac_get_config_defaults(&config); /* Switch to GCLK generator 0 */ config.clock_source = GCLK_GENERATOR_0; dac_init(dac_module, DAC, &config); /* Get the default DAC channel config */ dac_chan_get_config_defaults(&channel_config); /* Set the channel configuration, and enable it */ dac_chan_set_config(dac_module, DAC_CHANNEL_0, &channel_config); dac_chan_enable(dac_module, DAC_CHANNEL_0); /* Enable event triggered conversions */ struct dac_events events = { .on_event_start_conversion = true }; dac_enable_events(dac_module, &events); dac_enable(dac_module); } /** * \brief Configures the TC to generate output events at the sample frequency. * * Configures the TC in Frequency Generation mode, with an event output once * each time the audio sample frequency period expires. * * \param dev_inst Pointer to the TC module software instance to initialize */ static void configure_tc(struct tc_module *tc_module) { struct tc_config config; tc_get_config_defaults(&config); config.clock_source = GCLK_GENERATOR_0; config.wave_generation = TC_WAVE_GENERATION_MATCH_FREQ; tc_init(tc_module, TC3, &config); /* Enable periodic event output generation */ struct tc_events events = { .generate_event_on_overflow = true }; tc_enable_events(tc_module, &events); /* Set the timer top value to alter the overflow frequency */ tc_set_top_value(tc_module, system_gclk_gen_get_hz(GCLK_GENERATOR_0) / sample_rate); tc_enable(tc_module); } /** * \brief Configures the event system to link the sample timer to the DAC. * * Configures the event system, linking the TC module used for the audio sample * rate timing to the DAC, so that a new conversion is triggered each time the * DAC receives an event from the timer. */ static void configure_events(struct events_resource *event) { struct events_config config; events_get_config_defaults(&config); config.generator = EVSYS_ID_GEN_TC3_OVF; config.path = EVENTS_PATH_ASYNCHRONOUS; events_allocate(event, &config); events_attach_user(event, EVSYS_ID_USER_DAC_START); } /** * \brief Main application routine */ int main(void) { struct dac_module dac_module; struct tc_module tc_module; struct events_resource event; /* Initialize all the system clocks, pm, gclk... */ system_init(); /* Enable the internal bandgap to use as reference to the DAC */ system_voltage_reference_enable(SYSTEM_VOLTAGE_REFERENCE_BANDGAP); /* Module configuration */ configure_tc(&tc_module); configure_dac(&dac_module); configure_events(&event); /* Start the sample trigger timer */ tc_start_counter(&tc_module); while (true) { while (port_pin_get_input_level(SW0_PIN) == SW0_INACTIVE) { /* Wait for the button to be pressed */ } port_pin_toggle_output_level(LED0_PIN); for (uint32_t i = 0; i < number_of_samples; i++) { dac_chan_write(&dac_module, DAC_CHANNEL_0, wav_samples[i]); while (!(DAC->INTFLAG.reg & DAC_INTFLAG_EMPTY)) { /* Wait for data buffer to be empty */ } } while (port_pin_get_input_level(SW0_PIN) == SW0_ACTIVE) { /* Wait for the button to be depressed */ } } }
void samr21AlarmInit(void) { /*Configure system tick to generate periodic interrupts */ SysTick_Config(system_gclk_gen_get_hz(GCLK_GENERATOR_0) / 1000); }
/* 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) { } }