adafruit / Adafruit_Blinka

Add CircuitPython hardware API and libraries to MicroPython & CPython devices
https://learn.adafruit.com/circuitpython-on-raspberrypi-linux
MIT License
457 stars 345 forks source link

BLINKA_FORCEBOARD ignored when trying to use SPI from busio.py #130

Closed satmandu closed 5 years ago

satmandu commented 5 years ago

Trying to run this on a 3B+ on ubuntu arm64:

import board
import busio
import digitalio
import adafruit_bme280

spi = busio.SPI(board.SCK, MOSI=board.MOSI, MISO=board.MISO)
cs = digitalio.DigitalInOut(board.D5)
bme280 = adafruit_bme280.Adafruit_BME280_SPI(spi, cs)
print("\nTemperature: %0.1f C" % bme280.temperature)
print("Humidity: %0.1f %%" % bme280.humidity)
print("Pressure: %0.1f hPa" % bme280.pressure)

(I needed to do this first to get arm64 friendly RPi.GPIO):

sudo apt install mercurial
sudo pip3 install --upgrade hg+http://hg.code.sf.net/p/raspberry-gpio-python/code#egg=RPi.GPIO

For testing I do:

sudo BLINKA_FORCEBOARD=RASPBERRY_PI_3B_PLUS BLINKA_FORCECHIP=BCM2XXX python3 test.py 
Traceback (most recent call last):
  File "test.py", line 6, in <module>
    spi = busio.SPI(board.SCK, MOSI=board.MOSI, MISO=board.MISO)
  File "/usr/local/lib/python3.7/dist-packages/busio.py", line 78, in __init__
    from machine import SPI as _SPI
ModuleNotFoundError: No module named 'machine'

From looking at busio.py it seems that BLINKA_FORCEBOARD=RASPBERRY_PI_3B_PLUS doesn't make detector.board.any_raspberry_pi: evaluate as true.

Forcing

from adafruit_blinka.microcontroller.bcm283x.pin import Pin
from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI

does give the output I was expecting:

sudo BLINKA_FORCEBOARD=RASPBERRY_PI_3B_PLUS BLINKA_FORCECHIP=BCM2XXX python3 test.py
Temperature: 27.9 C
Humidity: 50.7 %
Pressure: 1011.8 hPa

(Detection of RPI3B+ from arm64 is another issue, since /proc/cpuinfo doesn't give anything useful on mainline arm64 kernels.) Though that is addressed in part in gpio-python here https://sourceforge.net/p/raspberry-gpio-python/tickets/161/ by looking at cat /proc/device-tree/system/linux,revision | xxd on some arm64 systems (though not on mainline kernels), though /proc/device-tree/model seems to be always useful:

cat /proc/device-tree/model 
Raspberry Pi 3 Model B
makermelissa commented 5 years ago

Hi, at the moment only Raspbian is officially supported. Would you like to try and get it working on ubuntu? I'm not sure if it will give you enough info to be correctly recognized.

satmandu commented 5 years ago

That would be useful. I have it working on ubuntu arm64 with a tiny bit of ugly hackery. (AFAIK Raspbian has not bothered with supporting arm64 yet.)

Any chance of using any code to verify the model from /proc/device-tree/model ?

I noticed that get_device_model in adafruit_platformdetect/init.py does exist, which might be able to find the correct info in /proc/device-tree/model if nothing useful comes up in /proc/cpuinfo.

makermelissa commented 5 years ago

Hi, we're adding lots of new boards lately and I'm sure at some point that would be handy. Would you like to give it a try with updating PlatformDetect to work with this?

satmandu commented 5 years ago

There's already some discussion of using device-tree/model here: https://github.com/adafruit/Adafruit_Python_PlatformDetect/issues/20

And it is already being used as per that thread in https://github.com/adafruit/adafruit-beaglebone-io-python/blob/master/source/common.c#L578 for beaglebone_blue. If there's some refactoring planned to integrate all that work, then it seems silly to add a one-off hack for the arm64 rpi boards.

But it would be nice to be able to manually specify the board through an environment variable and just have that work.

One quick fix for the raspberry pi arm64 machines would be to change busio.py from

def configure(self, baudrate=100000, polarity=0, phase=0, bits=8):
        if detector.board.any_raspberry_pi:
            from adafruit_blinka.microcontroller.bcm283x.pin import Pin
            from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI

to

def configure(self, baudrate=100000, polarity=0, phase=0, bits=8):
        if detector.board.any_raspberry_pi or detector.board.any_raspberry_pi_40_pin:
            from adafruit_blinka.microcontroller.bcm283x.pin import Pin
            from adafruit_blinka.microcontroller.generic_linux.spi import SPI as _SPI