mirror of
				https://github.com/espressif/esp-idf.git
				synced 2025-11-03 22:08:28 +00:00 
			
		
		
		
	bugfix:rotary encoder example isr service install
Fix the issue mentioned when using two or more encoders. Modify PCNT_CTRL_GND_IO to avoid the affect of USB JTAG(origin pin 19 is used for USB D-). Update esp32c3. peripherals.ld and docs for esp32s3. Closes https://github.com/espressif/esp-idf/issues/6889
This commit is contained in:
		@@ -29,7 +29,7 @@
 | 
				
			|||||||
#define PULSE_IO 21
 | 
					#define PULSE_IO 21
 | 
				
			||||||
#define PCNT_INPUT_IO 4
 | 
					#define PCNT_INPUT_IO 4
 | 
				
			||||||
#define PCNT_CTRL_VCC_IO 5
 | 
					#define PCNT_CTRL_VCC_IO 5
 | 
				
			||||||
#define PCNT_CTRL_GND_IO 19
 | 
					#define PCNT_CTRL_GND_IO 2
 | 
				
			||||||
#define HIGHEST_LIMIT 10
 | 
					#define HIGHEST_LIMIT 10
 | 
				
			||||||
#define LOWEST_LIMIT 0
 | 
					#define LOWEST_LIMIT 0
 | 
				
			||||||
#define MAX_THRESHOLD 5
 | 
					#define MAX_THRESHOLD 5
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,7 +14,6 @@ PROVIDE ( UHCI1  = 0x6000c000 );
 | 
				
			|||||||
PROVIDE ( HOST = 0x60015000 );
 | 
					PROVIDE ( HOST = 0x60015000 );
 | 
				
			||||||
PROVIDE ( RMT = 0x60016000 );
 | 
					PROVIDE ( RMT = 0x60016000 );
 | 
				
			||||||
PROVIDE ( RMTMEM = 0x60016400 );
 | 
					PROVIDE ( RMTMEM = 0x60016400 );
 | 
				
			||||||
PROVIDE ( PCNT = 0x60017000 );
 | 
					 | 
				
			||||||
PROVIDE ( SLC = 0x60018000 );
 | 
					PROVIDE ( SLC = 0x60018000 );
 | 
				
			||||||
PROVIDE ( LEDC = 0x60019000 );
 | 
					PROVIDE ( LEDC = 0x60019000 );
 | 
				
			||||||
PROVIDE ( TIMERG0 = 0x6001F000 );
 | 
					PROVIDE ( TIMERG0 = 0x6001F000 );
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,9 @@
 | 
				
			|||||||
Pulse Counter
 | 
					Pulse Counter
 | 
				
			||||||
=============
 | 
					=============
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					{IDF_TARGET_PCNT_UNIT_NUM:default="8", esp32s2="4"}
 | 
				
			||||||
 | 
					{IDF_TARGET_PCNT_MAX_UNIT_NUM:default="7", esp32s2="3"}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Introduction
 | 
					Introduction
 | 
				
			||||||
------------
 | 
					------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -22,13 +25,8 @@ Description of functionality of this API has been broken down into four sections
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
Configuration
 | 
					Configuration
 | 
				
			||||||
-------------
 | 
					-------------
 | 
				
			||||||
.. only:: esp32
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    The PCNT module has eight independent counting "units" numbered from 0 to 7. In the API they are referred to using :cpp:type:`pcnt_unit_t`. Each unit has two independent channels numbered as 0 and 1 and specified with :cpp:type:`pcnt_channel_t`.
 | 
					The PCNT module has {IDF_TARGET_PCNT_UNIT_NUM} independent counting "units" numbered from 0 to {IDF_TARGET_PCNT_MAX_UNIT_NUM}. In the API they are referred to using :cpp:type:`pcnt_unit_t`. Each unit has two independent channels numbered as 0 and 1 and specified with :cpp:type:`pcnt_channel_t`.
 | 
				
			||||||
 | 
					 | 
				
			||||||
