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,22 @@
|
|
|
1
|
+
from .constants import CFGAP_OFFSET, REPORT_TYPE, WAIT_FOR_ERASE
|
|
2
|
+
from .adapters import BaseAdapter, UDID
|
|
3
|
+
from .activate_device import ActivateDevice
|
|
4
|
+
from .utility import *
|
|
5
|
+
from .debug_device import DebugDevice
|
|
6
|
+
from .program_device import ProgramDevice
|
|
7
|
+
from .full_flash_erase import FullFlashErase
|
|
8
|
+
from .query_device import QueryDevice
|
|
9
|
+
from .enter_rma import EnterRma
|
|
10
|
+
from .factory_program_device import FactoryProgramDevice
|
|
11
|
+
from .partial_fuse_programming import PartialFuseProgramming
|
|
12
|
+
from .memory_validation_test import MemoryValidationTest
|
|
13
|
+
from .detect_flash_type import DetectFlashType
|
|
14
|
+
from .get_fuse_data import GetFuseData
|
|
15
|
+
from .report import (
|
|
16
|
+
ProgrammingReportGeneratorCC35XX,
|
|
17
|
+
ProgrammingReportGeneratorCC35XXE,
|
|
18
|
+
QueryReportGeneratorCC35XX,
|
|
19
|
+
QueryReportGeneratorCC35XXE,
|
|
20
|
+
EnterRmaReportGeneratorCC35XX,
|
|
21
|
+
EnterRmaReportGeneratorCC35XXE,
|
|
22
|
+
)
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
import pathlib
|
|
3
|
+
|
|
4
|
+
from communicator_core import (
|
|
5
|
+
BinaryDownloader,
|
|
6
|
+
DeviceLifeCycleNum,
|
|
7
|
+
DSSMStatus,
|
|
8
|
+
CC35XXE,
|
|
9
|
+
CC37XXR,
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
try:
|
|
13
|
+
from report import (
|
|
14
|
+
ProgrammingReportGeneratorCC35XXE,
|
|
15
|
+
ProgrammingReportGeneratorCC35XX,
|
|
16
|
+
)
|
|
17
|
+
from utility import ProgrammerUtility, get_lifecycle_state_reg_class
|
|
18
|
+
except ImportError:
|
|
19
|
+
from .report import (
|
|
20
|
+
ProgrammingReportGeneratorCC35XXE,
|
|
21
|
+
ProgrammingReportGeneratorCC35XX,
|
|
22
|
+
)
|
|
23
|
+
from .utility import ProgrammerUtility, get_lifecycle_state_reg_class
|
|
24
|
+
|
|
25
|
+
# uncomment for debug communicator code without build package communicator_core for every change
|
|
26
|
+
# if 'communicator' in sys.modules.keys():
|
|
27
|
+
# from communicator.communicator_core.core.cc35xx_config_ap import DeviceLifeCycleNum, DSSMStatus, LifeCycleStateReg
|
|
28
|
+
# from communicator.communicator_core.core.binary_downloader import BinaryDownloader
|
|
29
|
+
|
|
30
|
+
PROGRAMMER_ACTIVATE_LOGGER = logging.getLogger("activate")
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
# note: 0x4110295c - hw life cycle address
|
|
34
|
+
class ActivateDevice:
|
|
35
|
+
SIMULATION = "DEMO"
|
|
36
|
+
XDS110 = "XDS110"
|
|
37
|
+
|
|
38
|
+
def __init__(
|
|
39
|
+
self,
|
|
40
|
+
interface_type,
|
|
41
|
+
serial_number,
|
|
42
|
+
prog_inst_image_path,
|
|
43
|
+
programmer_artifacts_path,
|
|
44
|
+
fib_artifacts_path,
|
|
45
|
+
device_type,
|
|
46
|
+
report_file_path=None,
|
|
47
|
+
reset_on_timeout=True,
|
|
48
|
+
path_to_tac=None,
|
|
49
|
+
wait_timeout=2,
|
|
50
|
+
write_timeout=0,
|
|
51
|
+
wait_for_resp=True,
|
|
52
|
+
verbose=False,
|
|
53
|
+
tclk_delay=4,
|
|
54
|
+
chunk_size=1085,
|
|
55
|
+
jlink_speed_khz=None,
|
|
56
|
+
):
|
|
57
|
+
self.prog_utility = ProgrammerUtility(
|
|
58
|
+
programmer_artifacts_path, fib_artifacts_path
|
|
59
|
+
)
|
|
60
|
+
self.prog_inst_image_path = prog_inst_image_path
|
|
61
|
+
self.device_type = device_type
|
|
62
|
+
|
|
63
|
+
# Initialize the appropriate LifeCycleStateReg class based on device type
|
|
64
|
+
self._lifecycle_reg_class = get_lifecycle_state_reg_class(self.device_type)
|
|
65
|
+
self.path_to_tac = path_to_tac
|
|
66
|
+
if self.path_to_tac is None:
|
|
67
|
+
self.path_to_tac = self.prog_utility.get_default_activator(self.device_type)
|
|
68
|
+
|
|
69
|
+
self.report_file_path = (
|
|
70
|
+
report_file_path
|
|
71
|
+
if report_file_path
|
|
72
|
+
else (
|
|
73
|
+
pathlib.Path(self.prog_inst_image_path).parent / "activation_report.txt"
|
|
74
|
+
)
|
|
75
|
+
)
|
|
76
|
+
self.reset_on_timeout = reset_on_timeout
|
|
77
|
+
|
|
78
|
+
self.interface_type = interface_type
|
|
79
|
+
self.serial_number = serial_number
|
|
80
|
+
self.wait_timeout = wait_timeout
|
|
81
|
+
self.write_timeout = write_timeout
|
|
82
|
+
self.wait_for_resp = wait_for_resp
|
|
83
|
+
|
|
84
|
+
self.tclk_delay = tclk_delay
|
|
85
|
+
self.chunk_size = chunk_size
|
|
86
|
+
self.jlink_speed_khz = jlink_speed_khz
|
|
87
|
+
|
|
88
|
+
self.verbose = verbose
|
|
89
|
+
self.log_level = logging.INFO if verbose else logging.DEBUG
|
|
90
|
+
|
|
91
|
+
self.error_message = ""
|
|
92
|
+
|
|
93
|
+
# TODO: temporary - CC37XXR uses CC35XXE report generator until CC37XXR specific generators are available
|
|
94
|
+
if self.device_type in [CC35XXE, CC37XXR]:
|
|
95
|
+
self.report_generator = ProgrammingReportGeneratorCC35XXE(
|
|
96
|
+
programmer_artifacts_path=programmer_artifacts_path,
|
|
97
|
+
fib_artifacts_path=fib_artifacts_path,
|
|
98
|
+
report_file_path=self.report_file_path,
|
|
99
|
+
verbose=self.verbose,
|
|
100
|
+
)
|
|
101
|
+
else:
|
|
102
|
+
self.report_generator = ProgrammingReportGeneratorCC35XX(
|
|
103
|
+
programmer_artifacts_path=programmer_artifacts_path,
|
|
104
|
+
fib_artifacts_path=fib_artifacts_path,
|
|
105
|
+
report_file_path=self.report_file_path,
|
|
106
|
+
verbose=self.verbose,
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
def activate(self):
|
|
110
|
+
|
|
111
|
+
#################################################
|
|
112
|
+
## Step 0 ##
|
|
113
|
+
## check that all files exist ##
|
|
114
|
+
#################################################
|
|
115
|
+
|
|
116
|
+
self.path_to_tac = self.prog_utility.fix_path(self.path_to_tac)
|
|
117
|
+
res = self.prog_utility.file_path_exist(self.path_to_tac, "TI Activation")
|
|
118
|
+
if res is not None:
|
|
119
|
+
self.error_message = res
|
|
120
|
+
PROGRAMMER_ACTIVATE_LOGGER.error(self.error_message)
|
|
121
|
+
return False
|
|
122
|
+
#################################################
|
|
123
|
+
## Step 1 ##
|
|
124
|
+
## reset device and download TI Bootloader ##
|
|
125
|
+
#################################################
|
|
126
|
+
|
|
127
|
+
tbl_download = BinaryDownloader(
|
|
128
|
+
bin_file=self.path_to_tac,
|
|
129
|
+
interface_type=self.interface_type,
|
|
130
|
+
serial_number=self.serial_number,
|
|
131
|
+
wait_timeout=self.wait_timeout,
|
|
132
|
+
write_timeout=self.write_timeout,
|
|
133
|
+
verbose=self.verbose,
|
|
134
|
+
tclk_delay=self.tclk_delay,
|
|
135
|
+
chunk_size=self.chunk_size,
|
|
136
|
+
jlink_speed_khz=self.jlink_speed_khz,
|
|
137
|
+
)
|
|
138
|
+
|
|
139
|
+
# reset device
|
|
140
|
+
tbl_download.device.reset_device()
|
|
141
|
+
|
|
142
|
+
# Download TI bootloader
|
|
143
|
+
tbl_download.daemon = True
|
|
144
|
+
tbl_download.start()
|
|
145
|
+
|
|
146
|
+
while tbl_download.is_alive():
|
|
147
|
+
tbl_download.join(0.1)
|
|
148
|
+
|
|
149
|
+
error_code, error_msg = tbl_download.download_status
|
|
150
|
+
|
|
151
|
+
if error_code > 0:
|
|
152
|
+
PROGRAMMER_ACTIVATE_LOGGER.log(self.log_level, "Successfully loaded binary")
|
|
153
|
+
else:
|
|
154
|
+
self.error_message = f"Failed loading 'TI Activator' image"
|
|
155
|
+
PROGRAMMER_ACTIVATE_LOGGER.error(
|
|
156
|
+
f"Fail load binary with error code: {error_code}\nError message: {error_msg}"
|
|
157
|
+
)
|
|
158
|
+
return False
|
|
159
|
+
|
|
160
|
+
#################################################
|
|
161
|
+
## Step 2 ##
|
|
162
|
+
## read CFGAP and check life-cycle/DSSM status ##
|
|
163
|
+
#################################################
|
|
164
|
+
|
|
165
|
+
if self.interface_type != self.SIMULATION:
|
|
166
|
+
# Read cfgap - use device-specific register class
|
|
167
|
+
life_cycle_state_reg = self._lifecycle_reg_class(
|
|
168
|
+
interface=self.interface_type,
|
|
169
|
+
serial_number=self.serial_number,
|
|
170
|
+
verbose=self.verbose,
|
|
171
|
+
)
|
|
172
|
+
life_cycle_state_reg.read_reg()
|
|
173
|
+
life_cycle = life_cycle_state_reg.life_cycle_sw_coded
|
|
174
|
+
dssm_status = life_cycle_state_reg.dssm_status
|
|
175
|
+
life_cycle_state_reg.disconnect()
|
|
176
|
+
|
|
177
|
+
# Check if life cycle is one of allowed_life_cycle
|
|
178
|
+
allowed_life_cycle = [
|
|
179
|
+
DeviceLifeCycleNum.OPERATIONAL,
|
|
180
|
+
DeviceLifeCycleNum.RMA_HW_ANALYSIS,
|
|
181
|
+
DeviceLifeCycleNum.RMA_FAILIURE_ANALYSIS,
|
|
182
|
+
]
|
|
183
|
+
if life_cycle not in allowed_life_cycle:
|
|
184
|
+
self.error_message = "Life cycle is not valid"
|
|
185
|
+
PROGRAMMER_ACTIVATE_LOGGER.error(
|
|
186
|
+
f"Process is stopped. Life cycle {DeviceLifeCycleNum(life_cycle).name} is not valid."
|
|
187
|
+
)
|
|
188
|
+
return False
|
|
189
|
+
|
|
190
|
+
# Check if dssm status is DSSM_READY
|
|
191
|
+
if not dssm_status == DSSMStatus.DSSM_READY:
|
|
192
|
+
self.error_message = f"Device is not ready for activation"
|
|
193
|
+
PROGRAMMER_ACTIVATE_LOGGER.error(self.error_message)
|
|
194
|
+
return False
|
|
195
|
+
|
|
196
|
+
#################################################
|
|
197
|
+
## Step 3 ##
|
|
198
|
+
## download programming image ##
|
|
199
|
+
#################################################
|
|
200
|
+
|
|
201
|
+
prog_inst_downloader = BinaryDownloader(
|
|
202
|
+
bin_file=self.prog_inst_image_path,
|
|
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
|
+
wait_for_resp=self.wait_for_resp,
|
|
208
|
+
verbose=self.verbose,
|
|
209
|
+
expected_resp_size=self.report_generator.get_report_struct_size(),
|
|
210
|
+
tclk_delay=self.tclk_delay,
|
|
211
|
+
chunk_size=self.chunk_size,
|
|
212
|
+
jlink_speed_khz=self.jlink_speed_khz,
|
|
213
|
+
)
|
|
214
|
+
prog_inst_downloader.daemon = True
|
|
215
|
+
prog_inst_downloader.start()
|
|
216
|
+
|
|
217
|
+
while prog_inst_downloader.is_alive():
|
|
218
|
+
prog_inst_downloader.join(0.1)
|
|
219
|
+
|
|
220
|
+
error_code, error_msg = prog_inst_downloader.download_status
|
|
221
|
+
|
|
222
|
+
if error_code > 0:
|
|
223
|
+
PROGRAMMER_ACTIVATE_LOGGER.log(self.log_level, "Successfully loaded binary")
|
|
224
|
+
else:
|
|
225
|
+
self.error_message = f"Failed loading 'Programming Instruction' image"
|
|
226
|
+
PROGRAMMER_ACTIVATE_LOGGER.error(
|
|
227
|
+
f"Failed loading binary with error code: {error_code}\nError message: {error_msg}"
|
|
228
|
+
)
|
|
229
|
+
return False
|
|
230
|
+
|
|
231
|
+
#################################################
|
|
232
|
+
## Step 4 ##
|
|
233
|
+
## get response and print to the user ##
|
|
234
|
+
#################################################
|
|
235
|
+
|
|
236
|
+
if self.wait_for_resp:
|
|
237
|
+
|
|
238
|
+
# get response
|
|
239
|
+
report_content_raw = prog_inst_downloader.resp
|
|
240
|
+
|
|
241
|
+
# generate report
|
|
242
|
+
if not self.report_generator.generate_report(report_content_raw):
|
|
243
|
+
self.error_message = self.report_generator.error_message
|
|
244
|
+
return False
|
|
245
|
+
|
|
246
|
+
return True
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
from construct import Adapter
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class BaseAdapter(Adapter):
|
|
5
|
+
def _reverse_endian_obj(self, obj):
|
|
6
|
+
little_hex = bytearray.fromhex(obj)
|
|
7
|
+
little_hex.reverse()
|
|
8
|
+
str_little = "".join(format(x, "02x") for x in little_hex)
|
|
9
|
+
|
|
10
|
+
return str_little
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class UDID(BaseAdapter):
|
|
14
|
+
def _decode(self, obj, ctx, path):
|
|
15
|
+
str_little = "".join(map(lambda x: "%02x" % x, obj))
|
|
16
|
+
str_big = self._reverse_endian_obj(str_little)
|
|
17
|
+
return f"{str_big[:4]}-{str_big[4:8]}-{str_big[8:12]}-{str_big[12:16]}"
|
|
18
|
+
|
|
19
|
+
def _encode(self, obj, context, path):
|
|
20
|
+
obj = obj.replace("-", "")
|
|
21
|
+
str_little = self._reverse_endian_obj(obj)
|
|
22
|
+
obj_list = [str_little[i : i + 2] for i in range(0, len(str_little), 2)]
|
|
23
|
+
return list(map(lambda x: int(x, 16), obj_list))
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import enum
|
|
2
|
+
from construct import Byte, Enum, Int8ul
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
# CFGAP
|
|
6
|
+
class CFGAP_OFFSET(enum.IntEnum):
|
|
7
|
+
device_id_reg = 0x00
|
|
8
|
+
device_ext_info_reg = 0x04
|
|
9
|
+
debug_ss_version_reg = 0x08
|
|
10
|
+
sys_reg = 0x0C
|
|
11
|
+
device_info_reg = 0x10
|
|
12
|
+
life_cycle_state_reg = 0x14
|
|
13
|
+
dft_en_reg = 0x18
|
|
14
|
+
reset_req_reg = 0x1C
|
|
15
|
+
unique_device_id_reg_low = 0x28
|
|
16
|
+
unique_device_id_reg_high = 0x2C
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
# report type
|
|
20
|
+
class REPORT_TYPE(enum.IntEnum):
|
|
21
|
+
programming_pg1 = 0x01
|
|
22
|
+
query_pg1 = 0x02
|
|
23
|
+
debug_pg1 = 0x03
|
|
24
|
+
enter_rma_pg1 = 0x04
|
|
25
|
+
programming_pg2 = 0x16
|
|
26
|
+
query_pg2 = 0x17
|
|
27
|
+
debug_pg2 = 0x18
|
|
28
|
+
enter_rma_pg2 = 0x19
|
|
29
|
+
memory_validation_pg2 = 0x20
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
# flash image header
|
|
33
|
+
FLASH_IMAGE_HEADER = 12
|
|
34
|
+
FLASH_DISCOVERY_CONF_SIZE_CC35XX = 844
|
|
35
|
+
FLASH_DISCOVERY_CONF_SIZE_CC35XXE = 880
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
# flash status for erase flow
|
|
39
|
+
class FLASH_STATUS(enum.IntEnum):
|
|
40
|
+
ready_for_request = 0x00
|
|
41
|
+
ready_for_header = 0x01
|
|
42
|
+
erase_in_progress = 0x02
|
|
43
|
+
ready_for_content = 0x03
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
# wait for erase - max time
|
|
47
|
+
WAIT_FOR_ERASE = 110
|
|
48
|
+
|
|
49
|
+
# Timeout for polling flash detection (in seconds)
|
|
50
|
+
TIMEOUT_POLLING_FLASH_DETECT = 5
|
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
import pathlib
|
|
3
|
+
import time
|
|
4
|
+
|
|
5
|
+
from communicator_core import (
|
|
6
|
+
BinaryDownloader,
|
|
7
|
+
DeviceLifeCycleNum,
|
|
8
|
+
DSSMStatus,
|
|
9
|
+
CC35XXE,
|
|
10
|
+
CC37XXR,
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
try:
|
|
14
|
+
from utility import (
|
|
15
|
+
ProgrammerUtility,
|
|
16
|
+
TI_DEBUG_CC35XXE,
|
|
17
|
+
TI_DEBUG_CC35XX,
|
|
18
|
+
TI_DEBUG_CC37XXR,
|
|
19
|
+
get_lifecycle_state_reg_class,
|
|
20
|
+
)
|
|
21
|
+
except ImportError:
|
|
22
|
+
from .utility import (
|
|
23
|
+
ProgrammerUtility,
|
|
24
|
+
TI_DEBUG_CC35XXE,
|
|
25
|
+
TI_DEBUG_CC35XX,
|
|
26
|
+
TI_DEBUG_CC37XXR,
|
|
27
|
+
get_lifecycle_state_reg_class,
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
# uncomment for debug communicator code without build pakage 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
|
+
PROGRAMMER_DEBUG_LOGGER = logging.getLogger("debug")
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class DebugDevice:
|
|
39
|
+
SIMULATION = "DEMO"
|
|
40
|
+
XDS110 = "XDS110"
|
|
41
|
+
|
|
42
|
+
def __init__(
|
|
43
|
+
self,
|
|
44
|
+
interface_type,
|
|
45
|
+
serial_number,
|
|
46
|
+
debug_action_req_path,
|
|
47
|
+
programmer_artifacts_path,
|
|
48
|
+
fib_artifacts_path,
|
|
49
|
+
device_type,
|
|
50
|
+
report_file_path=None,
|
|
51
|
+
reset_on_timeout=True,
|
|
52
|
+
path_to_tdb=None,
|
|
53
|
+
wait_timeout=1,
|
|
54
|
+
write_timeout=0,
|
|
55
|
+
wait_for_resp=False,
|
|
56
|
+
execution_busy_timeout=10,
|
|
57
|
+
tclk_delay=4,
|
|
58
|
+
chunk_size=1085,
|
|
59
|
+
verbose=False,
|
|
60
|
+
):
|
|
61
|
+
self.debug_action_req_path = debug_action_req_path
|
|
62
|
+
self.device_type = device_type
|
|
63
|
+
|
|
64
|
+
# Initialize the appropriate LifeCycleStateReg class based on device type
|
|
65
|
+
self._lifecycle_reg_class = get_lifecycle_state_reg_class(self.device_type)
|
|
66
|
+
|
|
67
|
+
self.prog_utility = ProgrammerUtility(
|
|
68
|
+
programmer_artifacts_path, fib_artifacts_path
|
|
69
|
+
)
|
|
70
|
+
PATH_TI_DEBUG_CC35XX = (
|
|
71
|
+
pathlib.Path(self.prog_utility.get_tbl_dir_path()) / TI_DEBUG_CC35XX
|
|
72
|
+
)
|
|
73
|
+
PATH_TI_DEBUG_CC35XXE = (
|
|
74
|
+
pathlib.Path(self.prog_utility.get_tbl_dir_path()) / TI_DEBUG_CC35XXE
|
|
75
|
+
)
|
|
76
|
+
PATH_TI_DEBUG_CC37XXR = (
|
|
77
|
+
pathlib.Path(self.prog_utility.get_tbl_dir_path()) / TI_DEBUG_CC37XXR
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
self.path_to_tdb = path_to_tdb
|
|
81
|
+
|
|
82
|
+
if self.path_to_tdb is None:
|
|
83
|
+
if self.device_type == CC35XXE:
|
|
84
|
+
self.path_to_tdb = PATH_TI_DEBUG_CC35XXE
|
|
85
|
+
elif self.device_type == CC37XXR:
|
|
86
|
+
self.path_to_tdb = PATH_TI_DEBUG_CC37XXR
|
|
87
|
+
else:
|
|
88
|
+
self.path_to_tdb = PATH_TI_DEBUG_CC35XX
|
|
89
|
+
|
|
90
|
+
self.reset_on_timeout = reset_on_timeout
|
|
91
|
+
|
|
92
|
+
self.interface_type = interface_type
|
|
93
|
+
self.serial_number = serial_number
|
|
94
|
+
self.wait_timeout = wait_timeout
|
|
95
|
+
self.write_timeout = write_timeout
|
|
96
|
+
self.wait_for_resp = wait_for_resp
|
|
97
|
+
# wait until device execution done
|
|
98
|
+
self.execution_busy_timeout = execution_busy_timeout
|
|
99
|
+
self.tclk_delay = tclk_delay
|
|
100
|
+
self.chunk_size = chunk_size
|
|
101
|
+
|
|
102
|
+
self.verbose = verbose
|
|
103
|
+
self.log_level = logging.INFO if verbose else logging.DEBUG
|
|
104
|
+
self.error_message = ""
|
|
105
|
+
|
|
106
|
+
def debug(self):
|
|
107
|
+
if self.device_type is None:
|
|
108
|
+
PROGRAMMER_DEBUG_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_tdb = self.prog_utility.fix_path(self.path_to_tdb)
|
|
117
|
+
|
|
118
|
+
res = self.prog_utility.file_path_exist(self.path_to_tdb, "TI Debug")
|
|
119
|
+
if res is not None:
|
|
120
|
+
self.error_message = res
|
|
121
|
+
PROGRAMMER_DEBUG_LOGGER.error(self.error_message)
|
|
122
|
+
return False
|
|
123
|
+
|
|
124
|
+
self.debug_action_req_path = self.prog_utility.fix_path(
|
|
125
|
+
self.debug_action_req_path
|
|
126
|
+
)
|
|
127
|
+
|
|
128
|
+
res = self.prog_utility.file_path_exist(
|
|
129
|
+
self.debug_action_req_path, "debug_request"
|
|
130
|
+
)
|
|
131
|
+
if res is not None:
|
|
132
|
+
self.error_message = res
|
|
133
|
+
PROGRAMMER_DEBUG_LOGGER.error(self.error_message)
|
|
134
|
+
return False
|
|
135
|
+
|
|
136
|
+
#################################################
|
|
137
|
+
## Step 1 ##
|
|
138
|
+
## reset device and download TI Bootloader ##
|
|
139
|
+
#################################################
|
|
140
|
+
|
|
141
|
+
tbl_download = BinaryDownloader(
|
|
142
|
+
bin_file=self.path_to_tdb,
|
|
143
|
+
interface_type=self.interface_type,
|
|
144
|
+
serial_number=self.serial_number,
|
|
145
|
+
wait_timeout=self.wait_timeout,
|
|
146
|
+
write_timeout=self.write_timeout,
|
|
147
|
+
tclk_delay=self.tclk_delay,
|
|
148
|
+
chunk_size=self.chunk_size,
|
|
149
|
+
verbose=self.verbose,
|
|
150
|
+
)
|
|
151
|
+
|
|
152
|
+
# reset device
|
|
153
|
+
tbl_download.device.reset_device()
|
|
154
|
+
|
|
155
|
+
# Download TI bootloader
|
|
156
|
+
tbl_download.daemon = True
|
|
157
|
+
tbl_download.start()
|
|
158
|
+
|
|
159
|
+
while tbl_download.is_alive():
|
|
160
|
+
tbl_download.join(0.1)
|
|
161
|
+
|
|
162
|
+
error_code, error_msg = tbl_download.download_status
|
|
163
|
+
|
|
164
|
+
if error_code > 0:
|
|
165
|
+
PROGRAMMER_DEBUG_LOGGER.log(self.log_level, "Successfully loaded binary")
|
|
166
|
+
else:
|
|
167
|
+
PROGRAMMER_DEBUG_LOGGER.log(
|
|
168
|
+
self.log_level,
|
|
169
|
+
f"Fail load binary with error code: {error_code}\nError message: {error_msg}",
|
|
170
|
+
)
|
|
171
|
+
self.error_message = f"Failed loading 'TI Debug' image"
|
|
172
|
+
return False
|
|
173
|
+
|
|
174
|
+
#################################################
|
|
175
|
+
## Step 2 ##
|
|
176
|
+
## read CFGAP and check life-cycle/dssm status ##
|
|
177
|
+
#################################################
|
|
178
|
+
|
|
179
|
+
if self.interface_type != self.SIMULATION:
|
|
180
|
+
# Read cfgap - use device-specific register class
|
|
181
|
+
life_cycle_state_reg = self._lifecycle_reg_class(
|
|
182
|
+
interface=self.interface_type,
|
|
183
|
+
serial_number=self.serial_number,
|
|
184
|
+
verbose=self.verbose,
|
|
185
|
+
)
|
|
186
|
+
life_cycle_state_reg.read_reg()
|
|
187
|
+
life_cycle = life_cycle_state_reg.life_cycle_sw_coded
|
|
188
|
+
dssm_status = life_cycle_state_reg.dssm_status
|
|
189
|
+
life_cycle_state_reg.disconnect()
|
|
190
|
+
|
|
191
|
+
# Check if life cycle is one of allowed_life_cycle
|
|
192
|
+
allowed_life_cycle = [
|
|
193
|
+
DeviceLifeCycleNum.DEPLOYED,
|
|
194
|
+
DeviceLifeCycleNum.RMA_HW_ANALYSIS,
|
|
195
|
+
DeviceLifeCycleNum.RMA_FAILIURE_ANALYSIS,
|
|
196
|
+
]
|
|
197
|
+
|
|
198
|
+
if life_cycle not in allowed_life_cycle:
|
|
199
|
+
PROGRAMMER_DEBUG_LOGGER.log(
|
|
200
|
+
self.log_level,
|
|
201
|
+
f"Process is stopped. Life cycle {DeviceLifeCycleNum(life_cycle).name} is not valid.",
|
|
202
|
+
)
|
|
203
|
+
self.error_message = f"Life cycle is not valid"
|
|
204
|
+
return False
|
|
205
|
+
|
|
206
|
+
# Check if dssm status is DSSM_READY
|
|
207
|
+
if not dssm_status == DSSMStatus.DSSM_READY:
|
|
208
|
+
PROGRAMMER_DEBUG_LOGGER.log(
|
|
209
|
+
self.log_level, f"Device is not ready for debug"
|
|
210
|
+
)
|
|
211
|
+
self.error_message = f"Device is not ready for debug"
|
|
212
|
+
return False
|
|
213
|
+
|
|
214
|
+
#################################################
|
|
215
|
+
## Step 3 ##
|
|
216
|
+
## download debug action req ##
|
|
217
|
+
#################################################
|
|
218
|
+
|
|
219
|
+
debug_req_downloader = BinaryDownloader(
|
|
220
|
+
bin_file=self.debug_action_req_path,
|
|
221
|
+
interface_type=self.interface_type,
|
|
222
|
+
serial_number=self.serial_number,
|
|
223
|
+
wait_timeout=self.wait_timeout,
|
|
224
|
+
write_timeout=self.write_timeout,
|
|
225
|
+
wait_for_resp=self.wait_for_resp,
|
|
226
|
+
tclk_delay=self.tclk_delay,
|
|
227
|
+
chunk_size=self.chunk_size,
|
|
228
|
+
verbose=self.verbose,
|
|
229
|
+
)
|
|
230
|
+
debug_req_downloader.daemon = True
|
|
231
|
+
debug_req_downloader.start()
|
|
232
|
+
|
|
233
|
+
while debug_req_downloader.is_alive():
|
|
234
|
+
debug_req_downloader.join(0.1)
|
|
235
|
+
|
|
236
|
+
error_code, error_msg = debug_req_downloader.download_status
|
|
237
|
+
|
|
238
|
+
if error_code > 0:
|
|
239
|
+
PROGRAMMER_DEBUG_LOGGER.log(self.log_level, "Successfully loaded binary")
|
|
240
|
+
else:
|
|
241
|
+
PROGRAMMER_DEBUG_LOGGER.log(
|
|
242
|
+
self.log_level,
|
|
243
|
+
f"Fail load binary with error code: {error_code}\nError message: {error_msg}",
|
|
244
|
+
)
|
|
245
|
+
self.error_message = f"Failed loading 'Debug Action Request'"
|
|
246
|
+
return False
|
|
247
|
+
|
|
248
|
+
# check execution busy
|
|
249
|
+
if self.interface_type != self.SIMULATION:
|
|
250
|
+
# Read cfgap - use device-specific register class
|
|
251
|
+
life_cycle_state_reg = self._lifecycle_reg_class(
|
|
252
|
+
interface=self.interface_type,
|
|
253
|
+
serial_number=self.serial_number,
|
|
254
|
+
verbose=False,
|
|
255
|
+
)
|
|
256
|
+
life_cycle_state_reg.read_reg()
|
|
257
|
+
execution_busy = life_cycle_state_reg.execution_busy
|
|
258
|
+
|
|
259
|
+
timeout_time = time.perf_counter() + self.execution_busy_timeout
|
|
260
|
+
timeout_occur = time.perf_counter() > timeout_time
|
|
261
|
+
# Wait until execution_busy != 1 or if timeout occure
|
|
262
|
+
while execution_busy == 1 and not timeout_occur:
|
|
263
|
+
life_cycle_state_reg.read_reg()
|
|
264
|
+
execution_busy = life_cycle_state_reg.execution_busy
|
|
265
|
+
timeout_occur = time.perf_counter() > timeout_time
|
|
266
|
+
time.sleep(0.01)
|
|
267
|
+
|
|
268
|
+
life_cycle_state_reg.disconnect()
|
|
269
|
+
if timeout_occur and execution_busy == 1:
|
|
270
|
+
PROGRAMMER_DEBUG_LOGGER.error(
|
|
271
|
+
f"Timeout occur while waiting for acknowledge from device before move to execution"
|
|
272
|
+
)
|
|
273
|
+
self.error_message = "Timeout occur while waiting for acknowledge from device before move to execution"
|
|
274
|
+
return False
|
|
275
|
+
|
|
276
|
+
PROGRAMMER_DEBUG_LOGGER.log(self.log_level, f"Successfully start debug mode")
|
|
277
|
+
|
|
278
|
+
return True
|