/ components / driver / pcnt.c
pcnt.c
  1  // Copyright 2015-2020 Espressif Systems (Shanghai) PTE LTD
  2  //
  3  // Licensed under the Apache License, Version 2.0 (the "License");
  4  // you may not use this file except in compliance with the License.
  5  // You may obtain a copy of the License at
  6  //
  7  //     http://www.apache.org/licenses/LICENSE-2.0
  8  //
  9  // Unless required by applicable law or agreed to in writing, software
 10  // distributed under the License is distributed on an "AS IS" BASIS,
 11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 12  // See the License for the specific language governing permissions and
 13  // limitations under the License.
 14  
 15  #include "freertos/FreeRTOS.h"
 16  #include "freertos/semphr.h"
 17  #include "esp_log.h"
 18  #include "soc/soc_caps.h"
 19  #if SOC_PCNT_SUPPORTED
 20  #include "driver/periph_ctrl.h"
 21  #include "driver/pcnt.h"
 22  #include "hal/pcnt_hal.h"
 23  #include "esp_rom_gpio.h"
 24  
 25  #define PCNT_CHANNEL_ERR_STR  "PCNT CHANNEL ERROR"
 26  #define PCNT_UNIT_ERR_STR  "PCNT UNIT ERROR"
 27  #define PCNT_GPIO_ERR_STR  "PCNT GPIO NUM ERROR"
 28  #define PCNT_ADDRESS_ERR_STR  "PCNT ADDRESS ERROR"
 29  #define PCNT_PARAM_ERR_STR   "PCNT PARAM ERROR"
 30  #define PCNT_COUNT_MODE_ERR_STR "PCNT COUNTER MODE ERROR"
 31  #define PCNT_CTRL_MODE_ERR_STR  "PCNT CTRL MODE ERROR"
 32  #define PCNT_EVT_TYPE_ERR_STR   "PCNT value type error"
 33  #define PCNT_LIMT_VAL_ERR_STR   "PCNT limit value error"
 34  #define PCNT_NUM_ERR_STR   "PCNT num error"
 35  #define PCNT_DRIVER_ERR_STR  "PCNT driver error"
 36  
 37  #define PCNT_ENTER_CRITICAL(mux)    portENTER_CRITICAL(mux)
 38  #define PCNT_EXIT_CRITICAL(mux)     portEXIT_CRITICAL(mux)
 39  
 40  static const char *TAG = "pcnt";
 41  
 42  #define PCNT_CHECK(a, str, ret_val) \
 43      if (!(a)) { \
 44          ESP_LOGE(TAG,"%s(%d): %s", __FUNCTION__, __LINE__, str); \
 45          return (ret_val); \
 46      }
 47  
 48  typedef struct {
 49      pcnt_hal_context_t hal;        /*!< PCNT hal context*/
 50  } pcnt_obj_t;
 51  
 52  static pcnt_obj_t *p_pcnt_obj[PCNT_PORT_MAX] = {0};
 53  
 54  #define PCNT_OBJ_CHECK(pcnt_port) { \
 55      PCNT_CHECK((pcnt_port < PCNT_PORT_MAX), PCNT_NUM_ERR_STR, ESP_ERR_INVALID_ARG); \
 56      PCNT_CHECK((p_pcnt_obj[pcnt_port]), PCNT_DRIVER_ERR_STR, ESP_ERR_INVALID_STATE); \
 57  }
 58  
 59  typedef struct {
 60      void(*fn)(void *args);   /*!< isr function */
 61      void *args;              /*!< isr function args */
 62  } pcnt_isr_func_t;
 63  
 64  static pcnt_isr_func_t *pcnt_isr_func = NULL;
 65  static pcnt_isr_handle_t pcnt_isr_service = NULL;
 66  static portMUX_TYPE pcnt_spinlock = portMUX_INITIALIZER_UNLOCKED;
 67  
 68  static inline esp_err_t _pcnt_set_mode(pcnt_port_t pcnt_port, pcnt_unit_t unit, pcnt_channel_t channel, pcnt_count_mode_t pos_mode, pcnt_count_mode_t neg_mode, pcnt_ctrl_mode_t hctrl_mode, pcnt_ctrl_mode_t lctrl_mode)
 69  {
 70      PCNT_OBJ_CHECK(pcnt_port);
 71      PCNT_CHECK(unit < PCNT_UNIT_MAX, PCNT_UNIT_ERR_STR, ESP_ERR_INVALID_ARG);
 72      PCNT_CHECK(channel < PCNT_CHANNEL_MAX, PCNT_CHANNEL_ERR_STR, ESP_ERR_INVALID_ARG);
 73      PCNT_CHECK((pos_mode < PCNT_COUNT_MAX) && (neg_mode < PCNT_COUNT_MAX), PCNT_COUNT_MODE_ERR_STR, ESP_ERR_INVALID_ARG);
 74      PCNT_CHECK((hctrl_mode < PCNT_MODE_MAX) && (lctrl_mode < PCNT_MODE_MAX), PCNT_CTRL_MODE_ERR_STR, ESP_ERR_INVALID_ARG);
 75  
 76      pcnt_hal_set_mode(&(p_pcnt_obj[pcnt_port]->hal), unit, channel, pos_mode, neg_mode, hctrl_mode, lctrl_mode);
 77      return ESP_OK;
 78  }
 79  
 80  static inline esp_err_t _pcnt_set_pin(pcnt_port_t pcnt_port, pcnt_unit_t unit, pcnt_channel_t channel, int pulse_io, int ctrl_io)
 81  {
 82      PCNT_OBJ_CHECK(pcnt_port);
 83      PCNT_CHECK(unit < PCNT_UNIT_MAX, PCNT_UNIT_ERR_STR, ESP_ERR_INVALID_ARG);
 84      PCNT_CHECK(channel < PCNT_CHANNEL_MAX, PCNT_CHANNEL_ERR_STR, ESP_ERR_INVALID_ARG);
 85      PCNT_CHECK(GPIO_IS_VALID_GPIO(pulse_io) || pulse_io < 0, PCNT_GPIO_ERR_STR, ESP_ERR_INVALID_ARG);
 86      PCNT_CHECK(GPIO_IS_VALID_GPIO(ctrl_io) || ctrl_io < 0, PCNT_GPIO_ERR_STR, ESP_ERR_INVALID_ARG);
 87  
 88      if (pulse_io >= 0) {
 89          PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[pulse_io], PIN_FUNC_GPIO);
 90          gpio_set_direction(pulse_io, GPIO_MODE_INPUT);
 91          gpio_set_pull_mode(pulse_io, GPIO_PULLUP_ONLY);
 92          esp_rom_gpio_connect_in_signal(pulse_io, pcnt_periph_signals.units[unit].channels[channel].pulse_sig, 0);
 93      }
 94  
 95      if (ctrl_io >= 0) {
 96          PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[ctrl_io], PIN_FUNC_GPIO);
 97          gpio_set_direction(ctrl_io, GPIO_MODE_INPUT);
 98          gpio_set_pull_mode(ctrl_io, GPIO_PULLUP_ONLY);
 99          esp_rom_gpio_connect_in_signal(ctrl_io, pcnt_periph_signals.units[unit].channels[channel].control_sig, 0);
