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.

Opening SPI interface on Sitara



Hello,

We've been trying to access the SPI interface on our board with Sitara SoC. We are using the Android Gingerbread port built for this platform (and it's working). According to kernel/arch/arm/mach-omap2/board-ti8168evm.c, our interface is configured as bus 1 chip select 0. We compiled kernel/Documentation/spi/spidev_test.c as staticly linked ARM executable and tried to use it via console on our board by executing

./spidev_test -D /sys/devices/platform/omap2_mcspi.1/spi1.0/modalias

It manages to open the device, but fails to set the mode via ioctl function, giving us the "can't set spi mode: Inappropriate ioctl for device" message, for any combination of modes.

The program offers the following options:

Usage: ./spidev_test [-DsbdlHOLC3]
  -D --device   device to use (default /dev/spidev1.1)
  -s --speed    max speed (Hz)
  -d --delay    delay (usec)
  -b --bpw      bits per word
  -l --loop     loopback
  -H --cpha     clock phase
  -O --cpol     clock polarity
  -L --lsb      least significant bit first
  -C --cs-high  chip select active high
  -3 --3wire    SI/SO signals shared

Is it possible that ioctl is actually not supported for SPI on Sitara? Kernel documentation states that basic open/read/write/close mechanism offers only half duplex, but to use full duplex, we need ioctl which passes send and recieve arrays in a structure to driver.

So any help related to working with SPI on these chips will be much appreciated!

  • Ok, we have figured out this was not the usable SPI driver (it was there only for communication with EEPROM), so we added the real driver which sets up its /dev/spidev1.0 device and now it works.

  • Im just starting to work on the SPI interface on the AM335x Starter Kit.

    Would you happen to have a pointer on how to get started?

    Do I need to build a kernel or is there a simpler way?

    kind regards

    Jesper Taxbøl 

  • If you just need generic support for SPI interface, then simply enable SPIDEV support in kernel config (/arch/arm/configs/your_board, CONFIG_SPI_SPIDEV) and add spidev devices into the appropriate spi slave structure in /arch/arm/mach-omap2/board-yourboard.c and rebuild kernel from clean. For this Sitara we were using, it looked like this:

    struct spi_board_info __initdata ti816x_spi_slave_info[] = {
        {
            .modalias    = "m25p32",
            .platform_data    = &ti816x_spi_flash,
            .irq        = -1,
            .max_speed_hz    = 40000000,
            .bus_num    = 1,
            .chip_select    = 0,
        },
        {
            .modalias    = "spidev",
            .irq        = -1,
            .max_speed_hz    = 40000000,
            .bus_num    = 1,
            .chip_select    = 1,
        },
        {
            .modalias    = "spidev",
            .irq        = -1,
            .max_speed_hz    = 40000000,
            .bus_num    = 1,
            .chip_select    = 2,
        },
        {
            .modalias    = "spidev",
            .irq        = -1,
            .max_speed_hz    = 40000000,
            .bus_num    = 1,
            .chip_select    = 3,
        },
    };

    Device on the first chip select is handled by M25P32 driver, while other chip selects are covered by SPIDEV driver. So at runtime, you just open /dev/spidev1.1 (first bus, second chip select, make sure you have read/write access to this virtual file) and you do appropriate ioctl calls for full duplex transfers.

  • in my board-am355xevm.c i have:

    /*
    * SPI Flash works at 80Mhz however SPI Controller works at 48MHz.
    * So setup Max speed to be less than that of Controller speed
    */
    static struct spi_board_info am335x_spi0_slave_info[] = {
    {
    .modalias = "m25p80",
    .platform_data = &am335x_spi_flash,
    .irq = -1,
    .max_speed_hz = 24000000,
    .bus_num = 1,
    .chip_select = 0,
    },
    };

    static struct spi_board_info am335x_spi1_slave_info[] = {
    {
    .modalias = "m25p80",
    .platform_data = &am335x_spi_flash,
    .irq = -1,
    .max_speed_hz = 12000000,
    .bus_num = 2,
    .chip_select = 0,
    },
    };

    So I would replace m25p80 with spidev to have it running as a SPI dev device?

    Kind regards

    Jesper 

  • Yes, just remove the platform_data field and don't forget to turn on the SPIDEV driver in kernel config.


    You can then do simultaneous read-write via SPI like this:

    https://www.kernel.org/doc/Documentation/spi/spidev_test.c

    (see the "transfer" function).


    This method also works from within an Android application, you will just have to write SPI access part in C, and connect it with the Java part of application using JNI interface.

  • Thanx for your input. It sounds very good.

    Is the compiler built into the android platform so I just develop through a console. Or do i need to do it on my host PC and transfer the binary?

    I currently fighting building a custom SD card image, so Im not actually there yet but I'm studying. I have huge problems following the guide here, as it does not seem to produce any output files.

    Kind regards and merry christmas

    Jesper Taxbøl

     

  • Can't help you with this precisely, back then I was working with Android 2.3 on Sitara AM3894, I don't know how much has changed since then. But as far as I remember, you should have the necessary toolchain included your Android Rowboat, which you use then to build the kernel and Android itself.

    These TI's Android guides are not free from errors because it seems that the same people maintain guides for several platform, so it may happen that file/directory names get mixed up, maybe that's why you don't get any output files.

    For applications, I was using Eclipse IDE with Android SDK (for Java parts of application) and Android NDK (for C parts of application), it worked fine but it was messy to set it up properly in the first place.

  • I Just enabled the CONFIG_SPI_SPIDEV by adding "CONFIG_SPI_SPIDEV=y" to the kernel/arch/arm/configs/am335x_evm_defconfig.

    I also added the spidev in the board info file board-am355xevm.c:

    Thereafter i did a "make clean" followed by a "make TARGET_PRODUCT=am335xevm_sk OMAPES=4.x -j1" and a "make TARGET_PRODUCT=am335xevm_sk OMAPES=4.x -j1 sdcard_build"

    When I boot the device there is no /dev/spidev devices yet, but the following can be read from dmesg:

    root@android:/ # dmesg | grep spi                                              

    <4>[    0.193786]  omap2_mcspi.1: alias fck already exists

    <4>[    0.193908]  omap2_mcspi.2: alias fck already exists

    root@android:/ # 

    Any idea what I could be doing wrong?

    Kind regards

    Jesper