Jump to content

SPI Problem with Orange Pi 3 LTS


Brendow

Recommended Posts

Hello everyone,

 

I encountered an issue while using SPI with my Orange Pi 3 LTS, and now I'm going to share some solutions. Perhaps the Armbian Team can assist me in resolving the final problem.

These tests were conducted on Armbian 23.02.2 Bullseye with Linux 5.15.93-sunxi64.

 

The initial step I took to ensure the appearance of `spidev` on the Orange Pi 3 LTS was to include these configurations in `/boot/armbianEnv.txt`.

overlays=spi-spidev1
param_spidev_spi_bus=0
param_spidev_spi_cs=0

Note: If `spi-spidev` and `spi-spidev1` are added together, it will not work, and the `spidev` will not appear when using the `ls /dev/sp*` command.

 

After performing the above steps, I executed the `sudo reboot` command, and `/dev/spidev1.0` appeared.

root@orangepi3-lts:~/wiringOP# ls /dev/sp*
/dev/spidev1.0

 

However, this alone was insufficient to ensure proper functionality of SPI. I attempted to send a message to an ATMega 168p using a Python script that utilizes the `spidev` library.

The script is below:

import spidev

spi = spidev.SpiDev()
spi.open(1, 0)
spi.max_speed_hz=10000

payload = [0x0c, 0x00]
spi.xfer(payload)
print(*payload[1:])

 

The ATMega 168p occasionally received the message, and sometimes it did not. I suspected that the issue might be related to the MISO or MOSI connections. To investigate further, I directly connected the MISO pin of the Orange Pi 3 LTS to its MOSI pin, testing whether I would receive an echo in the script provided earlier. Indeed, I received the echo successfully.

 

Considering the observations so far, my remaining suspicion lies with the CS (Chip Select) line. If the CS line is not functioning properly, it may fail to select the specific device, resulting in issues with the request/response process (similar to what I experienced).

 

Hence, I proceeded to install wiringOp, on my device. This allowed me to read all the GPIOs of my Orange Pi 3 LTS and check for any anomalies. After successfully building it, I ran the command `gpio readall` and observed the following output:

root@orangepi3-lts:~/wiringOP# gpio readall
 +------+-----+----------+------+---+   OPi 3  +---+------+----------+-----+------+
 | GPIO | wPi |   Name   | Mode | V | Physical | V | Mode | Name     | wPi | GPIO |
 +------+-----+----------+------+---+----++----+---+------+----------+-----+------+
 |      |     |     3.3V |      |   |  1 || 2  |   |      | 5V       |     |      |
 |  122 |   0 |    SDA.0 |  OFF | 0 |  3 || 4  |   |      | 5V       |     |      |
 |  121 |   1 |    SCL.0 |  OFF | 0 |  5 || 6  |   |      | GND      |     |      |
 |  118 |   2 |    PWM.0 |  OFF | 0 |  7 || 8  | 0 | OFF  | PL02     | 3   | 354  |
 |      |     |      GND |      |   |  9 || 10 | 0 | OFF  | PL03     | 4   | 355  |
 |  120 |   5 |    RXD.3 |  OFF | 0 | 11 || 12 | 0 | OFF  | PD18     | 6   | 114  |
 |  119 |   7 |    TXD.3 |  OFF | 0 | 13 || 14 |   |      | GND      |     |      |
 |  362 |   8 |     PL10 |  OFF | 0 | 15 || 16 | 0 | OFF  | PD15     | 9   | 111  |
 |      |     |     3.3V |      |   | 17 || 18 | 0 | OFF  | PD16     | 10  | 112  |
 |  229 |  11 |   MOSI.1 | ALT2 | 0 | 19 || 20 |   |      | GND      |     |      |
 |  230 |  12 |   MISO.1 | ALT2 | 0 | 21 || 22 | 0 | OFF  | PD21     | 13  | 117  |
 |  228 |  14 |   SCLK.1 | ALT2 | 0 | 23 || 24 | 0 | OFF  | CE.1     | 15  | 227  |
 |      |     |      GND |      |   | 25 || 26 | 0 | OFF  | PL08     | 16  | 360  |
 +------+-----+----------+------+---+----++----+---+------+----------+-----+------+
 | GPIO | wPi |   Name   | Mode | V | Physical | V | Mode | Name     | wPi | GPIO |
 +------+-----+----------+------+---+   OPi 3  +---+------+----------+-----+------+

 

