MCSPI TX works fine, but RX all zeros

I've been struggling with a problem with MCSPI3 and MCSPI4 on the expansion
connector. I've enabled SPI3 and SPI4 and I'm testing with spidev. I've got
the PADCONFs set correctly -- (I've verified this more times than you can
imagine).

The problem is all SPI RX data is zero. TX Data goes out just fine, appears
out the SIMO line, along with SCLK and CS0. I've verified that the data is
getting to the expansion connector.

I've also configured the SOMI pad to have a pullup, which I verified on the
pin itself, which should produce all ones for RX data, but I still get
zeros.

I've also configured the SOMI pin as gpio, and verified that the data is
getting through to the cpu using /sys/class/gpio for testing. Both 1's and
0's work fine on the pin when being used as gpio, but not SPI.

I'm beginning to suspect that there is something wrong with the SPI
controller, but I doubt it.

I've also added some debugging code to drivers/spi/omap2_mcspi.c to print
out the data as it goes in an out of the driver. Here too, RX data is all
zeros. One place I did this is inside omap2_mcspi_txrx_pio, which is used
when the number of bytes to transfer is less than 8. It made it easier to
verify each byte going in and out.

I'm using linux-omap_git package for my kernel,
(Angstrom/2.6.27+2.6.28-rc6+r2+git). I know this is a few weeks old, but
I've looked through the commits and I don't see anything that would address
this.

Anyone have any insight on this issue?

Kevin

Have you checked if there are other pins/balls for the McSPI RX line and made
sure they are configured in some mode other than for the McSPI function?
Making them all the other possible McSPI3 and McSPI4 RX pins GPIO inputs
should be a safe thing.

I ran into a similar issue on the UART where RX didn't work due to U-boot
setting up another ball as the RX and I enabled the expansion connector
connected ball also as RX. I am guessing that caused an internal conflict
since there are 2 sources driving the same line. I fixed this by putting the
other ball in GPIO mode.

Yes, I thought of that. I've verified the contents of all the other PADCONF
registers that reference MCSPI3 or MCSPI4, and none of them are in a mode
which enables it on any pin/ball except for the one I'm using.

Kevin

Is the INPUTENABLE bit in the CONTROL_PADCONF_* register set to logic 1? Just double checking. It is one thing to have the MUXMODE setup for the MCSPI3 or MCSPI4, but you need to ensure the logic around the I/O pad is configured appropriately.

Brandon Azbell

Hi ,
What kind of peripheral you are testing with McSPI ?
The fundamental concept of SPI hardware is that it will have single
shift register for both Rx and Tx .

Assuming the use case of 8 bit configuration of SPI, with full duplex
communication, when you write 8 bit data to Transmit Hold register ,
CLK becomes active for 8 cycles (*only*), in which 8 bit data from
master is sent to slave and 8 bit data is received from slave. Hence
during this time if slave doesn't have any response , your Receive Hold
Register(RHR) will be ZERO .

Hence if you have request response transaction of x bits word size, when
you send REQ1 of x bits size, then response RES1 from slave will be
available after xth cycle, hence while sending REQ2 , your RHR will
contain RES1 and so on .. (*assuming no reset happens between REQ1 and
REQ2 .)

CS THR RHR
cycle 1 req1 0
cycle 2 req2 res1
cycle 3 req3 res2
cycle n req n res n-1

and so on

Regards,
Shankar

Kevin Uhlir wrote:

At this point, for testing, I've disconnected the peripheral, and hard
wired the SOMI input to "1". So, I should receive all '1's at all times.

I've also tried a loop back -- connecting SOMI to MOSI, while I can see the
correct data at the pin on the scope and the logic analyzer, all RX data is
still zero when the driver reads the RX register.

Kevin

Yes, the PADDCONF register is correct. When I look at the PADCONF register
directly, it is set to 0x119. Unless I'm mistaken this means input enable,
pull up, pull enable, and mode 1. Currently I'm testing with MCSPI3 on the
expansion connector, so MCSPI3_SOMI is configured with the PADCONF register
at 0x4800215c. I've also tried it when its set to 0x101, which just
eliminates the pull-up. I appreciate the suggestions, and welcome anyone
double checking this setting.

