免费注册 查看新帖 |

Chinaunix

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

SPI驱动问题,求各位大侠指点 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2014-12-01 15:43 |只看该作者 |倒序浏览
本帖最后由 vacdvacd 于 2014-12-01 15:48 编辑

最近要写一个基于Linux的SPI子系统的驱动。
我首先是先看了看其他的如MCP2515的驱动、drivers/spi/spidev.c中的内容以及AT25.c等。
现在是想要读我外设上面的寄存器信息。
SPI总线上的数据格式如下:

数据在时钟上升沿有效。
发送:0x22,0x00
返回:0x00,0x03
其中,0x22是slave设备上的寄存器地址,0x00代表本条发送指令结束.具体的时序如:




我使用的是6410板子,当然控制器驱动就直接用的是drivers/spi/spi_s3c.c
在mach-xxx中添加了我的spi_board_info信息,
现在init的时候注册spi驱动核心,运行probe的时候初始化一些数据结构成员,设备节点文件也创建完成。


但是现在我无论是直接使用spi_async()来进行数据同步,还是使用spi_write_then_read()来进行数据同步,都是读不出我想要的数据,我测试的方法就是发送0x22,0x00,然后读数据,循环进行试验,但是就是读不出来正确的数据(通过示波器测量,确定返回数据波形没有问题,和我画的时序图吻合),读出的数据很奇怪,而当我把MOSI接到GND也确实读的全是0,我很奇怪,就把DMA和SPI核心的debug打印打开了,如下:


[21474620.530000] s3c2410_dma_config: chan=33, xfer_unit=1, dcon=00000000
[21474620.530000] s3c2410_dma_config: Initial dcon is 00000000
[21474620.535000] s3c2410_dma_config: New dcon is 00000000
[21474620.540000] s3c2410_dma_config: DMA Channel control :  00000000
[21474620.545000] s3c2410_dma_config: dcon now 89000000
[21474620.550000] s3c2410_dma_enqueue: id=cf1e2940, data=5f300000, size=2
[21474620.555000] s3c2410_dma_enqueue: new buffer cf318000
[21474620.560000] s3c2410_dma_enqueue: buffer cf318000 queued onto empty channel
[21474620.560000] s3c_dma_waitforload channel number : 0
[21474620.575000] s3c2410_dma_config: chan=34, xfer_unit=1, dcon=00000000
[21474620.580000] s3c2410_dma_config: Initial dcon is 00000000
[21474620.585000] s3c2410_dma_config: New dcon is 00000000
[21474620.590000] s3c2410_dma_config: DMA Channel control :  00000000
[21474620.600000] s3c2410_dma_config: dcon now 86000000
[21474620.605000] s3c2410_dma_enqueue: id=cf1e2940, data=5f2fc000, size=2
[21474620.610000] s3c2410_dma_enqueue: new buffer cf318040
[21474620.615000] s3c2410_dma_enqueue: buffer cf318040 queued onto empty channel
[21474620.615000] s3c_start_dma: channel number=1, index=1
[21474620.615000] s3c_chan_loadbuffer: loading buffer cf318040 (0x5f2fc000,0x000002)
[21474620.615000] s3c_dma_loadbuffer: DMA control0 - 86000000
[21474620.615000] s3c_dma_loadbuffer: DMA control1 - 00000002
[21474620.615000] s3c_dma_start:wrote 00008b01 to S3C_DMAC_CxCONFIGURATION.
[21474620.650000] # s3c_dma_irq: TC status : 0x2
[21474620.650000] # DMA Controller 0: requestor 1
[21474620.650000] # DMA channel number : 1, index : 1
[21474620.650000] callback_fn will be called=c02585c4, buf=cf318040, id=cf1e2940, size=2, result=0
[21474620.650000] DMA CH 1: s3c_dma_lastxfer: load_state 0
[21474620.650000] DMA CH 1: s3c_dma_lastxfer: load_state : S3C2_DMALOAD_NONE0
[21474620.650000] # DMA CH 1(index:1): end of transfer, stopping channel (-43166)
[21474620.650000] s3c_dma_dostop: DMA Channel No : 1
[21474620.650000] s3c_dma_dostop: S3C_DMAC_CxCONFIGURATION : 00048b00
[21474620.650000] # s3c_dma_irq: TC status : 0x0
[21474620.710000] # s3c_dma_irq: TC status : 0x1
[21474620.710000] # DMA Controller 0: requestor 0
[21474620.710000] # DMA channel number : 0, index : 0
[21474620.710000] callback_fn will be called=c025861c, buf=cf318000, id=cf1e2940, size=2, result=0
[21474620.710000] DmaRx-2 [RX-OK]s3c_chan_loadbuffer: loading buffer cf318000 (0x5f300000,0x000002)
[21474620.710000] s3c_dma_loadbuffer: DMA control0 - 89000000
[21474620.710000] s3c_dma_loadbuffer: DMA control1 - 00000002
[21474620.710000] # s3c_dma_irq: TC status : 0x0
[21474620.755000] [    read_reg: 237] Read Data[0]=0x0
[21474620.760000] [    read_reg: 237] Read Data[1]=0x0
[21474620.765000] [    read_reg: 237] Read Data[2]=0x0
[21474620.770000]



而我read部分的主要代码如下:(chip-->tx_buffer中是我发送的数据0x22,0x00,而chip->rx_buffer用于接收数据)
        DECLARE_COMPLETION_ONSTACK(done);
        struct spi_transfer t = {
                .tx_buf = chip->tx_buffer,
                .rx_buf = chip->rx_buffer,
                .len        = len+1,
                .delay_usecs = 1000,
                .bits_per_word = 8,
                .cs_change = 0,
        };
        struct spi_message m;
        spi_message_init(&m);
        spi_message_add_tail(&t, &m);
        m.complete        = xxx_complete;
        m.context = &done;

        spin_lock_irq(chip->spin_lock);
        ret = spi_async(spi, &m);
        spin_unlock_irq(chip->spin_lock);

        if(ret == 0){
                wait_for_completion(&done);
                ret = m.status;
                if(ret == 0){
                        ret = m.actual_length;
                }
        }       
       
        if (ret < 0) {
                printk("[%20s:%4d] ERROR:sp_saync Failed\n",__FUNCTION__,__LINE__);
        }else{
                for(i=0;i<ret+1;i++){
                        printk("[%20s:%4d] Read Data[%d]=0x%x\n",
                                        __FUNCTION__, __LINE__, i, chip->rx_buffer);               
                }
        }       




目前spi驱动核心的机制应该是将我发送的数据add到工作队列中去发送,而工作队列的work处理函数应该是是采用的DMA+中断的方式,请问我现在接收的数据出现问题,有可能是什么方面的问题呢??我是菜鸟一个,希望各位大侠点拨一下,不甚感激!!!




论坛徽章:
0
2 [报告]
发表于 2015-03-14 23:51 |只看该作者
你怎么知道是采用dma和中断工作的,反正210上的代码是查询方式,还有请你做下spi的环回测试,out接in测试下了,还有建议你spi时钟不要太高

论坛徽章:
0
3 [报告]
发表于 2015-03-30 12:20 |只看该作者
时钟首先要设对,驱动层还可能要选择是8个比特还是24比特(填充字节)
另外就是CPHA,CPOL 可能要设定,就是SPI的极性与相位

论坛徽章:
0
4 [报告]
发表于 2015-04-06 11:28 |只看该作者
首先看下基本功能能不能实现:时钟高低电平对不对,时序对不对,然后就是联调。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP