Jump to content

SPI not working properly with cs-gpio


Ryzer

Recommended Posts

I have recently been trying to get my spi ili9341 working under kernel 6.6, having gotten it working previously. I checked to ensure there were no changes in the overlay required by the newer kernel. I confirmed that the pins were configured correctly and that the ILI9341 DRM module had loaded..

not_working_soft_cs3.thumb.PNG.5b53fb5e712e3d75815a4eae0c391c2d.PNGnot_working_soft_cs1.PNG

Despite this I was met with a white screen. Think I must have missed something I swapped out my SD card for another using an image based on kernel 5.15.88, where I was able to recieve a display. Looking back over the dmesg log, I noticed a slight difference in behaviour with the older kernel. firstly we can clearly see that the SPI driver is requesting to use gpio 34 as a chip select line compared to kernel 6.6.working_soft_cs1.thumb.PNG.c90b0c65f6aeb845beae9a5f9c795eb8.PNG

 

Secondly using gpioinfo to see which pins are currently set as output, to observe if gpio 34 has been set. A slight draw back with this approach is that it does not currently acknowledge when gpio are configured for spi.

 

Kernel 5.15.88:

working_soft_cs2.PNG.1222a795348431fc6ccd4dff49aac528.PNG

 

Kernel 6.6.16:

not_working_soft_cs2.PNG.0320962b29e606a60e48cc0026507b28.PNG

 

I later tried again but with my Pcduino3 using a more recent build based on kernel of 6.6.44 but achieved the same result. To confirm my theory that the problem lies somewhere within the chip select intialisation, I temporarily rerouted the pin used for the display to the Pcduino's native chip select pin (PI10) and recompiled the overlay to match. Now when I booted the pcduino I was met with a terminal window.

 

Edited by Ryzer
Link to comment
Share on other sites

Armbian & Khadas are rewarding contributors

Hi usual user,

 

which location do I source the old dtb from as there is a pcduino2.dtb at /boot/dtb/ as well as /boot/dtb-5.15.88. So far I have tried with fetching the spi-ili9341-tft.dtbo from the prevous build to no avail. As another test I have tried using the spi-gpio module in place of spi-sun4i but have been unable to get that to work at all. Do you have an A20 based board that you are able to test with the current kernel? If anyone else is experiencing the same issue it would be good to know.

Link to comment
Share on other sites

11 hours ago, Ryzer said:

which location do I source the old dtb from as there is a pcduino2.dtb at /boot/dtb/ as well as /boot/dtb-5.15.88.

/boot/dtb/ is probably a symlink to the real /boot/dtb-5.15.88 dirctory with the version number in the name to hint the source version the DTBs are build from.
I usually have plenty of kernels installed at the same time, so that it only takes to adjust the symlink to refer to a different DTB set. But this doesn't work so easily in Armbian with its single kernel layout strategy, because it results in name and directory conflicts there.
But in your case, it should be sufficient to copy the /boot/dtb-5.15.88 directory alongside to the /boot/dtb-6.6.16 directory and adjust the symlink accordingly.
Oh, just to be clear, they're both mainline kernel builds and there's no legacy kernel fork involved, because in this case it won't work, because most likely incompatible out of tree hacks are involved.

 

11 hours ago, Ryzer said:

As another test I have tried using the spi-gpio module in place of spi-sun4i but have been unable to get that to work at all.

You can't mix binaries of kernel components of different versions, not even different builds of the same version, because you can't make sure that the ABI hasn't changed. For DTBs intermixing is possible because they describe hardware and are agnostic of the consumer binary code. The mainline kernel with its "no regression" policy ensures that earlier releases remain functional.
For a given userspace, you can use any kernel as long as it's build is configured with the same components, because it exposes a stable userspace-kernel API.

Link to comment
Share on other sites

Hi usual user,

 

I have attempted your suggestion but to no avail unfortunately.reroute-dtb-test.PNG.bf5982dde3112339f69016a8c1f9e6ac.PNG

 

I did a bit of digging into previous commits to armbian build and found an interesting patch for the 5.15 kernel series:drv-spi-spi.c-fix-cs_gpio-spi-support.patch

This like a promising place to start from. Unfortunately I no longer have a copy of the kernel source code specificly for 5.15.88. and only managed to find 5.15.165 listed on kernel.org.  I guess I’ll need to closely examine spi.c under kernel 6.6 to figure out how it now handles GPIO-based chip selects.

 

Just to confirm all the builds where current when they where created. The only additional alterations that I had to do was a patch to enable hdmi support and adjust the perf unit IRQ number so that it does not conflict with a serial port.

Link to comment
Share on other sites

3 hours ago, Ryzer said:

