Skip to content

Commit b650e6f

Browse files
committed
esp32/Counter: Add IRQ_ROLL_OVER, IRQ_ROLL_UNDER.
esp32/Counter: Add IRQ_ROLL_OVER, IRQ_ROLL_UNDER. Signed-off-by: Ihor Nehrutsa <[email protected]>
1 parent 3fee7bc commit b650e6f

File tree

3 files changed

+91
-23
lines changed

3 files changed

+91
-23
lines changed

docs/esp32/pcnt.rst

+25-10
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,9 @@ Methods
8484
.. method:: Counter.value([value])
8585

8686
Get, and optionally set, the counter *value* as a signed 64-bit integer.
87+
Attention: Setting the counter brokes the IRQ_MATCH and IRQ_ZERO events.
8788

88-
.. method:: Counter.irq(handler=None, trigger=Counter.IRQ_MATCH1 | Counter.IRQ_ZERO, value=0)
89+
.. method:: Counter.irq(handler=None, trigger=Counter.IRQ_MATCH | Counter.IRQ_ZERO, value=0)
8990

9091
-*handler* specifies a function is called when the respective *trigger* event happens.
9192
The callback function *handler* receives a single argument, which is the Counter object.
@@ -96,14 +97,16 @@ Methods
9697

9798
-*trigger* events may be:
9899

99-
- Counter.IRQ_MATCH1 triggered when the counter matches the match1 value.
100+
- Counter.IRQ_MATCH triggered when the counter matches the match value.
100101
- Counter.IRQ_ZERO triggered when the counter matches the 0.
102+
- Counter.IRQ_ROLL_OVER triggered when the int16_t counter overloaded.
103+
- Counter.IRQ_ROLL_UNDER triggered when the int16_t counter underloaded.
101104

102-
The default is - trigger=Counter.IRQ_MATCH1 | Counter.IRQ_ZERO.
105+
The default is - trigger=Counter.IRQ_MATCH | Counter.IRQ_ZERO.
103106
The events are triggered when the counter value and match value are identical, but
104107
callbacks have always a latency.
105108

106-
- *value* sets a counter match1 value. When the counter matches these values,
109+
- *value* sets a counter match value. When the counter matches these values,
107110
a callback function can be called. They are 0 by default.
108111

109112
Attention: ``Counter.irq()`` resets counter to 0.
@@ -112,6 +115,18 @@ Attention: ``Counter.irq()`` resets counter to 0.
112115

113116
Returns the event status flags of the recent handled Counter interrupt as a bitmap.
114117

118+
===== ==== ======================= =============================================================
119+
bit # mask trigger coment
120+
===== ==== ======================= =============================================================
121+
0 1 if zero event: 0 - when counting up, 1 - when counting down
122+
2 4 Counter.IRQ_MATCH match value event when counting up
123+
3 8 Counter.IRQ_MATCH match value event when counting down
124+
4 16 Counter.IRQ_ROLL_UNDER roll under event
125+
5 32 Counter.IRQ_ROLL_OVER roll over event
126+
6 64 Counter.IRQ_ZERO zero event
127+
===== ==== ======================= =============================================================
128+
129+
115130
.. method:: Counter.id()
116131

117132
Returns id number.
@@ -133,7 +148,7 @@ Constants
133148

134149
Selects the counted edges.
135150

136-
.. data:: Counter.IRQ_MATCH1
151+
.. data:: Counter.IRQ_MATCH
137152
Counter.IRQ_ZERO
138153

