vacdvacd 发表于 2014-12-01 15:43

SPI驱动问题,求各位大侠指点

本帖最后由 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打印打开了,如下:


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



而我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+中断的方式,请问我现在接收的数据出现问题,有可能是什么方面的问题呢??我是菜鸟一个,希望各位大侠点拨一下,不甚感激!!!




zlw1005 发表于 2015-03-14 23:51

你怎么知道是采用dma和中断工作的,反正210上的代码是查询方式,还有请你做下spi的环回测试,out接in测试下了,还有建议你spi时钟不要太高

xuco 发表于 2015-03-30 12:20

时钟首先要设对,驱动层还可能要选择是8个比特还是24比特(填充字节)
另外就是CPHA,CPOL 可能要设定,就是SPI的极性与相位

Flyhung 发表于 2015-04-06 11:28

首先看下基本功能能不能实现:时钟高低电平对不对,时序对不对,然后就是联调。
页: [1]
查看完整版本: SPI驱动问题,求各位大侠指点