打印

请教嵌入式Linux下调试温湿度传感器(SHT10)驱动程序碰到问题

[复制链接]
1873|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
chenbo35|  楼主 | 2008-12-15 10:31 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
我的开发平台是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);

相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

3

主题

3

帖子

0

粉丝