Skip to content

Commit 51ba57e

Browse files
Add support for external triggers.
1 parent 9a8f19e commit 51ba57e

File tree

2 files changed

+80
-43
lines changed

2 files changed

+80
-43
lines changed

main.py

Lines changed: 35 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,19 @@ def _measure_avg(ppk_api, time_s, out_file):
5858

5959

6060
def _measure_triggers(ppk_api, time_us, level_ua, count, out_file):
61-
"""Prints the average current after the trigger voltage is reached."""
61+
"""Acquire and process trigger buffers."""
6262
buffers = ppk_api.measure_triggers(time_us, level_ua, count)
63+
_process_triggers(buffers, out_file)
64+
65+
66+
def _measure_ext_triggers(ppk_api, time_us, count, out_file):
67+
"""Acquire and process external trigger buffers."""
68+
buffers = ppk_api.measure_external_triggers(time_us, count)
69+
_process_triggers(buffers, out_file)
70+
71+
72+
def _process_triggers(buffers, out_file):
73+
"""Save the buffers if necessary and print their averages."""
6374
if out_file:
6475
with open(out_file, "w", newline='') as csv_file:
6576
csv_writer = csv.writer(csv_file)
@@ -99,8 +110,6 @@ def _add_and_parse_args():
99110
help="serial number of J-Link")
100111
parser.add_argument("-a", "--average", type=float,
101112
help="print average current over time")
102-
parser.add_argument("-t", "--trigger_microamps", type=int,
103-
help="set trigger threshold in microamps")
104113
parser.add_argument("-w", "--trigger_microseconds", type=int, nargs='?', default=5850,
105114
help="set trigger window in microseconds")
106115
parser.add_argument("-n", "--trigger_count", type=int, nargs='?', default=1,
@@ -117,25 +126,29 @@ def _add_and_parse_args():
117126
help="write measurement data to file", type=str)
118127
parser.add_argument("-g", "--spike_filtering",
119128
help="enable spike filtering", action="store_true")
120-
parser.add_argument("-x", "--enable_ext_trigger",
121-
help="enable 'TRIG IN' external trigger", action="store_true")
122-
group = parser.add_mutually_exclusive_group()
123-
group.add_argument("-k", "--skip_verify",
124-
help="save time by not verifying the PPK firmware",
125-
action="store_true")
126-
group.add_argument("-f", "--force",
127-
help="program the PPK firmware if necessary",
128-
action="store_true")
129+
trig_group = parser.add_mutually_exclusive_group()
130+
trig_group.add_argument("-t", "--trigger_microamps", type=int,
131+
help="set trigger threshold in microamps")
132+
trig_group.add_argument("-x", "--enable_ext_trigger",
133+
help="enable 'TRIG IN' external trigger", action="store_true")
134+
fw_group = parser.add_mutually_exclusive_group()
135+
fw_group.add_argument("-k", "--skip_verify",
136+
help="save time by not verifying the PPK firmware",
137+
action="store_true")
138+
fw_group.add_argument("-f", "--force",
139+
help="program the PPK firmware if necessary",
140+
action="store_true")
129141
return (parser, parser.parse_args())
130142

131143

132144
def _main():
133145
"""Parses arguments for the PPK CLI."""
134146
parser, args = _add_and_parse_args()
135147

136-
if not args.trigger_microamps:
137-
if not args.average or args.enable_ext_trigger:
148+
if not args.trigger_microamps and not args.enable_ext_trigger:
149+
if not args.average:
138150
parser.print_usage()
151+
print("main.py: error: no measurement operation specified")
139152
sys.exit(-1)
140153

141154
nrfjprog_api = None
@@ -147,7 +160,8 @@ def _main():
147160

148161
if args.external_vdd:
149162
if args.external_vdd < ppk_api.VDD_SET_MIN or args.external_vdd > ppk_api.VDD_SET_MAX:
150-
print("Invalid external voltage regulator value (%d)." % args.external_vdd)
163+
parser.print_usage()
164+
print("main.py: error: invalid external voltage regulator value (%d)" % args.external_vdd)
151165
_close_and_exit(nrfjprog_api, -1)
152166
else:
153167
ppk_api.vdd_set(args.external_vdd)
@@ -166,9 +180,6 @@ def _main():
166180
if args.spike_filtering:
167181
ppk_api.enable_spike_filtering()
168182

169-
if args.enable_ext_trigger:
170-
ppk_api.enable_ext_trigger_in()
171-
172183
if args.average:
173184
_measure_avg(ppk_api, args.average, args.out_file)
174185

@@ -178,10 +189,15 @@ def _main():
178189
args.trigger_microamps,
179190
args.trigger_count,
180191
args.out_file)
192+
elif args.enable_ext_trigger:
193+
_measure_ext_triggers(ppk_api,
194+
args.trigger_microseconds,
195+
args.trigger_count,
196+
args.out_file)
181197

182198
_close_and_exit(nrfjprog_api, 0)
183199
except Exception as ex:
184-
print(ex)
200+
print("main.py: error: " + str(ex))
185201
_close_and_exit(nrfjprog_api, -1)
186202

187203

ppk/ppk.py

Lines changed: 45 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ def __init__(self, error=None):
2121

2222
class RTTCommand():
2323
"""RTT command opcodes."""
24-
TRIGGER_SET = 0x01
24+
TRIG_SET = 0x01
2525
TRIG_WINDOW_SET = 0x03
2626
TRIG_SINGLE_SET = 0x05
2727
AVERAGE_START = 0x06
@@ -109,24 +109,6 @@ def get_metadata(self):
109109
raise PPKError("Invalid operation: must connect first.")
110110
return self._metadata.copy()
111111

