- 论坛徽章:
- 0
|
我的开发平台是pxa310,通过在驱动程序中模拟GPIO来读取SHT10的温湿度数据,Linux内核2.6.在驱动程序中没有读到SHT10的应答信号,发送命令以后SHT10 DATA引脚没有被拉低.示波器上面看到在SCK第8个下降沿跳低,在第9个SCK下降沿跳高,但是电平就跳低到2.3V,没有跳低到0.8V以下,后面的数据也没有读出来.但是我将这段程序移植到BLOB下面,不改变时序,只换用BLOB下对GPIO控制的接口函数,倒可以把数据读出来,而且数据正常, 不知道是什么问题想请教一下.中间重新编译过内核,和这个会有关吗?下面是我的驱动程序
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/miscdevice.h>
#include <linux/delay.h>
#include <linux/spinlock.h>
#include <linux/fs.h>
#include <linux/ioctl.h>
#include <linux/completion.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <asm/arch/pxa3xx_gpio.h>
#include <asm/arch/pxa-regs.h>
#include <asm/arch/mfp.h>
#include <asm/uaccess.h>
#define DEVICE_NAME "sht10"
#define noACK 0
#define ACK 1
#define MEASURE_TEMP 0x03
#define MEASURE_HUMI 0x05
#define MEASURE_REGI 0x07
#define MEASURE_RESET 0x1e
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
#define OSCC_REG 0x41350000
/*static sht10_do_tasklet(void);
DECLARE_TASKLET(sht10_tasklet,sht10_do_tasklet,0);
DECLARE_COMPLETION(comp);
*/
enum {TEMP,HUMI,REGI};
unsigned char buf[4]={0};
static void delay(void)
{
unsigned int i;
for(i=0;i<2000;i++);
// mdelay(10);
}
static void port_init(void)
{
pxa3xx_gpio_set_direction(79,1);
pxa3xx_gpio_set_direction(78,1);
}
static void data_output(void)
{
pxa3xx_gpio_set_direction(78,1);
}
static void data_input(void)
{
pxa3xx_gpio_set_direction(78,0);
}
static void set_sck(void)
{
pxa3xx_gpio_set_level(79,1);
}
static void clear_sck(void)
{
pxa3xx_gpio_set_level(79,0);
}
static void set_data(void)
{
pxa3xx_gpio_set_level(78,1);
}
static void clear_data(void)
{
pxa3xx_gpio_set_level(78,0);
}
static int read_data(void)
{
int level=0;
pxa3xx_gpio_set_direction(78,0);
level=pxa3xx_gpio_get_level(7 ;
pxa3xx_gpio_set_direction(78,1);
return level;
}
static void start_trans(void)
{
set_data();clear_sck();
delay();
set_sck();
delay();
clear_data();
delay();
clear_sck();
clear_sck();
clear_sck();
delay();delay();
delay();delay();
set_sck();
delay();
set_data();
delay();
clear_sck();
}
static void reset_sht10(void)
{
unsigned char i;
set_data();
clear_sck();
for(i=0;i<9;i++)
{
set_sck();
delay();
clear_sck();
delay();
}
start_trans();
}
static char write_byte(unsigned char value)
{
unsigned char i,error=0;
for(i=0x80;i>0;i>>=1)
{
if(i & value)
{
set_data();
}
else
{
clear_data();
}
set_sck();
delay();//delay();
clear_sck();
// delay();
}
//delay();
set_data();
set_sck();
error=read_data();
//printk("write byte read error=0x%x\n",error);
delay();delay();delay();
clear_sck();
return error;
}
static char read_byte(unsigned char ack)
{
unsigned char i,val=0;
set_data();
for(i=0x80;i>0;i/=2)
{
set_sck();
delay();
if(read_data()){
val=(val|i);
}
// delay();//delay();delay();
clear_sck();
delay();
}
//data_output();
delay();
if(ack==1){
clear_data();
}else{
set_data();
}
delay();//delay();delay();
set_sck();
delay();delay();delay();
clear_sck();
delay();//delay();delay();
set_data();
return val;
}
static int measure_sht10(unsigned char checksum,unsigned char mode)
{
unsigned char error=0;
unsigned int i=0;
start_trans();
switch(mode)
{
case TEMP:error+=write_byte(MEASURE_TEMP);i=1;break;
case HUMI:error+=write_byte(MEASURE_HUMI);break;
default:break;
}
while(1)
{
if(read_data()==0) break;
}
if(read_data())
{
error+=1;
printk("time out high level error+1\n" ;
}
//printk("after receive ack\n" ;
if(i){
buf[0]=read_byte(ACK);
buf[1]=read_byte(ACK);
printk("buf[0]=0x%x\n",buf[0]);
printk("buf[1]=0x%x\n",buf[1]);
}
else{
buf[2]=read_byte(ACK);
buf[3]=read_byte(ACK);
printk("buf[2]=0x%x\n",buf[2]);
printk("buf[3]=0x%x\n",buf[3]);
}
checksum=read_byte(noACK);
//printk("ready to return\n" ;
return error;
}
/*static int sht10_do_tasklet(void)
{
unsigned int error=0;
unsigned char checksum=0;
error+=measure_sht10(checksum,TEMP); //measure the temperature
error+=measure_sht10(checksum,HUMI); //measure the humidity
//error+=measure_sht10(checksum,REGI); //measure the humidity
complete(&comp);
if(error!=0)
{
printk("wrong in measure error==>%d\n",error);
}
else
{
printk("data correct!\n" ;
}
return error;
}*/
static ssize_t sht10_read(struct file *file,char *buffer,size_t count,loff_t *offp)
{
unsigned int error=0;
unsigned char checksum=0;
port_init();
reset_sht10();
error+=measure_sht10(checksum,TEMP); //measure the temperature
error+=measure_sht10(checksum,HUMI); //measure the humidity
// tasklet_schedule(&sht10_tasklet);
// wait_for_completion(&comp);
copy_to_user(buffer,(char *)&buf,sizeof(buf));
// return 0;
//printk("after copy to user\n" ;
if(error!=0)
{
printk("wrong in measure error==>%d\n",error);
}
else
{
printk("data correct!\n" ;
}
return error;
}
static struct file_operations sht10_fops = {
owner: THIS_MODULE,
read: sht10_read,
};
static struct miscdevice my_sht10 ={
.minor=4,
.name="sht10",
.fops=&sht10_fops,
};
struct pxa3xx_pin_config littleton_sensor_pins[] = {
PXA3xx_MFP_CFG("SENSOR_DATA", MFP_PIN_GPIO78, MFP_AF0, MFP_DS10X, 0, MFP_LPM_PULL_NEITHER,MFP_EDGE_NONE),
PXA3xx_MFP_CFG("SENSOR_SCK", MFP_PIN_GPIO79, MFP_AF0, MFP_DS10X, 0, MFP_LPM_PULL_NEITHER,MFP_EDGE_NONE),
};
void pxa3xx_enable_sensor_pins(void)
{
pxa3xx_mfp_set_configs(littleton_sensor_pins,ARRAY_SIZE(littleton_sensor_pins));
}
static int __init sht10_init(void)
{
misc_register(&my_sht10);
pxa3xx_enable_sensor_pins();
printk(DEVICE_NAME " initialized\n" ;
return 0;
}
static void __exit sht10_exit(void)
{
misc_deregister(&my_sht10);
}
module_init(sht10_init);
module_exit(sht10_exit); |
|