⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mcf5xxx_timer.c

📁 motorola 针对coldfire 5275 评估板的Dbug bootloader源程序
💻 C
字号:
/*
 * File:        mcf5xxx_timer.c
 * Purpose:     routines for accessing integrated timer modules
 *
 * Notes:       Provides an interface to the DMA timer module common
 *              to many ColdFire processors
 *
 * Modifications:
 *
 */

#include "src/include/dbug.h"
#include "src/cpu/coldfire/mcf5xxx/mcf5xxx_timer.h"

/********************************************************************/

static MCF5XXX_TIMER timer[TIMER_NUM_CH];

/********************************************************************/
uint32
timer_default_isr(void *not_used, MCF5XXX_TIMER *t)
{
    (void) not_used;
    
    /* Clear the pending event */
    MCF_TIMER_DTER(t->channel) = (0
        | MCF_TIMER_DTER_REF
        | MCF_TIMER_DTER_CAP);

    t->timeouts++;
    if (t->reference)
        if (--t->reference == 0)
            timer_stop(t->channel);

    return TRUE;
}

/********************************************************************/
uint32
timer_read(uint8 channel)
{
    uint32 now;

    now = MCF_TIMER_DTCN(channel);
    timer[channel].then = timer[channel].now;
    timer[channel].now = now;
    return now;
}

/********************************************************************/
void
timer_start(uint8 channel)
{
    /* Reset Timer module */
    MCF_TIMER_DTMR(channel) = 0;

    /* Clear any pending Timer events */
    MCF_TIMER_DTER(channel) = (0
        | MCF_TIMER_DTER_REF
        | MCF_TIMER_DTER_CAP);
    
#if (defined(CPU_MCF5282)  ||   \
     defined(CPU_MCF5275)  ||   \
     defined(CPU_MCF523X)  ||   \
     defined(CPU_MCF5271))  

    /* Set Timer Interrupt Control Register */
    MCF_INTC0_ICRn(19 + channel) = (uint8)(MCF_INTC0_ICRn_IL(timer[channel].level));
        
    /* Clear the appriopriate Interrupt Mask bit */
    MCF_INTC0_IMRL &= ~((MCF_INTC0_IMRL_INT_MASK19 << channel) | 
                        MCF_INTC0_IMRL_MASKALL);

#elif (defined(CPU_MCF5208))
    /* Set Timer Interrupt Control Register */
    MCF_INTC_ICR(32 + channel) = (uint8)(MCF_INTC_ICR_IL(timer[channel].level));
        
    /* Clear the appriopriate Interrupt Mask bit */
    MCF_INTC_IMRH &= ~(MCF_INTC_IMRH_INT_MASK32 << channel);
     
#elif (defined(CPU_MCF532X))
    /* Set Timer Interrupt Control Register */
    MCF_INTC0_ICR(32 + channel) = (uint8)(MCF_INTC_ICR_IL(timer[channel].level));
        
    /* Clear the appriopriate Interrupt Mask bit */
    MCF_INTC0_IMRH &= ~(MCF_INTC_IMRH_INT_MASK32 << channel);
     
#elif (defined(CPU_MCF5272))

    MCF_INTC_ICR1 = (0  | 
        MCF_INTC_ICR1_TMR_IPL(timer[channel].level, channel)    | 
        MCF_INTC_ICR1_TMR_IP(channel));
    
#elif (defined(CPU_MCF5307) ||   \
       defined(CPU_MCF5407) ||   \
       defined(CPU_MCF5249))           
       
    /* Clear the appriopriate Interrupt Mask bit */
    MCF_SIM_IMR &= ~(MCF_SIM_IMR_TIMER0 << channel);
    
    /* Set Timer Interrupt Control Register */
    MCF_SIM_ICR(channel - 1) = (0   |
        MCF_SIM_ICR_AVEC            |
        MCF_SIM_ICR_IL(timer[channel].level - 24)));

#else
#error "Unsuppoted ColdFire in timer.c"
#endif
        
    /* Reset the counter */
    MCF_TIMER_DTCN(channel) = 0;

    /* Write the TRR register */
    MCF_TIMER_DTRR(channel) = timer[channel].trr;

    /* Write the TMR register and start the free-running timer */
    MCF_TIMER_DTMR(channel) = timer[channel].tmr;
    
    #if defined(DEBUG_PRINT)
    	printf("DTMR = %08x\n", MCF_TIMER_DTMR(channel) ); 
    	printf("IMRH = %08x\n", MCF_INTC0_IMRH ); 
    	printf("ICR32 = %08x\n", MCF_INTC0_ICR32 ); 
    	printf("ICR(32) = %08x\n", MCF_INTC0_ICR(32) ); 
    	
    #endif

    
}
/********************************************************************/
void
timer_stop(uint8 channel)
{
    /* Get the latest time */
    timer_read(channel);

    /* Disable timer (reset) */
    MCF_TIMER_DTMR(channel) = 0;
}

