FlashTool Module#

LENZ BiSS Protocol Implementation

Provides BiSS encoder protocol standarts and utilities.

Author:

LENZ ENCODERS, 2020-2025

class lenz_flashtool.flashtool.FlashTool(port_description_prefixes=('XR21V',), baud_rate=12000000)#

Bases: object

Main interface for interacting with BiSS C encoders via FlashTool device, connected to a serial port. FlashTool device has 2 channels for encoder connection. Commands perform on channel 2 if not mentioned.

This class provides methods for: - Establishing serial communication with FlashTool device - Sending commands and data to the encoder - Reading encoder status and data - Performing firmware updates - Executing calibration routines

The class implements the singleton pattern to ensure only one connection exists.

Typical usage:
>>> with FlashTool() as ft:
...     ft.biss_read_snum()  # Read serial number of the encoder (on channel 2)
...     ft.encoder_power_cycle()  # Perform power cycle on channel 2
...     ft.biss_write_command('reboot2bl')  # Reboot to bootloader
biss_addr_read(addr, length)#

Reads a specific range of registers from the current BiSS bank.

Sends a read command for the given address and length, and returns the data as a NumPy array after checksum validation.

Parameters:
  • addr (int) – The starting BiSS register address (0-127).

  • length (int) – The number of registers to read.

Returns:

A NumPy array of uint8 values containing the register data.

Return type:

np.ndarray

Raises:
  • FlashToolError – If the read operation times out or a checksum error occurs.

  • ValueError – If the address is out of range.

Example

>>> ft = FlashTool()
>>> data = ft.biss_addr_read(0x10, 4)
>>> print(data)
array([0x01, 0x02, 0x03, 0x04], dtype=uint8)
biss_addr_readb(bissbank, addr, length)#

Reads a specific range of registers from the specified BiSS bank.

Selects the specified bank, sends a read command for the given address and length, and returns the data as a NumPy array after checksum validation.

Parameters:
  • bissbank (int) – The BiSS bank number to read from (0-255).

  • addr (int) – The starting BiSS register address (0-127).

  • length (int) – The number of registers to read.

Returns:

A NumPy array of uint8 values containing the register data.

Return type:

np.ndarray

Raises:
  • FlashToolError – If the read operation times out or a checksum error occurs.

  • ValueError – If the address or bank number is out of range.

Example

>>> ft = FlashTool()
>>> data = ft.biss_addr_readb(1, 0x10, 4)
>>> print(data)
array([0x01, 0x02, 0x03, 0x04], dtype=uint8)
biss_cmd_reboot2bl()#

Sends the BiSS command to reboot the device into bootloader mode.

Issues the ‘reboot2bl’ command to the BiSS encoder, initiating a reboot into bootloader mode for firmware updates. Note: This method is deprecated and should be replaced with biss_write_command(‘reboot2bl’).

Returns:

None

Example

>>> ft = FlashTool()
>>> ft.biss_cmd_reboot2bl()
WARNING: Deprecated method. Use biss_write_command('reboot2bl') instead.
biss_read_HSI()#

Reads the HSI (Harmonic Signal Indicator) data from the BiSS encoder.

Sends a read command to retrieve encoder metadata, including the HSI value, and logs the result. Returns the HSI value as a single-element tuple.

Returns:

A tuple containing the HSI value as a string, or None if the read fails.

Return type:

Optional[Tuple[str]]

Raises:

FlashToolError – If the read operation times out or a communication error occurs.

Example

>>> ft = FlashTool()
>>> hsi = ft.biss_read_HSI()
>>> print(hsi)
('1A',)
biss_read_angle_once()#

Reads the encoder angle once and prints it in degrees, minutes, and seconds.

Retrieves a single angle reading from encoder 2, converts it to degrees, and prints the formatted output.

Return type:

None

Returns:

None

Example

>>> ft = FlashTool()
>>> ft.biss_read_angle_once()
[2119664]:    45° 30' 15"
biss_read_calibration_temp_vcc()#

Continuously reads and prints encoder calibration state, signal modulation, temperature, and VCC.

Retrieves calibration data, including calibration state, signal modulation, temperature, and supply voltage, and prints them in a loop with a 1-second interval.

