写一个QEP的驱动
需要直接操作寄存器,板子是cortexA9 linux内核4.1.18
部分代码如下:
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <asm/io.h>
#include <asm/uaccess.h>
static int major = 231;
static int minor=0;
static dev_t devno;
static struct class *cls;
static struct device *test_device;
static unsigned char* ctrl_conf_gpmcad12;
static unsigned char* soc_pwmss2_reg;
static unsigned char* pwmssBaseAddr;
static unsigned char* pwmssBaseAddr2;
static unsigned char * pwmssBaseAddr3;
static unsigned char * ctrl_clock;
static int demo_buffer[2];
//引脚复用 qep2 引脚
#define CTRL_CONF_GPMC_AD12 0x44E10830//eQEP2A_IN
#define AD12 0x0000 //eQEP2A_IN
#define AD13 0x0004 //eQEP2B_IN
#define AD14 0x0008 // eQEP2_INDEX
#define AD15 0x000c //eQEP2_STROBE
#define SOC_PWMSS2_REG 0x48304000//PWMSS的物理地址(图三)
#define PWMSS_CLKCONFIG 0x0008//(图一)
0
#define PWMSS2BASE 0x48304180 //PWMSS_EQEP的c物理地址(图三)
#define EQEP_QPOSCNT 0x0 //(图二)
#define EQEP_QPOSMAX 0x8 //(图二)
#define EQEP_QUPRD 0x20 //(图二)
#define PWMSS2BASE2 0x483041A0
#define EQEP_QDECCTL 0x08//eQEP Decoder Control
#define EQEP_QEPCTL 0x0A //eQEP Control
#define EQEP_QCAPCTL 0x0C//eQEP Capture Control
#define PWMSS2BASE3 0x483041B0
#define EQEP_QEPSTS 0x08//eQEP Status
#define CONTROL_MODULE_CTRL_PWMSS 0x44E10664
#define CTRL_PWMSS 0x0000
static void fs4412_qep_init(void)
{
//管脚寄存器映射 4个寄存器
ctrl_conf_gpmcad12 = ioremap(CTRL_CONF_GPMC_AD12,16);
soc_pwmss2_reg = ioremap(SOC_PWMSS2_REG,16);
pwmssBaseAddr = ioremap(PWMSS2BASE,40);
pwmssBaseAddr2= ioremap(PWMSS2BASE2,20);
pwmssBaseAddr3 = ioremap(PWMSS2BASE3,12);
//时钟寄存器映射
ctrl_clock= ioremap(CONTROL_MODULE_CTRL_PWMSS,4);
//-----------------------------------------------------------------------------------------
//管脚配置
printk("%x",readw(pwmssBaseAddr2 + EQEP_QDECCTL));
readl(ctrl_conf_gpmcad12 + AD13);
readl(soc_pwmss2_reg + PWMSS_CLKCONFIG);
..............
}
每次一到最后一行就是Segementation Fault…
原因可能是soc_pwmss2_reg的指针类型错误?还是指针越界?还是ioremap错误?
这是datasheet相关…
图1 这个是soc_pwmss2_reg的寄存器偏移地址,用到了CLKCONFIG寄存器
图2 这个是pwmssBaseAddr /pwmssBaseAddr2 /pwmssBaseAddr3的寄存器偏移
主要用到了QDECCTL QEPCTL QCAPCTL QEPSTS 四个寄存器
图3 基地址