139154
Selects callback triggers.
@@ -180,7 +195,7 @@ See `Quadrature encoder outputs.
180195
Constructor
181196
-----------
182197

183-
.. class:: Encoder(id, phase_a=None, phase_b=None, \*, x124=4, filter_ns=0, match1=0)
198+
.. class:: Encoder(id, phase_a=None, phase_b=None, \*, x124=4, filter_ns=0, match=0)
184199

185200
The Encoder starts to count immediately. Filtering is disabled.
186201

@@ -203,7 +218,7 @@ Constructor
203218

204219
These keywords are the same as the Counter keywords, see above:
205220
- *filter_ns*
206-
- *match1*
221+
- *match*
207222

208223
Methods
209224
-------
@@ -218,7 +233,7 @@ in the constructor and internal hardware PCNT initialization.
218233
Constants
219234
---------
220235

221-
.. data:: Encoder.IRQ_MATCH1
236+
.. data:: Encoder.IRQ_MATCH
222237
Encoder.IRQ_ZERO
223238

224239
Selects callback triggers.
@@ -237,13 +252,13 @@ Constants
237252
n += 1
238253
print('irq_handler2()', self.id(), self.value(), n)
239254

240-
enc = Encoder(0, phase_a=Pin(17, mode=Pin.IN), phase_b=Pin(16, mode=Pin.IN), match1=1000)
255+
enc = Encoder(0, phase_a=Pin(17, mode=Pin.IN), phase_b=Pin(16, mode=Pin.IN), match=1000)
241256

242257
enc.pause()
243258
flt = enc.filter() # return current filter value.
244259
enc.filter(10_000) # filter delay is 10ms
245260
c = enc.value(0) # get current encoder value, set the encoder value to 0
246-
enc.irq(irq_handler1, Encoder.IRQ_MATCH1) # set irq handler
261+
enc.irq(irq_handler1, Encoder.IRQ_MATCH) # set irq handler
247262
enc.resume()
248263

249264
_c = None

ports/esp32/machine_encoder.c

+64-13
Original file line numberDiff line numberDiff line change
@@ -78,28 +78,42 @@ static void IRAM_ATTR pcnt_intr_handler(void *arg) {
7878
// self->event_status = PCNT.status_unit[id].val;
7979
pcnt_get_event_status(id, &self->event_status);
8080
if (self->event_status & PCNT_EVT_H_LIM) {
81+
// when counting up
82+
// debug_printf("H");
8183
self->counter += INT16_ROLL;
8284
self->counter_accum += INT16_ROLL;
85+
if (self->handler_roll_over != MP_OBJ_NULL) {
86+
mp_sched_schedule(self->handler_roll_over, MP_OBJ_FROM_PTR(self));
87+
mp_hal_wake_main_task_from_isr();
88+
}
8389
} else if (self->event_status & PCNT_EVT_L_LIM) {
90+
// when counting down
91+
// debug_printf("L");
8492
self->counter -= INT16_ROLL;
8593
self->counter_accum -= INT16_ROLL;
94+
if (self->handler_roll_under != MP_OBJ_NULL) {
95+
mp_sched_schedule(self->handler_roll_under, MP_OBJ_FROM_PTR(self));
96+
mp_hal_wake_main_task_from_isr();
97+
}
8698
}
87-
8899
if (self->event_status & PCNT_EVT_THRES_1) {
89-
// counting up
100+
// when counting up & treshold value > 0
101+
// debug_printf("1");
90102
if (self->counter_accum == self->counter_match) {
91103
mp_sched_schedule(self->handler_match, MP_OBJ_FROM_PTR(self));
92104
mp_hal_wake_main_task_from_isr();
93105
}
94-
}
95-
if (self->event_status & PCNT_EVT_THRES_0) {
96-
// counting down
106+
} else if (self->event_status & PCNT_EVT_THRES_0) {
107+
// when counting down & treshold value < 0
108+
// debug_printf("0");
97109
if (self->counter_accum == self->counter_match + INT16_ROLL) {
98110
mp_sched_schedule(self->handler_match, MP_OBJ_FROM_PTR(self));
99111
mp_hal_wake_main_task_from_isr();
100112
}
101113
}
102114
if (self->event_status & PCNT_EVT_ZERO) {
115+
// when counting up/down
116+
// debug_printf("Z");
103117
if (self->counter == 0) {
104118
mp_sched_schedule(self->handler_zero, MP_OBJ_FROM_PTR(self));
105119
mp_hal_wake_main_task_from_isr();
@@ -161,6 +175,12 @@ static void set_filter_value(pcnt_unit_t unit, int16_t value) {
161175
}
162176

163177
static void pcnt_disable_events(mp_pcnt_obj_t *self) {
178+
if (self->handler_roll_over != MP_OBJ_NULL) {
179+
self->handler_roll_over = MP_OBJ_NULL;
180+
}
181+
if (self->handler_roll_under != MP_OBJ_NULL) {
182+
self->handler_roll_under = MP_OBJ_NULL;
183+
}
164184
if (self->handler_match != MP_OBJ_NULL) {
165185
check_esp_err(pcnt_event_disable(self->unit, PCNT_EVT_THRES_1));
166186
check_esp_err(pcnt_event_disable(self->unit, PCNT_EVT_THRES_0));
@@ -183,6 +203,8 @@ static void reset(mp_pcnt_obj_t *self) {
183203
self->counter_match = 0;
184204
self->handler_match = MP_OBJ_NULL;
185205
self->handler_zero = MP_OBJ_NULL;
206+
self->handler_roll_over = MP_OBJ_NULL;
207+
self->handler_roll_under = MP_OBJ_NULL;
186208
self->event_status = 0;
187209

188210
self->filter = 0;
@@ -192,7 +214,6 @@ static void reset(mp_pcnt_obj_t *self) {
192214
static void pcnt_deinit(mp_pcnt_obj_t *self) {
193215
if (self != NULL) {
194216
check_esp_err(pcnt_counter_pause(self->unit));
195-
196217
check_esp_err(pcnt_intr_disable(self->unit));
197218

198219
check_esp_err(pcnt_event_disable(self->unit, PCNT_EVT_L_LIM));
@@ -202,6 +223,7 @@ static void pcnt_deinit(mp_pcnt_obj_t *self) {
202223
check_esp_err(pcnt_set_pin(self->unit, PCNT_CHANNEL_0, PCNT_PIN_NOT_USED, PCNT_PIN_NOT_USED));
203224
check_esp_err(pcnt_set_pin(self->unit, PCNT_CHANNEL_1, PCNT_PIN_NOT_USED, PCNT_PIN_NOT_USED));
204225

226+
check_esp_err(pcnt_counter_clear(self->unit));
205227
reset(self);
206228
pcnts[self->unit] = NULL;
207229
}
@@ -317,7 +339,7 @@ static mp_obj_t machine_PCNT_irq(size_t n_pos_args, const mp_obj_t *pos_args, mp
317339
mp_obj_t handler = args[ARG_handler].u_obj;
318340
mp_uint_t trigger = args[ARG_trigger].u_int;
319341

320-
if (trigger & ~(PCNT_EVT_THRES_1 | PCNT_EVT_ZERO)) {
342+
if (trigger & ~(PCNT_EVT_THRES_1 | PCNT_EVT_ZERO | PCNT_EVT_H_LIM | PCNT_EVT_L_LIM)) {
321343
mp_raise_ValueError(MP_ERROR_TEXT("trigger"));
322344
}
323345

@@ -333,6 +355,12 @@ static mp_obj_t machine_PCNT_irq(size_t n_pos_args, const mp_obj_t *pos_args, mp
333355
check_esp_err(pcnt_event_disable(self->unit, PCNT_EVT_ZERO));
334356
self->handler_zero = MP_OBJ_NULL;
335357
}
358+
if (trigger & PCNT_EVT_H_LIM) {
359+
self->handler_roll_over = MP_OBJ_NULL;
360+
}
361+
if (trigger & PCNT_EVT_L_LIM) {
362+
self->handler_roll_under = MP_OBJ_NULL;
363+
}
336364
} else {
337365
if (trigger & PCNT_EVT_THRES_1) {
338366
if (args[ARG_value].u_obj != MP_OBJ_NULL) {
@@ -362,6 +390,12 @@ static mp_obj_t machine_PCNT_irq(size_t n_pos_args, const mp_obj_t *pos_args, mp
362390
check_esp_err(pcnt_event_enable(self->unit, PCNT_EVT_THRES_1));
363391
check_esp_err(pcnt_event_enable(self->unit, PCNT_EVT_THRES_0));
364392
}
393+
if (trigger & PCNT_EVT_H_LIM) {
394+
self->handler_roll_over = handler;
395+
}
396+
if (trigger & PCNT_EVT_L_LIM) {
397+
self->handler_roll_under = handler;
398+
}
365399
if (trigger & PCNT_EVT_ZERO) {
366400
/*
367401
int16_t count;
@@ -571,19 +605,30 @@ static mp_obj_t machine_Counter_init(size_t n_args, const mp_obj_t *args, mp_map
571605
MP_DEFINE_CONST_FUN_OBJ_KW(machine_Counter_init_obj, 1, machine_Counter_init);
572606

573607
static void common_print_kw(const mp_print_t *print, mp_pcnt_obj_t *self) {
608+
if (self->handler_roll_over != MP_OBJ_NULL) {
609+
mp_printf(print, ", roll_over=%ld", INT16_ROLL);
610+
}
611+
if (self->handler_roll_under != MP_OBJ_NULL) {
612+
mp_printf(print, ", roll_under=%ld", -INT16_ROLL);
613+
}
574614
if (self->handler_match != MP_OBJ_NULL) {
575-
mp_printf(print, ", match1=%ld", self->match);
615+
mp_printf(print, ", match=%ld", self->match);
576616
}
577617
if (self->handler_zero != MP_OBJ_NULL) {
578-
mp_printf(print, ", match=0");
618+
mp_printf(print, ", match0=0");
579619
}
580620
mp_printf(print, ", filter_ns=%d)", filter_to_ns(self->filter));
581621
}
582622

583623
static void machine_Counter_print(const mp_print_t *print, mp_obj_t self_obj, mp_print_kind_t kind) {
584624
mp_pcnt_obj_t *self = MP_OBJ_TO_PTR(self_obj);
585625

586-
mp_printf(print, "Counter(%u, src=Pin(%u)", self->unit, self->aPinNumber);
626+
mp_printf(print, "Counter(%u", self->unit);
627+
if (self->aPinNumber == PCNT_PIN_NOT_USED) {
628+
mp_printf(print, ")");
629+
return;
630+
}
631+
mp_printf(print, "), src=Pin(%u)", self->aPinNumber);
587632
if (self->x124 < 0) {
588633
mp_printf(print, ", _src=Pin(%u)", self->bPinNumber);
589634
} else {
@@ -611,7 +656,9 @@ static void machine_Counter_print(const mp_print_t *print, mp_obj_t self_obj, mp
611656

612657
#define COMMON_CONSTANTS \
613658
{ MP_ROM_QSTR(MP_QSTR_IRQ_ZERO), MP_ROM_INT(PCNT_EVT_ZERO) }, \
614-
{ MP_ROM_QSTR(MP_QSTR_IRQ_MATCH1), MP_ROM_INT(PCNT_EVT_THRES_1) }
659+
{ MP_ROM_QSTR(MP_QSTR_IRQ_ROLL_OVER), MP_ROM_INT(PCNT_EVT_H_LIM) }, \
660+
{ MP_ROM_QSTR(MP_QSTR_IRQ_ROLL_UNDER), MP_ROM_INT(PCNT_EVT_L_LIM) }, \
661+
{ MP_ROM_QSTR(MP_QSTR_IRQ_MATCH), MP_ROM_INT(PCNT_EVT_THRES_1) }
615662

616663
static const mp_rom_map_elem_t machine_Counter_locals_dict_table[] = {
617664
{ MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&machine_Counter_init_obj) },
@@ -755,8 +802,12 @@ MP_DEFINE_CONST_FUN_OBJ_KW(machine_Encoder_init_obj, 1, machine_Encoder_init);
755802

756803
static void machine_Encoder_print(const mp_print_t *print, mp_obj_t self_obj, mp_print_kind_t kind) {
757804
mp_pcnt_obj_t *self = MP_OBJ_TO_PTR(self_obj);
758-
759-
mp_printf(print, "Encoder(%u, phase_a=Pin(%u), phase_b=Pin(%u), x124=%d", self->unit, self->aPinNumber, self->bPinNumber, self->x124);
805+
mp_printf(print, "Encoder(%u", self->unit);
806+
if (self->aPinNumber == PCNT_PIN_NOT_USED) {
807+
mp_printf(print, ")");
808+
return;
809+
}
810+
mp_printf(print, ", phase_a=Pin(%u), phase_b=Pin(%u), x124=%d", self->aPinNumber, self->bPinNumber, self->x124);
760811
common_print_kw(print, self);
761812
}
762813

ports/esp32/machine_encoder.h

+2
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ typedef struct _mp_pcnt_obj_t {
3434
counter_t counter_match; // (match - counter) - (match - counter) % INT16_ROLL
3535
mp_obj_t handler_match;
3636
mp_obj_t handler_zero;
37+
mp_obj_t handler_roll_over;
38+
mp_obj_t handler_roll_under;
3739
uint32_t event_status;
3840

3941
int filter;

0 commit comments

Comments
 (0)