programmer-core 1.0.29__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- programmer_core/__init__.py +22 -0
- programmer_core/activate_device.py +246 -0
- programmer_core/adapters.py +23 -0
- programmer_core/constants.py +50 -0
- programmer_core/debug_device.py +278 -0
- programmer_core/detect_flash_type.py +316 -0
- programmer_core/enter_rma.py +264 -0
- programmer_core/factory_program_device.py +667 -0
- programmer_core/full_flash_erase.py +268 -0
- programmer_core/get_fuse_data.py +277 -0
- programmer_core/memory_validation_test.py +357 -0
- programmer_core/partial_fuse_programming.py +342 -0
- programmer_core/program_device.py +775 -0
- programmer_core/query_device.py +274 -0
- programmer_core/report.py +921 -0
- programmer_core/utility.py +1822 -0
- programmer_core-1.0.29.dist-info/METADATA +146 -0
- programmer_core-1.0.29.dist-info/RECORD +20 -0
- programmer_core-1.0.29.dist-info/WHEEL +5 -0
- programmer_core-1.0.29.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
import pathlib
|
|
3
|
+
|
|
4
|
+
from communicator_core import (
|
|
5
|
+
BinaryDownloader,
|
|
6
|
+
DeviceLifeCycleNum,
|
|
7
|
+
DSSMStatus,
|
|
8
|
+
CC35XXE,
|
|
9
|
+
CC37XXR,
|
|
10
|
+
)
|
|
11
|
+
from flash_images_builder_core import ActionReqBuilder
|
|
12
|
+
|
|
13
|
+
try:
|
|
14
|
+
from report import QueryReportGeneratorCC35XXE, QueryReportGeneratorCC35XX
|
|
15
|
+
from utility import ProgrammerUtility, get_lifecycle_state_reg_class
|
|
16
|
+
except ImportError:
|
|
17
|
+
from .report import QueryReportGeneratorCC35XXE, QueryReportGeneratorCC35XX
|
|
18
|
+
from .utility import ProgrammerUtility, get_lifecycle_state_reg_class
|
|
19
|
+
|
|
20
|
+
# uncomment for debug communicator code without build pakage communicator-core for every change
|
|
21
|
+
# if 'communicator' in sys.modules.keys():
|
|
22
|
+
# from communicator.communicator_core.core.cc35xx_config_ap import DeviceLifeCycleNum, DSSMStatus, LifeCycleStateReg
|
|
23
|
+
# from communicator.communicator_core.core.binary_downloader import BinaryDownloader
|
|
24
|
+
|
|
25
|
+
PROGRAMMER_QUERY_LOGGER = logging.getLogger("query")
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class QueryDevice:
|
|
29
|
+
SIMULATION = "DEMO"
|
|
30
|
+
XDS110 = "XDS110"
|
|
31
|
+
|
|
32
|
+
def __init__(
|
|
33
|
+
self,
|
|
34
|
+
interface_type,
|
|
35
|
+
serial_number,
|
|
36
|
+
query_action_req_path,
|
|
37
|
+
programmer_artifacts_path,
|
|
38
|
+
fib_artifacts_path,
|
|
39
|
+
device_type,
|
|
40
|
+
report_file_path=None,
|
|
41
|
+
reset_on_timeout=True,
|
|
42
|
+
path_to_tpr=None,
|
|
43
|
+
wait_timeout=1,
|
|
44
|
+
write_timeout=0,
|
|
45
|
+
wait_for_resp=True,
|
|
46
|
+
verbose=False,
|
|
47
|
+
tclk_delay=4,
|
|
48
|
+
chunk_size=1085,
|
|
49
|
+
):
|
|
50
|
+
self.query_action_req_path = query_action_req_path
|
|
51
|
+
self.device_type = device_type
|
|
52
|
+
|
|
53
|
+
# Initialize the appropriate LifeCycleStateReg class based on device type
|
|
54
|
+
self._lifecycle_reg_class = get_lifecycle_state_reg_class(self.device_type)
|
|
55
|
+
|
|
56
|
+
self.prog_utility = ProgrammerUtility(
|
|
57
|
+
programmer_artifacts_path, fib_artifacts_path
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
self.path_to_tpr = path_to_tpr
|
|
61
|
+
if self.path_to_tpr is None:
|
|
62
|
+
self.path_to_tpr = self.prog_utility.get_default_prog(self.device_type)
|
|
63
|
+
|
|
64
|
+
self.report_file_path = (
|
|
65
|
+
report_file_path
|
|
66
|
+
if report_file_path
|
|
67
|
+
else (pathlib.Path(self.query_action_req_path).parent / "query_report.txt")
|
|
68
|
+
)
|
|
69
|
+
self.reset_on_timeout = reset_on_timeout
|
|
70
|
+
|
|
71
|
+
self.interface_type = interface_type
|
|
72
|
+
self.serial_number = serial_number
|
|
73
|
+
self.wait_timeout = wait_timeout
|
|
74
|
+
self.write_timeout = write_timeout
|
|
75
|
+
self.wait_for_resp = wait_for_resp
|
|
76
|
+
self.tclk_delay = tclk_delay
|
|
77
|
+
self.chunk_size = chunk_size
|
|
78
|
+
self.verbose = verbose
|
|
79
|
+
self.log_level = logging.INFO if verbose else logging.DEBUG
|
|
80
|
+
self.error_message = ""
|
|
81
|
+
|
|
82
|
+
# TODO: temporary - CC37XXR uses CC35XXE report generator until CC37XXR specific generators are available
|
|
83
|
+
if self.device_type in [CC35XXE, CC37XXR]:
|
|
84
|
+
self.report_generator = QueryReportGeneratorCC35XXE(
|
|
85
|
+
programmer_artifacts_path=programmer_artifacts_path,
|
|
86
|
+
fib_artifacts_path=fib_artifacts_path,
|
|
87
|
+
report_file_path=self.report_file_path,
|
|
88
|
+
verbose=self.verbose,
|
|
89
|
+
)
|
|
90
|
+
else:
|
|
91
|
+
self.report_generator = QueryReportGeneratorCC35XX(
|
|
92
|
+
programmer_artifacts_path=programmer_artifacts_path,
|
|
93
|
+
fib_artifacts_path=fib_artifacts_path,
|
|
94
|
+
report_file_path=self.report_file_path,
|
|
95
|
+
verbose=self.verbose,
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
def _get_selected_images(self, query_action_req_path):
|
|
99
|
+
with open(query_action_req_path, "rb") as f:
|
|
100
|
+
action_req_content_row = f.read()
|
|
101
|
+
|
|
102
|
+
action_req_builder = ActionReqBuilder(
|
|
103
|
+
header_version=None,
|
|
104
|
+
type=ActionReqBuilder.QUERY,
|
|
105
|
+
device_type=self.device_type,
|
|
106
|
+
payload_param=None,
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
action_req_parsed = action_req_builder.parse(action_req_content_row)
|
|
110
|
+
|
|
111
|
+
# TODO: check if this field exist or catch an error if false
|
|
112
|
+
selected_images = action_req_parsed["payload"]["action_payload"][
|
|
113
|
+
"query_req_content"
|
|
114
|
+
]
|
|
115
|
+
|
|
116
|
+
return selected_images
|
|
117
|
+
|
|
118
|
+
def query(self):
|
|
119
|
+
|
|
120
|
+
#################################################
|
|
121
|
+
## Step 0 ##
|
|
122
|
+
## check that all files exist ##
|
|
123
|
+
#################################################
|
|
124
|
+
self.path_to_tpr = self.prog_utility.fix_path(self.path_to_tpr)
|
|
125
|
+
res = self.prog_utility.file_path_exist(self.path_to_tpr, "TI Programmer")
|
|
126
|
+
if res is not None:
|
|
127
|
+
self.error_message = res
|
|
128
|
+
PROGRAMMER_QUERY_LOGGER.error(self.error_message)
|
|
129
|
+
return False
|
|
130
|
+
|
|
131
|
+
res = self.prog_utility.file_path_exist(
|
|
132
|
+
self.query_action_req_path, "query_request"
|
|
133
|
+
)
|
|
134
|
+
if res is not None:
|
|
135
|
+
self.error_message = res
|
|
136
|
+
PROGRAMMER_QUERY_LOGGER.error(self.error_message)
|
|
137
|
+
return False
|
|
138
|
+
|
|
139
|
+
#################################################
|
|
140
|
+
## Step 1 ##
|
|
141
|
+
## Reset device and download TI Bootloader ##
|
|
142
|
+
#################################################
|
|
143
|
+
|
|
144
|
+
tbl_download = BinaryDownloader(
|
|
145
|
+
bin_file=self.path_to_tpr,
|
|
146
|
+
interface_type=self.interface_type,
|
|
147
|
+
serial_number=self.serial_number,
|
|
148
|
+
wait_timeout=self.wait_timeout,
|
|
149
|
+
write_timeout=self.write_timeout,
|
|
150
|
+
verbose=self.verbose,
|
|
151
|
+
tclk_delay=self.tclk_delay,
|
|
152
|
+
chunk_size=self.chunk_size,
|
|
153
|
+
)
|
|
154
|
+
|
|
155
|
+
# reset device
|
|
156
|
+
tbl_download.device.reset_device()
|
|
157
|
+
|
|
158
|
+
# Download TI bootloader
|
|
159
|
+
tbl_download.daemon = True
|
|
160
|
+
tbl_download.start()
|
|
161
|
+
|
|
162
|
+
while tbl_download.is_alive():
|
|
163
|
+
tbl_download.join(0.1)
|
|
164
|
+
|
|
165
|
+
error_code, error_msg = tbl_download.download_status
|
|
166
|
+
|
|
167
|
+
if error_code > 0:
|
|
168
|
+
PROGRAMMER_QUERY_LOGGER.log(self.log_level, "Successfully loaded binary")
|
|
169
|
+
else:
|
|
170
|
+
self.error_message = f"Failed loading 'TI Programmer' image"
|
|
171
|
+
PROGRAMMER_QUERY_LOGGER.error(
|
|
172
|
+
f"Failed loading binary with error code: {error_code}\nError message: {error_msg}"
|
|
173
|
+
)
|
|
174
|
+
return False
|
|
175
|
+
|
|
176
|
+
#################################################
|
|
177
|
+
## Step 2 ##
|
|
178
|
+
## Read CFGAP and check life-cycle/dssm status ##
|
|
179
|
+
#################################################
|
|
180
|
+
|
|
181
|
+
if self.interface_type != self.SIMULATION:
|
|
182
|
+
# Read cfgap - use device-specific register class
|
|
183
|
+
life_cycle_state_reg = self._lifecycle_reg_class(
|
|
184
|
+
interface=self.interface_type,
|
|
185
|
+
serial_number=self.serial_number,
|
|
186
|
+
verbose=self.verbose,
|
|
187
|
+
)
|
|
188
|
+
life_cycle_state_reg.read_reg()
|
|
189
|
+
life_cycle = life_cycle_state_reg.life_cycle_sw_coded
|
|
190
|
+
dssm_status = life_cycle_state_reg.dssm_status
|
|
191
|
+
life_cycle_state_reg.disconnect()
|
|
192
|
+
|
|
193
|
+
# Check if life cycle is one of allowed_life_cycle
|
|
194
|
+
allowed_life_cycle = [
|
|
195
|
+
DeviceLifeCycleNum.DEPLOYED,
|
|
196
|
+
DeviceLifeCycleNum.RMA_HW_ANALYSIS,
|
|
197
|
+
DeviceLifeCycleNum.RMA_FAILIURE_ANALYSIS,
|
|
198
|
+
]
|
|
199
|
+
if life_cycle not in allowed_life_cycle:
|
|
200
|
+
self.error_message = f"Life cycle is not valid"
|
|
201
|
+
PROGRAMMER_QUERY_LOGGER.error(
|
|
202
|
+
f"Process is stopped. Life cycle {DeviceLifeCycleNum(life_cycle).name} is not valid."
|
|
203
|
+
)
|
|
204
|
+
return False
|
|
205
|
+
|
|
206
|
+
# Check if dssm status is DSSM_READY
|
|
207
|
+
if not dssm_status == DSSMStatus.DSSM_READY:
|
|
208
|
+
self.error_message = f"Device is not ready for query"
|
|
209
|
+
PROGRAMMER_QUERY_LOGGER.error(self.error_message)
|
|
210
|
+
return False
|
|
211
|
+
|
|
212
|
+
#################################################
|
|
213
|
+
## Step 3 ##
|
|
214
|
+
## Download query action req ##
|
|
215
|
+
#################################################
|
|
216
|
+
|
|
217
|
+
# check selected images
|
|
218
|
+
selected_images = self._get_selected_images(
|
|
219
|
+
query_action_req_path=self.query_action_req_path
|
|
220
|
+
)
|
|
221
|
+
|
|
222
|
+
query_req_downloader = BinaryDownloader(
|
|
223
|
+
bin_file=self.query_action_req_path,
|
|
224
|
+
interface_type=self.interface_type,
|
|
225
|
+
serial_number=self.serial_number,
|
|
226
|
+
wait_timeout=self.wait_timeout,
|
|
227
|
+
write_timeout=self.write_timeout,
|
|
228
|
+
wait_for_resp=self.wait_for_resp,
|
|
229
|
+
verbose=self.verbose,
|
|
230
|
+
expected_resp_size=self.report_generator._get_expected_report_size(
|
|
231
|
+
selected_images
|
|
232
|
+
),
|
|
233
|
+
tclk_delay=self.tclk_delay,
|
|
234
|
+
chunk_size=self.chunk_size,
|
|
235
|
+
)
|
|
236
|
+
query_req_downloader.daemon = True
|
|
237
|
+
query_req_downloader.start()
|
|
238
|
+
|
|
239
|
+
while query_req_downloader.is_alive():
|
|
240
|
+
query_req_downloader.join(0.1)
|
|
241
|
+
|
|
242
|
+
error_code, error_msg = query_req_downloader.download_status
|
|
243
|
+
|
|
244
|
+
if error_code > 0:
|
|
245
|
+
PROGRAMMER_QUERY_LOGGER.log(self.log_level, "Successfully loaded binary")
|
|
246
|
+
else:
|
|
247
|
+
self.error_message = f"Failed loading 'Query Action Request'"
|
|
248
|
+
PROGRAMMER_QUERY_LOGGER.error(
|
|
249
|
+
f"Failed loading binary with error code: {error_code}\nError message: {error_msg}"
|
|
250
|
+
)
|
|
251
|
+
return False
|
|
252
|
+
|
|
253
|
+
#################################################
|
|
254
|
+
## Step 4 ##
|
|
255
|
+
## get response and print to the user ##
|
|
256
|
+
#################################################
|
|
257
|
+
|
|
258
|
+
if self.wait_for_resp:
|
|
259
|
+
# parse report from device
|
|
260
|
+
report_content_raw = query_req_downloader.resp
|
|
261
|
+
|
|
262
|
+
# check selected images
|
|
263
|
+
selected_images = self._get_selected_images(
|
|
264
|
+
query_action_req_path=self.query_action_req_path
|
|
265
|
+
)
|
|
266
|
+
|
|
267
|
+
# parse report from device
|
|
268
|
+
if not self.report_generator.generate_report(
|
|
269
|
+
report_content_raw, selected_images
|
|
270
|
+
):
|
|
271
|
+
self.error_message = self.report_generator.error_message
|
|
272
|
+
return False
|
|
273
|
+
|
|
274
|
+
return True
|