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】北邮镜像站点(建设中)
相关文章推荐
- SylixOS的BSP开发实例之S3C2416 【第五篇】S3C2416 启动模式之 NandFlash
- SylixOS的BSP开发实例之S3C2416 【第三篇】S3C2416 寄存器描述
- SylixOS优先级与POSIX优先级关系
- SylixOS的BSP开发实例之S3C2416 【第二篇】内存映射与初始布局
- SylixOS的BSP开发实例之S3C2416【前言】常用软件介绍
- S3C2416移植内核linux2.6.35步骤和错误,文件系统挂载不上?
- SylixOS x86中断探测(二)
- SylixOS 常用shell指令
- SylixOS功能点介绍
- SylixOS Lite版本中断优先级设置
- SylixOS 下内核线程简介
- SylixOS下基于Zynq-7000加载FPGA程序
- SylixOS中select原理及使用分析
- SylixOS下kill 15信号问题分析
- 移植Eigen库到SylixOS下及使用方法
- sylixos标准工程移植到Lite版本
- SylixOS定时器测试误差分析
- SylixOS在ZYNQ7000上划分CACHE
- SylixOS的RMS浅析
- SylixOS实时以太网浅析