Hi,
We're working on interfacing with a spi flash chip on a 6sl board. We've
been able to get the general form of the spi transaction looking
correct but we're seeing an unexpected behavior with chip select.
I've attached a scope trace from the device. It shows what should be an
8-bit write (read-status instruction 0x05) followed by an 8-bit read.
The chip select should be kept asserted in between the write and read
but we're seeing that the 6sl spi driver seems to deassert it. The
userspace code we're using does:
struct spi_ioc_transfer mesg[2] = { 0, };
mesg[0].tx_buf = (unsigned long)out_buffer;
mesg[0].rx_buf = (unsigned long)NULL;
mesg[0].len = 1;
mesg[0].cs_change = 0;
num_tr++;
mesg[1].tx_buf = (unsigned long)NULL;
mesg[1].rx_buf = (unsigned long)in_buffer;
mesg[1].len = 1;
mesg[1].cs_change = 1;
num_tr++;
ret = ioctl(fd, SPI_IOC_MESSAGE(num_tr), mesg);
So it seems like the spi driver is ignoring the cs_change value set to
0 in the transmit message (mesg[0]) which should tell it to keep CS
asserted.
Looking on the fsl community threads, I found a thread from 2013 that
describes our problem exactly. It says:
"
My device requires that the CS be held for the entire transaction (cmd
byte + N data bytes returned from the device), however when I observe
the spi transfer on my logic analyzer I noticed that the i.MX6
releases CS between each data word. My device will not shift out its
data in this case.
"
https://community.freescale.com/thread/309866
I tried applying the patch from Jeff Coffman and it didn't apply on my 3.0.35 kernel. I fixed it up, looks like just positioning issues (patch attached) but when I tested it with an 8-bit write+read, it hangs the system.
I'm now thinking it may be quicker for us to force SPI_NO_CS and just
disable the mx6's spi controller cs handling and do the CS using gpio
in userspace rather than trying to fix the controller driver.
Please let me know what you think. Would appreciate any advice.
Thanks!
Original Attachment has been moved to: spi_imx.3.0.35.patch.zip
Hi,
I have the same problem. Anyone have solved this bug? (apart from using a GPIO to control the CS?)
You are right in that the simplest way to meet the specific SS signal waveform requirements of your SPI slave device is to control SS as GPIO in the user space code.
Another possible way is to try to modify the SPI driver code to control the SS_CTLx bits in the ECSPIx_CONFIGREG register, please refer to the corresponding description in the i.MX6SL Refernce Manual document.
Have a great day,
Artur
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
It looks like the SS_CTLx bits in the ECSPIx_CONFIGREG just enable the chip select to go low when data is transferred it does not force it high or low. Have you gotten this to work?
Thanks,
Greg
hy,
maybe you should take alook at the "i.MX 6Dual/6Quad Applications Processor Reference Manual".
You can find informations about the SPI configuration registers.
Is "21.4.4.1.3 Master Mode with SS_CTL[3:0] Control" what you want?
cheers
christopher
Hi Christopher,
Thanks for your reply. I'm using 6sl and the register manual is available. It is unclear what direction you're suggesting. Are you suggesting I modify userspace to manipulate the spi registers like SS_CTL directly? Or are you suggesting I modify spi_imx?
As I mentioned, I'm using spidev (in userspace) which uses the spi_imx driver. I imagine it would not be good to have userspace manipulate registers directly. Ideally, the goal would be to make the spi_imx driver do the right thing and honor the cs_change variable. Alternatively, bypass CS control via spi_imx using SPI_NO_CS. I'm hoping someone who has done this before and encountered this issue can advise with useful info.
Thanks!
Hi Jaya,
I am facing a similar problem. However I am on kernel 4.1.15 and the patch which you posted does not apply. Did you fix this problem in kernel or you controlled the chip select from user space?
Vishal
Hi Vishal,
In the end, we solved it by controlling chip select as gpio from user space.
Hope that helps.