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.
@@ -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