I did a bit of digging into previous commits to armbian build and found an interesting patch for the 5.15 kernel series:

Of course, I don't know which patches Armbian has applied at times, but what looks suspicious is the fact that the gpio line numbers used in the "/sys/kernel/debug/gpio" logs for the gpiochip1 differ. This shouldn't be caused by the DT, and if it is, it should be the same as using the 5.15.88 variant again.
To test the basic function of the GPIO subsystem in 6.6.16, post the state of "/sys/kernel/debug/gpio" while

gpioset -c0 34=on

is running at the same time with root permissions.

Link to comment
Share on other sites

Hi usual user,

 

I will admit that is a bit strange. gpiochip1 is the mapping for the IO on axp209 pmic. For some reason it is assigned a different base under kernel 6.6. if we look at gpio via the sysfs approuch this is more clearer to see. Another issue is that neither is 100% accurate as some listed gpio lines do not actually exist as there is not a single port that is associated with 32 pins. https://linux-sunxi.org/A20/PIO That said if the mapping was incorrect then surely the dc pin and backlight pins woud not be correct either.

 

Kernel 5.15.88

gpio_list_5_15.PNG.7726439f1b84d3f104273c9a09adce8e.PNG

 

Kernel 6.6:

gpio_list_6.6.PNG.4b7da8e6a6b22fa139a81e6bd427d3e5.PNG

 

 

Are you sure this is right as it returns an error and gpioset -h does not list a -c option

12 hours ago, usual user said:
gpioset -c0 34=on

 

 

Link to comment
Share on other sites

5 hours ago, Ryzer said:

Another issue is that neither is 100% accurate as some listed gpio lines do not actually exist

"/sys/kernel/debug/gpio" represents what the kernel has instantiated. Its accuracy depends on the exact description (DT), as the layout cannot be probed.
But many people think they can copy DT fragments of similar devices together to get an exact description of a particular device without verification. But it's just like a device schematic, it will never accurately replicate the layout design of another device. DT is just one step further, as it can change the layout itself at runtime.

 

5 hours ago, Ryzer said:

That said if the mapping was incorrect then surely the dc pin and backlight pins woud not be correct either.

The test was intended to verify that the GPIO subsystem is correctly configured and that the GPIO line can be acquired from a native GPIO process.
This is because the line cannot be operated as a native CS line by the SPI IP but only emulated with the cooperation of the GPIO Subsystem.

 

5 hours ago, Ryzer said:

Are you sure this is right as it returns an error and gpioset -h does not list a -c option

Mine does:

Spoiler
# gpioset --help

Usage: gpioset [OPTIONS] <line=value>...

Set values of GPIO lines.

Lines are specified by name, or optionally by offset if the chip option
is provided.
Values may be '1' or '0', or equivalently 'active'/'inactive' or 'on'/'off'.

The line output state is maintained until the process exits, but after that
is not guaranteed.
      
Options:
      --banner          display a banner on successful startup
  -b, --bias <bias>     specify the line bias
                        Possible values: 'pull-down', 'pull-up', 'disabled'.
                        (default is to leave bias unchanged)
      --by-names        treat lines as names even if they would parse as an offset
  -c, --chip <chip>     restrict scope to a particular chip
  -C, --consumer <name> consumer name applied to requested lines (default is 'gpioset')
  -d, --drive <drive>   specify the line drive mode
                        Possible values: 'push-pull', 'open-drain', 'open-source'.
                        (default is 'push-pull')
  -h, --help            display this help and exit
  -l, --active-low      treat the line as active low
  -p, --hold-period <period>
                        the minimum time period to hold lines at the requested values
  -s, --strict          abort if requested line names are not unique
  -t, --toggle <period>[,period]...
                        toggle the line(s) after the specified period(s)
                        If the last period is non-zero then the sequence repeats.
      --unquoted        don't quote line names
  -v, --version         output version information and exit
  -z, --daemonize       set values then detach from the controlling terminal
  
# gpioset --version

gpioset (libgpiod) v2.1.3
Copyright (C) 2017-2023 Bartosz Golaszewski
License: GPL-2.0-or-later
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

 

 

Link to comment
Share on other sites

Ok, you have confirmed that the GPIO line can be properly acquired by a suitable process and the GPIO subsystem is working as expected.
The SPI subsystem does not seem to do this as desired for the CS line.
Whether this is due to a bug patched out of tree in the 5.15.88 kernel, or just a configuration error in the DT, I can't say, since you haven't published any DT sources on how your SPI controller is wired.
I'm interested in the original sources from which the DTB was created, and not any from some disassembled DTB, as this has lost valuable information that was striped out during the assembly of the DTB.
But I also know that it is very difficult to acquire them with an Armbian build system since they most probably only exist as build artifacts which get composed from various patches.

