打印
[嵌入式linux]

上网down了个SPI接口AD芯片驱动,感觉有点头大

[复制链接]
4136|10
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
tiger84|  楼主 | 2010-3-10 08:58 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
//(1)Init_SPI()完成SPI的初始化
void Init_SPI(void)
{
    int i;
    rSPPRE0=0x32;
    rSPCON0=0x1e;
    for(i=0;i<10;i++)
    {
        rSPTDAT0=0xff;
    }
   
    rGPECON |=0x0a800000;
    rGPECON&=(~0x05400000);
    rGPEUP |=0x3800;
    //GPH5----->CS
    rGPHCON |=0x0400;
    rGPHCON&=(~0x0800);
    rGPHUP&=(~0x20);
    rGPHDAT |=0x20;
}
//(2)ad_wr()写入要求A/D转换的通道
static ssize_t ad_wr(struCt file *file,const char *bur,size_t count,loft_t *offset)
{
    int ret;
    int i;
    ret = 0;
    i = 0;   
    dbuf="kmalloc"(count *sizeof(unsigned char),GFP_KERNEL);
    copy_from_user(dbuf,bur,count);
    for(i = 0; i < count; i++)
    {
        ADTXdata[i]=dbuf[i];
    }   
    kfree(dbuf);
    return ret;
}
//(3)ad_rd()得到A/D转换的结果
statie ssize_t ad_rd(struet file *file,char *bur,size_t count,loft t *offset)
{
    int ret;
    int i;
    ret = 0;
    i = 0;
    ad_convert(); // 用2个?
    ad_convert();
    dbuf= kmalloc(count * sizeof(unsigned char),GFP KERNEL);
    for(i = 0; i < count; i++)
    {
        dbuf[i]=ADRXdata[i];
    }     
    copy_to_user(bur,dbuf,count);
    kfree(dbuf);
    return ret;
}
//(4)ad_convert()实际完成A/D转换
void ad_convert(void)
{
    rGPHDAT&=(~0x20);
    udelay(100000);
    spi_tx_data(ADTXdata[0]);
    ADRXdata[0]=rSPRDATO;
    spi_tx_data(0xff);
    ADRXdata [1 ]=rSPRDATO;
    rGPHDAT |=0x20;
}
//(5)spi_tx_data()完成发送数据
void spi_tx_data(unsigned char data)
{
    spi_poll_done();
    rSPTDAT0=data;
    spi_poll_done();
}

//(6)spi_poll_done()轮询SPI状态
static void spi_poll_done(void)
{
    while(!(rSPSTA0&0x01));
}

感觉最后一个函数很有问题,依据我的理解,这种是不是压根就不应该出现在驱动里面?但是各大网站疯狂转载,我又很疑惑,各位兄弟解疑下
PS:用的是s3c2410和AD7888

相关帖子

沙发
backupyan| | 2010-3-10 20:31 | 只看该作者
你怕什么?死循环?
Linux下不是多任务吗?

使用特权

评论回复
板凳
tiger84|  楼主 | 2010-3-10 20:43 | 只看该作者
看到这种while(!(rSPSTA0&0x01));写法,我就无语了

使用特权

评论回复
地板
goosen| | 2010-3-11 20:36 | 只看该作者
rSPSTA0 该是某个寄存器(用于标识spi 总线的一个状态,比如发送是否完成或是否空闲等,具体没看spi相关,只是猜)。

//(6)spi_poll_done()轮询SPI状态
static void spi_poll_done(void)
{
    while(!(rSPSTA0&0x01));
}

这么实现,一般情况或许不会有问题(驱动很多都有这么处理法的,简单处理,不过某些情况或许会出现异常,导致跑步下去)。比较好的是,查询一断时间(具体时间需根根据协议或芯片设定),超过则就是超时,返回错误就是。

使用特权

评论回复
5
sinanjj| | 2010-3-11 21:54 | 只看该作者
一般不会有问题.

但严格意义上讲肯定是有问题的. 比如: spi hack

使用特权

评论回复
6
后学| | 2010-3-13 18:44 | 只看该作者
你可以定时查询

使用特权

评论回复
7
weng8518| | 2010-3-15 21:57 | 只看该作者
有点看不懂哦。。。。

使用特权

评论回复
8
tiger84|  楼主 | 2010-3-19 13:31 | 只看该作者
已经搞定。利用现成的spidev最好了

使用特权

评论回复
9
justin198563| | 2012-9-19 22:26 | 只看该作者
8# tiger84

使用特权

评论回复
10
justin198563| | 2012-9-19 22:27 | 只看该作者
楼主能不能给具体说一下啊,谢谢!

使用特权

评论回复
11
zhongguoluren| | 2012-10-20 23:49 | 只看该作者
看到你们交流,我似乎有点感悟了

使用特权

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

本版积分规则

个人签名:专注ARM及linux性能优化

101

主题

862

帖子

0

粉丝