2008-02-19 15:42:00     chip select line toggling between consecutive "Messages"

Document created by Aaronwu Employee on Aug 5, 2013
Version 1Show Document
  • View in full screen mode

2008-02-19 15:42:00     chip select line toggling between consecutive "Messages"

murti iki (GERMANY)

Message: 51296    Hello,

 

After reading through bug number 3821 (submitted by Larry Samuel). I have understood that the chip select line toggles between consecutive messages. If I am not wrong when the last transfer in a message has cs_change = 0, the chip select line should stay active until the next message.

 

There is no problem between two transfers, the chip select line stays low however between messages it toggles regardless of the cs_change.

 

I also couldn't understand the part in the bug report 

Index: drivers/spi/spi_bfin5xx.c

 

===================================================================

--- drivers/spi/spi_bfin5xx.c   (revision 4081)

+++ drivers/spi/spi_bfin5xx.c   (working copy)

@@ -543,7 +543,7 @@ static void giveback(struct driver_data

                bfin_spi_disable(drv_data);

        }

 

-       if (!drv_data->cs_change)

+       if (drv_data->cs_change)

                cs_deactive(drv_data, chip);

 

        if (msg->complete)

 

If I understood correctly, later in the report it is told not to do this change.

I tried both versions to no success. Nothing changes (well at least to me). I would be happy if somebody can tell

me the purpose of that line.

 

Sorry for asking too many questions

cheers

Murti

 

QuoteReplyEditDelete

 

 

2008-02-24 22:15:00     Re: chip select line toggling between consecutive "Messages"

Yi Li (CHINA)

Message: 51567    Murti,

 

I think in bug 3821, they have mentioned the solution:

The key is to set CPHA to make spi work in proper mode.

 

(I am not the bug owner. If you have further question, I think Bryan will give you detailed answer).

 

"Larry:

 

 

Firstly, there are something wrong in the spi_bug.c

<adsp-spiadc.h> is only for "Blackfin BF53x ADSP SPI ADC

support" (drivers/char/bfin_spi_adc.c). So some ioctl similar to following

code are useless.

--

ioctl (fd,CMD_SPI_SET_CSENABLE,CFG_SPI_CHIPSEL2);

ioctl (fd,CMD_SPI_SET_CSLOW,CFG_SPI_CS2VALUE);

--

The same ioctl API you can found in include/linux/spi/spidev.h

Please replace the adsp-spiadc code to spidev API.

 

Secondly, if software intend to control cs_change, the CPHA should be set in

SPI_CTL register. So you have 2 method to do this:

1) set spi_mode to SPI_MODE_1 (SPI_CPHA | 0) in

arch/blackfin/mach-bf537/boards/stamp.c

---

#if defined(CONFIG_SPI_SPIDEV) || defined(CONFIG_SPI_SPIDEV_MODULE)

static struct bfin5xx_spi_chip spidev_chip_info = {

        .enable_dma = 0,

        .bits_per_word = 8,

        .cs_change_per_word = 0,

};

#endif

...........

#if defined(CONFIG_SPI_SPIDEV) || defined(CONFIG_SPI_SPIDEV_MODULE)

        {

                .modalias = "spidev",

                .max_speed_hz = 6250000,     /* max spi clock (SCK) speed in HZ

*/

                .bus_num = 0,

                .chip_select = 2,

                .controller_data = &spidev_chip_info,

                .mode = SPI_MODE_1,

        },

#endif

----

 

2) set CPHA in the spi_bug.c

---

ioctl(fd, SPI_IOC_WR_MODE, SPI_MODE_1);

 

"

QuoteReplyEditDelete

 

 

2008-02-25 03:47:23     Re: chip select line toggling between consecutive "Messages"

murti iki (GERMANY)

Message: 51582    Hello Yi,

 