Return type:

None

Returns:

None

Example

>>> ft = FlashTool()
>>> ft.biss_read_calibration_temp_vcc()
CalState: 32, SignalMod: [3671, 4362], EncTemp = 27 °C, Vcc = 4.98 V
...
biss_read_command_state()#

Reads the command state from the BiSS encoder.

Sends a read command to retrieve the command state, validates the response with a checksum check, and returns the state as a NumPy array.

Returns:

A NumPy array of uint8 values containing the command state, or None if the read fails.

Return type:

Optional[np.ndarray]

Raises:

FlashToolError – If the checksum validation fails or no data is received within the timeout.

Example

>>> ft = FlashTool()
>>> state = ft.biss_read_command_state()
>>> print(state)
array([0x01], dtype=uint8)
biss_read_flags()#

Reads and interprets state flags and command state from the BiSS encoder.

Retrieves state flags and command state, interprets them using helper functions, and logs the results. Returns the interpreted error flags and command state descriptions.

Returns:

A tuple containing:
  • A list of active error flag descriptions.

  • A list containing the command state description.

Return type:

Tuple[List[str], List[str]]

Raises:

FlashToolError – If reading state flags or command state fails.

Example

>>> ft = FlashTool()
>>> flags, cmd_state = ft.biss_read_flags()
>>> print(flags, cmd_state)
['FLASH_CRC_ERROR'], ['IDLE']
biss_read_flags_flashCRC()#

Reads the flash CRC error flag from the BiSS encoder.

Retrieves the state flags and extracts the flash CRC error flag (bit 1).

Returns:

The flash CRC flag value (0 or 1).

Return type:

int

Raises:

FlashToolError – If the read operation fails or CRC validation fails.

Example

>>> ft = FlashTool()
>>> crc_flag = ft.biss_read_flags_flashCRC()
>>> print(crc_flag)
0
biss_read_progver()#

Reads and logs the encoder’s program version.

Retrieves the program version from the BiSS encoder and logs it in a formatted string (e.g., “1.1.0.4”).

Return type:

None

Returns:

None

Example

>>> ft = FlashTool()
>>> ft.biss_read_progver()
INFO: Encoder's program version: 1.1.0.4
biss_read_registers(bissbank)#

Reads all registers from the specified BiSS bank and logs the results.

Selects the specified bank, sends a read command for all registers, validates the response with a checksum check, and logs the received data as NumPy arrays. Does not return the data, only logs it for debugging purposes.

Parameters:

bissbank (int) – The BiSS bank number to read from (0-255).

Raises:

FlashToolError – If the read operation times out or a communication error occurs.

Return type:

None

Example

>>> ft = FlashTool()
>>> ft.biss_read_registers(1)
INFO: BiSS registers:
...
biss_read_snum()#

Reads the serial number and metadata from the BiSS encoder.

Sends a read command to retrieve encoder metadata, including bootloader version, serial number, manufacturing date, and program version. Parses and logs the data, returning it as a tuple.

Returns:

A tuple containing the bootloader version, serial number, manufacturing date, and program version as hex strings, or None if the read fails.

Return type:

Optional[Tuple[str, str, str, str]]

Raises:

FlashToolError – If the read operation times out or a communication error occurs.

Example

>>> ft = FlashTool()
>>> data = ft.biss_read_snum()
>>> print(data)
('0100', '12345678', '20230101', '0200')
biss_read_state_flags()#

Reads the state flags from the BiSS encoder.

Sends a read command to retrieve the state flags, validates the response with a checksum check, and returns the flags as a NumPy array.

Returns:

A NumPy array of uint8 values containing the state flags.

Return type:

np.ndarray

Raises:

FlashToolError – If the checksum validation fails or no data is received within the timeout.

Example

>>> ft = FlashTool()
>>> flags = ft.biss_read_state_flags()
>>> print(flags)
array([0x01, 0x00], dtype=uint8)
biss_set_bank(bank_num)#

Sets the active BiSS bank for subsequent read/write operations.

Selects the specified bank number for BiSS register operations, ensuring it is within the valid range (0-255).

