Adafruit_Python_PlatformDetect/adafruit_platformdetect/board.py
Brennen Bearnes 0c491f95a2 refactor board detection to dependent on chip; simplify getattr checking
Per feedback here and elsewhere:

https://forum.armbian.com/topic/8981-adafruit-circuitpython/?tab=comments#comment-67633

There's still plenty to be done here, but this is cleaner than it was.

Also makes some names more consistent, and uses uppercase string values for id
constants.
2018-12-11 14:25:36 -07:00

136 lines
4.2 KiB
Python

import adafruit_platformdetect.chip as ap_chip
import platform
import sys
import re
# Pi revision codes from:
# https://www.raspberrypi.org/documentation/hardware/raspberrypi/revision-codes/README.md
BEAGLEBONE_BLACK = "BEAGLEBONE_BLACK"
FEATHER_HUZZAH = "FEATHER_HUZZAH"
FEATHER_M0_EXPRESS="FEATHER_M0_EXPRESS"
PYBOARD = "PYBOARD"
NODEMCU = "NODEMCU"
ORANGE_PI_PC = "ORANGE_PI_PC"
RASPBERRY_PI_B = "RASPBERRY_PI_B"
RASPBERRY_PI_B_PLUS = "RASPBERRY_PI_B_PLUS"
RASPBERRY_PI_A = "RASPBERRY_PI_A"
RASPBERRY_PI_A_PLUS = "RASPBERRY_PI_A_PLUS"
RASPBERRY_PI_CM1 = "RASPBERRY_PI_CM1"
RASPBERRY_PI_ZERO = "RASPBERRY_PI_ZERO"
RASPBERRY_PI_ZERO_W = "RASPBERRY_PI_ZERO_W"
RASPBERRY_PI_2B = "RASPBERRY_PI_2B"
RASPBERRY_PI_3B = "RASPBERRY_PI_3B"
RASPBERRY_PI_3B_PLUS = "RASPBERRY_PI_3B_PLUS"
RASPBERRY_PI_CM3 = "RASPBERRY_PI_CM3"
RASPBERRY_PI_3A_PLUS = "RASPBERRY_PI_3A_PLUS"
# TODO: Should this include RASPBERRY_PI_3A_PLUS or any other models?
ANY_RASPBERRY_PI_2_OR_3 = (
RASPBERRY_PI_2B,
RASPBERRY_PI_3B,
RASPBERRY_PI_3B_PLUS
)
_PI_REV_CODES = {
RASPBERRY_PI_B: ('0002', '0003', '0004', '0005', '0006', '000d', '000e', '000f'),
RASPBERRY_PI_B_PLUS: ('0010', '0013', '900032'),
RASPBERRY_PI_A: ('0007', '0008', '0009'),
RASPBERRY_PI_A_PLUS: ('0012', '0015', '900021'),
RASPBERRY_PI_CM1: ('0011', '0014'),
RASPBERRY_PI_ZERO: ('900092', '920092', '900093', '920093'),
RASPBERRY_PI_ZERO_W: ('9000c1',),
RASPBERRY_PI_2B: ('a01040', 'a01041', 'a21041', 'a22042'),
RASPBERRY_PI_3B: ('a22082', 'a32082', 'a52082'),
RASPBERRY_PI_3B_PLUS: ('a020d3',),
RASPBERRY_PI_CM3: ('a020a0',),
RASPBERRY_PI_3A_PLUS: ('9020e0',),
}
class Board:
"""
Attempt to detect specific boards.
"""
def __init__(self, detect):
self.detect = detect
@property
def id(self):
"""Return a unique id for the detected board, if any."""
chip_id = self.detect.chip.id
if chip_id == ap_chip.BCM2XXX:
return self._pi_id()
elif chip_id == ap_chip.AM33XX:
return BEAGLEBONE_BLACK
elif chip_id == ap_chip.SUN8I:
return self._armbian_id()
elif chip_id == ap_chip.ESP8266:
return FEATHER_HUZZAH
elif chip_id == ap_chip.SAMD21:
return FEATHER_M0_EXPRESS
elif chip_id == ap_chip.STM32:
return PYBOARD
return None
def _pi_id(self):
"""Try to detect id of a Raspberry Pi."""
# Check for Pi boards:
pi_rev_code = self._pi_rev_code()
if pi_rev_code:
for model, codes in _PI_REV_CODES.items():
if pi_rev_code in codes:
return model
return None
def _pi_rev_code(self):
"""Attempt to find a Raspberry Pi revision code for this board."""
# 2708 is Pi 1
# 2709 is Pi 2
# 2835 is Pi 3 (or greater) on 4.9.x kernel
# Anything else is not a Pi.
if self.detect.chip.id != ap_chip.BCM2XXX:
# Something else, not a Pi.
return None
return self.detect.get_cpuinfo_field('Revision')
@property
def _armbian_id(self):
"""Check whether the current board is an OrangePi PC."""
board_value = self.detect.get_armbian_release_field('BOARD')
if board_value == "orangepipc":
return ORANGE_PI_PC
return None
@property
def beaglebone_black(self):
"""Check whether the current board is a Beaglebone Black."""
return self.id == BEAGLEBONE_BLACK
@property
def orange_pi_pc(self):
"""Check whether the current board is an Orange Pi PC."""
return self.id == ORANGE_PI_PC
@property
def any_raspberry_pi(self):
"""Check whether the current board is any Raspberry Pi."""
return self._pi_rev_code() is not None
@property
def any_raspberry_pi_2_or_3(self):
return self.id in ANY_RASPBERRY_PI_2_OR_3
def __getattr__(self, attr):
"""
Detect whether the given attribute is the current board. Currently
handles Raspberry Pi models; other board properties are handled by
individual methods for the time being.
"""
if self.id == attr:
return True
else:
return False