You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

755 lines
27 KiB

2 years ago
3 years ago
2 years ago
3 years ago
3 years ago
3 years ago
3 years ago
4 years ago
3 years ago
1 year ago
1 year ago
4 years ago
2 years ago
2 years ago
2 years ago
3 years ago
3 years ago
3 years ago
3 years ago
4 years ago
1 year ago
1 year ago
4 years ago
3 years ago
4 years ago
3 years ago
4 years ago
4 years ago
4 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
  1. # SPDX-FileCopyrightText: 2021 Melissa LeBlanc-Williams for Adafruit Industries
  2. #
  3. # SPDX-License-Identifier: MIT
  4. """
  5. `adafruit_platformdetect.board`
  6. ================================================================================
  7. Detect boards
  8. * Author(s): Melissa LeBlanc-Williams
  9. Implementation Notes
  10. --------------------
  11. **Software and Dependencies:**
  12. * Linux and Python 3.7 or Higher
  13. """
  14. import os
  15. import re
  16. try:
  17. from typing import Optional
  18. except ImportError:
  19. pass
  20. from adafruit_platformdetect.constants import boards, chips
  21. __version__ = "0.0.0-auto.0"
  22. __repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_PlatformDetect.git"
  23. class Board:
  24. """Attempt to detect specific boards."""
  25. def __init__(self, detector) -> None:
  26. self.detector = detector
  27. self._board_id = None
  28. # pylint: disable=invalid-name, protected-access, too-many-return-statements
  29. @property
  30. def id(self) -> Optional[str]:
  31. """Return a unique id for the detected board, if any."""
  32. # There are some times we want to trick the platform detection
  33. # say if a raspberry pi doesn't have the right ID, or for testing
  34. # Caching
  35. if self._board_id:
  36. return self._board_id
  37. try:
  38. return os.environ["BLINKA_FORCEBOARD"]
  39. except (AttributeError, KeyError): # no forced board, continue with testing!
  40. pass
  41. chip_id = self.detector.chip.id
  42. board_id = None
  43. if chip_id == chips.H3:
  44. board_id = self._armbian_id() or self._allwinner_variants_id()
  45. elif chip_id == chips.BCM2XXX:
  46. board_id = self._pi_id()
  47. elif chip_id == chips.AM33XX:
  48. board_id = self._beaglebone_id()
  49. elif chip_id == chips.DRA74X:
  50. board_id = self._bbai_id()
  51. elif chip_id == chips.SUN8I:
  52. board_id = self._armbian_id() or self._allwinner_variants_id()
  53. elif chip_id == chips.SAMA5:
  54. board_id = self._sama5_id()
  55. elif chip_id == chips.IMX8MX:
  56. board_id = self._imx8mx_id()
  57. elif chip_id == chips.IMX6ULL:
  58. board_id = self._imx6ull_id()
  59. elif chip_id == chips.S905Y2:
  60. board_id = boards.RADXA_ZERO
  61. elif chip_id == chips.ESP8266:
  62. board_id = boards.FEATHER_HUZZAH
  63. elif chip_id == chips.SAMD21:
  64. board_id = boards.FEATHER_M0_EXPRESS
  65. elif chip_id == chips.STM32F405:
  66. board_id = boards.PYBOARD
  67. elif chip_id == chips.RP2040:
  68. board_id = boards.RASPBERRY_PI_PICO
  69. elif chip_id == chips.S805:
  70. board_id = boards.ODROID_C1
  71. elif chip_id == chips.S905:
  72. board_id = boards.ODROID_C2
  73. elif chip_id == chips.S905X3:
  74. board_id = self._s905x3_id()
  75. elif chip_id == chips.S922X:
  76. board_id = boards.ODROID_N2
  77. elif chip_id == chips.A311D:
  78. board_id = boards.KHADAS_VIM3
  79. elif chip_id == chips.EXYNOS5422:
  80. board_id = boards.ODROID_XU4
  81. elif chip_id == chips.FT232H:
  82. board_id = boards.FTDI_FT232H
  83. elif chip_id == chips.FT2232H:
  84. board_id = boards.FTDI_FT2232H
  85. elif chip_id == chips.APQ8016:
  86. board_id = boards.DRAGONBOARD_410C
  87. elif chip_id in (chips.T210, chips.T186, chips.T194, chips.T234):
  88. board_id = self._tegra_id()
  89. elif chip_id == chips.HFU540:
  90. board_id = self._sifive_id()
  91. elif chip_id == chips.C906:
  92. board_id = self._allwinner_id()
  93. elif chip_id == chips.JH71x0:
  94. board_id = self._beaglebone_id()
  95. elif chip_id == chips.MCP2221:
  96. board_id = boards.MICROCHIP_MCP2221
  97. elif chip_id == chips.BINHO:
  98. board_id = boards.BINHO_NOVA
  99. elif chip_id == chips.LPC4330:
  100. board_id = boards.GREATFET_ONE
  101. elif chip_id == chips.MIPS24KC:
  102. board_id = boards.ONION_OMEGA
  103. elif chip_id == chips.MIPS24KEC:
  104. board_id = boards.ONION_OMEGA2
  105. elif chip_id == chips.ZYNQ7000:
  106. board_id = self._pynq_id()
  107. elif chip_id == chips.A64:
  108. board_id = self._pine64_id()
  109. elif chip_id == chips.H6:
  110. board_id = self._pine64_id() or self._armbian_id()
  111. elif chip_id == chips.H5:
  112. board_id = self._armbian_id() or self._allwinner_variants_id()
  113. elif chip_id == chips.H616:
  114. board_id = self._armbian_id() or self._allwinner_variants_id()
  115. elif chip_id == chips.A33:
  116. board_id = self._clockwork_pi_id()
  117. elif chip_id == chips.RK3308:
  118. board_id = self._rock_pi_id()
  119. elif chip_id == chips.RK3399:
  120. board_id = self._rock_pi_id()
  121. elif chip_id == chips.ATOM_X5_Z8350:
  122. board_id = self._rock_pi_id()
  123. elif chip_id == chips.RK3288:
  124. board_id = self._asus_tinker_board_id()
  125. elif chip_id == chips.RK3328:
  126. board_id = self._rock_pi_id()
  127. elif chip_id == chips.RYZEN_V1605B:
  128. board_id = self._udoo_id()
  129. elif chip_id == chips.PENTIUM_N3710:
  130. board_id = self._udoo_id()
  131. elif chip_id == chips.STM32MP157:
  132. board_id = self._stm32mp1_id()
  133. elif chip_id == chips.STM32MP157DAA1:
  134. board_id = self._stm32mp1_id()
  135. elif chip_id == chips.MT8167:
  136. board_id = boards.CORAL_EDGE_TPU_DEV_MINI
  137. elif chip_id == chips.RP2040_U2IF:
  138. board_id = self._rp2040_u2if_id()
  139. elif chip_id == chips.GENERIC_X86:
  140. board_id = boards.GENERIC_LINUX_PC
  141. elif chip_id == chips.TDA4VM:
  142. board_id = self._tisk_id()
  143. self._board_id = board_id
  144. return board_id
  145. # pylint: enable=invalid-name
  146. def _pi_id(self) -> Optional[str]:
  147. """Try to detect id of a Raspberry Pi."""
  148. # Check for Pi boards:
  149. pi_rev_code = self._pi_rev_code()
  150. if pi_rev_code:
  151. for model, codes in boards._PI_REV_CODES.items():
  152. if pi_rev_code in codes:
  153. return model
  154. # We may be on a non-Raspbian OS, so try to lazily determine
  155. # the version based on `get_device_model`
  156. else:
  157. pi_model = self.detector.get_device_model()
  158. if pi_model:
  159. pi_model = pi_model.upper().replace(" ", "_")
  160. if "PLUS" in pi_model:
  161. re_model = re.search(r"(RASPBERRY_PI_\d).*([AB]_*)(PLUS)", pi_model)
  162. elif "CM" in pi_model: # untested for Compute Module
  163. re_model = re.search(r"(RASPBERRY_PI_CM)(\d)", pi_model)
  164. else: # untested for non-plus models
  165. re_model = re.search(r"(RASPBERRY_PI_\d).*([AB])", pi_model)
  166. if re_model:
  167. pi_model = "".join(re_model.groups())
  168. available_models = boards._PI_REV_CODES.keys()
  169. for model in available_models:
  170. if model == pi_model:
  171. return model
  172. return None
  173. def _pi_rev_code(self) -> Optional[str]:
  174. """Attempt to find a Raspberry Pi revision code for this board."""
  175. # 2708 is Pi 1
  176. # 2709 is Pi 2
  177. # 2835 is Pi 3 (or greater) on 4.9.x kernel
  178. # Anything else is not a Pi.
  179. if self.detector.chip.id != chips.BCM2XXX:
  180. # Something else, not a Pi.
  181. return None
  182. rev = self.detector.get_cpuinfo_field("Revision")
  183. if rev is not None:
  184. return rev
  185. try:
  186. with open("/proc/device-tree/system/linux,revision", "rb") as revision:
  187. rev_bytes = revision.read()
  188. if rev_bytes[:1] == b"\x00":
  189. rev_bytes = rev_bytes[1:]
  190. return rev_bytes.hex()
  191. except FileNotFoundError:
  192. return None
  193. # pylint: disable=no-self-use
  194. def _beaglebone_id(self) -> Optional[str]:
  195. """Try to detect id of a Beaglebone."""
  196. board_value = self.detector.get_device_compatible()
  197. # Older Builds
  198. if "freedom-u74-arty" in board_value:
  199. return boards.BEAGLEV_STARLIGHT
  200. # Newer Builds
  201. if "beaglev-starlight" in board_value:
  202. return boards.BEAGLEV_STARLIGHT
  203. try:
  204. with open("/sys/bus/nvmem/devices/0-00500/nvmem", "rb") as eeprom:
  205. eeprom_bytes = eeprom.read(16)
  206. except FileNotFoundError:
  207. try:
  208. with open("/sys/bus/nvmem/devices/0-00501/nvmem", "rb") as eeprom:
  209. eeprom_bytes = eeprom.read(16)
  210. except FileNotFoundError:
  211. return None
  212. if eeprom_bytes[:4] != b"\xaaU3\xee":
  213. return None
  214. # special condition for BeagleBone Green rev. 1A
  215. # refer to GitHub issue #57 in this repo for more info
  216. if eeprom_bytes == b"\xaaU3\xeeA335BNLT\x1a\x00\x00\x00":
  217. return boards.BEAGLEBONE_GREEN
  218. id_string = eeprom_bytes[4:].decode("ascii")
  219. for model, bb_ids in boards._BEAGLEBONE_BOARD_IDS.items():
  220. for bb_id in bb_ids:
  221. if id_string == bb_id[1]:
  222. return model
  223. board_value = self.detector.get_armbian_release_field("BOARD")
  224. return None
  225. # pylint: enable=no-self-use
  226. def _bbai_id(self) -> Optional[str]:
  227. """Try to detect id of a Beaglebone AI related board."""
  228. board_value = self.detector.get_device_model()
  229. if "BeagleBone AI" in board_value:
  230. return boards.BEAGLEBONE_AI
  231. return None
  232. def _tisk_id(self) -> Optional[str]:
  233. """Try to detect the id of aarch64 board."""
  234. compatible = self.detector.get_device_compatible()
  235. print(compatible)
  236. if not compatible:
  237. return None
  238. compats = compatible.split("\x00")
  239. for board_id, board_compats in boards._TI_SK_BOARD_IDS:
  240. if any(v in compats for v in board_compats):
  241. return board_id
  242. return None
  243. # pylint: disable=too-many-return-statements
  244. def _armbian_id(self) -> Optional[str]:
  245. """Check whether the current board is an OrangePi board."""
  246. board_value = self.detector.get_armbian_release_field("BOARD")
  247. board = None
  248. if board_value == "orangepipc":
  249. board = boards.ORANGE_PI_PC
  250. elif board_value == "orangepi-r1":
  251. board = boards.ORANGE_PI_R1
  252. elif board_value == "orangepizero":
  253. board = boards.ORANGE_PI_ZERO
  254. elif board_value == "orangepione":
  255. board = boards.ORANGE_PI_ONE
  256. elif board_value == "orangepilite":
  257. board = boards.ORANGE_PI_LITE
  258. elif board_value == "orangepiplus2e":
  259. board = boards.ORANGE_PI_PLUS_2E
  260. elif board_value == "orangepipcplus":
  261. board = boards.ORANGE_PI_PC_PLUS
  262. elif board_value == "pinebook-a64":
  263. board = boards.PINEBOOK
  264. elif board_value == "pineH64":
  265. board = boards.PINEH64
  266. elif board_value == "orangepi2":
  267. board = boards.ORANGE_PI_2
  268. elif board_value == "orangepi3":
  269. board = boards.ORANGE_PI_3
  270. elif board_value == "orangepi3-lts":
  271. board = boards.ORANGE_PI_3_LTS
  272. elif board_value == "bananapim2zero":
  273. board = boards.BANANA_PI_M2_ZERO
  274. elif board_value == "bananapim5":
  275. board = boards.BANANA_PI_M5
  276. elif board_value == "orangepizeroplus2-h5":
  277. board = boards.ORANGE_PI_ZERO_PLUS_2H5
  278. elif board_value == "orangepizeroplus":
  279. board = boards.ORANGE_PI_ZERO_PLUS
  280. elif board_value == "orangepizero2":
  281. board = boards.ORANGE_PI_ZERO_2
  282. elif board_value == "nanopiair":
  283. board = boards.NANOPI_NEO_AIR
  284. elif board_value == "nanopiduo2":
  285. board = boards.NANOPI_DUO2
  286. elif board_value == "nanopineo":
  287. board = boards.NANOPI_NEO
  288. return board
  289. # pylint: enable=too-many-return-statements
  290. # pylint: enable=too-many-return-statements
  291. def _sama5_id(self) -> Optional[str]:
  292. """Check what type sama5 board."""
  293. board_value = self.detector.get_device_model()
  294. if "Giant Board" in board_value:
  295. return boards.GIANT_BOARD
  296. return None
  297. def _s905x3_id(self) -> Optional[str]:
  298. """Check what type S905X3 board."""
  299. board_value = self.detector.get_device_model()
  300. if "Bananapi BPI-M5" in board_value:
  301. return boards.BANANA_PI_M5
  302. return boards.ODROID_C4
  303. def _stm32mp1_id(self) -> Optional[str]:
  304. """Check what type stm32mp1 board."""
  305. board_value = self.detector.get_device_model()
  306. if "STM32MP157C-DK2" in board_value:
  307. return boards.STM32MP157C_DK2
  308. if "LubanCat" in board_value:
  309. return boards.LUBANCAT_STM32MP157
  310. if "OSD32MP1-BRK" in board_value:
  311. return boards.OSD32MP1_BRK
  312. if "OSD32MP1-RED" in board_value:
  313. return boards.OSD32MP1_RED
  314. if "STM32MP1XX OLinuXino" in board_value:
  315. return boards.STMP157_OLINUXINO_LIME2
  316. return None
  317. def _imx8mx_id(self) -> Optional[str]:
  318. """Check what type iMX8M board."""
  319. board_value = self.detector.get_device_model()
  320. if "FSL i.MX8MM DDR4 EVK" in board_value:
  321. return boards.MAAXBOARD_MINI
  322. if "Freescale i.MX8MQ EVK" in board_value:
  323. return boards.MAAXBOARD
  324. if "Phanbell" in board_value:
  325. return boards.CORAL_EDGE_TPU_DEV
  326. return None
  327. def _imx6ull_id(self) -> Optional[str]:
  328. """Check what type iMX6ULL board."""
  329. board_value = self.detector.get_device_model()
  330. if "LubanCat" in board_value or "Embedfire" in board_value:
  331. return boards.LUBANCAT_IMX6ULL
  332. return None
  333. def _tegra_id(self) -> Optional[str]:
  334. """Try to detect the id of aarch64 board."""
  335. compatible = self.detector.get_device_compatible()
  336. if not compatible:
  337. return None
  338. compats = compatible.split("\x00")
  339. for board_id, board_compats in boards._JETSON_IDS:
  340. if any(v in compats for v in board_compats):
  341. return board_id
  342. return None
  343. def _sifive_id(self) -> Optional[str]:
  344. """Try to detect the id for Sifive RISCV64 board."""
  345. board_value = self.detector.get_device_model()
  346. if "hifive-unleashed-a00" in board_value:
  347. return boards.SIFIVE_UNLEASHED
  348. return None
  349. def _allwinner_id(self) -> Optional[str]:
  350. """Try to detect the id for Allwiner D1 board."""
  351. board_value = self.detector.get_device_model()
  352. if "sun20iw1p1" in board_value:
  353. return boards.ALLWINER_D1
  354. return None
  355. def _pine64_id(self) -> Optional[str]:
  356. """Try to detect the id for Pine64 board or device."""
  357. board_value = self.detector.get_device_model()
  358. board = None
  359. if "pine64" in board_value.lower():
  360. board = boards.PINE64
  361. elif "pine h64" in board_value.lower():
  362. board = boards.PINEH64
  363. elif "pinebook" in board_value.lower():
  364. board = boards.PINEBOOK
  365. elif "pinephone" in board_value.lower():
  366. board = boards.PINEPHONE
  367. elif "sopine" in board_value.lower():
  368. board = boards.SOPINE
  369. return board
  370. # pylint: disable=no-self-use
  371. def _pynq_id(self) -> Optional[str]:
  372. """Try to detect the id for Xilinx PYNQ boards."""
  373. try:
  374. with open(
  375. "/proc/device-tree/chosen/pynq_board", "r", encoding="utf-8"
  376. ) as board_file:
  377. board_model = board_file.read()
  378. match = board_model.upper().replace("-", "_").rstrip("\x00")
  379. for model in boards._PYNQ_IDS:
  380. if model == match:
  381. return model
  382. return None
  383. except FileNotFoundError:
  384. return None
  385. def _rock_pi_id(self) -> Optional[str]:
  386. """Check what type of Rock Pi board."""
  387. board_value = self.detector.get_device_model()
  388. board = None
  389. if board_value and "ROCK Pi S" in board_value:
  390. board = boards.ROCK_PI_S
  391. if board_value and "ROCK PI 4" in board_value.upper():
  392. board = boards.ROCK_PI_4
  393. if board_value and "ROCK PI E" in board_value.upper():
  394. board = boards.ROCK_PI_E
  395. if self.detector.check_board_name_value() == "ROCK Pi X":
  396. board = boards.ROCK_PI_X
  397. return board
  398. def _clockwork_pi_id(self) -> Optional[str]:
  399. """Check what type of Clockwork Pi board."""
  400. board_value = self.detector.get_device_model()
  401. board = None
  402. if board_value and "Clockwork CPI3" in board_value:
  403. board = boards.CLOCKWORK_CPI3
  404. return board
  405. def _udoo_id(self) -> Optional[str]:
  406. """Try to detect the id of udoo board."""
  407. board_asset_tag = self.detector.check_board_asset_tag_value()
  408. for board_id, board_tags in boards._UDOO_BOARD_IDS.items():
  409. if any(v == board_asset_tag for v in board_tags):
  410. return board_id
  411. if self.detector.check_board_name_value() == "UDOO x86":
  412. return boards.UDOO_X86
  413. return None
  414. def _asus_tinker_board_id(self) -> Optional[str]:
  415. """Check what type of Tinker Board."""
  416. board_value = self.detector.get_device_model()
  417. board = None
  418. if board_value and "ASUS Tinker Board" in board_value:
  419. board = boards._ASUS_TINKER_BOARD_IDS
  420. return board
  421. def _allwinner_variants_id(self) -> Optional[str]:
  422. """Try to detect the id of allwinner based board. (orangepi, nanopi)"""
  423. board_value = self.detector.get_device_model()
  424. board = None
  425. if not board_value:
  426. return board
  427. board_value = board_value.lower()
  428. chip_id = self.detector.chip.id
  429. if "nanopi" in board_value:
  430. if "neo" in board_value and "SUN8I" in chip_id:
  431. board = boards.NANOPI_NEO_AIR
  432. # TODO: Add other specifc board contexts here
  433. elif "orange pi" in board_value:
  434. if "zero" in board_value:
  435. if "H5" in chip_id:
  436. board = boards.ORANGE_PI_ZERO_PLUS_2H5
  437. elif "H616" in chip_id:
  438. board = boards.ORANGE_PI_ZERO_2
  439. # TODO: Add other specifc board contexts here
  440. return board
  441. def _rp2040_u2if_id(self) -> Optional[str]:
  442. import hid
  443. # look for it based on PID/VID
  444. for dev in hid.enumerate():
  445. # Raspberry Pi Pico
  446. vendor = dev["vendor_id"]
  447. product = dev["product_id"]
  448. if vendor == 0xCAFE and product == 0x4005:
  449. return boards.PICO_U2IF
  450. if vendor == 0x239A:
  451. # Feather RP2040
  452. if product == 0x00F1:
  453. return boards.FEATHER_U2IF
  454. # Itsy Bitsy RP2040
  455. if product == 0x00FD:
  456. return boards.ITSYBITSY_U2IF
  457. # QT Py RP2040
  458. if product == 0x00F7:
  459. return boards.QTPY_U2IF
  460. # QT2040 Trinkey
  461. if product == 0x0109:
  462. return boards.QT2040_TRINKEY_U2IF
  463. # MacroPad RP2040
  464. if product == 0x0107:
  465. return boards.MACROPAD_U2IF
  466. # Will only reach here if a device was added in chip.py but here.
  467. raise RuntimeError("RP2040_U2IF device was added to chip but not board.")
  468. @property
  469. def any_nanopi(self) -> bool:
  470. """Check whether the current board is any defined Nano Pi."""
  471. return self.id in boards._NANOPI_IDS
  472. @property
  473. def any_96boards(self) -> bool:
  474. """Check whether the current board is any 96boards board."""
  475. return self.id in boards._LINARO_96BOARDS_IDS
  476. @property
  477. def any_raspberry_pi(self) -> bool:
  478. """Check whether the current board is any Raspberry Pi."""
  479. return self._pi_rev_code() is not None
  480. @property
  481. def any_raspberry_pi_40_pin(self) -> bool:
  482. """Check whether the current board is any 40-pin Raspberry Pi."""
  483. return self.id in boards._RASPBERRY_PI_40_PIN_IDS
  484. @property
  485. def any_raspberry_pi_cm(self) -> bool:
  486. """Check whether the current board is any Compute Module Raspberry Pi."""
  487. return self.id in boards._RASPBERRY_PI_CM_IDS
  488. @property
  489. def any_beaglebone(self) -> bool:
  490. """Check whether the current board is any Beaglebone-family system."""
  491. return self.id in boards._BEAGLEBONE_IDS
  492. @property
  493. def any_orange_pi(self) -> bool:
  494. """Check whether the current board is any defined Orange Pi."""
  495. return self.id in boards._ORANGE_PI_IDS
  496. @property
  497. def any_lubancat(self) -> bool:
  498. """Check whether the current board is any defined lubancat."""
  499. return self.id in boards._LUBANCAT_IDS
  500. @property
  501. def any_coral_board(self) -> bool:
  502. """Check whether the current board is any defined Coral."""
  503. return self.id in boards._CORAL_IDS
  504. @property
  505. def any_pynq_board(self) -> bool:
  506. """Check whether the current board is any defined PYNQ Board."""
  507. return self.id in boards._PYNQ_IDS
  508. @property
  509. def any_giant_board(self) -> bool:
  510. """Check whether the current board is any defined Giant Board."""
  511. return self.GIANT_BOARD
  512. @property
  513. def any_odroid_40_pin(self) -> bool:
  514. """Check whether the current board is any defined 40-pin Odroid."""
  515. return self.id in boards._ODROID_40_PIN_IDS
  516. @property
  517. def khadas_vim3_40_pin(self) -> bool:
  518. """Check whether the current board is any defined 40-pin Khadas VIM3."""
  519. return self.id in boards._KHADAS_40_PIN_IDS
  520. @property
  521. def any_jetson_board(self) -> bool:
  522. """Check whether the current board is any defined Jetson Board."""
  523. return self.id in [v[0] for v in boards._JETSON_IDS]
  524. @property
  525. def any_sifive_board(self) -> bool:
  526. """Check whether the current board is any defined Jetson Board."""
  527. return self.id in boards._SIFIVE_IDS
  528. @property
  529. def any_onion_omega_board(self) -> bool:
  530. """Check whether the current board is any defined OpenWRT board."""
  531. return self.id in boards._ONION_OMEGA_BOARD_IDS
  532. @property
  533. def any_pine64_board(self) -> bool:
  534. """Check whether the current board is any Pine64 device."""
  535. return self.id in boards._PINE64_DEV_IDS
  536. @property
  537. def any_rock_pi_board(self) -> bool:
  538. """Check whether the current board is any Rock Pi device."""
  539. return self.id in boards._ROCK_PI_IDS
  540. @property
  541. def any_clockwork_pi_board(self) -> bool:
  542. """Check whether the current board is any Clockwork Pi device."""
  543. return self.CLOCKWORK_CPI3
  544. @property
  545. def any_udoo_board(self) -> bool:
  546. """Check to see if the current board is an UDOO board"""
  547. return self.id in boards._UDOO_BOARD_IDS
  548. @property
  549. def any_asus_tinker_board(self) -> bool:
  550. """Check to see if the current board is an ASUS Tinker Board"""
  551. return self.id in boards._ASUS_TINKER_BOARD_IDS
  552. @property
  553. def any_stm32mp1(self) -> bool:
  554. """Check whether the current board is any stm32mp1 board."""
  555. return self.id in boards._STM32MP1_IDS
  556. @property
  557. def any_bananapi(self) -> bool:
  558. """Check whether the current board is any BananaPi-family system."""
  559. return self.id in boards._BANANA_PI_IDS
  560. @property
  561. def any_maaxboard(self) -> bool:
  562. """Check whether the current board is any BananaPi-family system."""
  563. return self.id in boards._MAAXBOARD_IDS
  564. @property
  565. def any_tisk_board(self) -> bool:
  566. """Check whether the current board is any defined TI SK Board."""
  567. return self.id in [v[0] for v in boards._TI_SK_BOARD_IDS]
  568. @property
  569. def any_embedded_linux(self) -> bool:
  570. """Check whether the current board is any embedded Linux device."""
  571. return any(
  572. [
  573. self.any_raspberry_pi_40_pin,
  574. self.any_raspberry_pi,
  575. self.any_beaglebone,
  576. self.any_orange_pi,
  577. self.any_nanopi,
  578. self.any_giant_board,
  579. self.any_jetson_board,
  580. self.any_coral_board,
  581. self.any_odroid_40_pin,
  582. self.khadas_vim3_40_pin,
  583. self.any_96boards,
  584. self.any_sifive_board,
  585. self.any_onion_omega_board,
  586. self.any_pine64_board,
  587. self.any_pynq_board,
  588. self.any_rock_pi_board,
  589. self.any_clockwork_pi_board,
  590. self.any_udoo_board,
  591. self.any_asus_tinker_board,
  592. self.any_stm32mp1,
  593. self.any_lubancat,
  594. self.any_bananapi,
  595. self.any_maaxboard,
  596. self.any_tisk_board,
  597. ]
  598. )
  599. @property
  600. def ftdi_ft232h(self) -> bool:
  601. """Check whether the current board is an FTDI FT232H."""
  602. return self.id == boards.FTDI_FT232H
  603. @property
  604. def ftdi_ft2232h(self) -> bool:
  605. """Check whether the current board is an FTDI FT2232H."""
  606. return self.id == boards.FTDI_FT2232H
  607. @property
  608. def microchip_mcp2221(self) -> bool:
  609. """Check whether the current board is a Microchip MCP2221."""
  610. return self.id == boards.MICROCHIP_MCP2221
  611. @property
  612. def pico_u2if(self) -> bool:
  613. """Check whether the current board is a RPi Pico w/ u2if."""
  614. return self.id == boards.PICO_U2IF
  615. @property
  616. def feather_u2if(self) -> bool:
  617. """Check whether the current board is a Feather RP2040 w/ u2if."""
  618. return self.id == boards.FEATHER_U2IF
  619. @property
  620. def itsybitsy_u2if(self) -> bool:
  621. """Check whether the current board is a Itsy Bitsy w/ u2if."""
  622. return self.id == boards.ITSYBITSY_U2IF
  623. @property
  624. def macropad_u2if(self) -> bool:
  625. """Check whether the current board is a MacroPad w/ u2if."""
  626. return self.id == boards.MACROPAD_U2IF
  627. @property
  628. def qtpy_u2if(self) -> bool:
  629. """Check whether the current board is a QT Py w/ u2if."""
  630. return self.id == boards.QTPY_U2IF
  631. @property
  632. def qt2040_trinkey_u2if(self) -> bool:
  633. """Check whether the current board is a QT Py w/ u2if."""
  634. return self.id == boards.QT2040_TRINKEY_U2IF
  635. @property
  636. def binho_nova(self) -> bool:
  637. """Check whether the current board is an BINHO NOVA."""
  638. return self.id == boards.BINHO_NOVA
  639. @property
  640. def greatfet_one(self) -> bool:
  641. """Check whether the current board is a GreatFET One."""
  642. return self.id == boards.GREATFET_ONE
  643. def __getattr__(self, attr: str) -> bool:
  644. """
  645. Detect whether the given attribute is the currently-detected board. See list
  646. of constants at the top of this module for available options.
  647. """
  648. if self.id == attr:
  649. return True
  650. return False