This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Continuous spi transfer using linux spi framework on dm365

Hello,

I would like to create following scenario:
We need to have a never stopping continuous spi transfer between dm365 and an another chip on our board. I can imagine this on bare metal application level - having two data buffers I can link DMA transfers, which will automatically switch these buffers in an interrupt at the end of the transfer so the SPI peripheral will by continuously sending/receiving the data without any CPU interaction. Unfortunately I do not know if something similar is possible in linux. Surprisingly I can use dm365 as a slave even in linux, because davinci spi driver enables using external clock for spi even in master mode.

Using linux spi framework I can define a struct spi_message which contains several transfers (struct spi_transfer). Then the function spi_async will perform the transfer and it can also trigger a callback (spi_message::complete) when the transfer ends. Is it safe to call spi_async again in this callback? Is it fast enough to prevent a loss of some data when we have external spi_clock?

 with best regards
Jan 

  • Hi Jan,

    As I understand, the completion callback is called from a kernel thread that should not sleep. Due to this you cannot call a function from the callback, which can sleep. But as spi_async() function is asynchronous, practically you can call this function.

    Regards, Sudhakar

  • Hi Sudhakar,

    thank you for the answer. The described setup works for me with spi_async quite well. But now I'm solving another issue.
    On the SPI2 I have working described receiving using external clock and also transmitting using internal clock. Unfortunately the problem arises when I want to switch between these two. There was no mechanism to switch the internal/external clock (it was done only in davinci_spi_probe function) so I add this also to the davinci_spi_setup which can be called from my module. However when I do that (switching the clock source) the transfers stops to work.

    For example I can boot up my desk, invoke a process which receives on SPI2 with external clock and it works. Then I call another process which switches the clock and tries to transmit but this fails and vice versa.

    What is needed to be done to switch the clock on SPI device?

    best regards
    Jan
     

  • Hi Jan,

    In your last mail you had mentioned that you can use your dm365 as a slave in Linux but Linux does not have the infrastructure to support SPI slave mode. I am feeling that the issue you are seeing may be related to this.

    Regards, Sudhakar

  • Dear  Sudhakar,

    I will try to clarify my setup.

    I'm using ordinary linux spi framework. It works well when I want to send a message to some spi slave. I'm using also let's say "pseudo slave"  mode, which uses the ability of the spi hw to use external spi clock (this can be achieved by clearing CLKMOD bit in SPIGCR1 register, SPI_SCLK pin then works as input). Linux spi framework can also be used in this mode, because I the size of the data, which I need to receive - so I can execute spi_read function and the only difference is that the speed of the transfer is controlled by another chip.

    These two setups works for me but problem is the switching between them. When I change CLKMOD bit after my board starup it is ok, but when I change it once more then the next transfers hangs. It occurs even in the case that I reset the peripheral using its reset bit and setup another regs before the CLKMOD change.

    regards
    Jan 

  • Hi Jan,

    As I understand, you are able to receive the data from external SPI device even when you configured the CLKMOD bit as 0 when board boots up but the same transfer fails if you change the CLKMOD bit one more time. Can you confirm this?

    Also, the SPI driver you are using is pretty old. The new driver available in latest Linux kernel has many bug fixes and I strongly suggest you to check once with this updated driver. You can find the patches to the new driver at http://arago-project.org/git/projects/?p=linux-davinci.git;a=shortlog;h=refs/heads/davinci-spi-rewrite. The kernel tree in this link is based on Linux v2.6.37-rc2. You can have a look at the top 50 odd patches for SPI support.

    Regards, Sudhakar

  • Hi Sudhakar,

    Yes I confirm, that changing of CLKMOD bit after the successful transfer makes spi driver to hang. I discovered also that this is caused by the fact, that DMA events generation was not stopped correctly in the driver on the end of the transfer.  I checked quickly the proposed patches and it seems that the one there http://arago-project.org/git/projects/?p=linux-davinci.git;a=commit;h=fec209600b91b16f1fc18fffcb5a950c3668cda2 should be related to the described problem.

    As we are using the kernel v2.6.32.17 from the latest available SDK I doubt I will be able to apply proposed patches without problems but I will try it at least. We will surely switch to the newer PSP (kernel 2.6.37) or even the newer one if it is available, but it has to be done later because we need to present some functionality next week...

    best regards
    Jan 

  • Hi Sudhakar,

    I have applied the patches from davinci-spi-rewrite branch to our kernel and everything is working correctly now. Thank you.