?? decrmntr.c
字號:
/* @(#) pSOSystem PowerPC/V2.2.2: bsps/devices/powerpc/decrmntr.c 2.30 97/10/06 12:30:59 */
/***********************************************************************/
/* */
/* MODULE: bsps/devices/powerpc/decrmntr.c */
/* DATE: 97/10/06 */
/* PURPOSE: Timer driver for ads, sbc, mbx, gn15, pwrplus and pwrcore*/
/* bsps supplied with pSOSystem. */
/*---------------------------------------------------------------------*/
/* */
/* Copyright 1991 - 1997, Integrated Systems, Inc. */
/* ALL RIGHTS RESERVED */
/* */
/* Permission is hereby granted to licensees of Integrated Systems, */
/* Inc. products to use or abstract this computer program for the */
/* sole purpose of implementing a product based on Integrated */
/* Systems, Inc. products. No other rights to reproduce, use, */
/* or disseminate this computer program, whether in part or in */
/* whole, are granted. */
/* */
/* Integrated Systems, Inc. makes no representation or warranties */
/* with respect to the performance of this computer program, and */
/* specifically disclaims any responsibility for any damages, */
/* special or consequential, connected with the use of this program. */
/* */
/*---------------------------------------------------------------------*/
/* */
/*DESCRIPTION:This file contains the tick timer driver for the */
/* decrementer in the processor and timer chip Intel 82C54. */
/* Selection of one of the two is controlled by defining */
/* DEC_TICK_TIMER. The use of the decrementer alleviates the*/
/* need for the 8254 in the system. */
/* */
/***********************************************************************/
#include "bsp.h"
#include "board.h"
#include <bspfuncs.h>
#include <psos.h>
#include <configs.h>
#include <drv_intf.h>
#include <configs.h>
#include "bsplocal.h"
/*---------------------------------------------------------------------*/
/* General Definitions */
/*---------------------------------------------------------------------*/
/*---------------------------------------------------------------------*/
/* The node anchor address is a pointer to the node configuration */
/* table, which in turn points to the pSOS+ configuration table. This */
/* driver will look in the pSOS+ configuration table to see how many */
/* ticks per second are specified, and thus how many interrupts per */
/* second to generate. */
/*---------------------------------------------------------------------*/
extern NODE_CT *anchor;
/*---------------------------------------------------------------------*/
/* This field indicates if pSOS+ has initialized. */
/*---------------------------------------------------------------------*/
extern ULONG PsosUpFlag;
extern ULONG BoardDecClkRateHz;
/*---------------------------------------------------------------------*/
/* Define function prototypes */
/*---------------------------------------------------------------------*/
void RtcInit(struct ioparms *);
void Delay100ms(void);
void RtcIsr(void);
void DecIsr(void);
/*---------------------------------------------------------------------*/
/* Declarations of external functions & variables */
/*---------------------------------------------------------------------*/
extern void BspInformTick(void);
extern void ppcDECwr(ULONG);
extern ULONG ppcDECrd(void);
extern ULONG ppcDECcalib(void);
extern ULONG ppcTimeBasseRd(ULONG *);
/*---------------------------------------------------------------------*/
/* This flag indicated that the decrementer is being used for counting */
/* a 100 ms interval. */
/*---------------------------------------------------------------------*/
ULONG delay100ms;
/*---------------------------------------------------------------------*/
/* The time constant for the decrmenter is stored here. */
/*---------------------------------------------------------------------*/
ULONG rtcDecTimeConst;
/*---------------------------------------------------------------------*/
/* The decrementer driver should announce a tick to pSOS+ only after */
/* the tick timer has been initialized. */
/*---------------------------------------------------------------------*/
ULONG rtcDecInitDone;
/***********************************************************************/
/* DecIsr: Tick timer ISR. */
/* INPUTS: None */
/* OUTPUTS: None */
/* NOTES: Announces a tick. */
/***********************************************************************/
void DecIsr(void)
{
/*---------------------------------------------------------------------*/
/* If the tick timer has been initialized announce the tick to pSOS+ */
/*---------------------------------------------------------------------*/
if ((rtcDecInitDone != 0) && (PsosUpFlag != 0))
{
tm_tick();
/*------------------------------------------------------------------*/
/* Update the time constant in the decrementer */
/*------------------------------------------------------------------*/
ppcDECadj(rtcDecTimeConst);
/*------------------------------------------------------------------*/
/* Inform the BSP about Tick. So that BSPs can take different */
/* actions depending on the hardware set it has. */
/* This function is in "bspcfg.c" file. */
/*------------------------------------------------------------------*/
BspInformTick();
}
else
{
/*------------------------------------------------------------------*/
/* Update delay flag if it was set. */
/*------------------------------------------------------------------*/
if (delay100ms != 0)
delay100ms = 0;
/*------------------------------------------------------------------*/
/* Write the decrementer with a large value */
/*------------------------------------------------------------------*/
ppcDECwr(0x7FFFFFFF);
}
}
/***********************************************************************/
/* RtcInit: Initialize real time clock. */
/* INPUTS: None */
/* OUTPUTS: None */
/* NOTES: Installs the RTC Interrupt handler in Interrupt Table.*/
/***********************************************************************/
#if DEC_TICK_TIMER
void RtcInit (struct ioparms *p)
{
ULONG s;
ULONG AdjustCount;
/*---------------------------------------------------------------------*/
/* Set the count from pSOS+ configuration table */
/*---------------------------------------------------------------------*/
if (BD_VALIDATE_TICK2SEC) {
p->err = TIMR_TICKRATE;
return;
}
/*---------------------------------------------------------------------*/
/* Get the time constant specific to the board and the CPU installed */
/*---------------------------------------------------------------------*/
rtcDecTimeConst = BoardDecClkRateHz / (anchor->psosct->kc_ticks2sec);
/*---------------------------------------------------------------------*/
/* Time constant adjustment may be necessary because of the overhead */
/* caused by the reading and writing decremneter. */
/*---------------------------------------------------------------------*/
#ifdef BD_RTC_ADJUST_COUNT
AdjustCount = BD_RTC_ADJUST_COUNT; /* user specified adjustment */
#else
AdjustCount = ppcDECcalib(); /* runtime auto adjustment */
#endif
if(rtcDecTimeConst > AdjustCount)
rtcDecTimeConst -= AdjustCount;
/*---------------------------------------------------------------------*/
/* Update the decrementer */
/*---------------------------------------------------------------------*/
ppcDECwr(rtcDecTimeConst);
/*---------------------------------------------------------------------*/
/* Set init flag */
/*---------------------------------------------------------------------*/
rtcDecInitDone = 1;
/*---------------------------------------------------------------------*/
/* Finally, set return values in the I/O driver parameter structure. */
/*---------------------------------------------------------------------*/
p->used = 1;
p->err = 0;
p->out_retval = 0;
}
#endif /* DEC_TICK_TIMER */
#if 0
/***********************************************************************/
/* Delay100ms: Delay for 100ms */
/* INPUTS: None */
/* OUTPUTS: None */
/* NOTES: Provides a delay of 100msec. This routine should be used*/
/* before pSOS has initialized. */
/* */
/***********************************************************************/
#if DEC_TICK_TIMER
void Delay100ms(void)
{
ULONG i;
ULONG count100ms;
/*---------------------------------------------------------------------*/
/* Update delay flag */
/*---------------------------------------------------------------------*/
delay100ms = 1;
count100ms = BoardDecClkRateHz/10;
ppcDECwr(count100ms);
/*---------------------------------------------------------------------*/
/* Poll while the interval elapses */
/*---------------------------------------------------------------------*/
while (delay100ms != 0 && (i = ppcDECrd()) != 0 && i < count100ms);
/*---------------------------------------------------------------------*/
/* Update delay flag */
/*---------------------------------------------------------------------*/
delay100ms = 0;
}
#endif /* DEC_TICK_TIMER */
/***********************************************************************/
/* DelayNms: Delay for Nms */
/* INPUTS: Number of msec to delay for. */
/* OUTPUTS: None */
/* NOTES: Provides a delay of Nmsec. */
/* */
/***********************************************************************/
void DelayNmsec(ULONG msec)
{
register UINT curr_dec, tick_cnt, prev_dec;
register UINT timeout, rollover;
if ((rtcDecInitDone) && (PsosUpFlag))
rollover = rtcDecTimeConst;
else
rollover = 0x7FFFFFFF;
if (!msec)
return;
timeout = (BoardDecClkRateHz / 1000) * msec;
tick_cnt = 0;
for (prev_dec = ppcDECrd();;)
{
curr_dec = ppcDECrd();
if (curr_dec > prev_dec)
tick_cnt += (prev_dec + (rollover - curr_dec));
else
tick_cnt += (prev_dec - curr_dec);
prev_dec = curr_dec;
if (tick_cnt >= timeout)
return;
}
}
#endif /* 0 */
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -