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,316 @@
1
+ """
2
+ Detect Flash Type Module
3
+
4
+ This module provides functionality to detect the external flash type from a connected
5
+ CC35XXE device. It handles the complete flow:
6
+ 1. Check connected devices (handle "auto" serial number)
7
+ 2. Download ti_programmer
8
+ 4. Read flash type from CFGAP registers
9
+ 5. Print the result
10
+ """
11
+
12
+ import logging
13
+ import time
14
+
15
+ from communicator_core import (
16
+ Device,
17
+ BinaryDownloader,
18
+ CC3xxxRDeviceInfoReg,
19
+ DSSMStatus,
20
+ CC35XXE,
21
+ CC37XXR,
22
+ )
23
+
24
+ from flash_images_builder_core import (
25
+ UseHardware,
26
+ FLASH_DEVICE_SIZE_MAP,
27
+ FLASH_SIZE_MB_MAP,
28
+ )
29
+
30
+ from .utility import ProgrammerUtility, get_lifecycle_state_reg_class
31
+ from .constants import TIMEOUT_POLLING_FLASH_DETECT
32
+
33
+ # Logger for this module
34
+ DETECT_FLASH_LOGGER = logging.getLogger("detect-flash-type-module")
35
+
36
+
37
+ class DetectFlashType:
38
+ """
39
+ Class to detect the external flash type from a connected CC35XXE device.
40
+
41
+ This class handles the complete flow:
42
+ 1. Check connected devices (handle "auto" serial number)
43
+ 2. Download ti_programmer
44
+ 4. Read flash type from CFGAP registers
45
+ 5. Print the result
46
+ """
47
+
48
+ def __init__(
49
+ self,
50
+ interface_type,
51
+ serial_number,
52
+ programmer_artifacts_path,
53
+ fib_artifacts_path,
54
+ sysconfig=False,
55
+ jlink_speed_khz=None,
56
+ ):
57
+ """
58
+ Initialize the DetectFlashType instance.
59
+
60
+ Args:
61
+ interface_type: The interface type (e.g., "XDS110")
62
+ serial_number: The serial number of the XDS110 device, or "auto" to auto-select
63
+ programmer_artifacts_path: Path to the programmer artifacts directory
64
+ fib_artifacts_path: Path to the FIB artifacts directory
65
+ sysconfig: If True, show SysConfig-specific messages (when running from CCS)
66
+ """
67
+ self.interface_type = interface_type
68
+ self.serial_number = serial_number
69
+ self.device_type = None
70
+ self.result = None
71
+ self.sysconfig = sysconfig
72
+ self.jlink_speed_khz = jlink_speed_khz
73
+ self._lifecycle_reg_class = None # Will be set when device_type is known
74
+ self.prog_utility = ProgrammerUtility(
75
+ programmer_artifacts_path, fib_artifacts_path
76
+ )
77
+
78
+ def detect(self):
79
+ """
80
+ Detect the external flash type from the connected device.
81
+
82
+ This is the main entry point that runs the complete detection flow:
83
+ 1. Check connected devices (handle "auto" serial number)
84
+ 2. Download ti_programmer
85
+ 4. Read flash type from CFGAP registers
86
+ 5. Print the result
87
+
88
+ Returns:
89
+ Tuple of (flash_type, flash_size_mb) - both None if not recognized
90
+
91
+ Raises:
92
+ Exception: If flash detection fails
93
+ """
94
+ DETECT_FLASH_LOGGER.info(
95
+ f"Starting flash type detection (SN: {self.serial_number})"
96
+ )
97
+
98
+ # Step 1: Check connected devices (handle "auto" serial number)
99
+ if self.serial_number.lower() == "auto":
100
+ if self.interface_type == Device.JLINK or self.interface_type == Device.CMSISDAP:
101
+ # For JLINK, "" means connect to the first available device
102
+ self.serial_number = ""
103
+ else:
104
+ DETECT_FLASH_LOGGER.debug("Checking connected XDS110 devices...")
105
+ connected_devices = Device.get_connected_xds110_devices()
106
+
107
+ if len(connected_devices) == 0:
108
+ raise Exception(
109
+ "No XDS110 devices found. Please connect a device and try again."
110
+ )
111
+ elif len(connected_devices) > 1:
112
+ # Multiple devices connected - print formatted box and exit
113
+ self._print_multiple_devices_error(connected_devices)
114
+ return None, None # Signal to caller that detection should stop
115
+ else:
116
+ # Only one device connected - use it
117
+ self.serial_number = connected_devices[0]
118
+ DETECT_FLASH_LOGGER.debug(f"Auto-selected device: {self.serial_number}")
119
+
120
+ # Step 2: Get device type and Check if device is CC35XXE - flash detection only supported on CC35XXE
121
+ DETECT_FLASH_LOGGER.debug("Getting device type...")
122
+ with Device(
123
+ interface_type=self.interface_type, serial_number=self.serial_number,
124
+ ) as dev:
125
+ self.device_type = dev.get_device_type()
126
+
127
+ if self.device_type is None:
128
+ raise Exception(
129
+ "Failed to detect device type. Please check the device connection."
130
+ )
131
+
132
+ if self.device_type not in [CC35XXE, CC37XXR]:
133
+ raise Exception(
134
+ f"Flash detection is only supported on CC35XXE/CC37XXR devices. "
135
+ f"Detected device type: {self.device_type}"
136
+ )
137
+
138
+ # Initialize device-specific lifecycle register class
139
+ self._lifecycle_reg_class = get_lifecycle_state_reg_class(self.device_type)
140
+
141
+ # Step 3: Download ti_programmer
142
+ path_to_ti_programmer = self.prog_utility.get_default_prog(self.device_type)
143
+ self._download_binary(path_to_ti_programmer, "TI programmer")
144
+
145
+ # Step 5: Read flash type from CFGAP registers
146
+ DETECT_FLASH_LOGGER.debug("Reading flash type from CFGAP registers...")
147
+ # Use device-specific register class
148
+ life_cycle_state_reg = self._lifecycle_reg_class(
149
+ interface=self.interface_type,
150
+ serial_number=self.serial_number,
151
+ verbose=False,
152
+ )
153
+
154
+ timeout = time.time() + TIMEOUT_POLLING_FLASH_DETECT
155
+ while time.time() < timeout:
156
+ life_cycle_state_reg.read_reg()
157
+ dssm_status = life_cycle_state_reg.dssm_status
158
+ if dssm_status == DSSMStatus.DSSM_READY:
159
+ break
160
+ time.sleep(0.05)
161
+
162
+ if self.device_type == CC37XXR:
163
+ life_cycle_state_reg.disconnect()
164
+ device_id_reg = CC3xxxRDeviceInfoReg(
165
+ interface=self.interface_type,
166
+ serial_number=self.serial_number,
167
+ verbose=False,
168
+ )
169
+ device_id_reg.read_reg()
170
+ flash_index = device_id_reg.external_flash_part_number_index
171
+ device_id_reg.disconnect()
172
+ else:
173
+ flash_index = life_cycle_state_reg.external_flash_part_number_index
174
+ life_cycle_state_reg.disconnect()
175
+
176
+ DETECT_FLASH_LOGGER.debug(f"Flash type index: 0x{flash_index:02X}")
177
+
178
+ # Check if flash detection failed (index = 0x3F)
179
+ if flash_index == 0x3F:
180
+ raise Exception(
181
+ "Flash detection failed. The device did not return a valid flash index. "
182
+ )
183
+
184
+ # Convert flash index to flash type name
185
+ flash_type = None
186
+ for ft in UseHardware:
187
+ if ft.value == flash_index:
188
+ flash_type = ft.name
189
+ break
190
+
191
+ # Check if the detected flash index is not in the enum (not supported)
192
+ if flash_type is None:
193
+ raise Exception(
194
+ f"Detected flash index 0x{flash_index:02X} is not supported. "
195
+ )
196
+
197
+ # Get flash size in MB
198
+ flash_size_mb = None
199
+ size_str = FLASH_DEVICE_SIZE_MAP.get(flash_type)
200
+ if size_str:
201
+ flash_size_mb = FLASH_SIZE_MB_MAP.get(size_str)
202
+
203
+ self.result = {
204
+ "flash_type": flash_type,
205
+ "flash_index": flash_index,
206
+ "flash_size_mb": flash_size_mb,
207
+ }
208
+
209
+ # Step 6: Print the result
210
+ self._print_result()
211
+
212
+ # Return flash type (None if not recognized)
213
+ return self.result["flash_type"], self.result["flash_size_mb"]
214
+
215
+ def _download_binary(self, path_to_binary, binary_name):
216
+ """
217
+ Download a binary to the device.
218
+
219
+ Args:
220
+ path_to_binary: Path to the binary file
221
+ binary_name: Name of the binary for logging
222
+
223
+ Raises:
224
+ Exception: If download fails
225
+ """
226
+ DETECT_FLASH_LOGGER.debug(f"{binary_name} path: {path_to_binary}")
227
+
228
+ binary_download = BinaryDownloader(
229
+ bin_file=path_to_binary,
230
+ interface_type=self.interface_type,
231
+ serial_number=self.serial_number,
232
+ tclk_delay=4,
233
+ chunk_size=1085,
234
+ jlink_speed_khz=self.jlink_speed_khz,
235
+ )
236
+
237
+ # Reset device and download binary
238
+ DETECT_FLASH_LOGGER.debug("Resetting device...")
239
+ binary_download.device.reset_device()
240
+
241
+ DETECT_FLASH_LOGGER.debug(f"Downloading {binary_name}...")
242
+ binary_download.daemon = True
243
+ binary_download.start()
244
+
245
+ while binary_download.is_alive():
246
+ binary_download.join(0.1)
247
+
248
+ error_code, error_msg = binary_download.download_status
249
+
250
+ if error_code <= 0:
251
+ raise Exception(f"Failed to download {binary_name}: {error_msg}")
252
+
253
+ DETECT_FLASH_LOGGER.debug(f"{binary_name} downloaded successfully")
254
+
255
+ def _print_multiple_devices_error(self, connected_devices):
256
+ """
257
+ Print a formatted error box when multiple XDS110 devices are connected.
258
+
259
+ Args:
260
+ connected_devices: List of connected device serial numbers
261
+ """
262
+ error_message = f"""
263
+ +==============================================================================+
264
+ | MULTIPLE DEVICES DETECTED |
265
+ +==============================================================================+
266
+ | |
267
+ | Found {len(connected_devices)} XDS110 devices connected. |
268
+ | Please specify the serial number of the device you want to use. |
269
+ | |
270
+ | Connected devices: |
271
+ """
272
+ for sn in connected_devices:
273
+ error_message += f"| - {sn:<71}|\n"
274
+
275
+ # Show SysConfig-specific message only when running from CCS
276
+ if self.sysconfig:
277
+ error_message += """| |
278
+ | Set the serial number in SysConfig Memory Map section (Serial Number |
279
+ | field) |
280
+ | |
281
+ +==============================================================================+
282
+ """
283
+ else:
284
+ error_message += """| |
285
+ | Use the -param1 argument to specify the serial number. |
286
+ | |
287
+ +==============================================================================+
288
+ """
289
+ DETECT_FLASH_LOGGER.error(error_message)
290
+
291
+ def _print_result(self):
292
+ """
293
+ Print the detection result in a formatted box.
294
+ At this point, flash detection has succeeded and flash_type is valid.
295
+ """
296
+ if self.result is None:
297
+ return
298
+
299
+ flash_type_display = self.result["flash_type"]
300
+ flash_size_display = (
301
+ f"{self.result['flash_size_mb']}MB"
302
+ if self.result["flash_size_mb"]
303
+ else "N/A"
304
+ )
305
+
306
+ result_message = f"""
307
+ +==============================================================================+
308
+ | FLASH DETECTION RESULT |
309
+ +==============================================================================+
310
+ | |
311
+ | Flash Type: {flash_type_display:<63}|
312
+ | Flash Size: {flash_size_display:<63}|
313
+ | |
314
+ +==============================================================================+
315
+ """
316
+ DETECT_FLASH_LOGGER.info(result_message)
@@ -0,0 +1,264 @@
1
+ import logging
2
+ import pathlib
3
+
4
+ from communicator_core import (
5
+ BinaryDownloader,
6
+ DeviceLifeCycleNum,
7
+ DSSMStatus,
8
+ CC35XXE,
9
+ )
10
+
11
+ try:
12
+ from report import EnterRmaReportGeneratorCC35XXE, EnterRmaReportGeneratorCC35XX
13
+ from utility import ProgrammerUtility, TI_PROGRAMMER_CC35XX, TI_PROGRAMMER_CC35XXE, get_lifecycle_state_reg_class
14
+ except ImportError:
15
+ from .report import EnterRmaReportGeneratorCC35XXE, EnterRmaReportGeneratorCC35XX
16
+ from .utility import ProgrammerUtility, TI_PROGRAMMER_CC35XX, TI_PROGRAMMER_CC35XXE, get_lifecycle_state_reg_class
17
+
18
+ # uncomment for debug communicator code without build pakage communicator-core for every change
19
+ # if 'communicator' in sys.modules.keys():
20
+ # from communicator.communicator_core.core.cc35xx_config_ap import DeviceLifeCycleNum, DSSMStatus, LifeCycleStateReg
21
+ # from communicator.communicator_core.core.binary_downloader import BinaryDownloader
22
+
23
+ PROGRAMMER_RMA_LOGGER = logging.getLogger("enter_rma")
24
+
25
+
26
+ class EnterRma:
27
+ SIMULATION = "DEMO"
28
+ XDS110 = "XDS110"
29
+
30
+ def __init__(
31
+ self,
32
+ interface_type,
33
+ serial_number,
34
+ rma_action_req_path,
35
+ programmer_artifacts_path,
36
+ fib_artifacts_path,
37
+ device_type,
38
+ report_file_path=None,
39
+ reset_on_timeout=True,
40
+ path_to_trm=None,
41
+ wait_timeout=1,
42
+ write_timeout=0,
43
+ wait_for_resp=True,
44
+ verbose=False,
45
+ tclk_delay=4,
46
+ chunk_size=1085,
47
+ ):
48
+ self.rma_action_req_path = rma_action_req_path
49
+ self.device_type = device_type
50
+
51
+ # Initialize the appropriate LifeCycleStateReg class based on device type
52
+ self._lifecycle_reg_class = get_lifecycle_state_reg_class(self.device_type)
53
+ self.prog_utility = ProgrammerUtility(
54
+ programmer_artifacts_path, fib_artifacts_path
55
+ )
56
+
57
+ PATH_TI_RMA_CC35XX = (
58
+ pathlib.Path(self.prog_utility.get_tbl_dir_path()) / TI_PROGRAMMER_CC35XX
59
+ )
60
+ PATH_TI_RMA_CC35XXE = (
61
+ pathlib.Path(self.prog_utility.get_tbl_dir_path()) / TI_PROGRAMMER_CC35XXE
62
+ )
63
+ self.path_to_trm = path_to_trm
64
+ if self.path_to_trm is None:
65
+ self.path_to_trm = (
66
+ PATH_TI_RMA_CC35XXE
67
+ if self.device_type == CC35XXE
68
+ else PATH_TI_RMA_CC35XX
69
+ )
70
+
71
+ self.report_file_path = (
72
+ report_file_path
73
+ if report_file_path
74
+ else (
75
+ pathlib.Path(self.rma_action_req_path).parent / "enter_rma_report.txt"
76
+ )
77
+ )
78
+ self.reset_on_timeout = reset_on_timeout
79
+ self.interface_type = interface_type
80
+ self.serial_number = serial_number
81
+ self.wait_timeout = wait_timeout
82
+ self.write_timeout = write_timeout
83
+ self.wait_for_resp = wait_for_resp
84
+ self.tclk_delay = tclk_delay
85
+ self.chunk_size = chunk_size
86
+
87
+ self.verbose = verbose
88
+ self.log_level = logging.INFO if verbose else logging.DEBUG
89
+ self.error_message = ""
90
+
91
+ if self.device_type == CC35XXE:
92
+ self.report_generator = EnterRmaReportGeneratorCC35XXE(
93
+ programmer_artifacts_path=programmer_artifacts_path,
94
+ fib_artifacts_path=fib_artifacts_path,
95
+ report_file_path=self.report_file_path,
96
+ verbose=self.verbose,
97
+ )
98
+ else:
99
+ self.report_generator = EnterRmaReportGeneratorCC35XX(
100
+ programmer_artifacts_path=programmer_artifacts_path,
101
+ fib_artifacts_path=fib_artifacts_path,
102
+ report_file_path=self.report_file_path,
103
+ verbose=self.verbose,
104
+ )
105
+
106
+ def enter_rma(self):
107
+ if self.device_type is None:
108
+ PROGRAMMER_RMA_LOGGER.error("Failed to get device type")
109
+ self.error_message = "Failed to get device type"
110
+ return False
111
+ #################################################
112
+ ## Step 0 ##
113
+ ## check that all files exist ##
114
+ #################################################
115
+
116
+ self.path_to_trm = self.prog_utility.fix_path(self.path_to_trm)
117
+ res = self.prog_utility.file_path_exist(self.path_to_trm, "TI RMA")
118
+ if res is not None:
119
+ self.error_message = res
120
+ PROGRAMMER_RMA_LOGGER.error(self.error_message)
121
+ return False
122
+
123
+ res = self.prog_utility.file_path_exist(self.rma_action_req_path, "rma_request")
124
+ if res is not None:
125
+ self.error_message = res
126
+ PROGRAMMER_RMA_LOGGER.error(self.error_message)
127
+ return False
128
+
129
+ #################################################
130
+ ## Step 1 ##
131
+ ## reset device and download TI Bootloader ##
132
+ #################################################
133
+
134
+ tbl_download = BinaryDownloader(
135
+ bin_file=self.path_to_trm,
136
+ interface_type=self.interface_type,
137
+ serial_number=self.serial_number,
138
+ wait_timeout=self.wait_timeout,
139
+ write_timeout=self.write_timeout,
140
+ verbose=self.verbose,
141
+ tclk_delay=self.tclk_delay,
142
+ chunk_size=self.chunk_size,
143
+ )
144
+
145
+ # reset device
146
+ tbl_download.device.reset_device()
147
+
148
+ # Download TI bootloader
149
+ tbl_download.daemon = True
150
+ tbl_download.start()
151
+
152
+ while tbl_download.is_alive():
153
+ tbl_download.join(0.1)
154
+
155
+ error_code, error_msg = tbl_download.download_status
156
+
157
+ if error_code > 0:
158
+ PROGRAMMER_RMA_LOGGER.log(self.log_level, "Successfully loaded binary")
159
+ else:
160
+ PROGRAMMER_RMA_LOGGER.log(
161
+ self.log_level,
162
+ f"Fail load binary with error code: {error_code}\nError message: {error_msg}",
163
+ )
164
+ self.error_message = f"Failed loading 'TI RMA' image"
165
+ return False
166
+
167
+ #################################################
168
+ ## Step 2 ##
169
+ ## read CFGAP and check life-cycle/dssm status ##
170
+ #################################################
171
+
172
+ if self.interface_type != self.SIMULATION:
173
+ # Read cfgap - use device-specific register class
174
+ life_cycle_state_reg = self._lifecycle_reg_class(
175
+ interface=self.interface_type,
176
+ serial_number=self.serial_number,
177
+ verbose=self.verbose,
178
+ )
179
+ life_cycle_state_reg.read_reg()
180
+ life_cycle = life_cycle_state_reg.life_cycle_sw_coded
181
+ dssm_status = life_cycle_state_reg.dssm_status
182
+ life_cycle_state_reg.disconnect()
183
+
184
+ # Check if life cycle is one of allowed_life_cycle
185
+ allowed_life_cycle = [DeviceLifeCycleNum.DEPLOYED]
186
+
187
+ if life_cycle not in allowed_life_cycle:
188
+ self.error_message = f"Life cycle is not valid"
189
+ PROGRAMMER_RMA_LOGGER.log(
190
+ self.log_level,
191
+ f"Process is stopped. Life cycle {DeviceLifeCycleNum(life_cycle).name} is not valid.",
192
+ )
193
+ return False
194
+
195
+ # Check if dssm status is DSSM_READY
196
+ if not dssm_status == DSSMStatus.DSSM_READY:
197
+ PROGRAMMER_RMA_LOGGER.log(
198
+ self.log_level, f"Device is not ready for rma"
199
+ )
200
+ self.error_message = f"Device is not ready for rma"
201
+ return False
202
+
203
+ #################################################
204
+ ## Step 3 ##
205
+ ## download rma action req ##
206
+ #################################################
207
+
208
+ rma_req_downloader = BinaryDownloader(
209
+ bin_file=self.rma_action_req_path,
210
+ interface_type=self.interface_type,
211
+ serial_number=self.serial_number,
212
+ wait_timeout=self.wait_timeout,
213
+ write_timeout=self.write_timeout,
214
+ wait_for_resp=self.wait_for_resp,
215
+ verbose=self.verbose,
216
+ expected_resp_size=self.report_generator.get_report_struct_size(),
217
+ tclk_delay=self.tclk_delay,
218
+ chunk_size=self.chunk_size,
219
+ )
220
+ rma_req_downloader.daemon = True
221
+ rma_req_downloader.start()
222
+
223
+ while rma_req_downloader.is_alive():
224
+ rma_req_downloader.join(0.1)
225
+
226
+ error_code, error_msg = rma_req_downloader.download_status
227
+
228
+ if error_code > 0:
229
+ PROGRAMMER_RMA_LOGGER.log(self.log_level, "Successfully loaded binary")
230
+ else:
231
+ PROGRAMMER_RMA_LOGGER.log(
232
+ self.log_level,
233
+ f"Fail load binary with error code: {error_code}\nError message: {error_msg}",
234
+ )
235
+ self.error_message = f"Failed loading 'Rma Action Request'"
236
+ return False
237
+
238
+ #################################################
239
+ ## Step 4 ##
240
+ ## get response and print to the user ##
241
+ #################################################
242
+
243
+ if self.wait_for_resp:
244
+
245
+ # get response
246
+ report_content_raw = rma_req_downloader.resp
247
+
248
+ # generate report
249
+ if not self.report_generator.generate_report(report_content_raw):
250
+ self.error_message = self.report_generator.error_message
251
+ return False
252
+
253
+ # check if rma entry done
254
+ if (
255
+ self.report_generator.report_container.enter_rma_response_content.rma_entry_done
256
+ ):
257
+ PROGRAMMER_RMA_LOGGER.log(
258
+ self.log_level, f"Successfully enter rma mode"
259
+ )
260
+ else:
261
+ PROGRAMMER_RMA_LOGGER.log(self.log_level, f"failed to enter rma mode")
262
+ return False
263
+
264
+ return True