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

📄 timer_sample.c

📁 oki67500系列arm工程例程源代码
💻 C
字号:
/**********************************************************************************/
/*                                                                                */
/*    Copyright (C) 2003 Oki Electric Industry Co., LTD.                          */
/*                                                                                */
/*    System Name    :  ML675001 series                                           */
/*    Module Name    :  Simple IRQ and Timer Sample Program                       */
/*    File   Name    :  timer_sample.c                                            */
/*    Revision       :  01.00                                                     */
/*    Date           :  2003/03/09 initial version                                */
/*                                                                                */
/*    Variable 'COUNTER' is incremented by timer interrupt.                       */
/*    Interval  of timer interrupt is 100ms.                                      */
/**********************************************************************************/
#include "ML675001.h"
#include "common.h"
#include "cache.h"

/* type definition */
typedef void IRQ_HANDLER(void); /* type of interrupt handler function */
typedef IRQ_HANDLER *pIRQ_HANDLER;  /* and its pointer */

/* constants */
#define MHz     (1000000L)
#define TMRCYC  (10)      /* interval of TIMER interrupt (ms) */
#define CCLK    (60*MHz)    /* frequency of CCLK */
#define IRQSIZE    (32)     /* size of IRQ handler table */
#define VALUE_OF_TMRLR      /* reload value of timer */\
                ((0x10000L*(16*1000)-((TMRCYC)*(CCLK)))/(16*1000))

#if ((VALUE_OF_TMRLR) < 0 || 0x10000 <= (VALUE_OF_TMRLR))
#error Invalid value : VALUE_OF_TMRLR
#endif

/* functions */
int main(void);                     /* main routine */
static void init_irq(void);         /* initialize IRQ */
static void reg_irq_handler(void);  /* registration of IRQ handler */
static void set_timer(void);        /* setup TIMER */
static void timer_handler(void);    /* TIMER handler */
static void null_handler(void);     /* IRQ handler of unused IRQ number */
extern int get_irq_state(void);     /* this function isn't used in this sample */
__irq void IRQ_Handler(void);       /* IRQ handler (non-reenterant) */
#define call_handler(n) ((IRQ_HANDLER_TABLE[(n)])())

/* global variables */
static pIRQ_HANDLER IRQ_HANDLER_TABLE[IRQSIZE];  /* table of IRQ handler
                                                    if interrupt of interrupt number N
                                                    occurred, function of
                                                    IRQ_HANDLER_TABLE[N]
                                                    is called */
static volatile int COUNTER;    /* 100ms cycle counter */

/****************************************************************************/
/*  Enable IRQ                                                              */
/*  Function : UWORD Irq_en(void)                                           */
/*      Parameters                                                          */
/*          input  : nothing                                                */ 
/*          output : IRQ state before change                                */
/*                   0 : Enable                                             */
/*                   others : Disable                                       */
/*  Note : This function depends on ARM SDT                                 */
/****************************************************************************/
__swi (0x0) UWORD irq_en(void);

/****************************************************************************/
/*  Disable IRQ                                                             */
/*  Function : UWORD irq_dis(void)                                          */
/*      Parameters                                                          */
/*          input  : nothing                                                */ 
/*          output : IRQ state before change                                */
/*                   0 : Enable                                             */
/*                   others : Disable                                       */
/*  Note : This function depends on ARM SDT                                 */
/*         This function is not used in this sample program                 */
/****************************************************************************/
__swi (0x1) UWORD irq_dis(void);