I noticed that the CS pin (GPIO 227) is currently set to `OFF` and needs to be configured as `ALT2`  along with `MOSI.1`, `MISO.1`, and `SCLK.1` . This information gave me a clear direction on how to solve my problem. To investigate further, I began checking the device tree configuration using the following commands: `sudo armbian-config` -> `System` -> `Dtc`:

...
                        spi1-pins {
                                pins = "PH4\0PH5\0PH6";
                                function = "spi1";
                                phandle = <0x2b>;
                        };

                        spi1-cs-pin {
                                pins = "PH3";
                                function = "spi1";
                                phandle = <0x2c>;
                        };
...
                  spi@5011000 {
                        compatible = "allwinner,sun50i-h6-spi\0allwinner,sun8i-h3-spi";
                        reg = <0x5011000 0x1000>;
                        interrupts = <0x00 0x0b 0x04>;
                        clocks = <0x04 0x53 0x04 0x51>;
                        clock-names = "ahb\0mod";
                        dmas = <0x2a 0x17 0x2a 0x17>;
                        dma-names = "rx\0tx";
                        pinctrl-names = "default";
                        pinctrl-0 = <0x2b 0x2c>;
                        resets = <0x04 0x20>;
                        status = "disabled";
                        #address-cells = <0x01>;
                        #size-cells = <0x00>;
                        phandle = <0x72>;
                };
...

 

Upon examining the pinout diagram, I realized that the Orange Pi 3 LTS utilizes SPI1, and all the SPI pins (H3, H4, H5, H6) were correctly configured in the device tree. This led me to speculate that the issue might not be in the device tree itself but rather in the `spi-spidev1 overlay`. To investigate further, I decompiled the `sun50i-h6-spi-spidev1.dtbo` file located at `/boot/dtb/allwinner/overlay/` into a `.dts` file using the command `dtc -I dtb -O dts sun50i-h6-spi-spidev1.dtbo -o sun50i-h6-sp i-spidev1.dts`. Next, I edited the `pinctrl-0` section of the `sun50i-h6-spi-spidev1.dts` file, adding the addresses `0x2b` and `0x2c` (similar to what was done in spi@5011000).

/dts-v1/;

/ {
	compatible = "allwinner,sun8i-h3-spi";

	fragment@0 {
		target-path = "/aliases";

		__overlay__ {
			spi1 = "/soc/spi@5011000";
		};
	};

	fragment@1 {
		target = <0xffffffff>;

		__overlay__ {
			pinctrl-names = "default";
			pinctrl-0 = <0x2b 0x2c>;
			status = "okay";
			#address-cells = <0x01>;
			#size-cells = <0x00>;

			spidev@0 {
				compatible = "armbian,spi-dev";
				reg = <0x00>;
				spi-max-frequency = <0xf4240>;
			};
		};
	};

	__fixups__ {
		spi1 = "/fragment@1:target:0";
		spi1_pins = "/fragment@1/__overlay__:pinctrl-0:0";
	};
};

 

Compiled the modified `sun50i-h6-spi-spidev1.dts` file into a `.dtbo` using the command `dtc -O dtb -I dts sun50i-h6-spi-spidev1.dts -o sun50i-h6-spi-spidev1.dtbo`. Then, I rebooted the Orange Pi 3 LTS. After the reboot, I ran the `gpio readall` command again to check the GPIO pin status:

