Skip to content

Commit 6b0c880

Browse files
committed
Squashed commit of the following:
commit c57bc71 Author: Fabio Battaglia <tabaglio@posteo.net> Date: Tue Sep 3 07:37:45 2024 +0200 some more info print when dumping an IC commit cb59ccd Author: Fabio Battaglia <tabaglio@posteo.net> Date: Mon Sep 2 21:02:56 2024 +0200 rewording of an error commit 53f4672 Author: Fabio Battaglia <tabaglio@posteo.net> Date: Mon Sep 2 21:00:59 2024 +0200 Reorganize error handling for cxfer commit 1f7f955 Author: Fabio Battaglia <tabaglio@posteo.net> Date: Mon Sep 2 17:38:38 2024 +0200 Bump to 0.4.0, remove old read code commit 2d1ea9f Author: Fabio Battaglia <tabaglio@posteo.net> Date: Mon Sep 2 17:19:17 2024 +0200 Note the second pass to read the data commit fbdc6d8 Author: Fabio Battaglia <tabaglio@posteo.net> Date: Mon Sep 2 16:34:35 2024 +0200 current implementation of cxfer reading
1 parent 14f9966 commit 6b0c880

4 files changed

Lines changed: 56 additions & 37 deletions

File tree

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
# Changelog
22
Changelog for the dpdumper utility
33

4+
## [0.4.0] - 2024-08-22
5+
### Changed
6+
- Depends on dupicolib 0.5.0
7+
- Reading ICs now uses a different protocol that cuts transfer time in roughly half
8+
49
## [0.3.3] - 2024-08-22
510
### Changed
611
- Depends on dpdumperlib 0.0.2

pyproject.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
44

