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.

AM3358: SPI

Part Number: AM3358

Hi

I am trying to enable spi1 in am3358. But in am33xx.dtsi, i observed that spi1  and many things like i2c0, i2c2 all are disabled. But i2c0 is used internally in beaglebone black then why it is disabled in this file. can anyone help me to figure out why it is so given? I am using beaglebone black.

spi1: spi@481a0000 {
            compatible = "ti,omap4-mcspi";
            #address-cells = <1>;
            #size-cells = <0>;
            reg = <0x481a0000 0x400>;
            interrupts = <125>;
            ti,spi-num-cs = <2>;
            ti,hwmods = "spi1";
            dmas = <&edma 42 0
                &edma 43 0
                &edma 44 0
                &edma 45 0>;
            dma-names = "tx0", "rx0", "tx1", "rx1";
            status = "disabled";
        };

i2c0: i2c@44e0b000 {
            compatible = "ti,omap4-i2c";
            #address-cells = <1>;
            #size-cells = <0>;
            ti,hwmods = "i2c1";
            reg = <0x44e0b000 0x1000>;
            interrupts = <70>;
            status = "disabled";
        };

Thanks & Regards

Sandeep Kumar

  • Sandeep,

    am33xx.dtsi is a device tree include file and is used to create a baseline off which individual boards are based on. The idea is this base file has many peripherals disabled, which will get turned on as needed by the board specific dts files that include am33xx.dtsi. For example, for the BeagleBone Black top level DTS file is https://git.ti.com/cgit/ti-linux-kernel/ti-linux-kernel/tree/arch/arm/boot/dts/am335x-boneblack.dts?h=ti-linux-4.19.y. This file also includes https://git.ti.com/cgit/ti-linux-kernel/ti-linux-kernel/tree/arch/arm/boot/dts/am335x-bone-common.dtsi?h=ti-linux-4.19.y which will turn on certain peripherals like I2C that were initially disabled in the am33xx.dtsi base file. So basically, you have to think oft the device tree files in a layered fashion. To see what is active, start from the top level and work your way backwards. You can also reverse-compile the final device tree blob (*.dtb) back into source code to have ultimate clarify what the resulting device tree file the Kernel is using is (invoke the device tree compiler as 'dtc -I dtb am335x-boneblack.dtb'

    Regards, Andreas

  • Hi

    Thanks for clearing my doubt.  I have one more question regarding dts. I have changed the dts file in "am335x-bone-common.dtsi" like following lines....Is it ok?

    Note:I want uart0(for console), uart1, spi0, spi1, i2c0(it is used internally for board), i2c2. I did this but i didn't get i2c and spi enable in /dev/tty*.


    &am33xx_pinmux {
        pinctrl-names = "default";
        pinctrl-0 = <&clkout2_pin>;

        user_leds_s0: user_leds_s0 {
            pinctrl-single,pins = <
                AM33XX_IOPAD(0x854, PIN_OUTPUT_PULLDOWN | MUX_MODE7)    /* gpmc_a5.gpio1_21 */
                AM33XX_IOPAD(0x858, PIN_OUTPUT_PULLUP | MUX_MODE7)    /* gpmc_a6.gpio1_22 */
                AM33XX_IOPAD(0x85c, PIN_OUTPUT_PULLDOWN | MUX_MODE7)    /* gpmc_a7.gpio1_23 */
                AM33XX_IOPAD(0x860, PIN_OUTPUT_PULLUP | MUX_MODE7)    /* gpmc_a8.gpio1_24 */
            >;
        };

        i2c0_pins: pinmux_i2c0_pins {
            pinctrl-single,pins = <
                AM33XX_IOPAD(0x988, PIN_INPUT_PULLUP | MUX_MODE0)    /* i2c0_sda.i2c0_sda */
                AM33XX_IOPAD(0x98c, PIN_INPUT_PULLUP | MUX_MODE0)    /* i2c0_scl.i2c0_scl */
            >;
        };

        i2c2_pins: pinmux_i2c2_pins {
            pinctrl-single,pins = <
                AM33XX_IOPAD(0x978, PIN_INPUT_PULLUP | MUX_MODE3)    /* uart1_ctsn.i2c2_sda */
                AM33XX_IOPAD(0x97c, PIN_INPUT_PULLUP | MUX_MODE3)    /* uart1_rtsn.i2c2_scl */
            >;
        };

        uart0_pins: pinmux_uart0_pins {
            pinctrl-single,pins = <
                AM33XX_IOPAD(0x970, PIN_INPUT_PULLUP | MUX_MODE0)    /* uart0_rxd.uart0_rxd */
                AM33XX_IOPAD(0x974, PIN_OUTPUT_PULLDOWN | MUX_MODE0)    /* uart0_txd.uart0_txd */
            >;
        };
    /*******************************for uart1***************************************************/

        uart1_pins: pinmux_uart1_pins {
            pinctrl-single,pins = <
                AM33XX_IOPAD(0x980, PIN_INPUT_PULLUP | MUX_MODE0)    /* uart1_rxd.uart1_rxd */
                AM33XX_IOPAD(0x984, PIN_OUTPUT_PULLDOWN | MUX_MODE0)    /* uart1_txd.uart1_txd */
            >;
        };
    /***********************************************************************************************/



    /******************************for SPI*****************************************************/    
        spi0_pins: pinmux_spi0_pins {
                   pinctrl-single,pins = <
                AM33XX_IOPAD(0x950, PIN_INPUT_PULLUP | MUX_MODE0)    /* spi0_sclk*/
                AM33XX_IOPAD(0x954, PIN_INPUT_PULLUP | MUX_MODE0)    /* spi0_d0*/
                AM33XX_IOPAD(0x958, PIN_OUTPUT_PULLUP | MUX_MODE0)    /* spi0_d1*/
                AM33XX_IOPAD(0x95c, PIN_OUTPUT_PULLUP | MUX_MODE0)    /* spi0_cs0*/
                          
             >;
            };


        spi1_pins: pinmux_spi1_pins {
            pinctrl-single,pins = <
                AM33XX_IOPAD(0x990, PIN_INPUT_PULLUP | MUX_MODE3) /* spi1_sclk */
                AM33XX_IOPAD(0x994, PIN_INPUT_PULLUP | MUX_MODE3) /* spi1_d0 */
                AM33XX_IOPAD(0x998, PIN_OUTPUT_PULLUP | MUX_MODE3) /* spi1_d1 */
                AM33XX_IOPAD(0x99C, PIN_OUTPUT_PULLUP | MUX_MODE3) /* spi1_cs0 */
            >;
    };
    /************************************************************************************************/

        clkout2_pin: pinmux_clkout2_pin {
            pinctrl-single,pins = <
                AM33XX_IOPAD(0x9b4, PIN_OUTPUT_PULLDOWN | MUX_MODE3)    /* xdma_event_intr1.clkout2 */
            >;
        };

        cpsw_default: cpsw_default {
            pinctrl-single,pins = <
                /* Slave 1 */
                AM33XX_IOPAD(0x910, PIN_INPUT_PULLUP | MUX_MODE0)    /* mii1_rxerr.mii1_rxerr */
                AM33XX_IOPAD(0x914, PIN_OUTPUT_PULLDOWN | MUX_MODE0)    /* mii1_txen.mii1_txen */
                AM33XX_IOPAD(0x918, PIN_INPUT_PULLUP | MUX_MODE0)    /* mii1_rxdv.mii1_rxdv */
                AM33XX_IOPAD(0x91c, PIN_OUTPUT_PULLDOWN | MUX_MODE0)    /* mii1_txd3.mii1_txd3 */
                AM33XX_IOPAD(0x920, PIN_OUTPUT_PULLDOWN | MUX_MODE0)    /* mii1_txd2.mii1_txd2 */
                AM33XX_IOPAD(0x924, PIN_OUTPUT_PULLDOWN | MUX_MODE0)    /* mii1_txd1.mii1_txd1 */
                AM33XX_IOPAD(0x928, PIN_OUTPUT_PULLDOWN | MUX_MODE0)    /* mii1_txd0.mii1_txd0 */
                AM33XX_IOPAD(0x92c, PIN_INPUT_PULLUP | MUX_MODE0)    /* mii1_txclk.mii1_txclk */
                AM33XX_IOPAD(0x930, PIN_INPUT_PULLUP | MUX_MODE0)    /* mii1_rxclk.mii1_rxclk */
                AM33XX_IOPAD(0x934, PIN_INPUT_PULLUP | MUX_MODE0)    /* mii1_rxd3.mii1_rxd3 */
                AM33XX_IOPAD(0x938, PIN_INPUT_PULLUP | MUX_MODE0)    /* mii1_rxd2.mii1_rxd2 */
                AM33XX_IOPAD(0x93c, PIN_INPUT_PULLUP | MUX_MODE0)    /* mii1_rxd1.mii1_rxd1 */
                AM33XX_IOPAD(0x940, PIN_INPUT_PULLUP | MUX_MODE0)    /* mii1_rxd0.mii1_rxd0 */
            >;
        };

        cpsw_sleep: cpsw_sleep {
            pinctrl-single,pins = <
                /* Slave 1 reset value */
                AM33XX_IOPAD(0x910, PIN_INPUT_PULLDOWN | MUX_MODE7)
                AM33XX_IOPAD(0x914, PIN_INPUT_PULLDOWN | MUX_MODE7)
                AM33XX_IOPAD(0x918, PIN_INPUT_PULLDOWN | MUX_MODE7)
                AM33XX_IOPAD(0x91c, PIN_INPUT_PULLDOWN | MUX_MODE7)
                AM33XX_IOPAD(0x920, PIN_INPUT_PULLDOWN | MUX_MODE7)
                AM33XX_IOPAD(0x924, PIN_INPUT_PULLDOWN | MUX_MODE7)
                AM33XX_IOPAD(0x928, PIN_INPUT_PULLDOWN | MUX_MODE7)
                AM33XX_IOPAD(0x92c, PIN_INPUT_PULLDOWN | MUX_MODE7)
                AM33XX_IOPAD(0x930, PIN_INPUT_PULLDOWN | MUX_MODE7)
                AM33XX_IOPAD(0x934, PIN_INPUT_PULLDOWN | MUX_MODE7)
                AM33XX_IOPAD(0x938, PIN_INPUT_PULLDOWN | MUX_MODE7)
                AM33XX_IOPAD(0x93c, PIN_INPUT_PULLDOWN | MUX_MODE7)
                AM33XX_IOPAD(0x940, PIN_INPUT_PULLDOWN | MUX_MODE7)
            >;
        };

        davinci_mdio_default: davinci_mdio_default {
            pinctrl-single,pins = <
                /* MDIO */
                AM33XX_IOPAD(0x948, PIN_INPUT_PULLUP | SLEWCTRL_FAST | MUX_MODE0)    /* mdio_data.mdio_data */
                AM33XX_IOPAD(0x94c, PIN_OUTPUT_PULLUP | MUX_MODE0)            /* mdio_clk.mdio_clk */
            >;
        };

        davinci_mdio_sleep: davinci_mdio_sleep {
            pinctrl-single,pins = <
                /* MDIO reset value */
                AM33XX_IOPAD(0x948, PIN_INPUT_PULLDOWN | MUX_MODE7)
                AM33XX_IOPAD(0x94c, PIN_INPUT_PULLDOWN | MUX_MODE7)
            >;
        };

        mmc1_pins: pinmux_mmc1_pins {
            pinctrl-single,pins = <
                AM33XX_IOPAD(0x960, PIN_INPUT | MUX_MODE7)        /* spio0_cs1.gpio0_6 */
                AM33XX_IOPAD(0x8fc, PIN_INPUT_PULLUP | MUX_MODE0)    /* mmc0_dat0.mmc0_dat0 */
                AM33XX_IOPAD(0x8f8, PIN_INPUT_PULLUP | MUX_MODE0)    /* mmc0_dat1.mmc0_dat1 */
                AM33XX_IOPAD(0x8f4, PIN_INPUT_PULLUP | MUX_MODE0)    /* mmc0_dat2.mmc0_dat2 */
                AM33XX_IOPAD(0x8f0, PIN_INPUT_PULLUP | MUX_MODE0)    /* mmc0_dat3.mmc0_dat3 */
                AM33XX_IOPAD(0x904, PIN_INPUT_PULLUP | MUX_MODE0)    /* mmc0_cmd.mmc0_cmd */
                AM33XX_IOPAD(0x900, PIN_INPUT_PULLUP | MUX_MODE0)    /* mmc0_clk.mmc0_clk */
                AM33XX_IOPAD(0x9a0, PIN_INPUT | MUX_MODE4)        /* mcasp0_aclkr.mmc0_sdwp */
            >;
        };

        emmc_pins: pinmux_emmc_pins {
            pinctrl-single,pins = <
                AM33XX_IOPAD(0x880, PIN_INPUT_PULLUP | MUX_MODE2) /* gpmc_csn1.mmc1_clk */
                AM33XX_IOPAD(0x884, PIN_INPUT_PULLUP | MUX_MODE2) /* gpmc_csn2.mmc1_cmd */
                AM33XX_IOPAD(0x800, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad0.mmc1_dat0 */
                AM33XX_IOPAD(0x804, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad1.mmc1_dat1 */
                AM33XX_IOPAD(0x808, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad2.mmc1_dat2 */
                AM33XX_IOPAD(0x80c, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad3.mmc1_dat3 */
                AM33XX_IOPAD(0x810, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad4.mmc1_dat4 */
                AM33XX_IOPAD(0x814, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad5.mmc1_dat5 */
                AM33XX_IOPAD(0x818, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad6.mmc1_dat6 */
                AM33XX_IOPAD(0x81c, PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad7.mmc1_dat7 */
            >;
        };
    };

    &uart0 {
        pinctrl-names = "default";
        pinctrl-0 = <&uart0_pins>;

        status = "okay";
    };
    /**********************************UART1******************************************/
    &uart1 {
        pinctrl-names = "default";
        pinctrl-0 = <&uart1_pins>;

        status = "okay";
    };
    /**********************************************************************************************/
    /*********************************SPI********************************************/
    &spi0 {
        //#address-cells = <1>;  //not required
        //#size-cells = <0>;    //not required

        status = "okay";
        pinctrl-names = "default";
        pinctrl-0 = <&spi0_pins>;


         spidev@0{
        //    #address-cells = <1>;  //not required- need to check
        //    #size-cells = <0>; //not required- need to check

            compatible="rohm,dh2228fv";
                //compatible = "spidev";

            reg = <0>;
            spi-max-frequency = <16000000>;
    //      spi-cpha;                            //spi_clock_phase
        };

    };

    &spi1 {
        //#address-cells = <1>;
        //#size-cells = <0>;
        status = "okay";
        pinctrl-names = "default";
        pinctrl-0 = <&spi1_pins>;


          spidev@0{
        //    #address-cells = <1>; //not required- need to check
        //    #size-cells = <0>; //not required- need to check

            compatible="rohm,dh2228fv";
                //compatible = "spidev";

            reg = <0>;         //reg property for SPI subnodes are usually used to indicate the chip select to use when communicating with a particular driver
            spi-max-frequency = <16000000>;
    //       spi-cpha;                 //spi_clock_phase
        };



    };
    /*********************************************************************************************/
    &usb {
        status = "okay";
    };

    &usb_ctrl_mod {
        status = "okay";
    };

    &usb0_phy {
        status = "okay";
    };

    &usb1_phy {
        status = "okay";
    };

    &usb0 {
        status = "okay";
        dr_mode = "peripheral";
        interrupts-extended = <&intc 18 &tps 0>;
        interrupt-names = "mc", "vbus";
    };

    &usb1 {
        status = "okay";
        dr_mode = "host";
    };

    &cppi41dma  {
        status = "okay";
    };

    &i2c0 {
        pinctrl-names = "default";
        pinctrl-0 = <&i2c0_pins>;

        status = "okay";
        clock-frequency = <400000>;

        tps: tps@24 {
            reg = <0x24>;
        };

        baseboard_eeprom: baseboard_eeprom@50 {
            compatible = "atmel,24c256";
            reg = <0x50>;

            #address-cells = <1>;
            #size-cells = <1>;
            baseboard_data: baseboard_data@0 {
                reg = <0 0x100>;
            };
        };
    };

    &i2c2 {
        pinctrl-names = "default";
        pinctrl-0 = <&i2c2_pins>;

        status = "okay";
        clock-frequency = <100000>;

        cape_eeprom0: cape_eeprom0@54 {
            compatible = "atmel,24c256";
            reg = <0x54>;
            #address-cells = <1>;
            #size-cells = <1>;
            cape0_data: cape_data@0 {
                reg = <0 0x100>;
            };
        };

        cape_eeprom1: cape_eeprom1@55 {
            compatible = "atmel,24c256";
            reg = <0x55>;
            #address-cells = <1>;
            #size-cells = <1>;
            cape1_data: cape_data@0 {
                reg = <0 0x100>;
            };
        };

        cape_eeprom2: cape_eeprom2@56 {
            compatible = "atmel,24c256";
            reg = <0x56>;
            #address-cells = <1>;
            #size-cells = <1>;
            cape2_data: cape_data@0 {
                reg = <0 0x100>;
            };
        };

        cape_eeprom3: cape_eeprom3@57 {
            compatible = "atmel,24c256";
            reg = <0x57>;
            #address-cells = <1>;
            #size-cells = <1>;
            cape3_data: cape_data@0 {
                reg = <0 0x100>;
            };
        };
    };

    Note: I have only added those lines in dts which is highlighted in green.

  • Hi Sandeep,

    Sandeep kumar10 said:
    I have changed the dts file in "am335x-bone-common.dtsi" like following lines....Is it ok?

    In general, the following approach is recommended to maximize chances for success of any such customizations, including board dependencies:

    1. Pinmux settings should be a straight copy & paste from the TI pinmux tool, with the right interfaces/connections selected
    2. SPI and I2C (and an other) DTS defintions should be modeled after other existing AM335x-based boards in the Kernel tree

    Sandeep kumar10 said:
    i didn't get i2c and spi enable in /dev/tty*.

    What does that mean? I2C and SPI devices will show up as their own respective device class. /dev/tty* is only used for serial communication interfaces. If those devices don't show up at all it would be a good idea to  double-check the (Kernel) boot log for signs of I2C and SPI traces. It's also possible that the associated driver is not getting probed/included correctly. For example for your SPI slave device to get probed you need to have turned on the CONFIG_SPI_SPIDEV Kernel configuration (you can find this by searching the Kernel tree for the compatible string of your SPI device (in your case "rohm,dh2228fv") via 'git grep', then looking at the Makefile, which will give you the CONFIG you need).

    Regards, Andreas

  • Hi.....Thanks for help... now spi and i2c is enabled. I tried an application for spi, clock is coming and but data is not coming. I am working on that. I am using spidev for spi to develop an application, so is it ok to use  this compatible variable "(compatible="rohm,dh2228fv")" or i have to use  "(compatible = "spidev") ".

  • Sandeep kumar10 said:
    so is it ok to use  this compatible variable "(compatible="rohm,dh2228fv")"

    Yes please use this, the other compatible string will result in a bug/warning getting printed into the kernel log, triggered by this:

    drivers/spi/spidev.c-   /*
    drivers/spi/spidev.c-    * spidev should never be referenced in DT without a specific
    drivers/spi/spidev.c-    * compatible string, it is a Linux implementation thing
    drivers/spi/spidev.c-    * rather than a description of the hardware.
    drivers/spi/spidev.c-    */
    drivers/spi/spidev.c-   WARN(spi->dev.of_node &&
    drivers/spi/spidev.c-        of_device_is_compatible(spi->dev.of_node, "spidev"),
    drivers/spi/spidev.c:        "%pOF: buggy DT: spidev listed directly in DT\n", spi->dev.of_node);
    

    If you look at other platforms that's also how they do it, such as arch/arm/boot/dts/socfpga_cyclone5_socdk.dts.

    Regards, Andreas

  • Hi thanks...I used "(compatible="rohm,dh2228fv")" but it's data line is always high, it's not varying. Both D0 & D1 are always high. Clock is coming. I setted clock of 1 mhz but in oscilloscope it is not showing 1 mhz. It is showing other value. But when i close the application then i am not getting the clock it means clock is working but it  has other value. So what i am doing wrong here?

  • Hi Sandeep,

    can you please check this E2E post here for additional details on how to get the SPI working: https://e2e.ti.com/support/processors/f/791/p/888904/3287702#3287702

    It has a reference to sample code in the Kernel, and also shows a few things you can do on the Linux command line to experiment with the interface.

    Also make sure your pinmux is correct especially as it relates to the input/output signals. In this regard your SPI device tree node may need a 'ti,pindir-d0-out-d1-in = <1>;" property added to it which can be used to switch the D0/D1 signals.

    Regards, Andreas