root@orangepi3-lts:~# gpio readall
 +------+-----+----------+------+---+   OPi 3  +---+------+----------+-----+------+
 | GPIO | wPi |   Name   | Mode | V | Physical | V | Mode | Name     | wPi | GPIO |
 +------+-----+----------+------+---+----++----+---+------+----------+-----+------+
 |      |     |     3.3V |      |   |  1 || 2  |   |      | 5V       |     |      |
 |  122 |   0 |    SDA.0 |  OFF | 0 |  3 || 4  |   |      | 5V       |     |      |
 |  121 |   1 |    SCL.0 |  OFF | 0 |  5 || 6  |   |      | GND      |     |      |
 |  118 |   2 |    PWM.0 |  OFF | 0 |  7 || 8  | 0 | OFF  | PL02     | 3   | 354  |
 |      |     |      GND |      |   |  9 || 10 | 0 | OFF  | PL03     | 4   | 355  |
 |  120 |   5 |    RXD.3 |  OFF | 0 | 11 || 12 | 0 | OFF  | PD18     | 6   | 114  |
 |  119 |   7 |    TXD.3 |  OFF | 0 | 13 || 14 |   |      | GND      |     |      |
 |  362 |   8 |     PL10 |  OFF | 0 | 15 || 16 | 0 | OFF  | PD15     | 9   | 111  |
 |      |     |     3.3V |      |   | 17 || 18 | 0 | OFF  | PD16     | 10  | 112  |
 |  229 |  11 |   MOSI.1 | ALT2 | 0 | 19 || 20 |   |      | GND      |     |      |
 |  230 |  12 |   MISO.1 | ALT2 | 0 | 21 || 22 | 0 | OFF  | PD21     | 13  | 117  |
 |  228 |  14 |   SCLK.1 | ALT2 | 0 | 23 || 24 | 0 | ALT2 | CE.1     | 15  | 227  |
 |      |     |      GND |      |   | 25 || 26 | 0 | OFF  | PL08     | 16  | 360  |
 +------+-----+----------+------+---+----++----+---+------+----------+-----+------+
 | GPIO | wPi |   Name   | Mode | V | Physical | V | Mode | Name     | wPi | GPIO |
 +------+-----+----------+------+---+   OPi 3  +---+------+----------+-----+------+


The SPI functionality is now operational, but this solution is not definitive. To address the underlying issue, I need assistance as device trees, kernels, and other aspects of Linux are not within my area of expertise. It seems that the problem with the CS pin is related to an error during the boot process, resulting in an incorrect address assignment.

 

 

Well, I hope this information proves helpful to others who are experiencing the same issue as I did. :)

Remember: English is not my first language, so there may be some errors.

Link to comment
Share on other sites

"usual user" has posted instructions to incorporate your dtbo inside the dtb... but I personally like having a separate dtbo that is applied by uboot.

 

https://forum.armbian.com/topic/33800-orange-pi-zero-3-gpio/?do=findComment&comment=181688

 

dtb and dtbos are the correct way to assign pins and tell the kernel where everything is.

 

I don't think there's anything wrong with the boot process, if it only needs a dtbo to start working correctly. Everything depends on having good dtb and dtbos.

Link to comment
Share on other sites

Hi everyone! I didn't expect this post to be active again after almost a year without replies, so thanks for the revival!

 

After writing this "article," I stopped investigating the problem. However, the post being active again piqued my curiosity to see if the issue was resolved. Unfortunately, the problem persists on Armbian 23.11.1 (bookworm). I tried the same steps as before, but encountered a major issue. After recompiling and compiling the dts and rebooting, my device wouldn't boot anymore. It kept showing "UUID does not exist" (and I don't know why, so if anybody knows, please tell me).

 

I really appreciate your efforts @usual user for providing the .dts, but I think the problem lies in the overlay file of Armbian, which seems to be out of date.

 

It seems they forgot to update the overlay, as @robertoj mentioned that this isn't a problem in the boot process; the original dts that boots on the OPi 3 LTS is correct. I followed the same steps as before: sudo armbian-config -> System -> Dtc, and in the spi@5011000 section, they updated the phandle of the pins.

 

spi1-pins {
    pins = "PH4\0PH5\0PH6";
    function = "spi1";
    phandle = <0x32>;
};

