您的位置:首页 > 其它

SylixOS的BSP开发实例之S3C2416 【第六篇】S3C2416 驱动之定时器

2015-08-14 17:38 381 查看
/*********************************************************************************************************
定时器配置参数
*********************************************************************************************************/
#define TIMER_ENABLE            (1 << 0)                                /*  启动定时器                  */
#define TIMER_DISABLE           (0 << 0)                                /*  停止定时器                  */

#define TIMER_MANUAL_UPDATE     (1 << 1)                                /*  定时器手动重载              */
#define TIMER_UNMANUAL_UPDATE   (0 << 1)                                /*  定时器自动重载              */

#define TIMER_INVERTER          (1 << 2)                                /*  定时器输出翻转              */
#define TIMER_UNINVERTER        (0 << 2)                                /*  定时器输出不翻转            */

#define TIMER_RELOAD            (1 << 3)                                /*  循环计数                    */
#define TIMER_UNRELOAD          (0 << 3)                                /*  单次计数                    */

#define TIMER_DEADZONE          (1 << 4)                                /*  定时器0使用死区             */
#define TIMER_UNDEAD_ZONE       (0 << 4)                                /*  定时器0不使用死区           */


基本操作函数:

/*********************************************************************************************************
** 函数名称: s3c24xxTimerSetPrescaler0
** 功能描述: 设置定时器0 与 定时器1 的预分频因子
** 输    入: ucPrescaler     新的预分频因子
** 输    出: NONE
** 返    回: NONE
*********************************************************************************************************/
void  s3c24xxTimerSetPrescaler0 (unsigned char   ucPrescaler)
{
rTCFG0 &= 0xFFFFFF00;
rTCFG0 |= ucPrescaler;
}
/*********************************************************************************************************
** 函数名称: s3c24xxTimerSetPrescaler1
** 功能描述: 设置定时器2 3 与定时器4 的预分频因子
** 输    入: ucPrescaler     新的预分频因子
** 输    出: NONE
** 返    回: NONE
*********************************************************************************************************/
void  s3c24xxTimerSetPrescaler1 (unsigned char   ucPrescaler)
{
rTCFG0 &= 0xFFFF00FF;
rTCFG0 |= (unsigned int)(ucPrescaler << 8);
}
/*********************************************************************************************************
** 函数名称: s3c24xxTimerSetPrescaler
** 功能描述: 设置定时器2 3 与定时器4 的预分频因子
** 输    入: ucGroup         定时器组,0:定时器0,1   1:定时器 2,3,4
**           ucPrescaler     新的预分频因子
** 输    出: NONE
** 返    回:  0     正确
**           -1     错误
*********************************************************************************************************/
int  s3c24xxTimerSetPrescaler (unsigned char  ucGroup, unsigned char  ucPrescaler)
{
switch (ucGroup) {
case 0:                                                             /*  定时器组 0                  */
s3c24xxTimerSetPrescaler0(ucPrescaler);
break;

case 1:                                                             /*  定时器组 1                  */
s3c24xxTimerSetPrescaler1(ucPrescaler);
break;

default:                                                            /*  定时器组错误                */
return  (-1);
}

return  (0);
}
/*********************************************************************************************************
** 函数名称: s3c24xxTimerSetDeadZone
** 功能描述: 设置 定时器0 的死区
** 输    入: ucDeadZone      死区大小
** 输    出: NONE
** 返    回: NONE
*********************************************************************************************************/
void  s3c24xxTimerSetDeadZone (unsigned char  ucDeadZone)
{
rTCFG0 &= 0xFF00FFFF;
rTCFG0 |= (unsigned int)(ucDeadZone << 16);
}
/*********************************************************************************************************
** 函数名称: s3c24xxTimerSetMuxCnt
** 功能描述: 设置定时器的分频器
** 输    入: ucTimer        定时器
**           ucDivider      分频值
**                          0000 = 1/2  0001 = 1/4 0010 = 1/8
**                          0011 = 1/16 01xx = External TCLKx
** 输    出: NONE
** 返    回:  0     正确
**           -1     错误
*********************************************************************************************************/
int  s3c24xxTimerSetMuxCnt (unsigned char  ucTimer, unsigned char  ucDivider)
{
switch (ucTimer) {
case 0:                                                             /*  定时器 0                    */
rTCFG1 &= 0xFFFFFFF0;
rTCFG1 |= ucDivider;
break;

case 1:                                                             /*  定时器 1                    */
rTCFG1 &= 0xFFFFFF0F;
rTCFG1 |= (ucDivider << 4);
break;

case 2:                                                             /*  定时器 2                    */
rTCFG1 &= 0xFFFFF0FF;
rTCFG1 |= (unsigned int)(ucDivider << 8);
break;

case 3:                                                             /*  定时器 3                    */
rTCFG1 &= 0xFFFF0FFF;
rTCFG1 |= (unsigned int)(ucDivider << 12);
break;

case 4:                                                             /*  定时器 4                    */
rTCFG1 &= 0xFFF0FFFF;
rTCFG1 |= (unsigned int)(ucDivider << 16);
break;

default:                                                            /*  定时器错误                  */
return  (-1);
}

return  (0);
}
/*********************************************************************************************************
** 函数名称: s3c24xxTimerSetDMA
** 功能描述: 设置定时器的 DMA 链接
** 输    入: ucTimer        连接 DMA 的定时器号
**                          0  不连接
**                          1  为 TIMER0 依此类推
** 输    出: NONE
** 返    回:  0     正确
**           -1     错误
*********************************************************************************************************/
int  s3c24xxTimerSetDMA (unsigned char ucTimer)
{
if (ucTimer > 5) {
return  (-1);
}

rTCFG1 &= 0xFF0FFFFF;
rTCFG1 |= (unsigned int)(ucTimer << 20);

return  (0);
}
/*********************************************************************************************************
** 函数名称: s3c24xxTimerConfig
** 功能描述: 设置定时器控制选项
** 输    入: ucTimer        定时器号
**           ucOption       选项
**                          TIMER_xxxx (TIMER_ENABLE TIMER_DISABLE ....)
** 输    出: NONE
** 返    回:  0     正确
**           -1     错误
*********************************************************************************************************/
int  s3c24xxTimerConfig (unsigned char  ucTimer, unsigned char   ucOption)
{
switch (ucTimer) {
case 0:                                                             /*  定时器 0                    */
rTCON &= 0xFFFFFF00;
rTCON |= ucOption;
break;

case 1:                                                             /*  定时器 1                    */
rTCON &= 0xFFFFF0FF;
rTCON |= (unsigned int)(ucOption << 8);
break;

case 2:
4000
/*  定时器 2                    */
rTCON &= 0xFFFF0FFF;
rTCON |= (unsigned int)(ucOption << 12);
break;

case 3:                                                             /*  定时器 3                    */
rTCON &= 0xFFF0FFFF;
rTCON |= (unsigned int)(ucOption << 16);
break;

case 4:                                                             /*  定时器 4                    */
rTCON &= 0xFF0FFFFF;

if (ucOption &  TIMER_RELOAD) {                                 /*  timer4 没有 INVERTER 位     */
ucOption &= 0x07;
ucOption |= TIMER_INVERTER;                                 /*  INVERTER 位 决定 Reload     */
}

rTCON |= (unsigned int)(ucOption << 20);
break;

default:
return  (-1);
}

return  (0);
}
/*********************************************************************************************************
** 函数名称: s3c24xxTimerSetCnt
** 功能描述: 设置定时器初始计数值
** 输    入: ucTimer        定时器号
**           usCnt          计数值
** 输    出: NONE
** 返    回:  0     正确
**           -1     错误
*********************************************************************************************************/
int  s3c24xxTimerSetCnt (unsigned char  ucTimer, unsigned short   usCnt)
{
switch (ucTimer) {
case 0:                                                             /*  定时器 0                    */
rTCNTB0 = usCnt;
break;

case 1:                                                             /*  定时器 1                    */
rTCNTB1 = usCnt;
break;

case 2:                                                             /*  定时器 2                    */
rTCNTB2 = usCnt;
break;

case 3:                                                             /*  定时器 3                    */
rTCNTB3 = usCnt;
break;

case 4:                                                             /*  定时器 4                    */
rTCNTB4 = usCnt;
break;

default:
return  (-1);
}

return   (0);
}
/*********************************************************************************************************
** 函数名称: s3c24xxTimerSetCmp
** 功能描述: 设置定时器比较值
** 输    入: ucTimer        定时器号
**           usCnt          比较值
** 输    出: NONE
** 返    回:  0     正确
**           -1     错误
*********************************************************************************************************/
int  s3c24xxTimerSetCmp (unsigned char  ucTimer, unsigned short   usCnt)
{
switch (ucTimer) {
case 0:                                                             /*  定时器 0                    */
rTCMPB0 = usCnt;
break;

case 1:                                                             /*  定时器 1                    */
rTCMPB1 = usCnt;
break;

case 2:                                                             /*  定时器 2                    */
rTCMPB2 = usCnt;
break;

case 3:                                                             /*  定时器 3                    */
rTCMPB3 = usCnt;
break;

default:                                                            /*  没有定时器 4                */
return  (-1);
}

return   (0);
}
/*********************************************************************************************************
** 函数名称: s3c24xxTimerGetCnt
** 功能描述: 获得定时器计数值
** 输    入: ucTimer        定时器号
** 输    出: NONE
** 返    回: -1         错误
**           OTHERS     计数值
*********************************************************************************************************/
int  s3c24xxTimerGetCnt (unsigned char  ucTimer)
{
switch (ucTimer) {
case 0:                                                             /*  定时器 0                    */
return  (rTCNTO0);

case 1:                                                             /*  定时器 1                    */
return  (rTCNTO1);

case 2:                                                             /*  定时器 2                    */
return  (rTCNTO2);

case 3:                                                             /*  定时器 3                    */
return  (rTCNTO3);

case 4:                                                             /*  定时器 4                    */
return  (rTCNTO4);

default:
return  (-1);
}
}


