Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pin::export() errors out w/ "Device or resource busy" #146

Open
ghost opened this issue Feb 24, 2023 · 4 comments
Open

Pin::export() errors out w/ "Device or resource busy" #146

ghost opened this issue Feb 24, 2023 · 4 comments
Labels
bug Something isn't working

Comments

@ghost
Copy link

ghost commented Feb 24, 2023

Looking at the C code I can see that the SYSFS_GPIO_EXPORT() function does the same as the Rust function: it opens the "/sys/class/gpio/export" file and writes the pin number on it, so not sure why it's throwing the error here.

Device

Waveshare 4.2in on RPi4

Repro

Run examples/4in2, with let cs = Pin::new(8) to match the Pi4

  • Version: Tested on both 0.50.0 and latest master
  • Note: C tests from official waveshare repo finish successfully.

Error

thread 'main' panicked at 'cs export: Io(Os { code: 16, kind: ResourceBusy, message: "Device or resource busy" })', src/main.rs:34:17

Troubleshooting

$ gpio read 8
1
sudo lsof /sys/class/gpio/gpio8
lsof: status error on /sys/class/gpio/gpio8: No such file or directory

Other interesting results:

  • Moving the CS Pin export to the bottom, results in the error moving to the bottom, all other pins export successfully
  • Setting an arbitrary pin_num in let cs = Pin::new(); results in the program not erroring out and continuing to the end, but nothing is shown on the screen.
  • Test starts if I don't touch the pin:
let cs = Pin::new(8); //BCM7 CE0
// cs.export().expect("cs export");
// while !cs.is_exported() {}
// cs.set_direction(Direction::Out).expect("CS Direction");
// cs.set_value(1).expect("CS Value set to 1");

drawing is ok, and the program exits without errors, but I get a bunch of Input/output error on the pi after that, at any keypress, until I restart the pi, and the e-ink screen is not cleared, not even after calling clear_frame()?;, which does not error out.

@ghost
Copy link
Author

ghost commented Feb 25, 2023

Ok, I'm trying to see whether it's possible to exit the program without the Pi needing a reboot.

So, continuing without exporting CS, RST seems to be the next culprit:

let rst = Pin::new(17); //pin 36 //bcm16
rst.export().expect("rst export");
while !rst.is_exported() {}
rst.set_direction(Direction::Out).expect("rst Direction");
// rst.set_value(1).expect("rst Value set to 1");

std::process::exit(0);

exit with the line uncommented and the Pi crashes into I/O error until reboot. Exit as above, and it doesn't. Yay!

Moving on,

let mut epd4in2 =
        Epd4in2::new(&mut spi, cs, busy, dc, rst, &mut delay, None).expect("eink initalize error");

std::process::exit(0);

It always leave the Pi in crashed state. Looking into the implementation, it manipulates the RST value, so what I am trying now is to manipulate that back before the exit, see whether that changes anything.

I'm open for inputs on alternative ways to debug this, resetting a crashed Pi after every failed build is no fun!

@ghost
Copy link
Author

ghost commented Mar 2, 2023

In the 4in2 example, where are the Pin numbers taken from?

The file mentions a raspi-config, so it should have been written for the Pi, but the numbering is very different from the one shown on the [waveshare docs].(https://github.com/caemor/epd-waveshare/blob/main/examples/epd4in2.rs#L38-L60)

@JohnnyWulgaru
Copy link

JohnnyWulgaru commented Jul 19, 2023

I've run into the same issue with my 7.5in display as well.
According to the GPIO debug output Pin 8 is already in use by spidev kernel module.

Strangely enough the official Waveshare python code works just fine.

I've read some search results that you can remap which GPIO pin SPI uses but I am not really well versed in that kind of stuff so don't know what the side effects would be.

cat /sys/kernel/debug/gpio
gpiochip0: GPIOs 0-57, parent: platform/fe200000.gpio, pinctrl-bcm2711:
 gpio-0   (ID_SDA              )
 gpio-1   (ID_SCL              )
 gpio-2   (SDA1                )
 gpio-3   (SCL1                )
 gpio-4   (GPIO_GCLK           )
 gpio-5   (GPIO5               )
 gpio-6   (GPIO6               )
 gpio-7   (SPI_CE1_N           |spi0 CS1            ) out hi ACTIVE LOW
 gpio-8   (SPI_CE0_N           |spi0 CS0            ) in  hi ACTIVE LOW
 gpio-9   (SPI_MISO            )
 gpio-10  (SPI_MOSI            )
 gpio-11  (SPI_SCLK            )
 gpio-12  (GPIO12              )
 gpio-13  (GPIO13              )
<snip>

@JohnnyWulgaru
Copy link

I "blindly" remapped the CS0 pin of the SPI interface to a different pin. It seems to work now.
I used the following commands on my RPi4 to move CS0 from Pin8 to Pin26:

dtoverlay spi0-cs cs0_pin=26 cs1_pin=7
dtparam spi=off
dtparam spi=on

This moves the CS0 pin to 26 and the ResourceBusy error disappears and I can render content to my display.

@caemor caemor added the bug Something isn't working label Sep 28, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants