设计说明
源码说明
源代码位于 bsp/artinchip/:
bsp/artinchip/drv/pwm/drv_pwm.c,PWM Driver 层实现
bsp/artinchip/hal/pwm/hal_pwm.c,PWM HAL 层实现
bsp/artinchip/include/hal/hal_pwm.h,PWM HAL 层接口头文件
bsp/artinchip/drv/epwm/drv_epwm.c,EPWM Driver 层实现
bsp/artinchip/hal/pwmcs/hal_epwm.c,EPWM HAL 层实现
bsp/artinchip/include/hal/hal_epwm.h,EPWM HAL 层接口头文件
模块架构
PWM/EPWM 驱动 Driver 层采用 RT-Thread 的 PWM 设备驱动框架。HAL 层也可以支持 Baremetal 方式或配合自定义的设备驱动框架进行使用。(下文仅以PWM作为说明,EPWM同理)
关键流程设计
初始化流程
PWM 驱动的初始化接口通过 INIT_DEVICE_EXPORT(drv_pwm_init) 完成,主要是通过调用 PWM子系统的接口 rt_device_pwm_register() 注册一个 PWM设备。
PWM 控制器的初始化过程,主要步骤有:
1.初始化模块的clk
2.初始化模块的默认参数
3.向设备框架中注册PWM设备
数据结构设计
struct aic_pwm_arg
属于 HAL 层接口,记录每一个PWM通道的配置信息:
c
struct aic_pwm_arg {
u16 available;
u16 id;
enum aic_pwm_mode mode;
u32 tb_clk_rate;
u32 freq;
struct aic_pwm_action action0;
struct aic_pwm_action action1;
u32 period;
u32 duty;
s32 def_level;
enum pwm_polarity polarity;
};
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
struct aic_pwm_action
属于 HAL 层接口,记录一组Action的配置信息:
c
struct aic_pwm_action {
enum aic_pwm_action_type CBD;
enum aic_pwm_action_type CBU;
enum aic_pwm_action_type CAD;
enum aic_pwm_action_type CAU;
enum aic_pwm_action_type PRD;
enum aic_pwm_action_type ZRO;
};
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
Driver 层接口设计
以下接口是 PWM 设备驱动框架需要的标准接口。
c
struct rt_pwm_ops
{
rt_err_t (*control)(struct rt_device_pwm *device, int cmd, void *arg);
};
1
2
3
4
2
3
4
drv_pwm_control
函数原型 | rt_err_t drv_pwm_control(struct rt_device_pwm *device, int cmd, void *arg) |
---|---|
功能说明 | (类似ioctl的接口方式)配置一个 PWM 通道 |
参数定义 | device - 指向 PWM 设备的指针 cmd - ioctl 命令码 arg - 命令参数,指向struct rt_pwm_configuration结构的指针 |
返回值 | 0,成功; < 0,失败 |
注意事项 |
HAL 层接口设计
HAL 层的函数接口声明存放在 hal_pwm.h 中,主要接口有:
c
void hal_pwm_ch_init(u32 ch, enum aic_pwm_mode mode, u32 default_level,
struct aic_pwm_action *a0, struct aic_pwm_action *a1);
int hal_pwm_set(u32 ch, u32 duty_ns, u32 period_ns);
int hal_pwm_get(u32 ch, u32 *duty_ns, u32 *period_ns);
int hal_pwm_set_polarity(u32 ch, enum pwm_polarity polarity);
int hal_pwm_enable(u32 ch);
int hal_pwm_disable(u32 ch);
int hal_pwm_init(void);
int hal_pwm_deinit(void);
void hal_pwm_status_show(void);
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
Demo
本Demo实现了通过 PWM 来控制背光的亮度:
c
void turn_on_lcd_backlight(void)
{
struct rt_device_pwm *pwm_dev;
/* turn on the LCD backlight */
pwm_dev = (struct rt_device_pwm *)rt_device_find("pwm");
/* pwm frequency:100K = 10000ns */
rt_pwm_set(pwm_dev, LCD_PWM_DEV_CHANNEL, 10000, 10000);
rt_pwm_enable(pwm_dev, LCD_PWM_DEV_CHANNEL);
}
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10