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
*/
/***********************************************************************/
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<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
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;
}

View file

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

View file

@ -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;
}

View file

@ -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 @@ private:
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
};