FYI, I've tried the same pin, configured as gpio_132, PADCONF setting 0x104.
In this mode, when I export gpio_132, set its direction, and view its value,
it follows the hardware signal level correctly -- 0 when its pulled down, 1
when its pulled up. So the pin itself works.

Kevin

Yes, the PADDCONF register is correct. When I look at the PADCONF register
directly, it is set to 0x119. Unless I'm mistaken this means input enable,
pull up, pull enable, and mode 1. Currently I'm testing with MCSPI3 on the
expansion connector, so MCSPI3_SOMI is configured with the PADCONF register
at 0x4800215c. I've also tried it when its set to 0x101, which just
eliminates the pull-up. I appreciate the suggestions, and welcome anyone
double checking this setting.

FYI, I've tried the same pin, configured as gpio_132, PADCONF setting
0x104. In this mode, when I export gpio_132, set its direction, and view
its value, it follows the hardware signal level correctly -- 0 when its
pulled down, 1 when its pulled up. So the pin itself works.

Kevin

What about the McSPI module itself? Looking at the TRM, there is a TX only
mode. Also, does the OMAP side generate clocks when you are attempting to
receive? (Assuming the OMAP is the single master). If clocks isn't toggling,
you won't receive anything useful.

Another thing to check is the MCSPI_SYST register for the channel in use. It
can change the I/O direction of the SOMI/SIMO lines. Another one to check is
the MCsPI_CHxCONF which can force a single wire mode (xmit/rcvd on the same
pin).

I put some more debug code in the driver, and I see the TRM bits are
correct. The SCLK, MOSI, and CS0 are all working fine. I see the clock, I
see CS operating, I see MOSI changing according to the data sent, in sync
with the clock. I just tried SYST setting some values in, but it didn't
fix the problem. Also, the documentation says SYST is only used in system
test mode, which is not enabled.

I decided to dump all the registers in the driver, just before the transfer
is starts:

SYSCONFIG (d80b8010)=00000001 AUTOIDLE

SYSSTATUS (d80b8014)=00000001 RESETDONE

IRQSTATUS (d80b8018)=00000001 TX0_EMPTY

IRQENABLE (d80b801c)=00000000 no IRQ's enabled

WAKEUPENABLE (d80b8020)=00000000 no Wakups enabled

SYST (d80b8024)=00000000 nothing being tested

MODULCTRL (d80b8028)=00000001 SINGLE CHANNEL MODE, MASTER, not SYSTEMTEST

CHCONF (d80b802c)=001103e0 PHA=0, POL=0, CLKD=0x8, EPOL=1,
         WL=0x7, TRM=0 (tx+rx mode), DMAW=0, DMAR=0,
        DPE0=1 (do not transmit on somi)
        DPE1=0 (transmit on simo)
        IS=0 (receive on somi)
        TURBO=0
        FORCE=1 (enable CS0)
        SPIENSLV=0 (not used in mastermode)
        SBE=0 no start bit
        SBPOL=0 start bit polarity =0
        TCS=0 cs toggle to clock time
        FFEW=0 fifo not enabled
        FFER=0 fifo not enabled
        CLKG=clock divider granulatity power of 2

CHSTAT (d80b8030)=00000002 TXS -- tx empty

CHCTRL (d80b8034)=00000001 Channel Enabled, EXTCLOCK=0

Everything looks good to me, maybe I misinterpreted something?.

I also tried disabling autoidle, but that didn't help either.

