int timer_init(tim_t dev, unsigned long freq, timer_cb_t callback, void *arg) { TIMER_TypeDef *pre, *tim; /* test if given timer device is valid */ if (dev >= TIMER_NUMOF) { return -1; } /* save callback */ isr_ctx[dev].cb = callback; /* get timers */ pre = timer_config[dev].prescaler.dev; tim = timer_config[dev].timer.dev; /* enable clocks */ CMU_ClockEnable(cmuClock_HFPER, true); CMU_ClockEnable(timer_config[dev].prescaler.cmu, true); CMU_ClockEnable(timer_config[dev].timer.cmu, true); /* reset and initialize peripherals */ EFM32_CREATE_INIT(init_pre, TIMER_Init_TypeDef, TIMER_INIT_DEFAULT, .conf.enable = false, .conf.prescale = timerPrescale1 ); EFM32_CREATE_INIT(init_tim, TIMER_Init_TypeDef, TIMER_INIT_DEFAULT, .conf.enable = false, .conf.clkSel = timerClkSelCascade ); TIMER_Reset(tim); TIMER_Reset(pre); TIMER_Init(tim, &init_tim.conf); TIMER_Init(pre, &init_pre.conf); /* configure the prescaler top value */ uint32_t freq_timer = CMU_ClockFreqGet(timer_config[dev].prescaler.cmu); uint32_t top = ( freq_timer / TIMER_Prescaler2Div(init_pre.conf.prescale) / freq) - 1; TIMER_TopSet(pre, top); TIMER_TopSet(tim, 0xffff); /* enable interrupts for the channels */ TIMER_IntClear(tim, TIMER_IFC_CC0 | TIMER_IFC_CC1 | TIMER_IFC_CC2); TIMER_IntEnable(tim, TIMER_IEN_CC0 | TIMER_IEN_CC1 | TIMER_IEN_CC2); NVIC_ClearPendingIRQ(timer_config[dev].irq); NVIC_EnableIRQ(timer_config[dev].irq); /* start the timers */ TIMER_Enable(tim, true); TIMER_Enable(pre, true); return 0; }
void StoredFilter_Start(void) { Leds_SetLeds(0x4); CMU_ClockEnable(cmuClock_USART2, true); CMU_ClockEnable(cmuClock_GPIO, true); SPI_setup(2, 0, true); setupMEM(); setupFPGA(); setupSD(); done = false; setupTimer(); FPGA_Enable(); while(1) { if (done) break; } FPGA_Disable(); TIMER_Enable( TIMER0, false ); TIMER_Reset( TIMER0 ); FPGADriver_Destroy(); SDDriver_Finalize(); MEM_Destroy(); }
void STDMIXER_SetChannelOrderByProtocol() { const u8 *ch_map = CurrentProtocolChannelMap; if (! ch_map) { // for none protocol, assign any channel to thr is fine ch_map = EATRG0; } CLOCK_ResetWatchdog();// this function might be invoked after loading from template/model file, so feeding the dog in the middle unsigned safetysw = 0; s8 safetyval = 0; for (unsigned ch = 0; ch < 3; ch++) { // only the first 3 channels need to check if (Model.limits[ch].safetysw) { safetysw = Model.limits[ch].safetysw; safetyval = Model.limits[ch].safetyval; } if (ch_map[ch] == INP_THROTTLE) mapped_std_channels.throttle = ch; else if (ch_map[ch] == INP_AILERON) mapped_std_channels.actual_aile = mapped_std_channels.aile = ch; else if (ch_map[ch] == INP_ELEVATOR) mapped_std_channels.actual_elev = mapped_std_channels.elev = ch; } Model.limits[mapped_std_channels.throttle].safetysw = safetysw; Model.limits[mapped_std_channels.throttle].safetyval = safetyval; Model.limits[mapped_std_channels.aile].safetysw = 0; Model.limits[mapped_std_channels.elev].safetysw = 0; Model.limits[mapped_std_channels.aile].safetyval = 0; Model.limits[mapped_std_channels.elev].safetyval = 0; //printf("thro: %d, aile: %d, elev: %d\n\n", mapped_std_channels.throttle, mapped_std_channels.aile, mapped_std_channels.elev); MIXER_SetTemplate(mapped_std_channels.throttle, MIXERTEMPLATE_COMPLEX); MIXER_SetTemplate(mapped_std_channels.aile, MIXERTEMPLATE_CYC1); MIXER_SetTemplate(mapped_std_channels.elev, MIXERTEMPLATE_CYC2); struct Mixer *mix = MIXER_GetAllMixers(); for (unsigned idx = 0; idx < NUM_MIXERS; idx++) { if (mix[idx].src ==0) continue; if (mix[idx].dest == NUM_OUT_CHANNELS + 9) mix[idx].src = 0; // remove all mixers pointing to Virt10, because the Virt10 is reserved in Standard mode else if (MIXER_MUX(&mix[idx]) == MUX_REPLACE && mix[idx].src== INP_THROTTLE && mix[idx].dest < NUM_OUT_CHANNELS) { // src=THR && dest = virt should be pitch's mixer mix[idx].dest = mapped_std_channels.throttle; } } MIXER_SetTemplate(NUM_OUT_CHANNELS + 9, MIXERTEMPLATE_NONE);// remove all mixers pointing to Virt10 as the Virt10 is reserved in Standard mode mapped_std_channels.aile = NUM_OUT_CHANNELS; // virt 1 mapped_std_channels.elev = NUM_OUT_CHANNELS +1; // virt 2 // Simplfied timer sw, only throttle channel output is possible to be selected for (unsigned i = 0; i < NUM_TIMERS; i++) { if (Model.timer[i].src) Model.timer[i].src = mapped_std_channels.throttle + NUM_INPUTS +1; TIMER_Reset(i); } CLOCK_ResetWatchdog(); }
void toggle_source_cb(guiObject_t *obj, void *data) { u8 idx = (long)data; struct Timer *timer = &Model.timer[idx]; if(MIXER_SRC(timer->src)) { MIXER_SET_SRC_INV(timer->src, ! MIXER_SRC_IS_INV(timer->src)); TIMER_Reset(idx); GUI_Redraw(obj); } }
const char *set_start_cb(guiObject_t *obj, int dir, void *data) { (void)obj; u8 idx = (long)data; u8 changed; struct Timer *timer = &Model.timer[idx]; timer->timer = GUI_TextSelectHelper(timer->timer, 0, TIMER_MAX_VAL, dir, 5, 30, &changed); if (changed) TIMER_Reset(idx); TIMER_SetString(tp->timer, timer->timer*1000); return tp->timer; }
static unsigned _action_cb(u32 button, unsigned flags, void *data) { u8 i; if ((flags & BUTTON_PRESS) && CHAN_ButtonIsPressed(button, BUT_ENTER)) { u8 page = (0 << 4) | MENUTYPE_MAINMENU; PAGE_ChangeByID(PAGEID_MENU, page); } else if ((flags & BUTTON_PRESS) && CHAN_ButtonIsPressed(button, BUT_RIGHT)) { for ( i=0; i< NUM_TIMERS; i++) TIMER_StartStop(i); } else if ((flags & BUTTON_PRESS) && CHAN_ButtonIsPressed(button, BUT_LEFT)) { for ( i=0; i< NUM_TIMERS; i++) TIMER_Reset(i); } else if (! PAGE_QuickPage(button, flags, data)) { MIXER_UpdateTrim(button, flags, data); } return 1; }
static unsigned _action_cb(u32 button, unsigned flags, void *data) { u8 i; if ((flags & BUTTON_PRESS) && CHAN_ButtonIsPressed(button, BUT_ENTER)) { //see pagelist.h for mapping of 'page' to menu_id PAGE_PushByID(PAGEID_MENU, 0); } else if ((flags & BUTTON_PRESS) && CHAN_ButtonIsPressed(button, BUT_RIGHT)) { for ( i=0; i< NUM_TIMERS; i++) TIMER_StartStop(i); } else if ((flags & BUTTON_PRESS) && CHAN_ButtonIsPressed(button, BUT_LEFT)) { for ( i=0; i< NUM_TIMERS; i++) TIMER_Reset(i); } else if (! PAGE_QuickPage(button, flags, data)) { MIXER_UpdateTrim(button, flags, data); } return 1; }
// Private function prototypes ----------------------------------------------- // Private functions --------------------------------------------------------- // Exported functions -------------------------------------------------------- uint8_t bsp_tick_timer_init(void) { uint8_t ret = EXIT_SUCCESS; uint32_t timer_freq; uint32_t timer_top_count; TIMER_Reset(TIMER0); // Configure a system timer for tracking a tick counter. CMU_ClockEnable(cmuClock_TIMER0, true); // Set the timer configuration s_timer_init.enable = false; // Enable timer when init complete. s_timer_init.debugRun = true; // Stop counter during debug halt. s_timer_init.prescale = timer_prescale; // Prescale by 16 (2MHz clock) s_timer_init.clkSel = timerClkSelHFPerClk; // Select HFPER clock. s_timer_init.count2x = false; // Not 2x count mode. s_timer_init.ati = false; // No ATI. s_timer_init.fallAction = timerInputActionNone; // No action on falling input edge. s_timer_init.riseAction = timerInputActionNone; // No action on rising input edge. s_timer_init.mode = timerModeUp; // Up-counting. s_timer_init.dmaClrAct = false; // Do not clear DMA requests when DMA channel is active. s_timer_init.quadModeX4 = false; // Select X2 quadrature decode mode (if used). s_timer_init.oneShot = false; // Disable one shot. s_timer_init.sync = false; // Not started/stopped/reloaded by other timers. // Configure TIMER TIMER_Init(TIMER0, &s_timer_init); // Set counter top for tick rate timer_freq = CMU_ClockFreqGet(cmuClock_TIMER0) / (1 << timer_prescale); timer_top_count = (timer_freq / TIMER_TICK_RATE_HZ) - 1; TIMER_TopSet(TIMER0, timer_top_count); return ret; }
const char *_set_src_cb(guiTextSelect_t *obj, u8 *src, int dir, int idx, int source) { u8 changed; if (Model.mixer_mode == MIXER_STANDARD && Model.type == MODELTYPE_HELI) { //Improvement: only to intelligent switch setting for heli type in standard mode int is_neg = MIXER_SRC_IS_INV(*src); int step = mapped_std_channels.throttle + NUM_INPUTS +1; int newsrc = GUI_TextSelectHelper(MIXER_SRC(*src), 0, step, dir, step, step, &changed); MIXER_SET_SRC_INV(newsrc, is_neg); *src = newsrc; } else { if (source <= INP_NONE) *src = INPUT_SelectSource(*src, dir, &changed); else *src = INPUT_SelectInput(*src, source, &changed); } if (changed) { TIMER_Reset(idx); } GUI_TextSelectEnablePress(obj, MIXER_SRC(*src)); return INPUT_SourceName(tempstring, *src); }
const char *set_timertype_cb(guiObject_t *obj, int dir, void *data) { (void) obj; u8 idx = (long)data; struct Timer *timer = &Model.timer[idx]; u8 changed; timer->type = GUI_TextSelectHelper(timer->type, 0, TIMER_LAST, dir, 1, 1, &changed); if (changed){ if (timer->type == TIMER_LAST) timer->type = 0; TIMER_Reset(idx); update_countdown(idx); } switch (timer->type) { case TIMER_STOPWATCH: return _tr("stopwatch"); case TIMER_STOPWATCH_PROP: return _tr("stop-prop"); case TIMER_COUNTDOWN: return _tr("countdown"); case TIMER_COUNTDOWN_PROP: return _tr("cntdn-prop"); case TIMER_PERMANENT: return _tr("permanent"); case TIMER_LAST: break; } return ""; }
/**************************************************************************//** * @brief This function enables the 100us timer for HRM. *****************************************************************************/ static void startTimer () { // Enable clock for TIMER module CMU_ClockEnable(CLK_HRM_TIMER1, true); CMU_ClockEnable(CLK_HRM_TIMER2, true); TIMER_Reset(HRM_TIMER1); TIMER_Reset(HRM_TIMER2); // Select TIMER parameters TIMER_Init_TypeDef timerInit1 = { .enable = true, .debugRun = true, .prescale = timerPrescale1, .clkSel = timerClkSelHFPerClk, .fallAction = timerInputActionNone, .riseAction = timerInputActionNone, .mode = timerModeUp, .dmaClrAct = false, .quadModeX4 = false, .oneShot = false, .sync = false, }; TIMER_Init_TypeDef timerInit2 = { .enable = true, .debugRun = true, .prescale = timerPrescale1, .clkSel = timerClkSelCascade, .fallAction = timerInputActionNone, .riseAction = timerInputActionNone, .mode = timerModeUp, .dmaClrAct = false, .quadModeX4 = false, .oneShot = false, .sync = false, }; // Set TIMER Top value TIMER_TopSet(HRM_TIMER1, CMU_ClockFreqGet(cmuClock_HF)/1/10000); /*overflow every 100us*/ TIMER_TopSet(HRM_TIMER2, 0xffff); /*max 16 bits*/ // Configure TIMER TIMER_Init(HRM_TIMER1, &timerInit1); TIMER_Init(HRM_TIMER2, &timerInit2); } /**************************************************************************//** * @brief Initiate the Heart Rate Monitor *****************************************************************************/ void HeartRateMonitor_Init( Si114xPortConfig_t* i2c, HeartRateMonitor_Config_t configSelect ) { // Setup SysTick Timer for 10msec interrupts. if (SysTick_Config(CMU_ClockFreqGet(cmuClock_CORE) / 100)) while (1) ; // Setup Timer as 100 usec counter. The HRM API requires a 100usec timestamp. startTimer (); dataStorage.spo2 = &spo2Data; dataStorage.hrm = &hrmDataStorage; hrmHandle = &dataStorage; si114xhrm_Initialize(i2c, 0, &hrmHandle); if (configSelect == BIOMETRIC_EXP) { si114xhrm_Configure(hrmHandle, &biometricEXPHRMConfig); currentHRMConfig = &biometricEXPHRMConfig; } else if (configSelect == SI1143_PS) { si114xhrm_Configure(hrmHandle, &Si1143PsHRMConfig); currentHRMConfig = &Si1143PsHRMConfig; } else if (configSelect == SI1147_PS) { si114xhrm_Configure(hrmHandle, &Si1147PsHRMConfig); currentHRMConfig = &Si1147PsHRMConfig; } //turn off LEDs setRedLED (false); setGreenLED (false); bufferOverrunError = false; displayHeartRateValue = 0; displaySpo2Value = 0; HeartRateMonitor_UpdateDisplay(HRM_STATE_NOSIGNAL, false); } /**************************************************************************//** * @brief Check for samples in irq queue *****************************************************************************/ bool HeartRateMonitor_SamplesPending () { HANDLE si114xHandle; si114xhrm_GetLowLevelHandle(hrmHandle, &si114xHandle); return (Si114xIrqQueueNumentries(si114xHandle)>0); } /**************************************************************************//** * @brief Reset inactive timer values *****************************************************************************/ static void resetInactiveTimer() { enableInactiveTimer = false; inactiveTimeout = false; inactiveTimerCounter = 0; }
/***************************************************************************//** * @brief * Initialize the specified TIMER unit * * @details * * @note * * @param[in] device * Pointer to device descriptor * * @param[in] unitNumber * Unit number * * @return * Pointer to TIMER device ******************************************************************************/ static struct efm32_timer_device_t *rt_hw_timer_unit_init( rt_device_t device, rt_uint8_t unitNumber, rt_uint8_t mode) { struct efm32_timer_device_t *timer; TIMER_Init_TypeDef init; efm32_irq_hook_init_t hook; CMU_Clock_TypeDef timerClock; IRQn_Type timerIrq; do { /* Allocate device */ timer = rt_malloc(sizeof(struct efm32_timer_device_t)); if (timer == RT_NULL) { timer_debug("no memory for TIMER%d driver\n", unitNumber); break; } /* Initialization */ if (unitNumber >= TIMER_COUNT) { break; } switch (unitNumber) { case 0: timer->timer_device = TIMER0; timerClock = (CMU_Clock_TypeDef)cmuClock_TIMER0; timerIrq = TIMER0_IRQn; break; case 1: timer->timer_device = TIMER1; timerClock = (CMU_Clock_TypeDef)cmuClock_TIMER1; timerIrq = TIMER1_IRQn; break; case 2: timer->timer_device = TIMER2; timerClock = (CMU_Clock_TypeDef)cmuClock_TIMER2; timerIrq = TIMER2_IRQn; break; default: break; } /* Enable TIMER clock */ CMU_ClockEnable(timerClock, true); /* Reset */ TIMER_Reset(timer->timer_device); /* Init specified TIMER unit */ init.enable = false; init.debugRun = true; init.prescale = TMR_CFG_PRESCALER; init.clkSel = timerClkSelHFPerClk; init.fallAction = timerInputActionNone; init.riseAction = timerInputActionNone; init.mode = timerModeUp; init.dmaClrAct = false; init.quadModeX4 = false; init.oneShot = (mode > 0) ? true : false; init.sync = false; TIMER_Init(timer->timer_device, &init); /* Config interrupt and NVIC */ hook.type = efm32_irq_type_timer; hook.unit = unitNumber; hook.cbFunc = rt_hw_timer_isr; hook.userPtr = device; efm32_irq_hook_register(&hook); /* Enable overflow interrupt */ TIMER_IntEnable(timer->timer_device, TIMER_IF_OF); TIMER_IntClear(timer->timer_device, TIMER_IF_OF); /* Enable TIMERn interrupt vector in NVIC */ NVIC_ClearPendingIRQ(timerIrq); NVIC_SetPriority(timerIrq, EFM32_IRQ_PRI_DEFAULT); NVIC_EnableIRQ(timerIrq); return timer; } while(0); if (timer) { rt_free(timer); } rt_kprintf("TIMER: Init failed!\n"); return RT_NULL; }
void TIMER_Update() { unsigned i; unsigned chan_val = 0; u32 t = CLOCK_getms(); if (PROTOCOL_WaitingForSafe()) return; if( Transmitter.power_alarm > 0 ) TIMER_Power(); for (i = 0; i < NUM_TIMERS; i++) { if (Model.timer[i].src) { s16 val; if (MIXER_SRC(Model.timer[i].src) <= NUM_INPUTS) { volatile s16 *raw = MIXER_GetInputs(); val = raw[MIXER_SRC(Model.timer[i].src)]; } else { val = MIXER_GetChannel(Model.timer[i].src - NUM_INPUTS - 1, APPLY_SAFETY); } if (MIXER_SRC_IS_INV(Model.timer[i].src)) val = -val; if (Model.timer[i].type == TIMER_STOPWATCH_PROP || Model.timer[i].type == TIMER_COUNTDOWN_PROP) { chan_val = RANGE_TO_PCT(abs(val)); if (chan_val > 100) chan_val = 100; } else { unsigned new_state = (val - CHAN_MIN_VALUE > (CHAN_MAX_VALUE - CHAN_MIN_VALUE) / 20) ? 1 : 0; if (new_state != timer_state[i]) { if (new_state) last_time[i] = t; timer_state[i] = new_state; } } } if (timer_state[i]) { s32 delta = t - last_time[i]; if (Model.timer[i].type == TIMER_STOPWATCH_PROP || Model.timer[i].type == TIMER_COUNTDOWN_PROP) { delta = delta * chan_val / 100; } if (Model.timer[i].type == TIMER_PERMANENT) { timer_val[i] += delta; if( timer_val[i] >= 359999900) // Reset when 99h59mn59sec timer_val[i] = 0 ; Model.timer[i].val = timer_val[i]; } else if (Model.timer[i].type == TIMER_STOPWATCH || Model.timer[i].type == TIMER_STOPWATCH_PROP) { timer_val[i] += delta; } else { s32 warn_time; // start to beep for each prealert_interval at the last prealert_time(seconds) if (Transmitter.countdown_timer_settings.prealert_time != 0 && Transmitter.countdown_timer_settings.prealert_interval != 0 && timer_val[i] > Transmitter.countdown_timer_settings.prealert_interval && timer_val[i] < (s32)Transmitter.countdown_timer_settings.prealert_time + 1000) { // give extra 1seconds warn_time = ((timer_val[i] / Transmitter.countdown_timer_settings.prealert_interval) * Transmitter.countdown_timer_settings.prealert_interval); if (timer_val[i] > warn_time && (timer_val[i] - delta) <= warn_time) { MUSIC_Play(MUSIC_TIMER_WARNING); } } // Beep once for each timeup_interval past 0 if (timer_val[i] < 0 && Transmitter.countdown_timer_settings.timeup_interval != 0) { warn_time = ((timer_val[i] - Transmitter.countdown_timer_settings.timeup_interval) / Transmitter.countdown_timer_settings.timeup_interval) * Transmitter.countdown_timer_settings.timeup_interval; if (timer_val[i] > warn_time && (timer_val[i] - delta) <= warn_time) { MUSIC_Play(MUSIC_ALARM1 + i); } } if (timer_val[i] >= 0 && timer_val[i] < delta) { MUSIC_Play(MUSIC_ALARM1 + i); } timer_val[i] -= delta; } last_time[i] = t; } if (Model.timer[i].resetsrc) { s16 val; if (MIXER_SRC(Model.timer[i].resetsrc) <= NUM_INPUTS) { volatile s16 *raw = MIXER_GetInputs(); val = raw[MIXER_SRC(Model.timer[i].resetsrc)]; } else { val = MIXER_GetChannel(Model.timer[i].resetsrc - NUM_INPUTS - 1, APPLY_SAFETY); } if (MIXER_SRC_IS_INV(Model.timer[i].resetsrc)) val = -val; if (val - CHAN_MIN_VALUE > (CHAN_MAX_VALUE - CHAN_MIN_VALUE) / 20) { TIMER_Reset(i); } } } }
void TIMER_Init() { unsigned i; for (i = 0; i < NUM_TIMERS; i++) TIMER_Reset(i); }