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.

907 lines
33 KiB

2 years ago
3 years ago
1 year 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
1 year ago
1 year ago
1 year ago
4 years ago
2 years ago
2 years ago
2 years ago
1 year ago
1 year 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
1 year ago
3 years ago
4 years ago
4 years ago
2 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.AM65XX:
  50. board_id = self._siemens_simatic_iot2000_id()
  51. elif chip_id == chips.DRA74X:
  52. board_id = self._bbai_id()
  53. elif chip_id == chips.SUN4I:
  54. board_id = self._armbian_id()
  55. elif chip_id == chips.SUN7I:
  56. board_id = self._armbian_id()
  57. elif chip_id == chips.SUN8I:
  58. board_id = self._armbian_id() or self._allwinner_variants_id()
  59. elif chip_id == chips.SAMA5:
  60. board_id = self._sama5_id()
  61. elif chip_id == chips.IMX8MX:
  62. board_id = self._imx8mx_id()
  63. elif chip_id == chips.IMX6ULL:
  64. board_id = self._imx6ull_id()
  65. elif chip_id == chips.S905Y2:
  66. board_id = boards.RADXA_ZERO
  67. elif chip_id == chips.ESP8266:
  68. board_id = boards.FEATHER_HUZZAH
  69. elif chip_id == chips.SAMD21:
  70. board_id = boards.FEATHER_M0_EXPRESS
  71. elif chip_id == chips.STM32F405:
  72. board_id = boards.PYBOARD
  73. elif chip_id == chips.RP2040:
  74. board_id = boards.RASPBERRY_PI_PICO
  75. elif chip_id == chips.S805:
  76. board_id = boards.ODROID_C1
  77. elif chip_id == chips.RK3568B2:
  78. board_id = boards.ODROID_M1
  79. elif chip_id == chips.S905:
  80. board_id = boards.ODROID_C2
  81. elif chip_id == chips.S905X3:
  82. board_id = self._s905x3_id()
  83. elif chip_id == chips.S922X:
  84. board_id = boards.ODROID_N2
  85. elif chip_id == chips.A311D:
  86. board_id = boards.KHADAS_VIM3
  87. elif chip_id == chips.EXYNOS5422:
  88. board_id = boards.ODROID_XU4
  89. elif chip_id == chips.FT232H:
  90. board_id = boards.FTDI_FT232H
  91. elif chip_id == chips.FT2232H:
  92. board_id = boards.FTDI_FT2232H
  93. elif chip_id == chips.APQ8016:
  94. board_id = boards.DRAGONBOARD_410C
  95. elif chip_id in (chips.T210, chips.T186, chips.T194, chips.T234):
  96. board_id = self._tegra_id()
  97. elif chip_id == chips.HFU540:
  98. board_id = self._sifive_id()
  99. elif chip_id == chips.C906:
  100. board_id = self._allwinner_id()
  101. elif chip_id == chips.JH71x0:
  102. board_id = self._beaglebone_id()
  103. elif chip_id == chips.MCP2221:
  104. board_id = boards.MICROCHIP_MCP2221
  105. elif chip_id == chips.BINHO:
  106. board_id = boards.BINHO_NOVA
  107. elif chip_id == chips.LPC4330:
  108. board_id = boards.GREATFET_ONE
  109. elif chip_id == chips.MIPS24KC:
  110. board_id = boards.ONION_OMEGA
  111. elif chip_id == chips.MIPS24KEC:
  112. board_id = boards.ONION_OMEGA2
  113. elif chip_id == chips.ZYNQ7000:
  114. board_id = self._pynq_id()
  115. elif chip_id == chips.A10:
  116. board_id = self._armbian_id()
  117. elif chip_id == chips.A20:
  118. board_id = self._armbian_id()
  119. elif chip_id == chips.A64:
  120. board_id = self._pine64_id()
  121. elif chip_id == chips.H6:
  122. board_id = self._pine64_id() or self._armbian_id()
  123. elif chip_id == chips.H5:
  124. board_id = self._armbian_id() or self._allwinner_variants_id()
  125. elif chip_id == chips.H616:
  126. board_id = self._armbian_id() or self._allwinner_variants_id()
  127. elif chip_id == chips.A33:
  128. board_id = self._clockwork_pi_id()
  129. elif chip_id == chips.RK3308:
  130. board_id = self._rock_pi_id()
  131. elif chip_id == chips.RK3399:
  132. board_id = self._rock_pi_id() or self._armbian_id()
  133. elif chip_id == chips.RK3399_T:
  134. board_id = self._rock_pi_id() or self._armbian_id()
  135. elif chip_id == chips.ATOM_X5_Z8350:
  136. board_id = self._rock_pi_id()
  137. elif chip_id == chips.ATOM_J4105:
  138. board_id = self._j4105_id()
  139. elif chip_id == chips.RK3288:
  140. board_id = self._asus_tinker_board_id()
  141. elif chip_id == chips.RK3328:
  142. board_id = self._rock_pi_id()
  143. elif chip_id == chips.RK3566:
  144. board_id = self._rk3566_id()
  145. elif chip_id == chips.RK3568:
  146. board_id = self._rk3568_id()
  147. elif chip_id == chips.RK3588:
  148. board_id = self._rock_pi_id() or self._armbian_id()
  149. elif chip_id == chips.RYZEN_V1605B:
  150. board_id = self._udoo_id()
  151. elif chip_id == chips.PENTIUM_N3710:
  152. board_id = self._udoo_id()
  153. elif chip_id == chips.STM32MP157:
  154. board_id = self._stm32mp1_id()
  155. elif chip_id == chips.STM32MP157DAA1:
  156. board_id = self._stm32mp1_id()
  157. elif chip_id == chips.MT8167:
  158. board_id = boards.CORAL_EDGE_TPU_DEV_MINI
  159. elif chip_id == chips.RP2040_U2IF:
  160. board_id = self._rp2040_u2if_id()
  161. elif chip_id == chips.GENERIC_X86:
  162. board_id = boards.GENERIC_LINUX_PC
  163. elif chip_id == chips.TDA4VM:
  164. board_id = self._tisk_id()
  165. elif chip_id == chips.D1_RISCV:
  166. board_id = self._armbian_id()
  167. elif chip_id == chips.S905X:
  168. board_id = boards.AML_S905X_CC
  169. self._board_id = board_id
  170. return board_id
  171. # pylint: enable=invalid-name
  172. def _pi_id(self) -> Optional[str]:
  173. """Try to detect id of a Raspberry Pi."""
  174. # Check for Pi boards:
  175. pi_rev_code = self._pi_rev_code()
  176. if pi_rev_code:
  177. for model, codes in boards._PI_REV_CODES.items():
  178. if pi_rev_code in codes:
  179. return model
  180. # We may be on a non-Raspbian OS, so try to lazily determine
  181. # the version based on `get_device_model`
  182. else:
  183. pi_model = self.detector.get_device_model()
  184. if pi_model:
  185. pi_model = pi_model.upper().replace(" ", "_")
  186. if "PLUS" in pi_model:
  187. re_model = re.search(r"(RASPBERRY_PI_\d).*([AB]_*)(PLUS)", pi_model)
  188. elif "CM" in pi_model: # untested for Compute Module
  189. re_model = re.search(r"(RASPBERRY_PI_CM)(\d)", pi_model)
  190. else: # untested for non-plus models
  191. re_model = re.search(r"(RASPBERRY_PI_\d).*([AB])", pi_model)
  192. if re_model:
  193. pi_model = "".join(re_model.groups())
  194. available_models = boards._PI_REV_CODES.keys()
  195. for model in available_models:
  196. if model == pi_model:
  197. return model
  198. return None
  199. def _pi_rev_code(self) -> Optional[str]:
  200. """Attempt to find a Raspberry Pi revision code for this board."""
  201. # 2708 is Pi 1
  202. # 2709 is Pi 2
  203. # 2835 is Pi 3 (or greater) on 4.9.x kernel
  204. # Anything else is not a Pi.
  205. if self.detector.chip.id != chips.BCM2XXX:
  206. # Something else, not a Pi.
  207. return None
  208. rev = self.detector.get_cpuinfo_field("Revision")
  209. if rev is not None:
  210. return rev
  211. try:
  212. with open("/proc/device-tree/system/linux,revision", "rb") as revision:
  213. rev_bytes = revision.read()
  214. if rev_bytes[:1] == b"\x00":
  215. rev_bytes = rev_bytes[1:]
  216. return rev_bytes.hex()
  217. except FileNotFoundError:
  218. return None
  219. # pylint: disable=no-self-use
  220. def _beaglebone_id(self) -> Optional[str]:
  221. """Try to detect id of a Beaglebone."""
  222. board_value = self.detector.get_device_compatible()
  223. # Older Builds
  224. if "freedom-u74-arty" in board_value:
  225. return boards.BEAGLEV_STARLIGHT
  226. # Newer Builds
  227. if "beaglev-starlight" in board_value:
  228. return boards.BEAGLEV_STARLIGHT
  229. try:
  230. with open("/sys/bus/nvmem/devices/0-00500/nvmem", "rb") as eeprom:
  231. eeprom_bytes = eeprom.read(16)
  232. except FileNotFoundError:
  233. try:
  234. with open("/sys/bus/nvmem/devices/0-00501/nvmem", "rb") as eeprom:
  235. eeprom_bytes = eeprom.read(16)
  236. except FileNotFoundError:
  237. return None
  238. if eeprom_bytes[:4] != b"\xaaU3\xee":
  239. return None
  240. # special condition for BeagleBone Green rev. 1A
  241. # refer to GitHub issue #57 in this repo for more info
  242. if eeprom_bytes == b"\xaaU3\xeeA335BNLT\x1a\x00\x00\x00":
  243. return boards.BEAGLEBONE_GREEN
  244. id_string = eeprom_bytes[4:].decode("ascii")
  245. for model, bb_ids in boards._BEAGLEBONE_BOARD_IDS.items():
  246. for bb_id in bb_ids:
  247. if id_string == bb_id[1]:
  248. return model
  249. board_value = self.detector.get_armbian_release_field("BOARD")
  250. return None
  251. # pylint: enable=no-self-use
  252. def _bbai_id(self) -> Optional[str]:
  253. """Try to detect id of a Beaglebone AI related board."""
  254. board_value = self.detector.get_device_model()
  255. if "BeagleBone AI" in board_value:
  256. return boards.BEAGLEBONE_AI
  257. return None
  258. def _tisk_id(self) -> Optional[str]:
  259. """Try to detect the id of aarch64 board."""
  260. compatible = self.detector.get_device_compatible()
  261. print(compatible)
  262. if not compatible:
  263. return None
  264. compats = compatible.split("\x00")
  265. for board_id, board_compats in boards._TI_SK_BOARD_IDS:
  266. if any(v in compats for v in board_compats):
  267. return board_id
  268. return None
  269. # pylint: disable=too-many-return-statements
  270. def _armbian_id(self) -> Optional[str]:
  271. """Check whether the current board is an OrangePi board."""
  272. board_value = self.detector.get_armbian_release_field("BOARD")
  273. board = None
  274. if board_value == "orangepipc":
  275. board = boards.ORANGE_PI_PC
  276. elif board_value == "orangepi-r1":
  277. board = boards.ORANGE_PI_R1
  278. elif board_value == "orangepizero":
  279. board = boards.ORANGE_PI_ZERO
  280. elif board_value == "orangepione":
  281. board = boards.ORANGE_PI_ONE
  282. elif board_value == "orangepilite":
  283. board = boards.ORANGE_PI_LITE
  284. elif board_value == "orangepiplus2e":
  285. board = boards.ORANGE_PI_PLUS_2E
  286. elif board_value == "orangepipcplus":
  287. board = boards.ORANGE_PI_PC_PLUS
  288. elif board_value == "pinebook-a64":
  289. board = boards.PINEBOOK
  290. elif board_value == "pineH64":
  291. board = boards.PINEH64
  292. elif board_value == "orangepi2":
  293. board = boards.ORANGE_PI_2
  294. elif board_value == "orangepi3":
  295. board = boards.ORANGE_PI_3
  296. elif board_value == "orangepi3-lts":
  297. board = boards.ORANGE_PI_3_LTS
  298. elif board_value == "orangepi4":
  299. board = boards.ORANGE_PI_4
  300. elif board_value == "orangepi4-lts":
  301. board = boards.ORANGE_PI_4_LTS
  302. elif board_value == "orangepi5":
  303. board = boards.ORANGE_PI_5
  304. elif board_value == "bananapim2zero":
  305. board = boards.BANANA_PI_M2_ZERO
  306. elif board_value == "bananapim2plus":
  307. board = boards.BANANA_PI_M2_PLUS
  308. elif board_value == "bananapim5":
  309. board = boards.BANANA_PI_M5
  310. elif board_value == "orangepizeroplus2-h5":
  311. board = boards.ORANGE_PI_ZERO_PLUS_2H5
  312. elif board_value == "orangepizeroplus":
  313. board = boards.ORANGE_PI_ZERO_PLUS
  314. elif board_value == "orangepizero2":
  315. board = boards.ORANGE_PI_ZERO_2
  316. elif board_value == "nanopiair":
  317. board = boards.NANOPI_NEO_AIR
  318. elif board_value == "nanopiduo2":
  319. board = boards.NANOPI_DUO2
  320. elif board_value == "nanopineo":
  321. board = boards.NANOPI_NEO
  322. elif board_value == "nezha":
  323. board = boards.LICHEE_RV
  324. elif board_value == "pcduino2":
  325. board = boards.PCDUINO2
  326. elif board_value == "pcduino3":
  327. board = boards.PCDUINO3
  328. return board
  329. # pylint: enable=too-many-return-statements
  330. # pylint: enable=too-many-return-statements
  331. def _sama5_id(self) -> Optional[str]:
  332. """Check what type sama5 board."""
  333. board_value = self.detector.get_device_model()
  334. if "Giant Board" in board_value:
  335. return boards.GIANT_BOARD
  336. return None
  337. def _s905x3_id(self) -> Optional[str]:
  338. """Check what type S905X3 board."""
  339. board_value = self.detector.get_device_model()
  340. if "Bananapi BPI-M5" in board_value:
  341. return boards.BANANA_PI_M5
  342. return boards.ODROID_C4
  343. def _stm32mp1_id(self) -> Optional[str]:
  344. """Check what type stm32mp1 board."""
  345. board_value = self.detector.get_device_model()
  346. if "STM32MP157C-DK2" in board_value:
  347. return boards.STM32MP157C_DK2
  348. if "LubanCat" in board_value:
  349. return boards.LUBANCAT_STM32MP157
  350. if "OSD32MP1-BRK" in board_value:
  351. return boards.OSD32MP1_BRK
  352. if "OSD32MP1-RED" in board_value:
  353. return boards.OSD32MP1_RED
  354. if "STM32MP1XX OLinuXino" in board_value:
  355. return boards.STMP157_OLINUXINO_LIME2
  356. return None
  357. def _imx8mx_id(self) -> Optional[str]:
  358. """Check what type iMX8M board."""
  359. board_value = self.detector.get_device_model()
  360. if "FSL i.MX8MM DDR4 EVK" in board_value:
  361. return boards.MAAXBOARD_MINI
  362. if "Freescale i.MX8MQ EVK" in board_value:
  363. return boards.MAAXBOARD
  364. if "Phanbell" in board_value:
  365. return boards.CORAL_EDGE_TPU_DEV
  366. return None
  367. def _imx6ull_id(self) -> Optional[str]:
  368. """Check what type iMX6ULL board."""
  369. board_value = self.detector.get_device_model()
  370. if "LubanCat" in board_value or "Embedfire" in board_value:
  371. return boards.LUBANCAT_IMX6ULL
  372. return None
  373. def _tegra_id(self) -> Optional[str]:
  374. """Try to detect the id of aarch64 board."""
  375. compatible = self.detector.get_device_compatible()
  376. if not compatible:
  377. return None
  378. compats = compatible.split("\x00")
  379. for board_id, board_compats in boards._JETSON_IDS:
  380. if any(v in compats for v in board_compats):
  381. return board_id
  382. return None
  383. def _sifive_id(self) -> Optional[str]:
  384. """Try to detect the id for Sifive RISCV64 board."""
  385. board_value = self.detector.get_device_model()
  386. if "hifive-unleashed-a00" in board_value:
  387. return boards.SIFIVE_UNLEASHED
  388. return None
  389. def _allwinner_id(self) -> Optional[str]:
  390. """Try to detect the id for Allwiner D1 board."""
  391. board_value = self.detector.get_device_model()
  392. if "sun20iw1p1" in board_value:
  393. return boards.ALLWINER_D1
  394. return None
  395. def _pine64_id(self) -> Optional[str]:
  396. """Try to detect the id for Pine64 board or device."""
  397. board_value = self.detector.get_device_model()
  398. board = None
  399. if "pine64" in board_value.lower():
  400. board = boards.PINE64
  401. elif "pine h64" in board_value.lower():
  402. board = boards.PINEH64
  403. elif "pinebook" in board_value.lower():
  404. board = boards.PINEBOOK
  405. elif "pinephone" in board_value.lower():
  406. board = boards.PINEPHONE
  407. elif "sopine" in board_value.lower():
  408. board = boards.SOPINE
  409. return board
  410. # pylint: disable=no-self-use
  411. def _pynq_id(self) -> Optional[str]:
  412. """Try to detect the id for Xilinx PYNQ boards."""
  413. try:
  414. with open(
  415. "/proc/device-tree/chosen/pynq_board", "r", encoding="utf-8"
  416. ) as board_file:
  417. board_model = board_file.read()
  418. match = board_model.upper().replace("-", "_").rstrip("\x00")
  419. for model in boards._PYNQ_IDS:
  420. if model == match:
  421. return model
  422. return None
  423. except FileNotFoundError:
  424. return None
  425. def _rk3566_id(self) -> Optional[str]:
  426. """Check what type of rk3566 board."""
  427. board_value = self.detector.get_device_model()
  428. board = None
  429. if board_value and "LubanCat-Zero" in board_value:
  430. board = boards.LUBANCAT_ZERO
  431. if board_value and "LubanCat1" in board_value:
  432. board = boards.LUBANCAT1
  433. if board_value and "Radxa CM3 IO" in board_value:
  434. board = boards.RADXA_CM3
  435. return board
  436. def _rk3568_id(self) -> Optional[str]:
  437. """Check what type of rk3568 board."""
  438. board_value = self.detector.get_device_model()
  439. board = None
  440. if board_value and "LubanCat2" in board_value:
  441. board = boards.LUBANCAT2
  442. return board
  443. def _rock_pi_id(self) -> Optional[str]:
  444. """Check what type of Rock Pi board."""
  445. board_value = self.detector.get_device_model()
  446. board = None
  447. if board_value and "ROCK Pi S" in board_value:
  448. board = boards.ROCK_PI_S
  449. if board_value and "ROCK PI 4" in board_value.upper():
  450. board = boards.ROCK_PI_4
  451. if board_value and "ROCK PI E" in board_value.upper():
  452. board = boards.ROCK_PI_E
  453. if self.detector.check_board_name_value() == "ROCK Pi X":
  454. board = boards.ROCK_PI_X
  455. if board_value and "ROCK 5" in board_value.upper():
  456. board = boards.ROCK_PI_5
  457. if board_value and "RADXA ROCK 4C+" in board_value.upper():
  458. board = boards.ROCK_PI_4_C_PLUS
  459. return board
  460. def _clockwork_pi_id(self) -> Optional[str]:
  461. """Check what type of Clockwork Pi board."""
  462. board_value = self.detector.get_device_model()
  463. board = None
  464. if board_value and "Clockwork CPI3" in board_value:
  465. board = boards.CLOCKWORK_CPI3
  466. return board
  467. def _udoo_id(self) -> Optional[str]:
  468. """Try to detect the id of udoo board."""
  469. board_asset_tag = self.detector.check_board_asset_tag_value()
  470. for board_id, board_tags in boards._UDOO_BOARD_IDS.items():
  471. if any(v == board_asset_tag for v in board_tags):
  472. return board_id
  473. if self.detector.check_board_name_value() == "UDOO x86":
  474. return boards.UDOO_X86
  475. return None
  476. def _j4105_id(self) -> Optional[str]:
  477. """Try to detect the id of J4105 board."""
  478. try:
  479. with open(
  480. "/sys/devices/virtual/dmi/id/board_name", "r", encoding="utf-8"
  481. ) as board_name:
  482. board_value = board_name.read().rstrip()
  483. if board_value in ("ODYSSEY-X86J41X5", "ODYSSEY-X86J41O5"):
  484. return boards.ODYSSEY_X86J41X5
  485. return None
  486. except FileNotFoundError:
  487. return None
  488. def _asus_tinker_board_id(self) -> Optional[str]:
  489. """Check what type of Tinker Board."""
  490. board_value = self.detector.get_device_model()
  491. board = None
  492. if board_value and "ASUS Tinker Board" in board_value:
  493. board = boards._ASUS_TINKER_BOARD_IDS
  494. return board
  495. def _pcduino_board_id(self) -> Optional[str]:
  496. """Check on the type of Pcduino"""
  497. board_value = self.detector.get_device_model()
  498. board = None
  499. if "pcduino2" in board_value.lower():
  500. board = boards.PCDUINO2
  501. if "pcduino3" in board_value.lower():
  502. board = boards.PCDUINO3
  503. return board
  504. def _allwinner_variants_id(self) -> Optional[str]:
  505. """Try to detect the id of allwinner based board. (orangepi, nanopi)"""
  506. board_value = self.detector.get_device_model()
  507. board = None
  508. if not board_value:
  509. return board
  510. board_value = board_value.lower()
  511. chip_id = self.detector.chip.id
  512. if "nanopi" in board_value:
  513. if "neo" in board_value and "SUN8I" in chip_id:
  514. board = boards.NANOPI_NEO_AIR
  515. # TODO: Add other specifc board contexts here
  516. elif "orange pi" in board_value:
  517. if "zero" in board_value:
  518. if "H5" in chip_id:
  519. board = boards.ORANGE_PI_ZERO_PLUS_2H5
  520. elif "H616" in chip_id:
  521. board = boards.ORANGE_PI_ZERO_2
  522. # TODO: Add other specifc board contexts here
  523. return board
  524. def _rp2040_u2if_id(self) -> Optional[str]:
  525. import hid
  526. # look for it based on PID/VID
  527. for dev in hid.enumerate():
  528. # Raspberry Pi Pico
  529. vendor = dev["vendor_id"]
  530. product = dev["product_id"]
  531. if vendor == 0xCAFE and product == 0x4005:
  532. return boards.PICO_U2IF
  533. if vendor == 0x239A:
  534. # Feather RP2040
  535. if product == 0x00F1:
  536. return boards.FEATHER_U2IF
  537. # Itsy Bitsy RP2040
  538. if product == 0x00FD:
  539. return boards.ITSYBITSY_U2IF
  540. # QT Py RP2040
  541. if product == 0x00F7:
  542. return boards.QTPY_U2IF
  543. # QT2040 Trinkey
  544. if product == 0x0109:
  545. return boards.QT2040_TRINKEY_U2IF
  546. # MacroPad RP2040
  547. if product == 0x0107:
  548. return boards.MACROPAD_U2IF
  549. # Will only reach here if a device was added in chip.py but here.
  550. raise RuntimeError("RP2040_U2IF device was added to chip but not board.")
  551. def _siemens_simatic_iot2000_id(self) -> Optional[str]:
  552. """Try to detect if this is a IOT2050 Gateway."""
  553. board_value = self.detector.get_device_model()
  554. board = None
  555. if board_value and "SIMATIC IOT2050 Advanced" in board_value:
  556. board = boards.SIEMENS_SIMATIC_IOT2050_ADV
  557. elif board_value and "SIMATIC IOT2050 Basic" in board_value:
  558. board = boards.SIEMENS_SIMATIC_IOT2050_BASIC
  559. return board
  560. @property
  561. def any_siemens_simatic_iot2000(self) -> bool:
  562. """Check whether the current board is a SIEMENS SIMATIC IOT2000 Gateway."""
  563. return self.id in boards._SIEMENS_SIMATIC_IOT2000_IDS
  564. @property
  565. def any_nanopi(self) -> bool:
  566. """Check whether the current board is any defined Nano Pi."""
  567. return self.id in boards._NANOPI_IDS
  568. @property
  569. def any_96boards(self) -> bool:
  570. """Check whether the current board is any 96boards board."""
  571. return self.id in boards._LINARO_96BOARDS_IDS
  572. @property
  573. def any_raspberry_pi(self) -> bool:
  574. """Check whether the current board is any Raspberry Pi."""
  575. return self._pi_rev_code() is not None
  576. @property
  577. def any_raspberry_pi_40_pin(self) -> bool:
  578. """Check whether the current board is any 40-pin Raspberry Pi."""
  579. return self.id in boards._RASPBERRY_PI_40_PIN_IDS
  580. @property
  581. def any_raspberry_pi_cm(self) -> bool:
  582. """Check whether the current board is any Compute Module Raspberry Pi."""
  583. return self.id in boards._RASPBERRY_PI_CM_IDS
  584. @property
  585. def any_beaglebone(self) -> bool:
  586. """Check whether the current board is any Beaglebone-family system."""
  587. return self.id in boards._BEAGLEBONE_IDS
  588. @property
  589. def any_orange_pi(self) -> bool:
  590. """Check whether the current board is any defined Orange Pi."""
  591. return self.id in boards._ORANGE_PI_IDS
  592. @property
  593. def any_lubancat(self) -> bool:
  594. """Check whether the current board is any defined lubancat."""
  595. return self.id in boards._LUBANCAT_IDS
  596. @property
  597. def any_coral_board(self) -> bool:
  598. """Check whether the current board is any defined Coral."""
  599. return self.id in boards._CORAL_IDS
  600. @property
  601. def any_pynq_board(self) -> bool:
  602. """Check whether the current board is any defined PYNQ Board."""
  603. return self.id in boards._PYNQ_IDS
  604. @property
  605. def any_giant_board(self) -> bool:
  606. """Check whether the current board is any defined Giant Board."""
  607. return self.GIANT_BOARD
  608. @property
  609. def any_odroid_40_pin(self) -> bool:
  610. """Check whether the current board is any defined 40-pin Odroid."""
  611. return self.id in boards._ODROID_40_PIN_IDS
  612. @property
  613. def khadas_vim3_40_pin(self) -> bool:
  614. """Check whether the current board is any defined 40-pin Khadas VIM3."""
  615. return self.id in boards._KHADAS_40_PIN_IDS
  616. @property
  617. def any_jetson_board(self) -> bool:
  618. """Check whether the current board is any defined Jetson Board."""
  619. return self.id in [v[0] for v in boards._JETSON_IDS]
  620. @property
  621. def any_sifive_board(self) -> bool:
  622. """Check whether the current board is any defined Jetson Board."""
  623. return self.id in boards._SIFIVE_IDS
  624. @property
  625. def any_onion_omega_board(self) -> bool:
  626. """Check whether the current board is any defined OpenWRT board."""
  627. return self.id in boards._ONION_OMEGA_BOARD_IDS
  628. @property
  629. def any_pine64_board(self) -> bool:
  630. """Check whether the current board is any Pine64 device."""
  631. return self.id in boards._PINE64_DEV_IDS
  632. @property
  633. def any_rock_pi_board(self) -> bool:
  634. """Check whether the current board is any Rock Pi device."""
  635. return self.id in boards._ROCK_PI_IDS
  636. @property
  637. def any_clockwork_pi_board(self) -> bool:
  638. """Check whether the current board is any Clockwork Pi device."""
  639. return self.CLOCKWORK_CPI3
  640. @property
  641. def any_udoo_board(self) -> bool:
  642. """Check to see if the current board is an UDOO board"""
  643. return self.id in boards._UDOO_BOARD_IDS
  644. @property
  645. def any_seeed_board(self) -> bool:
  646. """Check to see if the current board is an SEEED board"""
  647. return self.id in boards._SEEED_BOARD_IDS
  648. @property
  649. def any_asus_tinker_board(self) -> bool:
  650. """Check to see if the current board is an ASUS Tinker Board"""
  651. return self.id in boards._ASUS_TINKER_BOARD_IDS
  652. @property
  653. def any_pcduino_board(self) -> bool:
  654. """Check whether the current board is any Pcduino board"""
  655. return self.id in boards._PCDUINO_DEV_IDS
  656. @property
  657. def any_stm32mp1(self) -> bool:
  658. """Check whether the current board is any stm32mp1 board."""
  659. return self.id in boards._STM32MP1_IDS
  660. @property
  661. def any_bananapi(self) -> bool:
  662. """Check whether the current board is any BananaPi-family system."""
  663. return self.id in boards._BANANA_PI_IDS
  664. @property
  665. def any_maaxboard(self) -> bool:
  666. """Check whether the current board is any BananaPi-family system."""
  667. return self.id in boards._MAAXBOARD_IDS
  668. @property
  669. def any_tisk_board(self) -> bool:
  670. """Check whether the current board is any defined TI SK Board."""
  671. return self.id in [v[0] for v in boards._TI_SK_BOARD_IDS]
  672. @property
  673. def any_lichee_riscv_board(self) -> bool:
  674. """Check whether the current board is any defined Lichee RISC-V."""
  675. return self.id in boards._LICHEE_RISCV_IDS
  676. @property
  677. def any_libre_computer_board(self) -> bool:
  678. """Check whether the current board is any defined Libre Computer board."""
  679. return self.id in boards._LIBRE_COMPUTER_IDS
  680. @property
  681. def os_environ_board(self) -> bool:
  682. """Check whether the current board is an OS environment variable special case."""
  683. def lazily_generate_conditions():
  684. yield self.board.FTDI_FT232H
  685. yield self.board.FTDI_FT2232H
  686. yield self.board.MICROCHIP_MCP2221
  687. yield self.board.BINHO_NOVA
  688. yield self.board.GREATFET_ONE
  689. yield self.board.PICO_U2IF
  690. yield self.board.FEATHER_U2IF
  691. yield self.board.ITSYBITY_U2IF
  692. yield self.board.MACROPAD_U2IF
  693. yield self.board.QTPY_U2IF
  694. yield self.board.QT2040_TRINKEY_U2IF
  695. return any(condition for condition in lazily_generate_conditions())
  696. @property
  697. def any_embedded_linux(self) -> bool:
  698. """Check whether the current board is any embedded Linux device."""
  699. def lazily_generate_conditions():
  700. yield self.any_raspberry_pi_40_pin
  701. yield self.any_raspberry_pi
  702. yield self.any_beaglebone
  703. yield self.any_orange_pi
  704. yield self.any_nanopi
  705. yield self.any_giant_board
  706. yield self.any_jetson_board
  707. yield self.any_coral_board
  708. yield self.any_odroid_40_pin
  709. yield self.khadas_vim3_40_pin
  710. yield self.any_96boards
  711. yield self.any_sifive_board
  712. yield self.any_onion_omega_board
  713. yield self.any_pine64_board
  714. yield self.any_pynq_board
  715. yield self.any_rock_pi_board
  716. yield self.any_clockwork_pi_board
  717. yield self.any_udoo_board
  718. yield self.any_seeed_board
  719. yield self.any_asus_tinker_board
  720. yield self.any_stm32mp1
  721. yield self.any_lubancat
  722. yield self.any_bananapi
  723. yield self.any_maaxboard
  724. yield self.any_tisk_board
  725. yield self.any_siemens_simatic_iot2000
  726. yield self.any_lichee_riscv_board
  727. yield self.any_pcduino_board
  728. yield self.any_libre_computer_board
  729. yield self.generic_linux
  730. return any(condition for condition in lazily_generate_conditions())
  731. @property
  732. def generic_linux(self) -> bool:
  733. """Check whether the current board is an Generic Linux System."""
  734. return self.id == boards.GENERIC_LINUX_PC
  735. @property
  736. def ftdi_ft232h(self) -> bool:
  737. """Check whether the current board is an FTDI FT232H."""
  738. return self.id == boards.FTDI_FT232H
  739. @property
  740. def ftdi_ft2232h(self) -> bool:
  741. """Check whether the current board is an FTDI FT2232H."""
  742. return self.id == boards.FTDI_FT2232H
  743. @property
  744. def microchip_mcp2221(self) -> bool:
  745. """Check whether the current board is a Microchip MCP2221."""
  746. return self.id == boards.MICROCHIP_MCP2221
  747. @property
  748. def pico_u2if(self) -> bool:
  749. """Check whether the current board is a RPi Pico w/ u2if."""
  750. return self.id == boards.PICO_U2IF
  751. @property
  752. def feather_u2if(self) -> bool:
  753. """Check whether the current board is a Feather RP2040 w/ u2if."""
  754. return self.id == boards.FEATHER_U2IF
  755. @property
  756. def itsybitsy_u2if(self) -> bool:
  757. """Check whether the current board is a Itsy Bitsy w/ u2if."""
  758. return self.id == boards.ITSYBITSY_U2IF
  759. @property
  760. def macropad_u2if(self) -> bool:
  761. """Check whether the current board is a MacroPad w/ u2if."""
  762. return self.id == boards.MACROPAD_U2IF
  763. @property
  764. def qtpy_u2if(self) -> bool:
  765. """Check whether the current board is a QT Py w/ u2if."""
  766. return self.id == boards.QTPY_U2IF
  767. @property
  768. def qt2040_trinkey_u2if(self) -> bool:
  769. """Check whether the current board is a QT Py w/ u2if."""
  770. return self.id == boards.QT2040_TRINKEY_U2IF
  771. @property
  772. def binho_nova(self) -> bool:
  773. """Check whether the current board is an BINHO NOVA."""
  774. return self.id == boards.BINHO_NOVA
  775. @property
  776. def greatfet_one(self) -> bool:
  777. """Check whether the current board is a GreatFET One."""
  778. return self.id == boards.GREATFET_ONE
  779. def __getattr__(self, attr: str) -> bool:
  780. """
  781. Detect whether the given attribute is the currently-detected board. See list
  782. of constants at the top of this module for available options.
  783. """
  784. if self.id == attr:
  785. return True
  786. return False