I also made sure that mcspi_ick and mcspi_fck are enabled as well, both by
calling clk_enable in the driver (which wasn't ever in there before), and by
examining the clock config registers.

Kevin

I was mistaken about clk_enable not being in the driver, it is in there.
But my problem persists. Rx is all zeros.

I've seen somewhat similar problem on pandora board, but there only
first byte was trashed. It appeared to be a problem in the driver, you
can try this patch:
http://marc.info/?l=linux-omap&m=122565580616920&w=2

I doubt it will fix this tough, your problem looks different.

Thanks for all who have tried to help on this. Its still not working.

In the mean time, I've coded up a simple bit bang spi routine, set the
padconf registers to mux the mcspi3(mode 1) pins to gpio(mode 4), and now I
can receive data through the bit-bang routine. This proves the
hardware/wiring/traces and everything else is correct. Since I can set
padconf to gpio/mode4 and input enable, as appropriate, it proves I'm
setting the right registers. This is only a temporary work around, so I can
continue, while looking for the real solution.

Unless there is something I'm overlooking, I don't believe the mcspi module
is working for receiving data. Has anyone else had success using mcspi3
and/or mcspi4?

Kevin

This is a great thread, I need to do something very similar. Is the
code you guys are talking about available anywhere? At least the bits
to laod the mcspi driver and setup the pin mux?

This would save me loads of time!

Philip

I've tried McSPI3 & McSPI4, and I got the same result, RX all zeros.
All the things I checked is the same with Kevin.
In my opinion, I also thought mcspi module may have problem to receive
data.
I have viewed the silicon errata of omap3530, but there is no function
exception about this issue.

Kevin, do you use gpio to simulate hardware spi?
Could you give me some sample codes to do so?
This would save me much time.

Philip, I have made some patches on my website.
http://www.csie.nctu.edu.tw/~yuchih/spi/
Hope it helps!
Maybe you could help us to figure where is the problem.

Yuchih

Yuchih wrote:

I've tried McSPI3 & McSPI4, and I got the same result, RX all zeros.
All the things I checked is the same with Kevin.
In my opinion, I also thought mcspi module may have problem to receive
data.
I have viewed the silicon errata of omap3530, but there is no function
exception about this issue.
  

One of my team also was having issues with this and posted a question or two late last year. We've been working on other items and haven't revisited this lately.

A couple of things to check (that I've thought of, but haven't looked into):

1) Make sure that OE is pulling recent code.....at one point we found the recipe was pulling code some 5 months old off of the git tree
2) Are the IO's being setup properly (I think this is still being done in Uboot)? I seem to remember several places that this could be mucked up.
3) There are some MCBSP driver patches that I'm not sure if they've made it into the main tree.....Tony Lindgren did the work with patches being released around September 24th.

Let me know if you have any success.

Thanks,

Keith

I've been having the same problem. I have verified that everything is
electrically connected (using GPIO) and that valid data is running
through the lines. I can watch data come into the omap on the miso
lines with my scope but the mcspi driver returns all zeros. I'm
wondering what the pandora people are doing to get around this problem
because they are using the same spi touchscreen chip as my project. I
wonder if everyone is using bitbanged spi...

~Kevin Kemper

Kevin,

That sounds quite interesting. Could you please post your bit bang
code?

Thanks in advance,

Gregoire

hello,

I have tried this patch. It works well for me!
http://lkml.indiana.edu/hypermail/linux/kernel/0810.2/1536.html

yuchih

Yuchih,

Thanks. I have patched my kernel and modified .config. I've read the
intro of the patch but I'm unsure how to modify mach-omap2/board-
omap3beagle.c to leverage this feature. Can you please paste your
code? If you don't have time, don't bother with a patch, snippet would
be enough,

Grégoire

Hello,
As information in the spi_gpio.h, there are two things you have to do.

1. register controller driver in arch/arm/mach-omap2/devices.c

diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/
devices.c
index 241e418..3ec6d04 100644
--- a/arch/arm/mach-omap2/devices.c
+++ b/arch/arm/mach-omap2/devices.c
@@ -14,6 +14,7 @@
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/io.h>
+#include <linux/spi/spi_gpio.h>

#include <mach/hardware.h>
#include <asm/mach-types.h>
@@ -278,6 +279,22 @@ static struct platform_device omap2_mcspi4 = {
};
#endif

+/*** added by yuchih***/
+static struct spi_gpio_platform_data spi5_gpio_platform_data = {
+ .miso = 138,
+ .mosi = 139,
+ .sck = 137,
+ .num_chipselect = 1,
+};