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

Missing support for USR% leds on BBB #96

Closed
hulkco opened this issue Mar 23, 2019 · 13 comments
Closed

Missing support for USR% leds on BBB #96

hulkco opened this issue Mar 23, 2019 · 13 comments
Assignees
Labels
bug Something isn't working

Comments

@hulkco
Copy link

hulkco commented Mar 23, 2019

Hi, I'm testing Blinka on a BBB, and I have this problem when trying to use User Leds

debian@beaglebone:/var/lib/cloud9/python$ sudo python3 blinka_blink.py
hello blinky!
Traceback (most recent call last):
  File "blinka_blink.py", line 9, in <module>
    led = digitalio.DigitalInOut(board.LED_USR1)
  File "/usr/local/lib/python3.5/dist-packages/Adafruit_Blinka-1.2.7.dev3+g5d33134-py3.5.egg/digitalio.py", line 67, in __init__
    self.direction = Direction.INPUT
  File "/usr/local/lib/python3.5/dist-packages/Adafruit_Blinka-1.2.7.dev3+g5d33134-py3.5.egg/digitalio.py", line 93, in direction
    self._pin.init(mode=Pin.IN)
  File "/usr/local/lib/python3.5/dist-packages/Adafruit_Blinka-1.2.7.dev3+g5d33134-py3.5.egg/adafruit_blinka/microcontroller/am335x/pin.py", line 30, in init
    GPIO.setup(self.id, GPIO.IN)
ValueError: Set gpio mode failed, missing file or invalid permissions.

Thank you for your attention

@s-light
Copy link
Contributor

s-light commented Mar 28, 2019

i also just have begun to play with Blinka and related on a PocketBeagle -
but with some digging it seems the LEDs are defined in the mapping:
board/beaglebone_black.py#L73
microcontroller/am335x/pin.py#L127

and can you test the example directly from an ssh-comandline?
i also had problems with the Cloud IDE with one example...
but the same one worked from the cmd..

also - from the cmd you can try if you need to run the example as root -
something like:
$ sudo python3 blinka_blink.py
i don't know if it is currently needed in every case..
but the or invalid permissions. part of the error message could point to this..

