diff --git a/platforms/common/i2c_spi_buses.cpp b/platforms/common/i2c_spi_buses.cpp index 466928de3f..1f59be0c5f 100644 --- a/platforms/common/i2c_spi_buses.cpp +++ b/platforms/common/i2c_spi_buses.cpp @@ -49,6 +49,31 @@ static List i2c_spi_module_instances; ///< list of currently running instances static pthread_mutex_t i2c_spi_module_instances_mutex = PTHREAD_MUTEX_INITIALIZER; + +I2CSPIDriverConfig::I2CSPIDriverConfig(const BusCLIArguments &cli, const BusInstanceIterator &iterator, + const px4::wq_config_t &wq_config_) + : module_name(iterator.moduleName()), + devid_driver_index(iterator.devidDriverIndex()), + bus_option(iterator.configuredBusOption()), + bus_type(iterator.busType()), + bus(iterator.bus()), + i2c_address(cli.i2c_address), + bus_frequency(cli.bus_frequency), + drdy_gpio(iterator.DRDYGPIO()), + spi_mode(cli.spi_mode), + spi_devid(iterator.devid()), + bus_device_index(iterator.busDeviceIndex()), + rotation(cli.rotation), + quiet_start(cli.quiet_start), + keep_running(cli.keep_running), + custom1(cli.custom1), + custom2(cli.custom2), + custom_data(cli.custom_data), + wq_config(wq_config_) +{ + +} + const char *BusCLIArguments::parseDefaultArguments(int argc, char *argv[]) { if (getOpt(argc, argv, "") == EOF) { @@ -223,7 +248,7 @@ bool BusCLIArguments::validateConfiguration() BusInstanceIterator::BusInstanceIterator(const char *module_name, const BusCLIArguments &cli_arguments, uint16_t devid_driver_index) - : _module_name(module_name), _bus_option(cli_arguments.bus_option), _type(cli_arguments.type), + : _module_name(module_name), _bus_option(cli_arguments.bus_option), _devid_driver_index(devid_driver_index), _i2c_address(cli_arguments.i2c_address), _spi_bus_iterator(spiFilter(cli_arguments.bus_option), cli_arguments.bus_option == I2CSPIBusOption::SPIExternal ? cli_arguments.chipselect_index : devid_driver_index, @@ -256,7 +281,7 @@ bool BusInstanceIterator::next() while (_current_instance != i2c_spi_module_instances.end()) { if (strcmp((*_current_instance)->_module_name, _module_name) == 0 && - _type == (*_current_instance)->_type) { + _devid_driver_index == (*_current_instance)->_devid_driver_index) { return true; } @@ -287,7 +312,8 @@ bool BusInstanceIterator::next() } if (_bus_option == (*_current_instance)->_bus_option && bus == (*_current_instance)->_bus && - _type == (*_current_instance)->_type && + _devid_driver_index == (*_current_instance)->_devid_driver_index && + busDeviceIndex() == (*_current_instance)->_bus_device_index && (!is_i2c || _i2c_address == (*_current_instance)->_i2c_address)) { break; } @@ -422,6 +448,15 @@ int BusInstanceIterator::externalBusIndex() const } } +int BusInstanceIterator::busDeviceIndex() const +{ + if (busType() == BOARD_SPI_BUS) { + return _spi_bus_iterator.busDeviceIndex(); + } + + return -1; +} + I2CBusIterator::FilterType BusInstanceIterator::i2cFilter(I2CSPIBusOption bus_option) { switch (bus_option) { @@ -451,8 +486,7 @@ SPIBusIterator::FilterType BusInstanceIterator::spiFilter(I2CSPIBusOption bus_op } struct I2CSPIDriverInitializing { - const BusCLIArguments &cli; - const BusInstanceIterator &iterator; + const I2CSPIDriverConfig &config; I2CSPIDriverBase::instantiate_method instantiate; int runtime_instance; I2CSPIDriverBase *instance{nullptr}; @@ -461,7 +495,7 @@ struct I2CSPIDriverInitializing { static void initializer_trampoline(void *argument) { I2CSPIDriverInitializing *data = (I2CSPIDriverInitializing *)argument; - data->instance = data->instantiate(data->cli, data->iterator, data->runtime_instance); + data->instance = data->instantiate(data->config, data->runtime_instance); } int I2CSPIDriverBase::module_start(const BusCLIArguments &cli, BusInstanceIterator &iterator, @@ -493,10 +527,13 @@ int I2CSPIDriverBase::module_start(const BusCLIArguments &cli, BusInstanceIterat case BOARD_INVALID_BUS: device_id.devid_s.bus_type = device::Device::DeviceBusType_UNKNOWN; break; } + + const px4::wq_config_t &wq_config = px4::device_bus_to_wq(device_id.devid); + I2CSPIDriverConfig driver_config{cli, iterator, wq_config}; const int runtime_instance = iterator.runningInstancesCount(); - I2CSPIDriverInitializing initializer_data{cli, iterator, instantiate, runtime_instance}; + I2CSPIDriverInitializing initializer_data{driver_config, instantiate, runtime_instance}; // initialize the object and bus on the work queue thread - this will also probe for the device - px4::WorkItemSingleShot initializer(px4::device_bus_to_wq(device_id.devid), initializer_trampoline, &initializer_data); + px4::WorkItemSingleShot initializer(wq_config, initializer_trampoline, &initializer_data); initializer.ScheduleNow(); initializer.wait(); I2CSPIDriverBase *instance = initializer_data.instance; @@ -556,6 +593,10 @@ int I2CSPIDriverBase::module_start(const BusCLIArguments &cli, BusInstanceIterat if (!started && !cli.quiet_start) { PX4_WARN("%s: no instance started (no device on bus?)", px4_get_taskname()); + + if (iterator.busType() == BOARD_I2C_BUS && cli.i2c_address == 0) { + PX4_ERR("%s: driver does not set i2c address", px4_get_taskname()); + } } return started ? 0 : -1; diff --git a/platforms/common/include/px4_platform_common/i2c_spi_buses.h b/platforms/common/include/px4_platform_common/i2c_spi_buses.h index 29ad8318b9..4e49eba37a 100644 --- a/platforms/common/include/px4_platform_common/i2c_spi_buses.h +++ b/platforms/common/include/px4_platform_common/i2c_spi_buses.h @@ -54,6 +54,37 @@ enum class I2CSPIBusOption : uint8_t { SPIExternal, }; +class BusCLIArguments; +class BusInstanceIterator; + +struct I2CSPIDriverConfig { + I2CSPIDriverConfig(const BusCLIArguments &cli, const BusInstanceIterator &iterator, + const px4::wq_config_t &wq_config_); + + const char *module_name; + uint16_t devid_driver_index; + I2CSPIBusOption bus_option; + board_bus_types bus_type; + int bus; + uint8_t i2c_address; + int bus_frequency; + spi_drdy_gpio_t drdy_gpio; + spi_mode_e spi_mode; + uint32_t spi_devid; + int bus_device_index; + + Rotation rotation; + + bool quiet_start; + bool keep_running; + + int custom1; + int custom2; + void *custom_data; + + const px4::wq_config_t &wq_config; +}; + /** * @class I2CSPIInstance * I2C/SPI driver instance used by BusInstanceIterator to find running instances. @@ -64,8 +95,10 @@ public: virtual ~I2CSPIInstance() = default; private: - I2CSPIInstance(const char *module_name, I2CSPIBusOption bus_option, int bus, uint8_t i2c_address, uint16_t type) - : _module_name(module_name), _bus_option(bus_option), _bus(bus), _type(type), _i2c_address(i2c_address) {} + I2CSPIInstance(const I2CSPIDriverConfig &config) + : _module_name(config.module_name), _bus_option(config.bus_option), _bus(config.bus), + _devid_driver_index(config.devid_driver_index), _bus_device_index(config.bus_device_index), + _i2c_address(config.i2c_address) {} friend class BusInstanceIterator; friend class I2CSPIDriverBase; @@ -73,7 +106,8 @@ private: const char *_module_name; const I2CSPIBusOption _bus_option; const int _bus; - const int16_t _type; ///< device type (driver-specific) + const uint16_t _devid_driver_index; + const int8_t _bus_device_index; const int8_t _i2c_address; ///< I2C address (optional) }; @@ -102,17 +136,15 @@ public: I2CSPIBusOption bus_option{I2CSPIBusOption::All}; - uint16_t type{0}; ///< device type (driver-specific) int requested_bus{-1}; int chipselect_index{1}; - Rotation rotation{ROTATION_NONE}; int bus_frequency{0}; spi_mode_e spi_mode{SPIDEV_MODE3}; - uint8_t i2c_address{0}; ///< optional I2C address: a driver can set this to allow configuring the I2C address + uint8_t i2c_address{0}; ///< I2C address (a driver must set the default address) bool quiet_start{false}; ///< do not print a message when startup fails bool keep_running{false}; ///< keep driver running even if no device is detected on startup - uint8_t orientation{0}; ///< distance_sensor_s::ROTATION_* + Rotation rotation{ROTATION_NONE}; ///< sensor rotation (MAV_SENSOR_ROTATION_* or distance_sensor_s::ROTATION_*) int custom1{0}; ///< driver-specific custom argument int custom2{0}; ///< driver-specific custom argument @@ -158,15 +190,20 @@ public: spi_drdy_gpio_t DRDYGPIO() const; bool external() const; int externalBusIndex() const; + int busDeviceIndex() const; void addInstance(I2CSPIInstance *instance); static I2CBusIterator::FilterType i2cFilter(I2CSPIBusOption bus_option); static SPIBusIterator::FilterType spiFilter(I2CSPIBusOption bus_option); + + const char *moduleName() const { return _module_name; } + uint16_t devidDriverIndex() const { return _devid_driver_index; } + private: const char *_module_name; const I2CSPIBusOption _bus_option; - const uint16_t _type; + const uint16_t _devid_driver_index; const uint8_t _i2c_address; SPIBusIterator _spi_bus_iterator; I2CBusIterator _i2c_bus_iterator; @@ -180,18 +217,16 @@ private: class I2CSPIDriverBase : public px4::ScheduledWorkItem, public I2CSPIInstance { public: - I2CSPIDriverBase(const char *module_name, const px4::wq_config_t &config, I2CSPIBusOption bus_option, int bus, - uint8_t i2c_address, uint16_t type) - : ScheduledWorkItem(module_name, config), - I2CSPIInstance(module_name, bus_option, bus, i2c_address, type) {} + I2CSPIDriverBase(const I2CSPIDriverConfig &config) + : ScheduledWorkItem(config.module_name, config.wq_config), + I2CSPIInstance(config) {} static int module_stop(BusInstanceIterator &iterator); static int module_status(BusInstanceIterator &iterator); static int module_custom_method(const BusCLIArguments &cli, BusInstanceIterator &iterator, bool run_on_work_queue = true); - using instantiate_method = I2CSPIDriverBase * (*)(const BusCLIArguments &cli, const BusInstanceIterator &iterator, - int runtime_instance); + using instantiate_method = I2CSPIDriverBase * (*)(const I2CSPIDriverConfig &config, int runtime_instance); protected: virtual ~I2CSPIDriverBase() = default; @@ -230,13 +265,12 @@ class I2CSPIDriver : public I2CSPIDriverBase public: static int module_start(const BusCLIArguments &cli, BusInstanceIterator &iterator) { - return I2CSPIDriverBase::module_start(cli, iterator, &T::print_usage, &T::instantiate); + return I2CSPIDriverBase::module_start(cli, iterator, &T::print_usage, InstantiateHelper::m); } protected: - I2CSPIDriver(const char *module_name, const px4::wq_config_t &config, I2CSPIBusOption bus_option, int bus, - uint8_t i2c_address = 0, uint16_t type = 0) - : I2CSPIDriverBase(module_name, config, bus_option, bus, i2c_address, type) {} + I2CSPIDriver(const I2CSPIDriverConfig &config) + : I2CSPIDriverBase(config) {} virtual ~I2CSPIDriver() = default; @@ -251,4 +285,33 @@ protected: } // *INDENT-ON* private: + + // SFINAE to use R::instantiate if it exists, and R::instantiate_default otherwise + template + class InstantiateHelper + { + template + static constexpr I2CSPIDriverBase::instantiate_method get(decltype(&C::instantiate)) { return &C::instantiate; } + template + static constexpr I2CSPIDriverBase::instantiate_method get(...) { return &C::instantiate_default; } + public: + static constexpr I2CSPIDriverBase::instantiate_method m = get(0); + }; + + static I2CSPIDriverBase *instantiate_default(const I2CSPIDriverConfig &config, int runtime_instance) + { + T *instance = new T(config); + + if (!instance) { + PX4_ERR("alloc failed"); + return nullptr; + } + + if (OK != instance->init()) { + delete instance; + return nullptr; + } + + return instance; + } }; diff --git a/platforms/common/include/px4_platform_common/spi.h b/platforms/common/include/px4_platform_common/spi.h index 9cf48939ff..2b1d6479fa 100644 --- a/platforms/common/include/px4_platform_common/spi.h +++ b/platforms/common/include/px4_platform_common/spi.h @@ -158,11 +158,13 @@ public: bool external() const { return px4_spi_bus_external(bus()); } + int busDeviceIndex() const { return _bus_device_index; } + private: const FilterType _filter; const uint16_t _devid_driver_index; const int _bus; - int _index{-1}; - int _external_bus_counter{0}; - int _bus_device_index{0}; + int _index{0}; + int _external_bus_counter{1}; + int _bus_device_index{-1}; }; diff --git a/platforms/common/spi.cpp b/platforms/common/spi.cpp index 4e507617b6..e581790975 100644 --- a/platforms/common/spi.cpp +++ b/platforms/common/spi.cpp @@ -109,8 +109,7 @@ bool px4_spi_bus_external(const px4_spi_bus_t &bus) bool SPIBusIterator::next() { - // we have at most 1 match per bus, so we can directly jump to the next bus - while (++_index < SPI_BUS_MAX_BUS_ITEMS && px4_spi_buses[_index].bus != -1) { + while (_index < SPI_BUS_MAX_BUS_ITEMS && px4_spi_buses[_index].bus != -1) { const px4_spi_bus_t &bus_data = px4_spi_buses[_index]; if (!board_has_bus(BOARD_SPI_BUS, bus_data.bus)) { @@ -127,7 +126,7 @@ bool SPIBusIterator::next() if (!bus_data.is_external) { if (_bus == bus_data.bus || _bus == -1) { // find device id - for (int i = 0; i < SPI_BUS_MAX_DEVICES; ++i) { + for (int i = _bus_device_index + 1; i < SPI_BUS_MAX_DEVICES; ++i) { if (PX4_SPI_DEVICE_ID == PX4_SPIDEVID_TYPE(bus_data.devices[i].devid) && _devid_driver_index == bus_data.devices[i].devtype_driver) { _bus_device_index = i; @@ -141,11 +140,10 @@ bool SPIBusIterator::next() case FilterType::ExternalBus: if (bus_data.is_external) { - ++_external_bus_counter; uint16_t cs_index = _devid_driver_index - 1; if (_bus == _external_bus_counter && cs_index < SPI_BUS_MAX_DEVICES && - bus_data.devices[cs_index].cs_gpio != 0) { + bus_data.devices[cs_index].cs_gpio != 0 && cs_index != _bus_device_index) { // we know that bus_data.devices[cs_index].devtype_driver == cs_index _bus_device_index = cs_index; return true; @@ -154,6 +152,13 @@ bool SPIBusIterator::next() break; } + + if (bus_data.is_external) { + ++_external_bus_counter; + } + + ++_index; + _bus_device_index = -1; } return false; diff --git a/platforms/nuttx/src/px4/nxp/imxrt/include/px4_arch/spi_hw_description.h b/platforms/nuttx/src/px4/nxp/imxrt/include/px4_arch/spi_hw_description.h index 91bc32e9f5..fe3ca8453d 100644 --- a/platforms/nuttx/src/px4/nxp/imxrt/include/px4_arch/spi_hw_description.h +++ b/platforms/nuttx/src/px4/nxp/imxrt/include/px4_arch/spi_hw_description.h @@ -73,16 +73,22 @@ static inline constexpr px4_spi_bus_t initSPIBus(SPI::Bus bus, const px4_spi_bus for (int i = 0; i < SPI_BUS_MAX_DEVICES; ++i) { ret.devices[i] = devices.devices[i]; - // check that the same device is configured only once (the chip-select code depends on that) - for (int j = i + 1; j < SPI_BUS_MAX_DEVICES; ++j) { - if (ret.devices[j].cs_gpio != 0) { - constexpr_assert(ret.devices[i].devid != ret.devices[j].devid, "Same device configured multiple times"); - } - } if (ret.devices[i].cs_gpio != 0) { - // A bus potentially requires locking if it is accessed by non-PX4 devices (i.e. NuttX drivers) - if (PX4_SPI_DEVICE_ID != PX4_SPIDEVID_TYPE(ret.devices[i].devid)) { + if (PX4_SPI_DEVICE_ID == PX4_SPIDEVID_TYPE(ret.devices[i].devid)) { + int same_devices_count = 0; + + for (int j = 0; j < i; ++j) { + if (ret.devices[j].cs_gpio != 0) { + same_devices_count += (ret.devices[i].devid & 0xff) == (ret.devices[j].devid & 0xff); + } + } + + // increment the 2. LSB byte to allow multiple devices of the same type + ret.devices[i].devid |= same_devices_count << 8; + + } else { + // A bus potentially requires locking if it is accessed by non-PX4 devices (i.e. NuttX drivers) ret.requires_locking = true; } } diff --git a/platforms/nuttx/src/px4/nxp/kinetis/include/px4_arch/spi_hw_description.h b/platforms/nuttx/src/px4/nxp/kinetis/include/px4_arch/spi_hw_description.h index 5dda16ec16..188748791e 100644 --- a/platforms/nuttx/src/px4/nxp/kinetis/include/px4_arch/spi_hw_description.h +++ b/platforms/nuttx/src/px4/nxp/kinetis/include/px4_arch/spi_hw_description.h @@ -67,16 +67,22 @@ static inline constexpr px4_spi_bus_t initSPIBus(SPI::Bus bus, const px4_spi_bus for (int i = 0; i < SPI_BUS_MAX_DEVICES; ++i) { ret.devices[i] = devices.devices[i]; - // check that the same device is configured only once (the chip-select code depends on that) - for (int j = i + 1; j < SPI_BUS_MAX_DEVICES; ++j) { - if (ret.devices[j].cs_gpio != 0) { - constexpr_assert(ret.devices[i].devid != ret.devices[j].devid, "Same device configured multiple times"); - } - } if (ret.devices[i].cs_gpio != 0) { - // A bus potentially requires locking if it is accessed by non-PX4 devices (i.e. NuttX drivers) - if (PX4_SPI_DEVICE_ID != PX4_SPIDEVID_TYPE(ret.devices[i].devid)) { + if (PX4_SPI_DEVICE_ID == PX4_SPIDEVID_TYPE(ret.devices[i].devid)) { + int same_devices_count = 0; + + for (int j = 0; j < i; ++j) { + if (ret.devices[j].cs_gpio != 0) { + same_devices_count += (ret.devices[i].devid & 0xff) == (ret.devices[j].devid & 0xff); + } + } + + // increment the 2. LSB byte to allow multiple devices of the same type + ret.devices[i].devid |= same_devices_count << 8; + + } else { + // A bus potentially requires locking if it is accessed by non-PX4 devices (i.e. NuttX drivers) ret.requires_locking = true; } } diff --git a/platforms/nuttx/src/px4/stm/stm32_common/include/px4_arch/spi_hw_description.h b/platforms/nuttx/src/px4/stm/stm32_common/include/px4_arch/spi_hw_description.h index d89a5be1f4..9ec1b80671 100644 --- a/platforms/nuttx/src/px4/stm/stm32_common/include/px4_arch/spi_hw_description.h +++ b/platforms/nuttx/src/px4/stm/stm32_common/include/px4_arch/spi_hw_description.h @@ -69,16 +69,22 @@ static inline constexpr px4_spi_bus_t initSPIBus(SPI::Bus bus, const px4_spi_bus for (int i = 0; i < SPI_BUS_MAX_DEVICES; ++i) { ret.devices[i] = devices.devices[i]; - // check that the same device is configured only once (the chip-select code depends on that) - for (int j = i + 1; j < SPI_BUS_MAX_DEVICES; ++j) { - if (ret.devices[j].cs_gpio != 0) { - constexpr_assert(ret.devices[i].devid != ret.devices[j].devid, "Same device configured multiple times"); - } - } if (ret.devices[i].cs_gpio != 0) { - // A bus potentially requires locking if it is accessed by non-PX4 devices (i.e. NuttX drivers) - if (PX4_SPI_DEVICE_ID != PX4_SPIDEVID_TYPE(ret.devices[i].devid)) { + if (PX4_SPI_DEVICE_ID == PX4_SPIDEVID_TYPE(ret.devices[i].devid)) { + int same_devices_count = 0; + + for (int j = 0; j < i; ++j) { + if (ret.devices[j].cs_gpio != 0) { + same_devices_count += (ret.devices[i].devid & 0xff) == (ret.devices[j].devid & 0xff); + } + } + + // increment the 2. LSB byte to allow multiple devices of the same type + ret.devices[i].devid |= same_devices_count << 8; + + } else { + // A bus potentially requires locking if it is accessed by non-PX4 devices (i.e. NuttX drivers) ret.requires_locking = true; } } diff --git a/src/lib/drivers/device/nuttx/I2C.cpp b/src/lib/drivers/device/nuttx/I2C.cpp index 353a0f8c65..c2ffb06c04 100644 --- a/src/lib/drivers/device/nuttx/I2C.cpp +++ b/src/lib/drivers/device/nuttx/I2C.cpp @@ -42,6 +42,7 @@ #include "I2C.hpp" +#include #include namespace device @@ -64,6 +65,11 @@ I2C::I2C(uint8_t device_type, const char *name, const int bus, const uint16_t ad _device_id.devid_s.address = address; } +I2C::I2C(const I2CSPIDriverConfig &config) + : I2C(config.devid_driver_index, config.module_name, config.bus, config.i2c_address, config.bus_frequency) +{ +} + I2C::~I2C() { if (_dev) { diff --git a/src/lib/drivers/device/nuttx/I2C.hpp b/src/lib/drivers/device/nuttx/I2C.hpp index beac354876..d37d809c8b 100644 --- a/src/lib/drivers/device/nuttx/I2C.hpp +++ b/src/lib/drivers/device/nuttx/I2C.hpp @@ -45,6 +45,8 @@ #include +struct I2CSPIDriverConfig; + #if !defined(CONFIG_I2C) # error I2C support requires CONFIG_I2C #endif @@ -87,6 +89,7 @@ protected: * @param frequency I2C bus frequency for the device (currently not used) */ I2C(uint8_t device_type, const char *name, const int bus, const uint16_t address, const uint32_t frequency); + I2C(const I2CSPIDriverConfig &config); virtual ~I2C(); /** diff --git a/src/lib/drivers/device/nuttx/SPI.cpp b/src/lib/drivers/device/nuttx/SPI.cpp index 5621275f72..8257b2d545 100644 --- a/src/lib/drivers/device/nuttx/SPI.cpp +++ b/src/lib/drivers/device/nuttx/SPI.cpp @@ -47,6 +47,7 @@ #include "SPI.hpp" +#include #include #include @@ -67,8 +68,7 @@ SPI::SPI(uint8_t device_type, const char *name, int bus, uint32_t device, enum s // fill in _device_id fields for a SPI device _device_id.devid_s.bus_type = DeviceBusType_SPI; _device_id.devid_s.bus = bus; - // Use the 2. LSB byte as SPI address. This is currently 0, but will allow to extend - // for multiple instances of the same device on a bus, should that ever be required. + // Use the 2. LSB byte as SPI address, which is non-zero for multiple instances of the same device on a bus _device_id.devid_s.address = (uint8_t)(device >> 8); if (!px4_spi_bus_requires_locking(bus)) { @@ -76,6 +76,12 @@ SPI::SPI(uint8_t device_type, const char *name, int bus, uint32_t device, enum s } } +SPI::SPI(const I2CSPIDriverConfig &config) + : SPI(config.devid_driver_index, config.module_name, config.bus, config.spi_devid, config.spi_mode, + config.bus_frequency) +{ +} + SPI::~SPI() { // XXX no way to let go of the bus... diff --git a/src/lib/drivers/device/nuttx/SPI.hpp b/src/lib/drivers/device/nuttx/SPI.hpp index a325d8f319..edc098bc5f 100644 --- a/src/lib/drivers/device/nuttx/SPI.hpp +++ b/src/lib/drivers/device/nuttx/SPI.hpp @@ -45,6 +45,8 @@ #include #include +struct I2CSPIDriverConfig; + namespace device __EXPORT { @@ -72,6 +74,9 @@ protected: * @param frequency SPI clock frequency */ SPI(uint8_t device_type, const char *name, int bus, uint32_t device, enum spi_mode_e mode, uint32_t frequency); + + SPI(const I2CSPIDriverConfig &config); + virtual ~SPI(); /** diff --git a/src/lib/drivers/device/posix/I2C.cpp b/src/lib/drivers/device/posix/I2C.cpp index 60fe4a25dd..d89489e290 100644 --- a/src/lib/drivers/device/posix/I2C.cpp +++ b/src/lib/drivers/device/posix/I2C.cpp @@ -47,6 +47,8 @@ #include #include +#include + namespace device { @@ -60,6 +62,11 @@ I2C::I2C(uint8_t device_type, const char *name, const int bus, const uint16_t ad _device_id.devid_s.address = address; } +I2C::I2C(const I2CSPIDriverConfig &config) + : I2C(config.devid_driver_index, config.module_name, config.bus, config.i2c_address, config.bus_frequency) +{ +} + I2C::~I2C() { if (_fd >= 0) { diff --git a/src/lib/drivers/device/posix/I2C.hpp b/src/lib/drivers/device/posix/I2C.hpp index 369b97bd93..321322aa48 100644 --- a/src/lib/drivers/device/posix/I2C.hpp +++ b/src/lib/drivers/device/posix/I2C.hpp @@ -43,6 +43,8 @@ #include "../CDev.hpp" #include +struct I2CSPIDriverConfig; + namespace device __EXPORT { @@ -79,6 +81,7 @@ protected: * @param frequency I2C bus frequency for the device (currently not used) */ I2C(uint8_t device_type, const char *name, const int bus, const uint16_t address, const uint32_t frequency); + I2C(const I2CSPIDriverConfig &config); virtual ~I2C(); /** diff --git a/src/lib/drivers/device/posix/SPI.cpp b/src/lib/drivers/device/posix/SPI.cpp index 56147ba5b9..9de983ee24 100644 --- a/src/lib/drivers/device/posix/SPI.cpp +++ b/src/lib/drivers/device/posix/SPI.cpp @@ -48,6 +48,7 @@ #include #include +#include #include namespace device @@ -66,6 +67,13 @@ SPI::SPI(uint8_t device_type, const char *name, int bus, uint32_t device, enum s _device_id.devid_s.address = (uint8_t)device; } +SPI::SPI(const I2CSPIDriverConfig &config) + : SPI(config.devid_driver_index, config.module_name, config.bus, config.spi_devid, config.spi_mode, + config.bus_frequency) +{ +} + + SPI::~SPI() { if (_fd >= 0) { diff --git a/src/lib/drivers/device/posix/SPI.hpp b/src/lib/drivers/device/posix/SPI.hpp index f33210d51f..3056584a53 100644 --- a/src/lib/drivers/device/posix/SPI.hpp +++ b/src/lib/drivers/device/posix/SPI.hpp @@ -58,6 +58,8 @@ enum spi_mode_e { SPIDEV_MODE3 = SPI_MODE_3 /* CPOL=1 CHPHA=1 */ }; +struct I2CSPIDriverConfig; + namespace device __EXPORT { @@ -85,6 +87,9 @@ protected: * @param frequency SPI clock frequency */ SPI(uint8_t device_type, const char *name, int bus, uint32_t device, enum spi_mode_e mode, uint32_t frequency); + + SPI(const I2CSPIDriverConfig &config); + virtual ~SPI(); /** diff --git a/src/lib/drivers/device/qurt/I2C.cpp b/src/lib/drivers/device/qurt/I2C.cpp index 1eb7a8dde4..28655a926f 100644 --- a/src/lib/drivers/device/qurt/I2C.cpp +++ b/src/lib/drivers/device/qurt/I2C.cpp @@ -44,6 +44,8 @@ #include +#include + namespace device { @@ -58,6 +60,11 @@ I2C::I2C(uint8_t device_type, const char *name, const int bus, const uint16_t ad _device_id.devid_s.address = address; } +I2C::I2C(const I2CSPIDriverConfig &config) + : I2C(config.devid_driver_index, config.module_name, config.bus, config.i2c_address, config.bus_frequency) +{ +} + I2C::~I2C() { if (_fd >= 0) { diff --git a/src/lib/drivers/device/qurt/I2C.hpp b/src/lib/drivers/device/qurt/I2C.hpp index 8dc7bd3578..ce7bd94f83 100644 --- a/src/lib/drivers/device/qurt/I2C.hpp +++ b/src/lib/drivers/device/qurt/I2C.hpp @@ -42,6 +42,8 @@ #include "../CDev.hpp" +struct I2CSPIDriverConfig; + namespace device __EXPORT { @@ -78,6 +80,7 @@ protected: * @param frequency I2C bus frequency for the device (currently not used) */ I2C(uint8_t device_type, const char *name, const int bus, const uint16_t address, const uint32_t frequency); + I2C(const I2CSPIDriverConfig &config); virtual ~I2C(); /** diff --git a/src/lib/drivers/device/qurt/SPI.cpp b/src/lib/drivers/device/qurt/SPI.cpp index 137e59456b..dec76b6fc9 100644 --- a/src/lib/drivers/device/qurt/SPI.cpp +++ b/src/lib/drivers/device/qurt/SPI.cpp @@ -46,6 +46,7 @@ #include "dev_fs_lib_spi.h" +#include #include namespace device @@ -64,6 +65,12 @@ SPI::SPI(uint8_t device_type, const char *name, int bus, uint32_t device, enum s _device_id.devid_s.address = (uint8_t)device; } +SPI::SPI(const I2CSPIDriverConfig &config) + : SPI(config.devid_driver_index, config.module_name, config.bus, config.spi_devid, config.spi_mode, + config.bus_frequency) +{ +} + SPI::~SPI() { if (_fd >= 0) { diff --git a/src/lib/drivers/device/qurt/SPI.hpp b/src/lib/drivers/device/qurt/SPI.hpp index a54610bec9..76a7364c1d 100644 --- a/src/lib/drivers/device/qurt/SPI.hpp +++ b/src/lib/drivers/device/qurt/SPI.hpp @@ -50,6 +50,8 @@ enum spi_mode_e { SPIDEV_MODE3 = 3 /* CPOL=1 CHPHA=1 */ }; +struct I2CSPIDriverConfig; + namespace device __EXPORT { @@ -70,6 +72,7 @@ protected: * @param frequency SPI clock frequency */ SPI(uint8_t device_type, const char *name, int bus, uint32_t device, enum spi_mode_e mode, uint32_t frequency); + SPI(const I2CSPIDriverConfig &config); virtual ~SPI(); /**