Skip to content

Commit b6eb32c

Browse files
committed
mimxrt/machine_encoder: Emulate the phases argument.
By dividing the internal counter by 1, 2 or 4. The default is 4, matching the hardware. Signed-off-by: robert-hh <robert@hammelrath.com>
1 parent 5e8bac1 commit b6eb32c

File tree

3 files changed

+49
-7
lines changed

3 files changed

+49
-7
lines changed

docs/library/mimxrt.Encoder.rst

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ Example usage::
2727
Constructors
2828
------------
2929

30-
.. class:: Encoder(id, phase_a, phase_b, *, home, match_pin, filter_ns, cpc, signed, index)
30+
.. class:: Encoder(id, phase_a, phase_b, *, home, match_pin, filter_ns, cpc, signed, index, phases)
3131
:no-index:
3232

3333
Construct and return a new quadrature encoder object using the following parameters:
@@ -72,6 +72,10 @@ Constructors
7272
- *index*\=value. A Pin specifier telling to which pin the index pulse is connected.
7373
At a rising slope of the index pulse the position counter is set to the init value
7474
and the cycles counter is increased by one. A *value* of *None* disables the index input.
75+
- *phases* specifies the number of signal edges to count and thus the
76+
granularity of the decoding. e.g. 4 phases corresponds to "4x quadrature
77+
decoding", and will result in four counts per pulse. Ports may support
78+
either 1, 2, or 4 phases and the default is 4 phase. *(Supported on MIMXRT)*
7579

7680
The arguments phase_a, phase_b and filter_ns are generic across ports, all other arguments are port-specific.
7781

ports/mimxrt/machine_encoder.c

Lines changed: 44 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ typedef struct _machine_encoder_obj_t {
4949
uint8_t mode;
5050
bool is_signed;
5151
uint8_t match_pin;
52+
uint8_t phases;
5253
uint32_t cpc;
5354
uint32_t filter;
5455
uint16_t status;
@@ -403,7 +404,7 @@ static void mp_machine_encoder_init_helper_common(machine_encoder_obj_t *self,
403404
static void mp_machine_encoder_init_helper(machine_encoder_obj_t *self,
404405
size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
405406
enum { ARG_phase_a, ARG_phase_b, ARG_home,
406-
ARG_match_pin, ARG_filter_ns, ARG_cpc, ARG_signed, ARG_index};
407+
ARG_match_pin, ARG_filter_ns, ARG_cpc, ARG_signed, ARG_index, ARG_phases};
407408

408409
static const mp_arg_t allowed_args[] = {
409410
{ MP_QSTR_phase_a, MP_ARG_OBJ, {.u_rom_obj = mp_const_none} },
@@ -414,6 +415,7 @@ static void mp_machine_encoder_init_helper(machine_encoder_obj_t *self,
414415
{ MP_QSTR_cpc, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = mp_const_none} },
415416
{ MP_QSTR_signed, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -1} },
416417
{ MP_QSTR_index, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_rom_obj = MP_ROM_INT(-1)} },
418+
{ MP_QSTR_phases, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 4} },
417419
};
418420
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
419421
mp_arg_parse_all(n_args, pos_args, kw_args,
@@ -442,6 +444,12 @@ static void mp_machine_encoder_init_helper(machine_encoder_obj_t *self,
442444
}
443445
}
444446

447+
// Get the Phases argument
448+
if ((args[ARG_phases].u_int != 1) && (args[ARG_phases].u_int != 2) && (args[ARG_phases].u_int != 4)) {
449+
mp_raise_ValueError(MP_ERROR_TEXT("invalid value for phases"));
450+
}
451+
self->phases = 4 / args[ARG_phases].u_int;
452+
445453
// Set the common options
446454
mp_machine_encoder_init_helper_common(self, args + ARG_match_pin, &self->enc_config);
447455