Parameters:

bank_num (int) – The BiSS bank number to select.

Raises:
  • ValueError – If the bank number is out of the valid range (0-255).

  • TypeError – If the bank number is not an integer.

Return type:

None

Example

>>> ft = FlashTool()
>>> ft.biss_set_bank(1)
biss_set_dir_ccw()#

Sets the encoder direction to counterclockwise.

Resets the FlashTool, power cycles the encoder, unlocks setup and flash, issues the counterclockwise direction command, saves to flash, and power cycles again.

Return type:

None

Returns:

None

Example

>>> ft = FlashTool()
>>> ft.biss_set_dir_ccw()
biss_set_dir_cw()#

Sets the encoder direction to clockwise.

Resets the FlashTool, power cycles the encoder, unlocks setup and flash, issues the clockwise direction command, saves to flash, and power cycles again.

Return type:

None

Returns:

None

Example

>>> ft = FlashTool()
>>> ft.biss_set_dir_cw()
biss_set_shift(shift_angle)#

Sets the encoder shift angle and verifies the operation.

Reads the current angle, unlocks setup and flash, writes the shift angle, saves to flash, power cycles the encoder, and verifies the new shift angle.

Parameters:

shift_angle (int) – The shift angle value to set.

Return type:

None

Returns:

None

Example

>>> ft = FlashTool()
>>> ft.biss_set_shift(1000)
[12345]:     45° 30' 15" # TODO
[1000]:      0°  0'  0"
biss_write(addr, data)#

Writes a single byte to a BiSS register at the specified address.

Sends a single 8-bit value to the specified BiSS register address. Note: This method is deprecated and may be removed in future versions.

Parameters:
  • addr (int) – The BiSS register address (0-127).

  • data (int) – The 8-bit integer value to write.

Raises:
  • ValueError – If the address is out of range (0-127) or if the data is negative.

  • TypeError – If the data is not an integer.

Return type:

None

Example

>>> ft = FlashTool()
>>> ft.biss_write(0x10, 0xFF)
WARNING: Deprecated method. Consider using biss_write_word instead.
biss_write_command(command)#

Sends a specific BiSS command to the encoder.

Issues a command from the biss_commands dictionary to the BiSS encoder, such as rebooting, setting direction, or initiating calibration. Commands are written to the command register.

Parameters:

command (str) –

The command key from biss_commands. Supported commands include:

  • ’non’: No operation command. Device remains in current state with no action taken.

  • ’load2k’: Load 2 KB of data from registers into device memory. Used for firmware updates.

  • ’staybl’: Force device to stay in bootloader mode.

  • ’run’: Exit bootloader mode and execute the main application program. Initiates normal encoder operation.

  • ’zeroing’: Perform encoder zeroing procedure. Resets position counter to zero at current mechanical position.

  • ’set_dir_cw’: Configure encoder direction sensing for clockwise rotation.

  • ’set_dir_ccw’: Configure encoder direction sensing for counterclockwise rotation.

  • ’saveflash’: Commit current configuration parameters to flash memory.

  • ’ampcalibrate’: Initiate amplitude calibration routine. Automatically adjusts signal amplitudes.

  • ’cleardiflut’: Clear differential lookup table (DifLUT). Resets all offset compensation values to default state.

  • ’set_fast_biss’: Enable high-speed BiSS communication mode.

  • ’set_default_biss’: Revert to standard BiSS communication mode.

  • ’reboot’: Perform device reboot.

  • ’reboot2bl’: Reboot device directly into bootloader mode.

  • ’loadseriald’: Write serial number and manufacturing date to OTP memory.

  • ’loaddevid’: Program DevID into OTP memory.

  • ’loadkey’: Store key in secure flash memory.

  • ’savediftable’: Save differential compensation table to memory.

  • ’unlockflash’: Enable write access to protected flash memory regions.

  • ’unlocksetup’: Disable configuration write protection.

  • ’enarccal’: Enable arc-based calibration mode.

  • ’clearcalflash’: Erase all high-speed oscillator (HSI) and differential calibration data from flash.

Raises:

FlashToolError – If the specified command is not found in biss_commands.

Example