you also can try to use the Adafruit Beaglebone I/O Python API
library directly and this way know if the used 'backend' works:
(it should already be installed - but it does not hurt to update it with pip3 ;-))

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""simple test for Adafruit_BBIO GPIO."""

import sys
import time

import Adafruit_BBIO.GPIO as GPIO

# print python version - just so we know what we are using ;-)
print(sys.version)

mypin = "USR3"
GPIO.setup(mypin, GPIO.OUT)

print(mypin, "blink...")

try:
    while True:
        GPIO.output(mypin, GPIO.HIGH)
        time.sleep(0.5)
        GPIO.output(mypin, GPIO.LOW)
        time.sleep(0.5)
except Exception as e:
    raise e
finally:
    print("cleanup")
    GPIO.output(mypin, GPIO.LOW)
    GPIO.cleanup()

PS: by the way - try to use code-block-formatting - that would be easier to read..

@pdp7
Copy link
Collaborator

pdp7 commented Mar 30, 2019

@hulkco thanks for raising this issue.

Please paste the output of this script:
sudo /opt/scripts/tools/version.sh
and paste the contents of:
/boot/uEnv.txt

The error you encountered:

ValueError: Set gpio mode failed, missing file or invalid permissions.

can be ambiguous as to the root cause.

When such an error occurs, running Python with strace will show the system calls that occurred and is useful to determining the exact path of the directory or file that is causing the error.

I will try to reproduce the issue you encountered and report back.

@pdp7
Copy link
Collaborator

pdp7 commented Mar 30, 2019

Adafruit_Blinka is using Adafruit_BBIO as the backend as @s-light mentioned.

For reference, the Linux kernel has a LED subsystem which is different than the GPIO subsystem. Therefore, the built-in LED devices show up under /sys/class/leds/ instead of /sys/class/gpio.

This requires a special case in Adafruit_BBIO to handle the built-in LEDs:
https://github.com/adafruit/adafruit-beaglebone-io-python/blob/master/source/event_gpio.c#L220

    // create file descriptor of value file
    if ((gpio >= USR_LED_GPIO_MIN) && (gpio <=  USR_LED_GPIO_MAX)) {
        snprintf(filename, sizeof(filename), "/sys/class/leds/beaglebone:green:usr%d/brightness", gpio -  USR_LED_GPIO_MIN);
    } else if (beaglebone_blue()) {
        //syslog(LOG_DEBUG, "Adafruit_BBIO: gpio open_value_file: beaglebone_blue() is true\n");
        switch(gpio) {
            case USR_LED_RED:
                snprintf(filename, sizeof(filename), "/sys/class/leds/red/brightness");
                break;
            case USR_LED_GREEN:
                snprintf(filename, sizeof(filename), "/sys/class/leds/green/brightness");
                break;
            case BAT25:
                snprintf(filename, sizeof(filename), "/sys/class/leds/bat25/brightness");
                break;
            case BAT50:
                snprintf(filename, sizeof(filename), "/sys/class/leds/bat50/brightness");
                break;
            case BAT75:
                snprintf(filename, sizeof(filename), "/sys/class/leds/bat75/brightness");
                break;
            case BAT100:
                snprintf(filename, sizeof(filename), "/sys/class/leds/bat100/brightness");
                break;
            case WIFI:
                snprintf(filename, sizeof(filename), "/sys/class/leds/wifi/brightness");
                break;
            default:
                snprintf(filename, sizeof(filename), "/sys/class/gpio/gpio%d/value", gpio);
                break;
        }
    } else {
        //syslog(LOG_DEBUG, "Adafruit_BBIO: gpio open_value_file: default gpio path\n");
        snprintf(filename, sizeof(filename), "/sys/class/gpio/gpio%d/value", gpio);
    }

Adafruit_Blinka should inherit this logic from Adafruit_BBIO. I'll test the USR LEDs too and report with my findings.

@pdp7 pdp7 self-assigned this Mar 30, 2019
@pdp7 pdp7 added the bug Something isn't working label Mar 30, 2019
@hulkco
Copy link
Author

hulkco commented Mar 30, 2019

I hope this helps.

The source code is:

import board
import digitalio
import busio
import time

#led = digitalio.DigitalInOut(board.LED_USR0)
led = digitalio.DigitalInOut(board.LED_USR1)
led.direction = digitalio.Direction.OUTPUT


while True:
    led.value = True
    time.sleep(0.5)
    led.value = False
    time.sleep(0.5)

The output using trace is:

$ sudo python3 -mtrace --trace led_test.py | egrep '^(digitalio.py)'
digitalio.py(8): """
digitalio.py(10): from adafruit_blinka.agnostic import board_id, detector
digitalio.py(16): elif detector.chip.AM33XX:
digitalio.py(17):     from adafruit_blinka.microcontroller.am335x.pin import Pin
digitalio.py(32): class DriveMode(Enum):
digitalio.py(33):     PUSH_PULL = None
digitalio.py(34):     OPEN_DRAIN = None
digitalio.py(37): DriveMode.PUSH_PULL = DriveMode()
digitalio.py(38): DriveMode.OPEN_DRAIN = DriveMode()
digitalio.py(41): class Direction(Enum):
digitalio.py(41): class Direction(Enum):
digitalio.py(42):     INPUT = None
digitalio.py(43):     OUTPUT = None
digitalio.py(46): Direction.INPUT = Direction()
digitalio.py(47): Direction.OUTPUT = Direction()
digitalio.py(50): class Pull(Enum):
digitalio.py(50): class Pull(Enum):
digitalio.py(51):     UP = None
digitalio.py(52):     DOWN = None
digitalio.py(56): Pull.UP = Pull()
digitalio.py(57): Pull.DOWN = Pull()
digitalio.py(62): class DigitalInOut(ContextManaged):
digitalio.py(62): class DigitalInOut(ContextManaged):
digitalio.py(63):     _pin = None
digitalio.py(65):     def __init__(self, pin):
digitalio.py(69):     def switch_to_output(self, value=False, drive_mode=DriveMode.PUSH_PULL):
digitalio.py(74):     def switch_to_input(self, pull=None):
digitalio.py(78):     def deinit(self):
digitalio.py(81):     @property
digitalio.py(85):     @direction.setter
digitalio.py(98):     @property
digitalio.py(102):     @value.setter
digitalio.py(109):     @property
digitalio.py(116):     @pull.setter
digitalio.py(135):     @property
digitalio.py(142):     @drive_mode.setter
Traceback (most recent call last):
  File "/usr/lib/python3.5/runpy.py", line 193, in _run_module_as_main
    "__main__", mod_spec)
  File "/usr/lib/python3.5/runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "/usr/lib/python3.5/trace.py", line 856, in <module>
    main()
  File "/usr/lib/python3.5/trace.py", line 802, in main
    t.runctx(code, globs, globs)
  File "/usr/lib/python3.5/trace.py", line 508, in runctx
    exec(cmd, globals, locals)
  File "led_test.py", line 7, in <module>
    led = digitalio.DigitalInOut(board.LED_USR1)
  File "/usr/local/lib/python3.5/dist-packages/digitalio.py", line 67, in __init__
    self.direction = Direction.INPUT
  File "/usr/local/lib/python3.5/dist-packages/digitalio.py", line 93, in direction
    self._pin.init(mode=Pin.IN)
  File "/usr/local/lib/python3.5/dist-packages/adafruit_blinka/microcontroller/am335x/pin.py", line 30, in init
    GPIO.setup(self.id, GPIO.IN)
