def read_node_slot_index(self): # read node slot index (physical slot position of node on S32_BPill PCB) try: data = self.read_block(None, READ_NODE_SLOTIDX, 1, 1) self.multi_node_slot_index = unpack_8(data) if data else -1 except Exception: self.multi_node_slot_index = -1
def check_set_multi_node_index(self, interface): # check if need to set different node index on multi-node processor and set if needed if self.multi_node_index == self.multi_curnode_index_holder[0]: return True success = False chk_retry_count = 0 out_value = None while success is False: if self.write_block(interface, WRITE_CURNODE_INDEX, pack_8(self.multi_node_index), False): data = self.read_block(interface, READ_CURNODE_INDEX, 1, 0, False) out_value = unpack_8(data) if data != None else None if out_value == self.multi_node_index: success = True else: chk_retry_count = chk_retry_count + 1 self.inc_read_error_count(interface) if chk_retry_count <= MAX_RETRY_COUNT * 5: self.node_log(interface, 'Error setting WRITE_CURNODE_INDEX, old={0}, new={1}, idx={2}, retry={3}'.\ format(self.multi_curnode_index_holder[0], self.multi_node_index, self.index, chk_retry_count)) gevent.sleep(0.025) else: self.node_log(interface, 'Error setting WRITE_CURNODE_INDEX, retry limit reached, old={0}, new={1}, idx={2}, retry={3}'.\ format(self.multi_curnode_index_holder[0], self.multi_node_index, self.index, chk_retry_count)) break if success: self.multi_curnode_index_holder[0] = self.multi_node_index return success
def discover(idxOffset, config, isS32BPillFlag=False, *args, **kwargs): nodes = [] config_ser_ports = getattr(config, 'SERIAL_PORTS', []) if isS32BPillFlag and len(config_ser_ports) == 0: config_ser_ports.append(DEF_S32BPILL_SERIAL_PORT) logger.debug( "Using default serial port ('{}') for S32_BPill board".format( DEF_S32BPILL_SERIAL_PORT)) if config_ser_ports: for index, comm in enumerate(config_ser_ports): rev_val = None baud_idx = 0 while rev_val == None and baud_idx < len(SERIAL_BAUD_RATES): node_serial_obj = serial.Serial( port=None, baudrate=SERIAL_BAUD_RATES[baud_idx], timeout=0.25) node_serial_obj.setDTR( 0) # clear in case line is tied to node-processor reset node_serial_obj.setRTS(0) node_serial_obj.setPort(comm) node_serial_obj.open( ) # open port (now that DTR is configured for no change) if baud_idx > 0: gevent.sleep( BOOTLOADER_CHILL_TIME) # delay needed for Arduino USB node = SerialNode(index + idxOffset, node_serial_obj) multi_count = 1 try: # handle serial multi-node processor # read NODE_API_LEVEL and verification value: data = node.read_block(None, READ_REVISION_CODE, 2, 2, False) rev_val = unpack_16(data) if data != None else None if rev_val and (rev_val >> 8) == 0x25: if (rev_val & 0xFF) >= 32: # check node API level data = node.read_block(None, READ_MULTINODE_COUNT, 1, 2, False) multi_count = unpack_8( data) if data != None else None if multi_count is None or multi_count < 0 or multi_count > 32: logger.error( 'Bad READ_MULTINODE_COUNT value fetched from serial node: ' + str(multi_count)) multi_count = 1 elif multi_count == 0: logger.debug( 'Fetched READ_MULTINODE_COUNT value of zero from serial node (no modules detected)' ) multi_count = 0 except Exception: multi_count = 1 logger.exception( 'Error fetching READ_MULTINODE_COUNT for serial node') if rev_val == None: node_serial_obj.close() baud_idx += 1 if rev_val: api_level = rev_val & 0xFF node.api_level = api_level node_version_str = None node_timestamp_str = None fver_log_str = '' ftyp_log_str = '' ftim_log_str = '' if api_level >= 34: # read firmware version and build timestamp strings node.read_firmware_version() if node.firmware_version_str: node_version_str = node.firmware_version_str fver_log_str = ", fw_version=" + node.firmware_version_str if node.api_level >= 35: node.read_firmware_proctype() if node.firmware_proctype_str: ftyp_log_str = ", fw_type=" + node.firmware_proctype_str node.read_firmware_timestamp() if node.firmware_timestamp_str: node_timestamp_str = node.firmware_timestamp_str ftim_log_str = ", fw_timestamp: " + node.firmware_timestamp_str if multi_count <= 1: if multi_count > 0: logger.info("Serial node {} found at port '{}', API_level={}, baudrate={}{}{}{}".format(\ index+idxOffset+1, node.serial.name, api_level, node.serial.baudrate, \ fver_log_str, ftyp_log_str, ftim_log_str)) nodes.append(node) else: if 'set_info_node_obj_fn' in kwargs: kwargs['set_info_node_obj_fn']( node) # set 'info_node_obj' in RHInterface logger.info("Serial node (with zero modules) found at port '{}', API_level={}, baudrate={}{}{}{}".format(\ node.serial.name, api_level, node.serial.baudrate, \ fver_log_str, ftyp_log_str, ftim_log_str)) else: logger.info("Serial multi-node found at port '{}', count={}, API_level={}, baudrate={}{}{}{}".\ format(node.serial.name, multi_count, api_level, node.serial.baudrate, \ fver_log_str, ftyp_log_str, ftim_log_str)) node.multi_node_index = 0 curnode_index_holder = [ -1 ] # tracker for index of current node for processor node.multi_curnode_index_holder = curnode_index_holder node.read_node_slot_index() logger.debug("Serial (multi) node {} (slot={}) added for port '{}'".format(\ index+idxOffset+1, node.multi_node_slot_index+1, node.serial.name)) nodes.append(node) slots_str = str(node.multi_node_slot_index + 1) for nIdx in range(1, multi_count): idxOffset += 1 node = SerialNode(index + idxOffset, node_serial_obj) node.multi_node_index = nIdx node.multi_curnode_index_holder = curnode_index_holder node.api_level = api_level node.firmware_version_str = node_version_str node.firmware_timestamp_str = node_timestamp_str node.read_node_slot_index() logger.debug("Serial (multi) node {} (slot={}) added for port '{}'".format(\ index+idxOffset+1, node.multi_node_slot_index+1, node.serial.name)) nodes.append(node) slots_str += ' ' + str(node.multi_node_slot_index + 1) logger.info("Receiver modules found at slot positions: " + slots_str) else: logger.error( 'Unable to fetch revision code for serial node at "{0}"'. format(comm)) return nodes