100      }
101  
102      return ESP_OK;
103  }
104  
105  static inline esp_err_t _pcnt_get_counter_value(pcnt_port_t pcnt_port, pcnt_unit_t pcnt_unit, int16_t *count)
106  {
107      PCNT_OBJ_CHECK(pcnt_port);
108      PCNT_CHECK(pcnt_unit < PCNT_UNIT_MAX, PCNT_UNIT_ERR_STR, ESP_ERR_INVALID_ARG);
109      PCNT_CHECK(count != NULL, PCNT_ADDRESS_ERR_STR, ESP_ERR_INVALID_ARG);
110      pcnt_hal_get_counter_value(&(p_pcnt_obj[pcnt_port]->hal), pcnt_unit, count);
111      return ESP_OK;
112  }
113  
114  static inline esp_err_t _pcnt_counter_pause(pcnt_port_t pcnt_port, pcnt_unit_t pcnt_unit)
115  {
116      PCNT_OBJ_CHECK(pcnt_port);
117      PCNT_CHECK(pcnt_unit < PCNT_UNIT_MAX, PCNT_UNIT_ERR_STR, ESP_ERR_INVALID_ARG);
118      PCNT_ENTER_CRITICAL(&pcnt_spinlock);
119      pcnt_hal_counter_pause(&(p_pcnt_obj[pcnt_port]->hal), pcnt_unit);
120      PCNT_EXIT_CRITICAL(&pcnt_spinlock);
121      return ESP_OK;
122  }
123  
124  static inline esp_err_t _pcnt_counter_resume(pcnt_port_t pcnt_port, pcnt_unit_t pcnt_unit)
125  {
126      PCNT_OBJ_CHECK(pcnt_port);
127      PCNT_CHECK(pcnt_unit < PCNT_UNIT_MAX, PCNT_UNIT_ERR_STR, ESP_ERR_INVALID_ARG);
128      PCNT_ENTER_CRITICAL(&pcnt_spinlock);
129      pcnt_hal_counter_resume(&(p_pcnt_obj[pcnt_port]->hal), pcnt_unit);
130      PCNT_EXIT_CRITICAL(&pcnt_spinlock);
131      return ESP_OK;
132  }
133  
134  static inline esp_err_t _pcnt_counter_clear(pcnt_port_t pcnt_port, pcnt_unit_t pcnt_unit)
135  {
136      PCNT_OBJ_CHECK(pcnt_port);
137      PCNT_CHECK(pcnt_unit < PCNT_UNIT_MAX, PCNT_UNIT_ERR_STR, ESP_ERR_INVALID_ARG);
138      PCNT_ENTER_CRITICAL(&pcnt_spinlock);
139      pcnt_hal_counter_clear(&(p_pcnt_obj[pcnt_port]->hal), pcnt_unit);
140      PCNT_EXIT_CRITICAL(&pcnt_spinlock);
141      return ESP_OK;
142  }
143  
144  static inline esp_err_t _pcnt_intr_enable(pcnt_port_t pcnt_port, pcnt_unit_t pcnt_unit)
145  {
146      PCNT_OBJ_CHECK(pcnt_port);
147      PCNT_CHECK(pcnt_unit < PCNT_UNIT_MAX, PCNT_UNIT_ERR_STR, ESP_ERR_INVALID_ARG);
148      PCNT_ENTER_CRITICAL(&pcnt_spinlock);
149      pcnt_hal_intr_enable(&(p_pcnt_obj[pcnt_port]->hal), pcnt_unit);
150      PCNT_EXIT_CRITICAL(&pcnt_spinlock);
151      return ESP_OK;
152  }
153  
154  static inline esp_err_t _pcnt_intr_disable(pcnt_port_t pcnt_port, pcnt_unit_t pcnt_unit)
155  {
156      PCNT_OBJ_CHECK(pcnt_port);
157      PCNT_CHECK(pcnt_unit < PCNT_UNIT_MAX, PCNT_UNIT_ERR_STR, ESP_ERR_INVALID_ARG);
158      PCNT_ENTER_CRITICAL(&pcnt_spinlock);
159      pcnt_hal_intr_disable(&(p_pcnt_obj[pcnt_port]->hal), pcnt_unit);
160      PCNT_EXIT_CRITICAL(&pcnt_spinlock);
161      return ESP_OK;
162  }
163  
164  static inline esp_err_t _pcnt_event_enable(pcnt_port_t pcnt_port, pcnt_unit_t unit, pcnt_evt_type_t evt_type)
165  {
166      PCNT_OBJ_CHECK(pcnt_port);
167      PCNT_CHECK(unit < PCNT_UNIT_MAX, PCNT_UNIT_ERR_STR, ESP_ERR_INVALID_ARG);
168      PCNT_CHECK(evt_type < PCNT_EVT_MAX, PCNT_EVT_TYPE_ERR_STR, ESP_ERR_INVALID_ARG);
169      pcnt_hal_event_enable(&(p_pcnt_obj[pcnt_port]->hal), unit, evt_type);
170      return ESP_OK;
171  }
172  
173  static inline esp_err_t _pcnt_event_disable(pcnt_port_t pcnt_port, pcnt_unit_t unit, pcnt_evt_type_t evt_type)
174  {
175      PCNT_OBJ_CHECK(pcnt_port);
176      PCNT_CHECK(unit < PCNT_UNIT_MAX, PCNT_UNIT_ERR_STR, ESP_ERR_INVALID_ARG);
177      PCNT_CHECK(evt_type < PCNT_EVT_MAX, PCNT_EVT_TYPE_ERR_STR, ESP_ERR_INVALID_ARG);
178      pcnt_hal_event_disable(&(p_pcnt_obj[pcnt_port]->hal), unit, evt_type);
179      return ESP_OK;
180  }
181  
182  static inline esp_err_t _pcnt_set_event_value(pcnt_port_t pcnt_port, pcnt_unit_t unit, pcnt_evt_type_t evt_type, int16_t value)
183  {
184      PCNT_OBJ_CHECK(pcnt_port);
185      PCNT_CHECK(unit < PCNT_UNIT_MAX, PCNT_UNIT_ERR_STR, ESP_ERR_INVALID_ARG);
186      PCNT_CHECK(evt_type < PCNT_EVT_MAX, PCNT_EVT_TYPE_ERR_STR, ESP_ERR_INVALID_ARG);
187      PCNT_CHECK(!(evt_type == PCNT_EVT_L_LIM && value > 0), PCNT_LIMT_VAL_ERR_STR, ESP_ERR_INVALID_ARG);
188      PCNT_CHECK(!(evt_type == PCNT_EVT_H_LIM && value < 0), PCNT_LIMT_VAL_ERR_STR, ESP_ERR_INVALID_ARG);
189      pcnt_hal_set_event_value(&(p_pcnt_obj[pcnt_port]->hal), unit, evt_type, value);
190      return ESP_OK;
191  }
192  
193  static inline esp_err_t _pcnt_get_event_value(pcnt_port_t pcnt_port, pcnt_unit_t unit, pcnt_evt_type_t evt_type, int16_t *value)
194  {
195      PCNT_OBJ_CHECK(pcnt_port);
196      PCNT_CHECK(unit < PCNT_UNIT_MAX, PCNT_UNIT_ERR_STR, ESP_ERR_INVALID_ARG);
197      PCNT_CHECK(evt_type < PCNT_EVT_MAX, PCNT_EVT_TYPE_ERR_STR, ESP_ERR_INVALID_ARG);
198      PCNT_CHECK(value != NULL, PCNT_ADDRESS_ERR_STR, ESP_ERR_INVALID_ARG);
199  
200      pcnt_hal_get_event_value(&(p_pcnt_obj[pcnt_port]->hal), unit, evt_type, value);
201      return ESP_OK;
202  }
203  
204  static inline esp_err_t _pcnt_get_event_status(pcnt_port_t pcnt_port, pcnt_unit_t unit, uint32_t *status)
205  {
206      PCNT_OBJ_CHECK(pcnt_port);
207      PCNT_CHECK(unit < PCNT_UNIT_MAX, PCNT_UNIT_ERR_STR, ESP_ERR_INVALID_ARG);
208      PCNT_CHECK(status != NULL, PCNT_ADDRESS_ERR_STR, ESP_ERR_INVALID_ARG);
209  
210      *status = pcnt_hal_get_event_status(&(p_pcnt_obj[pcnt_port]->hal), unit);
211      return ESP_OK;
212  }
213  
214  static inline esp_err_t _pcnt_set_filter_value(pcnt_port_t pcnt_port, pcnt_unit_t unit, uint16_t filter_val)
215  {
216      PCNT_OBJ_CHECK(pcnt_port);
217      PCNT_CHECK(unit < PCNT_UNIT_MAX, PCNT_UNIT_ERR_STR, ESP_ERR_INVALID_ARG);
218      PCNT_CHECK(filter_val < 1024, PCNT_PARAM_ERR_STR, ESP_ERR_INVALID_ARG);
219      pcnt_hal_set_filter_value(&(p_pcnt_obj[pcnt_port]->hal), unit, filter_val);
220      return ESP_OK;
221  }
222  
223  static inline esp_err_t _pcnt_get_filter_value(pcnt_port_t pcnt_port, pcnt_unit_t unit, uint16_t *filter_val)
224  {
225      PCNT_OBJ_CHECK(pcnt_port);
226      PCNT_CHECK(unit < PCNT_UNIT_MAX, PCNT_UNIT_ERR_STR, ESP_ERR_INVALID_ARG);
227      PCNT_CHECK(filter_val != NULL, PCNT_ADDRESS_ERR_STR, ESP_ERR_INVALID_ARG);
228  
229      pcnt_hal_get_filter_value(&(p_pcnt_obj[pcnt_port]->hal), unit, filter_val);
230      return ESP_OK;
231  }
232  
233  static inline esp_err_t _pcnt_filter_enable(pcnt_port_t pcnt_port, pcnt_unit_t unit)
234  {
235      PCNT_OBJ_CHECK(pcnt_port);
236      PCNT_CHECK(unit < PCNT_UNIT_MAX, PCNT_UNIT_ERR_STR, ESP_ERR_INVALID_ARG);
237      pcnt_hal_filter_enable(&(p_pcnt_obj[pcnt_port]->hal), unit);
238      return ESP_OK;
239  }
240  
241  static inline esp_err_t _pcnt_filter_disable(pcnt_port_t pcnt_port, pcnt_unit_t unit)
242  {
243      PCNT_OBJ_CHECK(pcnt_port);
244      PCNT_CHECK(unit < PCNT_UNIT_MAX, PCNT_UNIT_ERR_STR, ESP_ERR_INVALID_ARG);
245      pcnt_hal_filter_disable(&(p_pcnt_obj[pcnt_port]->hal), unit);
246      return ESP_OK;
247  }
248  
249  static inline esp_err_t _pcnt_isr_handler_add(pcnt_port_t pcnt_port, pcnt_unit_t unit, void(*isr_handler)(void *), void *args)
250  {
251      PCNT_OBJ_CHECK(pcnt_port);
252      PCNT_CHECK(pcnt_isr_func != NULL, "ISR service is not installed, call pcnt_install_isr_service() first", ESP_ERR_INVALID_STATE);
253      PCNT_CHECK(unit < PCNT_UNIT_MAX, "PCNT unit error", ESP_ERR_INVALID_ARG);
254      PCNT_ENTER_CRITICAL(&pcnt_spinlock);
255      _pcnt_intr_disable(PCNT_PORT_0, unit);
256  
257      if (pcnt_isr_func) {
258          pcnt_isr_func[unit].fn = isr_handler;
259          pcnt_isr_func[unit].args = args;
260      }
261  
262      _pcnt_intr_enable(PCNT_PORT_0, unit);
263      PCNT_EXIT_CRITICAL(&pcnt_spinlock);
264      return ESP_OK;
265  }
266  
267  static inline esp_err_t _pcnt_isr_handler_remove(pcnt_port_t pcnt_port, pcnt_unit_t unit)
268  {
269      PCNT_OBJ_CHECK(pcnt_port);
270      PCNT_CHECK(pcnt_isr_func != NULL, "ISR service is not installed", ESP_ERR_INVALID_STATE);
271      PCNT_CHECK(unit < PCNT_UNIT_MAX, "PCNT unit error", ESP_ERR_INVALID_ARG);
272      PCNT_ENTER_CRITICAL(&pcnt_spinlock);
273      _pcnt_intr_disable(PCNT_PORT_0, unit);
274  
275      if (pcnt_isr_func) {
276          pcnt_isr_func[unit].fn = NULL;
277          pcnt_isr_func[unit].args = NULL;
278      }
279  
280      PCNT_EXIT_CRITICAL(&pcnt_spinlock);
281      return ESP_OK;
282  }
283  
284  // pcnt interrupt service
285  static void IRAM_ATTR pcnt_intr_service(void *arg)
286  {
287      uint32_t status = 0;
288      pcnt_port_t pcnt_port = (pcnt_port_t)arg;
289      pcnt_hal_get_intr_status(&(p_pcnt_obj[pcnt_port]->hal), &status);
290      pcnt_hal_clear_intr_status(&(p_pcnt_obj[pcnt_port]->hal), status);
291  
292      while (status) {
293          int unit = __builtin_ffs(status) - 1;
294          status &= ~(1 << unit);
295  
296          if (pcnt_isr_func[unit].fn != NULL) {
297              (pcnt_isr_func[unit].fn)(pcnt_isr_func[unit].args);
298          }
299      }
300  }
301  
302  static inline esp_err_t _pcnt_isr_service_install(pcnt_port_t pcnt_port, int intr_alloc_flags)
303  {
304      PCNT_OBJ_CHECK(pcnt_port);
305      PCNT_CHECK(pcnt_isr_func == NULL, "ISR service already installed", ESP_ERR_INVALID_STATE);
306      esp_err_t ret = ESP_FAIL;
307      pcnt_isr_func = (pcnt_isr_func_t *) calloc(PCNT_UNIT_MAX, sizeof(pcnt_isr_func_t));
308  
309      if (pcnt_isr_func == NULL) {
310          ret = ESP_ERR_NO_MEM;
311      } else {
312          ret = pcnt_isr_register(pcnt_intr_service, (void *)pcnt_port, intr_alloc_flags, &pcnt_isr_service);
313          if (ret != ESP_OK) {
314              ESP_LOGE(TAG, "pcnt isr registration failed, maybe you need `pcnt_isr_unregister` to unregister your isr");
315              free(pcnt_isr_func);
316              pcnt_isr_func = NULL;
317          }
318      }
319  
320      return ret;
321  }
322  
323  static inline esp_err_t _pcnt_isr_service_uninstall(pcnt_port_t pcnt_port)
324  {
325      PCNT_OBJ_CHECK(pcnt_port);
326      PCNT_CHECK(pcnt_isr_func != NULL, "ISR Service not installed yet.", ESP_ERR_INVALID_STATE);
327      esp_err_t ret = ESP_FAIL;
328      ret = pcnt_isr_unregister(pcnt_isr_service);
329      free(pcnt_isr_func);
330      pcnt_isr_func = NULL;
331      pcnt_isr_service = NULL;
332  
333      return ret;
334  }
335  
336  static inline esp_err_t _pcnt_unit_config(pcnt_port_t pcnt_port, const pcnt_config_t *pcnt_config)
337  {
338      PCNT_OBJ_CHECK(pcnt_port);
339      uint8_t unit = pcnt_config->unit;
340      uint8_t channel = pcnt_config->channel;
341      int input_io = pcnt_config->pulse_gpio_num;
342      int ctrl_io = pcnt_config->ctrl_gpio_num;
343  
344      PCNT_CHECK(unit < PCNT_UNIT_MAX, PCNT_UNIT_ERR_STR, ESP_ERR_INVALID_ARG);
345      PCNT_CHECK(channel < PCNT_CHANNEL_MAX, PCNT_CHANNEL_ERR_STR, ESP_ERR_INVALID_ARG);
346      PCNT_CHECK(input_io < 0 || (GPIO_IS_VALID_GPIO(input_io) && (input_io != ctrl_io)), "PCNT pulse input io error", ESP_ERR_INVALID_ARG);
347      PCNT_CHECK(ctrl_io < 0 || GPIO_IS_VALID_GPIO(ctrl_io), "PCNT ctrl io error", ESP_ERR_INVALID_ARG);
348      PCNT_CHECK((pcnt_config->pos_mode < PCNT_COUNT_MAX) && (pcnt_config->neg_mode < PCNT_COUNT_MAX), PCNT_COUNT_MODE_ERR_STR, ESP_ERR_INVALID_ARG);
349      PCNT_CHECK((pcnt_config->hctrl_mode < PCNT_MODE_MAX) && (pcnt_config->lctrl_mode < PCNT_MODE_MAX), PCNT_CTRL_MODE_ERR_STR, ESP_ERR_INVALID_ARG);
350      /*Enalbe hardware module*/
351      static bool pcnt_enable = false;
352      if (pcnt_enable == false) {
353          periph_module_reset(pcnt_periph_signals.module);
354          pcnt_enable = true;
355      }
356      periph_module_enable(pcnt_periph_signals.module);
357      /*Set counter range*/
358      _pcnt_set_event_value(pcnt_port, unit, PCNT_EVT_H_LIM, pcnt_config->counter_h_lim);
359      _pcnt_set_event_value(pcnt_port, unit, PCNT_EVT_L_LIM, pcnt_config->counter_l_lim);
360      /*Default value after reboot is positive, we disable these events like others*/
361      _pcnt_event_disable(pcnt_port, unit, PCNT_EVT_H_LIM);
362      _pcnt_event_disable(pcnt_port, unit, PCNT_EVT_L_LIM);
363      _pcnt_event_disable(pcnt_port, unit, PCNT_EVT_ZERO);
364      _pcnt_filter_disable(pcnt_port, unit);
365      /*set pulse input and control mode*/
366      _pcnt_set_mode(pcnt_port, unit, channel, pcnt_config->pos_mode, pcnt_config->neg_mode, pcnt_config->hctrl_mode, pcnt_config->lctrl_mode);
367      /*Set pulse input and control pins*/
368      _pcnt_set_pin(pcnt_port, unit, channel, input_io, ctrl_io);
369      return ESP_OK;
370  }
371  
372  esp_err_t pcnt_deinit(pcnt_port_t pcnt_port)
373  {
374      PCNT_OBJ_CHECK(pcnt_port);
375  
376      heap_caps_free(p_pcnt_obj[pcnt_port]);
377      p_pcnt_obj[pcnt_port] = NULL;
378      return ESP_OK;
379  }
380  
381  esp_err_t pcnt_init(pcnt_port_t pcnt_port)
382  {
383      PCNT_CHECK((pcnt_port < PCNT_PORT_MAX), PCNT_NUM_ERR_STR, ESP_ERR_INVALID_ARG);
384      PCNT_CHECK((p_pcnt_obj[pcnt_port]) == NULL, "pcnt driver already initted", ESP_ERR_INVALID_STATE);
385  
386      p_pcnt_obj[pcnt_port] = (pcnt_obj_t *)heap_caps_calloc(1, sizeof(pcnt_obj_t), MALLOC_CAP_DEFAULT);
387  
388      if (p_pcnt_obj[pcnt_port] == NULL) {
389          ESP_LOGE(TAG, "PCNT driver malloc error");
390          return ESP_FAIL;
391      }
392  
393      pcnt_hal_init(&(p_pcnt_obj[pcnt_port]->hal), pcnt_port);
394      return ESP_OK;
395  }
396  
397  // TODO: The following functions are wrappers, for compatibility with current API.
398  
399  esp_err_t pcnt_unit_config(const pcnt_config_t *pcnt_config)
400  {
401      esp_err_t ret;
402  
403      if ((p_pcnt_obj[PCNT_PORT_0]) == NULL) {
404          ret = pcnt_init(PCNT_PORT_0);
405          if (ret != ESP_OK) {
406              return ret;
407          }
408      }
409      return _pcnt_unit_config(PCNT_PORT_0, pcnt_config);
410  }
411  
412  esp_err_t pcnt_set_mode(pcnt_unit_t unit, pcnt_channel_t channel, pcnt_count_mode_t pos_mode, pcnt_count_mode_t neg_mode, pcnt_ctrl_mode_t hctrl_mode, pcnt_ctrl_mode_t lctrl_mode)
413  {
414      return _pcnt_set_mode(PCNT_PORT_0, unit, channel, pos_mode, neg_mode, hctrl_mode, lctrl_mode);
415  }
416  
417  esp_err_t pcnt_set_pin(pcnt_unit_t unit, pcnt_channel_t channel, int pulse_io, int ctrl_io)
418  {
419      return _pcnt_set_pin(PCNT_PORT_0, unit, channel, pulse_io, ctrl_io);
420  }
421  
422  esp_err_t pcnt_get_counter_value(pcnt_unit_t pcnt_unit, int16_t *count)
423  {
424      return _pcnt_get_counter_value(PCNT_PORT_0, pcnt_unit, count);
425  }
426  
427  esp_err_t pcnt_counter_pause(pcnt_unit_t pcnt_unit)
428  {
429      return _pcnt_counter_pause(PCNT_PORT_0, pcnt_unit);
430  }
431  
432  esp_err_t pcnt_counter_resume(pcnt_unit_t pcnt_unit)
433  {
434      return _pcnt_counter_resume(PCNT_PORT_0, pcnt_unit);
435  }
436  
437  esp_err_t pcnt_counter_clear(pcnt_unit_t pcnt_unit)
438  {
439      return _pcnt_counter_clear(PCNT_PORT_0, pcnt_unit);
440  }
441  
442  esp_err_t pcnt_intr_enable(pcnt_unit_t pcnt_unit)
443  {
444      return _pcnt_intr_enable(PCNT_PORT_0, pcnt_unit);
445  }
446  
447  esp_err_t pcnt_intr_disable(pcnt_unit_t pcnt_unit)
448  {
449      return _pcnt_intr_disable(PCNT_PORT_0, pcnt_unit);
450  }
451  
452  esp_err_t pcnt_event_enable(pcnt_unit_t unit, pcnt_evt_type_t evt_type)
453  {
454      return _pcnt_event_enable(PCNT_PORT_0, unit, evt_type);
455  }
456  
457  esp_err_t pcnt_event_disable(pcnt_unit_t unit, pcnt_evt_type_t evt_type)
458  {
459      return _pcnt_event_disable(PCNT_PORT_0, unit, evt_type);
460  }
461  
462  esp_err_t pcnt_set_event_value(pcnt_unit_t unit, pcnt_evt_type_t evt_type, int16_t value)
463  {
464      return _pcnt_set_event_value(PCNT_PORT_0, unit, evt_type, value);
465  }
466  
467  esp_err_t pcnt_get_event_value(pcnt_unit_t unit, pcnt_evt_type_t evt_type, int16_t *value)
468  {
469      return _pcnt_get_event_value(PCNT_PORT_0, unit, evt_type, value);
470  }
471  
472  esp_err_t pcnt_get_event_status(pcnt_unit_t unit, uint32_t *status)
473  {
474      return _pcnt_get_event_status(PCNT_PORT_0, unit, status);
475  }
476  
477  esp_err_t pcnt_set_filter_value(pcnt_unit_t unit, uint16_t filter_val)
478  {
479      return _pcnt_set_filter_value(PCNT_PORT_0, unit, filter_val);
480  }
481  
482  esp_err_t pcnt_get_filter_value(pcnt_unit_t unit, uint16_t *filter_val)
483  {
484      return _pcnt_get_filter_value(PCNT_PORT_0, unit, filter_val);
485  }
486  
487  esp_err_t pcnt_filter_enable(pcnt_unit_t unit)
488  {
489      return _pcnt_filter_enable(PCNT_PORT_0, unit);
490  }
491  
492  esp_err_t pcnt_filter_disable(pcnt_unit_t unit)
493  {
494      return _pcnt_filter_disable(PCNT_PORT_0, unit);
495  }
496  
497  esp_err_t pcnt_isr_unregister(pcnt_isr_handle_t handle)
498  {
499      esp_err_t ret = ESP_FAIL;
500      PCNT_ENTER_CRITICAL(&pcnt_spinlock);
501      ret = esp_intr_free(handle);
502      PCNT_EXIT_CRITICAL(&pcnt_spinlock);
503      return ret;
504  }
505  
506  esp_err_t pcnt_isr_register(void (*fun)(void *), void *arg, int intr_alloc_flags, pcnt_isr_handle_t *handle)
507  {
508      esp_err_t ret = ESP_FAIL;
509      PCNT_CHECK(fun != NULL, PCNT_ADDRESS_ERR_STR, ESP_ERR_INVALID_ARG);
510      PCNT_ENTER_CRITICAL(&pcnt_spinlock);
511      ret = esp_intr_alloc(pcnt_periph_signals.irq, intr_alloc_flags, fun, arg, handle);
512      PCNT_EXIT_CRITICAL(&pcnt_spinlock);
513      return ret;
514  }
515  
516  esp_err_t pcnt_isr_handler_add(pcnt_unit_t unit, void(*isr_handler)(void *), void *args)
517  {
518      return _pcnt_isr_handler_add(PCNT_PORT_0, unit, isr_handler, args);
519  }
520  
521  esp_err_t pcnt_isr_handler_remove(pcnt_unit_t unit)
522  {
523      return _pcnt_isr_handler_remove(PCNT_PORT_0, unit);
524  }
525  
526  
527  esp_err_t pcnt_isr_service_install(int intr_alloc_flags)
528  {
529      return _pcnt_isr_service_install(PCNT_PORT_0, intr_alloc_flags);
530  }
531  
532  void pcnt_isr_service_uninstall()
533  {
534      _pcnt_isr_service_uninstall(PCNT_PORT_0);
535  }
536  
537  #endif // #if SOC_PCNT_SUPPORTED