ValueError: Set gpio mode failed, missing file or invalid permissions.
digitalio.py(66):         self._pin = Pin(pin.id)
digitalio.py(67):         self.direction = Direction.INPUT
digitalio.py(87):         self.__direction = dir
digitalio.py(88):         if dir is Direction.OUTPUT:
digitalio.py(92):         elif dir is Direction.INPUT:
digitalio.py(93):             self._pin.init(mode=Pin.IN)

@pdp7
Copy link
Collaborator

pdp7 commented Mar 30, 2019

@hulkco thanks, I able to reproduce the issue:

debian@beaglebone:~/pr/Adafruit_Blinka$ sudo strace -o /tmp/strace.log python3 examples/usr.py
Traceback (most recent call last):
  File "examples/usr.py", line 7, in <module>
    led = digitalio.DigitalInOut(board.LED_USR1)
  File "/usr/local/lib/python3.5/dist-packages/Adafruit_Blinka-1.2.9.dev5+gcbfa2eb.d20190330-py3.5.egg/digitalio.py", line 67, in __init__
    self.direction = Direction.INPUT
  File "/usr/local/lib/python3.5/dist-packages/Adafruit_Blinka-1.2.9.dev5+gcbfa2eb.d20190330-py3.5.egg/digitalio.py", line 93, in direction
    self._pin.init(mode=Pin.IN)
  File "/usr/local/lib/python3.5/dist-packages/Adafruit_Blinka-1.2.9.dev5+gcbfa2eb.d20190330-py3.5.egg/adafruit_blinka/microcontroller/am335x/pin.py", line 30, in init
    GPIO.setup(self.id, GPIO.IN)
ValueError: Set gpio mode failed, missing file or invalid permissions.
debian@beaglebone:~/pr/Adafruit_Blinka$ 

from the strace output:

debian@beaglebone:~/pr/Adafruit_Blinka$ sudo strace -o /tmp/strace.log python3 examples/usr.py

there is this line:

open("/sys/devices/platform/ocp/ocp:USR01_pinmux/state", O_WRONLY|O_CREAT|O_TRUNC, 0666) = -1 ENOENT (No such file or directory)

The issue is that is the wrong path for the USR LED.

I have to investigate why this is handled differently than in Adafruit_BBIO directly.

@pdp7
Copy link
Collaborator

pdp7 commented Mar 30, 2019

For comparision, in Adafruit_BBIO:

debian@beaglebone:~/adafruit-beaglebone-io-python/source/examples$ cat ~/usr1.py 
import Adafruit_BBIO.GPIO as GPIO
LED = "USR1"
GPIO.setup(LED, GPIO.OUT)
GPIO.output(LED, 1)
debian@beaglebone:~/adafruit-beaglebone-io-python/source/examples$ sudo strace -o /tmp/strace2.txt python3  ~/usr1.py
debian@beaglebone:~/adafruit-beaglebone-io-python/source/examples$ grep /sys /tmp/strace2.txt 
access("/sys/class/leds/beaglebone:green:usr1/brightness", W_OK) = 0
open("/sys/class/leds/beaglebone:green:usr1/brightness", O_WRONLY) = 4
access("/sys/class/leds/beaglebone:green:usr1/brightness", W_OK) = 0
open("/sys/class/leds/beaglebone:green:usr1/brightness", O_WRONLY) = 4

