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
This commit is contained in:
Wangjialin 2016-11-24 12:01:21 +08:00
parent 452bee7181
commit f97f198c9d
4 changed files with 110 additions and 23 deletions

View file

@ -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

View file

@ -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 ; */

View file

@ -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 <https://github.com/espressif/esp-idf/tree/master/examples/12_pcnt>`_.
Pulse counter with control signal and event interrupt example: `examples/12_pcnt <https://github.com/espressif/esp-idf/tree/master/examples/12_pcnt>`_.
API Reference
-------------

View file

@ -11,7 +11,9 @@
*/
#include <stdio.h>
#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);
}
}
}