pulse_counter_ulp: Record and dump all config items

This commit is contained in:
brisk 2024-09-11 14:14:36 +09:30
parent 8b66ff90d8
commit 67b746693f
3 changed files with 29 additions and 22 deletions

View file

@ -28,8 +28,7 @@ const char *to_string(CountMode count_mode) {
extern const uint8_t ulp_main_bin_start[] asm("_binary_ulp_main_bin_start"); extern const uint8_t ulp_main_bin_start[] asm("_binary_ulp_main_bin_start");
extern const uint8_t ulp_main_bin_end[] asm("_binary_ulp_main_bin_end"); extern const uint8_t ulp_main_bin_end[] asm("_binary_ulp_main_bin_end");
std::unique_ptr<UlpProgram> UlpProgram::start(gpio_num_t gpio_num, microseconds sleep_duration, std::unique_ptr<UlpProgram> UlpProgram::start(const Config &config) {
CountMode rising_edge_mode, CountMode falling_edge_mode) {
esp_err_t error = ulp_load_binary(0, ulp_main_bin_start, (ulp_main_bin_end - ulp_main_bin_start) / sizeof(uint32_t)); esp_err_t error = ulp_load_binary(0, ulp_main_bin_start, (ulp_main_bin_end - ulp_main_bin_start) / sizeof(uint32_t));
if (error != ESP_OK) { if (error != ESP_OK) {
ESP_LOGE(TAG, "Loading ULP binary failed: %s", esp_err_to_name(error)); ESP_LOGE(TAG, "Loading ULP binary failed: %s", esp_err_to_name(error));
@ -37,6 +36,7 @@ std::unique_ptr<UlpProgram> UlpProgram::start(gpio_num_t gpio_num, microseconds
} }
/* GPIO used for pulse counting. */ /* GPIO used for pulse counting. */
gpio_num_t gpio_num = static_cast<gpio_num_t>(config.pin_->get_pin());
int rtcio_num = rtc_io_number_get(gpio_num); int rtcio_num = rtc_io_number_get(gpio_num);
if (!rtc_gpio_is_valid_gpio(gpio_num)) { if (!rtc_gpio_is_valid_gpio(gpio_num)) {
ESP_LOGE(TAG, "GPIO used for pulse counting must be an RTC IO"); ESP_LOGE(TAG, "GPIO used for pulse counting must be an RTC IO");
@ -54,10 +54,10 @@ std::unique_ptr<UlpProgram> UlpProgram::start(gpio_num_t gpio_num, microseconds
ulp_edge_count = 0; ulp_edge_count = 0;
ulp_run_count = 0; ulp_run_count = 0;
ulp_debounce_counter = 3; ulp_debounce_counter = 3;
ulp_debounce_max_count = 3; ulp_debounce_max_count = config.debounce_;
ulp_next_edge = 0; ulp_next_edge = 0;
ulp_io_number = rtcio_num; /* map from GPIO# to RTC_IO# */ ulp_io_number = rtcio_num; /* map from GPIO# to RTC_IO# */
ulp_mean_exec_time = sleep_duration / microseconds{1}; ulp_mean_exec_time = config.sleep_duration_ / microseconds{1};
/* Initialize selected GPIO as RTC IO, enable input */ /* Initialize selected GPIO as RTC IO, enable input */
rtc_gpio_init(gpio_num); rtc_gpio_init(gpio_num);
@ -67,7 +67,7 @@ std::unique_ptr<UlpProgram> UlpProgram::start(gpio_num_t gpio_num, microseconds
/* Set ULP wake up period T /* Set ULP wake up period T
* Minimum pulse width has to be T * (ulp_debounce_counter + 1). * Minimum pulse width has to be T * (ulp_debounce_counter + 1).
*/ */
ulp_set_wakeup_period(0, sleep_duration / std::chrono::microseconds{1}); ulp_set_wakeup_period(0, config.sleep_duration_ / std::chrono::microseconds{1});
/* Start the program */ /* Start the program */
error = ulp_run(&ulp_entry - RTC_SLOW_MEM); error = ulp_run(&ulp_entry - RTC_SLOW_MEM);
@ -103,12 +103,11 @@ void UlpProgram::set_mean_exec_time(microseconds mean_exec_time) {
void PulseCounterUlpSensor::setup() { void PulseCounterUlpSensor::setup() {
ESP_LOGCONFIG(TAG, "Setting up pulse counter '%s'...", this->name_.c_str()); ESP_LOGCONFIG(TAG, "Setting up pulse counter '%s'...", this->name_.c_str());
this->pin_->setup(); this->config_.pin_->setup();
if (esp_sleep_get_wakeup_cause() == ESP_SLEEP_WAKEUP_UNDEFINED) { if (esp_sleep_get_wakeup_cause() == ESP_SLEEP_WAKEUP_UNDEFINED) {
ESP_LOGD(TAG, "Did not wake up from sleep, assuming restart or first boot and setting up ULP program"); ESP_LOGD(TAG, "Did not wake up from sleep, assuming restart or first boot and setting up ULP program");
this->storage_ = UlpProgram::start(static_cast<gpio_num_t>(this->pin_->get_pin()), this->sleep_duration_, this->storage_ = UlpProgram::start(this->config_);
this->rising_edge_mode, this->falling_edge_mode);
} else { } else {
ESP_LOGD(TAG, "Woke up from sleep, skipping set-up of ULP program"); ESP_LOGD(TAG, "Woke up from sleep, skipping set-up of ULP program");
this->storage_ = std::unique_ptr<UlpProgram>(new UlpProgram); this->storage_ = std::unique_ptr<UlpProgram>(new UlpProgram);
@ -129,9 +128,11 @@ void PulseCounterUlpSensor::set_total_pulses(uint32_t pulses) {
void PulseCounterUlpSensor::dump_config() { void PulseCounterUlpSensor::dump_config() {
LOG_SENSOR("", "Pulse Counter", this); LOG_SENSOR("", "Pulse Counter", this);
LOG_PIN(" Pin: ", this->pin_); LOG_PIN(" Pin: ", this->config_.pin_);
ESP_LOGCONFIG(TAG, " Rising Edge: %s", to_string(this->rising_edge_mode)); ESP_LOGCONFIG(TAG, " Rising Edge: %s", to_string(this->config_.rising_edge_mode_));
ESP_LOGCONFIG(TAG, " Falling Edge: %s", to_string(this->falling_edge_mode)); ESP_LOGCONFIG(TAG, " Falling Edge: %s", to_string(this->config_.falling_edge_mode_));
ESP_LOGCONFIG(TAG, " Sleep Duration: " PRIu32 " µs", this->config_.sleep_duration_ / microseconds{1});
ESP_LOGCONFIG(TAG, " Debounce: " PRIu16, this->config_.debounce_);
LOG_UPDATE_INTERVAL(this); LOG_UPDATE_INTERVAL(this);
} }

View file

@ -20,6 +20,13 @@ using microseconds = std::chrono::duration<uint32_t, std::micro>;
class UlpProgram { class UlpProgram {
public: public:
struct Config {
InternalGPIOPin *pin_;
CountMode rising_edge_mode_;
CountMode falling_edge_mode_;
microseconds sleep_duration_;
uint16_t debounce_;
};
struct State { struct State {
uint16_t edge_count; uint16_t edge_count;
uint16_t run_count; uint16_t run_count;
@ -29,18 +36,18 @@ class UlpProgram {
State peek_state() const; State peek_state() const;
void set_mean_exec_time(microseconds mean_exec_time); void set_mean_exec_time(microseconds mean_exec_time);
static std::unique_ptr<UlpProgram> start(gpio_num_t gpio_num, microseconds sleep_duration, CountMode rising_edge_mode, static std::unique_ptr<UlpProgram> start(const Config &config);
CountMode falling_edge_mode);
}; };
class PulseCounterUlpSensor : public sensor::Sensor, public PollingComponent { class PulseCounterUlpSensor : public sensor::Sensor, public PollingComponent {
public: public:
explicit PulseCounterUlpSensor() {} explicit PulseCounterUlpSensor() {}
void set_pin(InternalGPIOPin *pin) { pin_ = pin; } void set_pin(InternalGPIOPin *pin) { this->config_.pin_ = pin; }
void set_rising_edge_mode(CountMode mode) { this->rising_edge_mode = mode; } void set_rising_edge_mode(CountMode mode) { this->config_.rising_edge_mode_ = mode; }
void set_falling_edge_mode(CountMode mode) { this->falling_edge_mode = mode; } void set_falling_edge_mode(CountMode mode) { this->config_.falling_edge_mode_ = mode; }
void set_sleep_duration(uint32_t duration_us) { this->sleep_duration_ = duration_us * microseconds{1}; } void set_sleep_duration(uint32_t duration_us) { this->config_.sleep_duration_ = duration_us * microseconds{1}; }
void set_debounce(uint16_t debounce) { this->config_.debounce_ = debounce; }
void set_total_sensor(sensor::Sensor *total_sensor) { total_sensor_ = total_sensor; } void set_total_sensor(sensor::Sensor *total_sensor) { total_sensor_ = total_sensor; }
void set_total_pulses(uint32_t pulses); void set_total_pulses(uint32_t pulses);
@ -52,14 +59,12 @@ class PulseCounterUlpSensor : public sensor::Sensor, public PollingComponent {
void dump_config() override; void dump_config() override;
protected: protected:
InternalGPIOPin *pin_; UlpProgram::Config config_{};
CountMode rising_edge_mode{CountMode::increment}; sensor::Sensor *total_sensor_{nullptr};
CountMode falling_edge_mode{CountMode::disable};
std::unique_ptr<UlpProgram> storage_{}; std::unique_ptr<UlpProgram> storage_{};
clock::time_point last_time_{}; clock::time_point last_time_{};
microseconds sleep_duration_{20000};
uint32_t current_total_{0}; uint32_t current_total_{0};
sensor::Sensor *total_sensor_{nullptr};
}; };
} // namespace pulse_counter_ulp } // namespace pulse_counter_ulp

View file

@ -126,6 +126,7 @@ async def to_code(config):
cg.add(var.set_rising_edge_mode(count[CONF_RISING_EDGE])) cg.add(var.set_rising_edge_mode(count[CONF_RISING_EDGE]))
cg.add(var.set_falling_edge_mode(count[CONF_FALLING_EDGE])) cg.add(var.set_falling_edge_mode(count[CONF_FALLING_EDGE]))
cg.add(var.set_sleep_duration(config[CONF_SLEEP_DURATION])) cg.add(var.set_sleep_duration(config[CONF_SLEEP_DURATION]))
cg.add(var.set_debounce(config[CONF_DEBOUNCE]))
if CONF_TOTAL in config: if CONF_TOTAL in config:
sens = await sensor.new_sensor(config[CONF_TOTAL]) sens = await sensor.new_sensor(config[CONF_TOTAL])