Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
BaiXuePrincess
rt-thread
提交
878b2227
R
rt-thread
项目概览
BaiXuePrincess
/
rt-thread
与 Fork 源项目一致
Fork自
RT-Thread / rt-thread
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
rt-thread
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
878b2227
编写于
7月 18, 2017
作者:
勤
勤为本
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
将“龙芯1c库”中硬件定时器相关接口移植到RT-Thread
上级
d22df879
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
269 addition
and
0 deletion
+269
-0
bsp/ls1cdev/libraries/ls1c_timer.c
bsp/ls1cdev/libraries/ls1c_timer.c
+200
-0
bsp/ls1cdev/libraries/ls1c_timer.h
bsp/ls1cdev/libraries/ls1c_timer.h
+69
-0
未找到文件。
bsp/ls1cdev/libraries/ls1c_timer.c
0 → 100644
浏览文件 @
878b2227
// 硬件定时器源码
#include "ls1c_public.h"
#include "ls1c_pin.h"
#include "ls1c_clock.h"
#include "ls1c_regs.h"
#include "ls1c_pwm.h"
#include "ls1c_timer.h"
// 定时器中计数器(CNTR、HRC和LRC)的最大值
#define TIMER_COUNTER_MAX (0xffffff)
/*
* 获取指定定时器的寄存器基地址
* @timer 硬件定时器
* @ret 基地址
*/
unsigned
int
timer_get_reg_base
(
ls1c_timer_t
timer
)
{
unsigned
int
reg_base
=
0
;
switch
(
timer
)
{
case
TIMER_PWM0
:
reg_base
=
LS1C_REG_BASE_PWM0
;
break
;
case
TIMER_PWM1
:
reg_base
=
LS1C_REG_BASE_PWM1
;
break
;
case
TIMER_PWM2
:
reg_base
=
LS1C_REG_BASE_PWM2
;
break
;
case
TIMER_PWM3
:
reg_base
=
LS1C_REG_BASE_PWM3
;
break
;
}
return
reg_base
;
}
/*
* 初始化定时器,并开始定时
* @timer_info 定时器和定时时间信息
*/
void
timer_init
(
timer_info_t
*
timer_info
)
{
unsigned
int
timer_reg_base
=
0
;
// 寄存器基地址
unsigned
long
timer_clk
=
0
;
// 硬件定时器的时钟
unsigned
long
tmp
;
unsigned
int
ctrl
=
0
;
// 控制寄存器中的控制信息
// 判断入参
if
(
NULL
==
timer_info
)
{
return
;
}
/*
* 把定时时间换算为计数器的值
* 计数器值 = 定时器的时钟 * 定时时间(单位ns) / 1000000000
* 龙芯1c的定时器时钟为APB时钟,达到126Mhz,
* 为避免计算过程发生溢出,这里采用手动优化上面的计算式,也可以采用浮点运算
*/
timer_clk
=
clk_get_apb_rate
();
tmp
=
(
timer_clk
/
1000000
)
*
(
timer_info
->
time_ns
/
1000
);
// 将1000000000拆分为1000000和1000
tmp
=
MIN
(
tmp
,
TIMER_COUNTER_MAX
);
// 控制寄存器信息
ctrl
=
(
1
<<
LS1C_PWM_INT_LRC_EN
)
|
(
0
<<
LS1C_PWM_INT_HRC_EN
)
|
(
0
<<
LS1C_PWM_CNTR_RST
)
|
(
0
<<
LS1C_PWM_INT_SR
)
|
(
1
<<
LS1C_PWM_INTEN
)
|
(
1
<<
LS1C_PWM_SINGLE
)
|
(
1
<<
LS1C_PWM_OE
)
|
(
1
<<
LS1C_PWM_CNT_EN
);
// 设置各个寄存器
timer_reg_base
=
timer_get_reg_base
(
timer_info
->
timer
);
// 获取寄存器基地址
reg_write_32
(
0
,
(
volatile
unsigned
int
*
)(
timer_reg_base
+
LS1C_PWM_HRC
));
reg_write_32
(
tmp
--
,
(
volatile
unsigned
int
*
)(
timer_reg_base
+
LS1C_PWM_LRC
));
reg_write_32
(
0
,
(
volatile
unsigned
int
*
)(
timer_reg_base
+
LS1C_PWM_CNTR
));
reg_write_32
(
ctrl
,
(
volatile
unsigned
int
*
)(
timer_reg_base
+
LS1C_PWM_CTRL
));
return
;
}
/*
* 判断指定定时器是否超时(实现定时)
* @timer_info 定时器
* @ret TRUE or FALSE
*/
BOOL
timer_is_time_out
(
timer_info_t
*
timer_info
)
{
unsigned
int
timer_reg_base
=
0
;
// 寄存器基地址
unsigned
int
ctrl
;
// 控制寄存器的值
// 判断入参
if
(
NULL
==
timer_info
)
{
return
FALSE
;
}
// 读取控制寄存器
timer_reg_base
=
timer_get_reg_base
(
timer_info
->
timer
);
ctrl
=
reg_read_32
((
volatile
unsigned
int
*
)(
timer_reg_base
+
LS1C_PWM_CTRL
));
// 判断中断状态位
if
(
ctrl
&
(
1
<<
LS1C_PWM_INT_SR
))
{
return
TRUE
;
}
else
{
return
FALSE
;
}
}
/*
* 停止定时器
* @timer_info 定时器
*/
void
timer_stop
(
timer_info_t
*
timer_info
)
{
unsigned
int
timer_reg_base
=
0
;
// 判断入参
if
(
NULL
==
timer_info
)
{
return
;
}
timer_reg_base
=
timer_get_reg_base
(
timer_info
->
timer
);
reg_write_32
(
0
,
(
volatile
unsigned
int
*
)(
timer_reg_base
+
LS1C_PWM_CTRL
));
return
;
}
/*
* 获取定时器从初始化到现在的时间(实现计时功能),单位ns
* @timer_info 硬件定时器
* @ret 时间,单位ns
*/
unsigned
long
timer_get_time_ns
(
timer_info_t
*
timer_info
)
{
unsigned
int
timer_reg_base
=
0
;
unsigned
int
cntr
=
0
;
// 寄存器CNTR的值
unsigned
long
time_ns
=
0
;
// 时间,单位ns
unsigned
long
timer_clk
=
0
;
// 定时器时钟
// 读取寄存器CNTR的值
timer_reg_base
=
timer_get_reg_base
(
timer_info
->
timer
);
cntr
=
reg_read_32
((
volatile
unsigned
int
*
)(
timer_reg_base
+
LS1C_PWM_CNTR
));
/*
* 将CNTR值换算为时间,单位us
* 时间 = (计数器值CNTR * 1000000000) / 定时器时钟频率
* 为避免产生溢出,手动优化上式为 时间 = (计数器值CNTR * 1000) / (定时器时钟频率 / 1000000)
*/
timer_clk
=
clk_get_apb_rate
();
time_ns
=
(
cntr
*
1000
)
/
(
timer_clk
/
1000000
);
// myprintf("[%s] time_us=%lu, cntr=%d, timer_clk=%d\n", __FUNCTION__, time_ns, cntr, timer_clk);
return
time_ns
;
}
/*
* 打印timer相关寄存器的值
* @timer_info 硬件定时器
*/
void
timer_print_regs
(
timer_info_t
*
timer_info
)
{
unsigned
int
timer_reg_base
=
0
;
timer_reg_base
=
timer_get_reg_base
(
timer_info
->
timer
);
myprintf
(
"CNTR=0x%x, HRC=0x%x, LRC=0x%x, CTRL=0x%x
\n
"
,
reg_read_32
((
volatile
unsigned
int
*
)(
timer_reg_base
+
LS1C_PWM_CNTR
)),
reg_read_32
((
volatile
unsigned
int
*
)(
timer_reg_base
+
LS1C_PWM_HRC
)),
reg_read_32
((
volatile
unsigned
int
*
)(
timer_reg_base
+
LS1C_PWM_LRC
)),
reg_read_32
((
volatile
unsigned
int
*
)(
timer_reg_base
+
LS1C_PWM_CTRL
)));
return
;
}
bsp/ls1cdev/libraries/ls1c_timer.h
0 → 100644
浏览文件 @
878b2227
// 硬件定时器头文件
#ifndef __OPENLOONGSON_TIMER_H
#define __OPENLOONGSON_TIMER_H
#include "ls1c_public.h"
// 硬件定时器
typedef
enum
{
TIMER_PWM0
,
// PWM0用作硬件定时器
TIMER_PWM1
,
// PWM1用作硬件定时器
TIMER_PWM2
,
// PWM2用作硬件定时器
TIMER_PWM3
// PWM3用作硬件定时器
}
ls1c_timer_t
;
// 硬件定时器信息
typedef
struct
{
ls1c_timer_t
timer
;
// 硬件定时器
unsigned
long
time_ns
;
// 定时时间
}
timer_info_t
;
/*
* 初始化定时器,并开始定时
* @timer_info 定时器和定时时间信息
*/
void
timer_init
(
timer_info_t
*
timer_info
);
/*
* 判断指定定时器是否超时
* @timer_info 定时器
* @ret TRUE or FALSE
*/
BOOL
timer_is_time_out
(
timer_info_t
*
timer_info
);
/*
* 停止定时器
* @timer_info 定时器
*/
void
timer_stop
(
timer_info_t
*
timer_info
);
/*
* 获取定时器从初始化到现在的时间(实现计时功能),单位ns
* @timer_info 硬件定时器
* @ret 时间,单位ns
*/
unsigned
long
timer_get_time_ns
(
timer_info_t
*
timer_info
);
/*
* 打印timer相关寄存器的值
* @timer_info 硬件定时器
*/
void
timer_print_regs
(
timer_info_t
*
timer_info
);
#endif
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录