mirror of
https://github.com/esphome/esphome.git
synced 2024-11-23 23:48:11 +01:00
pulse_counter: Replace storage enum with dependency injection
This substantially reduces the need for #ifdefs to handle conditional dependency on the ULP system
This commit is contained in:
parent
fe533952cc
commit
bb0ed5b855
3 changed files with 27 additions and 36 deletions
|
@ -14,26 +14,6 @@ static const char *const TAG = "pulse_counter";
|
||||||
|
|
||||||
const char *const EDGE_MODE_TO_STRING[] = {"DISABLE", "INCREMENT", "DECREMENT"};
|
const char *const EDGE_MODE_TO_STRING[] = {"DISABLE", "INCREMENT", "DECREMENT"};
|
||||||
|
|
||||||
#ifdef HAS_PCNT
|
|
||||||
PulseCounterStorageBase *get_storage(Storage storage) {
|
|
||||||
switch (storage) {
|
|
||||||
case Storage::basic:
|
|
||||||
return new BasicPulseCounterStorage;
|
|
||||||
case Storage::pcnt:
|
|
||||||
return new HwPulseCounterStorage;
|
|
||||||
#ifdef CONF_USE_ULP
|
|
||||||
case Storage::ulp:
|
|
||||||
return new UlpPulseCounterStorage;
|
|
||||||
#endif
|
|
||||||
default:
|
|
||||||
return new BasicPulseCounterStorage;
|
|
||||||
}
|
|
||||||
return new BasicPulseCounterStorage;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
PulseCounterStorageBase *get_storage(Storage) { return new BasicPulseCounterStorage; }
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void IRAM_ATTR BasicPulseCounterStorage::gpio_intr(BasicPulseCounterStorage *arg) {
|
void IRAM_ATTR BasicPulseCounterStorage::gpio_intr(BasicPulseCounterStorage *arg) {
|
||||||
const uint32_t now = micros();
|
const uint32_t now = micros();
|
||||||
const bool discard = now - arg->last_pulse < arg->filter_us;
|
const bool discard = now - arg->last_pulse < arg->filter_us;
|
||||||
|
@ -203,9 +183,11 @@ bool UlpPulseCounterStorage::pulse_counter_setup(InternalGPIOPin *pin) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* GPIO used for pulse counting. */
|
/* GPIO used for pulse counting. */
|
||||||
gpio_num_t gpio_num = GPIO_NUM_0;
|
gpio_num_t gpio_num = static_cast<gpio_num_t>(pin->get_pin());
|
||||||
int rtcio_num = rtc_io_number_get(gpio_num);
|
int rtcio_num = rtc_io_number_get(gpio_num);
|
||||||
assert(rtc_gpio_is_valid_gpio(gpio_num) && "GPIO used for pulse counting must be an RTC IO");
|
if (!rtc_gpio_is_valid_gpio(gpio_num)) {
|
||||||
|
ESP_LOGE(TAG, "GPIO used for pulse counting must be an RTC IO");
|
||||||
|
}
|
||||||
|
|
||||||
/* Initialize some variables used by ULP program.
|
/* Initialize some variables used by ULP program.
|
||||||
* Each 'ulp_xyz' variable corresponds to 'xyz' variable in the ULP program.
|
* Each 'ulp_xyz' variable corresponds to 'xyz' variable in the ULP program.
|
||||||
|
@ -222,11 +204,9 @@ bool UlpPulseCounterStorage::pulse_counter_setup(InternalGPIOPin *pin) {
|
||||||
ulp_io_number = rtcio_num; /* map from GPIO# to RTC_IO# */
|
ulp_io_number = rtcio_num; /* map from GPIO# to RTC_IO# */
|
||||||
ulp_edge_count_to_wake_up = 10;
|
ulp_edge_count_to_wake_up = 10;
|
||||||
|
|
||||||
/* Initialize selected GPIO as RTC IO, enable input, disable pullup and pulldown */
|
/* Initialize selected GPIO as RTC IO, enable input */
|
||||||
rtc_gpio_init(gpio_num);
|
rtc_gpio_init(gpio_num);
|
||||||
rtc_gpio_set_direction(gpio_num, RTC_GPIO_MODE_INPUT_ONLY);
|
rtc_gpio_set_direction(gpio_num, RTC_GPIO_MODE_INPUT_ONLY);
|
||||||
rtc_gpio_pulldown_dis(gpio_num);
|
|
||||||
rtc_gpio_pullup_dis(gpio_num);
|
|
||||||
rtc_gpio_hold_en(gpio_num);
|
rtc_gpio_hold_en(gpio_num);
|
||||||
|
|
||||||
/* Set ULP wake up period to T = 20ms.
|
/* Set ULP wake up period to T = 20ms.
|
||||||
|
|
|
@ -20,8 +20,6 @@ enum PulseCounterCountMode {
|
||||||
PULSE_COUNTER_DECREMENT,
|
PULSE_COUNTER_DECREMENT,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class Storage { basic, pcnt, ulp };
|
|
||||||
|
|
||||||
#ifdef HAS_PCNT
|
#ifdef HAS_PCNT
|
||||||
using pulse_counter_t = int16_t;
|
using pulse_counter_t = int16_t;
|
||||||
#else
|
#else
|
||||||
|
@ -65,12 +63,9 @@ struct UlpPulseCounterStorage : public PulseCounterStorageBase {
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
PulseCounterStorageBase *get_storage(Storage storage = Storage::basic);
|
|
||||||
|
|
||||||
class PulseCounterSensor : public sensor::Sensor, public PollingComponent {
|
class PulseCounterSensor : public sensor::Sensor, public PollingComponent {
|
||||||
public:
|
public:
|
||||||
explicit PulseCounterSensor(Storage storage = Storage::basic) : storage_(*get_storage(storage)) {}
|
explicit PulseCounterSensor(PulseCounterStorageBase *storage) : storage_(*storage) {}
|
||||||
PulseCounterSensor(int storage = 0) : PulseCounterSensor(Storage(storage)) {}
|
|
||||||
|
|
||||||
void set_pin(InternalGPIOPin *pin) { pin_ = pin; }
|
void set_pin(InternalGPIOPin *pin) { pin_ = pin; }
|
||||||
void set_rising_edge_mode(PulseCounterCountMode mode) { storage_.rising_edge_mode = mode; }
|
void set_rising_edge_mode(PulseCounterCountMode mode) { storage_.rising_edge_mode = mode; }
|
||||||
|
|
|
@ -24,6 +24,7 @@ from esphome.core import CORE
|
||||||
|
|
||||||
CONF_USE_PCNT = "use_pcnt"
|
CONF_USE_PCNT = "use_pcnt"
|
||||||
CONF_USE_ULP = "use_ulp"
|
CONF_USE_ULP = "use_ulp"
|
||||||
|
CONF_STORAGE_ID = "storage"
|
||||||
|
|
||||||
pulse_counter_ns = cg.esphome_ns.namespace("pulse_counter")
|
pulse_counter_ns = cg.esphome_ns.namespace("pulse_counter")
|
||||||
PulseCounterCountMode = pulse_counter_ns.enum("PulseCounterCountMode")
|
PulseCounterCountMode = pulse_counter_ns.enum("PulseCounterCountMode")
|
||||||
|
@ -121,6 +122,9 @@ CONFIG_SCHEMA = cv.All(
|
||||||
accuracy_decimals=0,
|
accuracy_decimals=0,
|
||||||
state_class=STATE_CLASS_TOTAL_INCREASING,
|
state_class=STATE_CLASS_TOTAL_INCREASING,
|
||||||
),
|
),
|
||||||
|
cv.GenerateID(CONF_STORAGE_ID): cv.declare_id(
|
||||||
|
"pulse_counter::PulseCounterStorageBase"
|
||||||
|
),
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.extend(cv.polling_component_schema("60s")),
|
.extend(cv.polling_component_schema("60s")),
|
||||||
|
@ -130,15 +134,16 @@ CONFIG_SCHEMA = cv.All(
|
||||||
|
|
||||||
async def to_code(config):
|
async def to_code(config):
|
||||||
if config.get(CONF_USE_ULP):
|
if config.get(CONF_USE_ULP):
|
||||||
var = await sensor.new_sensor(config, 2)
|
cg.add_define("CONF_USE_ULP", True)
|
||||||
else:
|
storage = cg.Pvariable(
|
||||||
var = await sensor.new_sensor(config, config.get(CONF_USE_PCNT))
|
config[CONF_STORAGE_ID],
|
||||||
if config.get(CONF_USE_ULP):
|
cg.RawExpression("new pulse_counter::UlpPulseCounterStorage()"),
|
||||||
var.add_define("CONF_USE_ULP", True)
|
)
|
||||||
esp32.add_extra_build_file(
|
esp32.add_extra_build_file(
|
||||||
"src/CMakeLists.txt",
|
"src/CMakeLists.txt",
|
||||||
os.path.join(os.path.dirname(__file__), "CMakeLists.txt"),
|
os.path.join(os.path.dirname(__file__), "CMakeLists.txt"),
|
||||||
)
|
)
|
||||||
|
# FIXME These files don't get cleared when the config changes, necessitating deleting .esphome
|
||||||
esp32.add_extra_build_file(
|
esp32.add_extra_build_file(
|
||||||
"ulp/pulse_cnt.S",
|
"ulp/pulse_cnt.S",
|
||||||
os.path.join(os.path.dirname(__file__), "ulp/pulse_cnt.S"),
|
os.path.join(os.path.dirname(__file__), "ulp/pulse_cnt.S"),
|
||||||
|
@ -149,6 +154,17 @@ async def to_code(config):
|
||||||
esp32.add_idf_sdkconfig_option("CONFIG_ULP_COPROC_ENABLED", True)
|
esp32.add_idf_sdkconfig_option("CONFIG_ULP_COPROC_ENABLED", True)
|
||||||
esp32.add_idf_sdkconfig_option("CONFIG_ULP_COPROC_TYPE_FSM", True)
|
esp32.add_idf_sdkconfig_option("CONFIG_ULP_COPROC_TYPE_FSM", True)
|
||||||
esp32.add_idf_sdkconfig_option("CONFIG_ULP_COPROC_RESERVE_MEM", 1024)
|
esp32.add_idf_sdkconfig_option("CONFIG_ULP_COPROC_RESERVE_MEM", 1024)
|
||||||
|
elif config.get(CONF_USE_PCNT):
|
||||||
|
storage = cg.Pvariable(
|
||||||
|
config[CONF_STORAGE_ID],
|
||||||
|
cg.RawExpression("new pulse_counter::HwPulseCounterStorage()"),
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
storage = cg.Pvariable(
|
||||||
|
config[CONF_STORAGE_ID],
|
||||||
|
cg.RawExpression("new pulse_counter::BasicPulseCounterStorage()"),
|
||||||
|
)
|
||||||
|
var = await sensor.new_sensor(config, storage)
|
||||||
await cg.register_component(var, config)
|
await cg.register_component(var, config)
|
||||||
|
|
||||||
pin = await cg.gpio_pin_expression(config[CONF_PIN])
|
pin = await cg.gpio_pin_expression(config[CONF_PIN])
|
||||||
|
|
Loading…
Reference in a new issue