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