/********************************************************************/
uint32
timer_set_secs(uint8 channel, uint32 secs)
{
    uint32 timeout;

    /* Get the timeout in seconds */
    timeout = (uint32)(((timer[channel].period * 0xFFFF)/1000000000) + 0.5);

    if (timeout == 0)
    {
        timer[channel].reference = 1;
        return FALSE;
    }

    /* Save the reference reached counter value */
    timer[channel].reference = secs/timeout;

    /* Reset the timeout counter */
    timer[channel].timeouts = 0;

    /* Start the timer */
    timer_start(channel);

    return TRUE;
}

/********************************************************************/
uint32
timer_get_reference(uint8 channel)
{   

    return timer[channel].reference;
}

/********************************************************************/
uint32
timer_get_time(uint8 channel)
{
    /* NOT COMPLETE!  FIX */
    return (timer[channel].now - timer[channel].then);
}

/********************************************************************/
uint32
timer_init(uint8 channel, float period, float sysclock, uint32 level,
            void (*isr)(void*, void*))
{
    /* 
     * This routine should only be called by the project (board) specific
     * initialization code.
     */
    
    uint16 prescale;

    if ((channel > 3) || (level < 1) || (level > 7))
        return FALSE;

    /* If no period, disable timer */
    if (!period)
    {
        if (timer[channel].isr != NULL)
        {
            isr_remove_handler(ISR_DBUG_ISR,(void *)timer[channel].isr);
            timer[channel].isr = NULL;
        }
        timer[channel].tmr = 0;
        timer[channel].trr = 0;
        return TRUE;
    }

    /* Register the Timer Interrupt Service Routine */
    if (timer[channel].isr != NULL)
    {
        isr_remove_handler(ISR_DBUG_ISR, (void *)timer[channel].isr);
        timer[channel].isr = NULL;
    }
    if (isr == NULL)
    {
        isr = (void *)timer_default_isr;
    }

#if (defined(CPU_MCF5307) || defined(CPU_MCF5407) || defined(CPU_MCF5249))

    if (!isr_register_handler(ISR_DBUG_ISR, level, (void *)isr,
                        NULL, (void *)&timer[channel]))
    {
        timer[channel].isr = NULL;
        return FALSE;
    }
#else
    if (!isr_register_handler(ISR_DBUG_ISR, TIMER_VECTOR(channel), (void *)isr,
                        NULL, (void *)&timer[channel]))
    {
        timer[channel].isr = NULL;
        return FALSE;
    }
#endif  

    /* Set the Reference Reached value to the maximum value */
    timer[channel].trr = 0xFFFF;

    /* Calculate TMR value */
    timer[channel].tmr = (MCF_TIMER_DTMR_ORRI
                        | MCF_TIMER_DTMR_CE_NONE
                        | MCF_TIMER_DTMR_OM
                        | MCF_TIMER_DTMR_FRR
                        | MCF_TIMER_DTMR_RST);

    if (period < (1000/sysclock)) 
    {
        period = 1000/sysclock;
        timer[channel].tmr |= (MCF_TIMER_DTMR_CLK_DIV1 
                             | MCF_TIMER_DTMR_PS(0));
    }
    else if (period > (1000 * 256 * 16)/sysclock)
    {
        period = (1000 * 256 * 16)/sysclock;
        timer[channel].tmr |= (MCF_TIMER_DTMR_CLK_DIV16 
                             | MCF_TIMER_DTMR_PS(256));
    }
    else if (period <= (1000 * 256)/sysclock)
    {
        prescale = (uint16)((period * sysclock)/1000);
        timer[channel].tmr |= (MCF_TIMER_DTMR_CLK_DIV1 
                             | MCF_TIMER_DTMR_PS(prescale));
    }
    else /* period <= (1000 * 256 * 16)/sysclock */
    {
        prescale = (uint16)((period * sysclock)/(1000 * 16));
        timer[channel].tmr |= (MCF_TIMER_DTMR_CLK_DIV16 
                             | MCF_TIMER_DTMR_PS(prescale));
    }

    /* Save the Timer settings */
    timer[channel].period = period;
    timer[channel].isr = isr;
    timer[channel].channel = channel;
    timer[channel].level = level;

    return TRUE;
}

/********************************************************************/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -