utils.py 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. """
  2. Helper methods
  3. """
  4. import logging as log
  5. import time
  6. from communication import pci
  7. from errors import *
  8. from status import StatusStorage
  9. from board_config import BoardConfiguration
  10. from .... import config as kcg_config
  11. from boards_connected import available_boards
  12. def get_dec_from_bits(bits, msb=-1, lsb=-1):
  13. """
  14. Get decimal values from a string represented binary string
  15. :param bits: the string to convert
  16. :param msb: the most significant bit to use
  17. :param lsb: the least significant bit to use
  18. :return: the decimal value
  19. """
  20. rtrnValue = 0
  21. if (msb < 0 or lsb < 0):
  22. rtrnValue = int(bits)
  23. elif (msb < lsb) or (msb > 31) or (lsb > 31):
  24. log.info("Bit range for msb and lsb of get_dec_from_bits was wrong. Not truncating")
  25. rtrnValue = int(bits, 2)
  26. else:
  27. chunk = ('{0:032b}'.format(int(bits, 2)))[31-msb:32-lsb]
  28. rtrnValue = int(chunk, 2)
  29. return rtrnValue
  30. def get_status(board_id):
  31. """
  32. Get the satatus of the board (this is used for the status leds)
  33. :param board_id: the id of the board
  34. :return: dictionary with the bits for each led (lower case led names are the keys of this dict)
  35. """
  36. registers = pci.read(board_id, 3, '0x9050', decimal=True)
  37. bits = []
  38. bits += ['{0:032b}'.format(registers[0])]
  39. bits += ['{0:032b}'.format(registers[1])]
  40. bits += ['{0:032b}'.format(registers[2])]
  41. status = {}
  42. s1 = get_dec_from_bits(bits[0], 2, 0)
  43. if s1 == 0:
  44. # Pipeline in reset mode
  45. # self.pipeline_led.set_tri()
  46. status['pipeline'] = 2
  47. elif s1 == 1:
  48. # Pipeline is idle
  49. # self.pipeline_led.set_on()
  50. status['pipeline'] = 3
  51. elif s1 == 6:
  52. # Pipeline in error state
  53. # self.pipeline_led.set_off()
  54. status['pipeline'] = 1
  55. else:
  56. # Should not happen!
  57. # self.pipeline_led.set_out()
  58. status['pipeline'] = 0
  59. s2 = get_dec_from_bits(bits[0], 29, 26)
  60. if s2 == 0:
  61. # Master Control in reset mode
  62. # self.master_control_led.set_tri()
  63. status['master_control'] = 2
  64. elif s2 == 1:
  65. # Master Control is idle
  66. # self.master_control_led.set_on()
  67. status['master_control'] = 3
  68. elif s2 == 8:
  69. # Master Control in error state
  70. # self.master_control_led.set_off()
  71. status['master_control'] = 1
  72. else:
  73. # Should not happen!
  74. # self.master_control_led.set_out()
  75. status['master_control'] = 0
  76. s3 = get_dec_from_bits(bits[2], 15, 12)
  77. if s3 == 15:
  78. # Data Check Idle
  79. # self.data_check_led.set_on()
  80. status['data_check'] = 3
  81. else:
  82. # Data Check Error
  83. # self.data_check_led.set_off()
  84. status['data_check'] = 1
  85. s4 = int(bits[0][7])
  86. if s4 == 0:
  87. # PLL_LD not active
  88. # self.pll_ld_led.set_tri()
  89. status['PLL_LD'] = 2
  90. elif s4 == 1:
  91. # PLL_LD is active
  92. # self.pll_ld_led.set_on()
  93. status['PLL_LD'] = 3
  94. else:
  95. status['PLL_LD'] = 0
  96. return status
  97. def is_conneced(board_id):
  98. """
  99. Is the board connected?
  100. :param board_id: the id for the board to check
  101. :return: True if the board is connected else False
  102. """
  103. try:
  104. pci.read(board_id, 1, '0x9040')
  105. return True
  106. except BoardError:
  107. return False
  108. except InterfaceNotFoundError:
  109. return None
  110. def is_active(board_id):
  111. """
  112. Check if a board is active
  113. :param board_id: the board to check for
  114. :return: True if it is active else False
  115. """
  116. control = pci.read(board_id, 1, '0x9040')[0]
  117. control_bits = '{0:032b}'.format(int(control, 16))
  118. return control_bits[22:26] == "1111"
  119. def wait_for_revolutions(board_id):
  120. """
  121. Sleep as long as the revolutions in the accelerator last to not stop the acquisition before it ended.
  122. :param board_id: the board to wait for?
  123. :return:
  124. """
  125. n = pci.read(board_id, 1, '0x9020', decimal=True)[0] # Get the amount of orbits to observe
  126. # n = 1 # Use this for debugging purposes if no board is connected
  127. spin_time_ns = kcg_config.tRev * n
  128. time.sleep(spin_time_ns * 1.1) # 10% Safety margin
  129. _status = []
  130. _configs = []
  131. def create_new_board_config(identifier):
  132. """
  133. This creates a new instance of BoardConfiguration and also a new instance of StatusStorage
  134. :param identifier: the identifier for this board (not the id)
  135. :return:
  136. """
  137. global _configs
  138. global _status
  139. _configs.append(BoardConfiguration(identifier))
  140. _status.append(StatusStorage())
  141. def get_board_config(id):
  142. """
  143. Get the configuration instance for the board with the given id
  144. :param id: the id of the desired board
  145. :return: the instance of configuration
  146. """
  147. return _configs[id]
  148. def get_board_status(id):
  149. """
  150. Get the status storage instance for the board with the given id
  151. :param id: the id of the desired board
  152. :return: the instance of the status storage
  153. """
  154. return _status[id]