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.

AM3351: Linux support for SPI as a slave device

Part Number: AM3351

Our application uses two SPI peripheral devices each operating unidirectional.  

The SPI master uses the MOSI pin to send commands from the AM3351 to another processor.

At the same time using a second, distinct SPI peripheral on the AM3351, that SPI should be configured to use the MOSI pin to receive asynchronous responses and events from the other processor which is the master on that SPI bus and drives the CLK, CS, and MOSI from its side.  The AM3351 should have a large receive buffer which accumulates data from the other processor.  The AM3351 occasionally polls the slave SPI buffer and reads from it.

Is there any example code available for using the SPI devices on the AM3351 or similar under Linux in this fashion?  

If not, what example code is available for SPI interface on the AM3351 under Linux?

Thank you in advance for any help on this matter.

  • Is there any example code available for using the SPI devices on the AM3351 or similar under Linux in this fashion?  

    If not, what example code is available for SPI interface on the AM3351 under Linux?

    Basic SPI usage/documentation for AM335x is available in the respective SDK Kernel SPI module section at https://software-dl.ti.com/processor-sdk-linux/esd/AM335X/08_02_00_24/exports/docs/linux/Foundational_Components/Kernel/Kernel_Drivers/SPI.html

    Also, unlike what the SDK documentation suggests, SPI slave mode is actually supported, in DMA mode (I just filed an internal request to get those docs updated).

    The SPI slave mode is enabled through the spi-slave device tree property. If you search (`git grep`) the Kernel source tree you can find some examples how it's used in the device tree. I'm not aware of a ready-to use example for SPI slave mode on AM335x though.

    Then, there's a SPI slave mode example available on a different platform, see https://software-dl.ti.com/jacinto7/esd/processor-sdk-linux-jacinto7/08_06_00_11/exports/docs/linux/Foundational_Components/Kernel/Kernel_Drivers/SPI.html (end of this section). It uses two SPI devices connected together, one operated in slave mode, to demonstrate some loopback capability. So you could look at this as well.

    Our application uses two SPI peripheral devices each operating unidirectional.  

    If you want to connect two processors together using a serial link, why not use UART instead?

    • You can (and should) use HW flow control, completely and autonomously managing all data transfers, avoiding data loss/corruption
    • Less wiring effort
    • More "standard" interface, you can even route IP traffic over it easily if you wanted to
    • Easy to probe/analyze

    Regards, Andreas

  • Thank you Andreas.  Please advise when the those documents get updated.  Meanwhile we will dig into the information you've provided.

  • Please advise when the those documents get updated. 

    I just put the request into the queue yesterday, not sure when changes will be made and become live. It might be a month or two, in alignment with an upcoming SD v9.x refresh release of the SDK. The change regarding SPI will only be to say that the SPI slave mode is supported (w/ DMA) by the driver nothing more.

    Also as to my earlier point, I'd seriously explore other communication interfaces besides SPI.

    Regards, Andreas

  • Regarding your comment "I'd seriously explore other communication interfaces besides SPI", what would you recommend for supporting cost effective (zero glue logic) bursty, event driven, up to 5Mbps communications between two processors on the same PCB?

  • Hi Thomas,

    , what would you recommend for supporting cost effective (zero glue logic) bursty, event driven, up to 5Mbps communications between two processors on the same PCB?

    ah ok, if you need up to 5Mbps you can't use one of the "main" UARTs, which top out at about 3.6Mbps. However the AM335x devices have an alternate UART called "PRU UART" that is part of the PRU sub-system, that is capable of communication up to 12Mbps, while also supporting full hardware handshake. Fortunately, the use of this UART is not limited to the PRU sub-system itself, but it can also be used from Linux, please see here:

    https://software-dl.ti.com/processor-sdk-linux/esd/AM335X/08_02_00_24/exports/docs/linux/Foundational_Components/PRU-ICSS/Linux_Drivers/pruss-uart.html

    Regards, Andreas

  • Andreas Dannenberg said:

    there's a SPI slave mode example available on a different platform, see https://software-dl.ti.com/jacinto7/esd/processor-sdk-linux-jacinto7/08_06_00_11/exports/docs/linux/Foundational_Components/Kernel/Kernel_Drivers/SPI.html (end of this section).

    With 335x SDK v5 we had to write the slave side b/c the driver did not support it. In porting our code to SDK v8, we'd like to use the new driver as-is. I downloaded the J7200 SDK but don't see any reference to the example master-slave mode code or k3-j7200-mcspi-loopback.dtsi in u-boot. Can you verify our DTS nodes below for spi0 & spi1, or point me to the omap2 McSPI node reference. 

    SPI0 is in slave mode and SPI1 is in master mode.

    /* Multichannel Serial Port Interface (McSPI) */
    &spi0 {
      status = "okay";
      pinctrl-names = "default";
      pinctrl-0 = <&spi0_pins>;
      ti,pindir-d0-out-d1-in = <1>;
      #address-cells = <1>;
      #size-cells = <0>;
    
      slave@0 {
        compatible = "slave,bf548";
        #address-cells = <1>;
        #size-cells = <0>;
        reg = <0>;
        spi-max-frequency = <32000000>;
        spi-cpha;
      };
    };
    
    &spi1 {
      status = "okay";
      pinctrl-names = "default";
      pinctrl-0 = <&spi1_pins>;
      #address-cells = <1>;
      #size-cells = <0>;
    
      channel@0 {
        compatible = "master,bf548";
        #address-cells = <1>;
        #size-cells = <0>;
        reg = <0>;
        spi-max-frequency = <16000000>;
        spi-cpha;
      };
    };

    Currently the only relevant kernel boot messages (very early in the boot) are from added debug pr_info() statements in omap2_mcspi_request_dma() indicating a successful McSPI DMA request.

    [    2.669438] spi_omap2_mcspi:omap2_mcspi_request_dma: DMA requested (rx0, ch=41).
    [    2.677012] spi_omap2_mcspi:omap2_mcspi_request_dma: DMA requested (tx0, ch=40).
    [    2.684530] spi_omap2_mcspi:omap2_mcspi_request_dma: DMA requested (rx1, ch=43).
    [    2.691995] spi_omap2_mcspi:omap2_mcspi_request_dma: DMA requested (tx1, ch=42).
    

  • I downloaded the J7200 SDK but don't see any reference to the example master-slave mode code or k3-j7200-mcspi-loopback.dtsi in u-boot. Can you verify our DTS nodes below for spi0 & spi1, or point me to the omap2 McSPI node reference. 

    SDK v8.6 is based on kernel ti-linux-5.10.y. You can find the respective device tree code here:
    https://git.ti.com/cgit/ti-linux-kernel/ti-linux-kernel/tree/arch/arm64/boot/dts/ti/k3-j7200-mcspi-loopback.dts?h=ti-linux-5.10.y

    As for the DTS code snippet you posted, you need to rework/debug this so that it works with the "new" SPI slave driver capability. For example at least one of your nodes will need a spi-slave; property in it. Also your compatible strings look odd, but I suppose it's something connecting to a custom driver you have.

    Regards, Andreas