Project

General

Profile

SPI Comm - can transmit data from Linux, but not receive

Added by Jared Kirschner almost 8 years ago

Context:
- Hardware: MitySOM 5CSX board connected to another board containing several chips which communicate via SPI
- Software: the MitySOM processor is running the Altera Linux 4.1.22 LTSI RT kernel with a device tree I've customized based on the socfpga_cyclone5.dts device tree

[ Note: I had a long thread documenting the process of getting the above setup working -- https://support.criticallink.com/redmine/boards/45/topics/4963 ]

Problem:

I am attempting to communicate via SPI through a C++ program. I am able to write data to the correct device (meaning, I can control the chip select line properly), verified via scope traces of the SCLK, MOSI, and CS lines. I have also verified via scope traces that the chip I am attempting to communicate with is sending back the expected response on the processor's MISO line. Electrically, the communication is occurring as I expect.

However, the SPI receive buffer in my C++ program is always empty...

I've modified the kernel configuration and device tree to support SPI (a claim further supported by the scope traces). Relevant device tree snippet below:

&spi0 {
    status = "okay";

    spidev@0 {
        /* spidev causes a WARN_ON() so spoof with DAC compat */
        compatible = "rohm,dh2228fv";
        reg = <0>;    /* chip select */
        spi-max-frequency = <100000000>;
        enable-dma = <1>;
    };
    spidev@1 {
        /* spidev causes a WARN_ON() so spoof with DAC compat */
        compatible = "rohm,dh2228fv";
        reg = <1>;    /* chip select */
        spi-max-frequency = <100000000>;
        enable-dma = <1>;
    };
};

A simplified version of the relevant C++ test code which I've been trying to make work before proceeding/refactoring is attached (spi_test.cc). The output of the program generally looks like:

...
file: spi mode 2, 8 bits per word, 100000000 Hz max
STARTING SPI
rx: 0000 0000 0000 0000
BUFFER:
...

Do you have any examples of communicating with an SPI device from a MitySOM 5CSX board? And do you have any suspicions regarding the root cause of the empty receive buffer? Without other input, my next step might be to dig into the kernel-level SPI driver, but that's a rabbit hole I'd rather not enter unless there isn't a more likely cause (I've ruled out most of my suspicions already / fixed some problems along the way to getting the scope traces described above).

Please let me know if you need any clarification, elaboration, or additional information.

Thanks,
Jared


Replies (20)

RE: SPI Comm - can transmit data from Linux, but not receive - Added by Michael Williamson almost 8 years ago

Have you tried using the Loopback option to see if you can just loop back the command data and if RX is OK?

-Mike

RE: SPI Comm - can transmit data from Linux, but not receive - Added by Jared Kirschner almost 8 years ago

Are you referring to modifying the FPGA such that MOSI is connected to MISO?
If that works, it might indicate that somehow our MISO signal isn't hooked up correctly in the FPGA (which I'd be surprised by due to another test described below)
If it doesn't work, we know it's not caused by something outside the FPGA, and is limited to the processor + FPGA (e.g., device tree, Linux kernel driver, the test C++ code)

As stated in the initial post, I've verified that, if I send something via MOSI, I can see the proper response on the physical MISO line (with an oscilloscope), I just don't see anything on the processor. The hardware engineer on the project and I also recall piping the MISO pin going into the FPGA out to a test pin to probe, verifying that the MISO signal was actually making its way into the FPGA on the pin we expected.

We'll try your suggestion tomorrow and see what happens - it should give us more information whatever the result! I'll report back what we find.

Thanks,
Jared

RE: SPI Comm - can transmit data from Linux, but not receive - Added by Jared Kirschner almost 8 years ago

Hello Mike,

We've since conducted a loopback test (MOSI connected to MISO within the FPGA) and observed no change in behavior (still an empty receive buffer). The SCLK and CS lines are still behaving as expected as measured by an oscilloscope, indicating that SPI communication is being attempted (confirming the loopback test is actually running).