spi1-cs-pin {
    pins = "PH3";
    function = "spi1";
    phandle = <0x33>;
};

 

But when we checked the sun50i-h6-spi-spidev1.dtbo, it remained the same.

fragment@1 {
    target = <0xffffffff>;

    __overlay__ {
        pinctrl-names = "default";
        pinctrl-0 = <0xffffffff>;
        status = "okay";
        #address-cells = <0x01>;
        #size-cells = <0x00>;

        spidev@0 {
            compatible = "armbian,spi-dev";
            reg = <0x00>;
            spi-max-frequency = <0xf4240>;
        };
    };
};

Notice that the "pinctrl-0" is <0xffffffff>, which seems more like a placeholder than a real id of a node. The problem here is that we have a working device tree in the system, but when I activate the overlay using overlays=spi-spidev1 in /boot/armbianEnv.txt, it overwrites the correct dts and puts the wrong node id.

 

Before adding the overlay in your boot config, you can check this by going to /sys/firmware/devicetree/base/soc/spi@5011000 and using cat on pinctrl-0:

$> /sys/firmware/devicetree/base/soc/spi@5011000# cat pinctrl-0
23

 

What are these 2 and 3? If we look at the original device tree source, it's pinctrl-0 = <0x32 0x33>;, where 32 refers to the node spi1-pins and 33 to spi1-cs-pin. By using an ASCII to hex converter, we find that 2 corresponds to 0x32 and 3 to 0x33. You can also confirm which pins are assigned to these IDs by:

$> /sys/firmware/devicetree/base/soc/pinctrl@300b000/spi1-pins# cat phandle
2

$> /sys/firmware/devicetree/base/soc/pinctrl@300b000/spi1-cs-pin# cat phandle
3

 

So, what happens when we add the overlay?

/sys/firmware/devicetree/base/soc/spi@5011000# cat pinctrl-0
2

 

We see that we have 2 (MOSI.1, MISO.1, and SCLK.1) but not 3 (CE.1). In other words, we don't have CE.1 activated as WiringOP showed us.

 

But how can I simply fix that, given that (at least to me) recompiling and compiling aren't working more?

It's simple:

  1. Copy the spidev@0 part from the overlay.
  2. Access sudo armbian-config -> System -> Dtc and find spi@5011000.
  3. Put the spidev@0 inside it and set the status of this node to "okay" instead of "disabled".
  4. The final result will be:
spi@5011000 {
    compatible = "allwinner,sun50i-h6-spi\0allwinner,sun8i-h3-spi";
    reg = <0x5011000 0x1000>;
    interrupts = <0x00 0x0b 0x04>;
    clocks = <0x06 0x53 0x06 0x51>;
    clock-names = "ahb\0mod";
    dmas = <0x2f 0x17 0x2f 0x17>;
    dma-names = "rx\0tx";
    pinctrl-names = "default";
    pinctrl-0 = <0x32 0x33>;
    resets = <0x06 0x20>;
    status = "okay";
    #address-cells = <0x01>;
    #size-cells = <0x00>;
    phandle = <0x7a>;
    spidev@0 {
        compatible = "armbian,spi-dev";
        reg = <0x00>;
        spi-max-frequency = <0xf4240>;
    };
};

 

Save the modifications and now use this command to remove the wrong overlay:

$> cd /boot/dtb/allwinner/overlay/
$> mv sun50i-h6-spi-spidev1.dtbo .sun50i-h6-spi-spidev1.dtbo

 

After the reboot, you'll see:

$> ls /dev/ | grep spi
spidev0.0

 

Using gpio readall:

