bool timer_set(long cycles, bool start) { int tf_en = TFCMD & (1 << 0); /* save TF_EN status */ /* stop timer */ TFCMD = (0 << 0); /* TF_EN = disable */ /* optionally unregister any previously registered timer user */ if (start) { if (pfn_unregister != NULL) { pfn_unregister(); pfn_unregister = NULL; } } /* configure timer */ TFCON = (1 << 12) | /* TF_INT0_EN */ (4 << 8) | /* TF_CS = ECLK / 1 */ (1 << 6) | /* select ECLK (12 MHz) */ (0 << 4); /* TF_MODE_SEL = interval mode */ TFPRE = 0; /* no prescaler */ TFDATA0 = cycles; /* set interval period */ /* After the configuration, we must write '1' in TF_CLR to * initialize the timer (s5l8700 DS): * - Clear the counter register. * - The value of TF_START is set to TF_OUT. * - TF_DATA0 and TF_DATA1 are updated to the internal buffers. * - Initialize the state of the previously captured signal. */ TFCMD = (1 << 1) | /* TF_CLR = initialize timer */ (tf_en << 0); /* TF_EN = restore previous status */ return true; }
bool timer_set(long cycles, bool start) { /* Maximum cycle count expressible in the cycles parameter is 2^31-1 * and the modulus counter is capable of 2^32-1 and as a result there is * no requirement to use a prescaler > 1. This gives a frequency range of * ~0.015366822Hz - 66000000Hz. The highest input frequency gives the * greatest possible accuracy anyway. */ int oldstatus = disable_interrupt_save(IRQ_FIQ_STATUS); /* Halt timer if running - leave module clock enabled */ stop_timer(false); if (start && pfn_unregister != NULL) { pfn_unregister(); pfn_unregister = NULL; } /* CLKSRC = ipg_clk, * EPIT output disconnected, * Enabled in wait mode * Prescale 1 for 66MHz * Reload from modulus register, * Count from load value */ EPITCR2 = EPITCR_CLKSRC_IPG_CLK | EPITCR_WAITEN | EPITCR_IOVW | ((1-1) << EPITCR_PRESCALER_POS) | EPITCR_RLD | EPITCR_ENMOD; EPITLR2 = cycles; /* Event when counter reaches 0 */ EPITCMPR2 = 0; restore_interrupt(oldstatus); return true; }
bool timer_set(long cycles, bool start) { bool found = false; int prescale_option = 0; int actual_cycles = 0; /* Use the first prescale that fits Timer4's 20-bit counter */ while (!found && prescale_option < 7) { actual_cycles = cycles >> prescale_shifts[prescale_option]; if (actual_cycles < 0x100000) found = true; else prescale_option++; } if (!found) return false; /* Stop the timer and set new prescale & ref count */ TCFG(4) &= ~TCFG_EN; TCFG(4) = prescale_option << TCFG_SEL; TREF(4) = actual_cycles; if (start && pfn_unregister != NULL) { pfn_unregister(); pfn_unregister = NULL; } return true; }
bool timer_set(long cycles, bool start) { unsigned int divider = cycles, prescaler_bit = 0, prescaler = 1, old_irq; if(cycles < 1) return false; if(start && pfn_unregister != NULL) { pfn_unregister(); pfn_unregister = NULL; } /* Increase prescale values starting from 0 to make the cycle count fit */ while(divider > 65535 && prescaler <= 1024) { prescaler <<= 2; /* 1, 4, 16, 64, 256, 1024 */ prescaler_bit++; divider = cycles / prescaler; } old_irq = disable_irq_save(); __tcu_stop_counter(1); if(start) { __tcu_disable_pwm_output(1); __tcu_mask_half_match_irq(1); __tcu_unmask_full_match_irq(1); /* EXTAL clock = CFG_EXTAL (12Mhz in most targets) */ __tcu_select_extalclk(1); } REG_TCU_TCSR(1) = (REG_TCU_TCSR(1) & ~TCU_TCSR_PRESCALE_MASK) | (prescaler_bit << TCU_TCSR_PRESCALE_BIT); REG_TCU_TCNT(1) = 0; REG_TCU_TDHR(1) = 0; REG_TCU_TDFR(1) = divider; __tcu_clear_full_match_flag(1); if(start) { system_enable_irq(IRQ_TCU1); __tcu_start_counter(1); } restore_irq(old_irq); return true; }
bool timer_set(long cycles, bool start) { timer_stop(); if(start && pfn_unregister) { pfn_unregister(); pfn_unregister = NULL; } timer_cycles = cycles; return true; }
bool timer_set(long cycles, bool start) { if (start) { if (pfn_unregister != NULL) { pfn_unregister(); pfn_unregister = NULL; } TIMER1.ctrl &= ~0x80; /* disable the counter */ TIMER1.ctrl |= 0x40; /* reload after counting down to zero */ TIMER1.ctrl &= ~0xc; /* no prescaler */ TIMER1.clr = 1; /* clear an interrupt event */ } if (start || (cycles_new == -1)) /* within isr, cycles_new is "locked" */ { /* enable timer */ TIMER1.load = cycles - 1; TIMER1.ctrl |= 0x80; /* enable the counter */ } else cycles_new = cycles; return true; }
bool timer_set(long cycles, bool start) { int oldlevel; unsigned int divider=cycles, prescaler=0; if(cycles<1) return false; oldlevel = set_irq_level(HIGHEST_IRQ_LEVEL); bitset16(&IO_CLK_MOD2, CLK_MOD2_TMR0); /* enable TIMER0 clock */ IO_TIMER0_TMMD = CONFIG_TIMER0_TMMD_STOP; if (start && pfn_unregister != NULL) { pfn_unregister(); pfn_unregister = NULL; } oldlevel = disable_irq_save(); /* Increase prescale values starting from 0 to make the cycle count fit */ while(divider>65535 && prescaler<1024) { prescaler++; divider=cycles/(prescaler+1); } IO_TIMER0_TMPRSCL = prescaler; IO_TIMER0_TMDIV = divider; restore_irq(oldlevel); return true; }