Link to comment
Share on other sites

I have a feeling that there's some difference between ili9341.ko (adafruit) and fb_ili9341.ko, in the way they handle GPIOs and SPI pins.

 

fb_ili9341.ko handles the TFT perfectly in Linux 6.6.x (but it is desirable to use the DRM enabled ili9341.ko)

Link to comment
Share on other sites

7 hours ago, robertoj said:

I have a feeling that there's some difference between ili9341.ko (adafruit) and fb_ili9341.ko, in the way they handle GPIOs and SPI pins.

IMHO it is much more likely that the DT description is incorrect, but with the Armbian DT workflow there is not the slightest possibility to verify it automatically with the binding documentation.
But since not even the original DT sources are readily available, you can't even validate them manually.
And once sources are available, they are usually written in disassembler syntax, which does not make them easier to read.
In addition, there is the fact that many attempts are made to merge snippets of DTS from different devices by "copy & paste" in the hope of magically getting a working device. This is just as doomed to failure as the attempt to use arbitrary schematic snippets of various devices to describe a certain PCB for a specific device.
In the DT world it is even more challenging, because the DT layout is even use case dependent and runtime changeable.

Link to comment
Share on other sites

On 9/6/2024 at 10:13 AM, robertoj said:

I can see my SBC's DTS with armbian-config > System > DTC ... is this what you meant?

Since there is no public link to the result, I suspect it.

 

On 9/6/2024 at 10:13 AM, robertoj said:

It is almost identical to

Since a single false character in a DTS(O) can already lead to a malfunction in its consuming code, this is completely unsuitable for debugging.
If the DTB's build framework is added as a source of error, be my guest, but please don't expect any help from me in this case.
It's the same as asking an application developer to identify a bug in the compilation toolchain by disassembling their binary application code without having access to the exact sources from which the particular binay was built.

Link to comment
Share on other sites

On 8/29/2024 at 3:26 PM, Ryzer said:

Hi Usual user,

 

Thanks for your suggestion but looking under "/sys/kernel/debug/gpio" provides similiar output.

 

kernel 5.15.88:

working_soft_cs3.PNG.bdcda19de127aab36b78831554d07280.PNG

 

Kernel 6.6.16:

not_working_soft_cs4.PNG.fae076342e1b1ecc5128664cd655deec.PNG

 

Why is the row gpio-234 (RESET) not showing up in kernel 5.18.88, but it shows up in kernel 6.6.16?, and then it disappears again with your next experiment with updated libgpiod?

Link to comment
Share on other sites

18 hours ago, robertoj said:

Why is the row gpio-234 (RESET) not showing up in kernel 5.18.88, but it shows up in kernel 6.6.16?, and then it disappears again with your next experiment with updated libgpiod?

Since I don't even know which system component the supposed GPIO line is connected to, I could only speculate wildly. The appearance is certainly due to the wiring in the DT, but this is also a speculation to which I do not want to comment further, but leave it to qualified people. Alternatively, you could look in the exact DT sources from which the DTBs used at runtime were assembled, but I don't have access to that.
You could also add the line to the output with:

gpioset --consumer=reset -c0 234=on

but it certainly won't give the same functionality as in the original case, as it's a completely different use case.

Link to comment
Share on other sites

Hi Robertoj,

 

That was due to a little mixup in the overlays used with similiar names of spi-ili9341-tft and spi-tft-ili9341.dts. When working with spi-ili9341-tft.dts I assumed it was correct and working but I when I double checked the environment file on the 5.15.88 kernel the working overlay I was using was spi-tft-ili9341.dts. I cant remember what exactly the issue was as intially spi-ili9341-tft.dts did not work when compiled under 5.15.88. I have since recompiled it and it now does indeed work mostly, the only bit I need to address is getting the backlight to come on automatically which it does on spi-tft-ili9341.dts but not on spi-ili9341-tft.dts. I should have remember from before that the reset pin is not strictly necessary and in my case the reset pin aligns with the board reset pin. One other thing I have to be careful of is the connections do not appear to be great so if I accidently knock the screen it goes white then I have to reboot to get the display back.

Link to comment
Share on other sites

Hi Usual user,

 

Please find attached the dts sources copied from cache/sources/linux-kernel-worktree/6.6__sunxi_armhf/arch/arm/boot/dts/allwinner

 

sun4i-a10.dtsi sun4i-a10-pcduino.dts sun4i-a10-pcduino2.dts

 

The most recent version of the spi-ili9341-tft.dts overlay can be found here: https://github.com/Ryzer58/sunxi-DT-overlays/blob/master/examples/spi-ili9341-tft.dts

 

cheers

 

Ryzer

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