免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3396 | 回复: 2
打印 上一主题 下一主题

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

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-12-15 10:33 |只看该作者 |倒序浏览
我的开发平台是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);

论坛徽章:
0
2 [报告]
发表于 2008-12-16 02:20 |只看该作者
这样看是驱动能力不够啊。
电路没问题吗?
顺便问一下BLOB是什么?

论坛徽章:
0
3 [报告]
发表于 2008-12-16 09:36 |只看该作者
这里的Blob是bootloader的一种吧?

LZ的问题难道,莫非。。。 Linux下设备节点没建立? (应该不是这个问题,呵)
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP