2626
2727#include "shared-bindings/frequencyio/FrequencyIn.h"
2828
29- #include <stdint.h>
30-
3129#include "py/runtime.h"
3230
33- #include "supervisor/shared/tick.h"
34- #include "shared-bindings/time/__init__.h"
31+ static void IRAM_ATTR pcnt_overflow_handler (void * self_in ) {
32+ frequencyio_frequencyin_obj_t * self = self_in ;
33+ // reset counter
34+ pcnt_counter_clear (self -> unit );
3535
36- #include "common-hal/microcontroller/Pin.h"
36+ // increase multiplier
37+ self -> multiplier ++ ;
38+
39+ // reset interrupt
40+ PCNT .int_clr .val = BIT (self -> unit );
41+ }
3742
38- static void IRAM_ATTR frequencyin_interrupt_handler (void * self_in ) {
43+ static void IRAM_ATTR timer_interrupt_handler (void * self_in ) {
3944 frequencyio_frequencyin_obj_t * self = self_in ;
4045 // get counter value
4146 int16_t count ;
@@ -50,9 +55,41 @@ static void IRAM_ATTR frequencyin_interrupt_handler(void *self_in) {
5055 TIMERG0 .hw_timer [0 ].config .alarm_en = 1 ;
5156}
5257
53- static void init_timer (frequencyio_frequencyin_obj_t * self , uint16_t capture_period ) {
58+ static void init_pcnt (frequencyio_frequencyin_obj_t * self ) {
59+ // Prepare configuration for the PCNT unit
60+ const pcnt_config_t pcnt_config = {
61+ // Set PCNT input signal and control GPIOs
62+ .pulse_gpio_num = self -> pin ,
63+ .ctrl_gpio_num = PCNT_PIN_NOT_USED ,
64+ .channel = PCNT_CHANNEL_0 ,
65+ // What to do on the positive / negative edge of pulse input?
66+ .pos_mode = PCNT_COUNT_INC , // count both rising and falling edges
67+ .neg_mode = PCNT_COUNT_INC ,
68+ // Set counter limit
69+ .counter_h_lim = INT16_MAX ,
70+ .counter_l_lim = 0 ,
71+ };
72+
73+ // Initialize PCNT unit
74+ const int8_t unit = peripherals_pcnt_init (pcnt_config );
75+ if (unit == -1 ) {
76+ mp_raise_RuntimeError (translate ("All PCNT units in use" ));
77+ }
78+
79+ // set the GPIO back to high-impedance, as pcnt_unit_config sets it as pull-up
80+ gpio_set_pull_mode (self -> pin , GPIO_FLOATING );
81+
82+ self -> unit = (pcnt_unit_t )unit ;
83+
84+ // enable pcnt interrupt
85+ pcnt_event_enable (self -> unit , PCNT_EVT_H_LIM );
86+ pcnt_isr_register (pcnt_overflow_handler , (void * )self , ESP_INTR_FLAG_IRAM , & self -> handle );
87+ pcnt_intr_enable (self -> unit );
88+ }
89+
90+ static void init_timer (frequencyio_frequencyin_obj_t * self ) {
5491 // Prepare configuration for the timer module
55- timer_config_t config = {
92+ const timer_config_t config = {
5693 .alarm_en = true,
5794 .counter_en = false,
5895 .intr_type = TIMER_INTR_LEVEL ,
@@ -64,9 +101,9 @@ static void init_timer(frequencyio_frequencyin_obj_t* self, uint16_t capture_per
64101 // Initialize timer module
65102 timer_init (TIMER_GROUP_0 , TIMER_0 , & config );
66103 timer_set_counter_value (TIMER_GROUP_0 , TIMER_0 , 0 );
67- timer_set_alarm_value (TIMER_GROUP_0 , TIMER_0 , capture_period * 1000000 );
104+ timer_set_alarm_value (TIMER_GROUP_0 , TIMER_0 , self -> capture_period * 1000000 );
105+ timer_isr_register (TIMER_GROUP_0 , TIMER_0 , timer_interrupt_handler , (void * )self , ESP_INTR_FLAG_IRAM , & self -> handle );
68106 timer_enable_intr (TIMER_GROUP_0 , TIMER_0 );
69- timer_isr_register (TIMER_GROUP_0 , TIMER_0 , frequencyin_interrupt_handler , (void * )self , ESP_INTR_FLAG_IRAM , & self -> handle );
70107
71108 // Start timer
72109 timer_start (TIMER_GROUP_0 , TIMER_0 );
@@ -78,33 +115,15 @@ void common_hal_frequencyio_frequencyin_construct(frequencyio_frequencyin_obj_t*
78115 mp_raise_ValueError (translate ("Invalid capture period. Valid range: 1 - 500" ));
79116 }
80117
81- // Prepare configuration for the PCNT unit
82- const pcnt_config_t pcnt_config = {
83- // Set PCNT input signal and control GPIOs
84- .pulse_gpio_num = pin -> number ,
85- .ctrl_gpio_num = PCNT_PIN_NOT_USED ,
86- .channel = PCNT_CHANNEL_0 ,
87- // What to do on the positive / negative edge of pulse input?
88- .pos_mode = PCNT_COUNT_INC , // count both rising and falling edges
89- .neg_mode = PCNT_COUNT_INC ,
90- };
91-
92- // Initialize PCNT unit
93- const int8_t unit = peripherals_pcnt_init (pcnt_config );
94- if (unit == -1 ) {
95- mp_raise_RuntimeError (translate ("All PCNT units in use" ));
96- }
97-
98- // set the GPIO back to high-impedance, as pcnt_unit_config sets it as pull-up
99- gpio_set_pull_mode (pin -> number , GPIO_FLOATING );
100-
101- // initialize timer
102- init_timer (self , capture_period );
103-
104118 self -> pin = pin -> number ;
105- self -> unit = (pcnt_unit_t )unit ;
119+ self -> handle = NULL ;
120+ self -> multiplier = 0 ;
106121 self -> capture_period = capture_period ;
107122
123+ // initialize pcnt and timer
124+ init_pcnt (self );
125+ init_timer (self );
126+
108127 claim_pin (pin );
109128}
110129
@@ -118,15 +137,15 @@ void common_hal_frequencyio_frequencyin_deinit(frequencyio_frequencyin_obj_t* se
118137 }
119138 reset_pin_number (self -> pin );
120139 peripherals_pcnt_deinit (& self -> unit );
140+ timer_deinit (TIMER_GROUP_0 , TIMER_0 );
121141 if (self -> handle ) {
122- timer_deinit (TIMER_GROUP_0 , TIMER_0 );
123142 esp_intr_free (self -> handle );
124143 self -> handle = NULL ;
125144 }
126145}
127146
128147uint32_t common_hal_frequencyio_frequencyin_get_item (frequencyio_frequencyin_obj_t * self ) {
129- return self -> frequency ;
148+ return ( self -> frequency + ( self -> multiplier * INT16_MAX )) ;
130149}
131150
132151void common_hal_frequencyio_frequencyin_pause (frequencyio_frequencyin_obj_t * self ) {
0 commit comments