我的开发平台是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(78); 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
",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
"); } //printk("after receive ack
"); if(i){ buf[0]=read_byte(ACK); buf[1]=read_byte(ACK); printk("buf[0]=0x%x
",buf[0]); printk("buf[1]=0x%x
",buf[1]); } else{ buf[2]=read_byte(ACK); buf[3]=read_byte(ACK); printk("buf[2]=0x%x
",buf[2]); printk("buf[3]=0x%x
",buf[3]);
} checksum=read_byte(noACK); //printk("ready to return
"); 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
",error); } else { printk("data correct!
"); } 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
"); if(error!=0) { printk("wrong in measure error==>%d
",error); } else { printk("data correct!
"); } 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
"); return 0; }
static void __exit sht10_exit(void) { misc_deregister(&my_sht10); }
module_init(sht10_init); module_exit(sht10_exit);
|