免费注册 查看新帖 |

Chinaunix

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

[硬件及驱动] SPI外设驱动 LPC3250的SSP(spi)控制器PL022与AD7888通信的问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2012-11-22 10:26 |只看该作者 |倒序浏览
本帖最后由 120620056 于 2012-11-22 10:36 编辑

平台:FDI3250(LPC3250)
环境:linux2.6.39.2
SSP兼SPI控制器L022
外设:8通道AD7888 只有一个可写8位寄存器
问题:照AD7887_core.c 写了一个外设驱动AD7888_core.c,发现示波器只在读驱动时CS会拉低,时钟线只在50MV时有抖动,数据进出线没有反应,spi_sync返回值为零,通道数据返回零。

板级文件

static struct pl022_ssp_controller lpc32xx_ssp0_data = {
.bus_id = 0,
.num_chipselect = 2,
.enable_dma = 0,
};

static struct amba_device lpc32xx_ssp0_device = {
.dev = {
.coherent_dma_mask = ~0,
.init_name = "dev:ssp0",
.platform_data = &lpc32xx_ssp0_data,
},
.res = {
.start = LPC32XX_SSP0_BASE,
.end = (LPC32XX_SSP0_BASE + SZ_4K - 1),
.flags = IORESOURCE_MEM,
},
.dma_mask = ~0,
.irq = {IRQ_LPC32XX_SSP0, NO_IRQ},
};
static struct pl022_config_chip spi0_chip_info = {
.com_mode = INTERRUPT_TRANSFER,
.iface = SSP_INTERFACE_MOTOROLA_SPI,
.hierarchy = SSP_MASTER,
.slave_tx_disable = 0,
.clk_freq = {
.cpsdvsr= 2,
.scr= 8,
},
.rx_lev_trig = SSP_RX_4_OR_MORE_ELEM,
.tx_lev_trig = SSP_TX_4_OR_MORE_EMPTY_LOC,
.ctrl_len = SSP_BITS_8,
.wait_state = SSP_MWIRE_WAIT_ZERO,
.duplex = SSP_MICROWIRE_CHANNEL_FULL_DUPLEX,
.cs_control = fdi3250_spi_cs_set,
};
static int __init fdi3250_spi_devices_register(void)
{
static struct spi_board_info info[] = {
{
    .modalias = "ad7888",
.max_speed_hz=2500000,
.bus_num = 0,
.chip_select = 0,
.controller_data = &spi0_chip_info,
.platform_data = &spi_ad7888,
},

};

return spi_register_board_info(info, ARRAY_SIZE(info));
}
arch_initcall(fdi3250_spi_devices_register);
static struct amba_device *amba_devs[] __initdata = {
&lpc32xx_ssp0_device,

};

static int __init fdi3250_amba_devices_register(void)
{
for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
struct amba_device *d = amba_devs;
amba_device_register(d, &iomem_resource);
}

return 0;
}
device_initcall_sync(fdi3250_amba_devices_register);

驱动:
struct ad7888_platform_data {
u16 vref_mv;
bool en_dual;
bool use_onchip_ref;
};



static const struct ad7888_chip_info ad7888_chip_info_tbl[] = {                                                                                          
    /*
                           119      * More devices added in future
                           120      */
         [ID_AD7888] = {
                               .bits = 12,
                                .storagebits = 16,
                                .left_shift = 0,
                                        .sign=IIO_SCAN_EL_TYPE_UNSIGNED,
                                 .int_vref_mv = 2500,
                            },
         };

  