55
[project]
66
name = "dpdumper"
7-
version = "0.3.3"
7+
version = "0.4.0"
88
description = "Tool to use the dupico as a dumping device"
99
authors = [
1010
{ name = "Fabio Battaglia", email = "hkzlabnet@gmail.com" }
@@ -18,7 +18,7 @@ classifiers = [
1818
requires-python = ">=3.12"
1919
dependencies = [
2020
"pyserial ~= 3.5",
21-
"dupicolib >= 0.4.2",
21+
"dupicolib >= 0.5.0",
2222
"dpdumperlib >= 0.0.2"
2323
]
2424

requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
pyserial>=3.5
2-
dupicolib>=0.4.2
2+
dupicolib>=0.5.0
33
dpdumperlib>=0.0.2

src/dpdumper/hl_board_utilities.py

Lines changed: 48 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
"""This module contains high level utility code to perform operations on the board"""
22

3-
from typing import Generator, final, NamedTuple
3+
from typing import Callable, Generator, List, final, NamedTuple
4+
import logging
45

56
import serial
6-
import math
7-
import logging
87

8+
import dupicolib.utils as DPLibUtils
99
from dupicolib.hardware_board_commands import HardwareBoardCommands
1010
from dpdumperlib.ic.ic_definition import ICDefinition
1111

@@ -44,6 +44,15 @@ def _read_pin_map_generator(cmd_class: type[HardwareBoardCommands], ic: ICDefini
4444
out_data_h: int = hi_pins_mapped | data_on_mapped | act_h_mapped | wr_l_mapped | address_mapped
4545
yield out_data_h
4646

47+
def _build_update_callback(max_size: int) -> Callable[[int], None]:
48+
def update_callback(cur_read: int) -> None:
49+
if cur_read > max_size:
50+
cur_read = max_size
51+
_print_progressBar(cur_read, max_size)
52+
53+
return update_callback
54+
55+
4756
@final
4857
class DataElement(NamedTuple):
4958
data: int
@@ -60,50 +69,55 @@ class HLBoardUtilities:
6069
@classmethod
6170
def read_ic(cls, ser: serial.Serial, cmd_class: type[HardwareBoardCommands], ic: ICDefinition, check_hiz: bool = False) -> list[DataElement] | None:
6271
read_data: list[DataElement] = []
63-
addr_combs: int = 1 << len(ic.address) # Calculate the number of addresses that this IC supports
64-
wr_responses: list[int] = []
65-
66-
_LOGGER.debug(f'read_ic command with definition {ic.name}, checking hi-z {check_hiz}. IC has {addr_combs} addresses and data width {len(ic.data)} bits.')
67-
68-
try:
69-
hi_pins_mapped: int = cmd_class.map_value_to_pins(ic.adapter_hi_pins, 0xFFFFFFFFFFFFFFFF)
72+
addr_combs: int = 1 << len(ic.address) # Calculate the number of addresses
73+
data_width: int = -(len(ic.data) // -8)
74+
dump_size: int = addr_combs * data_width
75+
hi_pins: list[int] = list(set(ic.act_h_enable + ic.adapter_hi_pins))
7076

71-
_LOGGER.debug(f'This IC requires the following pin mask forced high: {hi_pins_mapped:0{16}X}')
77+
data_normal: bytes | None = None
78+
data_invert: bytes | None = None
7279

73-
cmd_class.write_pins(hi_pins_mapped, ser) # Start with these already enabled
74-
cmd_class.set_power(True, ser)
80+
upd_callback = _build_update_callback(dump_size)
7581

76-
tot_combs: int = addr_combs if not check_hiz else addr_combs * 2
82+
_LOGGER.debug(f'read_ic command with definition {ic.name}, checking hi-z {check_hiz}. IC has {addr_combs} addresses and data width {len(ic.data)} bits.')
7783

78-
pin_map_gen = _read_pin_map_generator(cmd_class, ic, check_hiz)
79-
80-
for i, pin_map in enumerate(pin_map_gen):
81-
if i % 250 == 0:
82-
_print_progressBar(i, tot_combs)
84+
print(f'IC has {addr_combs} addresses, for a total size of ~{-(dump_size//-1024)}KB.')
85+
if check_hiz:
86+
print('Read will be done in two passes to check for Hi-Z pins.')
8387

84-
wr_addr_response: int | None = cmd_class.write_pins(pin_map, ser)
88+
try:
89+
cmd_class.set_power(True, ser)
8590

86-
if wr_addr_response is None:
87-
return None # Something went wrong
88-
else:
89-
wr_responses.append(wr_addr_response)
91+
data_normal = cmd_class.cxfer_read(ic.address, ic.data, hi_pins, upd_callback, ser)
9092

91-
_print_progressBar(tot_combs, tot_combs)
93+
if not data_normal:
94+
raise IOError('Unable to read data from IC')
9295

96+
# If we need to check for Hi-Z, we need to forcefully set data pins to high and then redo the dump
9397
if check_hiz:
94-
for pulled_low, pulled_up in grouped_iterator(wr_responses, 2):
95-
hiz_pins: int = pulled_low ^ pulled_up
96-
read_data.append(DataElement(data=cmd_class.map_pins_to_value(ic.data, pulled_low), z_mask=cmd_class.map_pins_to_value(ic.data, hiz_pins)))
97-
else:
98-
for pulled_low in wr_responses:
99-
read_data.append(DataElement(data=cmd_class.map_pins_to_value(ic.data, pulled_low)))
100-
except Exception as exc:
101-
_LOGGER.critical(exc)
98+
print('Performing a second pass to detect Hi-Z pins!')
99+
hi_pins = list(set(hi_pins + ic.data))
100+
data_invert = cmd_class.cxfer_read(ic.address, ic.data, hi_pins, upd_callback, ser)
102101
finally:
103-
print('') # Avoid writing again on the 'Testing block' string
102+
ser.reset_input_buffer()
103+
ser.reset_output_buffer()
104104
cmd_class.set_power(False, ser)
105105
cmd_class.write_pins(0, ser)
106106

107+
# Reconstruct the data elements
108+
if data_normal and data_invert:
109+
if len(data_normal) != len(data_invert):
110+
raise IOError('Same IC read twice, bug got two dumps of different length!!!')
111+
112+
for dn, di in zip(DPLibUtils.iter_grouper(data_normal, data_width, 0), DPLibUtils.iter_grouper(data_invert, data_width, 0)):
113+
dni = int.from_bytes(bytes(dn))
114+
dii = int.from_bytes(bytes(di))
115+
read_data.append(DataElement(data=dni, z_mask=dni^dii))
116+
else:
117+
for dn in DPLibUtils.iter_grouper(data_normal, data_width, 0):
118+
dni = int.from_bytes(bytes(dn))
119+
read_data.append(DataElement(data=dni))
120+
107121
return read_data[:addr_combs]
108122

109123
@staticmethod

0 commit comments

Comments
 (0)