📄 kzcpmtimer.c
字号:
/******************************************************/
/* Filename: KzCpmTimer.c */
/* author : hyf */
/* copyright: kztech */
/* date : 2005.09.09 */
/******************************************************/
#include "vxworks.h"
#include "arch/ppc/vxPpcLib.h"
#include "intLib.h"
#include "drv/intrctl/ppc860intr.h"
#include "drv/multi/ppc860Cpm.h"
#include "drv/multi/ppc860Siu.h"
#include "config.h"
#include "semLib.h"
#include "msgQLib.h"
#include "iv.h"
#include "ads860.h"
#include "Limits.h"
#include "taskLib.h"
#include "KzCpmTimer.h"
#include "typedef.h"
#include "bsp.h"
#include "drv/multi/ppc860cpm.h"
#include "drv/multi/ppc860Siu.h"
_U32 RunLedStatus = LED_OFF,RunLedLightPeriod = 100,RunLedBlackPeriod = 0xffffffff;
_U32 AlarmLedStatus = LED_OFF,AlarmLedLightPeriod = 100,AlarmLedBlackPeriod = 0xffffffff;
_U32 ulRunLedLightCnt = 1;
void Drv_LedCtrl(_U32 LedNum, _U32 LedOnOff);
extern STATUS intConnect (VOIDFUNCPTR *vector, VOIDFUNCPTR routine,
int parameter);
#define CPM_MEM_BASE INTERNAL_MEM_MAP_ADDR
#define SYS_CLK_FATOR SYS_CPU_FREQ /1000000
LOCAL FUNCPTR sysAuxClk4Routine = NULL;
LOCAL int sysAuxClk4Arg = NULL;
LOCAL BOOL sysAuxClk4Running = FALSE;
LOCAL BOOL sysAuxClk4IntConnected = FALSE;
LOCAL int sysAuxClk4TicksPerSecond= 500;/*2ms一个CPM时钟中断*/
LOCAL int cpmTimer4CountUp = 0;
LOCAL int sysAuxClk4PsValue = 100;
LOCAL int CpmTime4IntPeriod = 2000;
SEM_ID CpmTimersemId;
MSG_Q_ID CpmTimerMsgQId;
void testTimerTask(void)
{
/*CpmTimersemId= semMCreate (SEM_Q_PRIORITY);*/
CpmTimerMsgQId = msgQCreate (20, 10, MSG_Q_FIFO);
if(CpmTimerMsgQId == NULL)
{
/*Drv_Print("create msg_q failed\r\n");*/
return;
}
taskSpawn("tTimerTask", 5, 0, 20000, (FUNCPTR)routineByCpmTimer, 0,0,0, 0,0,0,0,0,0,0);
}
/*test for count*/
void routineByCpmTimer(void)
{
char data[5];
int len=0;
while(1)
{
/*semTake(CpmTimersemId, WAIT_FOREVER);*/
len = msgQReceive(CpmTimerMsgQId, data,5, WAIT_FOREVER);
if(len >0)
{
/*Drv_Print("interrupt is on\r\n");*/
len =0;
}
taskDelay(1);
}
}
STATUS sysAuxClk4init(FUNCPTR routine,int arg ,int ticksPerSecond , UINT8 ps)
{
sysAuxClk4Connect(routine,arg);
sysAuxClk4RateSet(ticksPerSecond,ps);
/*如果辅助时钟已经在运行*/
if(sysAuxClk4Running)
{
/*禁止辅助时钟*/
sysAuxClk4Disable();
}
/*使能辅助时钟*/
sysAuxClk4Enable(ps);
return (OK);
}
STATUS sysAuxClk4Connect(FUNCPTR routine,int arg)
{
/* 传递函数入口到全局变量:sysAuxClk4Routine */
sysAuxClk4Routine = routine;
/* 传递入口函数参数到全局变量:sysAuxClk4Arg */
sysAuxClk4Arg = arg;
return (OK);
}
void sysAuxClk4Int (void)
{
/*char data[5];*/
/*1。 清除辅助时钟事件寄存器*/
*TER4(CPM_MEM_BASE) |= TER_REF;
/* 2。清除cpm中断服务寄存器的相应定时器的服务位*/
*CISR(CPM_MEM_BASE) = CISR_TIMER4;
/*3。判断中断入口函数是否存在*/
/*存在,进入调用处理*/
if(sysAuxClk4Routine != NULL)
(*sysAuxClk4Routine) (sysAuxClk4Arg);
#if 0
/*4。更新自定义时钟counter*/
cpmTimer4CountUp ++; /*全局变量*/
if(cpmTimer4CountUp % 4000 == 0) /*每2ms一次中断, 8s循环一次*/
{
cpmTimer4CountUp = 0;
/*semGive(CpmTimersemId);*/
data[0]='1';
data[1]='2';
data[2]='3';
data[3]='4';
data[4]='\0';
msgQSend(CpmTimerMsgQId,data,5, NO_WAIT, MSG_PRI_NORMAL);
/*Drv_Print("1\r\n");*/
}
/*5。Give 信号量给封装/解封模块,信号量定义和创建在封装/解封模块*/
#endif
}
void sysAuxClk4Disable (void)
{
/*1。判断辅助时钟的运行标志,检测中断处理程序是否运行*/
if (sysAuxClk4Running)
{
/*如果运行*/
/*2。 设置cpm中断屏蔽寄存器timer4 位,禁止中断*/
*CIMR(CPM_MEM_BASE) &= ~CISR_TIMER4;
/*3。设置timer 的控制寄存器timer4位,停止timer4*/
*TGCR(CPM_MEM_BASE) |= TGCR_STP4;
/* 4。设置辅助时钟的运行标志:FALSE */
sysAuxClk4Running = FALSE;
}
}
void sysAuxClk4Enable(UINT8 ps)
{
UINT32 tempDiv = 0;
UINT16 pstemp=0;
pstemp = (ps&0xff) << 8;
/*1。根据输入的ps,计算定时器的计数上限*/
tempDiv=(SYS_CPU_FREQ / ((UINT32)sysAuxClk4TicksPerSecond *(ps & 0xff)));
/*2。设置timer的控制寄存器,初始化timer*/
if((!sysAuxClk4Running) && (tempDiv <= USHRT_MAX * 16))
{
/*3。设置timer 控制寄存器:设置timer 的启动和复位位,同时不使能*/
*TGCR(CPM_MEM_BASE) &= ~(TGCR_RST4 | TGCR_STP4);
/*4。设置timer 计数寄存器,从0开始计数*/
*TCN4(CPM_MEM_BASE) = 0x0;
/*5。判断计数上限值是否过大,配置timer的参考寄存器和timer的模式寄存器的*/
if(tempDiv <= USHRT_MAX)
{
/*如果计数上限值有效,设置定时器的参考寄存器,设置计数上限*/
*TRR4(CPM_MEM_BASE) = (UINT16) tempDiv;
/*按照iclk的不同的配置方案,设置不同的timer的模式寄存器的值
TMR_ICLK_IN_GEN : 内部通用系统时钟
TMR_ICLK_IN_GEN_DIV16:内部16分频的系统时钟
TMR_ORI: Output Reference Interrupt Enable
TMR_FRR: Free Run/Restart
*/
/*设置定时器的模式寄存器*/
*TMR4(CPM_MEM_BASE) = (TMR_ICLK_IN_GEN | TMR_ORI | TMR_FRR | (TMR_PS_MSK & pstemp));
}
else /*如果值溢出*/
{
/*重新定时器的参考寄存器,设置计数上限值:缩小16倍*/
*TRR4(CPM_MEM_BASE) = (UINT16) (tempDiv /16);
/*设置定时器的模式寄存器*/
*TMR4(CPM_MEM_BASE) = (TMR_ICLK_IN_GEN_DIV16 | TMR_ORI |TMR_FRR | (TMR_PS_MSK & pstemp));
}
/*6。 清除timer的事件寄存器*/
*TER4(CPM_MEM_BASE) = 0xffff;
/*7。设置timer的中断位,启动中断*/
*CIMR(CPM_MEM_BASE) |= CISR_TIMER4;
/*8。连接中断服务程序*/
if (! sysAuxClk4IntConnected)
{
(void)intConnect ((VOIDFUNCPTR *)IV_TIMER4, (VOIDFUNCPTR) sysAuxClk4Int, NULL);
/*设置辅助时钟的中断程序的连接标志:TRUE */
sysAuxClk4IntConnected = TRUE;
}
/*9。设置timer的配置寄存器,使能timer */
*TGCR(CPM_MEM_BASE) |= TGCR_RST4;
/*10。设置辅助时钟的运行标志:TRUE */
sysAuxClk4Running = TRUE;
}
}
STATUS sysAuxClk4RateSet(int ticksPerSecond, UINT8 ps)
{
/*1。判断输入的ticksPerSecond是否合法 */
if (ticksPerSecond < AUX_CLK_RATE_MIN || ticksPerSecond > AUX_CLK_RATE_MAX)
return (ERROR);
/*2。传递ticksPerSecond 给全局变量:sysAuxClkTicksPerSecond */
sysAuxClk4TicksPerSecond = ticksPerSecond;
sysAuxClk4PsValue = ps;
/*如果辅助时钟已经在运行*/
if (sysAuxClk4Running)
{
/*3。禁止辅助时钟*/
sysAuxClk4Disable();
/*4。使能辅助时钟*/
sysAuxClk4Enable(ps);
}
return (OK);
}
int sysAuxClk4RateGet (void)
{
/*返回sysAuxClk4TicksPerSecond */
return (sysAuxClk4TicksPerSecond);
}
int cpmTimeGet(void)
{
UINT32 currentTime;
UINT16 countInTimer = 0;
UINT16 divlevel = 100;
/*CPM timer is count up register*/
countInTimer=*(TCN4(CPM_MEM_BASE));
divlevel = (*TMR4(CPM_MEM_BASE) & TMR_PS_MSK) >> 8;
/*Drv_Print("divlevel=%d\r\n",divlevel);*/
/*small scale + large scale*/
currentTime = countInTimer* divlevel /(SYS_CLK_FATOR) + cpmTimer4CountUp * CpmTime4IntPeriod;
/*Drv_Print("currentTime=%d\r\n",currentTime);*/
return currentTime;
}
void Led_Flash(void)
{
ulRunLedLightCnt++;
if (ulRunLedLightCnt%RunLedLightPeriod == 0)
{
Drv_LedCtrl(LED_RUN,LED_OFF);
RunLedStatus =LED_OFF;
}
if (ulRunLedLightCnt%(RunLedLightPeriod+55) == 0)
{
Drv_LedCtrl(LED_RUN,LED_ON);
RunLedStatus =LED_ON;
}
}
void Drv_LedCtrl(_U32 LedNum, _U32 LedOnOff)
{
if ((LED_RUN != LedNum)&&(LED_ALARM != LedNum)&&(LED_ALL != LedNum))
return;
if (LED_ON == LedOnOff)
{
*PCDAT(INTERNAL_MEM_MAP_ADDR) &= ~LedNum;
}
else if (LED_OFF == LedOnOff)
{
*PCDAT(INTERNAL_MEM_MAP_ADDR) |= LedNum;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -