boards_connected.py 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. """
  2. Discover and manage connected boards
  3. """
  4. import glob
  5. import logging as log
  6. from .... import config
  7. from ... kcgwidget import error
  8. from communication import pci
  9. DUMMY_PCI_i_OUTPUT = 'Vendor: 10ee, Device: 6028, Bus: 3, Slot: 0, Function: 0\n\
  10. Interrupt - Pin: 1, Line: 255\n\
  11. BAR 0 - MEM32, Start: 0xf5500000, Length: 0x 100000, Flags: 0x00040200\n\
  12. \n\
  13. DMA Engines: \n\
  14. DMA 0 C2S - Type: Packet, Address Width: 32 bits\n\
  15. \n\
  16. Banks: \n\
  17. 0x80 dma: DMA Registers\n\
  18. '
  19. class BoardsConnected(object):
  20. """
  21. Container for connected/available boards
  22. This will work as a generator and yield the available board_ids
  23. NOTE: this is subject to change. In the future this may yield board_names or tuples or something else
  24. """
  25. def __init__(self):
  26. self._board_ids = {}
  27. self._board_ids_reverse = {}
  28. self._device_files = {}
  29. self.count = 0
  30. def _device_id(self, dev_file):
  31. """
  32. Get the device id
  33. :param dev_file: the dev_file to use
  34. :return: string for the dev id
  35. """
  36. info_string = pci.info(dev_file=dev_file)
  37. # info_string = DUMMY_PCI_i_OUTPUT
  38. try:
  39. return info_string.split('Device: ')[1].split(',')[0]
  40. except IndexError:
  41. error(0x002, "Pci returned no or wrong information string. Device probably not found.", severe=True)
  42. def discover(self):
  43. """
  44. Discover connected boards
  45. This is either a dummy implementation that defaults to /dev/fpga0 for every board
  46. it will create 'virtual' boards
  47. OR:
  48. If config.use_dev_fpga_for_detection == True use number of /dev/fpga devices and use them
  49. """
  50. def get(dict_, what): # this will return the dict value for what (Key) or what if what not in dict_
  51. return dict_.get(what, what)
  52. if config.board_detection_method == 'dev':
  53. searchstring = '/dev/fpga'
  54. # searchstring = '/dev/lp'
  55. device_list = glob.glob(searchstring+'*')
  56. log.info("Found {num} devices.".format(num=len(device_list)))
  57. self._board_ids = {int(i.replace(searchstring, '')): get(config.device_names, self._device_id(i))
  58. for i in device_list}
  59. self._device_files = {int(i.replace(searchstring, '')): i for i in device_list}
  60. elif config.board_detection_method == 'dummy':
  61. num = 5
  62. self._board_ids = {i: get(config.device_names, 'test'+str(i)) for i in range(num)}
  63. self._device_files = {i: '/dev/fpga0' for i in self.board_ids}
  64. elif config.board_detection_method == 'list':
  65. self._board_ids = {i: get(config.device_names, self._device_id(d_f)) for i, d_f in enumerate(config.device_list)}
  66. self._device_files = {i: d_f for i, d_f in enumerate(config.device_list)}
  67. else:
  68. raise config.MisconfigurationError("board_detection_method was misconfigured")
  69. # if no boards detected create a dummy board (everything will be disabled in the gui) so the gui does
  70. # not crash
  71. if len(self._board_ids) == 0:
  72. self._board_ids[0] = None
  73. self._board_ids_reverse = {v: k for k, v in self._board_ids.items()} # build reverse look up
  74. @property
  75. def has_boards(self):
  76. """
  77. Check if at least one board is connected
  78. """
  79. if len(self.board_ids) == 1 and self._board_ids[0] is None:
  80. return False
  81. elif len(self.board_ids) > 0:
  82. return True
  83. else:
  84. return False
  85. @property
  86. def board_ids(self):
  87. """
  88. Get Board Ids as list
  89. """
  90. return self._board_ids.keys()
  91. @property
  92. def board_names(self):
  93. """
  94. Get Board Names as list
  95. :return:
  96. """
  97. return self._board_ids.values()
  98. def get_board_name_from_id(self, board_id):
  99. """
  100. Get the name of a board with the given board_id
  101. :param board_id: the board to get the name for
  102. :return: the name of the board with id board_id
  103. """
  104. return self._board_ids[board_id]
  105. def get_board_id_from_name(self, board_name):
  106. """
  107. Get the id of a board with the name board_name
  108. :param board_name: the name of the board to get the id for
  109. :return: the id of the board with name board_name
  110. """
  111. return self._board_ids_reverse[board_name]
  112. def get_device_file(self, board_id):
  113. """
  114. Get the device file (/dev/...) to use when communicating with the board
  115. :param board_id: the id of the board
  116. :return: the device file as string
  117. """
  118. return self._device_files[board_id]
  119. @property
  120. def multi_board(self):
  121. """
  122. If multiple boards are connected this is true else false
  123. """
  124. if len(self.board_ids) > 1:
  125. return True
  126. return False
  127. def __iter__(self):
  128. self.__cur_idx = 0
  129. return self
  130. def next(self):
  131. self.__cur_idx += 1
  132. if self.__cur_idx > len(self.board_ids):
  133. raise StopIteration
  134. return self.board_ids[self.__cur_idx-1]
  135. def __getitem__(self, item):
  136. return self.board_ids[item]
  137. available_boards = BoardsConnected()
  138. available_boards.discover()