>>> ft = FlashTool()
>>> ft.biss_write_command('reboot2bl')
biss_write_word(addr, word)#

Writes one or more 8, 16, or 32-bit words to BiSS registers starting at the specified address.

Converts the provided word(s) to bytes, handles endianness, and writes them to the BiSS encoder. Supports single integers or lists of integers, automatically determining the word size (8, 16, or 32 bits) based on the maximum value.

Parameters:
  • addr (int) – The starting BiSS register address (0-127).

  • word (Union[int, List[int]]) – A single integer or a list of integers to write.

Raises:
  • ValueError – If the address is out of range, the word list is empty, a word is negative,

  • or a word exceeds the 32-bit limit.

  • TypeError – If any word is not an integer.

  • FlashToolError – If a hardware communication error occurs.

Return type:

None

Example

>>> ft = FlashTool()
>>> ft.biss_write_word(0x10, 0xABCD)  # Write a 16-bit word
>>> ft.biss_write_word(0x20, [0x01, 0x02])  # Write two 8-bit words
biss_zeroing()#

Performs a zeroing calibration on the BiSS encoder.

Resets the FlashTool, power cycles the encoder, unlocks setup and flash, issues the zeroing command, saves to flash, and power cycles again.

Return type:

None

Returns:

None

Example

>>> ft = FlashTool()
>>> ft.biss_zeroing()
close()#

Closes the serial port connection and performs cleanup.

Executes all registered cleanup handlers, closes the serial port, restores original signal handlers, and resets the singleton instance. Logs the closure of the connection.

Returns:

None

Example

>>> ft = FlashTool()
>>> ft.close()
INFO: FlashTool: COM3 closed.
enable_signal_handling(signals=(Signals.SIGINT,))#

Enables signal handling for the specified signals to ensure proper cleanup.

Registers signal handlers to call the close method when the specified signals are received, preserving the original handlers for restoration during cleanup.

Parameters:

signals (Tuple[int, ...]) – Tuple of signal numbers to handle (e.g., signal.SIGINT). Defaults to (signal.SIGINT,).

Returns:

The FlashTool instance for method chaining.

Return type:

FlashTool

Example

>>> ft = FlashTool().enable_signal_handling((signal.SIGINT, signal.SIGTERM))
encoder_ch1_power_cycle()#

Performs a power cycle on the encoder on channel 1.

Powers off the encoder, waits 0.1 seconds, powers it back on, and waits another 0.1 seconds to ensure stabilization.

Return type:

None

Returns:

None

Example

>>> ft = FlashTool()
>>> ft.encoder_ch1_power_cycle()
encoder_ch1_power_off()#

Powers off the encoder on channel 1.

Sends a POWER_OFF command to the BiSS encoder connected to channel 1 of the FlashTool device.

Return type:

None

Returns:

None

Example

>>> ft = FlashTool()
>>> ft.encoder_ch1_power_off()
encoder_ch1_power_on()#

Powers on the encoder on channel 1.

Sends a POWER_ON command to the BiSS encoder connected to channel 1 of the FlashTool device.

Return type:

None

Returns:

None

Example

>>> ft = FlashTool()
>>> ft.encoder_ch1_power_on()
encoder_power_cycle()#

Performs a power cycle on the encoder on channel 2.

Powers off the encoder, waits 0.1 seconds, powers it back on, and waits another 0.1 seconds to ensure stabilization.

Return type:

None

Returns:

None

Example

>>> ft = FlashTool()
>>> ft.encoder_power_cycle()
encoder_power_off()#

Powers off the encoder on channel 2.

Sends a POWER_OFF command to the BiSS encoder connected to channel 2 of the FlashTool device.

Return type:

None

Returns:

None

Example

>>> ft = FlashTool()
>>> ft.encoder_power_off()
encoder_power_on()#

Powers on the encoder on channel 2.

Sends a POWER_ON command to the BiSS encoder connected to channel 2 of the FlashTool device.

Return type:

None

Returns:

None

Example

>>> ft = FlashTool()
>>> ft.encoder_power_on()
flashtool_rst()#

Resets the FlashTool device.

Sends a RESET command to the FlashTool, reinitializing its internal state.