$> sudo gpio readall
 +------+-----+----------+--------+---+   OPi 3  +---+--------+----------+-----+------+
 | GPIO | wPi |   Name   |  Mode  | V | Physical | V |  Mode  | Name     | wPi | GPIO |
 +------+-----+----------+--------+---+----++----+---+--------+----------+-----+------+
 |      |     |     3.3V |        |   |  1 || 2  |   |        | 5V       |     |      |
 |  122 |   0 |    SDA.0 |    OFF | 0 |  3 || 4  |   |        | 5V       |     |      |
 |  121 |   1 |    SCL.0 |    OFF | 0 |  5 || 6  |   |        | GND      |     |      |
 |  118 |   2 |    PWM.0 |    OFF | 0 |  7 || 8  | 0 | OFF    | PL02     | 3   | 354  |
 |      |     |      GND |        |   |  9 || 10 | 0 | OFF    | PL03     | 4   | 355  |
 |  120 |   5 |    RXD.3 |    OFF | 0 | 11 || 12 | 0 | OFF    | PD18     | 6   | 114  |
 |  119 |   7 |    TXD.3 |    OFF | 0 | 13 || 14 |   |        | GND      |     |      |
 |  362 |   8 |     PL10 |    OFF | 0 | 15 || 16 | 0 | OFF    | PD15     | 9   | 111  |
 |      |     |     3.3V |        |   | 17 || 18 | 0 | OFF    | PD16     | 10  | 112  |
 |  229 |  11 |   MOSI.1 |   ALT2 | 0 | 19 || 20 |   |        | GND      |     |      |
 |  230 |  12 |   MISO.1 |   ALT2 | 0 | 21 || 22 | 0 | OFF    | PD21     | 13  | 117  |
 |  228 |  14 |   SCLK.1 |   ALT2 | 0 | 23 || 24 | 0 | ALT2   | CE.1     | 15  | 227  |
 |      |     |      GND |        |   | 25 || 26 | 0 | OFF    | PL08     | 16  | 360  |
 +------+-----+----------+--------+---+----++----+---+--------+----------+-----+------+
 | GPIO | wPi |   Name   |  Mode  | V | Physical | V |  Mode  | Name     | wPi | GPIO |
 +------+-----+----------+--------+---+   OPi 3  +---+--------+----------+-----+------+

 

You should see CE.1 working.

 

Now, use spidev-test to see if SPI is working:

$> ./spidev_test  -v -D /dev/spidev0.0
spi mode: 0x0
bits per word: 8
max speed: 500000 Hz (500 KHz)
TX | FF FF FF FF FF FF 40 00 00 00 00 95 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF F0 0D  | ......@.... .................. .
RX | FF FF FF FF FF FF 40 00 00 00 00 95 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF F0 0D  | ......@.... .................. .

 

It's working! In the end, it seems that the overlay is incorrect (perhaps someone forgot to remove or update the "pinctrl-0 = <0xffffffff>") and needs to be updated.

 

I don't know if the solution I created is the best way, but it's working in the recent images. If anyone has a hint to improve this solution or knows why I'm getting "UUID does not exist" when I recompile my .dtbo file, please let me know to improve my knowledge :)

 

PS: You don't need to remove the overlay if you didn't add it to your armbianEnv.txt.

Edited by Brendow
Link to comment
Share on other sites

6 hours ago, Brendow said:

It kept showing "UUID does not exist" (and I don't know why, so if anybody knows, please tell me).

Chances are, you've destroyed the integrity of the resulting DTB and the kernel can't even access the device with the rootfs.

 

6 hours ago, Brendow said:

really appreciate your efforts @usual user for providing the .dts

That dtso was more ment in @robertoj's direction to showcase gpio-line-names setup for this device.

 

From the rest of your post, I don't really know what you're talking about. Nevertheless, I have written an overlay from scratch according to your recipe.
For a first test, please disable any overlay application using the Armbian method in armbianEnv.txt and apply the overlay with my method.
With an copy of your base DTB execute this command:

fdtoverlay --input sun50i-h6-orangepi-3-lts.dtb --output sun50i-h6-orangepi-3-lts.dtb sun50i-h6-orangepi-3-lts-spi1.dtbo

Now swap the currently used DTB with this one, reboot and test if it works as expected. After a successful test, you can try out the application with the Armbian method.

sun50i-h6-orangepi-3-lts-spi1.dtso

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
×
×
  • Create New...

Important Information

Terms of Use - Privacy Policy - Guidelines