Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
BaiXuePrincess
rt-thread
提交
d22df879
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看板
提交
d22df879
编写于
7月 18, 2017
作者:
勤
勤为本
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
将“龙芯1c库”中硬件pwm相关接口移植到RT-Thread
上级
09403019
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
274 addition
and
0 deletion
+274
-0
bsp/ls1cdev/libraries/ls1c_pwm.c
bsp/ls1cdev/libraries/ls1c_pwm.c
+197
-0
bsp/ls1cdev/libraries/ls1c_pwm.h
bsp/ls1cdev/libraries/ls1c_pwm.h
+77
-0
未找到文件。
bsp/ls1cdev/libraries/ls1c_pwm.c
0 → 100644
浏览文件 @
d22df879
// 封装硬件pwm接口
#include "ls1c_public.h"
#include "ls1c_pin.h"
#include "ls1c_pwm.h"
#include "ls1c_clock.h"
#include "ls1c_regs.h"
// pwm的最大周期
#define PWM_MAX_PERIOD (0xFFFFFF) // 计数器的值
/*
* 根据gpio获取相应pwm的基地址
* @gpio pwm引脚
* @ret pwm基地址
*/
unsigned
int
pwm_get_reg_base
(
unsigned
int
gpio
)
{
unsigned
int
reg_base
=
0
;
switch
(
gpio
)
{
case
LS1C_PWM0_GPIO06
:
case
LS1C_PWM0_GPIO04
:
reg_base
=
LS1C_REG_BASE_PWM0
;
break
;
case
LS1C_PWM1_GPIO92
:
case
LS1C_PWM1_GPIO05
:
reg_base
=
LS1C_REG_BASE_PWM1
;
break
;
case
LS1C_PWM2_GPIO52
:
case
LS1C_PWM2_GPIO46
:
reg_base
=
LS1C_REG_BASE_PWM2
;
break
;
case
LS1C_PWM3_GPIO47
:
case
LS1C_PWM3_GPIO53
:
reg_base
=
LS1C_REG_BASE_PWM3
;
break
;
}
return
reg_base
;
}
/*
* 禁止pwm
* @pwm_info PWMn的详细信息
*/
void
pwm_disable
(
pwm_info_t
*
pwm_info
)
{
unsigned
int
pwm_reg_base
=
0
;
// 检查入参
if
(
NULL
==
pwm_info
)
{
return
;
}
pwm_reg_base
=
pwm_get_reg_base
(
pwm_info
->
gpio
);
reg_write_32
(
0
,
(
volatile
unsigned
int
*
)(
pwm_reg_base
+
LS1C_PWM_CTRL
));
return
;
}
/*
* 使能PWM
* @pwm_info PWMn的详细信息
*/
void
pwm_enable
(
pwm_info_t
*
pwm_info
)
{
unsigned
int
pwm_reg_base
=
0
;
unsigned
int
ctrl
=
0
;
// 检查入参
if
(
NULL
==
pwm_info
)
{
return
;
}
// 获取基地址
pwm_reg_base
=
pwm_get_reg_base
(
pwm_info
->
gpio
);
// 清零计数器
reg_write_32
(
0
,
(
volatile
unsigned
int
*
)(
pwm_reg_base
+
LS1C_PWM_CNTR
));
// 设置控制寄存器
ctrl
=
(
0
<<
LS1C_PWM_INT_LRC_EN
)
|
(
0
<<
LS1C_PWM_INT_HRC_EN
)
|
(
0
<<
LS1C_PWM_CNTR_RST
)
|
(
0
<<
LS1C_PWM_INT_SR
)
|
(
0
<<
LS1C_PWM_INTEN
)
|
(
0
<<
LS1C_PWM_OE
)
|
(
1
<<
LS1C_PWM_CNT_EN
);
if
(
PWM_MODE_PULSE
==
pwm_info
->
mode
)
// 单脉冲
{
ctrl
|=
(
1
<<
LS1C_PWM_SINGLE
);
}
else
// 连续脉冲
{
ctrl
&=
~
(
1
<<
LS1C_PWM_SINGLE
);
}
reg_write_32
(
ctrl
,
(
volatile
unsigned
int
*
)(
pwm_reg_base
+
LS1C_PWM_CTRL
));
return
;
}
/*
* 初始化PWMn
* @pwm_info PWMn的详细信息
*/
void
pwm_init
(
pwm_info_t
*
pwm_info
)
{
unsigned
int
gpio
;
unsigned
long
pwm_clk
=
0
;
// pwm模块的时钟频率
unsigned
long
tmp
=
0
;
unsigned
int
pwm_reg_base
=
0
;
unsigned
long
period
=
0
;
// 判断入参
if
(
NULL
==
pwm_info
)
{
// 入参非法,则直接返回
return
;
}
gpio
=
pwm_info
->
gpio
;
// 配置相应引脚用作pwm,而非gpio
pin_set_purpose
(
gpio
,
PIN_PURPOSE_OTHER
);
// 复用
switch
(
gpio
)
{
// 不需要复用
case
LS1C_PWM0_GPIO06
:
case
LS1C_PWM1_GPIO92
:
break
;
case
LS1C_PWM0_GPIO04
:
// gpio04的第三复用
pin_set_remap
(
LS1C_PWM0_GPIO04
,
PIN_REMAP_THIRD
);
break
;
case
LS1C_PWM1_GPIO05
:
// gpio05的第三复用
pin_set_remap
(
LS1C_PWM1_GPIO05
,
PIN_REMAP_THIRD
);
break
;
case
LS1C_PWM2_GPIO52
:
// gpio52的第四复用
pin_set_remap
(
LS1C_PWM2_GPIO52
,
PIN_REMAP_FOURTH
);
break
;
case
LS1C_PWM2_GPIO46
:
// gpio46的第四复用
pin_set_remap
(
LS1C_PWM2_GPIO46
,
PIN_REMAP_FOURTH
);
break
;
case
LS1C_PWM3_GPIO47
:
// gpio47的第四复用
pin_set_remap
(
LS1C_PWM3_GPIO47
,
PIN_REMAP_FOURTH
);
break
;
case
LS1C_PWM3_GPIO53
:
// gpio53的第四复用
pin_set_remap
(
LS1C_PWM3_GPIO53
,
PIN_REMAP_FOURTH
);
break
;
default:
break
;
}
// 根据占空比和pwm周期计算寄存器HRC和LRC的值
// 两个64位数相乘,只能得到低32位,linux下却可以得到64位结果,
// 暂不清楚原因,用浮点运算代替
pwm_clk
=
clk_get_apb_rate
();
period
=
(
1
.
0
*
pwm_clk
*
pwm_info
->
period_ns
)
/
1000000000
;
period
=
MIN
(
period
,
PWM_MAX_PERIOD
);
// 限制周期不能超过最大值
tmp
=
period
-
(
period
*
pwm_info
->
duty
);
// 写寄存器HRC和LRC
pwm_reg_base
=
pwm_get_reg_base
(
gpio
);
reg_write_32
(
--
tmp
,
(
volatile
unsigned
int
*
)(
pwm_reg_base
+
LS1C_PWM_HRC
));
reg_write_32
(
--
period
,
(
volatile
unsigned
int
*
)(
pwm_reg_base
+
LS1C_PWM_LRC
));
// 写主计数器
pwm_enable
(
pwm_info
);
return
;
}
bsp/ls1cdev/libraries/ls1c_pwm.h
0 → 100644
浏览文件 @
d22df879
#ifndef __OPENLOONGSON_PWM_H
#define __OPENLOONGSON_PWM_H
// pwm引脚定义
#define LS1C_PWM0_GPIO06 (6) // gpio06用作pwm0
#define LS1C_PWM0_GPIO04 (4) // gpio04复用为pwm0
#define LS1C_PWM1_GPIO92 (92) // gpio92用作pwm1
#define LS1C_PWM1_GPIO05 (5) // gpio05复用为pwm1
#define LS1C_PWM2_GPIO52 (52) // gpio52复用为pwm2
#define LS1C_PWM2_GPIO46 (46) // gpio46复用为pwm2
#define LS1C_PWM3_GPIO47 (47) // gpio47复用为pwm3
#define LS1C_PWM3_GPIO53 (53) // gpio53复用为pwm3
// ...还有一些gpio可以复用为gpio的,有需要可以自己添加
// pwm控制寄存器的每个bit
#define LS1C_PWM_INT_LRC_EN (11) // 低脉冲计数器中断使能
#define LS1C_PWM_INT_HRC_EN (10) // 高脉冲计数器中断使能
#define LS1C_PWM_CNTR_RST (7) // 使能CNTR计数器清零
#define LS1C_PWM_INT_SR (6) // 中断状态位
#define LS1C_PWM_INTEN (5) // 中断使能位
#define LS1C_PWM_SINGLE (4) // 单脉冲控制位
#define LS1C_PWM_OE (3) // 脉冲输出使能
#define LS1C_PWM_CNT_EN (0) // 主计数器使能
// 硬件pwm工作模式
enum
{
// 正常模式--连续输出pwm波形
PWM_MODE_NORMAL
=
0
,
// 单脉冲模式,每次调用只发送一个脉冲,调用间隔必须大于pwm周期
PWM_MODE_PULSE
};
// 硬件pwm信息
typedef
struct
{
unsigned
int
gpio
;
// PWMn所在的gpio
unsigned
int
mode
;
// 工作模式(单脉冲、连续脉冲)
float
duty
;
// pwm的占空比
unsigned
long
period_ns
;
// pwm周期(单位ns)
}
pwm_info_t
;
/*
* 初始化PWMn
* @pwm_info PWMn的详细信息
*/
void
pwm_init
(
pwm_info_t
*
pwm_info
);
/*
* 禁止pwm
* @pwm_info PWMn的详细信息
*/
void
pwm_disable
(
pwm_info_t
*
pwm_info
);
/*
* 使能PWM
* @pwm_info PWMn的详细信息
*/
void
pwm_enable
(
pwm_info_t
*
pwm_info
);
#endif
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录