Skip to content

Commit

Permalink
Refactor to use PIO-specific driver on RP2040 platforms, rather than …
Browse files Browse the repository at this point in the history
…bitbang it

clean up

max 7

clang
  • Loading branch information
brentru committed Mar 6, 2025
1 parent ca568b3 commit 09095e5
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 11 deletions.
18 changes: 14 additions & 4 deletions src/components/ds18x20/controller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

/***********************************************************************/
/*!
Expand Down Expand Up @@ -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();

Expand Down Expand Up @@ -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!");
Expand Down Expand Up @@ -172,6 +181,7 @@ bool DS18X20Controller::Handle_Ds18x20Remove(pb_istream_t *stream) {
}
}
WS_DEBUG_PRINTLN("Removed!");
_num_drivers--;
return true;
}

Expand Down
1 change: 1 addition & 0 deletions src/components/ds18x20/controller.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ class DS18X20Controller {
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
42 changes: 36 additions & 6 deletions src/components/ds18x20/hardware.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

/***********************************************************************/
Expand All @@ -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;
}
Expand Down
9 changes: 8 additions & 1 deletion src/components/ds18x20/hardware.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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);
Expand All @@ -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
};
Expand Down

0 comments on commit 09095e5

Please sign in to comment.