If you have an example of SPI communication working on the stock Linux system provided with the MitySOM 5CSX, that could help point to whether the cause is a device tree difference, an application code difference, perhaps a kernel-level/driver difference (as I'm using a 4.1.22), or something else.

Thanks,
Jared

RE: SPI Comm - can transmit data from Linux, but not receive - Added by Michael Williamson almost 8 years ago

Here is some example code from the linux kernel documentation area.

BTW: our FPGA driver and the SPI HPS "hardcore" have a built in loopback mode, so you don't need to physically rewire the FPGA at the top level.

Can you run this with the loop back option set? Also, you might try running the test using a slow clock speed (try 10 MHz, just to get started). 100 MHz seems too fast. I don't think our FPGA driver supports that, and I am not sure if the HPS SPI peripheral can run that fast for receive.

/spidev_test -D /dev/spidevX.0

RE: SPI Comm - can transmit data from Linux, but not receive - Added by Jared Kirschner almost 8 years ago

Hello Mike,

I just saw this message, and will try it out first thing tomorrow. Unfortunately, a snow storm is preventing me from being in the office to try this out today.

Thanks,
Jared

RE: SPI Comm - can transmit data from Linux, but not receive - Added by Jared Kirschner almost 8 years ago

Hello Mike,

I modified the SPI device tree entry to have an "spi-max-frequency" of 1 MHz (a slow clock speed, as you suggested, to get started).

I kept the FPGA image in which we connected MOSI to MISO (rather than using the "loop back option" for the SPI HPS core). Our hardware engineer didn't see a "loop back mode configuration"; here's the HPS configuration we are using if it's relevant: https://continuumfiles.egnyte.com/fl/Jj8iCapDWn#folder-link/

I compiled and executed spidev_test and ran with the suggested settings.

The output was consistently:

spi mode: 0
bits per word: 8
max speed: 500000 Hz (500 KHz)

00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00
1 cycles run

I had a scope on the SCLK, and verified that a transfer was being attempted. That said, (I don't know whether this is germane, but) SCLK wasn't at the frequency I expected. When I set speed (-s flag) to 500 kHz (default), I observe an SCLK around 30 kHz; if I use the -s flag to set the speed to 250 kHz, I observe an SCLK around 15 kHz. Lastly, when I set the clock rate to 166.667 kHz, I observe an SCLK around 10 kHz... indicating the ratio between speed_hz and observed SCLK is at least consistent, though seems to be a factor of 16.66.. off (approximately).

When you say the FPGA driver and SPI HPS core have a built in loop back mode, what specifically should we be changing? (As previously stated, our hardware engineer didn't see such options.) And would you expect the behavior of this loop back mode to be any different than just connecting MOSI to MISO?

Thanks,
Jared

RE: SPI Comm - can transmit data from Linux, but not receive - Added by Daniel Vincelette almost 8 years ago

Hi Jared,

I'm in the middle of recreating your test with one of our dev kits. I'll connect up the MOSI to the MISO in the FPGA and run your test app. I'll let you know what I see, should be by end of day. I'll look into the RX issue first then see about tackling the odd speeds.

Dan

RE: SPI Comm - can transmit data from Linux, but not receive - Added by Daniel Vincelette almost 8 years ago

Hi Jared,

Unluckily I wasn't able to recreate the issue you are seeing. My RX buffer has the expected 0x8330 instead of 0x0000 after running. Would you mind posting the following: uImage, DTB, and DTS?

I'll try to run with your uImage and DTB to help pin point the issue.

Thanks!

Dan

RE: SPI Comm - can transmit data from Linux, but not receive - Added by Jared Kirschner almost 8 years ago

Hello Dan,

I've attached the requested files (Linux 4.1.22 LTSI RT branch compiled into "uImage" with defconfig "socfpga_mitysom5csx_custom_defconfig", and the device tree binary and source files).

That you were able to get the expected 0x8330 in the quick & dirty test program rules out a problem in the C++ test code...

I have not tried the SPI test program on any other Linux kernel version (e.g., 3.16) yet, but I may soon if I have time.

Thanks,
Jared

Linux_4.1.22-ltsi-rt_SPI.zip (3.95 MB) Linux_4.1.22-ltsi-rt_SPI.zip Linux kernel and device tree files

RE: SPI Comm - can transmit data from Linux, but not receive - Added by Daniel Vincelette almost 8 years ago

I've tried it with our 3.16 kernel and Altera's 4.1.22 and 4.1.22 RT kernel. All get data on the RX side. I'll try your kernel and device tree this morning and get back to you.

Dan

RE: SPI Comm - can transmit data from Linux, but not receive - Added by Daniel Vincelette almost 8 years ago

I've tried your kernel and the RX buffer is still working. I couldn't get uboot to actually boot your device-tree, I try rebuilding it and that didn't work either.

I've attached the dts/dtb I'm using.

Dan

RE: SPI Comm - can transmit data from Linux, but not receive - Added by Jared Kirschner almost 8 years ago

Hello Dan,

I replaced the uImage on my SD card (at /boot) with the uImage I sent you (to ensure it's the same as what you tested), and replaced the DTB with the DTB you attached (also in /boot).

I rebooted the card and ran the C++ tests (both the spidev_test.cc file Critical Link supplied, and the initial test code I provided), but the receive buffer still only contains zeroes (and I have a scope showing SCLK is still doing what I expect during the life of the test, and /dev/spidev32766.0 exists).

That seems to rule out the kernel configuration and kernel, if running the same uImage I see nothing in the receive buffer but you see the expected data.

What other parts of the system could be the cause? Differences that remain which I am aware of are:
- A different FPGA image
- Possibly a different u-boot (you mentioned you couldn't get u-boot to actually boot my device-tree, though I could, indicating a difference)

Could you attach your FPGA image / u-boot? Or do you recommend trying something else?

Thanks,
Jared

RE: SPI Comm - can transmit data from Linux, but not receive - Added by Daniel Vincelette almost 8 years ago

I've attached my preloader/uboot/fpga image.

I've also attached the spi_test c++ code I was working with, I've removed the chrono's part because I was having issues with getting to build with my toolchain (I'm not sure if it supports c++11 or not).

Dan

RE: SPI Comm - can transmit data from Linux, but not receive - Added by Jared Kirschner almost 8 years ago

Hello Dan,

When re-building an SD card image using my kernel (uImage), the DTB you attached, and the FPGA image (.rbf), U Boot image, and preloader image you attached, I am able to see data in the receive buffer.

That suggests to me that the problem is in one of the following: FPGA image, U Boot image, preloader image. Do you have any suspicions as to which is the most likely culprit? (We can send the FPGA image if that would be helpful.)

Some related, additional information: my hardware engineer colleague and I aren't sure in what ways the preloader generation depends on the FPGA image, but I believe we may not have regenerated the preloader very recently (SPI was possibly added to the FPGA after the preloader was last regenerated). Under what conditions does an FPGA change require preloader regeneration (if not always)?

Thanks,
Jared

RE: SPI Comm - can transmit data from Linux, but not receive - Added by Daniel Vincelette almost 8 years ago

Im thinking it's related to the preloader. The preloader is the one who does all the pin muxing for the HPS peripherals (including muxing any of these interfaces to the FPGA). If any HPS peripheral or any of the bridges between HPS and FPGA are changed the preloader should be regenerated.

I would recommend trying to regenerate your preloader and trying all your own binaries again. Let me know how that goes.

Dan

RE: SPI Comm - can transmit data from Linux, but not receive - Added by Jared Kirschner over 7 years ago

Hello Dan,

I'm back from vacation and looking into this again with my hardware engineer colleague. Our first attempt at regenerating the preloader based on our current FPGA image didn't result in working loopback communication, so we're trying to step through the possible causes and rule things out (between the U Boot image, preloader, FPGA image, and device tree).

Would it be possible for you to send your FPGA project (used to generate the .rbf and preloader) and the device tree source you used? We'll try to get the same result from those inputs (generating our own .rbf and preloader from the project, and compiling the device tree binary), just to see if we're doing something wrong in this part of the process. If we're not, at least we can narrow it down to something in our FPGA code or device tree source.

Thanks,
Jared

RE: SPI Comm - can transmit data from Linux, but not receive - Added by Jared Kirschner over 7 years ago

Edit: I see the device tree source above, so the FPGA project is the only information we'd need.

RE: SPI Comm - can transmit data from Linux, but not receive - Added by Jared Kirschner over 7 years ago

Update:

We got loopback working (so no longer need the FPGA project to compare with).

After regenerating our preloader, the loopback behavior changed, in that the operation hung rather than returning with an empty receive buffer.

Next, we tested all permutations of the device tree, FPGA image, and preloader (after ruling out U-boot), we narrowed the problem down to the FPGA image. The hps_0_spim0_ss_in_n signal on the hard processor instance was left explicitly unconnected; after tying it to 1, loopback started working.

In conclusion: we needed to regenerate the preloader for our current FPGA image, and tie the hps_0_spim0_ss_in_n signal to 1 (fix an FPGA bug).

RE: SPI Comm - can transmit data from Linux, but not receive - Added by Daniel Vincelette over 7 years ago

That's awesome to hear! Sorry for the bit of delay, I was working on packaging up my old build to send out to you guys.

Glad to hear you got it working.

Dan

RE: SPI Comm - can transmit data from Linux, but not receive - Added by Jared Kirschner over 7 years ago

For completeness:

I think the reason U-boot wouldn't boot the device tree I attached for you is because it's too large for the ubootenv.bin you are using.

In uBootMMCEnv.txt (used to generate ubootenv.bin), loadkerneladdr needs to be changed to be large enough to fit the device tree. The suggested uBootMMCEnv.txt has loadkerneladdr=0x7fc0, and the stock device tree is just smaller than that size. The device tree I attached is a bit larger than 0x7fc0 (I had the same problem as you at some point); changing loadkerneladdr to 0xffc0 resolved the issue.

Thanks for all the help!

    (1-20/20)
    Go to top
    Add picture from clipboard (Maximum size: 1 GB)