/****************************************************************************/
/*  Entry point                                                             */
/*  Function : main                                                         */
/*      Parameters                                                          */
/*          Input   :   Nothing                                             */
/*          Output  :   0                                                   */
/****************************************************************************/
int main(void)
{

    init_cache();  /* Initialize CACHE memory */
    cache_on(CACHE_BANK0);  /* Bank0 : Cache enable */

    /* initialize IRQ */
    init_irq();

    /* registration of IRQ handler */
    reg_irq_handler();

    /* setup TIMER */
    set_timer();
    
    /* initialize 100ms cycle counter */
    COUNTER = 0;
    
    /* enable IRQ */
    irq_en();

    /* light LED */
    init_led();    /* output mode */
    led_on(LED_START_PATTERN);

    /* timer start */
    put_wvalue(TMEN, 0x01); /* enable timer (write '1' in TMEN[0]) */

    /* infinite loop */
    for(;;)
        ;

    return 0;
}


/*------------------------ functions about TIMER -------------------------------*/

/****************************************************************************/
/*  Setup of timer                                                          */
/*  Function : set_timer                                                    */
/*      Parameters                                                          */
/*          Input   :   Nothing                                             */
/*          Output  :   Nothing                                             */
/****************************************************************************/
void set_timer(void)
{
    put_wvalue(TMEN, 0x0);      /* disable timer (write '0' in TMEN[0])*/
    put_wvalue(TMOVF, 0x01);    /* clear overflow register (write '1' in TMOVF[0])*/
    put_wvalue(TMRLR, VALUE_OF_TMRLR);  /* set TMRLR */

    return;
}

/****************************************************************************/
/*  Timer handler                                                           */
/*  Function : timer_handler                                                */
/*      Parameters                                                          */
/*          Input   :   Nothing                                             */
/*          Output  :   Nothing                                             */
/****************************************************************************/
void timer_handler(void)
{
    COUNTER++;  /* increment 100ms cycle counter */
    put_wvalue(TMOVF, 0x01);    /* clear TMOVF register (write '1' in TMOVF[0])
                                   if TMOVF register isn't cleared,
                                   timer interrupt never occur. */
    return;
}


/*------------------------ functions about IRQ ---------------------------------*/

/****************************************************************************/
/*  Initialize IRQ                                                   */
/*  Function : init_irq                                                     */
/*      Parameters                                                          */
/*          Input   :   Nothing                                             */
/*          Output  :   Nothing                                             */
/*  Note :                                                                  */
/****************************************************************************/
void init_irq(void)
{
    int i;

    /* initialize IRQ registers */
    put_wvalue(ILC0, 0x0);  /* all interrupt levels are 0 */
    put_wvalue(ILC1, 0x0);  /* all interrupt levels are 0 */
    put_wvalue(ILC, 0x0);   /* all interrupt levels are 0 */
    put_wvalue(IRQS, 0x0);  /* cancel sof IRQ */
    put_wvalue(CIL, 0x0FE); /* clear CIL register
                               (write '1' in CIL[n](1<=n<=7)) */

    /* initialize IRQ_HANDLER_TABLE */
    for(i=0; i<IRQSIZE; i++){
        IRQ_HANDLER_TABLE[i] = null_handler;    /* no interrupt handler is
                                                   defined yet */
    }
    
    return;
}