@pdp7
Copy link
Collaborator

pdp7 commented Apr 1, 2019

I believe this behavior is due to a bug in Adafruit_BBIO where USRn LED is setup initially in INPUT mode instead of OUTPUT mode.

I hard coded the pin to be an output to test:

diff --git a/src/adafruit_blinka/microcontroller/am335x/pin.py b/src/adafruit_blinka/microcontroller/am335x/pin.py
index 71715e6..0455454 100644
--- a/src/adafruit_blinka/microcontroller/am335x/pin.py
+++ b/src/adafruit_blinka/microcontroller/am335x/pin.py
@@ -24,12 +24,17 @@ class Pin:
         return self.id == other
 
     def init(self, mode=IN, pull=None):
+        print("am335x: init(): self.id {0}".format(self.id))
+        # HARD CODE TO OUTPUT
+        mode = self.OUT
         if mode != None:
             if mode == self.IN:
+                print("am335x: self.IN: self.id {0}".format(self.id))
                 self._mode = self.IN
                 GPIO.setup(self.id, GPIO.IN)
             elif mode == self.OUT:
                 self._mode = self.OUT
+                print("am335x: self.OUT: self.id {0}".format(self.id))
                 GPIO.setup(self.id, GPIO.OUT)
             else:
                 raise RuntimeError("Invalid mode for pin: %s" % self.id)

This now works:

led = digitalio.DigitalInOut(board.LED_USR0)

strace shows that the correct path is being used:

access("/sys/class/leds/beaglebone:green:usr0/brightness", W_OK) = 0
open("/sys/class/leds/beaglebone:green:usr0/brightness", O_WRONLY) = 4

I'll investigate further the root cause in Adafruit_BBIO

@pdp7
Copy link
Collaborator

pdp7 commented Apr 1, 2019

I can reproduce the behavior directly in Adafruit_BBIO by calling GPIO.setup("USR1", GPIO.IN) instead of GPIO.setup("USR1", GPIO.OUT)

import Adafruit_BBIO.GPIO as GPIO
GPIO.setup("USR1", GPIO.IN)

results in error:

Traceback (most recent call last):
  File "/home/debian/test-usr.py", line 2, in <module>
    GPIO.setup("USR1", GPIO.IN)
ValueError: Set gpio mode failed, missing file or invalid permissions.

and strace shows the bad path:

open("/sys/devices/platform/ocp/ocp:USR01_pinmux/state", O_WRONLY|O_CREAT|O_TRUNC, 0666) = -1 ENOENT (No such file or directory)

pdp7 added a commit to adafruit/adafruit-beaglebone-io-python that referenced this issue Apr 1, 2019
This fix resolves Adafruit_BBIO issue #310 and adafruit/Adafruit_Blinka#96 which was preventing the USR LEDs from being used by the CircuitPython Blinka library
@pdp7
Copy link
Collaborator

pdp7 commented Apr 1, 2019

This issue should now be resolved by the fix in Adafruit_BBIO for:
adafruit/adafruit-beaglebone-io-python#310

This example now runs OK and blinks USR0:

import board
import digitalio
import busio
import time

led = digitalio.DigitalInOut(board.LED_USR0)
led.direction = digitalio.Direction.OUTPUT


while True:
    led.value = True
    time.sleep(0.5)
    led.value = False
    time.sleep(0.5)

@pdp7
Copy link
Collaborator

pdp7 commented Apr 1, 2019

@hulkco please install the current master of https://github.com/adafruit/adafruit-beaglebone-io-python/ and let me know if USR LEDs work in Blinka. thanks!

@ladyada
Copy link
Member

ladyada commented Apr 1, 2019

amazing, thanks @pdp7

@pdp7
Copy link
Collaborator

pdp7 commented Apr 3, 2019

@hulkco have you had a chance to try the current master branch of Adafruit_BBIO and see if you can now blink USR LEDs with Blinka?

If so, I will create a new release of Adafruit_BBIO and publish to PyPI and then close this issue.

@hulkco
Copy link
Author

hulkco commented Apr 4, 2019

Ready @pdp7 , all the LEDs work, i close the issue, thanks dude!!!
Selección_091

@hulkco hulkco closed this as completed Apr 4, 2019
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

4 participants