Return type:

None

Returns:

None

Example

>>> ft = FlashTool()
>>> ft.flashtool_rst()
hex_line_send(hex_line)#

Sends a hex-formatted line to the FlashTool device.

Converts the provided hex line (starting with ‘:’) to bytes and transmits it to the FlashTool device via the serial port.

Parameters:

hex_line (str) – A string representing a hex line, including the leading ‘:’.

Returns:

The transmitted bytes.

Return type:

bytes

Example

>>> ft = FlashTool()
>>> ft.hex_line_send(':0100400C0AA9')
b'\x01\x00@\x0c\n\xa9'
port_read(length)#

Reads data from the serial port and validates it with a checksum check.

Waits for the specified number of data bytes plus a checksum byte, reads the data, and verifies the checksum. Logs the received data and checksum status, returning the data as a NumPy array.

Parameters:

length (int) – The number of data bytes to read (excluding the checksum byte).

Returns:

A NumPy array of uint8 values containing the received data (excluding header and checksum).

Return type:

np.ndarray

Raises:

FlashToolError – If the data is not received within the timeout period or if checksum validation fails.

Example

>>> ft = FlashTool()
>>> data = ft.port_read(10)
>>> print(data)
array([0x01, 0x02, ..., 0x0A], dtype=uint8)
read_data(read_time)#

Reads encoder data via SPI over USB for a specified duration.

Sends a command to read data, collects incoming packets, validates them with checksums, and extracts encoder values. Prints progress indicators during reading.

Parameters:

read_time (float) – The duration in seconds to read data.

Returns:

A NumPy array of int32 values containing the encoder readings.

Return type:

np.ndarray

Raises:

ValueError – If a checksum or command error occurs in the received data.

Example

>>> ft = FlashTool()
>>> data = ft.read_data(2.0)
Read USB data for 2.0 seconds: ..... OK!
>>> print(data)
array([12345, 12346, ...], dtype=int32)
read_data_enc1_AB_enc2_SPI(read_time, status=True)#

Read data from Encoder SPI (SIB, IRS) and AB over USB for a specified duration.

Sends a command to read data from both encoders, processes incoming packets, validates checksums, and extracts encoder values for both channels. Optionally prints progress indicators.

Data frame: 6 bytes 0 byte 1 byte 2 byte 3 byte 4 byte 5 byte Enc2 *256 *65536 Cou Enc1 *256

Returns:

Two np.ndarrays containing:
  • Encoder2 data.

  • Encoder1 data.

Return type:

tuple[np.ndarray, np.ndarray]

Raises:

ValueError – If a checksum or command error occurs in the received data.

read_data_enc1_enc2_SPI(read_time, status=True)#

Reads data from two encoders via SPI over USB for a specified duration.

Sends a command to read data from both encoders, processes incoming packets, validates checksums, and extracts encoder values for both channels. Optionally prints progress indicators.

Parameters:
  • read_time (float) – The duration in seconds to read data.

  • status (bool) – If True, prints progress indicators (dots and status messages). Defaults to True.

Returns:

Two lists containing the readings from encoder 1 and encoder 2, respectively.

Return type:

Tuple[List[int], List[int]]

Raises:

ValueError – If a checksum or command error occurs in the received data.

Example

>>> ft = FlashTool()
>>> enc1, enc2 = ft.read_data_enc1_enc2_SPI(2.0)
Read USB data for 2.0 seconds: ..... OK!
>>> print(enc1[:5], enc2[:5])
[12345, 12346, ...], [54321, 54322, ...]
register_cleanup(handler)#

Registers a cleanup function to be executed during close or on SIGINT.

Allows scripts to define custom cleanup operations, such as resetting hardware states or closing additional resources, which are called when the FlashTool connection is closed.

Parameters:

handler (Callable[[], None]) – A callable with no arguments that performs cleanup operations.

Returns:

The FlashTool instance for method chaining.

Return type:

FlashTool

Example

>>> def custom_cleanup():
...     elmo.motor_off()
...     print("Cleaning up resources. Stopping motor.")
>>> ft = FlashTool().register_cleanup(custom_cleanup)
select_FlashTool_mode(mode)#