/****************************************************************************/
/*  Registration of IRQ Handler                                             */
/*  Function : reg_irq_handler                                              */
/*      Parameters                                                          */
/*          Input   :   Nothing                                             */
/*          Output  :   Nothing                                             */
/*  Note : Initialization of IRQ needs to be performed before this process. */
/****************************************************************************/
void reg_irq_handler(void)
{
    /***********************************************************
      IRQ handler (timer_handler) is registered into IRQ handler table.
    ***********************************************************/
    IRQ_HANDLER_TABLE[INT_SYSTEM_TIMER] = timer_handler;

    /***********************************************************
      setup of ILC0.
      ILC0 sets interrupt level of IRQ number 0-7.
      ILC0_ILR0 corresponds to IRQ number 0.
      ILC0_ILR1 corresponds to IRQ number 1-3.
      ILC0_ILR4 corresponds to IRQ number 4 and 5.
      ILC0_ILR6 corresponds to IRQ number 6 and 7.
    ***********************************************************/
    set_wbit(ILC0, ILC0_ILR0 & ILC0_INT_LV1); /* interrupt level of
                       ||            ||          IRQ number 0 is set as 1
                   IRQ number  interrupt level  */

    /***********************************************************
      setup of ILC1.
      ILC1 sets interrupt level of IRQ number 8-15.
      ILC1_ILR8 corresponds to IRQ number 8.
      ILC1_ILR9 corresponds to IRQ number 9.
      ILC1_ILR10 corresponds to IRQ number 10.
      ILC1_ILR11 corresponds to IRQ number 11.
      ILC1_ILR12 corresponds to IRQ number 12.
      ILC1_ILR13 corresponds to IRQ number 13.
      ILC1_ILR14 corresponds to IRQ number 14.
      ILC1_ILR15 corresponds to IRQ number 15.
    ***********************************************************/
    /* in this sample ILC1 isn't used */

    /***********************************************************
      setup of ILC.
      ILC sets interrupt level of IRQ number 16-31.
      ILC_ILR16 corresponds to IRQ number 16 and 17.
      ILC_ILR18 corresponds to IRQ number 18 and 19.
      ILC_ILR20 corresponds to IRQ number 20 and 21.
      ILC_ILR22 corresponds to IRQ number 22 and 23.
      ILC_ILR24 corresponds to IRQ number 24 and 25.
      ILC_ILR26 corresponds to IRQ number 26 and 27.
      ILC_ILR28 corresponds to IRQ number 28 and 29.
      ILC_ILR30 corresponds to IRQ number 30 and 31.
    ***********************************************************/
    /* in this sample ILC isn't used */

    /***********************************************************
      setup of IDM.
      IDM sets IRQ detection mode and interrupt level of IRQ number 16-31.
      IDM_IDM16 and IDM_IDMP16 correspond to IRQ number 16 and 17.
      IDM_IDM18 and IDM_IDMP18 correspond to IRQ number 18 and 19.
      IDM_IDM20 and IDM_IDMP20 correspond to IRQ number 20 and 21.
      IDM_IDM22 and IDM_IDMP22 correspond to IRQ number 22 and 23.
      IDM_IDM24 and IDM_IDMP24 correspond to IRQ number 24 and 25.
      IDM_IDM26 and IDM_IDMP26 correspond to IRQ number 26 and 27.
      IDM_IDM28 and IDM_IDMP28 correspond to IRQ number 28 and 29.
      IDM_IDM30 and IDM_IDMP30 correspond to IRQ number 30 and 31.
    ***********************************************************/
    /* in this sample IDM isn't used */

    return;
}

/****************************************************************************/
/*  IRQ handler of unused IRQ number                                        */
/*  Function : null_handler                                                 */
/*      Parameters                                                          */
/*          Input   :   Nothing                                             */
/*          Output  :   Nothing                                             */
/****************************************************************************/
void null_handler(void)
{
    return;
}

/****************************************************************************/
/*  IRQ Handler (Non-Reenterant)                                            */
/*  Function : IRQ_Handler                                                  */
/*      Parameters                                                          */
/*          Input   :   Nothing                                             */
/*          Output  :   Nothing                                             */
/*  Note : This function depends on ARM SDT                                 */
/****************************************************************************/
__irq void IRQ_Handler(void)
{
    UWORD irn;

    irn = get_wvalue(IRN);  /* get IRQ number
                               after reading of the value of IRN register,
                               the bit of CIL register corresponds to
                               an interrupt level is set. */
    if(irn < 32){   /* check IRQ number
                       valid ranges of IRQ are 0-31. */
        call_handler(irn);  /* handler call */
    }
    put_wvalue(CILCL, CILCL_CLEAR); /* clear CIL register
                                       if arbitrary values are written in
                                       CILCL register,
                                       the most significant '1' bit of
                                       CIL register will be cleared. */

//    return;
}

⌨️ 快捷键说明

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