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,357 @@
1
+ import logging
2
+ import pathlib
3
+
4
+ from communicator_core import (
5
+ BinaryDownloader,
6
+ DeviceLifeCycleNum,
7
+ DSSMStatus,
8
+ )
9
+
10
+ from flash_images_builder_core import PsramOption, FIBUtility
11
+
12
+
13
+ try:
14
+ from report import (
15
+ MemoryValidationReportGeneratorCC35XXE,
16
+ )
17
+ from utility import (
18
+ ProgrammerUtility,
19
+ get_lifecycle_state_reg_class,
20
+ )
21
+ except ImportError:
22
+ from .report import (
23
+ MemoryValidationReportGeneratorCC35XXE,
24
+ )
25
+ from .utility import (
26
+ ProgrammerUtility,
27
+ get_lifecycle_state_reg_class,
28
+ )
29
+
30
+ # uncomment for debug communicator code without build package communicator_core for every change
31
+ # if 'communicator' in sys.modules.keys():
32
+ # from communicator.communicator_core.core.cc35xx_config_ap import DeviceLifeCycleNum, DSSMStatus, LifeCycleStateReg
33
+ # from communicator.communicator_core.core.binary_downloader import BinaryDownloader
34
+
35
+ PROG_MEMORY_VALIDATION_TEST_LOGGER = logging.getLogger("partial-fuse-programming")
36
+
37
+
38
+ # note: 0x4110295c - hw life cycle address
39
+ class MemoryValidationTest:
40
+ SIMULATION = "DEMO"
41
+ XDS110 = "XDS110"
42
+
43
+ def __init__(
44
+ self,
45
+ interface_type,
46
+ serial_number,
47
+ programmer_artifacts_path,
48
+ fib_artifacts_path,
49
+ device_type,
50
+ flash_type=None,
51
+ psram_type=PsramOption.NO_PSRAM.name,
52
+ enable_ota=False,
53
+ report_file_path=None,
54
+ reset_on_timeout=True,
55
+ path_to_tac=None,
56
+ wait_timeout=2,
57
+ write_timeout=0,
58
+ wait_for_resp=True,
59
+ verbose=False,
60
+ tclk_delay=4,
61
+ chunk_size=1085,
62
+ flash_radius_pass_value=15,
63
+ psram_radius_pass_value=10,
64
+ ):
65
+ self.device_type = device_type
66
+
67
+ # Initialize the appropriate LifeCycleStateReg class based on device type
68
+ self._lifecycle_reg_class = get_lifecycle_state_reg_class(self.device_type)
69
+
70
+ self.flash_type = flash_type
71
+ self.enable_ota = enable_ota
72
+ self.psram_type = psram_type
73
+ self.fuses_dict = {}
74
+ self.prog_utility = ProgrammerUtility(
75
+ programmer_artifacts_path, fib_artifacts_path
76
+ )
77
+ self.fib_utility = FIBUtility(fib_artifacts_path)
78
+
79
+ self.path_to_tac = path_to_tac
80
+ if self.path_to_tac is None:
81
+ self.path_to_tac = self.prog_utility.get_default_activator(self.device_type)
82
+
83
+ self.tmp_folder = self.prog_utility.get_act_n_init_tmp_folder()
84
+
85
+ self.report_file_path = (
86
+ report_file_path
87
+ if report_file_path
88
+ else (pathlib.Path(self.tmp_folder) / "memory_validation_test_report.txt")
89
+ )
90
+ self.fuses_json_file_path = (
91
+ pathlib.Path(self.tmp_folder) / "fuse_prog_inst_param.json"
92
+ )
93
+ self.programming_unsign_image_path = ""
94
+
95
+ self.reset_on_timeout = reset_on_timeout
96
+ self.interface_type = interface_type
97
+ self.serial_number = serial_number
98
+ self.wait_timeout = wait_timeout
99
+ self.write_timeout = write_timeout
100
+ self.wait_for_resp = wait_for_resp
101
+
102
+ self.tclk_delay = tclk_delay
103
+ self.chunk_size = chunk_size
104
+
105
+ self.flash_radius_pass_value = flash_radius_pass_value
106
+ self.psram_radius_pass_value = psram_radius_pass_value
107
+
108
+ self.verbose = verbose
109
+ self.log_level = logging.INFO if verbose else logging.DEBUG
110
+
111
+ self.error_message = ""
112
+
113
+ # TODO: temporary - CC37XXR uses CC35XXE report generator until CC37XXR specific generators are available
114
+ # Select report generator based on device type
115
+ self.report_generator = MemoryValidationReportGeneratorCC35XXE(
116
+ report_file_path=self.report_file_path,
117
+ programmer_artifacts_path=programmer_artifacts_path,
118
+ fib_artifacts_path=fib_artifacts_path,
119
+ verbose=self.verbose,
120
+ )
121
+
122
+ def memory_validation_test(self):
123
+
124
+ # delete report file if exist
125
+ report_path = pathlib.Path(self.report_file_path)
126
+ if report_path.exists():
127
+ try:
128
+ report_path.unlink()
129
+ PROG_MEMORY_VALIDATION_TEST_LOGGER.debug(
130
+ "Report file deleted successfully"
131
+ )
132
+ except Exception as e:
133
+ PROG_MEMORY_VALIDATION_TEST_LOGGER.warning(
134
+ f"Failed to delete report file: {e}"
135
+ )
136
+
137
+ #################################################
138
+ ## Step 0 ##
139
+ ## check that tac file exist ##
140
+ #################################################
141
+
142
+ self.path_to_tac = self.prog_utility.fix_path(self.path_to_tac)
143
+ res = self.prog_utility.file_path_exist(self.path_to_tac, "TI Activation")
144
+ if res is not None:
145
+ self.error_message = res
146
+ PROG_MEMORY_VALIDATION_TEST_LOGGER.error(self.error_message)
147
+ return False
148
+
149
+ #################################################
150
+ ## Step 1 ##
151
+ ## build prog inst image ##
152
+ #################################################
153
+
154
+ # get jsons file by flash type
155
+ ext_flash_dir_path = self.fib_utility.get_ext_flash_dir_path()
156
+
157
+ self.xspi_json, self.otfde_json, self.ext_mem_json = (
158
+ self.prog_utility.get_flash_jsons(
159
+ flash_type_files_folder=ext_flash_dir_path,
160
+ flash_device=self.flash_type,
161
+ enable_ota=self.enable_ota,
162
+ tmp_dir_path=self.tmp_folder,
163
+ psram_type=self.psram_type,
164
+ )
165
+ )
166
+
167
+ # update fuse params
168
+ self.fuses_dict["rot"] = "FF" * 32
169
+ self.prog_utility.create_new_fuses_json_file(
170
+ self.fuses_dict, self.fuses_json_file_path
171
+ )
172
+
173
+ # build programming image
174
+ self.programming_unsign_image_path, self.programming_image_to_sign_out_path = (
175
+ self.prog_utility.build_programming_image(
176
+ version="0.0.1.0",
177
+ pub_key_path=None,
178
+ activation_type=None,
179
+ dir_out_path=self.tmp_folder,
180
+ fuses_programming_instructions=self.fuses_json_file_path,
181
+ flash_discovery_config_xspi=self.xspi_json,
182
+ flash_discovery_config_otfde=self.otfde_json,
183
+ flash_discovery_config_ext_mem=self.ext_mem_json,
184
+ device=self.device_type,
185
+ logging_level=self.log_level,
186
+ )
187
+ )
188
+
189
+ #################################################
190
+ ## Step 1 ##
191
+ ## reset device and download TI Bootloader ##
192
+ #################################################
193
+
194
+ tbl_download = BinaryDownloader(
195
+ bin_file=self.path_to_tac,
196
+ interface_type=self.interface_type,
197
+ serial_number=self.serial_number,
198
+ wait_timeout=self.wait_timeout,
199
+ write_timeout=self.write_timeout,
200
+ verbose=self.verbose,
201
+ tclk_delay=self.tclk_delay,
202
+ chunk_size=self.chunk_size,
203
+ )
204
+
205
+ # reset device
206
+ tbl_download.device.reset_device()
207
+
208
+ # Download TI bootloader
209
+ tbl_download.daemon = True
210
+ tbl_download.start()
211
+
212
+ while tbl_download.is_alive():
213
+ tbl_download.join(0.1)
214
+
215
+ error_code, error_msg = tbl_download.download_status
216
+
217
+ if error_code > 0:
218
+ PROG_MEMORY_VALIDATION_TEST_LOGGER.log(
219
+ self.log_level, "Successfully loaded binary"
220
+ )
221
+ else:
222
+ self.error_message = f"Failed loading 'TI Activator' image"
223
+ PROG_MEMORY_VALIDATION_TEST_LOGGER.error(
224
+ f"Fail load binary with error code: {error_code}\nError message: {error_msg}"
225
+ )
226
+ return False
227
+
228
+ #################################################
229
+ ## Step 2 ##
230
+ ## read CFGAP and check life-cycle/DSSM status ##
231
+ #################################################
232
+
233
+ if self.interface_type != self.SIMULATION:
234
+ # Read cfgap - use device-specific register class
235
+ life_cycle_state_reg = self._lifecycle_reg_class(
236
+ interface=self.interface_type,
237
+ serial_number=self.serial_number,
238
+ verbose=self.verbose,
239
+ )
240
+ life_cycle_state_reg.read_reg()
241
+ life_cycle = life_cycle_state_reg.life_cycle_sw_coded
242
+ dssm_status = life_cycle_state_reg.dssm_status
243
+ life_cycle_state_reg.disconnect()
244
+
245
+ # Check if life cycle is one of allowed_life_cycle
246
+ allowed_life_cycle = [
247
+ DeviceLifeCycleNum.OPERATIONAL,
248
+ DeviceLifeCycleNum.RMA_HW_ANALYSIS,
249
+ DeviceLifeCycleNum.RMA_FAILIURE_ANALYSIS,
250
+ ]
251
+ if life_cycle not in allowed_life_cycle:
252
+ self.error_message = "Life cycle is not valid"
253
+ PROG_MEMORY_VALIDATION_TEST_LOGGER.error(
254
+ f"Process is stopped. Life cycle {DeviceLifeCycleNum(life_cycle).name} is not valid."
255
+ )
256
+ return False
257
+
258
+ # Check if dssm status is DSSM_READY
259
+ if not dssm_status == DSSMStatus.DSSM_READY:
260
+ self.error_message = f"Device is not ready for partial fuse programming"
261
+ PROG_MEMORY_VALIDATION_TEST_LOGGER.error(self.error_message)
262
+ return False
263
+
264
+ #################################################
265
+ ## Step 3 ##
266
+ ## download programming image ##
267
+ #################################################
268
+
269
+ prog_inst_downloader = BinaryDownloader(
270
+ bin_file=self.programming_unsign_image_path,
271
+ interface_type=self.interface_type,
272
+ serial_number=self.serial_number,
273
+ wait_timeout=self.wait_timeout,
274
+ write_timeout=self.write_timeout,
275
+ wait_for_resp=self.wait_for_resp,
276
+ verbose=self.verbose,
277
+ expected_resp_size=self.report_generator.get_report_struct_size(),
278
+ tclk_delay=self.tclk_delay,
279
+ chunk_size=self.chunk_size,
280
+ )
281
+ prog_inst_downloader.daemon = True
282
+ prog_inst_downloader.start()
283
+
284
+ while prog_inst_downloader.is_alive():
285
+ prog_inst_downloader.join(0.1)
286
+
287
+ error_code, error_msg = prog_inst_downloader.download_status
288
+
289
+ if error_code > 0:
290
+ PROG_MEMORY_VALIDATION_TEST_LOGGER.log(
291
+ self.log_level, "Successfully loaded binary"
292
+ )
293
+ else:
294
+ self.error_message = f"Failed loading 'Programming Instruction' image"
295
+ PROG_MEMORY_VALIDATION_TEST_LOGGER.error(
296
+ f"Failed loading binary with error code: {error_code}\nError message: {error_msg}"
297
+ )
298
+ return False
299
+
300
+ #################################################
301
+ ## Step 4 ##
302
+ ## get response and print to the user ##
303
+ #################################################
304
+
305
+ if self.wait_for_resp:
306
+ # get response
307
+ report_content_raw = prog_inst_downloader.resp
308
+
309
+ # generate report
310
+ if not self.report_generator.generate_report(report_content_raw):
311
+ self.error_message = self.report_generator.error_message
312
+ PROG_MEMORY_VALIDATION_TEST_LOGGER.info(
313
+ "Memory Validation Test Process: FAILED"
314
+ )
315
+ return False
316
+
317
+ # Memory validation was for psram
318
+ if self.psram_type != PsramOption.NO_PSRAM.name:
319
+ psarm_memory_validation_result = (
320
+ self.report_generator.report_container.psarm_memory_validation_result
321
+ )
322
+
323
+ if not psarm_memory_validation_result.valid:
324
+ PROG_MEMORY_VALIDATION_TEST_LOGGER.info(
325
+ "Memory Validation Test Process: FAILED - PSRAM test valid is False"
326
+ )
327
+ return False
328
+
329
+ if psarm_memory_validation_result.Radius < self.psram_radius_pass_value:
330
+ PROG_MEMORY_VALIDATION_TEST_LOGGER.info(
331
+ f"Memory Validation Test Process: FAILED - PSRAM radius {psarm_memory_validation_result.Radius} below threshold {self.psram_radius_pass_value}"
332
+ )
333
+ return False
334
+
335
+ # Memory validation was for flash
336
+ else:
337
+ flash_memory_validation_result = (
338
+ self.report_generator.report_container.flash_memory_validation_result
339
+ )
340
+
341
+ if not flash_memory_validation_result.valid:
342
+ PROG_MEMORY_VALIDATION_TEST_LOGGER.info(
343
+ "Memory Validation Test Process: FAILED - FLASH test valid is False"
344
+ )
345
+ return False
346
+
347
+ if flash_memory_validation_result.Radius < self.flash_radius_pass_value:
348
+ PROG_MEMORY_VALIDATION_TEST_LOGGER.info(
349
+ f"Memory Validation Test Process: FAILED - FLASH radius {flash_memory_validation_result.Radius} below threshold {self.flash_radius_pass_value}"
350
+ )
351
+ return False
352
+
353
+ PROG_MEMORY_VALIDATION_TEST_LOGGER.info(
354
+ "Memory Validation Test Process: SUCCEEDED"
355
+ )
356
+
357
+ return True
@@ -0,0 +1,342 @@
1
+ import logging
2
+ import pathlib
3
+
4
+ from communicator_core import (
5
+ BinaryDownloader,
6
+ DeviceLifeCycleNum,
7
+ DSSMStatus,
8
+ )
9
+
10
+ from flash_images_builder_core import (
11
+ FIBUtility,
12
+ )
13
+
14
+ try:
15
+ from report import (
16
+ ProgrammingReportGeneratorCC35XXE,
17
+ )
18
+ from utility import (
19
+ ProgrammerUtility,
20
+ get_lifecycle_state_reg_class,
21
+ )
22
+ except ImportError:
23
+ from .report import (
24
+ ProgrammingReportGeneratorCC35XXE,
25
+ )
26
+ from .utility import (
27
+ ProgrammerUtility,
28
+ get_lifecycle_state_reg_class,
29
+ )
30
+
31
+ # uncomment for debug communicator code without build package communicator_core for every change
32
+ # if 'communicator' in sys.modules.keys():
33
+ # from communicator.communicator_core.core.cc35xx_config_ap import DeviceLifeCycleNum, DSSMStatus, LifeCycleStateReg
34
+ # from communicator.communicator_core.core.binary_downloader import BinaryDownloader
35
+
36
+ PROGRAMMER_PARTIAL_FUSE_LOGGER = logging.getLogger("partial-fuse-programming")
37
+
38
+
39
+ # note: 0x4110295c - hw life cycle address
40
+ class PartialFuseProgramming:
41
+ SIMULATION = "DEMO"
42
+ XDS110 = "XDS110"
43
+
44
+ def __init__(
45
+ self,
46
+ interface_type,
47
+ serial_number,
48
+ programmer_artifacts_path,
49
+ fib_artifacts_path,
50
+ device_type,
51
+ restrict_ini=0,
52
+ country_code=0,
53
+ crda_code_enable=0,
54
+ mac_address="00:00:00:00:00:00",
55
+ wifi6_disable=0,
56
+ flash_type=None,
57
+ report_file_path=None,
58
+ reset_on_timeout=True,
59
+ path_to_tac=None,
60
+ wait_timeout=2,
61
+ write_timeout=0,
62
+ wait_for_resp=True,
63
+ verbose=False,
64
+ tclk_delay=4,
65
+ chunk_size=1085,
66
+ ):
67
+ # fuse configurarions --> exclude athutentication_enable & app_otp
68
+ self.restrict_ini = restrict_ini
69
+ self.country_code = country_code
70
+ self.mac_address = mac_address
71
+ self.wifi6_disable = wifi6_disable
72
+ self.flash_type = flash_type
73
+ self.prog_utility = ProgrammerUtility(
74
+ programmer_artifacts_path, fib_artifacts_path
75
+ )
76
+ self.fib_utility = FIBUtility(fib_artifacts_path)
77
+ self.mac_address_31_0, self.mac_address_47_32 = (
78
+ self.prog_utility.split_mac_address(self.mac_address)
79
+ )
80
+ self.crda_code_enable = crda_code_enable
81
+ self.device_type = device_type
82
+
83
+ # Initialize the appropriate LifeCycleStateReg class based on device type
84
+ self._lifecycle_reg_class = get_lifecycle_state_reg_class(self.device_type)
85
+
86
+ self.fuses_dict = {}
87
+ self.path_to_tac = path_to_tac
88
+ if self.path_to_tac is None:
89
+ self.path_to_tac = self.prog_utility.get_default_activator(self.device_type)
90
+
91
+ self.tmp_folder = self.prog_utility.get_act_n_init_tmp_folder()
92
+
93
+ self.report_file_path = (
94
+ report_file_path
95
+ if report_file_path
96
+ else (pathlib.Path(self.tmp_folder) / "partial_fuse_programming_report.txt")
97
+ )
98
+ self.fuses_json_file_path = (
99
+ pathlib.Path(self.tmp_folder) / "fuse_prog_inst_param.json"
100
+ )
101
+ self.programming_unsign_image_path = ""
102
+
103
+ self.reset_on_timeout = reset_on_timeout
104
+ self.interface_type = interface_type
105
+ self.serial_number = serial_number
106
+ self.wait_timeout = wait_timeout
107
+ self.write_timeout = write_timeout
108
+ self.wait_for_resp = wait_for_resp
109
+
110
+ self.tclk_delay = tclk_delay
111
+ self.chunk_size = chunk_size
112
+
113
+ self.verbose = verbose
114
+ self.log_level = logging.INFO if verbose else logging.DEBUG
115
+
116
+ self.error_message = ""
117
+
118
+ # TODO: temporary - CC37XXR uses CC35XXE report generator until CC37XXR specific generators are available
119
+ # Select report generator based on device type
120
+ self.report_generator = ProgrammingReportGeneratorCC35XXE(
121
+ programmer_artifacts_path=programmer_artifacts_path,
122
+ fib_artifacts_path=fib_artifacts_path,
123
+ report_file_path=self.report_file_path,
124
+ verbose=self.verbose,
125
+ )
126
+
127
+ def partial_fuse_programming_update(self):
128
+
129
+ # delete report file if exist
130
+ report_path = pathlib.Path(self.report_file_path)
131
+ if report_path.exists():
132
+ try:
133
+ report_path.unlink()
134
+ PROGRAMMER_PARTIAL_FUSE_LOGGER.debug("Report file deleted successfully")
135
+ except Exception as e:
136
+ PROGRAMMER_PARTIAL_FUSE_LOGGER.warning(
137
+ f"Failed to delete report file: {e}"
138
+ )
139
+
140
+ #################################################
141
+ ## Step 0 ##
142
+ ## check that tac file exist ##
143
+ #################################################
144
+
145
+ self.path_to_tac = self.prog_utility.fix_path(self.path_to_tac)
146
+ res = self.prog_utility.file_path_exist(self.path_to_tac, "TI Activation")
147
+ if res is not None:
148
+ self.error_message = res
149
+ PROGRAMMER_PARTIAL_FUSE_LOGGER.error(self.error_message)
150
+ return False
151
+
152
+ #################################################
153
+ ## Step 1 ##
154
+ ## build prog inst image ##
155
+ #################################################
156
+
157
+ # get jsons file by flash type
158
+ ext_flash_dir_path = self.fib_utility.get_ext_flash_dir_path()
159
+ self.xspi_json, self.otfde_json, self.ext_mem_json = (
160
+ self.prog_utility.get_flash_jsons(
161
+ flash_type_files_folder=ext_flash_dir_path,
162
+ flash_device=self.flash_type,
163
+ tmp_dir_path=self.tmp_folder,
164
+ )
165
+ )
166
+
167
+ # update fuse params
168
+ self.fuses_dict["rot"] = "00" * 32
169
+ self.fuses_dict["wifi6_disable"] = self.wifi6_disable
170
+ self.fuses_dict["vendor_restricted_ini"] = self.restrict_ini
171
+ self.fuses_dict["mac_address_31_0"] = self.mac_address_31_0
172
+ self.fuses_dict["mac_address_47_32"] = self.mac_address_47_32
173
+ self.fuses_dict["crda_country_code"] = self.country_code
174
+ self.fuses_dict["crda_code_enable"] = self.crda_code_enable
175
+
176
+ self.prog_utility.create_new_fuses_json_file(
177
+ self.fuses_dict, self.fuses_json_file_path
178
+ )
179
+
180
+ # build programming image
181
+ self.programming_unsign_image_path, self.programming_image_to_sign_out_path = (
182
+ self.prog_utility.build_programming_image(
183
+ version="0.0.1.0",
184
+ pub_key_path=None,
185
+ activation_type=None,
186
+ dir_out_path=self.tmp_folder,
187
+ fuses_programming_instructions=self.fuses_json_file_path,
188
+ flash_discovery_config_xspi=self.xspi_json,
189
+ flash_discovery_config_otfde=self.otfde_json,
190
+ flash_discovery_config_ext_mem=self.ext_mem_json,
191
+ device=self.device_type,
192
+ logging_level=self.log_level,
193
+ )
194
+ )
195
+
196
+ #################################################
197
+ ## Step 1 ##
198
+ ## reset device and download TI Bootloader ##
199
+ #################################################
200
+
201
+ tbl_download = BinaryDownloader(
202
+ bin_file=self.path_to_tac,
203
+ interface_type=self.interface_type,
204
+ serial_number=self.serial_number,
205
+ wait_timeout=self.wait_timeout,
206
+ write_timeout=self.write_timeout,
207
+ verbose=self.verbose,
208
+ tclk_delay=self.tclk_delay,
209
+ chunk_size=self.chunk_size,
210
+ )
211
+
212
+ # reset device
213
+ tbl_download.device.reset_device()
214
+
215
+ # Download TI bootloader
216
+ tbl_download.daemon = True
217
+ tbl_download.start()
218
+
219
+ while tbl_download.is_alive():
220
+ tbl_download.join(0.1)
221
+
222
+ error_code, error_msg = tbl_download.download_status
223
+
224
+ if error_code > 0:
225
+ PROGRAMMER_PARTIAL_FUSE_LOGGER.log(
226
+ self.log_level, "Successfully loaded binary"
227
+ )
228
+ else:
229
+ self.error_message = f"Failed loading 'TI Activator' image"
230
+ PROGRAMMER_PARTIAL_FUSE_LOGGER.error(
231
+ f"Fail load binary with error code: {error_code}\nError message: {error_msg}"
232
+ )
233
+ return False
234
+
235
+ #################################################
236
+ ## Step 2 ##
237
+ ## read CFGAP and check life-cycle/DSSM status ##
238
+ #################################################
239
+
240
+ if self.interface_type != self.SIMULATION:
241
+ # Read cfgap - use device-specific register class
242
+ life_cycle_state_reg = self._lifecycle_reg_class(
243
+ interface=self.interface_type,
244
+ serial_number=self.serial_number,
245
+ verbose=self.verbose,
246
+ )
247
+ life_cycle_state_reg.read_reg()
248
+ life_cycle = life_cycle_state_reg.life_cycle_sw_coded
249
+ dssm_status = life_cycle_state_reg.dssm_status
250
+ life_cycle_state_reg.disconnect()
251
+
252
+ # Check if life cycle is one of allowed_life_cycle
253
+ allowed_life_cycle = [
254
+ DeviceLifeCycleNum.OPERATIONAL,
255
+ DeviceLifeCycleNum.RMA_HW_ANALYSIS,
256
+ DeviceLifeCycleNum.RMA_FAILIURE_ANALYSIS,
257
+ ]
258
+ if life_cycle not in allowed_life_cycle:
259
+ self.error_message = "Life cycle is not valid"
260
+ PROGRAMMER_PARTIAL_FUSE_LOGGER.error(
261
+ f"Process is stopped. Life cycle {DeviceLifeCycleNum(life_cycle).name} is not valid."
262
+ )
263
+ return False
264
+
265
+ # Check if dssm status is DSSM_READY
266
+ if not dssm_status == DSSMStatus.DSSM_READY:
267
+ self.error_message = f"Device is not ready for partial fuse programming"
268
+ PROGRAMMER_PARTIAL_FUSE_LOGGER.error(self.error_message)
269
+ return False
270
+
271
+ #################################################
272
+ ## Step 3 ##
273
+ ## download programming image ##
274
+ #################################################
275
+
276
+ prog_inst_downloader = BinaryDownloader(
277
+ bin_file=self.programming_unsign_image_path,
278
+ interface_type=self.interface_type,
279
+ serial_number=self.serial_number,
280
+ wait_timeout=self.wait_timeout,
281
+ write_timeout=self.write_timeout,
282
+ wait_for_resp=self.wait_for_resp,
283
+ verbose=self.verbose,
284
+ expected_resp_size=self.report_generator.get_report_struct_size(),
285
+ tclk_delay=self.tclk_delay,
286
+ chunk_size=self.chunk_size,
287
+ )
288
+ prog_inst_downloader.daemon = True
289
+ prog_inst_downloader.start()
290
+
291
+ while prog_inst_downloader.is_alive():
292
+ prog_inst_downloader.join(0.1)
293
+
294
+ error_code, error_msg = prog_inst_downloader.download_status
295
+
296
+ if error_code > 0:
297
+ PROGRAMMER_PARTIAL_FUSE_LOGGER.log(
298
+ self.log_level, "Successfully loaded binary"
299
+ )
300
+ else:
301
+ self.error_message = f"Failed loading 'Programming Instruction' image"
302
+ PROGRAMMER_PARTIAL_FUSE_LOGGER.error(
303
+ f"Failed loading binary with error code: {error_code}\nError message: {error_msg}"
304
+ )
305
+ return False
306
+
307
+ #################################################
308
+ ## Step 4 ##
309
+ ## get response and print to the user ##
310
+ #################################################
311
+
312
+ if self.wait_for_resp:
313
+ # get response
314
+ report_content_raw = prog_inst_downloader.resp
315
+
316
+ # generate report
317
+ if not self.report_generator.generate_report(report_content_raw):
318
+ self.error_message = self.report_generator.error_message
319
+ PROGRAMMER_PARTIAL_FUSE_LOGGER.info(
320
+ "Partial Fuse Programming Process: FAILED"
321
+ )
322
+ return False
323
+
324
+ request_validation_status = (
325
+ self.report_generator.report_container.request_validation_status
326
+ )
327
+ if any(
328
+ [
329
+ request_validation_status.fuse_programming_instructions_alignment_verify_pass,
330
+ request_validation_status.recoverable_fault,
331
+ request_validation_status.non_recoverable_failure,
332
+ ]
333
+ ):
334
+ PROGRAMMER_PARTIAL_FUSE_LOGGER.info(
335
+ "Partial Fuse Programming Process: FAILED"
336
+ )
337
+ return False
338
+
339
+ PROGRAMMER_PARTIAL_FUSE_LOGGER.info(
340
+ "Partial Fuse Programming Process: SUCCEEDED"
341
+ )
342
+ return True