瀏覽代碼

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

勤为本 7 年之前
父節點
當前提交
878b222741
共有 2 個文件被更改,包括 269 次插入0 次删除
  1. 200 0
      bsp/ls1cdev/libraries/ls1c_timer.c
  2. 69 0
      bsp/ls1cdev/libraries/ls1c_timer.h

+ 200 - 0
bsp/ls1cdev/libraries/ls1c_timer.c

@@ -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 ;
+}
+
+

+ 69 - 0
bsp/ls1cdev/libraries/ls1c_timer.h

@@ -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
+