Select FlashTool mode.

Sends a SELECT Flashtool mode command to the FlashTool.

There are three modes:

0 –> BISS_MODE_SPI_SPI. 1 –> BISS_MODE_AB_UART. 2 –> BISS_MODE_SPI_UART_IRS. 3 –> BISS_MODE_AB_SPI.

Parameters:

mode (uint8) – The mode number (must be 0, 1, 2, 3).

Returns:

None

Raises:

ValueError – If the mode is not 0, 1, 2, 3.

Example

>>> ft = FlashTool()
>>> ft.select_FlashTool_mode(0)
select_SPI_channel(channel)#

Select SPI communication channel.

Sends a SELECT CHANNEL command to the FlashTool.

There are two channels:

0 –> channel 1; 1 –> channel 2.

Parameters:

channel (uint8) – The channel number (must be 0 or 1).

Return type:

None

Returns:

None

Raises:

ValueError – If the mode is not 0 or 1.

Example

>>> ft = FlashTool()
>>> ft.select_SPI_channel(0)
send_data_to_device(pages, crc_values, page_numbers, start_page, end_page, pbar=None, difmode=False)#

Transmits organized data pages to the BiSS encoder with CRC verification.

Sends pages of data to the encoder, writing CRC and page numbers as needed, and verifies each page with a flash CRC check. Supports a progress bar and differential mode for specific use cases.

Parameters:
  • pages (List[List[bytes]]) – A list of pages, where each page is a list of byte arrays.

  • crc_values (List[int]) – A list of CRC checksums for each page.

  • page_numbers (List[int]) – A list of page numbers corresponding to each page.

  • start_page (int) – The index of the first page to transmit.

  • end_page (int) – The index of the last page to transmit.

  • pbar (Optional[Any]) – An optional progress bar object for tracking transmission progress.

  • difmode (bool) – If True, uses differential table transmission mode. Defaults to False.

Raises:
  • SystemExit – If transmission fails after the maximum number of retries.

  • FlashToolError – If a hardware communication error occurs.

Return type:

None

Example

>>> ft = FlashTool()
>>> pages = [[b'\x01\x02', b'\x03\x04'], [b'\x05\x06', b'\x07\x08']]
>>> crc_values = [0x1234, 0x5678]
>>> page_numbers = [1, 2]
>>> ft.send_data_to_device(pages, crc_values, page_numbers, 0, 1)
INFO: Done uploading!
exception lenz_flashtool.flashtool.FlashToolError#

Bases: Exception

Custom exception for FlashTool errors.

Raised when a critical error occurs within the FlashTool library.

class lenz_flashtool.flashtool.UartCmd(*values)#

Bases: IntEnum

Enumeration of UART commands for communication with the FlashTool system.

This class defines all the hexadecimal command codes used for controlling power, channel selection, and data communication with the FlashTool hardware.

CMD_CH1_POWER_OFF = 8#

Command to power off encoder on channel 1.

Usage:
  • Sent to deactivate power to the secondary encoder (channel 1)

  • Useful for power management in dual-encoder systems

  • Typically used during maintenance or reconfiguration

  • Expects no additional parameters

Packet Structure:

Request: [DUMMY_DATA_SIZE][REG_ADDR][0x08][DUMMY_DATA][CHECKSUM] Response: None

Examples

>>>  :01004008DDDA
>>>  :04000008DDAADDAAE6
Type:

int

CMD_CH1_POWER_ON = 9#

Command to power on the encoder on channel 1.

Usage:
  • Sent to activate power to the secondary encoder (channel 1)

  • Should be preceded by channel selection if needed

  • Requires stabilization time (0.1s) before encoder communication

  • Expects no additional parameters

Packet Structure:

Request: [DUMMY_DATA_SIZE][REG_ADDR][0x09][DUMMY_DATA][CHECKSUM] Response: None

Examples

>>>  :0100000903F3
>>>  :0300A009A0A0A173
Type:

int

CMD_NVRST = 131#

Command to perform a non-volatile reset of the FlashTool.

Usage:
  • Clears any temporary settings

  • Requires stabilization time (0.1s) before encoder communication

  • Data and address in packet doesn’t matter

