1 1
jarmx

OPI R1 Setup a SPI slave in U-Boot

Recommended Posts

 

Hi all,

 

I have a OrangePi R1 and want to enable SPI in U-Boot to talk to connected leds. The leds are connected to SPI0 on the pins: 19 (MOSI), 4 (5v) and 6 (GND) . I enabled the CONFIG_SUN4I_SPI flag to enable the sunxi SPI driver. I also added the following lines to `arch/arm/dts/sun8i-h2-plus-orangepi-zero.dts` to enable both SPI0 and SPI1. 

&spi0 {
  status = "okay";
  flash@0 {
  	compatible = "mxicy,mx25l12805d", "jedec,spi-nor";
  };
};

&spi1 {
	status = "okay";
};

To control the leds I added a call to the following function inside the `board_init()` function inside: `/board/sunxi/board.c`.

 

static int set_leds()
{
    int bus = 0;
    int cs = 1;
    int mode = 0;

    struct spi_slave *slave;
    int ret = 0;

    printf("set_leds");
  
    char name[30], *str;
    struct udevice *dev;

    snprintf(name, sizeof(name), "generic_%d:%d", bus, cs);
  
    str = strdup(name);
    if (!str) return -ENOMEM;

    ret = spi_get_bus_and_cs(bus, cs, 38095, mode,  "spi_generic_drv",str, &dev, &slave);
    if (ret) return ret;

    ret = spi_claim_bus(slave);
    if (ret) goto done;

    uchar dout[2];
    uchar din[2];
    int bitlen = 16;

    ret = spi_xfer(slave, bitlen, dout, din, SPI_XFER_BEGIN | SPI_XFER_END);
done:
    spi_release_bus(slave);
    spi_free_slave(slave);
}

(please note that I am not transferring the actual data needed by the leds in this sample code)

 

When I flash the bootloader the leds wont respond (but I see the message printed in the console). I don''t have an oscilloscope so I am not able to see if the `spi_xfer` function actual sends the data. So my question is does this code look okey? Or is there something I am missing? 

 

Edited by jarmx

Share this post


Link to post
Share on other sites

I want them to turn on immediately when you power the board, booting to userspace takes around 15 seconds.

 

I have SPI sort of working now. I can send data to the leds but they only set the data when I disconnect and reconnect the MISO wire. Seems like a issue with the line not pulling up / down. Not sure how to fix this though.

Share this post


Link to post
Share on other sites

It it possible that the SPI driver in uboot for sun4i only works for SPI0? I see lines like 'sunxi_gpio_set_cfgpin(pin, SUNXI_GPC_SPI0);' inside the driver. Is there any know driver that works for SPI1?

 

Share this post


Link to post
Share on other sites
1 hour ago, jarmx said:

Is there any know driver that works for SPI1?

I really don't know ...

SPI in U-Boot is basically present for booting from SPIFlash, so maybe the code isn't there for such use-case ...

Share this post


Link to post
Share on other sites

I am trying to get software SPI to work. But I have some difficulties to get the driver working. I have added `CONFIG_SOFT_SPI=y` to `configs/orangepi_r1_defconfig` and added the following lines to the file in `arch/arm/dts/sun8i-h2-plus-orangepi-zero.dts` but for some reason the driver is not getting probed.  Can you see why this is? (probably a stupid mistake :blink:)

 

soft_spi: soft-spi {
  compatible = "spi-gpio";
  cs-gpios = <&pio 0 13 0>;
  gpio-sck = <&pio 0 14 0>;
  gpio-mosi = <&pio 0 15 0>;
};

(lines added to: `arch/arm/dts/sun8i-h2-plus-orangepi-zero.dts` after the `aliases` node)

 

=> dm tree
 Class    index  Probed  Driver      Name
