def set_mode(self, device_sn, nmbed=1):
        """`set_mode`.

        This function is used to temporarily set the EDBG to a specified mode.

        `int set_mode(char* sn, int nmbed)`

        +------------+------------+
        | Parameter  | Description |
        +============+============+
        | *sn* | Serial number of the device to set |
        | *nmbed* | 0 - Set to mbed mode. 1 - Set to DGI mode |
        +------------+------------+

        :param device_sn: Serial number of the device to set
        :type device_sn: str
        :param nmbed: 0 - Set to mbed mode. 1 - Set to DGI mode (defaults to
            DGI mode)
        :type nmbed: int
        :raises: :exc:`DeviceReturnError`
        """
        res = self.dgilib.set_mode(device_sn, nmbed)
        if self.verbose:
            print(f"\t{res} set_mode {nmbed}")
        if res:
            raise DeviceReturnError(f"set_mode returned: {res}")
    def get_device_serial(self, index=0):
        """`get_device_serial`.

        Gets the serial number of a detected device.

        `int get_device_serial(int index, char* sn)`

        +------------+------------+
        | Parameter  | Description |
        +============+============+
        | *index* | Index of device ranges from 0 to `get_device_count` - 1 |
        | *sn* | Pointer to buffer where the serial number of the device can
        be stored. 100 or more bytes must be allocated. This is used when
        connecting to a device |
        +------------+------------+

        :param index: Index of device ranges from 0 to `get_device_count` - 1
        :type index: int
        :return: The serial number of a detected device
        :rtype: str
        :raises: :exc:`DeviceReturnError`
        """
        device_sn = create_string_buffer(GET_STRING_SIZE)
        res = self.dgilib.get_device_serial(index, byref(device_sn))
        if self.verbose:
            print(f"\t{res} get_device_serial: {device_sn.value}")
        if res:
            raise DeviceReturnError(f"get_device_serial returned: {res}")
        return device_sn.value
    def connect(self, device_sn):
        """`connect`.

        Opens a connection to the specified device. This function must be
        called prior to any function requiring the connection handle.

        `int connect(char* sn, uint32_t* dgi_hndl_p)`

        +------------+------------+
        | Parameter  | Description |
        +============+============+
        | *sn* | Buffer holding the serial number of the device to open a
        connection to |
        | *dgi_hndl_p* | Pointer to a variable that will hold the handle of the
        connection |
        +------------+------------+

        :param device_sn: Serial number of the device
        :type device_sn: str
        :return: Variable that holds the handle of the connection
        :rtype: c_uint()
        :raises: :exc:`DeviceReturnError`
        """
        dgi_hndl = c_uint()  # Create the dgi_hndl

        # Initialize (not in manual, exists in dgilib.h)
        # self.dgilib.Initialize(byref(dgi_hndl))

        res = self.dgilib.connect(device_sn, byref(dgi_hndl))
        if self.verbose:
            print(f"\t{res} connect")
        if res:
            raise DeviceReturnError(f"connect returned: {res}")

        return dgi_hndl
    def auxiliary_power_initialize(self):
        """`auxiliary_power_initialize`.

        Initializes the power parser.

        `int auxiliary_power_initialize(uint32_t* power_hndl_p, uint32_t
        dgi_hndl)`

        +------------+------------+
        | Parameter  | Description |
        +============+============+
        | *power_hndl_p* | Pointer to variable that will hold the handle to
        the power parser |
        | *dgi_hndl* | Handle of the connection |
        +------------+------------+

        :return: Handle of the power parser
        :rtype: c_uint()
        :raises: :exc:`DeviceReturnError`
        """
        power_hndl = c_uint()

        res = self.dgilib.auxiliary_power_initialize(byref(power_hndl),
                                                     self.dgi_hndl)
        if self.verbose:
            print(f"\t{res} auxiliary_power_initialize")
        if res:
            raise DeviceReturnError(
                f"auxiliary_power_initialize returned: {res}")

        return power_hndl
    def interface_set_configuration(self, interface_id, config_id,
                                    config_value):
        """`interface_set_configuration`.

        Sets the given configuration fields for the specified interface.
        Consult the DGI documentation for details.

        `int interface_set_configuration(uint32_t dgi_hndl, int interface_id,
        unsigned int* config_id, unsigned int* config_value, unsigned int
        config_cnt)`

        +------------+------------+
        | Parameter  | Description |
        +============+============+
        | *dgi_hndl* | Handle to connection |
        | *interface_id* | The ID of the interface |
        | *config_id* | Buffer that holds the ID field for the configuration
        items to set |
        | *config_value* | Buffer that holds the value field for the
        configuration items to set |
        | *config_cnt* | Number of items to set |
        +------------+------------+

        :param interface_id: The ID of the interface
        :type interface_id: int
        :param config_id: List that holds the ID field for the configuration
            items to set
        :type config_id: list(int)
        :param config_value: List that holds the value field for the
            configuration items to set (must have the same number of elements
        as config_id)
        :type config_value: list(int)
        :raises: :exc:`DeviceArgumentError`
        :raises: :exc:`DeviceReturnError`
        """
        if len(config_id) == len(config_value):
            config_cnt = c_uint(len(config_id))
        else:
            raise DeviceArgumentError(
                f"interface_set_configuration: the length of config_id list "
                f"({len(config_id)}) is not equal to the length of "
                f"config_value list ({len(config_value)})")

        config_id = (c_uint * NUM_CONFIG_IDS)(*config_id)
        config_value = (c_uint * NUM_CONFIG_IDS)(*config_value)
        res = self.dgilib.interface_set_configuration(self.dgi_hndl,
                                                      interface_id,
                                                      byref(config_id),
                                                      byref(config_value),
                                                      config_cnt)
        if self.verbose:
            print(f"\t{res} interface_set_configuration: {interface_id}, "
                  f"config_cnt: {config_cnt.value}")
            if self.verbose >= 2:
                for i in range(config_cnt.value):
                    print(f"\t\tconfig_id: {config_id[i]},\tvalue: "
                          f"{config_value[i]}")
        if res:
            raise DeviceReturnError(
                f"interface_set_configuration: {interface_id} returned: {res}")
    def get_device_name(self, index=0):
        """`get_device_name`.

        Gets the name of a detected device.

        `int get_device_name(int index, char* name)`

        +------------+------------+
        | Parameter  | Description |
        +============+============+
        | *index* | Index of device ranges from 0 to `get_device_count` - 1 |
        | *name* | Pointer to buffer where name of device can be stored. 100
        or more bytes must be allocated |
        +------------+------------+

        :param index: Index of device ranges from 0 to `get_device_count` - 1
        :type index: int
        :return: The name of a detected device
        :rtype: str
        :raises: :exc:`DeviceReturnError`
        """
        name = create_string_buffer(GET_STRING_SIZE)
        res = self.dgilib.get_device_name(index, byref(name))
        if self.verbose:
            print(f"\t{res} get_device_name: {name.value}")
        if res:
            raise DeviceReturnError(f"get_device_name returned: {res}")
        return name.value
    def start_polling(self):
        """`start_polling`.

        This function will start the polling system and start acquisition on
        enabled interfaces. It is possible to enable/disable interfaces both
        before and after the polling has been started. However, no data will be
        transferred until the polling is started.

        `int start_polling(uint32_t dgi_hndl)`

        +------------+------------+
        | Parameter  | Description |
        +============+============+
        | *dgi_hndl* | Handle of the connection |
        +------------+------------+

        :param dgi_hndl: Handle of the connection
        :type dgi_hndl: c_uint()
        :raises: :exc:`DeviceReturnError`
        """
        res = self.dgilib.start_polling(self.dgi_hndl)
        if self.verbose:
            print(f"\t{res} start_polling")
        if res:
            raise DeviceReturnError(f"start_polling returned: {res}")
    def auxiliary_power_lock_data_for_reading(self):
        """`auxiliary_power_lock_data_for_reading`.

        Blocks the parsing thread from accessing all the buffers. This must be
        called before the user application code accesses the buffers, or a
        call to `auxiliary_power_copy_data` is made. Afterwards
        `auxiliary_power_free_data` must be called. Minimize the amount of
        time between locking and freeing to avoid buffer overflows.

        `int auxiliary_power_lock_data_for_reading(uint32_t power_hndl)`

        +------------+------------+
        | Parameter  | Description |
        +============+============+
        | *power_hndl* | Handle of the power parser |
        +------------+------------+

        :raises: :exc:`DeviceReturnError`
        """
        res = self.dgilib.auxiliary_power_lock_data_for_reading(
            self.power_hndl)
        if self.verbose:
            print(f"\t{res} auxiliary_power_lock_data_for_reading")
        if res:
            raise DeviceReturnError(
                f"auxiliary_power_lock_data_for_reading returned: {res}")
    def interface_enable(self, interface_id, timestamp=True):
        """`interface_enable`.

        Enables the specified interface. Note that no data acquisition will
        begin until a session has been started.

        `int interface_enable(uint32_t dgi_hndl, int interface_id, bool
        timestamp)`

        +------------+------------+
        | Parameter  | Description |
        +============+============+
        | *dgi_hndl* | Handle of the connection |
        | *interface_id* | The ID of the interface to enable. |
        | *timestamp* | Setting this to true will make the interface use
        timestamping. Consult the DGI documentation for details on the
        timestamping option. |
        +------------+------------+

        :param interface_id: The ID of the interface to enable
        :type interface_id: int
        :param timestamp: Setting this to true will make the interface use
            timestamping (defaults to True)
        :type timestamp: bool
        :raises: :exc:`DeviceReturnError`
        """
        res = self.dgilib.interface_enable(self.dgi_hndl, interface_id,
                                           timestamp)
        if self.verbose:
            print(f"\t{res} interface_enable: {interface_id}, timestamp: "
                  f"{timestamp}")
        if res:
            raise DeviceReturnError(
                f"interface_enable: {interface_id}, timestamp: {timestamp} "
                f"returned: {res}")
    def auxiliary_power_get_circuit_type(self):
        """`auxiliary_power_get_circuit_type`.

        Gets the type of power circuit.

        `int auxiliary_power_get_circuit_type(uint32_t power_hndl, int*
        circuit)`

        +------------+------------+
        | Parameter  | Description |
        +============+============+
        | *power_hndl* | Handle of the power parser |
        | *circuit* | Pointer to a variable that will hold the circuit type:
        OLD_XAM = 0x00, XAM = 0x10, PAM = 0x11, UNKNOWN = 0xFF |
        +------------+------------+

        :return: The circuit type: OLD_XAM = 0x00, XAM = 0x10, PAM = 0x11,
            UNKNOWN = 0xFF
        :rtype: int
        :raises: :exc:`DeviceReturnError`
        """
        circuit = c_int()
        res = self.dgilib.auxiliary_power_get_circuit_type(
            self.power_hndl, byref(circuit))
        if self.verbose:
            print(f"\t{res} auxiliary_power_get_circuit_type: {circuit.value}")
        if res:
            raise DeviceReturnError(
                f"auxiliary_power_get_circuit_type: {circuit.value} returned: "
                f"{res}")

        return circuit.value
    def auxiliary_power_trigger_calibration(self, circuit_type=XAM):
        """`auxiliary_power_trigger_calibration`.

        Triggers a calibration of the specified type. This can take some time,
        so use `auxiliary_power_get_status` to check for completion.

        `int auxiliary_power_trigger_calibration(uint32_t power_hndl, int type)
        `

        +------------+------------+
        | Parameter  | Description |
        +============+============+
        | *power_hndl* | Handle of the power parser |
        | *type* | Type of calibration to trigger. See the DGI documentation
        for details. |
        +------------+------------+

        :param circuit_type: Type of calibration to trigger (defaults to XAM)
        :type circuit_type: int
        :raises: :exc:`DeviceReturnError`
        """
        circuit_type = c_int(circuit_type)
        res = self.dgilib.auxiliary_power_trigger_calibration(
            self.power_hndl, circuit_type)
        if self.verbose:
            print(f"\t{res} auxiliary_power_trigger_calibration")
        if res:
            raise DeviceReturnError(
                f"auxiliary_power_trigger_calibration returned: {res}")
    def interface_read_data(self, interface_id):
        """`interface_read_data`.

        Reads the data received on the specified interface. This should be
        called regularly to avoid overflows in the system. DGILib can buffer
        10M samples.

        `int interface_read_data(uint32_t dgi_hndl, int interface_id, unsigned
        char* buffer, unsigned long long* timestamp, int* length, unsigned int*
        ovf_index, unsigned int* ovf_length, unsigned int* ovf_entry_count)`

        +------------+------------+
        | Parameter  | Description |
        +============+============+
        | *dgi_hndl* | Handle of the connection |
        | *interface_id* | The ID of the interface |
        | *buffer* | Buffer that will hold the received data. The buffer must
        have allocated 10M elements. |
        | *timestamp* | If timestamp is enabled for the interface, the buffer
        that will hold the received data. The buffer must have allocated 10M
        elements. Otherwise send 0. |
        | *length* | Pointer to a variable that will hold the count of
        elements received |
        | *ovf_index* | Reserved. Set to 0. |
        | *ovf_length* | Reserved. Set to 0. |
        | *ovf_entry_count* | Reserved. Set to 0. Could be set to a pointer to
        a variable that can be used as an indicator of overflows. Overflow
        would be indicated by non-zero value. |
        +------------+------------+

        :param interface_id: The ID of the interface
        :type interface_id: int
        :return: Tuple of a list of received values and a list of ticks
        :rtype: tuple(list(int), list(int))
        :raises: :exc:`DeviceReturnError`
        """
        buffer = (c_ubyte * BUFFER_SIZE)()
        ticks = (c_ulonglong * BUFFER_SIZE)()
        length = c_uint(0)
        ovf_index = c_uint(0)
        ovf_length = c_uint(0)
        ovf_entry_count = c_uint(0)
        res = self.dgilib.interface_read_data(self.dgi_hndl, interface_id,
                                              buffer, ticks, byref(length),
                                              byref(ovf_index),
                                              byref(ovf_length),
                                              byref(ovf_entry_count))
        if self.verbose:
            print(f"\t{res} interface_read_data: {interface_id}, length: "
                  f"{length.value}")
            if self.verbose >= 2:
                for i in range(length.value):
                    print(f"\t{i}:\tbuffer: {buffer[i]},\ttick: {ticks[i]}")
        if res:
            raise DeviceReturnError(
                f"interface_read_data: {interface_id} returned: {res}")

        return ticks[:length.value], buffer[:length.value]
    def interface_get_configuration(self, interface_id):
        """`interface_get_configuration`.

        Gets the configuration associated with the specified interface.
        Consult the DGI documentation for details.

        `int interface_get_configuration(uint32_t dgi_hndl, int interface_id,
        unsigned int* config_id, unsigned int* config_value, unsigned int*
        config_cnt)`

        +------------+------------+
        | Parameter  | Description |
        +============+============+
        | *dgi_hndl* | Handle to connection |
        | *interface_id* | The ID of the interface |
        | *config_id* | Buffer that will hold the ID field for the
        configuration item |
        | *config_value* | Buffer that will hold the value field for the
        configuration item |
        | *config_cnt* | Pointer to variable that will hold the count of stored
        configuration items |
        +------------+------------+

        :param interface_id: The ID of the interface
        :type interface_id: int
        :return: Tuple of a list of configuration IDs and a list of
            configuration values
        :rtype: tuple(list(int), list(int))
        :raises: :exc:`DeviceReturnError`
        """
        config_id = (c_uint * NUM_CONFIG_IDS)()
        config_value = (c_uint * NUM_CONFIG_IDS)()
        config_cnt = c_uint()
        res = self.dgilib.interface_get_configuration(self.dgi_hndl,
                                                      interface_id,
                                                      byref(config_id),
                                                      byref(config_value),
                                                      byref(config_cnt))
        if self.verbose:
            print(f"\t{res} interface_get_configuration: {interface_id}, "
                  f"config_cnt: {config_cnt.value}")
            if self.verbose >= 2:
                for i in range(config_cnt.value):
                    print(f"\t\tconfig_id: {config_id[i]},\tvalue: "
                          f"{config_value[i]}")
        if res:
            raise DeviceReturnError(
                f"\t{res} interface_get_configuration: {interface_id}, "
                f"config_cnt: {config_cnt.value} returned: {res}")

        return config_id[:config_cnt.value], config_value[:config_cnt.value]
    def auxiliary_power_start(self, mode=0, parameter=0):
        """`auxiliary_power_start`.

        Starts parsing of power data. The power and power sync interfaces are
        enabled automatically, but note that it is necessary to start the
        polling separately. This only starts the parser that consumes data
        from the DGILib buffer.

        `int auxiliary_power_start(uint32_t power_hndl, int mode, int
        parameter)`

        +------------+------------+
        | Parameter  | Description |
        +============+============+
        | *power_hndl* | Handle of the power parser |
        | *mode* | Sets the mode of capture. |
        |  | 0 - continuous capturing which requires the user to periodically
        consume the data. |
        |  | 1 - oneshot capturing that captures data until the buffer has
        been read once, has been filled or the time from the first received
        sample in seconds equals the specified parameter. |
        | *parameter* | Mode specific |
        +------------+------------+

        :param mode: Sets the mode of capture (defaults to 0)
            - 0: continuous capturing which requires the user to periodically
                consume the data
            - 1: oneshot capturing that captures data until the buffer has
            been read once, has been filled or the time from the first
                received sample in seconds equals the specified parameter
        :type mode: int
        :param parameter: Mode specific (defaults to 0)
        :type parameter: int or None
        :raises: :exc:`DeviceReturnError`
        """
        mode = c_int(mode)
        parameter = c_int(parameter)
        res = self.dgilib.auxiliary_power_start(self.power_hndl, mode,
                                                parameter)
        if self.verbose:
            print(f"\t{res} auxiliary_power_start, mode: {mode.value}, "
                  f"parameter: {parameter.value}")
        if res:
            raise DeviceReturnError(
                f"auxiliary_power_start, mode: {mode.value}, parameter: "
                f"{parameter.value} returned: {res}")
    def interface_write_data(self, interface_id, buffer):
        """`interface_write_data`.

        Writes data to the specified interface. A maximum of 255 elements can
        be written each time. An error return code will be given if data
        hasn't been written yet.

        TODO: A non-zero return value indicates an error. An error will be
        returned if the interface is still in the process of writing data.
        Wait a while and try again. The function get_connection_status can be
        used to verify if there is an error condition.

        `int interface_write_data(uint32_t dgi_hndl, int interface_id,
        unsigned char* buffer, int* length)`

        +------------+------------+
        | Parameter  | Description |
        +============+============+
        | *dgi_hndl* | Handle of the connection |
        | *interface_id* | The ID of the interface |
        | *buffer* | Buffer that holds the data to write. The buffer must have
        allocated 10M elements |
        | *length* | Pointer to a variable that will hold the count of
        elements received |
        +------------+------------+

        :param interface_id: The ID of the interface
        :type interface_id: int
        :param buffer: Buffer that holds the data to write (defaults to None)
        :type buffer: int
        :raises: :exc:`DeviceReturnError`
        """
        length = c_uint(len(buffer))
        buffer = (c_ubyte * BUFFER_SIZE)(*buffer)
        res = self.dgilib.interface_write_data(self.dgi_hndl, interface_id,
                                               byref(buffer), byref(length))
        if self.verbose:
            print(f"\t{res} interface_write_data: {interface_id}, length: "
                  f"{length.value}")
            if self.verbose >= 2:
                for i in range(length.value):
                    print(f"\t{i}:\tbuffer: {buffer[i]}")
        if res:
            raise DeviceReturnError(
                f"TODO: interface_write_data: {interface_id} returned: {res}")
    def auxiliary_power_stop(self):
        """`auxiliary_power_stop`.

        Stops parsing of power data.

        `int auxiliary_power_stop(uint32_t power_hndl)`

        +------------+------------+
        | Parameter  | Description |
        +============+============+
        | *power_hndl* | Handle of the power parser |
        +------------+------------+

        :raises: :exc:`DeviceReturnError`
        """
        res = self.dgilib.auxiliary_power_stop(self.power_hndl)
        if self.verbose:
            print(f"\t{res} auxiliary_power_stop")
        if res:
            raise DeviceReturnError(f"auxiliary_power_stop returned: {res}")
    def disconnect(self):
        """`disconnect`.

        Closes the specified connection.

        `int disconnect(uint32_t dgi_hndl)`

        +------------+------------+
        | Parameter  | Description |
        +============+============+
        | *dgi_hndl* | Handle of the connection |
        +------------+------------+

        :raises: :exc:`DeviceReturnError`
        """
        res = self.dgilib.disconnect(self.dgi_hndl)
        if self.verbose:
            print(f"\t{res} disconnect")
        if res:
            raise DeviceReturnError(f"disconnect returned: {res}")
    def auxiliary_power_unregister_buffer_pointers(self,
                                                   channel=0,
                                                   power_type=0):
        """`auxiliary_power_unregister_buffer_pointers`.

        Unregisters the pointers for the specified power channel.

        `int auxiliary_power_unregister_buffer_pointers(uint32_t power_hndl,
        int channel, int type)`

        +------------+------------+
        | Parameter  | Description |
        +============+============+
        | *power_hndl* | Handle of the power parser |
        | *channel* | Power channel for this buffer: A = 0, B = 1 (Power
        Debugger specific) |
        | *type* | Type of power data: Current = 0, Voltage = 1, Range = 2 |
        +------------+------------+

        :param channel: Power channel for this buffer: A = 0, B = 1 (defaults
            to 0)
        :type channel: int
        :param power_type: Type of power data: Current = 0, Voltage = 1,
            Range = 2 (defaults to 0)
        :type power_type: int
        :raises: :exc:`DeviceReturnError`
        """
        channel = c_int(channel)
        power_type = c_int(power_type)

        res = self.dgilib.auxiliary_power_unregister_buffer_pointers(
            self.power_hndl, channel, power_type)
        if self.verbose:
            print(
                f"\t{res} auxiliary_power_unregister_buffer_pointers, channel:"
                f" {channel.value}, power_type: {power_type.value}")
        if res:
            raise DeviceReturnError(
                f"auxiliary_power_unregister_buffer_pointers, channel: "
                f"{channel.value}, power_type: {power_type.value} returned: "
                f"{res}")
    def auxiliary_power_uninitialize(self):
        """`auxiliary_power_uninitialize`.

        Uninitializes the power parser.

        `int auxiliary_power_uninitialize(uint32_t power_hndl)`

        +------------+------------+
        | Parameter  | Description |
        +============+============+
        | *power_hndl* | Handle of the power parser |
        +------------+------------+

        :raises: :exc:`DeviceReturnError`
        """
        res = self.dgilib.auxiliary_power_uninitialize(self.power_hndl)
        if self.verbose:
            print(f"\t{res} auxiliary_power_uninitialize")
        if res:
            raise DeviceReturnError(
                f"auxiliary_power_uninitialize returned: {res}")
    def auxiliary_power_free_data(self):
        """`auxiliary_power_free_data`.

        Clears the power data buffers and allows the power parser to continue.

        `int auxiliary_power_free_data(uint32_t power_hndl)`

        +------------+------------+
        | Parameter  | Description |
        +============+============+
        | *power_hndl* | Handle of the power parser |
        +------------+------------+

        :raises: :exc:`DeviceReturnError`
        """
        res = self.dgilib.auxiliary_power_free_data(self.power_hndl)
        if self.verbose:
            print(f"\t{res} auxiliary_power_free_data")
        if res:
            raise DeviceReturnError(
                f"auxiliary_power_free_data returned: {res}")
    def interface_disable(self, interface_id):
        """`interface_disable`.

        Disables the specified interface.

        `int interface_disable(uint32_t dgi_hndl, int interface_id)`

        +------------+------------+
        | Parameter  | Description |
        +============+============+
        | *dgi_hndl* | Handle of the connection |
        | *interface_id* | The ID of the interface to disable. |
        +------------+------------+

        :param interface_id: The ID of the interface to disable
        :type interface_id: int
        :raises: :exc:`DeviceReturnError`
        """
        res = self.dgilib.interface_disable(self.dgi_hndl, interface_id)
        if self.verbose:
            print(f"\t{res} interface_disable: {interface_id}")
        if res:
            raise DeviceReturnError(f"interface_disable returned: {res}")
    def stop_polling(self):
        """`stop_polling`.

        This function will stop the polling system and stop acquisition on all
        interfaces.

        `int stop_polling(uint32_t dgi_hndl)`

        +------------+------------+
        | Parameter  | Description |
        +============+============+
        | *dgi_hndl* | Handle of the connection |
        +------------+------------+

        :param dgi_hndl: Handle of the connection
        :type dgi_hndl: c_uint()
        :raises: :exc:`DeviceReturnError`
        """
        res = self.dgilib.stop_polling(self.dgi_hndl)
        if self.verbose:
            print(f"\t{res} stop_polling")
        if res:
            raise DeviceReturnError(f"stop_polling returned: {res}")
    def interface_clear_buffer(self, interface_id):
        """`interface_clear_buffer`.

        Clears the data in the buffers for the specified interface.

        `int interface_clear_buffer(uint32_t dgi_hndl, int interface_id)`

        +------------+------------+
        | Parameter  | Description |
        +============+============+
        | *dgi_hndl* | Handle of the connection |
        | *interface_id* | The ID of the interface |
        +------------+------------+

        :param interface_id: The ID of the interface
        :type interface_id: int
        :raises: :exc:`DeviceReturnError`
        """
        res = self.dgilib.interface_clear_buffer(self.dgi_hndl, interface_id)
        if self.verbose:
            print(f"\t{res} interface_clear_buffer: {interface_id}")
        if res:
            raise DeviceReturnError(f"interface_clear_buffer returned: {res}")
    def get_fw_version(self):
        """`get_fw_version`.

        Gets the firmware version of the DGI device connected. Note that this
        is the version of the DGI device, and not the tool.

        `int get_fw_version(uint32_t dgi_hndl, unsigned char* major, unsigned
        char* minor)`

        +------------+------------+
        | Parameter  | Description |
        +============+============+
        | *dgi_hndl* | Handle of the connection |
        | *major* | Pointer to a variable where the major version will be
        stored |
        | *minor* | Pointer to a variable where the minor version will be
        stored |
        +------------+------------+

        :return: Version information of the DGI device:
            - major_fw: the major firmware version of the DGI device connected
            - minor_fw: the minor firmware version of the DGI device connected
        :rtype: tuple(int, int)
        """
        major_fw = c_ubyte()
        minor_fw = c_ubyte()
        res = self.dgilib.get_fw_version(self.dgi_hndl, byref(major_fw),
                                         byref(minor_fw))
        if self.verbose:
            print(f"\t{res} get_fw_version")
        if res:
            raise DeviceReturnError(f"get_fw_version returned: {res}")
        if self.verbose:
            print(f"major_fw: {major_fw.value}\nminor_fw: {minor_fw.value}")

        return major_fw.value, minor_fw.value
    def target_reset(self, hold_reset):
        """`target_reset`.

        This function is used to control the state of the reset line connected
        to the target, if available.

        `int target_reset(uint32_t dgi_hndl, bool hold_reset)`

        +------------+------------+
        | Parameter  | Description |
        +============+============+
        | *dgi_hndl* | Handle of the connection |
        | *hold_reset* | True will assert reset, false will release it |
        +------------+------------+

        :param hold_reset: True will assert reset, False will release it
        :type hold_reset: bool
        :raises: :exc:`DeviceReturnError`
        """
        res = self.dgilib.target_reset(self.dgi_hndl, hold_reset)
        if self.verbose:
            print(f"\t{res} target_reset {hold_reset}")
        if res:
            raise DeviceReturnError(f"target_reset returned: {res}")
    def interface_list(self):
        """`interface_list`.

        Queries the connected DGI device for available interfaces. Refer to
        the DGI documentation to resolve the ID.

        `int interface_list(uint32_t dgi_hndl, unsigned char* interfaces,
        unsigned char* count)`

        +------------+------------+
        | Parameter  | Description |
        +============+============+
        | *dgi_hndl* | Handle of the connection |
        | *interfaces* | Buffer to hold the ID of the available interfaces.
        Should be able to hold minimum 10 elements, but a larger count should
        be used to be future proof. |
        | *count* | Pointer to a variable that will be set to the number of
        interfaces registered in buffer. |
        +------------+------------+

        :return: List of available interfaces
        :rtype: list(int)
        :raises: :exc:`DeviceReturnError`
        """
        interfaces = (c_ubyte * NUM_INTERFACES)()
        interfaceCount = c_ubyte()
        res = self.dgilib.interface_list(self.dgi_hndl, byref(interfaces),
                                         byref(interfaceCount))
        if self.verbose:
            print(
                f"\t{res} interface_list: {interfaces[:interfaceCount.value]},"
                f" interfaceCount: {interfaceCount.value}")
        if res:
            raise DeviceReturnError(f"interface_list returned: {res}")

        return interfaces[:interfaceCount.value]
    def auxiliary_power_copy_data(self,
                                  channel=0,
                                  power_type=0,
                                  max_count=BUFFER_SIZE):
        """`auxiliary_power_copy_data`.

        Copies parsed power data into the specified buffer. Remember to lock
        the buffers first. If the count parameter is the same as max_count
        there is probably more data to be read. Do another read to get the
        remaining data.

        `int auxiliary_power_copy_data(uint32_t power_hndl, float* buffer,
        double* timestamp, size_t* count, size_t max_count, int channel, int
        type)`

        +------------+------------+
        | Parameter  | Description |
        +============+============+
        | *power_hndl* | Handle of the power parser |
        | *buffer* | Buffer that will hold the samples. |
        | *timestamp* | Buffer that will hold the timestamp for the samples. |
        | *count* | Pointer to a variable that will hold the count of elements
        copied |
        | *max_count* | Maximum number of elements that the buffer can hold |
        | *channel* | Power channel for this buffer: A = 0, B = 1 (Power
        Debugger specific) |
        | *type* | Type of power data: Current = 0, Voltage = 1, Range = 2 |
        +------------+------------+

        :param channel: Power channel for this buffer: A = 0, B = 1 (defaults
            to 0)
        :type channel: int
        :param power_type: Type of power data: Current = 0, Voltage = 1,
            Range = 2 (defaults to 0)
        :type power_type: int
        :param max_count: Maximum number of elements that the buffer can hold
            (defaults to BUFFER_SIZE)
        :type max_count: int
        :return: Tuple of a list of samples and a list of the timestamps for
            the samples
        :rtype: tuple(list(int), list(int))
        :raises: :exc:`DeviceReturnError`
        """
        # buffer = (c_float * max_count)()
        # timestamp = (c_double * max_count)()
        count = c_size_t()
        max_count = c_size_t(max_count)
        channel = c_int(channel)
        power_type = c_int(power_type)

        res = self.dgilib.auxiliary_power_copy_data(
            self.power_hndl,
            self.powerBuffer,
            self.powerTimestamp,
            # byref(self.powerCount),
            # buffer,
            # timestamp,
            byref(count),
            max_count,
            channel,
            power_type,
        )
        if self.verbose:
            print(f"\t{res} auxiliary_power_copy_data: {count.value} samples, "
                  f"power_type: {power_type.value}")
            # f"\t{res} auxiliary_power_copy_data: {self.powerCount.value} "
            # f"samples, power_type: {power_type.value}"
            if self.verbose >= 3:
                for i in range(min(count.value, MAX_PRINT)):
                    # for i in range(min(self.powerCount.value, MAX_PRINT)):
                    #     print(f"\t{i}: buffer: {buffer[i]}, timestamp: "
                    #         f"{timestamp[i]}")
                    print(f"\t{i}: buffer: {self.powerBuffer[i]}, timestamp: "
                          f"{self.powerTimestamp[i]}")
        if res:
            raise DeviceReturnError(
                f"auxiliary_power_copy_data returned: {res}")

        return (self.powerTimestamp[:count.value],
                self.powerBuffer[:count.value])
    def auxiliary_power_register_buffer_pointers(self,
                                                 channel=0,
                                                 power_type=0,
                                                 max_count=BUFFER_SIZE):
        """`auxiliary_power_register_buffer_pointers`.

        Registers a set of pointers to be used for storing the
        calibrated power data. The buffers can then be locked by
        auxiliary_power_lock_data_for_reading, and the data directly read from
        the specified buffers.
        Zero-pointers can be specified to get the buffers allocated within
        DGILib. This requires the data to be fetched using
        auxiliary_power_copy_data.

        `int auxiliary_power_register_buffer_pointers(uint32_t power_hndl,
        float* buffer, double* timestamp, size_t*
        count, size_t max_count, int channel, int type)`

        +------------+------------+
        | Parameter  | Description |
        +============+============+
        | *power_hndl* | Handle of the power parser |
        | *buffer* | Buffer that will hold the samples. Set to 0 for
        automatically allocated. |
        | *timestamp* | Buffer that will hold the timestamp for the samples.
        Set to 0 for automatically allocated. |
        | *count* | Pointer to a variable that will hold the count of samples.
        Set to 0 for automatically allocated. |
        | *max_count* | Number of samples that can fit into the specified
        buffers. Or size of automatically allocated buffers. |
        | *channel* | Power channel for this buffer: A = 0, B = 1 (Power
        Debugger specific) |
        | *type* | Type of power data: Current = 0, Voltage = 1, Range = 2 |
        +------------+------------+

        :param channel: Power channel for this buffer: A = 0, B = 1 (defaults
            to 0)
        :type channel: int
        :param power_type: Type of power data: Current = 0, Voltage = 1,
            Range = 2 (defaults to 0)
        :type power_type: int
        :param max_count: Number of samples that can fit into the specified
            buffers (defaults to BUFFER_SIZE)
        :type max_count: int
        :raises: :exc:`DeviceReturnError`
        """
        self.powerBuffer = (c_float * max_count)()
        self.powerTimestamp = (c_double * max_count)()
        self.powerCount = c_size_t()

        max_count = c_size_t(max_count)
        channel = c_int(channel)
        power_type = c_int(power_type)

        res = self.dgilib.auxiliary_power_register_buffer_pointers(
            self.power_hndl,
            byref(self.powerBuffer),
            byref(self.powerTimestamp),
            byref(self.powerCount),
            max_count,
            channel,
            power_type,
        )
        if self.verbose:
            print(f"\t{res} auxiliary_power_register_buffer_pointers")
        if res:
            raise DeviceReturnError(
                f"auxiliary_power_register_buffer_pointers returned: {res}")