Packet Structure:

Request: [DUMMY_DATA_SIZE][REG_ADDR][0x83][DUMMY_DATA][CHECKSUM] Response: None

Examples

>>>  :01004083221A
>>>  :0400408311111111F5
Type:

int

CMD_POWER_OFF = 11#

Command to power off encoder on channel 2.

Usage:
  • Sent to deactivate power to the encoder connected to channel 2

  • Typically used during maintenance or reconfiguration

  • Expects no additional parameters

  • Data and address in packet doesn’t matter

Packet Structure:

Request: [DUMMY_DATA_SIZE][REG_ADDR][0x0B][DUMMY_DATA][CHECKSUM] Response: None

Examples

>>>  :0100400BFFB5
>>>  :0400400B111111116D
Type:

int

CMD_POWER_ON = 12#

Command to power on the encoder on channel 2.

Usage:
  • Sent to activate power to the encoder connected to channel 2

  • Should be followed by a stabilization delay (0.1s) before communication

  • Expects no additional parameters

  • Data and address in packet doesn’t matter

Packet Structure:

Request: [DUMMY_DATA_SIZE][REG_ADDR][0x0C][DUMMY_DATA][CHECKSUM] Response: None

Examples

>>>  :0100400C0AA9
>>>  :0300400CAABBCC80
Type:

int

CMD_SELECT_FLASHTOOL_MODE = 1#

Command to select FlashTool mode for communication.

Usage:
  • Sent before any channel-specific operations

  • Parameter:

    0x00 for BISS_MODE_SPI_SPI, 0x01 for BISS_MODE_AB_UART, 0x02 for BISS_MODE_SPI_UART_IRS, 0x03 for BISS_MODE_AB_SPI

  • Defines all subsequent communications via SPI, AB (incremental), UART for channels 1 and 2 until changed

  • Address in packet doesn’t matter

Note

FlashTool mode is persistent until changed or power cycled Default: BISS_MODE_SPI_SPI (0x00)

Packet Structure:

Request: [01][REG_ADDR][0x01][CHANNEL_BYTE][CHECKSUM] Where CHANNEL_BYTE is 0x00, 0x01, 0x02 or 0x03

Example

>>> :0100000100FE  Select FlashTool mode - BISS_MODE_SPI_SPI
Type:

int

CMD_SELECT_SPI_CH = 10#

Command to select SPI communication channel.

Usage:
  • Sent before any channel-specific operations

  • Parameter: 0x00 for channel 1, 0x01 for channel 2

  • Affects all subsequent SPI communications until changed

Note

Channel selection is persistent until changed or power cycled Default: Channel 2 (0x01)

Packet Structure:

Request: [01][REG_ADDR][0x0A][CHANNEL_BYTE][CHECKSUM] Where CHANNEL_BYTE is 0x00 or 0x01

Example

>>> :0100400A00F4  Select channel 1
Type:

int

HEX_READ_ANGLE_TWO_ENC_AB_SPI = 120#

Command to read angle data via AB (incremental) interface over SPI.

Usage:
  • SPI angle reading

  • Provides quadrature-encoded equivalent output

Note

channel 1 - AB channel 2 - SPI

Type:

int

HEX_READ_ANGLE_TWO_ENC_AB_UART = 121#

Command to read angle data via AB (incremental) interface over UART.

Usage:
  • Alternative to SPI angle reading

  • Provides quadrature-encoded equivalent output

  • Faster update rate than SPI in some implementations

Type:

int

HEX_READ_ANGLE_TWO_ENC_SPI = 128#

Command to read angle data from two encoders via SPI.

Usage:
  • Continuous streaming mode for dual-encoder reading

  • Requires both encoders to be powered on

  • Returns multiple measurement frames in each response packet

Response Format:

Each 245-byte packet contains:

>>> [Header][FrameCount][Reserved][DataFrames...][Checksum]

Where:

  • Header: [0xF0, 0x00, 0x00, 0x90] (fixed pattern)

  • FrameCount: Number of valid data frames (typically 30)

  • DataFrames: 30 measurement frames (8 bytes each):