Thanks for the answer. I think in that bug report CPHA is already set (it's also set in my program). However the Chip_select line stil toggles.

I would be very happy if Bryan can have a look at this issue

 

thanks alot

murti

QuoteReplyEditDelete

 

 

2008-02-25 13:17:00     Re: chip select line toggling between consecutive "Messages"

Mike Frysinger (UNITED STATES)

Message: 51608    please post the exact resources you have in your board file as well as the SPI functions you're trying to use

QuoteReplyEditDelete

 

 

2008-02-26 01:51:22     Re: chip select line toggling between consecutive "Messages"

murti iki (GERMANY)

Message: 51643    Here is the code snippet that I use in the write part of my driver module, which is basically a slightly changed version of bfin_spi_adc.c. Other than that I am using 2007R1.1-RC3.

 

static ssize_t adc_spi_write (struct file *filp, const char *buf, size_t count, loff_t *f_pos)

{

    unsigned short tdata=0x2001;

    unsigned short tdata2=0x2020;

   struct spi_message m,m1;

    struct spi_transfer t,t1,t2;  

     

        printk("aa\n");

    struct bfin_spi_adc *bfin_spi_adc = filp->private_data;

     

        if (count <= 0)

        return 0;

 

        // ya simdi aklima geliyor, neden burda copy_from_userspace yapmiyoruz ???

        blackfin_dcache_flush_range((unsigned long)buf,((unsigned long)buf+(count)));

      

        spi_message_init(&m);

    spi_message_init(&m1);

      

        memset(&t1,0,(sizeof t1));

        memset(&t,0,(sizeof t));

    memset(&t2,0,(sizeof t2));

      

     

        t.cs_change = 0;

    t.bits_per_word = 8;

        t.tx_buf = buf;

        t.len = count;    // number of 8 byte transfers

 

        t1.cs_change = 0;

    t1.bits_per_word = 8;

        t1.tx_buf = &tdata;

        t1.len = 2;  

 

  

        t2.cs_change = 0;

    t2.bits_per_word = 8;

        t2.tx_buf = &tdata2;

        t2.len = 2;

      

 

    spi_message_add_tail(&t, &m);

    spi_message_add_tail(&t1, &m);

    spi_message_add_tail(&t2,&m1);

  

          

    

    spi_sync(bfin_spi_adc->spidev, &m);

    spi_sync(bfin_spi_adc->spidev, &m1);

 

return 0;

}

 

In between messages, CS toggles. Between transfers in a message it stays low.

QuoteReplyEditDelete

 

 

2008-02-26 02:07:41     Re: chip select line toggling between consecutive "Messages"

Mike Frysinger (UNITED STATES)

Message: 51645    but what about board resources ?  both pieces are critical for testing

QuoteReplyEditDelete

 

 

2008-02-26 10:29:01     Re: chip select line toggling between consecutive "Messages"

murti iki (GERMANY)

Message: 51664    sorry about that, here is the code snippet from stamp.c

 

static struct bfin5xx_spi_chip spi_adc_chip_info = {

    .ctl_reg = 0x1400,  //software control of the slave_select no

    .enable_dma = 0,         /* use dma transfer with this chip*/

    .bits_per_word = 8,

    .cs_change_per_word = 0,   //original had value 0  08.02.2008 Rifat

};

 

 

{

        .modalias = "bfin_spi_adc_6", /* Name of spi_driver for this device */

        .max_speed_hz = 6250000,     /* max spi clock (SCK) speed in HZ */

        .bus_num = 1, /* Framework bus number */

        .chip_select = 6, /* Framework chip select. */

        .platform_data = NULL, /* No spi_driver specific config */

        .controller_data = &spi_adc_chip_info,

    },

 

 

QuoteReplyEditDelete

 

 

2008-02-26 23:46:47     Re: chip select line toggling between consecutive "Messages"

Mike Frysinger (UNITED STATES)

Message: 51689    you're saying that during a single spi_sync(), the cs stays low like you want ?  but after one spi_sync() and before the next spi_sync() it toggles ?  that is correct behavior ... you have no guarantee the spi bus wont be taken by some other device driver in between calls to spi_sync()

QuoteReplyEditDelete

 

 

2008-02-27 02:22:52     Re: chip select line toggling between consecutive "Messages"

murti iki (GERMANY)

Message: 51696    hmm, but as far as I remember in the documentation of spidev

it says that if the cs_change part of the last transfer in a message is 0 then the chip select line is kept low untill the next message comes.

QuoteReplyEditDelete

 

 

2008-02-27 02:38:05     Re: chip select line toggling between consecutive "Messages"

Mike Frysinger (UNITED STATES)

Message: 51697    you're not using the spidev device driver

 

the comments in include/linux/spi/spidev.h though mean you pass in an array of transfers and the cs_change controls the cs behavior between individual transfers, not messages ... the spidev behavior translates to using the common spi framework from kernel space: one ioctl is equivalent to one message

 

one message is composed of multiple transfers ... you can control the cs behavior between transfers, not messages ... after all, you have no idea if another spi device will claim the bus and do its own message in between your messages.  the spi framework only gives you the ability to hold the bus for 1 message (which may include multiple transfers).

QuoteReplyEditDelete

 

 

2008-02-27 07:29:59     Re: chip select line toggling between consecutive "Messages"

murti iki (GERMANY)

Message: 51732    Actually I was referring to the paragraph in the document "spi-summary" under ..\linux2.6\documentation\spi

 

  "An spi_message is a sequence of protocol operations, executed

   as one atomic sequence.  SPI driver controls include:

 

     + when bidirectional reads and writes start ... by how its

       sequence of spi_transfer requests is arranged;

 

     + optionally defining short delays after transfers ... using

       the spi_transfer.delay_usecs setting;

 

     + whether the chipselect becomes inactive after a transfer and

       any delay ... by using the spi_transfer.cs_change flag;

 

     + hinting whether the next message is likely to go to this same

       device ... using the spi_transfer.cs_change flag on the last

       transfer in that atomic group, and potentially saving costs

       for chip deselect and select operations "

 

The last paragraph made me think that if the last transfer in a message had cs_change = 0 then CS would be kept low.

Anyway it turns out that this is not so.

Thank you for your help

QuoteReplyEditDelete

 

 

2008-02-27 12:57:03     Re: chip select line toggling between consecutive "Messages"

Mike Frysinger (UNITED STATES)

Message: 51748    the last paragraph is a helpful optimization when sending multiple messages, not a guarantee ... so if it's absolutely required that the next spi transaction is from your driver in order to properly communicate with the device, you cannot rely on it

Attachments

    Outcomes