将“龙芯1c库”中硬件定时器相关接口移植到RT-Thread

This commit is contained in:
勤为本 2017-07-18 11:33:27 +08:00
parent d22df879ac
commit 878b222741
2 changed files with 269 additions and 0 deletions

View File

@ -0,0 +1,200 @@
// 硬件定时器源码
#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 ;
}

View File

@ -0,0 +1,69 @@
// 硬件定时器头文件
#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