#pragma once

#include "../../../include/dv-processing/io/camera/davis.hpp"

#include <pybind11/pybind11.h>

namespace py = pybind11;

/**
 * @brief Bind discoverDevices class to python
 * @param m pybind The module to bind to
 */
void bind_davis(py::module &m) {
	static dv::io::camera::USBDevice::loggerCallbackType DEFAULT_CLI_LOGGER
		= [](const dv::io::camera::USBDevice::LogLevel level, const std::string_view deviceName,
			  const std::string_view message) {
			  std::cerr << fmt::format("[{}] {}: {}", level, deviceName, message) << std::endl;
		  };

	py::class_<dv::io::camera::DAVIS, dv::io::camera::USBDevice, dv::io::camera::SyncCameraInputBase> davis(
		m, "DAVIS", "DAVIS camera.");

	py::enum_<dv::io::camera::parser::DAVIS::SensorModel>(davis, "SensorModel")
		.value("DAVIS240A", dv::io::camera::parser::DAVIS::SensorModel::DAVIS240A)
		.value("DAVIS240B", dv::io::camera::parser::DAVIS::SensorModel::DAVIS240B)
		.value("DAVIS240C", dv::io::camera::parser::DAVIS::SensorModel::DAVIS240C)
		.value("DAVIS346", dv::io::camera::parser::DAVIS::SensorModel::DAVIS346)
		.value("DAVIS640", dv::io::camera::parser::DAVIS::SensorModel::DAVIS640)
		.value("CDAVIS", dv::io::camera::parser::DAVIS::SensorModel::CDAVIS);

	py::enum_<dv::io::camera::parser::DAVIS::ColorMode>(davis, "ColorMode")
		.value("DEFAULT", dv::io::camera::parser::DAVIS::ColorMode::DEFAULT)
		.value("GRAYSCALE", dv::io::camera::parser::DAVIS::ColorMode::GRAYSCALE)
		.value("ORIGINAL", dv::io::camera::parser::DAVIS::ColorMode::ORIGINAL)
		.value("ORIGINAL_SPLIT", dv::io::camera::parser::DAVIS::ColorMode::ORIGINAL_SPLIT);

	py::enum_<dv::io::camera::DAVIS::Davis240BiasCF>(davis, "Davis240BiasCF")
		.value("Diff", dv::io::camera::DAVIS::Davis240BiasCF::Diff)
		.value("On", dv::io::camera::DAVIS::Davis240BiasCF::On)
		.value("Off", dv::io::camera::DAVIS::Davis240BiasCF::Off)
		.value("ApsCascode", dv::io::camera::DAVIS::Davis240BiasCF::ApsCascode)
		.value("DiffCascode", dv::io::camera::DAVIS::Davis240BiasCF::DiffCascode)
		.value("ApsReadoutSourceFollower", dv::io::camera::DAVIS::Davis240BiasCF::ApsReadoutSourceFollower)
		.value("LocalBuffer", dv::io::camera::DAVIS::Davis240BiasCF::LocalBuffer)
		.value("PixelInverter", dv::io::camera::DAVIS::Davis240BiasCF::PixelInverter)
		.value("Photoreceptor", dv::io::camera::DAVIS::Davis240BiasCF::Photoreceptor)
		.value("PhotoreceptorSourceFollower", dv::io::camera::DAVIS::Davis240BiasCF::PhotoreceptorSourceFollower)
		.value("Refractory", dv::io::camera::DAVIS::Davis240BiasCF::Refractory)
		.value("AERPullDown", dv::io::camera::DAVIS::Davis240BiasCF::AERPullDown)
		.value("LCOLTimeout", dv::io::camera::DAVIS::Davis240BiasCF::LCOLTimeout)
		.value("AERPullUpX", dv::io::camera::DAVIS::Davis240BiasCF::AERPullUpX)
		.value("AERPullUpY", dv::io::camera::DAVIS::Davis240BiasCF::AERPullUpY)
		.value("PadFollower", dv::io::camera::DAVIS::Davis240BiasCF::PadFollower)
		.value("ApsOverflowLevel", dv::io::camera::DAVIS::Davis240BiasCF::ApsOverflowLevel)
		.value("BiasBuffer", dv::io::camera::DAVIS::Davis240BiasCF::BiasBuffer);

	py::enum_<dv::io::camera::DAVIS::Davis346BiasVDAC>(davis, "Davis346BiasVDAC")
		.value("ApsOverflowLevel", dv::io::camera::DAVIS::Davis346BiasVDAC::ApsOverflowLevel)
		.value("ApsCascode", dv::io::camera::DAVIS::Davis346BiasVDAC::ApsCascode)
		.value("ADCReferenceHigh", dv::io::camera::DAVIS::Davis346BiasVDAC::ADCReferenceHigh)
		.value("ADCReferenceLow", dv::io::camera::DAVIS::Davis346BiasVDAC::ADCReferenceLow)
		.value("ADCTestVoltage", dv::io::camera::DAVIS::Davis346BiasVDAC::ADCTestVoltage);

	py::enum_<dv::io::camera::DAVIS::Davis346BiasCF>(davis, "Davis346BiasCF")
		.value("LocalBuffer", dv::io::camera::DAVIS::Davis346BiasCF::LocalBuffer)
		.value("PadFollower", dv::io::camera::DAVIS::Davis346BiasCF::PadFollower)
		.value("Diff", dv::io::camera::DAVIS::Davis346BiasCF::Diff)
		.value("On", dv::io::camera::DAVIS::Davis346BiasCF::On)
		.value("Off", dv::io::camera::DAVIS::Davis346BiasCF::Off)
		.value("PixelInverter", dv::io::camera::DAVIS::Davis346BiasCF::PixelInverter)
		.value("Photoreceptor", dv::io::camera::DAVIS::Davis346BiasCF::Photoreceptor)
		.value("PhotoreceptorSourceFollower", dv::io::camera::DAVIS::Davis346BiasCF::PhotoreceptorSourceFollower)
		.value("Refractory", dv::io::camera::DAVIS::Davis346BiasCF::Refractory)
		.value("ReadoutBuffer", dv::io::camera::DAVIS::Davis346BiasCF::ReadoutBuffer)
		.value("ApsReadoutSourceFollower", dv::io::camera::DAVIS::Davis346BiasCF::ApsReadoutSourceFollower)
		.value("ADCComparator", dv::io::camera::DAVIS::Davis346BiasCF::ADCComparator)
		.value("COLSelectLow", dv::io::camera::DAVIS::Davis346BiasCF::COLSelectLow)
		.value("DACBuffer", dv::io::camera::DAVIS::Davis346BiasCF::DACBuffer)
		.value("LCOLTimeout", dv::io::camera::DAVIS::Davis346BiasCF::LCOLTimeout)
		.value("AERPullDown", dv::io::camera::DAVIS::Davis346BiasCF::AERPullDown)
		.value("AERPullUpX", dv::io::camera::DAVIS::Davis346BiasCF::AERPullUpX)
		.value("AERPullUpY", dv::io::camera::DAVIS::Davis346BiasCF::AERPullUpY)
		.value("BiasBuffer", dv::io::camera::DAVIS::Davis346BiasCF::BiasBuffer);

	py::enum_<dv::io::camera::DAVIS::CDavisBiasVDAC>(davis, "CDavisBiasVDAC")
		.value("ApsCascode", dv::io::camera::DAVIS::CDavisBiasVDAC::ApsCascode)
		.value("OVG1Low", dv::io::camera::DAVIS::CDavisBiasVDAC::OVG1Low)
		.value("OVG2Low", dv::io::camera::DAVIS::CDavisBiasVDAC::OVG2Low)
		.value("TX2OVG2High", dv::io::camera::DAVIS::CDavisBiasVDAC::TX2OVG2High)
		.value("Gnd07", dv::io::camera::DAVIS::CDavisBiasVDAC::Gnd07)
		.value("ADCTestVoltage", dv::io::camera::DAVIS::CDavisBiasVDAC::ADCTestVoltage)
		.value("ADCReferenceHigh", dv::io::camera::DAVIS::CDavisBiasVDAC::ADCReferenceHigh)
		.value("ADCReferenceLow", dv::io::camera::DAVIS::CDavisBiasVDAC::ADCReferenceLow);

	py::enum_<dv::io::camera::DAVIS::CDavisBiasCF>(davis, "CDavisBiasCF")
		.value("LocalBuffer", dv::io::camera::DAVIS::CDavisBiasCF::LocalBuffer)
		.value("PadFollower", dv::io::camera::DAVIS::CDavisBiasCF::PadFollower)
		.value("PixelInverter", dv::io::camera::DAVIS::CDavisBiasCF::PixelInverter)
		.value("Diff", dv::io::camera::DAVIS::CDavisBiasCF::Diff)
		.value("On", dv::io::camera::DAVIS::CDavisBiasCF::On)
		.value("Off", dv::io::camera::DAVIS::CDavisBiasCF::Off)
		.value("Photoreceptor", dv::io::camera::DAVIS::CDavisBiasCF::Photoreceptor)
		.value("PhotoreceptorSourceFollower", dv::io::camera::DAVIS::CDavisBiasCF::PhotoreceptorSourceFollower)
		.value("Refractory", dv::io::camera::DAVIS::CDavisBiasCF::Refractory)
		.value("ArrayBiasBuffer", dv::io::camera::DAVIS::CDavisBiasCF::ArrayBiasBuffer)
		.value("ArrayLogicBuffer", dv::io::camera::DAVIS::CDavisBiasCF::ArrayLogicBuffer)
		.value("FallTime", dv::io::camera::DAVIS::CDavisBiasCF::FallTime)
		.value("RiseTime", dv::io::camera::DAVIS::CDavisBiasCF::RiseTime)
		.value("ReadoutBuffer", dv::io::camera::DAVIS::CDavisBiasCF::ReadoutBuffer)
		.value("ApsReadoutSourceFollower", dv::io::camera::DAVIS::CDavisBiasCF::ApsReadoutSourceFollower)
		.value("ADCComparator", dv::io::camera::DAVIS::CDavisBiasCF::ADCComparator)
		.value("DACBuffer", dv::io::camera::DAVIS::CDavisBiasCF::DACBuffer)
		.value("LCOLTimeout", dv::io::camera::DAVIS::CDavisBiasCF::LCOLTimeout)
		.value("AERPullDown", dv::io::camera::DAVIS::CDavisBiasCF::AERPullDown)
		.value("AERPullUpX", dv::io::camera::DAVIS::CDavisBiasCF::AERPullUpX)
		.value("AERPullUpY", dv::io::camera::DAVIS::CDavisBiasCF::AERPullUpY)
		.value("BiasBuffer", dv::io::camera::DAVIS::CDavisBiasCF::BiasBuffer);

	davis.def_static(
		"findDevices",
		[](const std::string_view filterBySerialNumber) {
			return dv::io::camera::DAVIS::findDevices(filterBySerialNumber, DEFAULT_CLI_LOGGER);
		},
		py::arg("filterBySerialNumber") = "", "Find connected DAVIS cameras.");

	// Frames and events.
	davis
		.def(py::init([](const dv::io::camera::USBDevice::LogLevel deviceLogLevel) {
			return std::make_unique<dv::io::camera::DAVIS>(DEFAULT_CLI_LOGGER, deviceLogLevel);
		}),
			py::arg("deviceLogLevel") = dv::io::camera::USBDevice::LogLevel::LVL_WARNING,
			"Open the first DAVIS camera that can be found.")
		.def(py::init([](const std::string_view filterBySerialNumber,
						  const dv::io::camera::USBDevice::LogLevel deviceLogLevel) {
			return std::make_unique<dv::io::camera::DAVIS>(filterBySerialNumber, DEFAULT_CLI_LOGGER, deviceLogLevel);
		}),
			py::arg("filterBySerialNumber"),
			py::arg("deviceLogLevel") = dv::io::camera::USBDevice::LogLevel::LVL_WARNING,
			"Open the DAVIS camera with the specified serial number.")
		.def(py::init([](const dv::io::camera::USBDevice::DeviceDescriptor &deviceToOpen,
						  const dv::io::camera::USBDevice::LogLevel deviceLogLevel) {
			return std::make_unique<dv::io::camera::DAVIS>(deviceToOpen, DEFAULT_CLI_LOGGER, deviceLogLevel);
		}),
			py::arg("deviceToOpen"), py::arg("deviceLogLevel") = dv::io::camera::USBDevice::LogLevel::LVL_WARNING,
			"Open the DAVIS camera corresponding to the specified descriptor.")
		.def("getLogicVersion", &dv::io::camera::DAVIS::getLogicVersion, "Get camera FPGA logic version.")
		.def("getLogicPatchLevel", &dv::io::camera::DAVIS::getLogicPatchLevel, "Get camera FPGA logic patch level.")
		.def("getSensorModel", &dv::io::camera::DAVIS::getSensorModel,
			"Get the exact model of the DAVIS sensor chip mounted in this camera.")
		.def("getPixelArrangementEvents", &dv::io::camera::DAVIS::getPixelArrangementEvents,
			"Get pixel color filter arrangement for event readout on color DAVIS.")
		.def("getPixelArrangementFrames", &dv::io::camera::DAVIS::getPixelArrangementFrames,
			"Get pixel color filter arrangement for frame readout on color DAVIS.")
		.def("getEventColor", &dv::io::camera::DAVIS::getEventColor,
			"Determine the color of the Bayer color filter for a specific event, based on its pixel address. WHITE "
			"means White/No Filter. Please take into account that there are usually twice as many green pixels as "
			"there are red or blue ones.")
		.def("isEventsRunning", &dv::io::camera::DAVIS::isEventsRunning, "Report if the event output is running.")
		.def("setEventsRunning", &dv::io::camera::DAVIS::setEventsRunning, py::arg("run"),
			"Enable or disable the event output.")
		.def("getFlipHorizontalEvents", &dv::io::camera::DAVIS::getFlipHorizontalEvents,
			"Status of horizontal events flip.")
		.def("setFlipHorizontalEvents", &dv::io::camera::DAVIS::setFlipHorizontalEvents,
			py::arg("flipHorizontalEvents"), "Flip events horizontally.")
		.def("getFlipVerticalEvents", &dv::io::camera::DAVIS::getFlipVerticalEvents, "Status of vertical events flip.")
		.def("setFlipVerticalEvents", &dv::io::camera::DAVIS::setFlipVerticalEvents, py::arg("flipVerticalEvents"),
			"Flip events vertically.")
		.def("getCropAreaEvents", &dv::io::camera::DAVIS::getCropAreaEvents, "Get events Region of Interest (ROI).")
		.def("setCropAreaEvents", &dv::io::camera::DAVIS::setCropAreaEvents, py::arg("cropAreaEvents"),
			"Set events Region of Interest (ROI).")
		.def("getFlipHorizontalFrames", &dv::io::camera::DAVIS::getFlipHorizontalFrames,
			"Status of horizontal frames flip.")
		.def("setFlipHorizontalFrames", &dv::io::camera::DAVIS::setFlipHorizontalFrames,
			py::arg("flipHorizontalFrames"), "Flip frames horizontally.")
		.def("getFlipVerticalFrames", &dv::io::camera::DAVIS::getFlipVerticalFrames, "Status of vertical frames flip.")
		.def("setFlipVerticalFrames", &dv::io::camera::DAVIS::setFlipVerticalFrames, py::arg("flipVerticalFrames"),
			"Flip frames vertically.")
		.def("getCropAreaFrames", &dv::io::camera::DAVIS::getCropAreaFrames, "Get frames Region of Interest (ROI).")
		.def("setCropAreaFrames", &dv::io::camera::DAVIS::setCropAreaFrames, py::arg("cropAreaFrames"),
			"Set frames Region of Interest (ROI).")
		.def("getExternalAERControl", &dv::io::camera::DAVIS::getExternalAERControl, "Get external AER control status.")
		.def("setExternalAERControl", &dv::io::camera::DAVIS::setExternalAERControl,
			"Enable or disable external AER control feature.")
		.def("getBackgroundActivityFilter", &dv::io::camera::DAVIS::getBackgroundActivityFilter,
			"Get background activity noise filter time delta value.")
		.def("setBackgroundActivityFilter", &dv::io::camera::DAVIS::setBackgroundActivityFilter, py::arg("timeIn250us"),
			"Set background activity noise filter time delta value.")
		.def("getRefractoryPeriodFilter", &dv::io::camera::DAVIS::getRefractoryPeriodFilter,
			"Get refractory period filter time delta value.")
		.def("setRefractoryPeriodFilter", &dv::io::camera::DAVIS::setRefractoryPeriodFilter, py::arg("timeIn250us"),
			"Set refractory period filter time delta value.")
		.def("getSkipFilter", &dv::io::camera::DAVIS::getSkipFilter, "Get event skip filter skip value.")
		.def("setSkipFilter", &dv::io::camera::DAVIS::setSkipFilter, py::arg("skipEvery"),
			"Set event skip filter skip value. Drops every Nth event.")
		.def("isFramesRunning", &dv::io::camera::DAVIS::isFramesRunning, "Report if the frames output is running.")
		.def("setFramesRunning", &dv::io::camera::DAVIS::setFramesRunning, py::arg("run"),
			"Enable or disable the frames output.")
		.def("snapshot", &dv::io::camera::DAVIS::snapshot, "Takes a snapshot (one frame), like a photo-camera.")
		.def("getColorMode", &dv::io::camera::DAVIS::getColorMode, "Get frames color mode.")
		.def("setColorMode", &dv::io::camera::DAVIS::setColorMode, py::arg("colorMode"), "Set frames color mode.")
		.def("getAutoExposure", &dv::io::camera::DAVIS::getAutoExposure, "Report if auto-exposure feature is enabled.")
		.def("setAutoExposure", &dv::io::camera::DAVIS::setAutoExposure, py::arg("enabled"),
			"Enable auto-exposure feature.")
		.def("getExposureDuration", &dv::io::camera::DAVIS::getExposureDuration, "Get current frame exposure duration.")
		.def("setExposureDuration", &dv::io::camera::DAVIS::setExposureDuration, py::arg("exposureDurationUs"),
			"Set frame exposure duration.")
		.def("getFrameInterval", &dv::io::camera::DAVIS::getFrameInterval,
			" Get frame interval, the time between two consecutive frames.")
		.def("setFrameInterval", &dv::io::camera::DAVIS::setFrameInterval, py::arg("frameIntervalUs"),
			"Set frame interval, the time between two consecutive frames.");

	// IMU
	davis
		.def("isImuRunningAccelerometer", &dv::io::camera::DAVIS::isImuRunningAccelerometer,
			"Status of IMU accelerometer.")
		.def("setImuRunningAccelerometer", &dv::io::camera::DAVIS::setImuRunningAccelerometer, py::arg("run"),
			"Enable or disable IMU accelerometer.")
		.def("isImuRunningGyroscope", &dv::io::camera::DAVIS::isImuRunningGyroscope, "Status of IMU gyroscope.")
		.def("setImuRunningGyroscope", &dv::io::camera::DAVIS::setImuRunningGyroscope, py::arg("run"),
			"Enable or disable IMU gyroscope.")
		.def("isImuRunningTemperature", &dv::io::camera::DAVIS::isImuRunningTemperature,
			"Status of IMU temperature measurement.")
		.def("setImuRunningTemperature", &dv::io::camera::DAVIS::setImuRunningTemperature, py::arg("run"),
			"Enable or disable IMU temperature measurement.")
		.def("getIMUFlipX", &dv::io::camera::DAVIS::getIMUFlipX, "Status of IMU X axis flipping.")
		.def("setIMUFlipX", &dv::io::camera::DAVIS::setIMUFlipX, py::arg("flipX"),
			"Enable or disable IMU X axis flipping.")
		.def("getIMUFlipY", &dv::io::camera::DAVIS::getIMUFlipY, "Status of IMU Y axis flipping.")
		.def("setIMUFlipY", &dv::io::camera::DAVIS::setIMUFlipY, py::arg("flipY"),
			"Enable or disable IMU Y axis flipping.")
		.def("getIMUFlipZ", &dv::io::camera::DAVIS::getIMUFlipZ, "Status of IMU Z axis flipping.")
		.def("setIMUFlipZ", &dv::io::camera::DAVIS::setIMUFlipZ, py::arg("flipZ"),
			"Enable or disable IMU Z axis flipping.")
		.def("getImuAccelRange", &dv::io::camera::DAVIS::getImuAccelRange, "Get current IMU accelerometer range.")
		.def("setImuAccelRange", &dv::io::camera::DAVIS::setImuAccelRange, py::arg("range"),
			"Set IMU accelerometer range.")
		.def("getImuGyroRange", &dv::io::camera::DAVIS::getImuGyroRange, "Get current IMU gyroscope range.")
		.def("setImuGyroRange", &dv::io::camera::DAVIS::setImuGyroRange, py::arg("range"), "Set IMU gyroscope range.");

	// External SYNC connectors.
	davis
		.def("isDetectorRunning", &dv::io::camera::DAVIS::isDetectorRunning,
			"Report status of external signal detector.")
		.def("setDetectorRunning", &dv::io::camera::DAVIS::setDetectorRunning, py::arg("run"),
			"Enable or disable external signal detector.")
		.def("getDetectorRisingEdges", &dv::io::camera::DAVIS::getDetectorRisingEdges,
			"Report status of rising edge detection on the SIGNAL_IN line.")
		.def("setDetectorRisingEdges", &dv::io::camera::DAVIS::setDetectorRisingEdges, py::arg("detectRising"),
			"Detect rising edges (low to high transitions) on the SIGNAL_IN line.")
		.def("getDetectorFallingEdges", &dv::io::camera::DAVIS::getDetectorFallingEdges,
			"Report status of falling edge detection on the SIGNAL_IN line.")
		.def("setDetectorFallingEdges", &dv::io::camera::DAVIS::setDetectorFallingEdges, py::arg("detectFalling"),
			"Detect falling edges (high to low transitions) on the SIGNAL_IN line.")
		.def("getGeneratorInjectTriggerOnRisingEdge", &dv::io::camera::DAVIS::getGeneratorInjectTriggerOnRisingEdge,
			"Report status of trigger event injection feature for external signal generator rising edges.")
		.def("setGeneratorInjectTriggerOnRisingEdge", &dv::io::camera::DAVIS::setGeneratorInjectTriggerOnRisingEdge,
			py::arg("injectRising"),
			"Inject a trigger event of type EXTERNAL_GENERATOR_RISING_EDGE into the event stream from the device.")
		.def("getGeneratorInjectTriggerOnFallingEdge", &dv::io::camera::DAVIS::getGeneratorInjectTriggerOnFallingEdge,
			"Report status of trigger event injection feature for external signal generator falling edges.")
		.def("setGeneratorInjectTriggerOnFallingEdge", &dv::io::camera::DAVIS::setGeneratorInjectTriggerOnFallingEdge,
			py::arg("injectFalling"),
			"Inject a trigger event of type EXTERNAL_GENERATOR_FALLING_EDGE into the event stream from the device.")
		.def("isGeneratorRunning", &dv::io::camera::DAVIS::isGeneratorRunning,
			"Report status of external signal generator.")
		.def("setGeneratorRunning", &dv::io::camera::DAVIS::setGeneratorRunning, py::arg("run"),
			"Enable or disable external signal generator (PWM-like output).")
		.def("getGeneratorHighTime", &dv::io::camera::DAVIS::getGeneratorHighTime, "Get current PWM high time.")
		.def("setGeneratorHighTime", &dv::io::camera::DAVIS::setGeneratorHighTime, py::arg("highTimeUs"),
			"Set PWM high time for external signal generator.")
		.def("getGeneratorLowTime", &dv::io::camera::DAVIS::getGeneratorLowTime, "Get current PWM low time.")
		.def("setGeneratorLowTime", &dv::io::camera::DAVIS::setGeneratorLowTime, py::arg("lowTimeUs"),
			"Set PWM low time for external signal generator.");

	// DAVIS biases.
	davis
		.def("getDavis240BiasCoarseFine", &dv::io::camera::DAVIS::getDavis240BiasCoarseFine, py::arg("bias"),
			"Get low-level coarse/fine values for a specific bias.")
		.def("setDavis240BiasCoarseFine", &dv::io::camera::DAVIS::setDavis240BiasCoarseFine, py::arg("bias"),
			py::arg("coarse"), py::arg("fine"), "Set specific bias to new low-level coarse/fine values.")
		.def("getDavis346BiasVoltage", &dv::io::camera::DAVIS::getDavis346BiasVoltage, py::arg("bias"),
			"Get voltage value in 52.4 milliVolt increments for a specific voltage bias.")
		.def("setDavis346BiasVoltage", &dv::io::camera::DAVIS::setDavis346BiasVoltage, py::arg("bias"),
			py::arg("voltageValue"), "Set specific voltage bias to a new value in 52.4 milliVolt increments.")
		.def("getDavis346BiasCoarseFine", &dv::io::camera::DAVIS::getDavis346BiasCoarseFine, py::arg("bias"),
			"Get low-level coarse/fine values for a specific bias.")
		.def("setDavis346BiasCoarseFine", &dv::io::camera::DAVIS::setDavis346BiasCoarseFine, py::arg("bias"),
			py::arg("coarse"), py::arg("fine"), "Set specific bias to new low-level coarse/fine values.")
		.def("getCDavisBiasVoltage", &dv::io::camera::DAVIS::getCDavisBiasVoltage, py::arg("bias"),
			"Get voltage value in 52.4 milliVolt increments for a specific voltage bias.")
		.def("setCDavisBiasVoltage", &dv::io::camera::DAVIS::setCDavisBiasVoltage, py::arg("bias"),
			py::arg("voltageValue"), "Set specific voltage bias to a new value in 52.4 milliVolt increments.")
		.def("getCDavisBiasCoarseFine", &dv::io::camera::DAVIS::getCDavisBiasCoarseFine, py::arg("bias"),
			"Get low-level coarse/fine values for a specific bias.")
		.def("setCDavisBiasCoarseFine", &dv::io::camera::DAVIS::setCDavisBiasCoarseFine, py::arg("bias"),
			py::arg("coarse"), py::arg("fine"), "Set specific bias to new low-level coarse/fine values.");

	// USB.
	davis
		.def("getUSBEarlyPacketDelay", &dv::io::camera::DAVIS::getUSBEarlyPacketDelay,
			"Get value of USB early packet timeout.")
		.def("setUSBEarlyPacketDelay", &dv::io::camera::DAVIS::setUSBEarlyPacketDelay, py::arg("earlyPacketDelayUs"),
			"Send data over USB early if this timeout is reached, instead of waiting on buffers being full.");
}
