Skip to content

Commit

Permalink
anemometer: added ESP32C3 support with fallback to interrupt based ap…
Browse files Browse the repository at this point in the history
…proach
  • Loading branch information
QB4-dev committed Feb 18, 2024
1 parent 89ddc54 commit 74d5ff8
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 44 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ or [GitLab examples](https://gitlab.com/UncleRus/esp-idf-lib/tree/master/example

| Component | Description | License | Supported on | Thread safety |
|--------------------------|----------------------------------------------------------------------------------|---------|--------------------|---------------|
| **anemometer** | Driver for impulse wind speed sensors(anemometers) | BSD-3-Clause | esp32, esp8266, esp32s2 | no |
| **anemometer** | Driver for impulse wind speed sensors(anemometers) | BSD-3-Clause | esp32, esp8266, esp32s2, esp32c3 | no |
| **ds3502** | Driver for nonvolatile digital potentiometer DS3502 | BSD-3-Clause | esp32, esp8266, esp32s2, esp32c3 | yes |
| **example** | An example component | ISC | esp32, esp8266, esp32s2, esp32c3 | n/a |
| **hd44780** | Driver for HD44780 compatible LCD text displays | BSD-3-Clause | esp32, esp8266, esp32s2, esp32c3 | no |
Expand Down
1 change: 1 addition & 0 deletions components/anemometer/.eil.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ targets:
- esp32
- esp8266
- esp32s2
- esp32c3
license: BSD-3
copyrights:
- name: qb4-dev
Expand Down
98 changes: 55 additions & 43 deletions components/anemometer/anemometer.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,22 +57,73 @@ static portMUX_TYPE mux = portMUX_INITIALIZER_UNLOCKED;
#error cannot identify the target
#endif

#if defined(HELPER_TARGET_IS_ESP32) && !defined(CONFIG_IDF_TARGET_ESP32C3) \
&& ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)

#define ESP_PCNT_SUPPORTED (1)
#else
#define ESP_PCNT_SUPPORTED (0)
#endif

#define CHECK_ARG(VAL) do { if (!(VAL)) return ESP_ERR_INVALID_ARG; } while (0)

typedef struct {
gpio_num_t input_pin; //!< GPIO input pin
float sf; //!< scale factor
int pps; //!< measured pulses count per second
esp_timer_handle_t timer; //!< periodic timer to reset pps count
#if HELPER_TARGET_IS_ESP8266
int pulse_count; //!< pulses counter
#elif HELPER_TARGET_IS_ESP32

#if ESP_PCNT_SUPPORTED
pcnt_unit_handle_t pcnt_unit; //!< hardware pulse counter
pcnt_channel_handle_t pcnt_ch; //!< hardware pulse counter channel
#else
int pulse_count; //!< pulses counter
#endif
} anemometer_priv_t;

#if HELPER_TARGET_IS_ESP8266
#if ESP_PCNT_SUPPORTED

static esp_err_t anemometer_pulse_counter_init(anemometer_priv_t *priv)
{
pcnt_unit_config_t unit_config = {
.high_limit = 2048,
.low_limit = -1
};

pcnt_chan_config_t ch_config = {
.edge_gpio_num = priv->input_pin,
.level_gpio_num = -1
};

ESP_ERROR_CHECK(pcnt_new_unit(&unit_config,&priv->pcnt_unit));
ESP_ERROR_CHECK(pcnt_new_channel(priv->pcnt_unit,&ch_config,&priv->pcnt_ch));
ESP_ERROR_CHECK(pcnt_channel_set_edge_action(priv->pcnt_ch,
PCNT_CHANNEL_EDGE_ACTION_INCREASE,PCNT_CHANNEL_EDGE_ACTION_HOLD));
ESP_ERROR_CHECK(pcnt_unit_enable(priv->pcnt_unit));
ESP_ERROR_CHECK(pcnt_unit_clear_count(priv->pcnt_unit));
ESP_ERROR_CHECK(pcnt_unit_start(priv->pcnt_unit));
return ESP_OK;
}

static esp_err_t anemometer_pulse_counter_deinit(anemometer_priv_t *priv)
{
ESP_ERROR_CHECK(pcnt_unit_stop(priv->pcnt_unit));
ESP_ERROR_CHECK(pcnt_unit_disable(priv->pcnt_unit));
ESP_ERROR_CHECK(pcnt_del_channel(priv->pcnt_ch));
ESP_ERROR_CHECK(pcnt_del_unit(priv->pcnt_unit));
return ESP_OK;
}

static void timer_event_callback(void *arg)
{
anemometer_priv_t *priv = (anemometer_priv_t *)arg;

pcnt_unit_get_count(priv->pcnt_unit,&priv->pps);
pcnt_unit_clear_count(priv->pcnt_unit);
}

#else

static void IRAM_ATTR gpio_isr_handler(void* arg)
{
anemometer_priv_t *priv = (anemometer_priv_t *)arg;
Expand Down Expand Up @@ -114,45 +165,6 @@ static void timer_event_callback(void *arg)
PORT_EXIT_CRITICAL();
}

#elif HELPER_TARGET_IS_ESP32
static esp_err_t anemometer_pulse_counter_init(anemometer_priv_t *priv)
{
pcnt_unit_config_t unit_config = {
.high_limit = 2048,
.low_limit = -1
};

pcnt_chan_config_t ch_config = {
.edge_gpio_num = priv->input_pin,
.level_gpio_num = -1
};

ESP_ERROR_CHECK(pcnt_new_unit(&unit_config,&priv->pcnt_unit));
ESP_ERROR_CHECK(pcnt_new_channel(priv->pcnt_unit,&ch_config,&priv->pcnt_ch));
ESP_ERROR_CHECK(pcnt_channel_set_edge_action(priv->pcnt_ch,
PCNT_CHANNEL_EDGE_ACTION_INCREASE,PCNT_CHANNEL_EDGE_ACTION_HOLD));
ESP_ERROR_CHECK(pcnt_unit_enable(priv->pcnt_unit));
ESP_ERROR_CHECK(pcnt_unit_clear_count(priv->pcnt_unit));
ESP_ERROR_CHECK(pcnt_unit_start(priv->pcnt_unit));
return ESP_OK;
}

static esp_err_t anemometer_pulse_counter_deinit(anemometer_priv_t *priv)
{
ESP_ERROR_CHECK(pcnt_unit_stop(priv->pcnt_unit));
ESP_ERROR_CHECK(pcnt_unit_disable(priv->pcnt_unit));
ESP_ERROR_CHECK(pcnt_del_channel(priv->pcnt_ch));
ESP_ERROR_CHECK(pcnt_del_unit(priv->pcnt_unit));
return ESP_OK;
}

static void timer_event_callback(void *arg)
{
anemometer_priv_t *priv = (anemometer_priv_t *)arg;

pcnt_unit_get_count(priv->pcnt_unit,&priv->pps);
pcnt_unit_clear_count(priv->pcnt_unit);
}
#endif

static esp_err_t anemometer_timer_setup(anemometer_priv_t *priv)
Expand Down

0 comments on commit 74d5ff8

Please sign in to comment.