@@ -552,7 +560,7 @@ static mp_obj_t machine_encoder_value(size_t n_args, const mp_obj_t *args) {
552560
uint32_t actual_value = ENC_GetPositionValue(self->instance);
553561
if (n_args > 1) {
554562
// Set the encoder position value and clear the rev counter.
555-
uint32_t value = mp_obj_int_get_truncated(args[1]);
563+
uint32_t value = mp_obj_int_get_truncated(args[1]) * (4 / self->phases);
556564
clear_encoder_registers(self);
557565
// Set the position and rev register
558566
ENC_SetInitialPositionValue(self->instance, value);
@@ -562,9 +570,13 @@ static mp_obj_t machine_encoder_value(size_t n_args, const mp_obj_t *args) {
562570
}
563571
// Get the position as signed or unsigned 32 bit value.
564572
if (self->is_signed) {
565-
return mp_obj_new_int((int32_t)actual_value);
573+
int32_t value = (int32_t)actual_value;
574+
if (value < 0) {
575+
value -= (self->phases - 1);
576+
}
577+
return mp_obj_new_int(value / self->phases);
566578
} else {
567-
return mp_obj_new_int_from_uint(actual_value);
579+
return mp_obj_new_int_from_uint(actual_value / self->phases);
568580
}
569581
}
570582
static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_encoder_value_obj, 1, 2, machine_encoder_value);
@@ -776,9 +788,36 @@ static mp_obj_t machine_counter_init(size_t n_args, const mp_obj_t *args, mp_map
776788
}
777789
MP_DEFINE_CONST_FUN_OBJ_KW(machine_counter_init_obj, 1, machine_counter_init);
778790

791+
792+
// counter.value([value])
793+
static mp_obj_t machine_counter_value(size_t n_args, const mp_obj_t *args) {
794+
machine_encoder_obj_t *self = MP_OBJ_TO_PTR(args[0]);
795+
if (!self->active) {
796+
mp_raise_ValueError(MP_ERROR_TEXT("device stopped"));
797+
}
798+
uint32_t actual_value = ENC_GetPositionValue(self->instance);
799+
if (n_args > 1) {
800+
// Set the encoder position value and clear the rev counter.
801+
uint32_t value = mp_obj_int_get_truncated(args[1]);
802+
clear_encoder_registers(self);
803+
// Set the position and rev register
804+
ENC_SetInitialPositionValue(self->instance, value);
805+
ENC_DoSoftwareLoadInitialPositionValue(self->instance);
806+
// Reset the INIT Value
807+
ENC_SetInitialPositionValue(self->instance, 0);
808+
}
809+
// Get the position as signed or unsigned 32 bit value.
810+
if (self->is_signed) {
811+
return mp_obj_new_int((int32_t)actual_value);
812+
} else {
813+
return mp_obj_new_int_from_uint(actual_value);
814+
}
815+
}
816+
static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_counter_value_obj, 1, 2, machine_counter_value);
817+
779818
static const mp_rom_map_elem_t machine_counter_locals_dict_table[] = {
780819
{ MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&machine_encoder_deinit_obj) },
781-
{ MP_ROM_QSTR(MP_QSTR_value), MP_ROM_PTR(&machine_encoder_value_obj) },
820+
{ MP_ROM_QSTR(MP_QSTR_value), MP_ROM_PTR(&machine_counter_value_obj) },
782821
{ MP_ROM_QSTR(MP_QSTR_cycles), MP_ROM_PTR(&machine_encoder_cycles_obj) },
783822
{ MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&machine_counter_init_obj) },
784823
{ MP_ROM_QSTR(MP_QSTR_irq), MP_ROM_PTR(&machine_encoder_irq_obj) },

tests/extmod_hardware/machine_encoder.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@ def setUp(self):
4545
out0_pin(0)
4646
out1_pin(0)
4747
self.enc = Encoder(id, in0_pin, in1_pin, phases=1)
48-
self.pulses = 0 # track the expected encoder position in software
4948
self.pulses = start_value # track the expected encoder position in software
5049

5150
def tearDown(self):

0 commit comments

Comments
 (0)