Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 5e7c0710b9 | |||
| 5131535bda | |||
| ac5a6ef77a |
@@ -1950,18 +1950,22 @@ class CC2650SingleMasterCentralDevice(CC2650MasterDevice, Synchronized):
|
||||
@synchronized
|
||||
def reset_software(self):
|
||||
"""software reset cc2650 (master)"""
|
||||
# print('resettt---------14')
|
||||
# print()
|
||||
# self.log_verbose('reset (software)')
|
||||
|
||||
self.log_verbose('reset (software)')
|
||||
# try:
|
||||
# #self._cc2650.send("3B", 1, 0, 0)
|
||||
# pass
|
||||
|
||||
try:
|
||||
#self._cc2650.send("3B", 1, 0, 0)
|
||||
pass
|
||||
# except SerialTimeoutException as e:
|
||||
# raise RecvTimeout('device CC2650 reset fail') from e
|
||||
|
||||
except SerialTimeoutException as e:
|
||||
raise RecvTimeout('device CC2650 reset fail') from e
|
||||
|
||||
finally:
|
||||
sleep(0.1)
|
||||
# finally:
|
||||
# sleep(0.1)
|
||||
print("pass")
|
||||
print()
|
||||
|
||||
|
||||
@synchronized
|
||||
def init_hardware(self, timeout=1):
|
||||
@@ -1975,6 +1979,7 @@ class CC2650SingleMasterCentralDevice(CC2650MasterDevice, Synchronized):
|
||||
# send scan command
|
||||
try:
|
||||
print(':: scan_send_ins ::', self.CC2650_COMMAND_LEN, 3, 0, 0)
|
||||
print()
|
||||
self._cc2650.send(self.CC2650_COMMAND_LEN, 3, 0, 0)
|
||||
|
||||
except SerialTimeoutException as e:
|
||||
@@ -2010,7 +2015,7 @@ class CC2650SingleMasterCentralDevice(CC2650MasterDevice, Synchronized):
|
||||
scan_ins.append(1) #length
|
||||
scan_ins.append(0xF1)
|
||||
|
||||
# print('send_scan', bytes(scan_ins))
|
||||
print('send_scan', list(scan_ins))
|
||||
self._cc2650.send("bytes", bytes(scan_ins))
|
||||
|
||||
# for wait_scan_response in range(5):
|
||||
@@ -2170,6 +2175,7 @@ class CC2650SingleMasterCentralDevice(CC2650MasterDevice, Synchronized):
|
||||
|
||||
# send device mac and addrType
|
||||
try:
|
||||
print('send_connect..',list(connect_ins))
|
||||
self._cc2650.send("bytes", bytes(connect_ins))
|
||||
|
||||
except SerialTimeoutException as e:
|
||||
@@ -2202,39 +2208,26 @@ class CC2650SingleMasterCentralDevice(CC2650MasterDevice, Synchronized):
|
||||
|
||||
# send device mac and addrType
|
||||
try:
|
||||
# print('send_connect',bytes(connect_ins))
|
||||
print('send_connect',list(connect_ins))
|
||||
self._cc2650.send("bytes", bytes(connect_ins))
|
||||
|
||||
except SerialTimeoutException as e:
|
||||
raise RecvTimeout('device CC2650 connect fail') from e
|
||||
|
||||
else:
|
||||
sleep(2)
|
||||
|
||||
# connection establish done?
|
||||
for retry_recv_ack in range(5):
|
||||
self._cc2650.send("bytes", bytes((0, 0, 0, 0)))
|
||||
|
||||
sleep(1)
|
||||
try:
|
||||
con_done = self._cc2650.recv_uart(timeout = 0.1)
|
||||
|
||||
except RecvTimeout:
|
||||
self.log_info("recv connection timeout, retry... ")
|
||||
continue
|
||||
self.log_info("recv connection timeout, fail... ")
|
||||
|
||||
# is the ack valid?
|
||||
if con_done is None:
|
||||
continue
|
||||
|
||||
elif con_done[0] is 46 and \
|
||||
if con_done[0] is 46 and \
|
||||
con_done[1] is 80 and \
|
||||
con_done[2] is 48 and \
|
||||
con_done[3] is 4:
|
||||
connected = True
|
||||
# print('con_done=', con_done)
|
||||
break
|
||||
else:
|
||||
continue
|
||||
print('con_done=', con_done)
|
||||
|
||||
# if select device is invalid or connect failed
|
||||
self._interface.flush_input()
|
||||
@@ -2255,6 +2248,36 @@ class CC2650SingleMasterCentralDevice(CC2650MasterDevice, Synchronized):
|
||||
|
||||
return ret
|
||||
|
||||
def check_mem_survive(self) -> Optional[CC2650Device]:
|
||||
|
||||
ack = []
|
||||
ins = bytearray()
|
||||
ins.append(10)
|
||||
ins.append(1) #length
|
||||
ins.append(0xF1)
|
||||
|
||||
try:
|
||||
self._cc2650.send("bytes", bytes(ins))
|
||||
|
||||
except SerialTimeoutException as e:
|
||||
raise RecvTimeout('device CC2650 check_mem_survive timeout') from e
|
||||
|
||||
else:
|
||||
# sleep(1)
|
||||
try:
|
||||
ack = self._cc2650.recv_uart(timeout = 0.1)
|
||||
|
||||
except RecvTimeout:
|
||||
self.log_info("no survive device")
|
||||
|
||||
else:
|
||||
print('ack=', ack)
|
||||
|
||||
if ack == [3]:
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
@synchronized
|
||||
def disconnect(self, device: int, force=False) -> bool:
|
||||
self.log_info(DEVICE_DISCONNECTING, device)
|
||||
@@ -2265,7 +2288,7 @@ class CC2650SingleMasterCentralDevice(CC2650MasterDevice, Synchronized):
|
||||
ins.append(0xF1)
|
||||
|
||||
try:
|
||||
# print('send_disconnect',bytes(ins))
|
||||
print('send_disconnect',list(ins))
|
||||
self._cc2650.send("bytes", bytes(ins))
|
||||
|
||||
except RecvTimeout:
|
||||
@@ -2300,28 +2323,20 @@ class CC2650SingleMasterCentralDevice(CC2650MasterDevice, Synchronized):
|
||||
ins.append(handle)
|
||||
ins.append(0xF1)
|
||||
|
||||
for _ in range(2):
|
||||
try:
|
||||
# print('send_read',bytes(ins))
|
||||
self._cc2650.send("bytes", bytes(ins))
|
||||
except SerialTimeoutException:
|
||||
raise RecvTimeout('device CC2650 send read_characteristic fail')
|
||||
try:
|
||||
print('read_characteristic',list(ins))
|
||||
self._cc2650.send("bytes", bytes(ins))
|
||||
|
||||
except SerialTimeoutException:
|
||||
raise RecvTimeout('device CC2650 send read_characteristic fail')
|
||||
|
||||
try:
|
||||
ret = self._cc2650.recv_uart(timeout = 2)
|
||||
except Exception as e2:
|
||||
raise RecvTimeout()
|
||||
else:
|
||||
# print("======== read ret = ", ret)
|
||||
self._interface.flush_input()
|
||||
|
||||
# try:
|
||||
# ret = self._cc2650.recv_uart(timeout = 1)
|
||||
# except Exception as e2:
|
||||
# raise RecvTimeout()
|
||||
# else:
|
||||
# # print("read_characteristic ret = ", ret)
|
||||
# pass
|
||||
try:
|
||||
ret = self._cc2650.recv_uart(timeout = 2)
|
||||
except Exception as e2:
|
||||
raise RecvTimeout()
|
||||
else:
|
||||
# print("======== read ret = ", ret)
|
||||
self._interface.flush_input()
|
||||
|
||||
if ret is None:
|
||||
return None
|
||||
@@ -2349,23 +2364,21 @@ class CC2650SingleMasterCentralDevice(CC2650MasterDevice, Synchronized):
|
||||
|
||||
|
||||
try:
|
||||
self._cc2650.send("bytes", bytes(data_array))
|
||||
# print('send_write',bytes(data_array))
|
||||
self._cc2650.send("bytes", list(data_array))
|
||||
print('send_write',list(data_array))
|
||||
|
||||
except SerialTimeoutException as e:
|
||||
raise RecvTimeout('device CC2650 send instruction fail') from e
|
||||
|
||||
# read error code
|
||||
try:
|
||||
ret = self._cc2650.recv_uart()
|
||||
ret = self._cc2650.recv_uart(timeout = 0.1)
|
||||
print('ret=', ret)
|
||||
|
||||
# print("_______ write ack = ", ret)
|
||||
except Exception as e2:
|
||||
pass
|
||||
|
||||
else:
|
||||
pass
|
||||
|
||||
self._interface.flush_input()
|
||||
self._interface.flush_output()
|
||||
|
||||
@@ -2542,24 +2555,78 @@ class CC2650MultiMasterCentralDevice(CC2650MasterDevice, Synchronized):
|
||||
else:
|
||||
self.log_warn('cannot %s notify for device : %s' % (message, device.__class__.__name__))
|
||||
|
||||
# def reset(self, device: Optional[List[int]] = None, software_reset=True):
|
||||
# print('resettt---------15')
|
||||
# print()
|
||||
|
||||
# # self.log_verbose('reset')
|
||||
|
||||
# # reset hardware
|
||||
# # print("reset device = ", device)
|
||||
# print('device:', device, software_reset)
|
||||
# print('self._device', list(self._device))
|
||||
# print('self._cc2650_once:', list(self._cc2650))
|
||||
# print('|')
|
||||
# print('|')
|
||||
# for i in range(len(self._cc2650)):
|
||||
# print('i', i)
|
||||
# if device is None or i in device:
|
||||
# self._device[i] = None
|
||||
|
||||
# m = self._cc2650[i]
|
||||
|
||||
# if m is None:
|
||||
# m = CC2650SingleMasterCentralDevice(self._master, self._interface, self._options)
|
||||
|
||||
# self._interface.flush()
|
||||
# self._selector.select(i)
|
||||
|
||||
# try:
|
||||
# self.log_info('reset device', i)
|
||||
|
||||
# with m:
|
||||
# m.reset_internal()
|
||||
# m.reset_hardware()
|
||||
|
||||
# if software_reset:
|
||||
# check_mem_survive_flag = m.check_mem_survive()
|
||||
# if check_mem_survive_flag:
|
||||
# self._cc2650[i] = m
|
||||
|
||||
# except RecvTimeout:
|
||||
# self.log_warn('reset device', i, 'fail')
|
||||
# self._cc2650[i] = None
|
||||
|
||||
# print('self._cc2650::', list(self._cc2650))
|
||||
|
||||
# return
|
||||
|
||||
def reset(self, device: Optional[List[int]] = None, software_reset=True):
|
||||
print('resettt---------15')
|
||||
print()
|
||||
|
||||
# self.log_verbose('reset')
|
||||
|
||||
# reset hardware
|
||||
# print("reset device = ", device)
|
||||
print('device:', device, software_reset)
|
||||
print('self._device', list(self._device))
|
||||
print('self._cc2650_once:', list(self._cc2650))
|
||||
print('|')
|
||||
print('|')
|
||||
|
||||
for i in range(len(self._cc2650)):
|
||||
if device is None or i in device:
|
||||
if device is None:
|
||||
self._device[i] = None
|
||||
|
||||
m = self._cc2650[i]
|
||||
|
||||
if m is None:
|
||||
m = CC2650SingleMasterCentralDevice(self._master, self._interface, self._options)
|
||||
# m.set_log_level(self._cc2650_log_level)
|
||||
|
||||
self._interface.flush()
|
||||
self._selector.select(i)
|
||||
# self._mem_selector.select(i)
|
||||
|
||||
|
||||
try:
|
||||
self.log_info('reset device', i)
|
||||
@@ -2567,51 +2634,20 @@ class CC2650MultiMasterCentralDevice(CC2650MasterDevice, Synchronized):
|
||||
with m:
|
||||
m.reset_internal()
|
||||
m.reset_hardware()
|
||||
|
||||
if software_reset:
|
||||
m.reset_software()
|
||||
self._cc2650[i] = m
|
||||
|
||||
|
||||
if not software_reset:
|
||||
check_mem_survive_flag = m.check_mem_survive()
|
||||
if check_mem_survive_flag:
|
||||
self._cc2650[i] = m
|
||||
|
||||
except RecvTimeout:
|
||||
self.log_warn('reset device', i, 'fail')
|
||||
self._cc2650[i] = None
|
||||
|
||||
if not software_reset:
|
||||
return
|
||||
print('self._cc2650::', list(self._cc2650))
|
||||
|
||||
# check reset result
|
||||
available_device_id = list(map(lambda it: it[0],
|
||||
filter(lambda it: it[1] is not None,
|
||||
enumerate(self._cc2650))))
|
||||
|
||||
if len(available_device_id) == 0:
|
||||
raise RuntimeError("reset fail, no device found")
|
||||
|
||||
self.log_verbose('available device', ' '.join(map(str, available_device_id)))
|
||||
|
||||
# initial hardware
|
||||
for i in range(len(self._cc2650)):
|
||||
m = self._cc2650[i]
|
||||
|
||||
if m is not None:
|
||||
self._interface.flush()
|
||||
self._selector.select(i)
|
||||
# self._mem_selector.select(i)
|
||||
|
||||
try:
|
||||
self.log_info('init device', i)
|
||||
|
||||
except RecvTimeout:
|
||||
self.log_warn('init device', i, 'fail')
|
||||
self._cc2650[i] = None
|
||||
|
||||
# check init result, again
|
||||
available_device_id = list(map(lambda it: it[0],
|
||||
filter(lambda it: it[1] is not None,
|
||||
enumerate(self._cc2650))))
|
||||
|
||||
if len(available_device_id) == 0:
|
||||
raise RuntimeError("init fail, no device success")
|
||||
return
|
||||
|
||||
def reset_empty_master(self, device: Optional[List[int]] = None, software_reset=True):
|
||||
self.log_verbose('reset')
|
||||
|
||||
@@ -261,7 +261,8 @@ class DeviceManager(MasterDevice, Synchronized):
|
||||
|
||||
__slots__ = ('_handler', '_options',
|
||||
'_library_path', '_library',
|
||||
'_interface', '_master', '_found_history', '_found', '_device', '_master_log_level')
|
||||
'_interface', '_master', '_found_history', '_found', '_device', '_master_log_level',
|
||||
'_mem_survive_channel')
|
||||
|
||||
def __init__(self,
|
||||
options: DeviceManagerOptions,
|
||||
@@ -381,8 +382,13 @@ class DeviceManager(MasterDevice, Synchronized):
|
||||
"""reset master device"""
|
||||
self._device.clear()
|
||||
self._demo.clear()
|
||||
print('resettt---------21')
|
||||
print()
|
||||
self._centralMaster.reset(device, software_reset)
|
||||
|
||||
def get_mem_survive_channel(self):
|
||||
return self._mem_survive_channel
|
||||
|
||||
def available_device(self) -> List[int]:
|
||||
return self._centralMaster.available_device()
|
||||
|
||||
|
||||
@@ -890,11 +890,11 @@ class I4V4Z4T4DataDecoder(RecDataDecoder):
|
||||
finish_mode_falg = data[19]
|
||||
|
||||
# print('decode', list(data[20:]))
|
||||
mem_wrong = data[20]
|
||||
mem_retry_cnt = data[21]
|
||||
mem_green_wrong = data[22]
|
||||
mem_green_retry_cnt = data[23]
|
||||
ram_num = data[24]
|
||||
mem_wrong = data[120]
|
||||
mem_retry_cnt = data[121]
|
||||
mem_green_wrong = data[122]
|
||||
mem_green_retry_cnt = data[123]
|
||||
ram_num = data[124]
|
||||
broken_flag = data[-1]
|
||||
|
||||
if (finish_mode_falg & 0b11110000 == 0b10100000):
|
||||
|
||||
+58
-294
@@ -25,25 +25,26 @@ _SLEEP_TIME_ = 0.001
|
||||
def zero_buffer(size: int) -> List[int]:
|
||||
return [0] * size
|
||||
|
||||
|
||||
class ExtMemSpiInterface(LowLevelHardwareInterface):
|
||||
class MultiExtMemSpiInterface(LowLevelHardwareInterface):
|
||||
MEM_INS_MARKED = [MEM_INS_WRITE, 0, 2, 1, 1]
|
||||
MEM_INS_RESET = [MEM_INS_WRITE, 0, 2, 1, 1, 0, 0xFF]
|
||||
|
||||
__slots__ = ('_spi', '_tx_buffer', '_tx_buffer_header', '_tx_buffer_data',
|
||||
__slots__ = ('_selector', '_wait_for_first_data', '_spi', '_tx_buffer', '_tx_buffer_header', '_tx_buffer_data',
|
||||
'pin_busy', 'pin_request', 'pin_reset', 'pin_sel',
|
||||
'_pin_sel_val',
|
||||
'_read_green_times','_read_red_times',
|
||||
'_elite_data_len', '_mem_header_len', '_mem_tailer_len', '_single_data_len',
|
||||
'_head_wrong_cnt')
|
||||
|
||||
def __init__(self, device: Tuple[int, int] = None):
|
||||
super().__init__()
|
||||
def __init__(self,
|
||||
select: Selector,
|
||||
device: Tuple[int, int] = None):
|
||||
|
||||
self._spi = HardwareImplSpiInterface(device,
|
||||
spi_speed=12_000_000 # XXX temp parameter
|
||||
)
|
||||
|
||||
self._elite_data_len = 20
|
||||
self._elite_data_len = 120
|
||||
self._mem_header_len = 3
|
||||
self._mem_tailer_len = 8
|
||||
self._single_data_len = self._elite_data_len + self._mem_header_len + self._mem_tailer_len
|
||||
@@ -59,46 +60,70 @@ class ExtMemSpiInterface(LowLevelHardwareInterface):
|
||||
self.pin_reset = OutputPin.get_used(P3Pin.MEM_RST, True)
|
||||
self.pin_sel: Optional[InputPin] = InputPin.get_used(P3Pin.MEM_SEL)
|
||||
|
||||
self._pin_sel_val = False
|
||||
|
||||
self._read_green_times = 0
|
||||
self._read_red_times = 0
|
||||
|
||||
self._head_wrong_cnt = [0, 0, 0, 0, 0, 0, 0, 0]
|
||||
|
||||
|
||||
self._selector = select
|
||||
|
||||
self._pin_sel_val = [False for _ in range(Selector.SIZE)]
|
||||
self._wait_for_first_data = [True for _ in range(Selector.SIZE)]
|
||||
|
||||
@property
|
||||
def select(self) -> int:
|
||||
return self._selector.channel
|
||||
|
||||
@select.setter
|
||||
def select(self, value: int):
|
||||
self._selector.select(value)
|
||||
|
||||
def changed(self, flip=False) -> bool:
|
||||
channel = self._selector.channel
|
||||
old = self._pin_sel_val[channel]
|
||||
value = bool(self.pin_sel)
|
||||
|
||||
if flip:
|
||||
self._pin_sel_val[channel] = value
|
||||
|
||||
return value != old
|
||||
|
||||
def reset(self):
|
||||
self._spi.reset()
|
||||
|
||||
def close(self):
|
||||
self._selector.close()
|
||||
self._spi.close()
|
||||
|
||||
def flush(self):
|
||||
self.pin_reset.output(False)
|
||||
self.pin_reset.output(True)
|
||||
|
||||
@property
|
||||
def select(self) -> int:
|
||||
return 0
|
||||
|
||||
@select.setter
|
||||
def select(self, value: int):
|
||||
pass
|
||||
|
||||
def changed(self, flip=False) -> bool:
|
||||
old = self._pin_sel_val
|
||||
value = self.pin_sel.input()
|
||||
|
||||
if flip:
|
||||
self._pin_sel_val = value
|
||||
|
||||
return value != old
|
||||
|
||||
def send_byte(self, data: bytes):
|
||||
raise RuntimeError()
|
||||
|
||||
def recv_byte(self, size: int) -> Optional[bytes]:
|
||||
raise RuntimeError()
|
||||
|
||||
# def flush_all(self):
|
||||
# for _ in self._selector.foreach():
|
||||
# self.pin_reset.output(False)
|
||||
# self.pin_reset.output(True)
|
||||
|
||||
def foreach(self) -> Iterable[int]:
|
||||
for channel in self._selector.foreach():
|
||||
yield channel
|
||||
|
||||
def set_wait_flag(self, spi_idx:int = None, value:bool = None):
|
||||
self._wait_for_first_data[spi_idx] = value
|
||||
|
||||
def get_wait_flag(self, spi_idx:int = None) -> Optional[bool]:
|
||||
if spi_idx < Selector.SIZE:
|
||||
return self._wait_for_first_data[spi_idx]
|
||||
else:
|
||||
return None
|
||||
|
||||
def request_data(self):
|
||||
self.pin_request.output(False)
|
||||
sleep(0.001)
|
||||
@@ -162,7 +187,6 @@ class ExtMemSpiInterface(LowLevelHardwareInterface):
|
||||
address = 0
|
||||
|
||||
# first read to get data length
|
||||
tx = self._tx_buffer
|
||||
tx_h = self._tx_buffer_header
|
||||
|
||||
tx_h[0] = MEM_INS_READ
|
||||
@@ -356,90 +380,23 @@ class ExtMemSpiInterface(LowLevelHardwareInterface):
|
||||
|
||||
self._spi.send_byte(tx)
|
||||
|
||||
def flush_all(self):
|
||||
self.flush()
|
||||
|
||||
def foreach(self) -> Iterable[int]:
|
||||
yield 0
|
||||
|
||||
|
||||
class MultiExtMemSpiInterface(ExtMemSpiInterface):
|
||||
__slots__ = ('_selector', '_wait_for_first_data')
|
||||
|
||||
def __init__(self,
|
||||
select: Selector,
|
||||
device: Tuple[int, int] = None):
|
||||
super().__init__(device)
|
||||
|
||||
self._selector = select
|
||||
|
||||
self._pin_sel_val = [False for _ in range(Selector.SIZE)]
|
||||
self._wait_for_first_data = [True for _ in range(Selector.SIZE)]
|
||||
|
||||
@property
|
||||
def select(self) -> int:
|
||||
return self._selector.channel
|
||||
|
||||
@select.setter
|
||||
def select(self, value: int):
|
||||
self._selector.select(value)
|
||||
|
||||
def changed(self, flip=False) -> bool:
|
||||
channel = self._selector.channel
|
||||
old = self._pin_sel_val[channel]
|
||||
value = bool(self.pin_sel)
|
||||
|
||||
if flip:
|
||||
self._pin_sel_val[channel] = value
|
||||
|
||||
return value != old
|
||||
|
||||
def reset(self):
|
||||
self._spi.reset()
|
||||
|
||||
def close(self):
|
||||
self._selector.close()
|
||||
super().close()
|
||||
|
||||
def flush_all(self):
|
||||
for _ in self._selector.foreach():
|
||||
self.pin_reset.output(False)
|
||||
self.pin_reset.output(True)
|
||||
|
||||
def foreach(self) -> Iterable[int]:
|
||||
for channel in self._selector.foreach():
|
||||
yield channel
|
||||
|
||||
def set_wait_flag(self, spi_idx:int = None, value:bool = None):
|
||||
self._wait_for_first_data[spi_idx] = value
|
||||
|
||||
def get_wait_flag(self, spi_idx:int = None) -> Optional[bool]:
|
||||
if spi_idx < Selector.SIZE:
|
||||
return self._wait_for_first_data[spi_idx]
|
||||
else:
|
||||
return None
|
||||
|
||||
|
||||
class ExtMemManager:
|
||||
def __init__(self, ext_mem: ExtMemSpiInterface):
|
||||
def __init__(self, ext_mem: MultiExtMemSpiInterface):
|
||||
self._mem_sel = InputPin.get_used(P3Pin.MEM_SEL, pull_up_down=True)
|
||||
self._mem_req = OutputPin.get_used(P3Pin.MEM_REQ, initial=True)
|
||||
|
||||
self._ext_mem = ext_mem
|
||||
|
||||
@property
|
||||
def mem_sel(self) -> int:
|
||||
return int(self._mem_sel)
|
||||
|
||||
@property
|
||||
def mem_req(self) -> int:
|
||||
return int(self._mem_req)
|
||||
print('ExtMemManager.....')
|
||||
print()
|
||||
|
||||
def mem_request(self):
|
||||
self._mem_req.pulse()
|
||||
sleep(_SLEEP_TIME_)
|
||||
|
||||
def get_ext_mem_register(self) -> List[Tuple[Optional[int], Optional[int]]]:
|
||||
print('get_ext_mem_register......')
|
||||
print()
|
||||
ret = [(None, None) for _ in range(Selector.SIZE)]
|
||||
|
||||
for channel in self._ext_mem.foreach():
|
||||
@@ -483,37 +440,13 @@ class ExtMemManager:
|
||||
|
||||
return 0
|
||||
|
||||
def get_no_device_channel(self, result: List[Tuple[Optional[int], Optional[int]]] = None) -> List[int]:
|
||||
if result is None:
|
||||
result = self.get_ext_mem_register()
|
||||
|
||||
ret = []
|
||||
|
||||
for channel, result in enumerate(result):
|
||||
if self.is_no_device(result):
|
||||
ret.append(channel)
|
||||
|
||||
return ret
|
||||
|
||||
def get_memory_test_fail(self, result: List[Tuple[Optional[int], Optional[int]]] = None) -> List[int]:
|
||||
if result is None:
|
||||
result = self.get_ext_mem_register()
|
||||
|
||||
ret = []
|
||||
|
||||
for channel, result in enumerate(result):
|
||||
if self.is_no_device(result):
|
||||
continue
|
||||
|
||||
if self.is_memory_test_fail(result) != 0:
|
||||
ret.append(channel)
|
||||
|
||||
return ret
|
||||
|
||||
def get_available_channel(self, result: List[Tuple[Optional[int], Optional[int]]] = None) -> List[int]:
|
||||
print('get_available_channel......')
|
||||
print()
|
||||
if result is None:
|
||||
result = self.get_ext_mem_register()
|
||||
|
||||
|
||||
ret = []
|
||||
|
||||
for channel, result in enumerate(result):
|
||||
@@ -527,172 +460,3 @@ class ExtMemManager:
|
||||
|
||||
return ret
|
||||
|
||||
def test_available_channel(self, result: List[Tuple[Optional[int], Optional[int]]] = None) -> List[int]:
|
||||
if result is None:
|
||||
result = self.get_ext_mem_register()
|
||||
|
||||
available_channel = []
|
||||
|
||||
for channel, result in enumerate(result):
|
||||
r1, r2 = result
|
||||
|
||||
if self.is_no_device(result):
|
||||
print('channel', channel, 'no device')
|
||||
continue
|
||||
|
||||
test_pass = True
|
||||
|
||||
if r1 is None or r2 is None:
|
||||
test_pass = False
|
||||
print('channel', channel, 'mem_sel', 'x', 'not change')
|
||||
|
||||
if r1 is not None and r1 > 0 and r1 != DEFAULT_REGISTER_VALUE:
|
||||
test_pass = False
|
||||
print('channel', channel, 'mem_sel', 0, 'register', r1)
|
||||
|
||||
if r2 is not None and r2 > 0 and r2 != DEFAULT_REGISTER_VALUE:
|
||||
test_pass = False
|
||||
print('channel', channel, 'mem_sel', 1, 'register', r2)
|
||||
|
||||
if test_pass:
|
||||
print('channel', channel, 'mem_sel', 0, 'register', r1)
|
||||
print('channel', channel, 'mem_sel', 1, 'register', r2)
|
||||
available_channel.append(channel)
|
||||
|
||||
return available_channel
|
||||
|
||||
def test_memory_read_write(self, channel: int, print_result=False) -> bool:
|
||||
self._ext_mem.select = channel
|
||||
|
||||
addr = 4
|
||||
size = 100
|
||||
test_pass = True
|
||||
|
||||
while addr < MEM_SIZE:
|
||||
d1 = [randint(10, 99) for _ in range(size)]
|
||||
d2 = [randint(10, 99) for _ in range(size)]
|
||||
|
||||
self.mem_request()
|
||||
m1 = int(self._mem_sel)
|
||||
self._ext_mem.write_memory(addr, d1)
|
||||
|
||||
self.mem_request()
|
||||
m2 = int(self._mem_sel)
|
||||
self._ext_mem.write_memory(addr, d2)
|
||||
|
||||
self.mem_request()
|
||||
m11 = int(self._mem_sel)
|
||||
r1 = self._ext_mem.read_memory(addr, size)
|
||||
|
||||
if m1 != m11:
|
||||
test_pass = False
|
||||
if print_result:
|
||||
print('channel', channel, 'mem_sel not change')
|
||||
|
||||
if d1 != r1:
|
||||
test_pass = False
|
||||
if print_result:
|
||||
self.print_bytes_diff(d1, r1)
|
||||
|
||||
self.mem_request()
|
||||
m22 = int(self._mem_sel)
|
||||
r2 = self._ext_mem.read_memory(addr, size)
|
||||
|
||||
if m2 != m22:
|
||||
test_pass = False
|
||||
if print_result:
|
||||
print('channel', channel, 'mem_sel not change')
|
||||
|
||||
if d2 != r2:
|
||||
test_pass = False
|
||||
if print_result:
|
||||
self.print_bytes_diff(d2, r2)
|
||||
|
||||
addr += size
|
||||
|
||||
return test_pass
|
||||
|
||||
@staticmethod
|
||||
def print_bytes_diff(_1: List[int], _2: List[int]):
|
||||
s1 = ''
|
||||
s2 = ''
|
||||
|
||||
l1 = len(_1)
|
||||
l2 = len(_2)
|
||||
|
||||
for i in range(min(l1, l2)):
|
||||
v1 = _1[i]
|
||||
v2 = _2[i]
|
||||
|
||||
if v1 == v2:
|
||||
s1 += '%02X ' % v1
|
||||
s2 += '%02X ' % v2
|
||||
else:
|
||||
s1 += '%02X ' % v1
|
||||
s2 += pc('%02X' % v2, RED) + ' '
|
||||
|
||||
if l1 == l2:
|
||||
pass
|
||||
|
||||
elif l1 < l2:
|
||||
for i in range(l1, l2):
|
||||
s2 += pc('%02X' % _2[i], GREEN) + ' '
|
||||
else:
|
||||
for i in range(l2, l1):
|
||||
s1 += pc('%02X' % _1[i], RED) + ' '
|
||||
|
||||
print(s1)
|
||||
print(s2)
|
||||
|
||||
|
||||
def hardware_test():
|
||||
ext_mem = MultiExtMemSpiInterface(Selector.get(Selector.MEM_SELECTOR))
|
||||
|
||||
fake_mode = False
|
||||
|
||||
try:
|
||||
ext_mem.reset()
|
||||
except FileNotFoundError:
|
||||
fake_mode = True
|
||||
|
||||
ret = {
|
||||
'channel_count': Selector.SIZE,
|
||||
'memory_size': MEM_SIZE,
|
||||
'pin_mem_req': P3Pin.MEM_REQ,
|
||||
'pin_mem_sel': P3Pin.MEM_SEL,
|
||||
}
|
||||
|
||||
if not fake_mode:
|
||||
tester = ExtMemManager(ext_mem)
|
||||
|
||||
result = tester.get_ext_mem_register()
|
||||
no_device = tester.get_no_device_channel(result)
|
||||
reg_fail = tester.get_memory_test_fail(result)
|
||||
available = tester.get_available_channel(result)
|
||||
|
||||
channel = ['unknown' for _ in range(Selector.SIZE)]
|
||||
|
||||
for ch in range(len(channel)):
|
||||
if ch in no_device:
|
||||
channel[ch] = 'no_device'
|
||||
|
||||
elif ch in reg_fail:
|
||||
channel[ch] = 'reg_fail'
|
||||
|
||||
elif not tester.test_memory_read_write(ch):
|
||||
channel[ch] = 'mem_fail'
|
||||
|
||||
else:
|
||||
channel[ch] = 'available'
|
||||
|
||||
ret['register'] = result
|
||||
ret['available'] = available
|
||||
ret['channel'] = channel
|
||||
|
||||
return ret
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
from pprint import pprint
|
||||
|
||||
pprint(hardware_test())
|
||||
|
||||
+17
-6
@@ -280,11 +280,14 @@ class Main(CliMain):
|
||||
@cli_command('controller')
|
||||
def _controller_server(self, command: str, argv: List[str]):
|
||||
"""controller server"""
|
||||
print(self, command, argv)
|
||||
print('##_controller_server')
|
||||
return _ControlServer
|
||||
|
||||
@cli_command('data')
|
||||
def _data_server(self, command: str, argv: List[str]):
|
||||
"""data server"""
|
||||
print('##_data_server')
|
||||
return _DataServer
|
||||
|
||||
@cli_command('export')
|
||||
@@ -302,6 +305,7 @@ class Main(CliMain):
|
||||
return LEDControlMain(command)
|
||||
|
||||
def run(self):
|
||||
print('RUN!!!!!!!!!!!!!!!!!!!')
|
||||
self.print_help()
|
||||
|
||||
|
||||
@@ -335,15 +339,16 @@ class _ServerMain(CliSubCommandMain, metaclass=abc.ABCMeta):
|
||||
def run(self):
|
||||
exit_code = 1
|
||||
|
||||
server = self.create_server()
|
||||
print('create_server')
|
||||
|
||||
if _RUNTIME_COMPILE:
|
||||
exit_code = server.main()
|
||||
else:
|
||||
with self.profiling_options.generate_profile_context():
|
||||
exit_code = server.main()
|
||||
server = self.create_server()
|
||||
exit_code = server.main()
|
||||
print('....after create_server')
|
||||
print('.. ..')
|
||||
print()
|
||||
|
||||
sys.exit(exit_code)
|
||||
|
||||
|
||||
|
||||
# noinspection PyUnusedLocal
|
||||
@@ -355,6 +360,7 @@ class _ControlServer(_ServerMain):
|
||||
from biopro.device.manager import DeviceManagerOptions
|
||||
from biopro.server.data import DataServerOptions
|
||||
from biopro.exp_pro.manager import ExpManagerOption
|
||||
print('command', command)
|
||||
|
||||
super().__init__(command)
|
||||
|
||||
@@ -456,6 +462,8 @@ class _ControlServer(_ServerMain):
|
||||
def create_server(self) -> SocketServer:
|
||||
from biopro.server.main import ControlServer
|
||||
|
||||
print('..create_server')
|
||||
|
||||
return ControlServer(self.server_device_options,
|
||||
self.server_data_options,
|
||||
self.server_controller_options,
|
||||
@@ -477,8 +485,11 @@ class _DataServer(_ServerMain):
|
||||
def create_server(self) -> SocketServer:
|
||||
from biopro.server.data import DataServer
|
||||
|
||||
print('.1.create_server')
|
||||
|
||||
return DataServer(self.server_data_options)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
print('START!!!!!!!!!!!!!!!!!!!!!!!!')
|
||||
Main().main()
|
||||
|
||||
@@ -10,7 +10,7 @@ import base64
|
||||
from biopro.data import *
|
||||
from biopro.devlib.data import *
|
||||
from biopro.generator import GeneratorOptions
|
||||
from biopro.impl.ext_mem import ExtMemSpiInterface, MultiExtMemSpiInterface, ExtMemManager
|
||||
from biopro.impl.ext_mem import MultiExtMemSpiInterface, ExtMemManager
|
||||
from biopro.impl.selector import Selector
|
||||
from biopro.recording import RecordingMetaFile, RecordingFileWriter
|
||||
from biopro.util.address import EMPTY_ADDRESS, address_str
|
||||
@@ -132,7 +132,7 @@ class DataServer(SocketServer, DataAPI):
|
||||
|
||||
if self._spi is not None:
|
||||
self.log_verbose('spi flush')
|
||||
self._spi.flush_all()
|
||||
# self._spi.flush_all()
|
||||
|
||||
self.reset_available_channel()
|
||||
|
||||
@@ -199,6 +199,8 @@ class DataServer(SocketServer, DataAPI):
|
||||
|
||||
self.setup_spi(spi_mode)
|
||||
|
||||
print('self.setup()')
|
||||
print()
|
||||
# restart
|
||||
self.setup()
|
||||
|
||||
@@ -224,9 +226,9 @@ class DataServer(SocketServer, DataAPI):
|
||||
return
|
||||
elif spi_mode == self.MODE_DISABLE:
|
||||
spi = None
|
||||
elif spi_mode == self.MODE_SINGLE:
|
||||
spi = ExtMemSpiInterface()
|
||||
elif spi_mode == self.MODE_SELECTOR:
|
||||
print('~~~~~')
|
||||
print()
|
||||
spi = MultiExtMemSpiInterface(Selector.get(Selector.MEM_SELECTOR))
|
||||
else:
|
||||
raise ValueError('illegal spi mode : ' + spi_mode)
|
||||
@@ -304,6 +306,8 @@ class DataServer(SocketServer, DataAPI):
|
||||
return self._spi_mode
|
||||
|
||||
def available_channel(self, reset=False) -> List[int]:
|
||||
print('!!!!!!!!!!!!!!')
|
||||
print()
|
||||
if reset:
|
||||
self.reset_available_channel()
|
||||
|
||||
|
||||
@@ -84,7 +84,9 @@ class ControlServer(SocketServer, ControlServerAPI, CacheAPI, CacheNotifyHandler
|
||||
# data server
|
||||
data_options = DataServerOptions.get_options(*options)
|
||||
data_options.repository = device_option.repository
|
||||
print('self.data_server')
|
||||
self.data_server = DataServerProcess(data_options)
|
||||
print('self.data_server')
|
||||
|
||||
# experimental protocol
|
||||
# exp_options = ExpManagerOption.get_options(*options)
|
||||
@@ -198,6 +200,8 @@ class ControlServer(SocketServer, ControlServerAPI, CacheAPI, CacheNotifyHandler
|
||||
def setup(self) -> None:
|
||||
"""setup the control server
|
||||
"""
|
||||
print('ControlServer: setup')
|
||||
print()
|
||||
# print allow host
|
||||
from biopro.util.inet import allow_host
|
||||
|
||||
@@ -217,6 +221,7 @@ class ControlServer(SocketServer, ControlServerAPI, CacheAPI, CacheNotifyHandler
|
||||
self.run_thread(_RandomCrashThread())
|
||||
|
||||
# data server
|
||||
print('start_process')
|
||||
interface = self.device_manager.interface
|
||||
options = self.data_server.options
|
||||
if interface == DeviceHardwareInterface.INTERFACE_DUMMY:
|
||||
@@ -227,6 +232,7 @@ class ControlServer(SocketServer, ControlServerAPI, CacheAPI, CacheNotifyHandler
|
||||
options.storage_root = str(self.file_manager.storage_root)
|
||||
|
||||
self.data_server.start_process()
|
||||
print('start_process___')
|
||||
|
||||
# file manager
|
||||
self.log_verbose('setup file manager')
|
||||
@@ -236,7 +242,9 @@ class ControlServer(SocketServer, ControlServerAPI, CacheAPI, CacheNotifyHandler
|
||||
|
||||
# device manager
|
||||
self.log_verbose('setup device manager')
|
||||
print('self.device_manager.setup()')
|
||||
self.device_manager.setup()
|
||||
print('self.device_manager.setup()____')
|
||||
self.submit_thread(self._setup_library)
|
||||
|
||||
# device manager reset
|
||||
@@ -269,6 +277,9 @@ class ControlServer(SocketServer, ControlServerAPI, CacheAPI, CacheNotifyHandler
|
||||
self.mqtt_thread.start()
|
||||
# self.run_thread(self.mqtt_thread)
|
||||
|
||||
print('ControlServer: setup______end')
|
||||
print()
|
||||
|
||||
def _setup_file_manager(self):
|
||||
self.log_verbose('setup file manager')
|
||||
|
||||
@@ -312,7 +323,8 @@ class ControlServer(SocketServer, ControlServerAPI, CacheAPI, CacheNotifyHandler
|
||||
|
||||
def _setup_device(self):
|
||||
# wait data server
|
||||
|
||||
print('resettt---------30')
|
||||
print()
|
||||
self.log_verbose('device hardware reset')
|
||||
self.device_manager.reset(software_reset=False)
|
||||
|
||||
@@ -362,6 +374,8 @@ class ControlServer(SocketServer, ControlServerAPI, CacheAPI, CacheNotifyHandler
|
||||
while retry < 10:
|
||||
try:
|
||||
with client:
|
||||
print('resettt---------31')
|
||||
print()
|
||||
client.reset()
|
||||
break
|
||||
except RuntimeError:
|
||||
@@ -403,6 +417,8 @@ class ControlServer(SocketServer, ControlServerAPI, CacheAPI, CacheNotifyHandler
|
||||
def _setup_device_manager(self, available_channel: List[int]):
|
||||
# device reset
|
||||
# only reset those device has channel available
|
||||
print('resettt---------33')
|
||||
print()
|
||||
self.log_verbose('reset device')
|
||||
self.device_manager.reset(available_channel)
|
||||
|
||||
|
||||
@@ -121,6 +121,7 @@ class ControllerProcess(LoggerFlag, Generic[PO, PC], metaclass=abc.ABCMeta):
|
||||
cmd = current_command_header()
|
||||
|
||||
cmd.extend(arg)
|
||||
print('cmd', cmd, env)
|
||||
|
||||
self.__process = process = Popen(cmd, env=env)
|
||||
self.log_info('process PID :', process.pid)
|
||||
|
||||
@@ -465,7 +465,7 @@ class RecordingProcess(Process):
|
||||
"""
|
||||
raw_data = []
|
||||
index = 0
|
||||
elite_data_len = 20
|
||||
elite_data_len = 120
|
||||
mem_header_len = 3
|
||||
mem_tailer_len = 8
|
||||
single_data_len = elite_data_len + mem_header_len + mem_tailer_len
|
||||
|
||||
@@ -621,16 +621,20 @@ class CliMain(AbstractCliMain, metaclass=abc.ABCMeta):
|
||||
self.__cli_help_document[handle] = _resolve_doc(handle.help_doc)
|
||||
|
||||
def main(self, argv: List[str] = None):
|
||||
print('main', argv)
|
||||
if argv is None:
|
||||
print('Main None', sys.argv[1:])
|
||||
argv = sys.argv[1:]
|
||||
|
||||
try:
|
||||
argv = self.parsing(argv)
|
||||
print('1', argv)
|
||||
|
||||
if argv is None:
|
||||
self.run()
|
||||
else:
|
||||
command, *argv = argv
|
||||
print('2', command, argv)
|
||||
|
||||
self.invoke_subcommand(command, argv)
|
||||
|
||||
@@ -654,6 +658,7 @@ class CliMain(AbstractCliMain, metaclass=abc.ABCMeta):
|
||||
|
||||
while i < len(argv):
|
||||
arg = argv[i]
|
||||
print('arg', i, arg)
|
||||
|
||||
if not left_all and arg.startswith('-'):
|
||||
|
||||
@@ -676,6 +681,7 @@ class CliMain(AbstractCliMain, metaclass=abc.ABCMeta):
|
||||
|
||||
else:
|
||||
# sub command
|
||||
print('self._cli_commands', self._cli_commands)
|
||||
if parsing_sub_command and j == 0:
|
||||
if arg in self._cli_commands:
|
||||
return argv[i:]
|
||||
@@ -711,7 +717,7 @@ class CliMain(AbstractCliMain, metaclass=abc.ABCMeta):
|
||||
# handle not found
|
||||
return False
|
||||
|
||||
# print('_handle_flags_', arg)
|
||||
print('_handle_flags_', arg)
|
||||
handle.invoke(arg)
|
||||
|
||||
if handle.force_return:
|
||||
@@ -728,6 +734,7 @@ class CliMain(AbstractCliMain, metaclass=abc.ABCMeta):
|
||||
:return: number of arguments consumed, 0 if fail.
|
||||
"""
|
||||
arg, value = part_suffix(arg, '=')
|
||||
print('_handle_options_', arg, value)
|
||||
|
||||
handle = self._cli_options.get(arg, None)
|
||||
|
||||
@@ -761,6 +768,7 @@ class CliMain(AbstractCliMain, metaclass=abc.ABCMeta):
|
||||
:return: None if fail, true if left all.
|
||||
"""
|
||||
a = self._cli_arguments
|
||||
print('cli_argument', arg, pos, a)
|
||||
handle = a.get(pos, None)
|
||||
|
||||
if handle is None and pos == 0:
|
||||
@@ -817,10 +825,11 @@ class CliMain(AbstractCliMain, metaclass=abc.ABCMeta):
|
||||
:return:
|
||||
"""
|
||||
handle = self._cli_commands.get(command, None)
|
||||
print('handle', handle)
|
||||
|
||||
if handle is None:
|
||||
raise RuntimeError('sub-command not found : ' + command)
|
||||
|
||||
|
||||
return handle.invoke(command, argv)
|
||||
|
||||
def print_help(self, print_usage=True, file: Optional[IO] = None) -> None:
|
||||
|
||||
@@ -529,6 +529,7 @@ class CliHandleCommand(CliHandle):
|
||||
"""
|
||||
try:
|
||||
main = self.handle(self._target, command, argv)
|
||||
print('3', main, self._target, command, argv)
|
||||
|
||||
except (MainForceReturn, SystemExit, KeyboardInterrupt):
|
||||
raise
|
||||
@@ -546,6 +547,7 @@ class CliHandleCommand(CliHandle):
|
||||
elif isinstance(main, type):
|
||||
# initialize CliSubCommandMain
|
||||
main = main(command)
|
||||
print('4', main)
|
||||
|
||||
if not isinstance(main, AbstractCliMain):
|
||||
raise RuntimeError('not a CliSubCommandMain : ' + type(main).__class__)
|
||||
|
||||
@@ -64,8 +64,10 @@ class ProfileOptions(CliOptions):
|
||||
self.profiling_sorting = fields
|
||||
|
||||
def generate_profile_context(self) -> 'ProfileContext':
|
||||
print('self.profiling_method:', self.profiling_method)
|
||||
if self.profiling_method is None:
|
||||
ret = _NullProfileContext(self)
|
||||
print('ret=', ret)
|
||||
|
||||
else:
|
||||
try:
|
||||
|
||||
Reference in New Issue
Block a user