diff --git a/components/driver/include/driver/pcnt.h b/components/driver/include/driver/pcnt.h index c751473ba..e96450d0b 100644 --- a/components/driver/include/driver/pcnt.h +++ b/components/driver/include/driver/pcnt.h @@ -98,6 +98,8 @@ typedef intr_handle_t pcnt_isr_handle_t; /** * @brief Configure Pulse Counter unit + * @note + * This function will disable three events: PCNT_EVT_L_LIM, PCNT_EVT_H_LIM, PCNT_EVT_ZERO. * * @param pcnt_config Pointer of Pulse Counter unit configure parameter * @@ -233,16 +235,19 @@ esp_err_t pcnt_get_event_value(pcnt_unit_t unit, pcnt_evt_type_t evt_type, int16 /** * @brief Register PCNT interrupt handler, the handler is an ISR. * The handler will be attached to the same CPU core that this function is running on. + * Please do not use pcnt_isr_service_install if this function was called. * * @param fn Interrupt handler function. * @param arg Parameter for handler function * @param intr_alloc_flags Flags used to allocate the interrupt. One or multiple (ORred) * ESP_INTR_FLAG_* values. See esp_intr_alloc.h for more info. * @param handle Pointer to return handle. If non-NULL, a handle for the interrupt will - * be returned here. + * be returned here. Calling esp_intr_free to unregister this ISR service if needed, + * but only if the handle is not NULL. * * @return * - ESP_OK Success + * - ESP_ERR_NOT_FOUND Can not find the interrupt that matches the flags. * - ESP_ERR_INVALID_ARG Function pointer error. */ esp_err_t pcnt_isr_register(void (*fn)(void*), void * arg, int intr_alloc_flags, pcnt_isr_handle_t *handle); @@ -358,7 +363,8 @@ esp_err_t pcnt_isr_handler_add(pcnt_unit_t unit, void(*isr_handler)(void *), voi /** * @brief Install PCNT ISR service. * @note We can manage different interrupt service for each unit. - * Please do not use pcnt_isr_register if this function was called. + * This function will use the default ISR handle service, Calling pcnt_isr_service_uninstall to + * uninstall the default service if needed. Please do not use pcnt_isr_register if this function was called. * * @param intr_alloc_flags Flags used to allocate the interrupt. One or multiple (ORred) * ESP_INTR_FLAG_* values. See esp_intr_alloc.h for more info. diff --git a/components/driver/pcnt.c b/components/driver/pcnt.c index b859b495b..6fcc2b552 100644 --- a/components/driver/pcnt.c +++ b/components/driver/pcnt.c @@ -24,6 +24,7 @@ #define PCNT_COUNT_MODE_ERR_STR "PCNT COUNTER MODE ERROR" #define PCNT_CTRL_MODE_ERR_STR "PCNT CTRL MODE ERROR" #define PCNT_EVT_TYPE_ERR_STR "PCNT value type error" +#define PCNT_LIMT_VAL_ERR_STR "PCNT limit value error" #define PCNT_ENTER_CRITICAL(mux) portENTER_CRITICAL(mux) #define PCNT_EXIT_CRITICAL(mux) portEXIT_CRITICAL(mux) @@ -221,6 +222,8 @@ esp_err_t pcnt_set_event_value(pcnt_unit_t unit, pcnt_evt_type_t evt_type, int16 { PCNT_CHECK(unit < PCNT_UNIT_MAX, PCNT_UNIT_ERR_STR, ESP_ERR_INVALID_ARG); PCNT_CHECK(evt_type < PCNT_EVT_MAX, PCNT_EVT_TYPE_ERR_STR, ESP_ERR_INVALID_ARG); + PCNT_CHECK(!(evt_type == PCNT_EVT_L_LIM && value > 0), PCNT_LIMT_VAL_ERR_STR, ESP_ERR_INVALID_ARG); + PCNT_CHECK(!(evt_type == PCNT_EVT_H_LIM && value < 0), PCNT_LIMT_VAL_ERR_STR, ESP_ERR_INVALID_ARG); if(evt_type == PCNT_EVT_L_LIM) { PCNT.conf_unit[unit].conf2.cnt_l_lim = value; } else if(evt_type == PCNT_EVT_H_LIM) { diff --git a/examples/peripherals/pcnt/main/pcnt_example_main.c b/examples/peripherals/pcnt/main/pcnt_example_main.c index 2a4b3695c..a5da7946b 100644 --- a/examples/peripherals/pcnt/main/pcnt_example_main.c +++ b/examples/peripherals/pcnt/main/pcnt_example_main.c @@ -54,6 +54,7 @@ #define LEDC_OUTPUT_IO 18 // Output GPIO of a sample 1 Hz pulse generator xQueueHandle pcnt_evt_queue; // A queue to handle pulse counter events +pcnt_isr_handle_t user_isr_handle = NULL; //user's ISR service handle /* A sample structure to pass events from the PCNT * interrupt handler to the main program. @@ -159,7 +160,7 @@ static void pcnt_example_init(void) pcnt_counter_clear(PCNT_TEST_UNIT); /* Register ISR handler and enable interrupts for PCNT unit */ - pcnt_isr_register(pcnt_example_intr_handler, NULL, 0, NULL); + pcnt_isr_register(pcnt_example_intr_handler, NULL, 0, &user_isr_handle); pcnt_intr_enable(PCNT_TEST_UNIT); /* Everything is set up, now go to counting */ @@ -206,4 +207,9 @@ void app_main() printf("Current counter value :%d\n", count); } } + if(user_isr_handle) { + //Free the ISR service handle. + esp_intr_free(user_isr_handle); + user_isr_handle = NULL; + } }