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:
parent
452bee7181
commit
f97f198c9d
|
@ -17,6 +17,8 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define PCNT_PIN_NOT_USED (-1) /*!< Pin are not used */
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
PCNT_MODE_KEEP = 0, /*!< Control mode: won't change counter mode*/
|
PCNT_MODE_KEEP = 0, /*!< Control mode: won't change counter mode*/
|
||||||
PCNT_MODE_REVERSE = 1, /*!< Control mode: invert counter mode(increase -> decrease, decrease -> increase);*/
|
PCNT_MODE_REVERSE = 1, /*!< Control mode: invert counter mode(increase -> decrease, decrease -> increase);*/
|
||||||
|
@ -59,7 +61,7 @@ typedef enum {
|
||||||
} pcnt_evt_type_t;
|
} pcnt_evt_type_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief PCNT configure struct
|
* @brief Pulse Counter configure struct
|
||||||
*/
|
*/
|
||||||
typedef 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 */
|
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;
|
} 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
|
* @return
|
||||||
* - ESP_OK Success
|
* - ESP_OK Success
|
||||||
|
@ -88,7 +90,7 @@ esp_err_t pcnt_unit_config(pcnt_config_t *pcnt_config);
|
||||||
/**
|
/**
|
||||||
* @brief Get pulse counter value
|
* @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
|
* @param count Pointer to accept counter value
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
|
@ -133,7 +135,8 @@ esp_err_t pcnt_counter_clear(pcnt_unit_t pcnt_unit);
|
||||||
/**
|
/**
|
||||||
* @brief Enable PCNT interrupt for PCNT unit
|
* @brief Enable PCNT interrupt for PCNT unit
|
||||||
* @note
|
* @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
|
* @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
|
* @brief Enable PCNT event of PCNT unit
|
||||||
*
|
*
|
||||||
* @param unit PCNT unit number
|
* @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
|
* @return
|
||||||
* - ESP_OK Success
|
* - ESP_OK Success
|
||||||
* - ESP_ERR_INVALID_ARG Parameter error
|
* - 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
|
* @brief Disable PCNT event of PCNT unit
|
||||||
*
|
*
|
||||||
* @param unit PCNT unit number
|
* @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
|
* @return
|
||||||
* - ESP_OK Success
|
* - ESP_OK Success
|
||||||
* - ESP_ERR_INVALID_ARG Parameter error
|
* - 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
|
* @brief Set PCNT event value of PCNT unit
|
||||||
*
|
*
|
||||||
* @param unit PCNT unit number
|
* @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
|
* @param value Counter value for PCNT event
|
||||||
*
|
*
|
||||||
* @return
|
* @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
|
* @brief Get PCNT event value of PCNT unit
|
||||||
*
|
*
|
||||||
* @param unit PCNT unit number
|
* @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
|
* @param value Pointer to accept counter value for PCNT event
|
||||||
*
|
*
|
||||||
* @return
|
* @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 unit PCNT unit number
|
||||||
* @param channel PCNT channel number
|
* @param channel PCNT channel number
|
||||||
* @param pulse_io Pulse signal input GPIO
|
* @param pulse_io Pulse signal input GPIO
|
||||||
|
* @note
|
||||||
|
* Set to PCNT_PIN_NOT_USED if unused.
|
||||||
* @param ctrl_io Control signal input GPIO
|
* @param ctrl_io Control signal input GPIO
|
||||||
|
* @note
|
||||||
|
* Set to PCNT_PIN_NOT_USED if unused.
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
* - ESP_OK Success
|
* - ESP_OK Success
|
||||||
|
|
|
@ -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_M ((PCNT_CORE_STATUS_U0_V)<<(PCNT_CORE_STATUS_U0_S))
|
||||||
#define PCNT_CORE_STATUS_U0_V 0xFFFFFFFF
|
#define PCNT_CORE_STATUS_U0_V 0xFFFFFFFF
|
||||||
#define PCNT_CORE_STATUS_U0_S 0
|
#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)
|
#define PCNT_U1_STATUS_REG (DR_REG_PCNT_BASE + 0x0094)
|
||||||
/* PCNT_CORE_STATUS_U1 : RO ;bitpos:[31:0] ;default: 32'h0 ; */
|
/* PCNT_CORE_STATUS_U1 : RO ;bitpos:[31:0] ;default: 32'h0 ; */
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
PCNT
|
Pulse Counter
|
||||||
========
|
========
|
||||||
|
|
||||||
Overview
|
Overview
|
||||||
|
@ -9,7 +9,7 @@ The PCNT (Pulse Counter) module is designed to count the number of rising and/or
|
||||||
Application Example
|
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
|
API Reference
|
||||||
-------------
|
-------------
|
||||||
|
|
|
@ -11,7 +11,9 @@
|
||||||
*/
|
*/
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "freertos/FreeRTOS.h"
|
#include "freertos/FreeRTOS.h"
|
||||||
|
#include "freertos/portmacro.h"
|
||||||
#include "freertos/task.h"
|
#include "freertos/task.h"
|
||||||
|
#include "freertos/queue.h"
|
||||||
#include "driver/periph_ctrl.h"
|
#include "driver/periph_ctrl.h"
|
||||||
#include "driver/ledc.h"
|
#include "driver/ledc.h"
|
||||||
#include "driver/gpio.h"
|
#include "driver/gpio.h"
|
||||||
|
@ -45,28 +47,49 @@ static const char* TAG = "PCNT_TEST";
|
||||||
#define PCNT_INPUT_CTRL_IO (5)
|
#define PCNT_INPUT_CTRL_IO (5)
|
||||||
#define LEDC_OUPUT_IO (18)
|
#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)
|
void IRAM_ATTR pcnt_intr_handler(void* arg)
|
||||||
{
|
{
|
||||||
uint32_t intr_status = PCNT.int_st.val;
|
uint32_t intr_status = PCNT.int_st.val;
|
||||||
int i;
|
int i;
|
||||||
|
pcnt_evt_t evt;
|
||||||
|
portBASE_TYPE HPTaskAwoken = pdFALSE;
|
||||||
|
|
||||||
for(i = 0; i < PCNT_UNIT_MAX; i++) {
|
for(i = 0; i < PCNT_UNIT_MAX; i++) {
|
||||||
if(intr_status & (BIT(i))) {
|
if(intr_status & (BIT(i))) {
|
||||||
ESP_EARLY_LOGI(TAG, "EVENT[%d] intr\n", i);
|
evt.unit = i;
|
||||||
PCNT.int_clr.val |= BIT(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) {
|
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) {
|
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) {
|
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) {
|
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) {
|
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 */
|
/*Init LEDC for pulse input signal */
|
||||||
ledc_init();
|
ledc_init();
|
||||||
|
/*Init PCNT event queue */
|
||||||
|
pcnt_evt_queue = xQueueCreate(10, sizeof(pcnt_evt_t));
|
||||||
/*Init PCNT functions*/
|
/*Init PCNT functions*/
|
||||||
pcnt_init();
|
pcnt_init();
|
||||||
|
|
||||||
int16_t count = 0;
|
int16_t count = 0;
|
||||||
|
pcnt_evt_t evt;
|
||||||
|
portBASE_TYPE res;
|
||||||
while(1)
|
while(1)
|
||||||
{
|
{
|
||||||
pcnt_get_counter_value(PCNT_TEST_UNIT, &count);
|
res = xQueueReceive(pcnt_evt_queue, &evt, 1000 / portTICK_RATE_MS);
|
||||||
printf("Current counter value :%d\n", count);
|
if(res == pdTRUE) {
|
||||||
vTaskDelay(1000 / portTICK_RATE_MS);
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue