26
26
27
27
#include "shared-bindings/frequencyio/FrequencyIn.h"
28
28
29
- #include <stdint.h>
30
-
31
29
#include "py/runtime.h"
32
30
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 );
35
35
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
+ }
37
42
38
- static void IRAM_ATTR frequencyin_interrupt_handler (void * self_in ) {
43
+ static void IRAM_ATTR timer_interrupt_handler (void * self_in ) {
39
44
frequencyio_frequencyin_obj_t * self = self_in ;
40
45
// get counter value
41
46
int16_t count ;
@@ -50,9 +55,41 @@ static void IRAM_ATTR frequencyin_interrupt_handler(void *self_in) {
50
55
TIMERG0 .hw_timer [0 ].config .alarm_en = 1 ;
51
56
}
52
57
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 ) {
54
91
// Prepare configuration for the timer module
55
- timer_config_t config = {
92
+ const timer_config_t config = {
56
93
.alarm_en = true,
57
94
.counter_en = false,
58
95
.intr_type = TIMER_INTR_LEVEL ,
@@ -64,9 +101,9 @@ static void init_timer(frequencyio_frequencyin_obj_t* self, uint16_t capture_per
64
101
// Initialize timer module
65
102
timer_init (TIMER_GROUP_0 , TIMER_0 , & config );
66
103
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 );
68
106
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 );
70
107
71
108
// Start timer
72
109
timer_start (TIMER_GROUP_0 , TIMER_0 );
@@ -78,33 +115,15 @@ void common_hal_frequencyio_frequencyin_construct(frequencyio_frequencyin_obj_t*
78
115
mp_raise_ValueError (translate ("Invalid capture period. Valid range: 1 - 500" ));
79
116
}
80
117
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
-
104
118
self -> pin = pin -> number ;
105
- self -> unit = (pcnt_unit_t )unit ;
119
+ self -> handle = NULL ;
120
+ self -> multiplier = 0 ;
106
121
self -> capture_period = capture_period ;
107
122
123
+ // initialize pcnt and timer
124
+ init_pcnt (self );
125
+ init_timer (self );
126
+
108
127
claim_pin (pin );
109
128
}
110
129
@@ -118,15 +137,15 @@ void common_hal_frequencyio_frequencyin_deinit(frequencyio_frequencyin_obj_t* se
118
137
}
119
138
reset_pin_number (self -> pin );
120
139
peripherals_pcnt_deinit (& self -> unit );
140
+ timer_deinit (TIMER_GROUP_0 , TIMER_0 );
121
141
if (self -> handle ) {
122
- timer_deinit (TIMER_GROUP_0 , TIMER_0 );
123
142
esp_intr_free (self -> handle );
124
143
self -> handle = NULL ;
125
144
}
126
145
}
127
146
128
147
uint32_t common_hal_frequencyio_frequencyin_get_item (frequencyio_frequencyin_obj_t * self ) {
129
- return self -> frequency ;
148
+ return ( self -> frequency + ( self -> multiplier * INT16_MAX )) ;
130
149
}
131
150
132
151
void common_hal_frequencyio_frequencyin_pause (frequencyio_frequencyin_obj_t * self ) {
0 commit comments