Ejemplo n.º 1
0
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;
}
Ejemplo n.º 4
0
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;
}
Ejemplo n.º 6
0
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;
}
Ejemplo n.º 7
0
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;
}