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 <Ihor.Nehrutsa@gmail.com>
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

Lines changed: 25 additions & 10 deletions
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

Lines changed: 64 additions & 13 deletions
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

Lines changed: 2 additions & 0 deletions
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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy