diff --git a/src/components/ds18x20/controller.cpp b/src/components/ds18x20/controller.cpp index 7f46811f1..06a4a3b2c 100644 --- a/src/components/ds18x20/controller.cpp +++ b/src/components/ds18x20/controller.cpp @@ -19,14 +19,20 @@ @brief DS18X20Controller constructor */ /***********************************************************************/ -DS18X20Controller::DS18X20Controller() { _DS18X20_model = new DS18X20Model(); } +DS18X20Controller::DS18X20Controller() { + _num_drivers = 0; + _DS18X20_model = new DS18X20Model(); +} /***********************************************************************/ /*! @brief DS18X20Controller destructor */ /***********************************************************************/ -DS18X20Controller::~DS18X20Controller() { delete _DS18X20_model; } +DS18X20Controller::~DS18X20Controller() { + _num_drivers = 0; + delete _DS18X20_model; +} /***********************************************************************/ /*! @@ -59,7 +65,8 @@ bool DS18X20Controller::Handle_Ds18x20Add(pb_istream_t *stream) { uint8_t pin_name = atoi(_DS18X20_model->GetDS18x20AddMsg()->onewire_pin + 1); // Initialize the DS18X20Hardware object - auto new_dsx_driver = std::make_unique(pin_name); + auto new_dsx_driver = + std::make_unique(pin_name, _num_drivers); // Attempt to get the sensor's ID on the OneWire bus to show it's been init'd bool is_initialized = new_dsx_driver->GetSensor(); @@ -95,8 +102,10 @@ bool DS18X20Controller::Handle_Ds18x20Add(pb_istream_t *stream) { } // If the sensor was successfully initialized, add it to the controller - if (is_initialized == true) + if (is_initialized == true) { _DS18X20_pins.push_back(std::move(new_dsx_driver)); + _num_drivers++; + } // Print out the details WS_DEBUG_PRINTLN("[ds18x] New Sensor Added!"); @@ -172,6 +181,7 @@ bool DS18X20Controller::Handle_Ds18x20Remove(pb_istream_t *stream) { } } WS_DEBUG_PRINTLN("Removed!"); + _num_drivers--; return true; } diff --git a/src/components/ds18x20/controller.h b/src/components/ds18x20/controller.h index a77182f47..037e517b7 100644 --- a/src/components/ds18x20/controller.h +++ b/src/components/ds18x20/controller.h @@ -41,6 +41,7 @@ class DS18X20Controller { private: DS18X20Model *_DS18X20_model; ///< ds18x20 model std::vector> _DS18X20_pins; + int _num_drivers; }; extern Wippersnapper_V2 WsV2; ///< Wippersnapper V2 instance #endif // WS_DS18X20_CONTROLLER_H \ No newline at end of file diff --git a/src/components/ds18x20/hardware.cpp b/src/components/ds18x20/hardware.cpp index 4936d983f..beaf37aa0 100644 --- a/src/components/ds18x20/hardware.cpp +++ b/src/components/ds18x20/hardware.cpp @@ -19,14 +19,17 @@ @brief DS18X20Hardware constructor @param onewire_pin The OneWire bus pin to use. + @param sensor_num + Unique identifier for the sensor driver. */ /***********************************************************************/ -DS18X20Hardware::DS18X20Hardware(uint8_t onewire_pin) : _drv_therm(_ow) { +DS18X20Hardware::DS18X20Hardware(uint8_t onewire_pin, int sensor_num) + : _drv_therm(_ow) { is_read_temp_c = false; is_read_temp_f = false; + _sensor_num = sensor_num; // Initialize the OneWire bus object _onewire_pin = onewire_pin; - new (&_ow) OneWireNg_CurrentPlatform(onewire_pin, false); } /***********************************************************************/ @@ -39,13 +42,40 @@ DS18X20Hardware::~DS18X20Hardware() { INPUT); // Set the pin to hi-z and release it for other uses } -/***********************************************************************/ +/****************************************************************************/ /*! - @brief Get the sensor's ID - @returns True if the sensor was successfully identified, False otherwise. + @brief Initializes the DS18X20 sensor driver and verifies that the + sensor is present on the OneWire bus. + @returns True if the sensor was successfully initialized, False + otherwise. */ -/***********************************************************************/ +/****************************************************************************/ bool DS18X20Hardware::GetSensor() { +// Initialize the DS18X20 driver +#ifdef ARDUINO_ARCH_RP2040 + // RP2040 is special - it uses the PIO's rather than the standard bitbang + // implementation In this implementation, we select the PIO instance based on + // driver identifier + + // NOTE: We are only going to allow *up to* 7 DS18x20 sensors on RP2040 + // because the status pixel requires a PIO SM to be allocated prior. + int pio_num; + if (_sensor_num <= 4) { + // drivers 0 thru 3 are handled by PIO0/SM0..4 + new (&_ow) OneWireNg_CurrentPlatform(_onewire_pin, false, 0); + } else if (_sensor_num <= 7) { + // drivers 5 thru 8 are handled by PIO1/SM1..4 + new (&_ow) OneWireNg_CurrentPlatform(_onewire_pin, false, 1); + } else { + WS_DEBUG_PRINTLN( + "[ds18x20] ERROR: You may only add up to 7 sensors on RP2040!"); + return false; + } +#else + // Initialize the standard bit-banged DS18X20 driver object + new (&_ow) OneWireNg_CurrentPlatform(_onewire_pin, false); +#endif + OneWireNg::ErrorCode ec = _ow->readSingleId(_sensorId); return ec == OneWireNg::EC_SUCCESS; } diff --git a/src/components/ds18x20/hardware.h b/src/components/ds18x20/hardware.h index 0fcb8288c..95e8b6663 100644 --- a/src/components/ds18x20/hardware.h +++ b/src/components/ds18x20/hardware.h @@ -20,6 +20,12 @@ #include "drivers/DSTherm.h" #include "utils/Placeholder.h" +#if defined(ARDUINO_ARCH_RP2040) +#define CONFIG_RP2040_PIO_DRIVER ///< Enable the OneWireNg_PicoRP2040PIO driver +#define CONFIG_RP2040_PIOSM_NUM_USED \ + 1 ///< 4 drivers handled by PIO1, 4 drivers handled by PIO2 +#endif + /**************************************************************************/ /*! @brief Interface for interacting with the's DallasTemp @@ -28,7 +34,7 @@ /**************************************************************************/ class DS18X20Hardware { public: - DS18X20Hardware(uint8_t onewire_pin); + DS18X20Hardware(uint8_t onewire_pin, int sensor_num); ~DS18X20Hardware(); uint8_t GetOneWirePin(); void SetResolution(int resolution); @@ -55,6 +61,7 @@ class DS18X20Hardware { uint8_t _onewire_pin; ///< Pin utilized by the OneWire bus, used for addressing char _onewire_pin_name[5]; ///< Name of the OneWire bus pin + int _sensor_num; float _period; ///< The desired period to read the sensor, in seconds float _prv_period; ///< Last time the sensor was polled, in seconds };