📄 timer_sample.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 + -