.. only:: esp32s2
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    The PCNT module has four independent counting "units" numbered from 0 to 3. In the API they are referred to using :cpp:type:`pcnt_unit_t`. Each unit has two independent channels numbered as 0 and 1 and specified with :cpp:type:`pcnt_channel_t`.
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
The configuration is provided separately per unit's channel using :cpp:type:`pcnt_config_t` and covers:
 | 
					The configuration is provided separately per unit's channel using :cpp:type:`pcnt_config_t` and covers:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -17,6 +17,7 @@
 | 
				
			|||||||
#include "esp_compiler.h"
 | 
					#include "esp_compiler.h"
 | 
				
			||||||
#include "esp_log.h"
 | 
					#include "esp_log.h"
 | 
				
			||||||
#include "driver/pcnt.h"
 | 
					#include "driver/pcnt.h"
 | 
				
			||||||
 | 
					#include "sys/lock.h"
 | 
				
			||||||
#include "hal/pcnt_hal.h"
 | 
					#include "hal/pcnt_hal.h"
 | 
				
			||||||
#include "rotary_encoder.h"
 | 
					#include "rotary_encoder.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -34,6 +35,13 @@ static const char *TAG = "rotary_encoder";
 | 
				
			|||||||
#define EC11_PCNT_DEFAULT_HIGH_LIMIT (100)
 | 
					#define EC11_PCNT_DEFAULT_HIGH_LIMIT (100)
 | 
				
			||||||
#define EC11_PCNT_DEFAULT_LOW_LIMIT  (-100)
 | 
					#define EC11_PCNT_DEFAULT_LOW_LIMIT  (-100)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// A flag to identify if pcnt isr service has been installed.
 | 
				
			||||||
 | 
					static bool is_pcnt_isr_service_installed = false;
 | 
				
			||||||
 | 
					// A lock to avoid pcnt isr service being installed twice in multiple threads.
 | 
				
			||||||
 | 
					static _lock_t isr_service_install_lock;
 | 
				
			||||||
 | 
					#define LOCK_ACQUIRE() _lock_acquire(&isr_service_install_lock)
 | 
				
			||||||
 | 
					#define LOCK_RELEASE() _lock_release(&isr_service_install_lock)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct {
 | 
					typedef struct {
 | 
				
			||||||
    int accumu_count;
 | 
					    int accumu_count;
 | 
				
			||||||
    rotary_encoder_t parent;
 | 
					    rotary_encoder_t parent;
 | 
				
			||||||
@@ -141,8 +149,16 @@ esp_err_t rotary_encoder_new_ec11(const rotary_encoder_config_t *config, rotary_
 | 
				
			|||||||
    pcnt_counter_pause(ec11->pcnt_unit);
 | 
					    pcnt_counter_pause(ec11->pcnt_unit);
 | 
				
			||||||
    pcnt_counter_clear(ec11->pcnt_unit);
 | 
					    pcnt_counter_clear(ec11->pcnt_unit);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // register interrupt handler
 | 
					
 | 
				
			||||||
    ROTARY_CHECK(pcnt_isr_service_install(0) == ESP_OK, "install isr service failed", err, ESP_FAIL);
 | 
					    // register interrupt handler in a thread-safe way
 | 
				
			||||||
 | 
					    LOCK_ACQUIRE();
 | 
				
			||||||
 | 
					    if (!is_pcnt_isr_service_installed) {
 | 
				
			||||||
 | 
					        ROTARY_CHECK(pcnt_isr_service_install(0) == ESP_OK, "install isr service failed", err, ESP_FAIL);
 | 
				
			||||||
 | 
					        // make sure pcnt isr service won't be installed more than one time
 | 
				
			||||||
 | 
					        is_pcnt_isr_service_installed = true;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    LOCK_RELEASE();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pcnt_isr_handler_add(ec11->pcnt_unit, ec11_pcnt_overflow_handler, ec11);
 | 
					    pcnt_isr_handler_add(ec11->pcnt_unit, ec11_pcnt_overflow_handler, ec11);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pcnt_event_enable(ec11->pcnt_unit, PCNT_EVT_H_LIM);
 | 
					    pcnt_event_enable(ec11->pcnt_unit, PCNT_EVT_H_LIM);
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user