Refactor to use PIO-specific driver on RP2040 platforms, rather than bitbang it

clean up

max 7

clang
This commit is contained in:
brentru 2025-03-05 16:48:54 -05:00
parent ca568b36e2
commit 09095e56f3
4 changed files with 59 additions and 11 deletions

View file

@ -19,14 +19,20 @@
@brief DS18X20Controller constructor @brief DS18X20Controller constructor
*/ */
/***********************************************************************/ /***********************************************************************/
DS18X20Controller::DS18X20Controller() { _DS18X20_model = new DS18X20Model(); } DS18X20Controller::DS18X20Controller() {
_num_drivers = 0;
_DS18X20_model = new DS18X20Model();
}
/***********************************************************************/ /***********************************************************************/
/*! /*!
@brief DS18X20Controller destructor @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); uint8_t pin_name = atoi(_DS18X20_model->GetDS18x20AddMsg()->onewire_pin + 1);
// Initialize the DS18X20Hardware object // Initialize the DS18X20Hardware object
auto new_dsx_driver = std::make_unique<DS18X20Hardware>(pin_name); auto new_dsx_driver =
std::make_unique<DS18X20Hardware>(pin_name, _num_drivers);
// Attempt to get the sensor's ID on the OneWire bus to show it's been init'd // 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(); 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 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)); _DS18X20_pins.push_back(std::move(new_dsx_driver));
_num_drivers++;
}
// Print out the details // Print out the details
WS_DEBUG_PRINTLN("[ds18x] New Sensor Added!"); WS_DEBUG_PRINTLN("[ds18x] New Sensor Added!");
@ -172,6 +181,7 @@ bool DS18X20Controller::Handle_Ds18x20Remove(pb_istream_t *stream) {
} }
} }
WS_DEBUG_PRINTLN("Removed!"); WS_DEBUG_PRINTLN("Removed!");
_num_drivers--;
return true; return true;
} }

View file

@ -41,6 +41,7 @@ public:
private: private:
DS18X20Model *_DS18X20_model; ///< ds18x20 model DS18X20Model *_DS18X20_model; ///< ds18x20 model
std::vector<std::unique_ptr<DS18X20Hardware>> _DS18X20_pins; std::vector<std::unique_ptr<DS18X20Hardware>> _DS18X20_pins;
int _num_drivers;
}; };
extern Wippersnapper_V2 WsV2; ///< Wippersnapper V2 instance extern Wippersnapper_V2 WsV2; ///< Wippersnapper V2 instance
#endif // WS_DS18X20_CONTROLLER_H #endif // WS_DS18X20_CONTROLLER_H

View file

@ -19,14 +19,17 @@
@brief DS18X20Hardware constructor @brief DS18X20Hardware constructor
@param onewire_pin @param onewire_pin
The OneWire bus pin to use. 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_c = false;
is_read_temp_f = false; is_read_temp_f = false;
_sensor_num = sensor_num;
// Initialize the OneWire bus object // Initialize the OneWire bus object
_onewire_pin = onewire_pin; _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 INPUT); // Set the pin to hi-z and release it for other uses
} }
/***********************************************************************/ /****************************************************************************/
/*! /*!
@brief Get the sensor's ID @brief Initializes the DS18X20 sensor driver and verifies that the
@returns True if the sensor was successfully identified, False otherwise. sensor is present on the OneWire bus.
@returns True if the sensor was successfully initialized, False
otherwise.
*/ */
/***********************************************************************/ /****************************************************************************/
bool DS18X20Hardware::GetSensor() { 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); OneWireNg::ErrorCode ec = _ow->readSingleId(_sensorId);
return ec == OneWireNg::EC_SUCCESS; return ec == OneWireNg::EC_SUCCESS;
} }

View file

@ -20,6 +20,12 @@
#include "drivers/DSTherm.h" #include "drivers/DSTherm.h"
#include "utils/Placeholder.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 @brief Interface for interacting with the's DallasTemp
@ -28,7 +34,7 @@
/**************************************************************************/ /**************************************************************************/
class DS18X20Hardware { class DS18X20Hardware {
public: public:
DS18X20Hardware(uint8_t onewire_pin); DS18X20Hardware(uint8_t onewire_pin, int sensor_num);
~DS18X20Hardware(); ~DS18X20Hardware();
uint8_t GetOneWirePin(); uint8_t GetOneWirePin();
void SetResolution(int resolution); void SetResolution(int resolution);
@ -55,6 +61,7 @@ private:
uint8_t uint8_t
_onewire_pin; ///< Pin utilized by the OneWire bus, used for addressing _onewire_pin; ///< Pin utilized by the OneWire bus, used for addressing
char _onewire_pin_name[5]; ///< Name of the OneWire bus pin 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 _period; ///< The desired period to read the sensor, in seconds
float _prv_period; ///< Last time the sensor was polled, in seconds float _prv_period; ///< Last time the sensor was polled, in seconds
}; };