Compare commits
29 Commits
dev/eis
...
rel/v1.3.0
| Author | SHA1 | Date | |
|---|---|---|---|
| 31b6a60046 | |||
| 12e0ec7c69 | |||
| 7087ded6d4 | |||
| cdb4ddfe04 | |||
| 8d68d15023 | |||
| 3ebf283c89 | |||
| a70d20c4b8 | |||
| 8be3e1fa0e | |||
| e33b4d9a21 | |||
| a38fe5066f | |||
| b6abf0885a | |||
| a3c0f1e4a3 | |||
| 6446204013 | |||
| 3b60d74c47 | |||
| d1c4b0a29f | |||
| 0034681e55 | |||
| 6b3649c8a0 | |||
| 3f1ba0971c | |||
| 95d27aa6f2 | |||
| 651e34d6e0 | |||
| d3621e0c9c | |||
| 0d1b1f4825 | |||
| ec0fe2ec9f | |||
| 67b645dac6 | |||
| a3d794d9a1 | |||
| 197a3a6f05 | |||
| b9dc607ac0 | |||
| ae2f8e7e70 | |||
| a13dde3055 |
@@ -0,0 +1,7 @@
|
|||||||
|
.DS_Store
|
||||||
|
*.cpython-37.opt-2.pyc
|
||||||
|
*.pyc
|
||||||
|
*/__pycache__
|
||||||
|
/.vscode
|
||||||
|
/media
|
||||||
|
python/biopro/sever/_identify.py
|
||||||
@@ -315,14 +315,6 @@ class CC2650MasterDevice(MasterDevice, metaclass=abc.ABCMeta):
|
|||||||
|
|
||||||
return cls.CC2650_RESET_PIN
|
return cls.CC2650_RESET_PIN
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def get_uart_irq_pin(cls) -> OutputPin:
|
|
||||||
if cls.CC2650_UART_IRQ is None:
|
|
||||||
cls.CC2650_UART_IRQ = OutputPin.get_used(P3Pin.MEM_RST, initial=True)
|
|
||||||
|
|
||||||
return cls.CC2650_UART_IRQ
|
|
||||||
|
|
||||||
|
|
||||||
class CC2650Device(Device):
|
class CC2650Device(Device):
|
||||||
|
|
||||||
def __init__(self,
|
def __init__(self,
|
||||||
@@ -955,9 +947,6 @@ class CC2650SingleMasterDevice(CC2650MasterDevice, Synchronized):
|
|||||||
|
|
||||||
self._cc2650.recv_util(..., when=self._cond, timeout=timeout)
|
self._cc2650.recv_util(..., when=self._cond, timeout=timeout)
|
||||||
|
|
||||||
def available_device(self) -> List[int]:
|
|
||||||
return [0]
|
|
||||||
|
|
||||||
@synchronized
|
@synchronized
|
||||||
def scan_callback(self, callback: Callable[[DeviceResponseInfo], None], timeout=5, all_device=False) -> bool:
|
def scan_callback(self, callback: Callable[[DeviceResponseInfo], None], timeout=5, all_device=False) -> bool:
|
||||||
if self._scan_max_time != timeout:
|
if self._scan_max_time != timeout:
|
||||||
@@ -1442,11 +1431,6 @@ class CC2650MultiMasterDevice(CC2650MasterDevice, Synchronized):
|
|||||||
super().shutdown()
|
super().shutdown()
|
||||||
self._selector.close()
|
self._selector.close()
|
||||||
|
|
||||||
def available_device(self) -> List[int]:
|
|
||||||
return list(map(lambda it: it[0],
|
|
||||||
filter(lambda it: it[1] is not None,
|
|
||||||
enumerate(self._cc2650))))
|
|
||||||
|
|
||||||
def get_device(self, device: int) -> Optional[Device]:
|
def get_device(self, device: int) -> Optional[Device]:
|
||||||
return self._device[device]
|
return self._device[device]
|
||||||
|
|
||||||
@@ -1942,10 +1926,8 @@ class CC2650SingleMasterCentralDevice(CC2650MasterDevice, Synchronized):
|
|||||||
self.log_verbose('reset (hardware)')
|
self.log_verbose('reset (hardware)')
|
||||||
|
|
||||||
pin.output(False)
|
pin.output(False)
|
||||||
sleep(0.1)
|
# sleep(0.001)
|
||||||
|
|
||||||
pin.output(True)
|
pin.output(True)
|
||||||
sleep(0.1)
|
|
||||||
|
|
||||||
@synchronized
|
@synchronized
|
||||||
def reset_software(self):
|
def reset_software(self):
|
||||||
@@ -1968,9 +1950,6 @@ class CC2650SingleMasterCentralDevice(CC2650MasterDevice, Synchronized):
|
|||||||
"""initialize cc2650 (master)"""
|
"""initialize cc2650 (master)"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def available_device(self) -> List[int]:
|
|
||||||
return [0]
|
|
||||||
|
|
||||||
def scan_send_ins(self):
|
def scan_send_ins(self):
|
||||||
# send scan command
|
# send scan command
|
||||||
try:
|
try:
|
||||||
@@ -1986,21 +1965,16 @@ class CC2650SingleMasterCentralDevice(CC2650MasterDevice, Synchronized):
|
|||||||
clean_buf = self._cc2650.receive_timeout("20B", timeout=3)
|
clean_buf = self._cc2650.receive_timeout("20B", timeout=3)
|
||||||
print("clean_buf = ", clean_buf)
|
print("clean_buf = ", clean_buf)
|
||||||
|
|
||||||
def cc2650_uart_irq(self):
|
# def cc2650_uart_irq(self):
|
||||||
uart_irq = self.get_uart_irq_pin()
|
# uart_irq = self.get_uart_irq_pin()
|
||||||
uart_irq.output(False)
|
# uart_irq.output(False)
|
||||||
sleep(0.001)
|
# sleep(0.001)
|
||||||
uart_irq.output(True)
|
# uart_irq.output(True)
|
||||||
|
|
||||||
@synchronized
|
@synchronized
|
||||||
def scan_callback(self, callback: Callable[[DeviceResponseInfo], None], timeout=5, all_device=False) -> bool:
|
def scan_callback(self, callback: Callable[[DeviceResponseInfo], None], timeout=5, all_device=False) -> bool:
|
||||||
# if self._scan_max_time != timeout:
|
|
||||||
# self.log_info('set max scan limit time', timeout)
|
|
||||||
# self._scan_max_time = timeout
|
|
||||||
|
|
||||||
self._found = found = []
|
self._found = found = []
|
||||||
self._found_with_id = []
|
self._found_with_id = []
|
||||||
number_of_device = 0
|
|
||||||
hdr_BPHS = [66, 80, 72, 83]
|
hdr_BPHS = [66, 80, 72, 83]
|
||||||
scan_response: Union[Optional[tuple], Any] = None
|
scan_response: Union[Optional[tuple], Any] = None
|
||||||
|
|
||||||
@@ -2013,39 +1987,13 @@ class CC2650SingleMasterCentralDevice(CC2650MasterDevice, Synchronized):
|
|||||||
# print('send_scan', bytes(scan_ins))
|
# print('send_scan', bytes(scan_ins))
|
||||||
self._cc2650.send("bytes", bytes(scan_ins))
|
self._cc2650.send("bytes", bytes(scan_ins))
|
||||||
|
|
||||||
# for wait_scan_response in range(5):
|
|
||||||
# try:
|
|
||||||
# scan_response = self._cc2650.recv_uart(0.2)
|
|
||||||
# except RecvTimeout:
|
|
||||||
# if wait_scan_response == 4:
|
|
||||||
# self.reset_internal()
|
|
||||||
# self.reset_hardware()
|
|
||||||
# self._interface.flush()
|
|
||||||
# return True
|
|
||||||
# else:
|
|
||||||
# self.log_info("wait for scan response")
|
|
||||||
# continue
|
|
||||||
|
|
||||||
# # check if response is valid
|
|
||||||
# if scan_response is None:
|
|
||||||
# if wait_scan_response == 4:
|
|
||||||
# self.reset_internal()
|
|
||||||
# self.reset_hardware()
|
|
||||||
# self._interface.flush()
|
|
||||||
# else:
|
|
||||||
# self.log_info("wait for scan response")
|
|
||||||
# continue
|
|
||||||
# else:
|
|
||||||
# break
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
scan_response = self._cc2650.recv_uart(0.2)
|
scan_response = self._cc2650.recv_uart(timeout)
|
||||||
except RecvTimeout:
|
except RecvTimeout:
|
||||||
self.reset_internal()
|
# self.reset_internal()
|
||||||
self.reset_hardware()
|
# self.reset_hardware()
|
||||||
self._interface.flush()
|
# self._interface.flush()
|
||||||
return True
|
return False
|
||||||
|
|
||||||
|
|
||||||
# instruction format:
|
# instruction format:
|
||||||
# ins[0]: get_scan_response = 0x04
|
# ins[0]: get_scan_response = 0x04
|
||||||
@@ -2140,6 +2088,35 @@ class CC2650SingleMasterCentralDevice(CC2650MasterDevice, Synchronized):
|
|||||||
def found(self) -> List[DeviceResponseInfo]:
|
def found(self) -> List[DeviceResponseInfo]:
|
||||||
return self._found
|
return self._found
|
||||||
|
|
||||||
|
def check_mem_survive(self) -> Optional[CC2650Device]:
|
||||||
|
ack = []
|
||||||
|
ins = bytearray()
|
||||||
|
ins.append(10)
|
||||||
|
ins.append(1) #length
|
||||||
|
ins.append(0xF1)
|
||||||
|
# print('ins', list(ins))
|
||||||
|
|
||||||
|
try:
|
||||||
|
self._cc2650.send("bytes", bytes(ins))
|
||||||
|
|
||||||
|
except SerialTimeoutException as e:
|
||||||
|
raise RecvTimeout('device CC2650 check_mem_survive timeout') from e
|
||||||
|
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
ack = self._cc2650.recv_uart(0.001)
|
||||||
|
|
||||||
|
except RecvTimeout:
|
||||||
|
self.log_info("no memory board")
|
||||||
|
|
||||||
|
# else:
|
||||||
|
# print('ack=', ack)
|
||||||
|
|
||||||
|
if ack == [3]:
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
@synchronized
|
@synchronized
|
||||||
def connect(self, response: DeviceResponseInfo, direct_connect: bool = False) -> Optional[CC2650Device]:
|
def connect(self, response: DeviceResponseInfo, direct_connect: bool = False) -> Optional[CC2650Device]:
|
||||||
if self._handle is not None:
|
if self._handle is not None:
|
||||||
@@ -2555,11 +2532,10 @@ class CC2650MultiMasterCentralDevice(CC2650MasterDevice, Synchronized):
|
|||||||
|
|
||||||
if m is None:
|
if m is None:
|
||||||
m = CC2650SingleMasterCentralDevice(self._master, self._interface, self._options)
|
m = CC2650SingleMasterCentralDevice(self._master, self._interface, self._options)
|
||||||
# m.set_log_level(self._cc2650_log_level)
|
self._cc2650[i] = m
|
||||||
|
|
||||||
self._interface.flush()
|
self._interface.flush()
|
||||||
self._selector.select(i)
|
self._selector.select(i)
|
||||||
# self._mem_selector.select(i)
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self.log_info('reset device', i)
|
self.log_info('reset device', i)
|
||||||
@@ -2567,10 +2543,7 @@ class CC2650MultiMasterCentralDevice(CC2650MasterDevice, Synchronized):
|
|||||||
with m:
|
with m:
|
||||||
m.reset_internal()
|
m.reset_internal()
|
||||||
m.reset_hardware()
|
m.reset_hardware()
|
||||||
|
m.reset_software()
|
||||||
if software_reset:
|
|
||||||
m.reset_software()
|
|
||||||
self._cc2650[i] = m
|
|
||||||
|
|
||||||
except RecvTimeout:
|
except RecvTimeout:
|
||||||
self.log_warn('reset device', i, 'fail')
|
self.log_warn('reset device', i, 'fail')
|
||||||
@@ -2579,83 +2552,11 @@ class CC2650MultiMasterCentralDevice(CC2650MasterDevice, Synchronized):
|
|||||||
if not software_reset:
|
if not software_reset:
|
||||||
return
|
return
|
||||||
|
|
||||||
# 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")
|
|
||||||
|
|
||||||
def reset_empty_master(self, device: Optional[List[int]] = None, software_reset=True):
|
|
||||||
self.log_verbose('reset')
|
|
||||||
|
|
||||||
# reset hardware
|
|
||||||
# print("reset device = ", device)
|
|
||||||
for i in range(len(self._cc2650)):
|
|
||||||
# print(i)
|
|
||||||
|
|
||||||
m = self._cc2650[i]
|
|
||||||
d = self._device[i]
|
|
||||||
|
|
||||||
# print(m, d)
|
|
||||||
|
|
||||||
if m is not None and d 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)
|
|
||||||
|
|
||||||
with m:
|
|
||||||
m.reset_internal()
|
|
||||||
m.reset_hardware()
|
|
||||||
|
|
||||||
except RecvTimeout:
|
|
||||||
self.log_warn('reset device', i, 'fail')
|
|
||||||
self._cc2650[i] = None
|
|
||||||
|
|
||||||
def available_device(self) -> List[int]:
|
|
||||||
return list(map(lambda it: it[0],
|
|
||||||
filter(lambda it: it[1] is not None,
|
|
||||||
enumerate(self._cc2650))))
|
|
||||||
|
|
||||||
def _foreach_empty_master(self) -> Iterable[int]:
|
def _foreach_empty_master(self) -> Iterable[int]:
|
||||||
for i in range(len(self._cc2650)):
|
for i in range(len(self._device)):
|
||||||
m = self._cc2650[i]
|
|
||||||
d = self._device[i]
|
d = self._device[i]
|
||||||
|
|
||||||
if m is not None and d is None:
|
if d is None:
|
||||||
yield i
|
yield i
|
||||||
|
|
||||||
def scan_callback(self, callback: Callable[[DeviceResponseInfo], None], timeout=5, all_device=False) -> bool:
|
def scan_callback(self, callback: Callable[[DeviceResponseInfo], None], timeout=5, all_device=False) -> bool:
|
||||||
@@ -2663,28 +2564,35 @@ class CC2650MultiMasterCentralDevice(CC2650MasterDevice, Synchronized):
|
|||||||
|
|
||||||
all_result = False
|
all_result = False
|
||||||
|
|
||||||
for device in self._foreach_empty_master():
|
for device in range(len(self._cc2650)):
|
||||||
self.log_verbose('use', device)
|
self.log_verbose('use', device)
|
||||||
|
|
||||||
m = self._cc2650[device]
|
m = self._cc2650[device]
|
||||||
d = self._device[device]
|
d = self._device[device]
|
||||||
|
|
||||||
if m is not None and d is None:
|
if d is None:
|
||||||
error = None
|
error = None
|
||||||
|
|
||||||
with self:
|
with self:
|
||||||
self._interface.flush()
|
self._interface.flush()
|
||||||
self._selector.select(device)
|
self._selector.select(device)
|
||||||
# self._mem_selector.select(device)
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
sleep(0.0001)
|
if m.check_mem_survive() == False:
|
||||||
result = m.scan_callback(callback, timeout=timeout)
|
continue
|
||||||
|
|
||||||
|
result = m.scan_callback(callback, timeout=0.001)
|
||||||
|
|
||||||
except RuntimeError as e:
|
except RuntimeError as e:
|
||||||
error = e
|
error = e
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
|
||||||
|
if result == False:
|
||||||
|
result = True
|
||||||
|
all_result = all_result or result
|
||||||
|
continue
|
||||||
|
|
||||||
all_result = all_result or result
|
all_result = all_result or result
|
||||||
|
|
||||||
if result and not all_device:
|
if result and not all_device:
|
||||||
@@ -2692,8 +2600,7 @@ class CC2650MultiMasterCentralDevice(CC2650MasterDevice, Synchronized):
|
|||||||
|
|
||||||
if error is not None:
|
if error is not None:
|
||||||
self.log_warn('suppressed error : ' + str(error))
|
self.log_warn('suppressed error : ' + str(error))
|
||||||
# self.reset(device)
|
|
||||||
sleep(1)
|
|
||||||
return all_result
|
return all_result
|
||||||
|
|
||||||
def found(self) -> List[DeviceResponseInfo]:
|
def found(self) -> List[DeviceResponseInfo]:
|
||||||
@@ -2746,7 +2653,6 @@ class CC2650MultiMasterCentralDevice(CC2650MasterDevice, Synchronized):
|
|||||||
with self:
|
with self:
|
||||||
self._interface.flush()
|
self._interface.flush()
|
||||||
self._selector.select(master)
|
self._selector.select(master)
|
||||||
# self._mem_selector.select(device)
|
|
||||||
|
|
||||||
sleep(0.0001)
|
sleep(0.0001)
|
||||||
d = m.connect(response, direct_connect)
|
d = m.connect(response, direct_connect)
|
||||||
|
|||||||
@@ -383,9 +383,6 @@ class DeviceManager(MasterDevice, Synchronized):
|
|||||||
self._demo.clear()
|
self._demo.clear()
|
||||||
self._centralMaster.reset(device, software_reset)
|
self._centralMaster.reset(device, software_reset)
|
||||||
|
|
||||||
def available_device(self) -> List[int]:
|
|
||||||
return self._centralMaster.available_device()
|
|
||||||
|
|
||||||
@logging_info
|
@logging_info
|
||||||
def shutdown(self, release_resource=True):
|
def shutdown(self, release_resource=True):
|
||||||
# shutdown reset memeryboard
|
# shutdown reset memeryboard
|
||||||
@@ -575,6 +572,11 @@ class DeviceManager(MasterDevice, Synchronized):
|
|||||||
if slave.device_id == device:
|
if slave.device_id == device:
|
||||||
return slave
|
return slave
|
||||||
|
|
||||||
|
elif isinstance(device, str):
|
||||||
|
for slave in self._device:
|
||||||
|
if ':'.join('{:02x}'.format(b) for b in slave.mac_address) == device:
|
||||||
|
return slave
|
||||||
|
|
||||||
elif isinstance(device, DeviceInfo):
|
elif isinstance(device, DeviceInfo):
|
||||||
for slave in self._device:
|
for slave in self._device:
|
||||||
if device.match(slave):
|
if device.match(slave):
|
||||||
|
|||||||
@@ -948,12 +948,13 @@ class I4V4Z4T4DataDecoder(RecDataDecoder):
|
|||||||
ret.append_data(3, cycle_number)
|
ret.append_data(3, cycle_number)
|
||||||
|
|
||||||
# memoryboard information
|
# memoryboard information
|
||||||
ret.append_data(4, mem_wrong)
|
# ret.append_data(4, mem_wrong)
|
||||||
ret.append_data(5, mem_retry_cnt)
|
# ret.append_data(5, mem_retry_cnt)
|
||||||
ret.append_data(6, mem_green_wrong)
|
# ret.append_data(6, mem_green_wrong)
|
||||||
ret.append_data(7, mem_green_retry_cnt)
|
# ret.append_data(7, mem_green_retry_cnt)
|
||||||
ret.append_data(8, ram_num)
|
# ret.append_data(8, ram_num)
|
||||||
ret.append_data(9, broken_flag)
|
# ret.append_data(9, broken_flag)
|
||||||
|
# ret.append_data(4, ram_num)
|
||||||
|
|
||||||
if cycle_number != self._cycle_number:
|
if cycle_number != self._cycle_number:
|
||||||
# notify cycle_number change
|
# notify cycle_number change
|
||||||
|
|||||||
@@ -963,10 +963,6 @@ class MasterDevice(LoggerFlag, metaclass=abc.ABCMeta):
|
|||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@abc.abstractmethod
|
|
||||||
def available_device(self) -> List[int]:
|
|
||||||
pass
|
|
||||||
|
|
||||||
def scan(self, timeout=5, all_device=False) -> List[DeviceResponseInfo]:
|
def scan(self, timeout=5, all_device=False) -> List[DeviceResponseInfo]:
|
||||||
"""scan the nearby device.
|
"""scan the nearby device.
|
||||||
|
|
||||||
@@ -1101,9 +1097,6 @@ class NullMasterDevice(MasterDevice):
|
|||||||
def shutdown(self, release_resource=True):
|
def shutdown(self, release_resource=True):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def available_device(self) -> List[int]:
|
|
||||||
return []
|
|
||||||
|
|
||||||
def scan(self, timeout=5, all_device=False) -> List[DeviceResponseInfo]:
|
def scan(self, timeout=5, all_device=False) -> List[DeviceResponseInfo]:
|
||||||
return []
|
return []
|
||||||
|
|
||||||
|
|||||||
@@ -3720,12 +3720,9 @@ class CC2650Central(LoggerFlag):
|
|||||||
if ret is not None and len(ret) > 0:
|
if ret is not None and len(ret) > 0:
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
elif _time() - start > 1:
|
elif _time() - start > 0.01: # read timeout
|
||||||
return None
|
return None
|
||||||
|
|
||||||
else:
|
|
||||||
sleep(0.01)
|
|
||||||
|
|
||||||
def _recv_event(self, timeout: Optional[float] = 1) -> Optional[list]:
|
def _recv_event(self, timeout: Optional[float] = 1) -> Optional[list]:
|
||||||
code = self._recv_byte()
|
code = self._recv_byte()
|
||||||
# print("code = ", code)
|
# print("code = ", code)
|
||||||
|
|||||||
+83
-338
@@ -16,8 +16,6 @@ MEM_REG_READ = 0x05
|
|||||||
DEFAULT_REGISTER_VALUE = 0b0100_0011 # 67
|
DEFAULT_REGISTER_VALUE = 0b0100_0011 # 67
|
||||||
MEM_SIZE = 0x1000
|
MEM_SIZE = 0x1000
|
||||||
|
|
||||||
_RUNTIME_COMPILE = False
|
|
||||||
|
|
||||||
_SLEEP_TIME_ = 0.001
|
_SLEEP_TIME_ = 0.001
|
||||||
|
|
||||||
|
|
||||||
@@ -25,73 +23,94 @@ _SLEEP_TIME_ = 0.001
|
|||||||
def zero_buffer(size: int) -> List[int]:
|
def zero_buffer(size: int) -> List[int]:
|
||||||
return [0] * size
|
return [0] * size
|
||||||
|
|
||||||
|
class MultiExtMemSpiInterface(LowLevelHardwareInterface):
|
||||||
class ExtMemSpiInterface(LowLevelHardwareInterface):
|
|
||||||
MEM_INS_MARKED = [MEM_INS_WRITE, 0, 2, 1, 1]
|
MEM_INS_MARKED = [MEM_INS_WRITE, 0, 2, 1, 1]
|
||||||
MEM_INS_RESET = [MEM_INS_WRITE, 0, 2, 1, 1, 0, 0xFF]
|
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_header', '_tx_buffer_data',
|
||||||
'pin_busy', 'pin_request', 'pin_reset', 'pin_sel',
|
'pin_busy', 'pin_mem_req', 'pin_mem_sel', 'pin_ram_sel',
|
||||||
'_pin_sel_val',
|
'_pin_sel_val',
|
||||||
|
'_pin_ram_sel_value', '_pin_mem_sel_value', '_pin_mem_req_value',
|
||||||
'_read_green_times','_read_red_times',
|
'_read_green_times','_read_red_times',
|
||||||
'_elite_data_len', '_mem_header_len', '_mem_tailer_len', '_single_data_len',
|
'_elite_data_len', '_mem_header_len', '_mem_tailer_len', '_single_data_len',
|
||||||
'_head_wrong_cnt')
|
'_head_wrong_cnt')
|
||||||
|
|
||||||
def __init__(self, device: Tuple[int, int] = None):
|
def __init__(self,
|
||||||
super().__init__()
|
select: Selector,
|
||||||
self._spi = HardwareImplSpiInterface(device,
|
device: Tuple[int, int] = None):
|
||||||
spi_speed=12_000_000 # XXX temp parameter
|
|
||||||
)
|
|
||||||
|
|
||||||
self._elite_data_len = 20
|
self._spi = HardwareImplSpiInterface(device,
|
||||||
|
spi_speed=12_000_000)
|
||||||
|
|
||||||
|
self._elite_data_len = 120
|
||||||
self._mem_header_len = 3
|
self._mem_header_len = 3
|
||||||
self._mem_tailer_len = 8
|
self._mem_tailer_len = 8
|
||||||
self._single_data_len = self._elite_data_len + self._mem_header_len + self._mem_tailer_len
|
self._single_data_len = self._elite_data_len + self._mem_header_len + self._mem_tailer_len
|
||||||
|
|
||||||
# buffer
|
# buffer
|
||||||
self._tx_buffer = [0] * 512
|
|
||||||
self._tx_buffer_header = [0] * 11
|
self._tx_buffer_header = [0] * 11
|
||||||
self._tx_buffer_data = [0] * (self._single_data_len * 10 + 3)
|
self._tx_buffer_data = [0] * (self._single_data_len * 10 + 3)
|
||||||
|
|
||||||
# memory control pin
|
# memory control pin
|
||||||
self.pin_busy = OutputPin.get_used(P3Pin.MEM_BZY, True)
|
self.pin_busy = OutputPin.get_used(P3Pin.MEM_BZY, True)
|
||||||
self.pin_request = OutputPin.get_used(P3Pin.MEM_REQ, True)
|
self.pin_mem_req = OutputPin.get_used(P3Pin.MEM_REQ, False)
|
||||||
self.pin_reset = OutputPin.get_used(P3Pin.MEM_RST, True)
|
self.pin_mem_sel = OutputPin.get_used(P3Pin.MEM_RST, True) # MEM_RST -> actually which memory board is assign
|
||||||
self.pin_sel: Optional[InputPin] = InputPin.get_used(P3Pin.MEM_SEL)
|
self.pin_ram_sel: Optional[InputPin] = InputPin.get_used(P3Pin.MEM_SEL) # MEM_SEL -> actually is RAM_SEL, which RAM is assign
|
||||||
|
|
||||||
self._pin_sel_val = False
|
self._pin_ram_sel_value = [bool(self.pin_ram_sel) for _ in range(Selector.SIZE)]
|
||||||
|
self._pin_mem_sel_value = [bool(self.pin_mem_sel) for _ in range(Selector.SIZE)]
|
||||||
|
self._pin_mem_req_value = [bool(self.pin_mem_req) for _ in range(Selector.SIZE)]
|
||||||
|
|
||||||
self._read_green_times = 0
|
self._read_green_times = 0
|
||||||
self._read_red_times = 0
|
self._read_red_times = 0
|
||||||
|
|
||||||
self._head_wrong_cnt = [0, 0, 0, 0, 0, 0, 0, 0]
|
self._head_wrong_cnt = [0, 0, 0, 0, 0, 0, 0, 0]
|
||||||
|
|
||||||
def reset(self):
|
|
||||||
self._spi.reset()
|
|
||||||
|
|
||||||
def close(self):
|
self._selector = select
|
||||||
self._spi.close()
|
|
||||||
|
|
||||||
def flush(self):
|
self._pin_sel_val = [False for _ in range(Selector.SIZE)]
|
||||||
self.pin_reset.output(False)
|
self._wait_for_first_data = [True for _ in range(Selector.SIZE)]
|
||||||
self.pin_reset.output(True)
|
|
||||||
|
def set_pin_mem_req(self, value: bool):
|
||||||
|
channel = self.select
|
||||||
|
self.pin_mem_req.output(value)
|
||||||
|
self._pin_mem_req_value[channel] = value
|
||||||
|
|
||||||
|
def set_pin_mem_sel(self, value: bool):
|
||||||
|
channel = self.select
|
||||||
|
self.pin_mem_sel.output(value)
|
||||||
|
self._pin_mem_sel_value[channel] = value
|
||||||
|
|
||||||
|
def get_pin_mem_req(self):
|
||||||
|
channel = self.select
|
||||||
|
return self._pin_mem_req_value[channel]
|
||||||
|
|
||||||
|
def get_pin_ram_sel(self):
|
||||||
|
channel = self.select
|
||||||
|
if self.pin_ram_sel.input() == 0:
|
||||||
|
self._pin_ram_sel_value[channel] = False
|
||||||
|
else:
|
||||||
|
self._pin_ram_sel_value[channel] = True
|
||||||
|
return self._pin_ram_sel_value[channel]
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def select(self) -> int:
|
def select(self) -> int:
|
||||||
return 0
|
return self._selector.channel
|
||||||
|
|
||||||
@select.setter
|
@select.setter
|
||||||
def select(self, value: int):
|
def select(self, value: int):
|
||||||
|
self._selector.select(value)
|
||||||
|
|
||||||
|
def reset(self):
|
||||||
|
self._spi.reset()
|
||||||
|
|
||||||
|
def flush(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def changed(self, flip=False) -> bool:
|
def close(self):
|
||||||
old = self._pin_sel_val
|
self._selector.close()
|
||||||
value = self.pin_sel.input()
|
self._spi.close()
|
||||||
|
|
||||||
if flip:
|
|
||||||
self._pin_sel_val = value
|
|
||||||
|
|
||||||
return value != old
|
|
||||||
|
|
||||||
def send_byte(self, data: bytes):
|
def send_byte(self, data: bytes):
|
||||||
raise RuntimeError()
|
raise RuntimeError()
|
||||||
@@ -99,25 +118,18 @@ class ExtMemSpiInterface(LowLevelHardwareInterface):
|
|||||||
def recv_byte(self, size: int) -> Optional[bytes]:
|
def recv_byte(self, size: int) -> Optional[bytes]:
|
||||||
raise RuntimeError()
|
raise RuntimeError()
|
||||||
|
|
||||||
def request_data(self):
|
def foreach(self) -> Iterable[int]:
|
||||||
self.pin_request.output(False)
|
for channel in self._selector.foreach():
|
||||||
sleep(0.001)
|
yield channel
|
||||||
|
|
||||||
# count = 0
|
def set_wait_flag(self, spi_idx:int = None, value:bool = None):
|
||||||
# for i in range(300):
|
self._wait_for_first_data[spi_idx] = value
|
||||||
# count = count + 1
|
|
||||||
|
|
||||||
self.pin_request.output(True)
|
def get_wait_flag(self, spi_idx:int = None) -> Optional[bool]:
|
||||||
|
if spi_idx < Selector.SIZE:
|
||||||
# sleep(0.001) -> 1.2ms
|
return self._wait_for_first_data[spi_idx]
|
||||||
# no sleep -> 5us ~ 12us (central can't receive)
|
else:
|
||||||
|
return None
|
||||||
# for i in range
|
|
||||||
# (1000) -> 500us ~ 1ms
|
|
||||||
# (500) -> 200us ~ 500us
|
|
||||||
# (300) -> 120us ~ 270us (seldom)
|
|
||||||
# (200) -> 70us ~ 160us (skip req about every 64 time) x
|
|
||||||
# (100) -> 40us ~ 100us (skip req sometimes) x
|
|
||||||
|
|
||||||
def compare_green_data(self, data_first: Union[bytes, List[int]], data_second: Union[bytes, List[int]], data_third: Union[bytes, List[int]], length: int):
|
def compare_green_data(self, data_first: Union[bytes, List[int]], data_second: Union[bytes, List[int]], data_third: Union[bytes, List[int]], length: int):
|
||||||
data = []
|
data = []
|
||||||
@@ -162,7 +174,6 @@ class ExtMemSpiInterface(LowLevelHardwareInterface):
|
|||||||
address = 0
|
address = 0
|
||||||
|
|
||||||
# first read to get data length
|
# first read to get data length
|
||||||
tx = self._tx_buffer
|
|
||||||
tx_h = self._tx_buffer_header
|
tx_h = self._tx_buffer_header
|
||||||
|
|
||||||
tx_h[0] = MEM_INS_READ
|
tx_h[0] = MEM_INS_READ
|
||||||
@@ -178,8 +189,8 @@ class ExtMemSpiInterface(LowLevelHardwareInterface):
|
|||||||
|
|
||||||
if (data[0] != 255 or data[1] != 255 or data[2] != 255):
|
if (data[0] != 255 or data[1] != 255 or data[2] != 255):
|
||||||
self._head_wrong_cnt[device] = self._head_wrong_cnt[device] + 1
|
self._head_wrong_cnt[device] = self._head_wrong_cnt[device] + 1
|
||||||
if (self._head_wrong_cnt[device] < 6):
|
if (self._head_wrong_cnt[device] <= 5): # print 5 times
|
||||||
print('data_first[0:3] != [255, 255, 255]', device)
|
print('data_first[0:3] != [255, 255, 255], device:', device, ',', self._head_wrong_cnt[device], 'times')
|
||||||
print(list(data[0:7]))
|
print(list(data[0:7]))
|
||||||
|
|
||||||
data[0:3] = [255, 255, 255]
|
data[0:3] = [255, 255, 255]
|
||||||
@@ -198,13 +209,13 @@ class ExtMemSpiInterface(LowLevelHardwareInterface):
|
|||||||
# if (data_first[0] != 255 or data_first[1] != 255 or data_first[2] != 255):
|
# if (data_first[0] != 255 or data_first[1] != 255 or data_first[2] != 255):
|
||||||
# self._head_wrong_cnt[device] = self._head_wrong_cnt[device] + 1
|
# self._head_wrong_cnt[device] = self._head_wrong_cnt[device] + 1
|
||||||
# if (self._head_wrong_cnt[device] < 10):
|
# if (self._head_wrong_cnt[device] < 10):
|
||||||
# print('data_first[0:3] != [255, 255, 255]', device)
|
# print('data_first[0:3] != [255, 255, 255], device:', device, ',', self._head_wrong_cnt[device], 'times')
|
||||||
# print(list(data_first[0:7]))
|
# print(list(data_first[0:7]))
|
||||||
|
|
||||||
# if (data_second[0] != 255 or data_second[1] != 255 or data_second[2] != 255):
|
# if (data_second[0] != 255 or data_second[1] != 255 or data_second[2] != 255):
|
||||||
# self._head_wrong_cnt[device] = self._head_wrong_cnt[device] + 1
|
# self._head_wrong_cnt[device] = self._head_wrong_cnt[device] + 1
|
||||||
# if (self._head_wrong_cnt[device] < 10):
|
# if (self._head_wrong_cnt[device] < 10):
|
||||||
# print('data_second[0:3] != [255, 255, 255]', device)
|
# print('data_first[0:3] != [255, 255, 255], device:', device, ',', self._head_wrong_cnt[device], 'times')
|
||||||
# print(list(data_second[0:7]))
|
# print(list(data_second[0:7]))
|
||||||
|
|
||||||
# if (data_first[3:] == data_second[3:]):
|
# if (data_first[3:] == data_second[3:]):
|
||||||
@@ -356,108 +367,39 @@ class ExtMemSpiInterface(LowLevelHardwareInterface):
|
|||||||
|
|
||||||
self._spi.send_byte(tx)
|
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:
|
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
|
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)
|
|
||||||
|
|
||||||
def mem_request(self):
|
|
||||||
self._mem_req.pulse()
|
|
||||||
sleep(_SLEEP_TIME_)
|
|
||||||
|
|
||||||
def get_ext_mem_register(self) -> List[Tuple[Optional[int], Optional[int]]]:
|
def get_ext_mem_register(self) -> List[Tuple[Optional[int], Optional[int]]]:
|
||||||
ret = [(None, None) for _ in range(Selector.SIZE)]
|
ret = [(None, None) for _ in range(Selector.SIZE)]
|
||||||
|
|
||||||
for channel in self._ext_mem.foreach():
|
for channel in self._ext_mem.foreach():
|
||||||
r = [None, None]
|
r = [None, None]
|
||||||
|
|
||||||
self.mem_request()
|
self._ext_mem.set_pin_mem_sel(False)
|
||||||
sleep(0.01)
|
pin_value = self._ext_mem.get_pin_mem_req()
|
||||||
m1 = int(self._mem_sel)
|
self._ext_mem.set_pin_mem_req(not pin_value)
|
||||||
|
|
||||||
|
m1 = int(self._ext_mem.get_pin_ram_sel())
|
||||||
# print("m1 = ", m1)
|
# print("m1 = ", m1)
|
||||||
self._ext_mem.write_register(DEFAULT_REGISTER_VALUE)
|
self._ext_mem.write_register(DEFAULT_REGISTER_VALUE)
|
||||||
r[m1] = self._ext_mem.read_register()
|
r[m1] = self._ext_mem.read_register()
|
||||||
|
sleep(0.040)
|
||||||
|
self._ext_mem.set_pin_mem_sel(True)
|
||||||
|
sleep(0.200)
|
||||||
|
|
||||||
self.mem_request()
|
self._ext_mem.set_pin_mem_sel(False)
|
||||||
sleep(0.01)
|
pin_value = self._ext_mem.get_pin_mem_req()
|
||||||
m2 = int(self._mem_sel)
|
self._ext_mem.set_pin_mem_req(not pin_value)
|
||||||
|
|
||||||
|
m2 = int(self._ext_mem.get_pin_ram_sel())
|
||||||
# print("m2 = ", m2)
|
# print("m2 = ", m2)
|
||||||
self._ext_mem.write_register(DEFAULT_REGISTER_VALUE)
|
self._ext_mem.write_register(DEFAULT_REGISTER_VALUE)
|
||||||
r[m2] = self._ext_mem.read_register()
|
r[m2] = self._ext_mem.read_register()
|
||||||
|
sleep(0.040)
|
||||||
|
self._ext_mem.set_pin_mem_sel(True)
|
||||||
|
sleep(0.200)
|
||||||
|
|
||||||
ret[channel] = tuple(r)
|
ret[channel] = tuple(r)
|
||||||
|
|
||||||
@@ -483,33 +425,6 @@ class ExtMemManager:
|
|||||||
|
|
||||||
return 0
|
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]:
|
def get_available_channel(self, result: List[Tuple[Optional[int], Optional[int]]] = None) -> List[int]:
|
||||||
if result is None:
|
if result is None:
|
||||||
result = self.get_ext_mem_register()
|
result = self.get_ext_mem_register()
|
||||||
@@ -526,173 +441,3 @@ class ExtMemManager:
|
|||||||
ret.append(channel)
|
ret.append(channel)
|
||||||
|
|
||||||
return ret
|
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())
|
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ class HardwareImplSpiInterface(LowLevelHardwareInterface):
|
|||||||
*MISO*, *SCLK*, *GE0_N*
|
*MISO*, *SCLK*, *GE0_N*
|
||||||
"""
|
"""
|
||||||
|
|
||||||
__slots__ = ('_device', '_spi', '_spi_mode', 'pin_request', '_spi_speed')
|
__slots__ = ('_device', '_spi', '_spi_mode', '_spi_speed')
|
||||||
|
|
||||||
def __init__(self,
|
def __init__(self,
|
||||||
device: Tuple[int, int] = None,
|
device: Tuple[int, int] = None,
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ class UARTInterface(LowLevelHardwareInterface):
|
|||||||
self._serial = serial.Serial(self._port,
|
self._serial = serial.Serial(self._port,
|
||||||
baudrate=self._baudrate,
|
baudrate=self._baudrate,
|
||||||
timeout=0,
|
timeout=0,
|
||||||
writeTimeout=1)
|
writeTimeout=0.01)
|
||||||
# deprecate function name which change at version 3.0
|
# deprecate function name which change at version 3.0
|
||||||
self._serial.flushInput()
|
self._serial.flushInput()
|
||||||
self._serial.flushOutput()
|
self._serial.flushOutput()
|
||||||
|
|||||||
@@ -117,14 +117,14 @@ class Selector:
|
|||||||
self._p1.output(p[1])
|
self._p1.output(p[1])
|
||||||
self._p2.output(p[2])
|
self._p2.output(p[2])
|
||||||
|
|
||||||
if (value == 4 and self._last_sel != 6):
|
# if (value == 4 and self._last_sel != 6):
|
||||||
print('mem_sel is not use gray code, value:', value, ', last value:', self._last_sel)
|
# print('mem_sel is not use gray code, value:', value, ', last value:', self._last_sel)
|
||||||
elif (value == 5 and self._last_sel != 4):
|
# elif (value == 5 and self._last_sel != 4):
|
||||||
print('mem_sel is not use gray code, value:', value, ', last value:', self._last_sel)
|
# print('mem_sel is not use gray code, value:', value, ', last value:', self._last_sel)
|
||||||
elif (value == 7 and self._last_sel != 5):
|
# elif (value == 7 and self._last_sel != 5):
|
||||||
print('mem_sel is not use gray code, value:', value, ', last value:', self._last_sel)
|
# print('mem_sel is not use gray code, value:', value, ', last value:', self._last_sel)
|
||||||
elif (value == 6 and self._last_sel != 7):
|
# elif (value == 6 and self._last_sel != 7):
|
||||||
print('mem_sel is not use gray code, value:', value, ', last value:', self._last_sel)
|
# print('mem_sel is not use gray code, value:', value, ', last value:', self._last_sel)
|
||||||
|
|
||||||
self._last_sel = value
|
self._last_sel = value
|
||||||
|
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ class RoutineConnectDeviceThread(ServerThread):
|
|||||||
self._current_times = 0
|
self._current_times = 0
|
||||||
self._time = time()
|
self._time = time()
|
||||||
|
|
||||||
if len(self._manager._device) < len(self._manager.available_device()) and not self.check_device_status('update') and not self.check_device_status('running') and self._current_times < 3:
|
if not self.check_device_status('update') and not self.check_device_status('running') and self._current_times < 3:
|
||||||
self._current_times += 1
|
self._current_times += 1
|
||||||
register_device = DeviceAPI.getAll()
|
register_device = DeviceAPI.getAll()
|
||||||
if register_device is not None:
|
if register_device is not None:
|
||||||
|
|||||||
+54
-241
@@ -10,7 +10,7 @@ import base64
|
|||||||
from biopro.data import *
|
from biopro.data import *
|
||||||
from biopro.devlib.data import *
|
from biopro.devlib.data import *
|
||||||
from biopro.generator import GeneratorOptions
|
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.impl.selector import Selector
|
||||||
from biopro.recording import RecordingMetaFile, RecordingFileWriter
|
from biopro.recording import RecordingMetaFile, RecordingFileWriter
|
||||||
from biopro.util.address import EMPTY_ADDRESS, address_str
|
from biopro.util.address import EMPTY_ADDRESS, address_str
|
||||||
@@ -131,9 +131,6 @@ class DataServer(SocketServer, DataAPI):
|
|||||||
self._available_channel.clear()
|
self._available_channel.clear()
|
||||||
|
|
||||||
if self._spi is not None:
|
if self._spi is not None:
|
||||||
self.log_verbose('spi flush')
|
|
||||||
self._spi.flush_all()
|
|
||||||
|
|
||||||
self.reset_available_channel()
|
self.reset_available_channel()
|
||||||
|
|
||||||
LEAK.reset()
|
LEAK.reset()
|
||||||
@@ -200,7 +197,7 @@ class DataServer(SocketServer, DataAPI):
|
|||||||
self.setup_spi(spi_mode)
|
self.setup_spi(spi_mode)
|
||||||
|
|
||||||
# restart
|
# restart
|
||||||
self.setup()
|
# self.setup()
|
||||||
|
|
||||||
# data_server setup mqtt start
|
# data_server setup mqtt start
|
||||||
if self.mqtt_thread is not None:
|
if self.mqtt_thread is not None:
|
||||||
@@ -224,8 +221,6 @@ class DataServer(SocketServer, DataAPI):
|
|||||||
return
|
return
|
||||||
elif spi_mode == self.MODE_DISABLE:
|
elif spi_mode == self.MODE_DISABLE:
|
||||||
spi = None
|
spi = None
|
||||||
elif spi_mode == self.MODE_SINGLE:
|
|
||||||
spi = ExtMemSpiInterface()
|
|
||||||
elif spi_mode == self.MODE_SELECTOR:
|
elif spi_mode == self.MODE_SELECTOR:
|
||||||
spi = MultiExtMemSpiInterface(Selector.get(Selector.MEM_SELECTOR))
|
spi = MultiExtMemSpiInterface(Selector.get(Selector.MEM_SELECTOR))
|
||||||
else:
|
else:
|
||||||
@@ -511,8 +506,6 @@ class DataServer(SocketServer, DataAPI):
|
|||||||
# start sync
|
# start sync
|
||||||
for runtime in r:
|
for runtime in r:
|
||||||
if runtime is not None and not runtime.sync_started:
|
if runtime is not None and not runtime.sync_started:
|
||||||
# if isinstance(runtime, DeviceDataRuntime):
|
|
||||||
# self.spi_flush(runtime.device)
|
|
||||||
|
|
||||||
# if client is not None:
|
# if client is not None:
|
||||||
# client.drop_data(runtime.device)
|
# client.drop_data(runtime.device)
|
||||||
@@ -562,28 +555,11 @@ class DataServer(SocketServer, DataAPI):
|
|||||||
# self.spi_reset_ram_header(c._device)
|
# self.spi_reset_ram_header(c._device)
|
||||||
self._spi.set_wait_flag(c._device, True)
|
self._spi.set_wait_flag(c._device, True)
|
||||||
|
|
||||||
self._configurations[d] = None
|
del self._configurations[d]
|
||||||
self.log_info('stop_sync', c._device)
|
self.log_info('stop_sync', c._device)
|
||||||
self.mqtt_thread.broadcast_command('stop:' + str(c._device))
|
self.mqtt_thread.broadcast_command('stop:' + str(c._device))
|
||||||
# r.append(c)
|
# r.append(c)
|
||||||
|
|
||||||
# stop sync
|
|
||||||
# for runtime in r:
|
|
||||||
# if runtime is not None and runtime.sync_started:
|
|
||||||
# self.log_info('stop_sync', runtime.device)
|
|
||||||
# self.mqtt_thread.broadcast_command('stop:' + str(runtime.device))
|
|
||||||
|
|
||||||
# try:
|
|
||||||
# runtime.shutdown()
|
|
||||||
# except:
|
|
||||||
# print_exception(self)
|
|
||||||
|
|
||||||
# # finally:
|
|
||||||
# # # self.spi_flush(runtime.device)
|
|
||||||
# # if _FLAG_DATA_LOST_STATS_:
|
|
||||||
# # if isinstance(runtime, DeviceDataRuntime):
|
|
||||||
# # runtime.log_data_receive_statistics(self)
|
|
||||||
# # runtime.shutdown()
|
|
||||||
|
|
||||||
# stop runtime, none device working
|
# stop runtime, none device working
|
||||||
if not self.sync_started:
|
if not self.sync_started:
|
||||||
@@ -663,52 +639,40 @@ class DataServer(SocketServer, DataAPI):
|
|||||||
client.clear()
|
client.clear()
|
||||||
client.close_socket()
|
client.close_socket()
|
||||||
|
|
||||||
def recv_data_form_spi(self) -> bool:
|
|
||||||
"""
|
|
||||||
"""
|
|
||||||
current_time = time()
|
|
||||||
|
|
||||||
|
def get_spi_obj(self):
|
||||||
|
return self._spi
|
||||||
|
|
||||||
|
def whether_to_record(self, device):
|
||||||
|
# if user click "start", return True; if user click "stop", return False;
|
||||||
|
if device in self._configurations.keys() and self._configurations[device] is not None:
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
def recv_data_form_spi_new(self, device) -> bool:
|
||||||
ret = False
|
ret = False
|
||||||
|
sync = self.get_spi_obj()
|
||||||
|
|
||||||
devicelist = self._configurations.keys()
|
if sync.get_pin_mem_req() == sync.get_pin_ram_sel():
|
||||||
|
spi_data = sync.recv_memory(device)
|
||||||
|
signal = sync.get_pin_mem_req()
|
||||||
|
sync.set_pin_mem_req(not signal)
|
||||||
|
data = spi_data
|
||||||
|
|
||||||
devicelist = [4, 5, 7, 6]
|
else:
|
||||||
|
data = None
|
||||||
|
|
||||||
for c in devicelist:
|
if data is not None:
|
||||||
sync = self._spi
|
if self._configurations[device].queue_flag:
|
||||||
sync.select = c
|
self._configurations[device].queue_flag = False
|
||||||
|
print("q size= ", self._configurations[device]._queue_rec.qsize())
|
||||||
|
|
||||||
# delay 120us ~ 270us
|
self._configurations[device].put_rec_queue(data)
|
||||||
count = 0
|
ret = True
|
||||||
for i in range(300):
|
|
||||||
count = count + 1
|
|
||||||
|
|
||||||
if c in self._configurations.keys() and self._configurations[c] is not None:
|
|
||||||
data = self.spi_recv(c)
|
|
||||||
if time() - current_time > 0.1:
|
|
||||||
print('time, spi_recv', current_time, time() - current_time)
|
|
||||||
current_time = time()
|
|
||||||
if data is not None:
|
|
||||||
try:
|
|
||||||
|
|
||||||
if self._configurations[c].queue_flag:
|
|
||||||
self._configurations[c].queue_flag = False
|
|
||||||
print("q size= ", self._configurations[c]._queue_rec.qsize())
|
|
||||||
|
|
||||||
self._configurations[c].put_rec_queue(data)
|
|
||||||
if time() - current_time > 0.05:
|
|
||||||
print('time, queue', current_time, time() - current_time)
|
|
||||||
current_time = time()
|
|
||||||
# print('done put queue')
|
|
||||||
except:
|
|
||||||
return
|
|
||||||
else:
|
|
||||||
ret = True
|
|
||||||
# else:
|
|
||||||
# print('****1')
|
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
def rec_update(self) -> bool:
|
def rec_update(self) -> bool:
|
||||||
|
|
||||||
device_id = self._queue_db_error.get()
|
device_id = self._queue_db_error.get()
|
||||||
@@ -722,165 +686,6 @@ class DataServer(SocketServer, DataAPI):
|
|||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def recv_data_foreach_runtime(self, device_id: int) -> bool:
|
|
||||||
# """foreach data runtime to receive data. called by :class:`DataRuntimeThread`.
|
|
||||||
|
|
||||||
# :return: has runtime received data
|
|
||||||
# """
|
|
||||||
# q = None
|
|
||||||
# data = None
|
|
||||||
# try:
|
|
||||||
# q = self._queue_spi_dict[device_id].get()
|
|
||||||
# except:
|
|
||||||
# return False
|
|
||||||
|
|
||||||
# ret = False
|
|
||||||
|
|
||||||
|
|
||||||
# if self._queue_spi_dict[device_id].qsize() > 10:
|
|
||||||
# print('qsize: ', device_id, self._queue_spi_dict[device_id].qsize())
|
|
||||||
|
|
||||||
# for c in self._configurations:
|
|
||||||
# if self._configurations[c] is not None and self._configurations[c].sync_started:
|
|
||||||
# if self._configurations[c]._device == device_id:
|
|
||||||
# try:
|
|
||||||
# data = self._configurations[c].sync_data(q)
|
|
||||||
# except EODInterrupt:
|
|
||||||
# self._configurations[c].sync_started = False
|
|
||||||
# except:
|
|
||||||
# # catch any error and ignore it
|
|
||||||
# print_exception(self)
|
|
||||||
# self._configurations[c].sync_started = False
|
|
||||||
|
|
||||||
# else:
|
|
||||||
# if data is not None and len(data) > 0:
|
|
||||||
# ret = True
|
|
||||||
# # if self._configurations[c].sync_file_request:
|
|
||||||
# # self._configurations[c].sync_file()
|
|
||||||
# # for c in self._configurations:
|
|
||||||
# # # print('_configurations', c)
|
|
||||||
# # if c is not None and c.sync_started:
|
|
||||||
# # if q[0] == c._device:
|
|
||||||
# # try:
|
|
||||||
# # # print('c.time', c._prev_data, c._prev_time_stamp, c._prev_delta_time)
|
|
||||||
# # # c._timer_of_not_send = int(time())
|
|
||||||
# # data = c.sync_data(q[1])
|
|
||||||
|
|
||||||
# # except EODInterrupt:
|
|
||||||
# # c.sync_started = False
|
|
||||||
|
|
||||||
# # except:
|
|
||||||
# # # catch any error and ignore it
|
|
||||||
# # print_exception(self)
|
|
||||||
# # c.sync_started = False
|
|
||||||
|
|
||||||
# # else:
|
|
||||||
# # if data is not None and len(data) > 0:
|
|
||||||
# # ret = True
|
|
||||||
|
|
||||||
# # if c.sync_file_request:
|
|
||||||
# # c.sync_file()
|
|
||||||
# del q
|
|
||||||
# del data
|
|
||||||
|
|
||||||
return
|
|
||||||
|
|
||||||
def spi_flush(self, device: int):
|
|
||||||
"""clean spi buffer"""
|
|
||||||
|
|
||||||
if self._spi is not None:
|
|
||||||
self._spi.select = device
|
|
||||||
self._spi.flush()
|
|
||||||
return
|
|
||||||
|
|
||||||
def spi_reset_ram_header(self, device: int):
|
|
||||||
if self._spi is not None:
|
|
||||||
self._spi.select = device
|
|
||||||
self._spi.request_data()
|
|
||||||
sleep(0.01)
|
|
||||||
self._spi.reset()
|
|
||||||
self._spi.flush()
|
|
||||||
return
|
|
||||||
|
|
||||||
def spi_send(self, device: int, address: int, data: bytes):
|
|
||||||
sync = self._spi
|
|
||||||
|
|
||||||
if sync is None:
|
|
||||||
return
|
|
||||||
|
|
||||||
sync.select = device
|
|
||||||
sync.write_memory(address, data)
|
|
||||||
return
|
|
||||||
|
|
||||||
def spi_recv(self, device: int) -> Optional[bytes]:
|
|
||||||
sync = self._spi
|
|
||||||
|
|
||||||
if sync is None:
|
|
||||||
return None
|
|
||||||
if self._is_usb_port(device):
|
|
||||||
# if self._is_demo_usb_port(device):
|
|
||||||
# self._usb will be a list when suporting multi usb device
|
|
||||||
sync = self._usb
|
|
||||||
|
|
||||||
if sync is None:
|
|
||||||
return None
|
|
||||||
|
|
||||||
data = sync.recv_memory()
|
|
||||||
if data is None:
|
|
||||||
return None
|
|
||||||
|
|
||||||
data_length = len(data) + 1
|
|
||||||
header = 0xFF
|
|
||||||
data_counter = 0x00
|
|
||||||
data_header = [header, data_counter, data_length, device]
|
|
||||||
data_header.extend(data)
|
|
||||||
|
|
||||||
return bytes(data_header)
|
|
||||||
|
|
||||||
else:
|
|
||||||
sync = self._spi
|
|
||||||
|
|
||||||
if sync is None:
|
|
||||||
return None
|
|
||||||
|
|
||||||
# sync.select = device
|
|
||||||
|
|
||||||
# sleep(0.003)
|
|
||||||
|
|
||||||
if sync.changed(flip=True):
|
|
||||||
spi_data = sync.recv_memory(device)
|
|
||||||
|
|
||||||
return spi_data
|
|
||||||
# if sync.get_wait_flag(device) is False:
|
|
||||||
# return spi_data
|
|
||||||
# else:
|
|
||||||
# sync.set_wait_flag(device, False)
|
|
||||||
# print("discard first data")
|
|
||||||
# return None
|
|
||||||
# return sync.recv_memory()
|
|
||||||
else:
|
|
||||||
sync.request_data()
|
|
||||||
|
|
||||||
return None
|
|
||||||
|
|
||||||
def _is_usb_port(self, device: int) -> bool:
|
|
||||||
max_spi_port_number = 8
|
|
||||||
|
|
||||||
if device >= max_spi_port_number:
|
|
||||||
return True
|
|
||||||
else:
|
|
||||||
return False
|
|
||||||
|
|
||||||
sync.select = device
|
|
||||||
|
|
||||||
if sync.changed(flip=True):
|
|
||||||
# print('recv_memory~~~')
|
|
||||||
return sync.recv_memory()
|
|
||||||
else:
|
|
||||||
# print('request_data___')
|
|
||||||
return sync.request_data()
|
|
||||||
|
|
||||||
|
|
||||||
class DataRuntime(metaclass=abc.ABCMeta):
|
class DataRuntime(metaclass=abc.ABCMeta):
|
||||||
__slots__ = ('_server', '_device', '_meta_file', '_data_format',
|
__slots__ = ('_server', '_device', '_meta_file', '_data_format',
|
||||||
'_sync_started', 'sync_file_request', '_writer')
|
'_sync_started', 'sync_file_request', '_writer')
|
||||||
@@ -1328,12 +1133,6 @@ class DataRuntimeThread(ServerThread):
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
def routine(self, event = None) -> None:
|
def routine(self, event = None) -> None:
|
||||||
# start = time()
|
|
||||||
# ret = self._server.recv_data_foreach_runtime(self._device_id)
|
|
||||||
# self._counter += 1
|
|
||||||
# if self._counter > 10000:
|
|
||||||
# gc.collect()
|
|
||||||
# self._counter = 0
|
|
||||||
del ret
|
del ret
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -1346,8 +1145,9 @@ class SpiRuntimeThread(ServerThread):
|
|||||||
# routine period control
|
# routine period control
|
||||||
self._start_time = 0.0
|
self._start_time = 0.0
|
||||||
self._time_stamp = 0.0
|
self._time_stamp = 0.0
|
||||||
self._interval = 0.15
|
self._interval = 0.045
|
||||||
self._timer = time()
|
self._timer = time()
|
||||||
|
self._read_memory_board_idx = 0
|
||||||
|
|
||||||
def setup(self) -> None:
|
def setup(self) -> None:
|
||||||
super().setup()
|
super().setup()
|
||||||
@@ -1360,27 +1160,40 @@ class SpiRuntimeThread(ServerThread):
|
|||||||
# self._server.close_cache_client()
|
# self._server.close_cache_client()
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def routine(self, event = None) -> None:
|
def routine(self, event = None) -> None: # routine 50 ms
|
||||||
server = self._server
|
server = self._server
|
||||||
self._timer = time()
|
self._timer = time()
|
||||||
ret = server.recv_data_form_spi()
|
|
||||||
|
sync = server.get_spi_obj()
|
||||||
|
|
||||||
|
# select channel
|
||||||
|
devicelist = [4, 5, 7, 6]
|
||||||
|
c = devicelist[self._read_memory_board_idx]
|
||||||
|
sync.select = c
|
||||||
|
|
||||||
|
if server.whether_to_record(c):
|
||||||
|
sync.set_pin_mem_sel(False)
|
||||||
|
ret = server.recv_data_form_spi_new(c) # read ram & put data into queue, if has data, ret = true
|
||||||
|
|
||||||
|
self._read_memory_board_idx = 0 if self._read_memory_board_idx == 3 else self._read_memory_board_idx + 1
|
||||||
|
|
||||||
run_time = time() - self._timer
|
run_time = time() - self._timer
|
||||||
if run_time > self._interval:
|
|
||||||
print('time, recv_data_form_spi_routine_time', time(), run_time)
|
|
||||||
|
|
||||||
if run_time > 0.15:
|
if run_time > 0.045:
|
||||||
run_time = 0.15
|
print('time, recv_data_form_spi_routine_time', time(), run_time)
|
||||||
|
run_time = 0.045
|
||||||
|
|
||||||
if server.sync_started:
|
if server.sync_started:
|
||||||
event.wait((self._interval - run_time))
|
event.wait(self._interval - run_time)
|
||||||
|
sync.set_pin_mem_sel(True)
|
||||||
|
sleep(0.005)
|
||||||
|
return
|
||||||
else:
|
else:
|
||||||
|
event.wait(self._interval - run_time)
|
||||||
|
sync.set_pin_mem_sel(True)
|
||||||
self.close()
|
self.close()
|
||||||
return
|
return
|
||||||
|
|
||||||
self._start_time = time()
|
|
||||||
return
|
|
||||||
|
|
||||||
class RecRuntimeThread(ServerThread):
|
class RecRuntimeThread(ServerThread):
|
||||||
def __init__(self, server: DataServer):
|
def __init__(self, server: DataServer):
|
||||||
super().__init__('RecRunTime', MAGENTA)
|
super().__init__('RecRunTime', MAGENTA)
|
||||||
|
|||||||
@@ -213,8 +213,8 @@ class ControlServer(SocketServer, ControlServerAPI, CacheAPI, CacheNotifyHandler
|
|||||||
self.led_thread.set_state(LED.POWER_ON)
|
self.led_thread.set_state(LED.POWER_ON)
|
||||||
|
|
||||||
# sha checking
|
# sha checking
|
||||||
if _RUNTIME_COMPILE or not self._controller_options.flag_disable_sha_check:
|
# if _RUNTIME_COMPILE or not self._controller_options.flag_disable_sha_check:
|
||||||
self.run_thread(_RandomCrashThread())
|
# self.run_thread(_RandomCrashThread())
|
||||||
|
|
||||||
# data server
|
# data server
|
||||||
interface = self.device_manager.interface
|
interface = self.device_manager.interface
|
||||||
@@ -307,8 +307,15 @@ class ControlServer(SocketServer, ControlServerAPI, CacheAPI, CacheNotifyHandler
|
|||||||
if len(controller) == 0:
|
if len(controller) == 0:
|
||||||
ControllerAPI.create(hardware_info)
|
ControllerAPI.create(hardware_info)
|
||||||
elif len(controller) > 0:
|
elif len(controller) > 0:
|
||||||
if hardware_info['mac_address'] != controller[0]['mac_address'] or hardware_info['software_version'] != controller[0]['software_version'] or hardware_info['mqtt_id'] != controller[0]['mqtt_id']:
|
if hardware_info['mac_address'] != controller[0]['mac_address'] or hardware_info['software_version'] != controller[0]['software_version'] or hardware_info['mqtt_id'] != controller[0]['mqtt_id'] or hardware_info['wifi_name'] != controller[0]['wifi_name']:
|
||||||
ControllerAPI.updateByAttrs('mac_address', hardware_info['mac_address'], {'software_version': hardware_info['software_version'], 'mqtt_id': mqtt_id })
|
ControllerAPI.updateByAttrs (
|
||||||
|
'mac_address', hardware_info['mac_address'], {
|
||||||
|
'software_version': hardware_info['software_version'],
|
||||||
|
'mqtt_id': mqtt_id,
|
||||||
|
'name': hardware_info['name'],
|
||||||
|
'wifi_name': hardware_info['wifi_name']
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
def _setup_device(self):
|
def _setup_device(self):
|
||||||
# wait data server
|
# wait data server
|
||||||
@@ -328,7 +335,7 @@ class ControlServer(SocketServer, ControlServerAPI, CacheAPI, CacheNotifyHandler
|
|||||||
if available_channel is None:
|
if available_channel is None:
|
||||||
self.device_manager.setup(DeviceHardwareInterface.INTERFACE_DUMMY)
|
self.device_manager.setup(DeviceHardwareInterface.INTERFACE_DUMMY)
|
||||||
else:
|
else:
|
||||||
self._setup_device_manager(available_channel)
|
self.broadcast_command('state:device_available')
|
||||||
|
|
||||||
except ServerShutdownException as e:
|
except ServerShutdownException as e:
|
||||||
self.interrupt(e)
|
self.interrupt(e)
|
||||||
@@ -400,24 +407,6 @@ class ControlServer(SocketServer, ControlServerAPI, CacheAPI, CacheNotifyHandler
|
|||||||
self.log_verbose('available channel', available_channel)
|
self.log_verbose('available channel', available_channel)
|
||||||
return available_channel
|
return available_channel
|
||||||
|
|
||||||
def _setup_device_manager(self, available_channel: List[int]):
|
|
||||||
# device reset
|
|
||||||
# only reset those device has channel available
|
|
||||||
self.log_verbose('reset device')
|
|
||||||
self.device_manager.reset(available_channel)
|
|
||||||
|
|
||||||
# device checking
|
|
||||||
available_device = self.device_manager.available_device()
|
|
||||||
|
|
||||||
self.log_verbose('available device', available_device)
|
|
||||||
self.broadcast_command('state:device_available')
|
|
||||||
|
|
||||||
if len(available_device) == 0:
|
|
||||||
raise RuntimeError('empty device')
|
|
||||||
|
|
||||||
elif available_device != available_channel:
|
|
||||||
raise RuntimeError('device/channel mismatch')
|
|
||||||
|
|
||||||
def _setup_restart_device_manager(self, interface: str):
|
def _setup_restart_device_manager(self, interface: str):
|
||||||
self.log_info('shutdown device manager')
|
self.log_info('shutdown device manager')
|
||||||
self.device_manager.shutdown()
|
self.device_manager.shutdown()
|
||||||
@@ -656,9 +645,9 @@ class ControlServer(SocketServer, ControlServerAPI, CacheAPI, CacheNotifyHandler
|
|||||||
if self.device_manager.scan_callback(callback, timeout=self._scan_max_timeout, all_device=True):
|
if self.device_manager.scan_callback(callback, timeout=self._scan_max_timeout, all_device=True):
|
||||||
self.broadcast_command(DataMessage.scan('done'))
|
self.broadcast_command(DataMessage.scan('done'))
|
||||||
|
|
||||||
if device_not_found:
|
# if device_not_found:
|
||||||
# no device found, longer the max scan time
|
# # no device found, longer the max scan time
|
||||||
self._scan_max_timeout = min(10, self._scan_max_timeout + 2)
|
# self._scan_max_timeout = min(10, self._scan_max_timeout + 2)
|
||||||
|
|
||||||
@logging_info
|
@logging_info
|
||||||
def hardware_device(self) -> List[DeviceResponseInfo]:
|
def hardware_device(self) -> List[DeviceResponseInfo]:
|
||||||
|
|||||||
@@ -324,19 +324,52 @@ class RecordingProcess(Process):
|
|||||||
|
|
||||||
if (save == False):
|
if (save == False):
|
||||||
self._wrong_cnt += 1
|
self._wrong_cnt += 1
|
||||||
print('jump cnt', self._wrong_cnt, 'times', datetime.now())
|
print('jump cnt', self._wrong_cnt, 'times, device:', device, ',', datetime.now())
|
||||||
|
|
||||||
return save
|
return save
|
||||||
|
|
||||||
def _check_jump_ram(self, raw_data: bytes, colum_now: int, colum_total: int, save: bool, device: int):
|
def _check_jump_ram(self, raw_data: bytes, colum_now: int, colum_total: int, save: bool, device: int):
|
||||||
i = colum_now
|
i = colum_now
|
||||||
|
|
||||||
if (raw_data[i][0] == 255 and raw_data[i][3] == device):
|
if (raw_data[i][0] == 255 and raw_data[i][3] == device):
|
||||||
if (i <= colum_total - 3):
|
if colum_total < 3:
|
||||||
if(raw_data[i + 1][1] - raw_data[i][1] == 1 and raw_data[i + 2][1] - raw_data[i + 1][1] == 1):
|
print('this ram data < 3 records, need to fix, colum_total = ', colum_total)
|
||||||
|
if colum_total == 1:
|
||||||
|
print('raw_data[0]', raw_data[0])
|
||||||
|
|
||||||
|
elif colum_total == 2:
|
||||||
|
print('raw_data[0]', raw_data[0])
|
||||||
|
print('raw_data[1]', raw_data[1])
|
||||||
|
|
||||||
|
else:
|
||||||
|
|
||||||
|
if((raw_data[i + 1][1] - raw_data[i][1] == 1 and raw_data[i + 2][1] - raw_data[i + 1][1] == 1) or
|
||||||
|
(raw_data[i][1] == 255 and raw_data[i + 1][1] == 0 and raw_data[i + 2][1] == 1) or
|
||||||
|
(raw_data[i][1] == 254 and raw_data[i + 1][1] == 255 and raw_data[i + 2][1] == 0)):
|
||||||
|
|
||||||
|
if ((raw_data[i][1] == 255 and raw_data[i + 1][1] == 0 and raw_data[i + 2][1] == 1) or
|
||||||
|
(raw_data[i][1] == 254 and raw_data[i + 1][1] == 255 and raw_data[i + 2][1] == 0)):
|
||||||
|
print('cnt = [254, 255, 0] or [255, 0, 1]')
|
||||||
|
|
||||||
save = True
|
save = True
|
||||||
self._skip_ram_cnt += 1
|
self._skip_ram_cnt += 1
|
||||||
last_data_cnt = raw_data[i][1]
|
last_data_cnt = raw_data[i][1]
|
||||||
|
if (device == 4):
|
||||||
|
print('self._last_cnt[4]:', self._last_cnt[4], ', last_data_cnt:', last_data_cnt)
|
||||||
|
if (device == 5):
|
||||||
|
print('self._last_cnt[5]:', self._last_cnt[5], ', last_data_cnt:', last_data_cnt)
|
||||||
|
if (device == 6):
|
||||||
|
print('self._last_cnt[6]:', self._last_cnt[6], ', last_data_cnt:', last_data_cnt)
|
||||||
|
if (device == 7):
|
||||||
|
print('self._last_cnt[7]:', self._last_cnt[7], ', last_data_cnt:', last_data_cnt)
|
||||||
|
|
||||||
print('skip RAM, but data is right, solve data', list(raw_data[i]), 'skip Ram', self._skip_ram_cnt, 'times')
|
print('skip RAM, but data is right, solve data', list(raw_data[i]), 'skip Ram', self._skip_ram_cnt, 'times')
|
||||||
|
print('data:')
|
||||||
|
print('|', list(raw_data[0]))
|
||||||
|
print('|', list(raw_data[1]))
|
||||||
|
print('| ... ... ...')
|
||||||
|
print('| ... ... ...')
|
||||||
|
print('|', list(raw_data[colum_total-1]))
|
||||||
print()
|
print()
|
||||||
|
|
||||||
if (device == 4):
|
if (device == 4):
|
||||||
@@ -465,7 +498,7 @@ class RecordingProcess(Process):
|
|||||||
"""
|
"""
|
||||||
raw_data = []
|
raw_data = []
|
||||||
index = 0
|
index = 0
|
||||||
elite_data_len = 20
|
elite_data_len = 120
|
||||||
mem_header_len = 3
|
mem_header_len = 3
|
||||||
mem_tailer_len = 8
|
mem_tailer_len = 8
|
||||||
single_data_len = elite_data_len + mem_header_len + mem_tailer_len
|
single_data_len = elite_data_len + mem_header_len + mem_tailer_len
|
||||||
|
|||||||
@@ -67,7 +67,7 @@
|
|||||||
"FREQ_STOP": {
|
"FREQ_STOP": {
|
||||||
"description": "End of Freq Scan",
|
"description": "End of Freq Scan",
|
||||||
"record_meta": true,
|
"record_meta": true,
|
||||||
"initial": 1,
|
"initial": 7,
|
||||||
"domain": [
|
"domain": [
|
||||||
"FREQ_MAX"
|
"FREQ_MAX"
|
||||||
],
|
],
|
||||||
@@ -100,7 +100,7 @@
|
|||||||
"DC_BIAS": {
|
"DC_BIAS": {
|
||||||
"description": "DC voltage bias in mV",
|
"description": "DC voltage bias in mV",
|
||||||
"record_meta": true,
|
"record_meta": true,
|
||||||
"initial": 0,
|
"initial": 15000,
|
||||||
"domain": [
|
"domain": [
|
||||||
35001
|
35001
|
||||||
],
|
],
|
||||||
|
|||||||
Reference in New Issue
Block a user