-----------------------------------------
 root        0  [ + ]   root_drive  root_driver
 simple_bus  0  [ + ]   generic_si  |-- soc
 phy         0  [ + ]   sun4i_usb_  |   |-- phy@1c19400
 usb         0  [ + ]   ehci_sunxi  |   |-- usb@1c1a000
 usb_hub     0  [ + ]   usb_hub     |   |   `-- usb_hub
 usb         1  [ + ]   ohci_sunxi  |   |-- usb@1c1a400
 usb         2  [ + ]   ehci_sunxi  |   |-- usb@1c1b000
 usb_hub     1  [ + ]   usb_hub     |   |   `-- usb_hub
 usb         3  [ + ]   ehci_sunxi  |   |-- usb@1c1c000
 usb_hub     2  [ + ]   usb_hub     |   |   `-- usb_hub
 usb         4  [ + ]   ohci_sunxi  |   |-- usb@1c1c400
 gpio        0  [ + ]   gpio_sunxi  |   |-- pinctrl@1c20800
 gpio        1  [ + ]   gpio_sunxi  |   |   |-- PA
 gpio        2  [ + ]   gpio_sunxi  |   |   |-- PB
 gpio        3  [ + ]   gpio_sunxi  |   |   |-- PC
 gpio        4  [ + ]   gpio_sunxi  |   |   |-- PD
 gpio        5  [ + ]   gpio_sunxi  |   |   |-- PE
 gpio        6  [ + ]   gpio_sunxi  |   |   |-- PF
 gpio        7  [ + ]   gpio_sunxi  |   |   |-- PG
 gpio        8  [ + ]   gpio_sunxi  |   |   |-- PH
 gpio        9  [ + ]   gpio_sunxi  |   |   `-- PI
 eth         0  [ + ]   eth_sun8i_  |   |-- ethernet@1c30000
 serial      0  [ + ]   ns16550_se  |   |-- serial@1c28000
 gpio        10  [ + ]   gpio_sunxi  |   `-- pinctrl@1f02c00
 gpio        11  [ + ]   gpio_sunxi  |       `-- PL
 spi         0  [   ]   soft_spi    `-- soft-spi

(output from U-Boot when issuing the `dm tree` command)

 

Share this post


Link to post
Share on other sites

I tested it on OPi Zero (basically the same device) with u-boot master branch and it passed the loopback test.

defconfig changes:

diff --git a/configs/orangepi_zero_defconfig b/configs/orangepi_zero_defconfig
index e5a4c1d9fc..39528026a6 100644
--- a/configs/orangepi_zero_defconfig
+++ b/configs/orangepi_zero_defconfig
@@ -9,10 +9,19 @@ CONFIG_DRAM_ODT_EN=y
 CONFIG_SPL_SPI_SUNXI=y
 CONFIG_NR_DRAM_BANKS=1
 # CONFIG_SYS_MALLOC_CLEAR_ON_INIT is not set
+# CONFIG_USE_BOOTCOMMAND is not set
 CONFIG_CONSOLE_MUX=y
 # CONFIG_CMD_FLASH is not set
+CONFIG_CMD_SF=y
+CONFIG_CMD_SF_TEST=y
+CONFIG_CMD_SPI=y
 CONFIG_DEFAULT_DEVICE_TREE="sun8i-h2-plus-orangepi-zero"
+CONFIG_MTD=y
+CONFIG_DM_SPI_FLASH=y
 CONFIG_SUN8I_EMAC=y
-CONFIG_USB_OHCI_HCD=y
+CONFIG_SPI=y
+CONFIG_DM_SPI=y
+CONFIG_SOFT_SPI=y
 CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_OHCI_HCD=y
 CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE=y

DT changes:

diff --git a/arch/arm/dts/sun8i-h2-plus-orangepi-zero.dts b/arch/arm/dts/sun8i-h2-plus-orangepi-zero.dts
index 0bc031fe4c..40b078723d 100644
--- a/arch/arm/dts/sun8i-h2-plus-orangepi-zero.dts
+++ b/arch/arm/dts/sun8i-h2-plus-orangepi-zero.dts
@@ -59,6 +59,8 @@
 		/* ethernet0 is the H3 emac, defined in sun8i-h3.dtsi */
 		ethernet0 = &emac;
 		ethernet1 = &xr819;
+		spi0 = &softspi0;
+		spi1 = &softspi1;
 	};
 
 	chosen {
@@ -89,6 +91,26 @@
 		gpio = <&pio 0 20 GPIO_ACTIVE_HIGH>;
 	};
 
+	softspi0: soft-spi0 {
+		compatible = "spi-gpio";
+		status = "okay";
+		gpio-sck = <&pio 2 2 0>;
+		gpio-mosi = <&pio 2 0 0>;
+		gpio-miso = <&pio 2 1 0>;
+		cs-gpios = <&pio 2 3 0>;
+		num-chipselects = <1>;
+	};
+
+	softspi1: soft-spi1 {
+		compatible = "spi-gpio";
+		status = "okay";
+		gpio-sck = <&pio 0 14 0>;
+		gpio-mosi = <&pio 0 15 0>;
+		gpio-miso = <&pio 0 16 0>;
+		cs-gpios = <&pio 0 13 0>;
+		num-chipselects = <1>;
+	};
+
 	wifi_pwrseq: wifi_pwrseq {
 		compatible = "mmc-pwrseq-simple";
 		reset-gpios = <&r_pio 0 7 GPIO_ACTIVE_LOW>;

Partial console log:

=> echo loopback wire disconnected
loopback wire disconnected
=> sspi 1:0 16 1234
0000
=> echo loopback wire connected
loopback wire connected
=> sspi 1:0 16 1234
1234
=> dm tree
 Class     Index  Probed  Driver                Name
-----------------------------------------------------------
 root         0  [ + ]   root_driver           root_driver
 simple_bus   0  [ + ]   generic_simple_bus    |-- soc
 mmc          0  [ + ]   sunxi_mmc             |   |-- mmc@1c0f000
 blk          0  [   ]   mmc_blk               |   |   `-- mmc@1c0f000.blk
 mmc          1  [ + ]   sunxi_mmc             |   |-- mmc@1c10000
 blk          1  [   ]   mmc_blk               |   |   `-- mmc@1c10000.blk
 phy          0  [ + ]   sun4i_usb_phy         |   |-- phy@1c19400
 usb          0  [ + ]   ehci_generic          |   |-- usb@1c1a000
 usb_hub      0  [ + ]   usb_hub               |   |   `-- usb_hub
 usb          1  [ + ]   ohci_generic          |   |-- usb@1c1a400
 usb_hub      1  [ + ]   usb_hub               |   |   `-- usb_hub
 usb          2  [ + ]   ehci_generic          |   |-- usb@1c1b000
 usb_hub      2  [ + ]   usb_hub               |   |   `-- usb_hub
 usb          3  [ + ]   ohci_generic          |   |-- usb@1c1b400
 usb_hub      3  [ + ]   usb_hub               |   |   `-- usb_hub
 clk          0  [ + ]   sun8i_h3_ccu          |   |-- clock@1c20000
 reset        0  [ + ]   sunxi_reset           |   |   `-- reset
 gpio         0  [ + ]   gpio_sunxi            |   |-- pinctrl@1c20800
 gpio         1  [ + ]   gpio_sunxi            |   |   |-- PA
 gpio         2  [ + ]   gpio_sunxi            |   |   |-- PB
 gpio         3  [ + ]   gpio_sunxi            |   |   |-- PC
 gpio         4  [ + ]   gpio_sunxi            |   |   |-- PD
 gpio         5  [ + ]   gpio_sunxi            |   |   |-- PE
 gpio         6  [ + ]   gpio_sunxi            |   |   |-- PF
 gpio         7  [ + ]   gpio_sunxi            |   |   |-- PG
 gpio         8  [ + ]   gpio_sunxi            |   |   |-- PH
 gpio         9  [ + ]   gpio_sunxi            |   |   `-- PI
 eth          0  [ + ]   eth_sun8i_emac        |   |-- ethernet@1c30000
 serial       0  [ + ]   ns16550_serial        |   |-- serial@1c28000
 gpio        10  [ + ]   gpio_sunxi            |   `-- pinctrl@1f02c00
 gpio        11  [ + ]   gpio_sunxi            |       `-- PL
 spi          0  [ + ]   soft_spi              |-- soft-spi0
 spi_generi   0  [ + ]   spi_generic_drv       |   `-- generic_0:0
 spi          1  [ + ]   soft_spi              |-- soft-spi1
 spi_generi   1  [ + ]   spi_generic_drv       |   `-- generic_1:0
 clk          1  [ + ]   fixed_rate_clock      |-- osc24M_clk
 clk          2  [ + ]   fixed_rate_clock      |-- osc32k_clk
 clk          3  [   ]   fixed_rate_clock      `-- internal-osc-clk
=>

 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
1 1