>>> [ENC1_LOW][ENC1_MID][ENC1_HIGH][ENC1_COUNTER]
>>> [ENC2_LOW][ENC2_MID][ENC2_HIGH][ENC2_COUNTER]
  • Checksum: 1 byte (sum of first 244 bytes modulo 256)

Data Interpretation:
>>> Encoder Angle = (HIGH << 16) | (MID << 8) | LOW

Counter = Single byte turn counter

Example Packet Structure:
>>> F0 00 00 90 [30 frames...] [checksum]
Type:

int

HEX_READ_CMD = 130#

Generic read command for encoder data.

Usage:
  • Followed by register address and dummy data with size equal to required read data size

  • Can read various status and configuration registers

  • Response length depends on target register

Packet Structure:
  • Request: [DUMMY_DATA_SIZE][REG_ADDR][0x82][DUMMY_DATA][CHECKSUM]

  • Response: [DATA_SIZE][REG_ADDR][0x92][DATA][CHECKSUM]

Examples

Read Example:
>>>  :01004082013C
Response:
>>>  0x10040920528

Another example writing 3 to BSEL register (changing BiSS Bank to 3):

Requests:
>>>  :0100400D03AF  Writing 3 to register 0x40
>>>  :01004082013C  Reading register 0x40
Response:
>>>  0x1004092032A  Register 0x40 keeps 0x03
Type:

int

HEX_WRITE_CMD = 13#

Command to write data to encoder registers.

Usage:
  • Used for configuration and parameter setting

Packet Structure:

Request: [DATA_SIZE][REG_ADDR][0x0D][DATA_MSB][DATA_LSB][CHECKSUM] Response: None

Example

>>>  :0100400D05AD
Type:

int

lenz_flashtool.flashtool.biss_send_dif(file_path, pbar=None)#

Main function for transmitting DIF tables to BiSS device.

Parameters:
  • file_path (str) – Path to input DIF CSV file

  • pbar (Optional[Any]) – Optional progress bar object

Return type:

None

lenz_flashtool.flashtool.biss_send_hex(file_path, nonce=None, pbar=None)#

Main function for transmitting HEX files to BiSS device.

Parameters:
  • file_path (str) – Path to input HEX file

  • nonce (Optional[int]) – Optional security nonce value

  • pbar (Optional[Any]) – Optional progress bar object

Return type:

None

lenz_flashtool.flashtool.calculate_checksum(hex_data)#

Calculate Intel HEX-style checksum for a hex string.

Parameters:

hex_data (str) – Hex string without leading ‘:’ or ending checksum

Return type:

int

Returns:

Checksum byte (0-255)

Example

>>> calculate_checksum("10010000214601360121470136007EFE09D21901")
64
lenz_flashtool.flashtool.generate_hex_line(address, command, data)#

Generate a formatted hex line for communication with a device.

Parameters:
  • address (int) – The 16-bit address field.

  • command (int) – The command byte.

  • data (List[int]) – A list of data bytes to include in the hex line.

Returns:

The formatted hex line string, including the starting ‘:’ and checksum.

Return type:

str

lenz_flashtool.flashtool.get_nonce(filename)#

Retrieve the nonce values from a binary file.

Parameters:

filename (str) – The base filename (without extension) of the nonce file.

Returns:

A list of 32-bit unsigned integers representing the nonces.

Return type:

List[int]

lenz_flashtool.flashtool.init_logging(logfilename=None, stdout_level=20, file_level=10, logger_name='lenz_flashtool')#

Initializes the logging system with console and optional file handlers.

This function sets up a logger with a stdout handler and, if a filename is provided, a file handler. Each handler has its own logging level and formatter.

Parameters:
  • logfilename (Optional[str]) – The name of the file to log messages to. If None, no file logging occurs.

  • stdout_level (int) – The logging level for the stdout handler (default: INFO).

  • file_level (int) – The logging level for the file handler (default: DEBUG).

  • logger_name (str) – The name of the logger to configure (default: “lenz_flashtool”). If None, the root logger is configured.

Returns:

The configured logger instance.

Return type:

logging.Logger

Raises:

ValueError – If logging levels are invalid.