From f97f198c9de4e44e80bacb429c54e7178e421373 Mon Sep 17 00:00:00 2001 From: Wangjialin Date: Thu, 24 Nov 2016 12:01:21 +0800 Subject: [PATCH] driver: improve pulse counter code 1. Modify some comments in pcnt.h 2. Modify api/pcnt.rst 3. Improve example code. 4. Add status definitions in pcnt_reg.h --- components/driver/include/driver/pcnt.h | 32 ++++++++---- components/esp32/include/soc/pcnt_reg.h | 30 +++++++++++ docs/api/pcnt.rst | 4 +- examples/12_pcnt/main/pcnt_test.c | 67 +++++++++++++++++++++---- 4 files changed, 110 insertions(+), 23 deletions(-) diff --git a/components/driver/include/driver/pcnt.h b/components/driver/include/driver/pcnt.h index 47bf25fe7..deff78183 100644 --- a/components/driver/include/driver/pcnt.h +++ b/components/driver/include/driver/pcnt.h @@ -17,6 +17,8 @@ extern "C" { #endif +#define PCNT_PIN_NOT_USED (-1) /*!< Pin are not used */ + typedef enum { PCNT_MODE_KEEP = 0, /*!< Control mode: won't change counter mode*/ PCNT_MODE_REVERSE = 1, /*!< Control mode: invert counter mode(increase -> decrease, decrease -> increase);*/ @@ -59,7 +61,7 @@ typedef enum { } pcnt_evt_type_t; /** - * @brief PCNT configure struct + * @brief Pulse Counter configure struct */ typedef struct { int pulse_gpio_num; /*!< Pulse input gpio_num, if you want to use gpio16, pulse_gpio_num = 16, a negative value will be ignored */ @@ -75,9 +77,9 @@ typedef struct { } pcnt_config_t; /** - * @brief Configure PCNT unit + * @brief Configure Pulse Counter unit * - * @param pcnt_config Pointer of PCNT unit configure parameter + * @param pcnt_config Pointer of Pulse Counter unit configure parameter * * @return * - ESP_OK Success @@ -88,7 +90,7 @@ esp_err_t pcnt_unit_config(pcnt_config_t *pcnt_config); /** * @brief Get pulse counter value * - * @param pcnt_unit PCNT unit number + * @param pcnt_unit Pulse Counter unit number * @param count Pointer to accept counter value * * @return @@ -133,7 +135,8 @@ esp_err_t pcnt_counter_clear(pcnt_unit_t pcnt_unit); /** * @brief Enable PCNT interrupt for PCNT unit * @note - * Five watch point events share the same interrupt source for each unit. + * Each Pulse counter unit has five watch point events that share the same interrupt. + * Configure events with pcnt_event_enable() and pcnt_event_disable() * * @param pcnt_unit PCNT unit number * @@ -158,8 +161,8 @@ esp_err_t pcnt_intr_disable(pcnt_unit_t pcnt_unit); * @brief Enable PCNT event of PCNT unit * * @param unit PCNT unit number - * @param evt_type PCNT watch point event type, five events share a same interrupt source - * + * @param evt_type Watch point event type. + * All enabled events share the same interrupt (one interrupt per pulse counter unit). * @return * - ESP_OK Success * - ESP_ERR_INVALID_ARG Parameter error @@ -170,8 +173,8 @@ esp_err_t pcnt_event_enable(pcnt_unit_t unit, pcnt_evt_type_t evt_type); * @brief Disable PCNT event of PCNT unit * * @param unit PCNT unit number - * @param evt_type PCNT watch point event type, five events share a same interrupt source - * + * @param evt_type Watch point event type. + * All enabled events share the same interrupt (one interrupt per pulse counter unit). * @return * - ESP_OK Success * - ESP_ERR_INVALID_ARG Parameter error @@ -182,7 +185,9 @@ esp_err_t pcnt_event_disable(pcnt_unit_t unit, pcnt_evt_type_t evt_type); * @brief Set PCNT event value of PCNT unit * * @param unit PCNT unit number - * @param evt_type PCNT watch point event type, five events share a same interrupt source + * @param evt_type Watch point event type. + * All enabled events share the same interrupt (one interrupt per pulse counter unit). + * * @param value Counter value for PCNT event * * @return @@ -195,7 +200,8 @@ esp_err_t pcnt_set_event_value(pcnt_unit_t unit, pcnt_evt_type_t evt_type, int16 * @brief Get PCNT event value of PCNT unit * * @param unit PCNT unit number - * @param evt_type PCNT watch point event type, five events share a same interrupt source + * @param evt_type Watch point event type. + * All enabled events share the same interrupt (one interrupt per pulse counter unit). * @param value Pointer to accept counter value for PCNT event * * @return @@ -229,7 +235,11 @@ esp_err_t pcnt_isr_register(uint32_t pcnt_intr_num, void (*fn)(void*), void * ar * @param unit PCNT unit number * @param channel PCNT channel number * @param pulse_io Pulse signal input GPIO + * @note + * Set to PCNT_PIN_NOT_USED if unused. * @param ctrl_io Control signal input GPIO + * @note + * Set to PCNT_PIN_NOT_USED if unused. * * @return * - ESP_OK Success diff --git a/components/esp32/include/soc/pcnt_reg.h b/components/esp32/include/soc/pcnt_reg.h index 7a3a78bf2..9809faf73 100644 --- a/components/esp32/include/soc/pcnt_reg.h +++ b/components/esp32/include/soc/pcnt_reg.h @@ -1319,6 +1319,36 @@ #define PCNT_CORE_STATUS_U0_M ((PCNT_CORE_STATUS_U0_V)<<(PCNT_CORE_STATUS_U0_S)) #define PCNT_CORE_STATUS_U0_V 0xFFFFFFFF #define PCNT_CORE_STATUS_U0_S 0 +/*0: positive value to zero; 1: negative value to zero; 2: counter value negative ; 3: counter value positive*/ +#define PCNT_STATUS_CNT_MODE 0x3 +#define PCNT_STATUS_CNT_MODE_M ((PCNT_STATUS_CNT_MODE_V)<<(PCNT_STATUS_CNT_MODE_S)) +#define PCNT_STATUS_CNT_MODE_V 0x3 +#define PCNT_STATUS_CNT_MODE_S 0 +/* counter value equals to thresh1*/ +#define PCNT_STATUS_THRES1 BIT(2) +#define PCNT_STATUS_THRES1_M BIT(2) +#define PCNT_STATUS_THRES1_V 0x1 +#define PCNT_STATUS_THRES1_S 2 +/* counter value equals to thresh0*/ +#define PCNT_STATUS_THRES0 BIT(3) +#define PCNT_STATUS_THRES0_M BIT(3) +#define PCNT_STATUS_THRES0_V 0x1 +#define PCNT_STATUS_THRES0_S 3 +/* counter value reaches h_lim*/ +#define PCNT_STATUS_L_LIM BIT(4) +#define PCNT_STATUS_L_LIM_M BIT(4) +#define PCNT_STATUS_L_LIM_V 0x1 +#define PCNT_STATUS_L_LIM_S 4 +/* counter value reaches l_lim*/ +#define PCNT_STATUS_H_LIM BIT(5) +#define PCNT_STATUS_H_LIM_M BIT(5) +#define PCNT_STATUS_H_LIM_V 0x1 +#define PCNT_STATUS_H_LIM_S 5 +/* counter value equals to zero*/ +#define PCNT_STATUS_ZERO BIT(6) +#define PCNT_STATUS_ZERO_M BIT(6) +#define PCNT_STATUS_ZERO_V 0x1 +#define PCNT_STATUS_ZERO_S 6 #define PCNT_U1_STATUS_REG (DR_REG_PCNT_BASE + 0x0094) /* PCNT_CORE_STATUS_U1 : RO ;bitpos:[31:0] ;default: 32'h0 ; */ diff --git a/docs/api/pcnt.rst b/docs/api/pcnt.rst index a3f654909..848fa5526 100644 --- a/docs/api/pcnt.rst +++ b/docs/api/pcnt.rst @@ -1,4 +1,4 @@ -PCNT +Pulse Counter ======== Overview @@ -9,7 +9,7 @@ The PCNT (Pulse Counter) module is designed to count the number of rising and/or Application Example ------------------- -PCNT counter with control signal and event interrupt example: `examples/12_pcnt `_. +Pulse counter with control signal and event interrupt example: `examples/12_pcnt `_. API Reference ------------- diff --git a/examples/12_pcnt/main/pcnt_test.c b/examples/12_pcnt/main/pcnt_test.c index 2980dde4b..1da4cca56 100644 --- a/examples/12_pcnt/main/pcnt_test.c +++ b/examples/12_pcnt/main/pcnt_test.c @@ -11,7 +11,9 @@ */ #include #include "freertos/FreeRTOS.h" +#include "freertos/portmacro.h" #include "freertos/task.h" +#include "freertos/queue.h" #include "driver/periph_ctrl.h" #include "driver/ledc.h" #include "driver/gpio.h" @@ -45,28 +47,49 @@ static const char* TAG = "PCNT_TEST"; #define PCNT_INPUT_CTRL_IO (5) #define LEDC_OUPUT_IO (18) +xQueueHandle pcnt_evt_queue; /*A queue to handle pulse counter event*/ + + +typedef struct { + int unit; /*pulse counter unit*/ + uint32_t status; /*pulse counter internal status*/ +} pcnt_evt_t; + void IRAM_ATTR pcnt_intr_handler(void* arg) { uint32_t intr_status = PCNT.int_st.val; int i; + pcnt_evt_t evt; + portBASE_TYPE HPTaskAwoken = pdFALSE; + for(i = 0; i < PCNT_UNIT_MAX; i++) { if(intr_status & (BIT(i))) { - ESP_EARLY_LOGI(TAG, "EVENT[%d] intr\n", i); - PCNT.int_clr.val |= BIT(i); + evt.unit = i; + evt.status = PCNT.status_unit[i].val; + PCNT.int_clr.val = BIT(i); + /*H LIM EVT*/ if(PCNT.status_unit[i].h_lim_lat) { - ESP_EARLY_LOGI(TAG, "H LIM EVT\n"); + //do something } + /*L LIM EVT*/ if(PCNT.status_unit[i].l_lim_lat) { - ESP_EARLY_LOGI(TAG, "L LIM EVT\n"); + //do something } + /*THRES0 EVT*/ if(PCNT.status_unit[i].thres0_lat) { - ESP_EARLY_LOGI(TAG, "THRES0 EVT\n"); + //do something } + /*THRES1 EVT*/ if(PCNT.status_unit[i].thres1_lat) { - ESP_EARLY_LOGI(TAG, "THRES1 EVT\n"); + //do something } + /*ZERO EVT*/ if(PCNT.status_unit[i].zero_lat) { - ESP_EARLY_LOGI(TAG, "ZERO EVT\n"); + //do something + } + xQueueSendFromISR(pcnt_evt_queue, &evt, &HPTaskAwoken); + if(HPTaskAwoken == pdTRUE) { + portYIELD_FROM_ISR(); } } } @@ -165,15 +188,39 @@ void app_main() { /*Init LEDC for pulse input signal */ ledc_init(); + /*Init PCNT event queue */ + pcnt_evt_queue = xQueueCreate(10, sizeof(pcnt_evt_t)); /*Init PCNT functions*/ pcnt_init(); int16_t count = 0; + pcnt_evt_t evt; + portBASE_TYPE res; while(1) { - pcnt_get_counter_value(PCNT_TEST_UNIT, &count); - printf("Current counter value :%d\n", count); - vTaskDelay(1000 / portTICK_RATE_MS); + res = xQueueReceive(pcnt_evt_queue, &evt, 1000 / portTICK_RATE_MS); + if(res == pdTRUE) { + pcnt_get_counter_value(PCNT_TEST_UNIT, &count); + printf("Event PCNT unit[%d]; cnt: %d\n", evt.unit, count); + if(evt.status & PCNT_STATUS_THRES1_M) { + printf("THRES1 EVT\n"); + } + if(evt.status & PCNT_STATUS_THRES0_M) { + printf("THRES0 EVT\n"); + } + if(evt.status & PCNT_STATUS_L_LIM_M) { + printf("L_LIM EVT\n"); + } + if(evt.status & PCNT_STATUS_H_LIM_M) { + printf("H_LIM EVT\n"); + } + if(evt.status & PCNT_STATUS_ZERO_M) { + printf("ZERO EVT\n"); + } + } else { + pcnt_get_counter_value(PCNT_TEST_UNIT, &count); + printf("Current counter value :%d\n", count); + } } }