系统tick应用:
</pre><pre class="cpp" name="code">/*********************************************************************************************************
TICK 服务相关配置
*********************************************************************************************************/
#define TICK_IN_THREAD  0
#if TICK_IN_THREAD > 0
static LW_HANDLE    htKernelTicks;                                      /*  操作系统时钟服务线程句柄    */
#endif                                                                  /*  TICK_IN_THREAD > 0          */
/*********************************************************************************************************
** 函数名称: __tickThread
** 功能描述: 初始化 tick 服务线程
** 输    入: NONE
** 输    出: NONE
** 返    回: NONE
*********************************************************************************************************/
#if TICK_IN_THREAD > 0
static VOID   __tickThread (VOID)
{
for (;;) {
API_ThreadSuspend(htKernelTicks);
API_KernelTicks();                                              /*  内核 TICKS 通知             */
API_TimerHTicks();                                              /*  高速 TIMER TICKS 通知       */
}
}
#endif                                                                  /*  TICK_IN_THREAD > 0          */
/*********************************************************************************************************
** 函数名称: __tickTimer
** 功能描述: tick 定时器中断服务
** 输    入: NONE
** 输    出: NONE
** 返    回: 中断服务返回
*********************************************************************************************************/
static irqreturn_t  __tickTimer (VOID)
{
INTER_CLR_PNDING(BIT_TIMER4);                                       /*  清除中断                    */

API_KernelTicksContext();                                           /*  保存被时钟中断的线程控制块  */
#if TICK_IN_THREAD > 0
API_ThreadResume(htKernelTicks);
#else
API_KernelTicks();                                                  /*  内核 TICKS 通知             */
API_TimerHTicks();                                                  /*  高速 TIMER TICKS 通知       */
#endif                                                                  /*  TICK_IN_THREAD > 0          */

return  (LW_IRQ_HANDLED);
}
/*********************************************************************************************************
精确时间换算参数
*********************************************************************************************************/
static UINT32   GuiFullCnt;
static UINT64   Gui64NSecPerCnt7;                                       /*  提高 7bit 精度              */
/*********************************************************************************************************
** 函数名称: bspTickInit
** 功能描述: 初始化 tick 时钟
** 输    入: NONE
** 输    出: NONE
** 返    回: NONE
*********************************************************************************************************/
VOID  bspTickInit (VOID)
{
#if TICK_IN_THREAD > 0
LW_CLASS_THREADATTR     threakattr;
#endif
GuiFullCnt       = (UINT16)((PCLK / 800) / LW_TICK_HZ);
Gui64NSecPerCnt7 = ((1000 * 1000 * 1000 / LW_TICK_HZ) << 7) / GuiFullCnt;

#if TICK_IN_THREAD > 0
API_ThreadAttrBuild(&threakattr,
(8 * LW_CFG_KB_SIZE),
LW_PRIO_T_TICK,
((LW_OPTION_THREAD_STK_CHK ) |
(LW_OPTION_THREAD_UNSELECT) |
(LW_OPTION_OBJECT_GLOBAL  ) |
(LW_OPTION_THREAD_SAFE    )),
LW_NULL);
htKernelTicks = API_ThreadCreate("t_tick", (PTHREAD_START_ROUTINE)__tickThread, &threakattr, LW_NULL);
#endif                                                                  /*  TICK_IN_THREAD > 0          */

API_InterVectorConnect(LW_IRQ_14,
(PINT_SVR_ROUTINE)__tickTimer,
LW_NULL,
"tick_timer");

s3c24xxTimerSetPrescaler(1, 99);
s3c24xxTimerSetMuxCnt(4, 2);
s3c24xxTimerSetCnt(4, (UINT16)GuiFullCnt);
s3c24xxTimerConfig(4, TIMER_MANUAL_UPDATE);
s3c24xxTimerConfig(4, TIMER_ENABLE | TIMER_RELOAD | TIMER_UNMANUAL_UPDATE);

bspIntVecterEnable(LW_IRQ_14);
}
/*********************************************************************************************************
** 函数名称: bspTickHighResolution
** 功能描述: 修正从最近一次 tick 到当前的精确时间.
** 输    入: ptv       需要修正的时间
** 输    入: NONE
** 输    出: NONE
** 返    回: NONE
*********************************************************************************************************/
VOID  bspTickHighResolution (struct timespec *ptv)
{
REGISTER UINT32  uiCntCur, uiDone;

uiCntCur = (UINT32)s3c24xxTimerGetCnt(4);
uiDone   = GuiFullCnt - uiCntCur;

/*
*  检查是否有 TICK 中断请求
*/
if (rSRCPND1 & BIT_TIMER4) {
/*
*  这里由于 TICK 没有及时更新, 所以需要重新获取并且加上一个 TICK 的时间
*/
uiCntCur = (UINT32)s3c24xxTimerGetCnt(4);
uiDone   = GuiFullCnt - uiCntCur;

if (uiCntCur != 0) {
uiDone   += GuiFullCnt;
}
}

ptv->tv_nsec += (LONG)((Gui64NSecPerCnt7 * uiDone) >> 7);
if (ptv->tv_nsec >= 1000000000) {
ptv->tv_nsec -= 1000000000;
ptv->tv_sec++;
}
}


SylixOS技术讨论群(32537017) SylixOS开发者联盟群(216907470)

系统常用链接:

【1】系统主页  www.sylixos.com

【2】系统百科 
wiki.sylixos.com/index.php/%E9%A6%96%E9%A1%B5

【3】系统下载  git.sylixos.com/cgit/

【4】系统论坛 
bbs.sylixos.com/forum.php

【5】社区新闻 
bbs.sylixos.com/forum.php

【6】清华镜像站点 coop.tuna.tsinghua.edu.cn/git  coop.tuna.tsinghua.edu.cn/git (改版中)

【7】北邮镜像站点(建设中)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息