How to use streaming mode?#
Streaming allows you to run a longer capture that is not limited by your ChipWhisperer capture device’s on-board storage.
Streaming is supported by CW-Pro and CW-Husky.
The downside? The sample rate must be kept below roughly 10 MS/s (Pro) or 20 MS/s (Husky), which is well below the maximum sampling rates supported.
The streaming sampling rate limit isn’t enforced by the API: the capture is always attempted, and if the sampling rate is too high, the capture will fail.
Whether a capture succeeds or not depends on the capture size and activity from other devices on your USB bus. For example, if some other USB-based oscilloscope or logic analyzer is also triggered by the capture, you will not be able to achieve the maximum sampling rates.
Supported Capture Hardware:
❌ CW-Nano
❌ CW-Lite
✅ CW-Pro
✅ CW-Husky
Required ChipWhisperer software installation:
✅ any release
%run '../connect.ipynb'
cw.scope_logger.setLevel(cw.logging.WARNING) # turn warnings back on
The default sampling rate (29.48 MS/s) is too high for streaming so we reduce it to 7.37 MS/s. How this is done depends on your capture hardware:
if scope._is_husky:
scope.clock.adc_mul = 1
else: # Pro
scope.clock.adc_src = 'clkgen_x1'
(ChipWhisperer Scope WARNING|File ChipWhispererHuskyClock.py:703) Target clock may drop; you may need to reset your target.
Turning on streaming is very simple: just set scope.adc.stream_mode
.
Let’s capture 1 million samples:
scope.adc.stream_mode = True
scope.adc.samples = int(1e6)
If your target is running simpleserial-aes
firmware, this will run the target AES operation. For different target firmware, substitute with what’s needed to make your target “go”:
trace = cw.capture_trace(scope, target, bytearray(16), bytearray(16))
print(scope.errors)
sam_errors = False
sam_led_setting = Default
XADC errors = False
ADC errors = False
extclk error = False
trace errors = False
When you have a very long capture, you can run into timeout issues: after scope.adc.timeout
seconds, cw.capture_trace()
times out in error.
For example, 20 million samples at 7.37 MS/s is almost 3 seconds, so we need to increase scope.adc.timeout
accordingly for the capture to succeed:
scope.adc.timeout = 3
scope.adc.samples = int(20e6)
trace = cw.capture_trace(scope, target, bytearray(16), bytearray(16))
On Husky, a failed stream capture may require the notebook to be restarted.
Finally, note that the stated maximum sampling rate can be exceeded if the capture is relatively short.
For example, this 150000-sample capture at 29.48 MS/s should work reliably on Husky:
if scope._is_husky:
scope.clock.adc_mul = 4
else: # Pro
scope.clock.adc_src = 'clkgen_x4'
(ChipWhisperer Scope WARNING|File ChipWhispererHuskyClock.py:703) Target clock may drop; you may need to reset your target.
scope.adc.timeout = 1
scope.adc.samples = 150000
trace = cw.capture_trace(scope, target, bytearray(16), bytearray(16))
Finally, on Husky a faster streaming rate can be achieved by lowering the number of bits per sample (default 12) to 8:
scope.adc.bits_per_sample = 8
assert not scope.adc.errors, scope.adc.errors