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.

99 lines
3.4 KiB

5 years ago
5 years ago
5 years ago
  1. """Attempt detection of current chip / CPU."""
  2. import sys
  3. import os
  4. AM33XX = "AM33XX"
  5. BCM2XXX = "BCM2XXX"
  6. ESP8266 = "ESP8266"
  7. SAMD21 = "SAMD21"
  8. STM32 = "STM32"
  9. SUN8I = "SUN8I"
  10. S805 = "S805"
  11. S905 = "S905"
  12. GENERIC_X86 = "GENERIC_X86"
  13. FT232H = "FT232H"
  14. class Chip:
  15. """Attempt detection of current chip / CPU."""
  16. def __init__(self, detector):
  17. self.detector = detector
  18. @property
  19. def id(self): # pylint: disable=invalid-name,too-many-branches,too-many-return-statements
  20. """Return a unique id for the detected chip, if any."""
  21. # There are some times we want to trick the platform detection
  22. # say if a raspberry pi doesn't have the right ID, or for testing
  23. try:
  24. return os.environ['BLINKA_FORCECHIP']
  25. except KeyError: # no forced chip, continue with testing!
  26. pass
  27. # Special case, if we have an environment var set, we could use FT232H
  28. try:
  29. if os.environ['BLINKA_FT232H']:
  30. # we can't have ftdi1 as a dependency cause its wierd
  31. # to install, sigh.
  32. import ftdi1 as ftdi # pylint: disable=import-error
  33. try:
  34. ctx = None
  35. ctx = ftdi.new() # Create a libftdi context.
  36. # Enumerate FTDI devices.
  37. count, _ = ftdi.usb_find_all(ctx, 0, 0)
  38. if count < 0:
  39. raise RuntimeError('ftdi_usb_find_all returned error %d : %s' %
  40. count, ftdi.get_error_string(self._ctx))
  41. if count == 0:
  42. raise RuntimeError('BLINKA_FT232H environment variable' + \
  43. 'set, but no FT232H device found')
  44. finally:
  45. # Make sure to clean up list and context when done.
  46. if ctx is not None:
  47. ftdi.free(ctx)
  48. return FT232H
  49. except KeyError: # no FT232H environment var
  50. pass
  51. platform = sys.platform
  52. if platform == "linux":
  53. return self._linux_id()
  54. if platform == "esp8266":
  55. return ESP8266
  56. if platform == "samd21":
  57. return SAMD21
  58. if platform == "pyboard":
  59. return STM32
  60. # nothing found!
  61. return None
  62. # pylint: enable=invalid-name
  63. def _linux_id(self):
  64. """Attempt to detect the CPU on a computer running the Linux kernel."""
  65. linux_id = None
  66. hardware = self.detector.get_cpuinfo_field("Hardware")
  67. if hardware is None:
  68. vendor_id = self.detector.get_cpuinfo_field("vendor_id")
  69. if vendor_id in ("GenuineIntel", "AuthenticAMD"):
  70. linux_id = GENERIC_X86
  71. elif hardware in ("BCM2708", "BCM2709", "BCM2835"):
  72. linux_id = BCM2XXX
  73. elif "AM33XX" in hardware:
  74. linux_id = AM33XX
  75. elif "sun8i" in hardware:
  76. linux_id = SUN8I
  77. elif "ODROIDC" in hardware:
  78. linux_id = S805
  79. elif "ODROID-C2" in hardware:
  80. linux_id = S905
  81. return linux_id
  82. def __getattr__(self, attr):
  83. """
  84. Detect whether the given attribute is the currently-detected chip. See
  85. list of constants at the top of this module for available options.
  86. """
  87. if self.id == attr:
  88. return True
  89. return False