Target API¶
The target object provides the interface for configuring the target device under test (DUT). There are currently two UART communication classes:
Simple Serial Target (default)
and two FPGA based targets:
The easiest way to create a target object is to use the chipwhisperer.target
function:
import chipwhisperer as cw
scope = cw.scope()
target = cw.target(scope, cw.targets.SimpleSerial)
- target(scope, target_type=<class 'chipwhisperer.capture.targets.SimpleSerial.SimpleSerial'>, **kwargs) chipwhisperer.target(scope, target_type=targets.SimpleSerial, **kwargs)¶
Create a target object and connect to it.
- Parameters:
scope (ScopeTemplate) – Scope object that we’re connecting to the target through.
target_type (TargetTemplate, optional) – Target type to connect to. Defaults to targets.SimpleSerial. Types can be found in chipwhisperer.targets.
**kwargs – Additional keyword arguments to pass to target setup. See target.con or target._con for your target_type for more information
- Return type:
Union
[CW305
,CW305_ECC
,CW310
,CW340
,SimpleSerial
,SimpleSerial2
,SimpleSerial2_CDC
]- Returns:
Connected target object specified by target_type.
Serial Targets¶
Simple Serial Target¶
38400bps ASCII encoded serial. See SimpleSerial for protocol documentation.:
import chipwhisperer as cw
scope = cw.scope()
target = cw.target(scope)
Supported Targets:
- class SimpleSerial¶
SimpleSerial target object.
This class contains the public API for a target that uses serial communication.
The easiest way to connect to the target is:
import chipwhisperer as cw scope = cw.scope() target = cw.target(scope)
The target is automatically connected to if the default configuration adequate.
A noflush=True kwarg may be used to suppress an initial protocol-specific flush of the UART. The caller is then responsible for invoking flush() manually to flush underlying buffers.
For more help use the help() function with one of the submodules (target.baud, target.write, target.read, …).
Warning
The CWLite, CW1200, and CWNano have a 128 byte read buffer and a 128 byte send buffer. If the read buffer overflows, a warning message will be printed. Prior to firmware 0.20, the send buffer can silently overflow. In ChipWhisperer 5.4, this is upgraded to a 200 byte read/send buffer.
- property baud¶
The current baud rate of the serial connection.
- Getter:
Return the current baud rate.
- Setter:
Set a new baud rate. Valid baud rates are any integer in the range [500, 2000000].
- Raises:
AttributeError – Target doesn’t allow baud to be changed.
- close()¶
Close target
- dis()¶
Disconnect from target
- flush()¶
Removes all data from the serial buffer.
New in version 5.1: Added target.flush()
- get_simpleserial_commands(timeout=250, ack=True)¶
Gets available simpleserial commands for target
- Parameters:
timeout (int, optional) – Value to use for timeouts during initial read of expected data in ms. If 0, block until all expected data is returned. Defaults to 250.
ack (bool, optional) – Wait for ack after sending key. Defaults to True.
- Returns:
List of dics with fields ‘cmd’ command_byte, ‘len’ command_length, ‘flags’ command_flags
- in_waiting()¶
Returns the number of characters available from the serial buffer.
- Returns:
The number of characters available via a target.read() call.
New in version 5.1: Added target.in_waiting()
- in_waiting_tx()¶
Returns the number of characters waiting to be sent by the ChipWhisperer.
Requires firmware version >= 0.2 for the CWLite/Nano and firmware version and firmware version >= 1.2 for the CWPro.
Used internally to avoid overflowing the TX buffer, since CW version 5.3
- Returns:
The number of characters waiting to be sent to the target
New in version 5.3.1: Added public method for in_waiting_tx().
- init()¶
Init Hardware
- is_done()¶
Always returns True
- read(num_char=0, timeout=250)¶
Reads data from the target over serial.
- Parameters:
num_char (int, optional) – Number of byte to read. If 0, read all data available. Defaults to 0.
timeout (int, optional) – How long in ms to wait before returning. If 0, block for a long time. Defaults to 250.
- Returns:
String of received data.
New in version 5.1: Added target.read()
- set_key(key, ack=True, timeout=250, always_send=False)¶
Checks if key is different than the last one sent. If so, send it.
Uses simpleserial_write(‘k’)
- Parameters:
key (bytearray) – key to send
ack (bool, optional) – Wait for ack after sending key. Defaults to True.
timeout (int, optional) – How long in ms to wait for the ack. Defaults to 250.
- Raises:
Warning – Device did not ack or error during read.
New in version 5.1: Added target.set_key()
- property simpleserial_last_read¶
The last raw string read by a simpleserial_read* command
- property simpleserial_last_sent¶
The last raw string written via simpleserial_write
- simpleserial_read(cmd, pay_len, end='\n', timeout=250, ack=True)¶
Reads a simpleserial command from the target over serial.
Reads a command starting with <start> with an ASCII encoded bytearray payload of length exp_len*2 (i.e. exp_len=16 for an AES128 key) and ending with <end>. Converts the payload to a bytearray. Will ignore non-ASCII bytes in the payload, but warn the user of them.
- Parameters:
cmd (str) – Expected start of the command. Will warn the user if the received command does not start with this string.
pay_len (int) – Expected length of the returned bytearray in number of bytes. Note that SimpleSerial commands send data as ASCII; this is the length of the data that was encoded.
end (str, optional) – Expected end of the command. Will warn the user if the received command does not end with this string. Defaults to ‘n’
timeout (int, optional) – Value to use for timeouts during reads in ms. If 0, block until all expected data is returned. Defaults to 250.
ack (bool, optional) – Expect an ack at the end for SimpleSerial >= 1.1. Defaults to True.
- Returns:
The received payload as a bytearray or None if the read failed.
Example
Reading ciphertext back from the target after a ‘p’ command:
ct = target.simpleserial_read('r', 16)
- Raises:
Warning – Device did not ack or error during read.
New in version 5.1: Added target.simpleserial_read()
- simpleserial_read_witherrors(cmd, pay_len, end='\n', timeout=250, glitch_timeout=8000, ack=True)¶
Reads a simpleserial command from the target over serial, but returns invalid responses.
Reads a command starting with <start> with an ASCII encoded bytearray payload of length exp_len*2 (i.e. exp_len=16 for an AES128 key) and ending with <end>. Converts the payload to a bytearray, returns a dictionary showing if processing was successful along with decoded and raw values. This function is designed to be used with glitching where you may have invalid responses.
- Parameters:
cmd (str) – Expected start of the command. Will warn the user if the received command does not start with this string.
pay_len (int) – Expected length of the returned bytearray in number of bytes. Note that SimpleSerial commands send data as ASCII; this is the length of the data that was encoded.
end (str, optional) – Expected end of the command. Will warn the user if the received command does not end with this string. Defaults to ‘n’
timeout (int, optional) – Value to use for timeouts during initial read of expected data in ms. If 0, block until all expected data is returned. Defaults to 250.
glitch_timeout (int, optional) – Value to wait for additional data if expected data isn’t returned. Useful to have a longer timeout for a reset or other unexpected event.
ack (bool, optional) – Expect an ack at the end for SimpleSerial >= 1.1. Defaults to True.
- Returns:
valid (bool): Did response look valid? payload: Bytearray of decoded data (only if valid is ‘True’, otherwise None) full_response: Raw output of serial port. rv: If ‘ack’ in command, includes return value
- Return type:
A dictionary with these elements
Example
- Reading the output of one of the glitch tests when no error:
resp = target.simpleserial_read_witherrors(‘r’, 4) print(resp) >{‘valid’: True, ‘payload’: CWbytearray(b’c4 09 00 00’), ‘full_response’: ‘rC4090000n’, ‘rv’: 0}
- Reading the output of one of the glitch tests when an error happened:
resp = target.simpleserial_read_witherrors(‘r’, 4) print(resp) >{‘valid’: False, ‘payload’: None, ‘full_response’: ‘x00x00x00x00x00x00x00rRESET n’, ‘rv’: None}
- Raises:
Warning – Device did not ack or error during read.
New in version 5.2: Added target.simpleserial_read_witherrors()
- simpleserial_wait_ack(timeout=500)¶
Waits for an ack from the target for timeout ms
- Parameters:
timeout (int, optional) – Time to wait for an ack in ms. If 0, block until we get an ack. Defaults to 500.
- Returns:
The return code from the ChipWhisperer command or None if the target failed to ack
- Raises:
Warning – Target not connected.
New in version 5.1: Added target.simpleserial_wait_ack
New in version 5.2: Defined return value
- simpleserial_write(cmd, num, end='\n')¶
Writes a simpleserial command to the target over serial.
Writes ‘cmd’ + ascii(num) + ‘end’ over serial. Flushes the read and write buffers before writing.
- Parameters:
cmd (str) – String to start the simpleserial command with. For ‘p’.
num (bytearray) – Number to write as part of command. For example, the 16 byte plaintext for the ‘p’ command. Converted to hex-ascii before being sent. If set to ‘none’ is omitted.
end (str, optional) – String to end the simpleserial command with. Defaults to ‘n’.
Example
Sending a ‘p’ command:
key, pt = ktp.new_pair() target.simpleserial_write('p', pt)
- Raises:
Warning – Write attempted while disconnected or error during write.
New in version 5.1: Added target.simpleserial_write()
- write(data, timeout=0)¶
Writes data to the target over serial.
- Parameters:
data (str) – Data to write over serial.
timeout (float or None) – Wait <timeout> seconds for write buffer to clear. If None, block for a long time. If 0, return immediately. Defaults to 0.
- Raises:
Warning – Target not connected
New in version 5.1: Added target.write()
Simple Serial V2 Target¶
230400bps COBS serial. See SimpleSerial for protocol documentation.:
import chipwhisperer as cw
scope = cw.scope()
target = cw.target(scope, cw.targets.SimpleSerial2)
Supported Targets:
- class SimpleSerial2¶
Target object for new SimpleSerial V2 protocol.
New in version 5.4: Added SimpleSerial V2 (not on by default)
Currently, the easiest way to use it is:
scope = cw.scope() target = cw.target(scope, cw.targets.SimpleSerial2, flush_on_err=False)
For more help, use the help() function with one of the submodules (target.baud, target.write, target.read, …).
The protocol is as follows:
[cmd, subcmd, data_len, data_0, …, data_n, crc (poly=0xA6)]
The frame is then consistant overhead byte stuffed (COBS) to remove all 0x00 bytes. An 0x00 byte is then appended to the end of the frame.
Uses 230400bps by default.
Return packets have the form:
[cmd, data_len, data_0, …, data_n, crc (poly=0xA6)]
All commands sent to the target will be responded to with an ack/error packet.
Allows us to send more information in the same number of bytes. Also should be more robust and a bit easier to work with:
It’s easy to reset communications by sending frame bytes (0x00)
- We have many ways of checking the validity of a packet:
-Frame byte where it shouldn’t be -No frame byte at end of message -CRC
No need to specify length of return message
- property baud¶
The current baud rate of the serial connection.
- Getter:
Return the current baud rate.
- Setter:
Set a new baud rate. Valid baud rates are any integer in the range [500, 2000000].
- Raises:
AttributeError – Target doesn’t allow baud to be changed.
- close()¶
Close target
- con(scope=None, flush_on_err=True, **kwargs)¶
Connect to target
- dis()¶
Disconnect from target
- flush()¶
Removes all data from the serial buffer.
- flush_on_error()¶
Internally used to reset comms and flush serial buffer when we get an error.
- get_simpleserial_commands(timeout=250, flush_on_err=None, ack=True)¶
Gets available simpleserial commands for target
- Parameters:
timeout (int, optional) – Value to use for timeouts during initial read of expected data in ms. If 0, block until all expected data is returned. Defaults to 250.
flush_on_err (bool/None, optional) – If True, reset/flush the serial lines. If False, don’t. If None, determine via whether or not flush_on_err was True or False when passed to con()
ack (bool, optional) – Wait for ack after sending key. Defaults to True.
- Returns:
List of dics with fields ‘cmd’ command_byte, ‘len’ 0x00, ‘flags’ 0x00
- in_waiting()¶
Returns the number of characters available from the serial buffer.
- Returns:
The number of characters available via a target.read() call.
- in_waiting_tx()¶
Returns the number of characters waiting to be sent by the ChipWhisperer.
Requires firmware version >= 0.2 for the CWLite/Nano and firmware version and firmware version >= 1.2 for the CWPro.
Used internally to avoid overflowing the TX buffer, since CW version 5.3
- Returns:
The number of characters waiting to be sent to the target
- is_done()¶
Required on other platforms
- read(num_char=0, timeout=250)¶
Reads data from the target over serial.
- Parameters:
num_char (int, optional) – Number of byte to read. If 0, read all data available. Defaults to 0.
timeout (int, optional) – How long in ms to wait before returning. If 0, block until data received. Defaults to 250.
- Returns:
String of received data.
- read_cmd(cmd=None, pay_len=None, timeout=250, flush_on_err=None)¶
Read and decode simpleserial-v2 command
- Parameters:
cmd (str, optional) – Expected start of the command. Will warn the user if the received command does not start with this string. Defaults to None
pay_len (int, optional) – Expected length of the returned bytearray in number of bytes. If None, uses the length field of the packet to determine how much data to read
timeout (int, optional) – Value to use for timeouts during initial read of expected data in ms. If 0, block until all expected data is returned. Defaults to 250.
flush_on_err (bool/None, optional) – If True, reset/flush the serial lines. If False, don’t. If None, determine via whether or not flush_on_err was True or False when passed to con()
- reset_comms()¶
Try to reset communication with the target and put it in a state to read commands
Sends 10 0x00 bytes, sleeps for 0.05 seconds, then flushes the serial buffer
- send_cmd(cmd, scmd, data)¶
Send a SSV2 command to the target.
Does all the CRC/Byte stuffing for you
- Parameters:
cmd (char or int) – The command to use
scmd (int) – The subcommand to use
data (bytearray) – The data to send
- set_key(key, ack=True, timeout=250, always_send=False)¶
Checks if key is different than the last one sent. If so, send it.
Uses simpleserial_write(‘k’)
- Parameters:
key (bytearray) – key to send
ack (bool, optional) – Wait for ack after sending key. Defaults to True.
timeout (int, optional) – How long in ms to wait for the ack. Defaults to 250.
- Raises:
Warning – Device did not ack or error during read.
- simpleserial_read(cmd=None, pay_len=None, end='\n', timeout=250, ack=True)¶
Reads back response from target and ack packet.
- Parameters:
cmd (str, optional) – Expected start of the command. Will warn the user if the received command does not start with this string. Defaults to None
pay_len (int, optional) – Expected length of the returned bytearray in number of bytes. If None, uses the length field of the packet to determine how much data to read
end (str, optional) – Unused
timeout (int, optional) – Value to use for timeouts during initial read of expected data in ms. If 0, block until all expected data is returned. Defaults to 250.
ack (bool, optional) – Expect an ack packet at the end for SimpleSerial 2. Defaults to True.
- simpleserial_read_witherrors(cmd=None, pay_len=None, end='\n', timeout=250, glitch_timeout=1000, ack=True)¶
Reads a simpleserial command from the target over serial, but returns invalid responses.
Reads a command starting with <start> with a COBS encoded bytearray payload of length pay_len (i.e. pay_len=16 for an AES128 key) and ending with 0x00. Does normal read_cmd() stuff (decoding, etc). If an error is found (timeout, frame issues, etc), a single read of 1000 character with glitch_timeout as a timeout is done, and the raw response is returned.
The packet will be valid if:
All requested reads return the requested characters
No frame bytes except the terminator are read
The packet doesn’t end with a frame byte
If an ack packet isn’t received
- Parameters:
cmd (str, optional) – Expected start of the command. Will warn the user if the received command does not start with this string. Defaults to None
pay_len (int, optional) – Expected length of the returned bytearray in number of bytes. If None, uses the length field of the packet to determine how much data to read
end (str, optional) – Unused
timeout (int, optional) – Value to use for timeouts during initial read of expected data in ms. If 0, block until all expected data is returned. Defaults to 250.
glitch_timeout (int, optional) – Value to wait for additional data if expected data isn’t returned. Useful to have a longer timeout for a reset or other unexpected event. Defaults to 1000
ack (bool, optional) – Expect an ack packet at the end for SimpleSerial >= 2. Defaults to True.
- Returns:
valid (bool): Did response look valid? payload: Bytearray of decoded data (only if valid is ‘True’, otherwise None) full_response: Raw output of serial port. rv: If ‘ack’ in command, includes return value
- Return type:
A dictionary with these elements
Example
- Reading the output of one of the glitch tests when no error:
resp = target.simpleserial_read_witherrors(‘r’, 4) print(resp) >{‘valid’: True, ‘payload’: CWbytearray(b’c4 09 00 00’), ‘full_response’: ‘rC4090000n’, ‘rv’: 0}
- Reading the output of one of the glitch tests when an error happened:
resp = target.simpleserial_read_witherrors(‘r’, 4) print(resp) >{‘valid’: False, ‘payload’: None, ‘full_response’: ‘x00x00x00x00x00x00x00rRESET n’, ‘rv’: None}
- Raises:
Warning – Device did not ack or error during read.
- simpleserial_wait_ack(timeout=500)¶
Waits for an ack/error packet from the target for timeout ms
- Parameters:
timeout (int, optional) – Time to wait for an ack in ms. If 0, block until we get an ack. Defaults to 500.
- Returns:
The return code from the ChipWhisperer command or None if the target failed to ack
- simpleserial_write(cmd, data, end='\n')¶
Mimic SimpleSerial v1 behaviour with new firmware
Internal/firmware details may change
Special cases for ‘p’ and ‘k’ to use sub command to select what to do with simpleserial-aes
- Parameters:
cmd (str) – If ‘p’, SSV2 cmd=0x01, scmd=0x01. If ‘k’, SSV2 cmd=0x01, scmd=0x02. Otherwise, SSV2 cmd=cmd, scmd=0x00.
data (bytearray) – Number to write as part of command. For example, the 16 byte plaintext for the ‘p’ command. If an empty list is given, [0x00] is sent.
end (str, optional) – Unused
Example
Sending a ‘p’ command:
key, pt = ktp.new_pair() target.simpleserial_write('p', pt)
- static strerror(e)¶
Get string error message based on integer error e
- write(data, timeout=0)¶
Writes data to the target over serial.
- Parameters:
data (str) – Data to write over serial.
timeout (float or None) – Wait <timeout> seconds for write buffer to clear. If None, block for a long time. If 0, return immediately. Defaults to 0.
- Raises:
Warning – Target not connected
Simple Serial V2 CDC Target¶
Variant of Simple Serial V2 Target that uses the ChipWhisperer’s CDC serial port instead of its custom USB interface.:
import chipwhisperer as cw
scope = cw.scope()
target = cw.target(scope, cw.targets.SimpleSerial2_CDC) # autodetects COM (/dev/ttyACMx) port
- class SimpleSerial2_CDC¶
Target Option for Using SSV2 with a CDC Port
New in version 5.5: Added CDC SSV2
Currently, the easiest way to use it is:
scope = cw.scope() target = cw.target(scope, cw.targets.SimpleSerial2_CDC)
Upon connection, this target object will using USB info from the scope object to figure out which serial port to use. You can also specify the serial port manually using the dev_path parameter.
target = cw.target(scope, cw.targets.SimpleSerial2_CDC, dev_path='COM5')
Other than that, usage is mostly the same as regular simpleserial V2, except the read timeout is always fixed to 250ms.
It does offer better performance than the regular SSV2 object if reading serial data back from the target.
- property baud¶
The current baud rate of the serial connection.
- Getter:
Return the current baud rate.
- Setter:
Set a new baud rate. Valid baud rates are any integer in the range [500, 2000000].
- Raises:
AttributeError – Target doesn’t allow baud to be changed.
- close()¶
Close target
- con(scope, dev_path=None, interface=None, flush_on_err=True)¶
Connect to target
- flush()¶
Removes all data from the serial buffer.
- in_waiting()¶
Returns the number of characters available from the serial buffer.
- Returns:
The number of characters available via a target.read() call.
- in_waiting_tx()¶
Returns the number of characters waiting to be sent by the ChipWhisperer.
Requires firmware version >= 0.2 for the CWLite/Nano and firmware version and firmware version >= 1.2 for the CWPro.
Used internally to avoid overflowing the TX buffer, since CW version 5.3
- Returns:
The number of characters waiting to be sent to the target
- read(num_char=0, timeout=250)¶
Reads data from the target over serial.
- Parameters:
num_char (int, optional) – Number of byte to read. If 0, read all data available. Defaults to 0.
timeout (int, optional) – How long in ms to wait before returning. If 0, block until data received. Defaults to 250.
- Returns:
String of received data.
- write(data)¶
Writes data to the target over serial.
- Parameters:
data (str) – Data to write over serial.
timeout (float or None) – Wait <timeout> seconds for write buffer to clear. If None, block for a long time. If 0, return immediately. Defaults to 0.
- Raises:
Warning – Target not connected
FPGA Targets¶
CW305 FPGA Target¶
Used for controlling and communicating with the CW305 Artix FPGA Target.:
import chipwhisperer as cw
target = cw.target(None, cw.targets.CW305) # programs default bitstream, see _con() for full arg list
Examples:
- class CW305¶
CW305 target object.
This class contains the public API for the CW305 hardware. To connect to the CW305, the easiest method is:
import chipwhisperer as cw scope = cw.scope() # scope can also be None here, unlike with the default SimpleSerial target = cw.target(scope, cw.targets.CW305, bsfile=<valid FPGA bitstream file>)
As of CW5.3, you can also specify the following:
# can also be '35t' target = cw.target(scope, fpga_id='100t')
To automatically program with the example AES bitstream
If you’re using the reference designs, typical configuration requires you to set the FPGA VCC-INT voltage and enable and set the clock via the PLL. You’ll probably also want to disable the USB clock during encryption to reduce noise:
target.vccint_set(1.0) #set VCC-INT to 1V target.pll.pll_enable_set(True) #Enable PLL chip target.pll.pll_outenable_set(False, 0) # Disable unused PLL0 target.pll.pll_outenable_set(True, 1) # Enable PLL target.pll.pll_outenable_set(False, 2) # Disable unused PLL2 # optional, but reduces power trace noise target.clkusbautooff = True target.clksleeptime = 1 # 1ms typically good for sleep
Don’t forget to clock the ChipWhisperer ADC off the FPGA instead of the internal clock:
scope.clock.adc_src = "extclk_x4" scope.clock.reset_adc() # make sure the DCM is locked
Note that connecting to the CW305 includes programming the CW305 FPGA, if it isn’t already.
For more help about CW305 settings, try help() on this CW305 submodule:
target.pll
- INITB_state()¶
Returns the state of the FPGA’s INITB pin
The INITB is high when the FPGA is programmed, and low when it is not
- Returns:
True if the INITB is high, False if INITB is low, None if the result is invalid
- batchRun(batchsize=1024, random_key=True, random_pt=True, seed=None)¶
Run multiple encryptions on random data
- Parameters:
batchsize (int) – The number of encryption to run (default 1024).
random_key (bool) – True if the key is random (default False).
random_pt (bool) – True if the plaintext are random (default True).
seed (int) – random int32 for the PRG.
- checkEncryptionKey(key)¶
Validate encryption key
- dis()¶
Disconnect from target
- fpga_read(addr, readlen)¶
Read from an address on the FPGA
- Parameters:
addr (int) – Address to read from
readlen (int) – Length of data to read
- Returns:
Requested data as a list
- fpga_write(addr, data)¶
Write to an address on the FPGA
- Parameters:
addr (int) – Address to write to
data (list) – Data to write to addr
- get_fpga_buildtime()¶
Returns date and time when FPGA bitfile was generated.
- go()¶
Disable USB clock (if requested), perform encryption, re-enable clock
- is_done()¶
Check if FPGA is done
- is_programmed()¶
Is FPGA programmed
- Returns:
True if the FPGA is programmed, otherwise False
Warning
This function may erroneously return True if the FPGA is not powered
- loadEncryptionKey(key)¶
Write encryption key to FPGA
- loadInput(inputtext)¶
Write input to FPGA
- readOutput()¶
“Read output from FPGA
- set_key(key, ack=False, timeout=250, always_send=False)¶
Checks if key is different from the last one sent. If so, send it.
- Parameters:
key (bytearray) – key to send
ack – Unused
timeout – Unused
New in version 5.1: Added set_key to CW305
- simpleserial_read(cmd, pay_len, end='\n', timeout=250, ack=True)¶
Read data from target
Mimics simpleserial protocol of serial based targets
- Parameters:
cmd (str) – Command to ues. Only accepts ‘r’ for now.
pay_len – Unused
end – Unused
timeout – Unused
ack – Unused
Returns: Value from Crypto output register
New in version 5.1: Added simpleserial_read to CW305
- simpleserial_write(cmd, data, end=None)¶
Write data to target.
Mimics simpleserial protocol of serial based targets.
- Parameters:
cmd (str) – Command to use. Target supports ‘p’ (write plaintext), and ‘k’ (write key).
data (bytearray) – Data to write to target
end – Unused
- Raises:
ValueError – Unknown command
New in version 5.1: Added simpleserial_write to CW305
- slurp_defines(defines_files=None)¶
Parse Verilog defines file so we can access register and bit definitions by name and avoid ‘magic numbers’.
- Parameters:
defines_files (list) – list of Verilog define files to parse
target.pll¶
- class PLLCDCE906(usb, ref_freq, board='CW305')¶
- calcMulDiv(freqdesired, freqsource)¶
Calculate Multiply & Divide settings for PLL based on input frequency
- cdce906init()¶
Set defaults on CDCE906 PLL Chip
- cdce906read(addr)¶
Read a byte from the CDCE906 External PLL Chip
- cdce906setoutput(outpin, divsource, slewrate='+0nS', enabled=True, inverted=False)¶
Setup the outputs for the PLL chip
- cdce906write(addr, data)¶
Write a byte to the CDCE906 External PLL Chip
- outnumToPin(outnum)¶
Convert from PLL Number to actual output pin
- outputUpdateOutputs(outnum, pllsrc_new=None, pllenabled_new=None, pllslewrate_new=None)¶
Update the output pins with enabled/disabled, slew rate, etc
- pll_enable_get()¶
Read if PLL chip is enabled or disabled
- pll_enable_set(enabled)¶
Enable or disable the PLL chip
- pll_outenable_get(outnum)¶
Get whether a PLL is enabled or not
- Parameters:
outnum (int) – The PLL to get the enable status of
- Returns:
True if the PLL is enabled, False if it isn’t
- pll_outenable_set(enabled, outnum)¶
Enable or disable a PLL
- Parameters:
enabled (bool) – Whether to enable (True) or disable (False) the specified PLL.
outnum (int) – The PLL to enable or disable
- pll_outfreq_get(outnum)¶
Read the programmed output frequency from a PLL on the CW305
- Parameters:
outnum (int) – PLL to read from (i.e. for PLL 0, use outnum=0)
- Returns:
The output frequency of the specified PLL
- pll_outfreq_set(freq, outnum)¶
Set the output frequency of a PLL
- Parameters:
freq (int) – The desired output frequency of the PLL. Must be in range [630kHz, 167MHz]
outnum (int) – The PLL to set the output frequency of
- Raises:
ValueError – Desired frequency is bigger than 167MHz or smaller than 630kHz
- pll_outslew_get(outnum)¶
Get slew rate of PLL output
- pll_outslew_set(slew, outnum)¶
Set clock slew rate for the selected clock output.
- Parameters:
slew (string) – Desired slew rate. Allowed values: ‘+3nS’, ‘+2nS’, ‘+1nS’, ‘+0nS’.
outnum (int) – PLL output
- Raises:
ValueError – Invalid PLL output or invalid slew value
- pll_outsource_get(outnum)¶
Get output source settings
- pll_outsource_set(source, outnum)¶
Update clock source for the selected clock output.
Output 0 can be configured for PLL0, PLL1, or PLL2.
Output 1 is restricted to PLL1.
Output 2 is restricted to PLL2.
- Parameters:
source (String) – Desired clock source (‘PLL0’, ‘PLL1’, ‘PLL2’)
outnum (int) – Output to configure. 0 goes to CLK-SMA X6, 1 goes to FPGA pin N13, and 2 goes to FPGA pin E12.
- Raises:
ValueError – Invalid source for specified clock output
- pll_writedefaults()¶
Save PLL settings to EEPROM, making them power-on defaults
- pllread(pllnum)¶
Read N/M/output divisors from PLL chip
- pllwrite(pllnum, N, M, outdiv)¶
Write N/M/output divisors to PLL chip
CW310¶
Used for controlling and communicating with the CW310 Bergen Board.:
import chipwhisperer as cw
target = cw.target(None, cw.targets.CW310)
Examples:
Coming soon!
- class CW310(*args, **kwargs)¶
CW310 Bergen Board target object.
This class contains the public API for the CW310 hardware. To connect to the CW310, the easiest method is:
import chipwhisperer as cw scope = cw.scope() # scope can also be None here, unlike with the default SimpleSerial target = cw.target(scope, cw.targets.CW310, bsfile=<valid FPGA bitstream file>)
Inherits the CW305 object, so you can use the same methods as the CW305, provided the register interface in your FPGA build is the same.
You can also set the voltage and current settings for the USB-C Power port on the CW310
# set USB PDO 3 to 20V 5A target.usb_set_voltage(3, 20) target.usb.set_current(3, 5)
# renegotiate PDO (applies above settings) target.usb_negotiate_pdo()
For more help about CW310 settings, try help() on this CW310 submodule:
target.pll
- usb_set_voltage(pdo_num, voltage)¶
Set the voltage for one of the USBC PDOs.
PDO1 is always 5V 1A and cannot be changed.
- Parameters:
pdo_num (int) – The PDO to set the voltage for. Can be 2 or 3
voltage (float) – The voltage to set. Must be between 5 and 20 inclusive. Has a resolution of 0.05V
- usb_set_current(pdo_num, current)¶
Set the current for one of the USBC PDOs.
PDO1 is always 5V 1A and cannot be changed.
- Parameters:
pdo_num (int) – The PDO to set the current for. Can be 2 or 3
voltage (float) – The current to set. Must be between 0.5 and 5 inclusive. Has a resolution of 0.01A
- usb_negotiate_pdo()¶
Renegotate the USBC PDOs. Must be done for new PDOs settings to take effect
- gpio_mode(timeout=200)¶
Allow arbitrary GPIO access on SAM3U
Allows low-level IO access to SAM3U GPIO, and also SPI transfers. (see documentation on the returned object for more info)
- Parameters:
timeout (int) – USB timeout in ms. Defaults to 200.
- Returns:
A FPGAIO object which can be used to access IO on the CW305.
- _con(scope=None, bsfile=None, force=False, fpga_id=None, defines_files=None, slurp=True, prog_speed=20000000.0, sn=None, hw_location=None, platform='cw310')¶
Connect to CW305 board, and download bitstream.
If the target has already been programmed it skips reprogramming unless forced.
- Parameters:
scope (ScopeTemplate) – An instance of a scope object.
bsfile (path) – The path to the bitstream file to program the FPGA with.
force (bool) – Whether or not to force reprogramming.
fpga_id (string) – ‘100t’, ‘35t’, or None. If bsfile is None and fpga_id specified, program with AES firmware for fpga_id
defines_files (list, optional) – path to cw305_defines.v
slurp (bool, optional) – Whether or not to slurp the Verilog defines.
platform (string, optional) – ‘cw305’, or ‘ss2’ for non-CW305 target FPGA platforms. The latter is intended for target designs using the ss2.v simpleserial-to-parallel wrapper.
version (optional) – when required to differentiate from multiple possible bitfiles for a particular target (to be used with fpga_id)
- fpga_write(addr, data)¶
Write to an address on the FPGA
- Parameters:
addr (int) – Address to write to
data (list) – Data to write to addr
- fpga_read(addr, readlen)¶
Read from an address on the FPGA
- Parameters:
addr (int) – Address to read from
readlen (int) – Length of data to read
- Returns:
Requested data as a list
- cdc_settings target.cdc_settings¶
Check or set whether USART settings can be changed via the USB CDC connection
i.e. whether you can change USART settings (baud rate, 8n1) via a serial client like PuTTY
- Getter:
An array of length two for the two CDC ports
- Setter:
Can set either via an integer (which sets both ports) or an array of length 2 (which sets each port)
Returns None if using firmware before the CDC port was added
Common Target Methods¶
Note
Both the CW310 and CW305 inherit common methods from Common Scope Attributes
FPGA Advanced Control¶
Advanced IO control for FPGA targets
CW305 SPI Program¶
- class FPGASPI(usb, timeout=200)¶
Programmer for the CW305’s onboard SPI flash
Built for AT25DF321A, but has customizable codes for write enable/disable, chip erase, status, write, read, and block erase, as well as page size.
To program the SPI, the CW305 must be loaded with a special bitstream (will be done automatically if you specify fpga_id when connecting to the CW305) and have FW version > 0.30 for its USB microcontroller.
Basic usage:
fpga = cw.target(None, cw.targets.CW305, fpga_id='100t') #for CW305_100t fpga = cw.target(None, cw.targets.CW305, fpga_id='35t') #for CW305_35t spi = fpga.spi_mode() spi.erase_chip() # can also use spi.erase_block() for smaller/faster erases with open('bitfile.bit', 'rb') as f: data = list(f.read()) spi.program(data) # also verifies by default
Warning
The AT25DF321A has the following behaviour:
Writes longer than a page (256 bytes) will use only the last 256 bytes
Reads can cross page boundaries (though read() and verify() will only read 256 bytes at a time)
Writes that don’t begin on a page bound will wrap if a page boundary is crossed
The user is responsible for ensuring that their writes begin on page boundaries.
- cmd_read_mem(length, addr)¶
Read up to a page of data
For the default chip, a page is 256 bytes
- Parameters:
length (int) – Length of data to read
addr (int) – Address to read from
- Raises:
ValueError – length is bigger than a page
- cmd_write_mem(data, addr=0, timeout=1000)¶
Write up to a page of data
For the default chip, a page is 256 bytes.
- Parameters:
data (list) – Data to write
addr (int) – Address to write to, defaults to 0x00.
timeout (int) – Timeout in ms. If None, set to 0xFFFFFFFF (approx 1000 hours) Defaults to 1000 (1s).
- Raises:
ValueError – Data is longer than a page
IOError – Wait timed out
- enable_interface(enable)¶
Enable or disable the SPI interface
- Parameters:
enable (bool) – Enable (True) or disable (False) SPI interface
- enable_write(enable)¶
Enable write/erase commands on the SPI chip.
- Parameters:
enable (bool) – Enable (True) or disable (False) write/erase on the SPI chip
- erase_block(addr, size='4K', timeout=1000)¶
Erase a block on the SPI chip. See spi.ERASE_BLOCK for available erase lengths
- Parameters:
addr (int) – Address to erase from
size (string) – See spi.ERASE_BLOCK for available sizes
timeout (int) – Timeout in ms. If None, set to 0xFFFFFFFF (approx 1000 hours) Defaults to 1000 (1s).
- Raises:
IOError – Erase timed out
- erase_chip(timeout=None)¶
Erase the whole SPI chip. Slow (~25s)
- Parameters:
timeout (int) – Timeout in ms. If None, set to 0xFFFFFFFF (approx 1000 hours)
- Raises:
IOError – Erase timed out
- program(data, addr=0, verify=True, timeout=1000)¶
Program (and optionally verify) the chip with data.
- Parameters:
data (list) – data to write
addr (int) – Address to start programming from. Defaults to 0x00. Must align with a page.
verify (bool) – If True, verify data written at end of full write. Defaults to True.
timeout (int) – Timeout in ms for writes. If None, set to 0xFFFFFFFF (approx 1000 hours) Defaults to 1000 (1s).
- Raises:
IOError – Verify failed or timeout
- read(length, addr=0)¶
Read data on the SPI chip
- Parameters:
length (int) – Length of data to read
addr (int) – Address to start read from. Must align with a page.
- set_cs_pin(status)¶
Set the SPI pin high or low
- Parameters:
status (bool) – Set CS pin high (True) or low (False)
- spi_tx_rx(data)¶
Write up to 64 bytes of data to the SPI chip
- Parameters:
data (list) – Write data over the SPI interface
- Raises:
ValueError – len(data) > 64
- verify(data, addr=0)¶
Verify the data on the SPI chip
- Parameters:
data (list) – data to verify
addr (int) – Address to start verification from. Defaults to 0x00. Must align with a page.
- Raises:
IOError – Verify failed
- wait_busy(timeout=1000)¶
Wait for the busy status on the FPGA to clear
- Parameters:
timeout (int) – Timeout in ms. If None, set to 0xFFFFFFFF (approx 1000 hours) Defaults to 1000 (1s).
- Raises:
IOError – Wait timed out
CW305 SAM3U IO Control¶
- class FPGAIO(usb, timeout=200)¶
User IO to override external bus.
Allows you to use any pin on the SAM3U as a user IO. This includes pins such as the external IO interface, and basically anything else you can find.
- The pin names are strings, and come from one of three sources:
SAM3U pin names, such as “PC11”, “PB9”, etc.
Net names from the CW305 schematic such as “USB_A20”.
The FPGA ball location that is connected to the SAM3U pin, such as “M2”.
Any function taking a pin name assumes you pass a string with one of those. You do not need to specify your source - it will autodetect the pin name (if possible). The SAM3U pin names allow access to every pin, including those which are not actually connected on the PCB itself.
Beyond simple GPIO toggling, a bit-banged SPI interface can be defined and connected to any of the SAM3U pins. The bit-banged interface is done on the SAM3U microcontroller, with a default SCK frequency of around 1.5 MHz. You can additionally define waitstates to slow down this clock.
Basic usage:
fpga = cw.target(None, cw.targets.CW305) io = target.gpio_mode() # Take over the SAM3U blue LED (normally controlled by firmware, won't be after this) import time io.pin_set_output("LED_BLUE") io.pin_set_state("LED_BLUE", 0) time.sleep(0.5) io.pin_set_state("LED_BLUE", 1) # Example - toggle pin associated with FPGA pin C1 (would be USB_A11) import time io.pin_set_output("C1") io.pin_set_state("C1", 0) time.sleep(0.1) io.pin_set_state("C1", 1) # Setup a SPI interface based on schematic net names io.spi1_setpins(sdo="USB_A20", sdi="USB_A19", sck="USB_A18", cs="USB_A17") io.spi1_enable(True) somedata = [0x11, 0x22, 0x33] response = io.spi1_transfer(somedata) print(response)
- If you want to see all possible pin names, you can access them with:
io.SAM3U_PIN_NAMES.keys() io.SCHEMATIC_PIN_NAMES.keys() io.FPGA_PIN_NAMES.keys()
- pin_name_to_number(pinname)¶
Convert from a user-friendly pin name to the number.
This function can be passed a name from the schematic (such as “USB_A20”), a name from the SAM3U peripherals (such as “PB22”), or a FPGA pin location (such as “M2”). It will attempt to auto-detect which one you passed.
- Parameters:
pinname (str) – Name such as “PB22”, “USB_A20”, or “M2”.
- pin_set_output(pinname)¶
Set a given pin as an output.
- Parameters:
pinname (str) – Name such as “PB22”, “USB_A20”, or “M2”.
- pin_set_state(pinname, state)¶
Set the state of a pin (must have been set as output previously).
- Parameters:
pinname (str) – Name such as “PB22”, “USB_A20”, or “M2”.
state (bool) – Set pin high (True) or low (False)
- spi1_enable(enable, waitcycles=0)¶
Enable or disable the SPI interface.
- Parameters:
enable (bool) – Enable (True) or disable (False) SPI interface
- spi1_set_cs_pin(status)¶
Set the SPI pin high or low.
- Parameters:
status (bool) – Set CS pin high (True) or low (False)
- spi1_setpins(sdo, sdi, sck, cs)¶
Set the pins to be used for the SPI1 interface.
- Parameters:
sdo (str) – Serial Data Out (output from SAM3U) pin name such as “PB22”, “USB_A20”, or “M2”.
sdi (str) – Serial Data In (input to SAM3U) pin name such as “PB22”, “USB_A20”, or “M2”.
sck (str) – Serial Clock (output from SAM3U) pin name such as “PB22”, “USB_A20”, or “M2”.
cs (str) – Chip Select (output from SAM3U) name such as “PB22”, “USB_A20”, or “M2”.
- spi1_transfer(data)¶
Writes data, dropping CS before and raising after, returns read data.
- Parameters:
data (list) – Write data over the SPI interface
- spi1_tx_rx(data)¶
Write up to 64 bytes of data to the SPI interface (no CS action).
This is a low-level function that performs a single transfer. Does not affect the CS pin.
- Parameters:
data (list) – Write data over the SPI interface
- Raises:
ValueError – len(data) > 64
Serial Target Programming¶
ChipWhisperer includes built in bootloaders for STM32F, XMEGA, and AVR
target boards. These bootloaders can be accessed via the
chipwhisperer.program_target()
function. There are multiple programmer
types available:
programmers.STM32FProgrammer
programmers.XMEGAProgrammer
programmers.AVRProgrammer
Example:
import chipwhisperer as cw
# ...scope setup, firmware build, etc
cw.program_target(scope, cw.programmers.STM32FProgrammer, "/path/to/firmware.hex")
- program_target(scope, prog_type, fw_path, **kwargs)¶
Program the target using the programmer <type>
Programmers can be found in the programmers submodule
- Parameters:
scope (ScopeTemplate) – Connected scope object to use for programming
prog_type (Programmer) – Programmer to use. See chipwhisperer.programmers for available programmers
fw_path (str) – Path to hex file to program
New in version 5.0.1: Simplified programming target