112-
def enable_ext_trigger_in(self):
113-
"""Enable the 'TRIG IN' external trigger."""
114-
if not self._connected:
115-
raise PPKError("Invalid operation: must connect first.")
116-
self._log("Enable 'TRIG IN' external trigger.")
117-
if not self._ext_trig_enabled:
118-
self._write_ppk_cmd([RTTCommand.EXT_TRIG_IN_TOGGLE])
119-
self._ext_trig_enabled = True
120-
121-
def disable_ext_trigger_in(self):
122-
"""Disable the 'TRIG IN' external trigger."""
123-
if not self._connected:
124-
raise PPKError("Invalid operation: must connect first.")
125-
self._log("Disable 'TRIG IN' external trigger.")
126-
if self._ext_trig_enabled:
127-
self._write_ppk_cmd([RTTCommand.EXT_TRIG_IN_TOGGLE])
128-
self._ext_trig_enabled = False
129-
130112
def enable_dut_power(self):
131113
"""Turn DUT power on."""
132114
if not self._connected:
@@ -166,7 +148,13 @@ def set_user_resistors(self, user_r1, user_r2, user_r3):
166148
self._write_ppk_cmd(cmd)
167149

168150
def enable_spike_filtering(self):
169-
"""Enable spike filtering feature."""
151+
"""Enable spike filtering feature.
152+
153+
When this is turned on, the PPK software will filter data directly
154+
after an automatic range switch. This will limit unwanted spikes
155+
due to rapid switching, but may also remove short current spikes
156+
that might be of significance.
157+
"""
170158
if not self._connected:
171159
raise PPKError("Invalid operation: must connect first.")
172160
self._log("Enabling spike filtering.")
@@ -253,13 +241,25 @@ def measure_triggers(self, window_time_us, level_ua, count=1):
253241
if not self._connected:
254242
raise PPKError("Invalid operation: must connect first.")
255243
self._log("measure_triggers(%r, %r, %r)." % (window_time_us, level_ua, count))
256-
ppk_helper = PPKDataHelper()
257244
self.set_trigger_window(window_time_us)
258245
if count == 1:
259246
self._set_single_trigger(level_ua)
260247
else:
261248
self._set_trigger(level_ua)
262-
# Each buffer includes a timestamp.
249+
return self._measure_triggers(count)
250+
251+
def measure_external_triggers(self, window_time_us, count=1):
252+
"""Wait for the 'TRIG IN' pin before capturing trigger buffers."""
253+
if not self._connected:
254+
raise PPKError("Invalid operation: must connect first.")
255+
self._log("measure_external_triggers(%r, %r)." % (window_time_us, count))
256+
self.set_trigger_window(window_time_us)
257+
self._enable_ext_trigger_in()
258+
return self._measure_triggers(count)
259+
260+
def _measure_triggers(self, count=1):
261+
""""""
262+
ppk_helper = PPKDataHelper()
263263
samples_count = count * 2
264264
while True:
265265
self._read_and_parse_ppk_data(ppk_helper)
@@ -268,7 +268,10 @@ def measure_triggers(self, window_time_us, level_ua, count=1):
268268
if samples_count <= collected_buffs:
269269
break
270270
self._log('')
271-
self._stop_trigger()
271+
if self._ext_trig_enabled:
272+
self._disable_ext_trigger_in()
273+
else:
274+
self._stop_trigger()
272275
self._flush_rtt()
273276
result = []
274277
for ts, trig_buf in ppk_helper.get_trigger_buffs(*self._resistors):
@@ -277,6 +280,24 @@ def measure_triggers(self, window_time_us, level_ua, count=1):
277280
result.append((np_avg(trig_buf), timestamped_buf))
278281
return result
279282

283+
def _enable_ext_trigger_in(self):
284+
"""Enable the 'TRIG IN' external trigger.
285+
286+
The external trigger is used in place of the normal TRIG_SET
287+
and TRIG_SINGLE_SET commands.
288+
"""
289+
self._log("Enable 'TRIG IN' external trigger.")
290+
if not self._ext_trig_enabled:
291+
self._write_ppk_cmd([RTTCommand.EXT_TRIG_IN_TOGGLE])
292+
self._ext_trig_enabled = True
293+
294+
def _disable_ext_trigger_in(self):
295+
"""Disable the 'TRIG IN' external trigger."""
296+
self._log("Disable 'TRIG IN' external trigger.")
297+
if self._ext_trig_enabled:
298+
self._write_ppk_cmd([RTTCommand.EXT_TRIG_IN_TOGGLE])
299+
self._ext_trig_enabled = False
300+
280301
def _start_average_measurement(self):
281302
"""Start generating average current measurements."""
282303
self._log("Starting average measurement.")
@@ -298,7 +319,7 @@ def _set_trigger(self, level_ua):
298319
high = (level_ua >> 16) & 0xFF
299320
mid = (level_ua >> 8) & 0xFF
300321
low = level_ua & 0xFF
301-
self._write_ppk_cmd([RTTCommand.TRIGGER_SET, high, mid, low])
322+
self._write_ppk_cmd([RTTCommand.TRIG_SET, high, mid, low])
302323

303324
def _set_single_trigger(self, level_ua):
304325
"""Set the single trigger level.

0 commit comments

Comments
 (0)