static int ad7888_scan_direct(struct ad7888_state *st, unsigned ch)
          {
                      int ret = spi_sync(st->spi, &st->msg[ch]);
                       if (ret)
                                    return ret;
                     printk("ret=%d\n",ret);
                             return (st->data[(ch * 2)] << | st->data[(ch * 2) + 1];
                           }


static ssize_t ad7888_scan(struct device *dev,
                                  struct device_attribute *attr,
                                   char *buf)
   {
               struct iio_dev *dev_info = dev_get_drvdata(dev);
                struct ad7888_state *st = dev_info->dev_data;
                     struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
                      int ret;
                  

mutex_lock(&dev_info->mlock);
printk("ad7888_scan_direat\n";
ret = ad7888_scan_direct(st, this_attr->address);
mutex_unlock(&dev_info->mlock);



    if (ret < 0)
       return ret;
          
               return sprintf(buf, "%d\n", (ret >> st->chip_info->left_shift) &
                                         RES_MASK(st->chip_info->bits));
             }

static IIO_DEV_ATTR_IN_RAW(0, ad7888_scan, 0);
static IIO_DEV_ATTR_IN_RAW(1, ad7888_scan, 1);
                  
static struct attribute *ad7888_attributes[]={
        &iio_dev_attr_in0_raw.dev_attr.attr,
        &iio_dev_attr_in1_raw.dev_attr.attr,
        NULL,
};

static const struct attribute_group ad7888_attribute_group={
        .attrs=ad7888_attributes,
//        .is_visible=
};




static int __devinit ad7888_probe(struct spi_device *spi)
{
        printk("ad7888_probe\n";
        struct ad7888_platform_data *pdata=spi->dev.platform_data;
        printk("use_onchip_ref=%d\n",pdata->use_onchip_ref);
        struct ad7888_state *st;
        int ret,voltage_uv=0;
        st=kzalloc(sizeof(*st),GFP_KERNEL);
        if(st == NULL){
        ret=-ENOMEM;
        goto error_ret;
        }
        st->reg=regulator_get(&spi->dev,"vcc";
        if(!IS_ERR(st->reg)){
        ret=regulator_enable(st->reg);
        if(ret)
                goto error_put_reg;
        voltage_uv=regulator_get_voltage(st->reg);
        }
st->chip_info=&ad7888_chip_info_tbl[spi_get_device_id(spi)->driver_data];       
spi_set_drvdata(spi,st);
atomic_set(&st->protect_ring,0);
st->spi=spi;
st->indio_dev=iio_allocate_device();
if(st->indio_dev == NULL){
        ret = -ENOMEM;
        goto error_disable_reg;
}

st->indio_dev->dev.parent = &spi->dev;
st->indio_dev->attrs = &ad7888_attribute_group;
st->indio_dev->dev_data = (void *)(st);
st->indio_dev->driver_module= THIS_MODULE;
st->indio_dev->modes =INDIO_DIRECT_MODE;
st->tx_cmd_buf[0]=0x00;
st->xfer[0].rx_buf = &st->data[0];
st->xfer[0].tx_buf = &st->tx_cmd_buf[0];
st->xfer[0].len=2;
spi_message_init(&st->msg[0]);
spi_message_add_tail(&st->xfer[0],&st->msg[0]);
st->tx_cmd_buf[2]=0x08;
st->xfer[1].rx_buf = &st->data[0];
st->xfer[1].tx_buf = &st->tx_cmd_buf[2];
st->xfer[1].len=2;
st->tx_cmd_buf[4]=0x00;
st->xfer[2].rx_buf = &st->data[2];
st->xfer[2].tx_buf = &st->tx_cmd_buf[4];
st->xfer[2].len=2;
spi_message_init(&st->msg[1]);
spi_message_add_tail(&st->xfer[1],&st->msg[1]);
spi_message_add_tail(&st->xfer[2],&st->msg[1]);
st->tx_cmd_buf[6]=0x08;
st->xfer[3].rx_buf = &st->data[0];
st->xfer[3].tx_buf= &st->tx_cmd_buf[6];
st->xfer[3].len=2;
spi_message_init(&st->msg[2]);


spi_message_add_tail(&st->xfer[3],&st->msg[2]);
if(pdata && pdata->use_onchip_ref)
st->int_vref_mv = st->chip_info->int_vref_mv;

printk("st->mv=%ld\n",st->int_vref_mv);
ret=iio_device_register(st->indio_dev);
        return 0;

error_disable_reg:
        if(!IS_ERR(st->reg))
        regulator_disable(st->reg);
error_put_reg:
        if (!IS_ERR(st->reg))
                regulator_put(st->reg);
        kfree(st);
error_ret:
        return ret;
}

static int ad7888_remove(struct spi_device *spi)
{
        return 0;


}




static struct spi_device_id ad7888_id[]={
        {"ad7888",ID_AD7888},
        {}
};

static struct spi_driver ad7888_driver={
        .driver={
                .name="ad7888",
                .bus=&spi_bus_type,
                .owner=THIS_MODULE,
        },
        .probe=ad7888_probe,
        .remove=__devexit_p(ad7888_remove),
        .id_table = ad7888_id,
};

static int __init ad7888_init(void)
{
        return spi_register_driver(&ad7888_driver);
}

static void __exit ad7888_exit(void)
{
        spi_unregister_driver(&ad7888_driver);
}

module_init(ad7888_init);
module_exit(ad7888_exit);

MODULE_AUTHOR("xianfu_wu <wuxianfu163@163.com>";
MODULE_LICENSE("GPL";

论坛徽章:
0
2 [报告]
发表于 2012-11-22 10:32 |只看该作者
[root@nxp /]# cat /sys/bus/iio/devices/device2/in1_raw
ad7888_scan_direat
ssp-pl022 dev:ssp0: flush
ssp-pl022 dev:ssp0: readwriter, rx: c194b760, rxend: c194b762, tx: c194b742, txend: c194b744
ssp-pl022 dev:ssp0: readwriter, rx: c194b760, rxend: c194b762, tx: c194b744, txend: c194b744
ssp-pl022 dev:ssp0: flush
ssp-pl022 dev:ssp0: readwriter, rx: c194b762, rxend: c194b764, tx: c194b744, txend: c194b746
ssp-pl022 dev:ssp0: readwriter, rx: c194b762, rxend: c194b764, tx: c194b746, txend: c194b746
ret=0
0

论坛徽章:
0
3 [报告]
发表于 2012-11-23 09:28 |只看该作者
没有人做过相关的工作吗,或者给解决的问题途径也好呀

论坛徽章:
0
4 [报告]
发表于 2012-11-24 10:50 |只看该作者
{:3_196:}为什么我的问题无人问津
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP