本文为在用龙芯1c做3D打印机过程中的笔记。龙芯1c做的3d打印机简称“龙印”
3d打印机固件marlin巧妙运用定时器让整个固件不必依赖实时操作系统,即把对实时性要求较高的部分巧妙的用定时器中断来实现了。
marlin固件的原理分析请参考《3D打印机:FPGA+Nios_ii移植Marlin固件二:Marlin固件的详细分析》 http://blog.sina.com.cn/s/blog_679933490102vv8z.html
由此可见定时器中断在marlin中的重要性。这里把龙芯1c的pwm用作定时器,而不输出pwm脉冲,并定时产生中断。不多说了上源码
源码“ls1c_pwm_timer.c”
/*
* drivers\misc\ls1c_pwm_timer.c
* 把龙芯1c的pwm用作定时器,定时产生中断
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/interrupt.h>
#include <linux/err.h>
#include <linux/miscdevice.h>
#include <linux/gpio.h>
#include <linux/ls1c_3dprinter_motor.h>
#include <linux/delay.h>
#include <linux/signal.h>
#include <linux/sched.h>
#include <linux/fs.h>
#include <linux/time.h>
#include <linux/errno.h>
#include <linux/clk.h>
#include <linux/mutex.h>
#include <linux/kfifo.h>
// 定时器默认的定时时间(单位ns)
#define PWM_TIMER_DEF_TIME_NS (1*1000*1000*1000) // 1s
// 寄存器偏移
#define REG_PWM_CNTR 0x00
#define REG_PWM_HRC 0x04
#define REG_PWM_LRC 0x08
#define REG_PWM_CTRL 0x0c
// 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_OE (3) // 脉冲输出使能控制位
#define LS1C_PWM_CNT_EN (0) // CNTR使能位
static void __iomem *pwm_timer_reg_base = NULL; // 映射后的寄存器基地址
static struct workqueue_struct *pwm_timer_queue; // 定时器中断的下半部--工作队列
static struct work_struct pwm_timer_work;
static unsigned long long pwm_timer_clk_rate; // pwm的计数器的时钟频率
static DEFINE_MUTEX(pwm_timer_lock);
// 设置定时器时间
// @period_ns 定时器时间,单位(ns)
static void pwm_timer_set_time(unsigned long period_ns)
{
unsigned long long tmp = 0;
tmp = pwm_timer_clk_rate * period_ns;
do_div(tmp, 1000000000);
writel(tmp, pwm_timer_reg_base+REG_PWM_LRC);
printk(KERN_DEBUG "[%s] pwm_timer_clk_rate=%llu, REG_PWM_LRC's value=%llu\n",
__FUNCTION__,
pwm_timer_clk_rate,
tmp);
return ;
}
static void pwm_timer_enable(void)
{
unsigned int tmp = 0;
tmp = readl(pwm_timer