Oliviers-OSS / libmpsse

Automatically exported from code.google.com/p/libmpsse
0 stars 0 forks source link

One too many clock edges are output whe using SPI modes 1 and 3 #15

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
1. Set MPSSE.SPI.Open(SPI1, ***, MSB) or MPSSE.SPI.Open(SPI3, ***, MSB)
2. Attach scope to SCLK, MOSI and CS lines
3. Write one byte

What is the expected output? What do you see instead?

8 clock cycles are expected on SCLK, but another clock edge appears at the end 
of the transmission: this edge appears BEFORE CS goes high, thus it is received 
by any guest device present on the SPI bus, causing it to shift its internal 
register once more.

In SPI mode 1 the clock should remain low after the last (8th) falling edge, 
while in SPI mode 3 the clock should remain high after the 8th rising edge.
Modes 0 and 2 operate correctly.

What version of the product are you using? On what operating system?

Using r122 from svn (same problem happens with release 1.2-1), host device is a 
C232HM cable equipped with a FTDI232H IC.
OS is gentoo x86-64, libftdi 0.20

Please provide any additional information below.

I was trying to communicate with an AD5293, that supports only SPI mode 1. Word 
size is 2 Bytes.
The device was ignoring all the commands.
After analyzing the data coming out of MISO, I realized that the read-back word 
was the same I'd input, only shifted one position.

Using the scope I was able to verify that another clock edge indeed appears on 
SCLK before the chip select is removed (a rising edge, in this case), the clock 
then proceeds to remain high until the end of the transmission (even if it's 
supposed to idle low in mode 1).

SPI mode 1 devices are supposed to clock out the MSB of their internal register 
on the rising edge of SCLK, therefore the additional clock edge effectively 
shifts the guest device internal register, making the command invalid.

Also, some devices (like the AD5293) have an internal counter attached to SCLK 
and, if the count is not an exact multiple of the word size, they will ignore 
the received data altogether (which is what happens in my case, since the 
device counts 17 clock cycles).

Digging into mpsse.c, I stumbled upon the comment on line 381, which at first 
sight seemed to be the source of my problems.
I tried to replace {mpsse->pstop |= SK} with {mpsse->pstop &= ~SK}, hoping that 
would solve the issue, but this change has no effect whatsoever: the clock 
keeps going high at the end of the transmission.

I've verified that the opposite thing is happening in mode 3: in this case, the 
clock goes low before the chip select is removed, adding a 9th (falling) clock 
edge.
The behavior persists even if I change the pstop condition on mpsse.c:369.

Original issue reported on code.google.com by pietro.g...@gmail.com on 5 Dec 2012 at 7:14

GoogleCodeExporter commented 9 years ago
Hi. I'm no expert, but I just happen to be reading about the FTDI chips this 
week, and I ran across your question shortly after looking at this app note: 
http://www.ftdichip.com/Support/Documents/AppNotes/AN_114_FTDI_Hi_Speed_USB_To_S
PI_Example.pdf - and I remembered running across this quote while I was reading 
about their SPI support: "It is recommended that designers review the SPI Slave 
data sheet to determine the SPI mode implementation. FTDI device can only 
support mode 0 and mode 2 due to the limitation of MPSSE engine." Sorry to be 
the bearer of bad news, but it sounds like this might not be fixable, at least 
until they make some change to the MPSSE engine to address the problem. (or, I 
guess, you might be able to do something in bit-bang mode, for a lot more work 
and at a slower speed.) Good luck!

Original comment by jvm...@gmail.com on 7 Dec 2012 at 10:20

GoogleCodeExporter commented 9 years ago
Hi.
I see... Thank you for pointing this out.
Maybe a note should be added to this library stating that only modes 0 and 2 
are working properly...

Original comment by pietro.g...@gmail.com on 7 Dec 2012 at 10:27

GoogleCodeExporter commented 9 years ago
Yes, the MPSSE engine only supports modes 0 and 2.

This library makes an attempt to support modes 1 and 3 in software, though as 
you've seen in the comments/code/scope, it's a hack since the MPSSE engine 
doesn't want to work properly in these modes. I've tested modes 1 and 3 against 
the DS1305 real time clock chip successfully, and I've used mode 3 successfully 
with various SPI EEPROMs and SPI flash chips, though YMMV. You can always use 
the bitbang mode if necessary, but this will obviously be much slower.

I will add a statement to this effect in the documentation.

Original comment by heffne...@gmail.com on 9 Dec 2012 at 3:05

GoogleCodeExporter commented 9 years ago
Hi,
It seems modes 1 and 3 will work correctly only with devices that support 
instruction decoding "on the fly": that is, the instruction is executed -if 
valid- as soon as it's loaded into the shift register, without waiting for CS 
to go high.

Unfortunately, when you are communicating with SPI slaves that support 
daisy-chaining, the execution of commands can only take place after CS is 
removed. This ensures that the correct codes have been loaded throughout the 
whole chain.
In this case an additional clock cycle is completely disruptive...

Devices that perform clock counting are also affected by this and will void the 
transferred data every time.

Original comment by pietro.g...@gmail.com on 11 Dec 2012 at 4:04

GoogleCodeExporter commented 9 years ago
Thanks pietro, I've updated the SPI README file as well as the summary on the 
main project page to reflect the state of SPI 1/3 support.

Original comment by heffne...@gmail.com on 28 Jan 2013 at 6:46