Skip to content

Commit 4f2d497

Browse files
committed
mimxrt: Support Encoder/Counter for the MIMXRT117x family.
1 parent dd38eeb commit 4f2d497

File tree

2 files changed

+116
-19
lines changed

2 files changed

+116
-19
lines changed

ports/mimxrt/boards/make-pins.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,7 @@ def module_instance_factory(pins, output_file, name):
329329
if name == "FLEXPWM":
330330
output_file.write(f"#define {k} {k[-4:]}\n")
331331
if name == "XBAR":
332-
output_file.write(f"#define {k} {k}A1\n")
332+
output_file.write(f"#define {k} {k[:4]}A1\n")
333333
for i in v:
334334
output_file.write(i + "\n")
335335

ports/mimxrt/machine_encoder.c

Lines changed: 115 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ typedef struct _machine_encoder_obj_t {
4242
mp_obj_base_t base;
4343
ENC_Type *instance;
4444
int8_t id;
45+
bool active;
4546
uint8_t input_a;
4647
uint8_t input_b;
4748
uint8_t mode;
@@ -69,13 +70,6 @@ typedef struct _encoder_xbar_signal_t {
6970
#define ENCODER_TRIGGER_ROLL_UNDER (kENC_PositionRollUnderFlag)
7071
#define ENCODER_ALL_INTERRUPTS (0x7f)
7172

72-
#if !defined(XBAR_ENC_DIR_OFFSET)
73-
#define XBAR_ENC_DIR_OFFSET (12)
74-
#define XBAR_ENC_DIR_REGISTER GPR6
75-
#define XBAR_OUT_MIN (4)
76-
#define XBAR_OUT_MAX (19)
77-
#endif
78-
7973
#define XBAR_IN (1)
8074
#define XBAR_OUT (0)
8175

@@ -86,6 +80,58 @@ typedef struct _encoder_xbar_signal_t {
8680

8781
STATIC void encoder_deinit_single(machine_encoder_obj_t *self);
8882

83+
#if defined MIMXRT117x_SERIES
84+
85+
#define XBAR_ENC_DIR_OFFSET_1 (4)
86+
#define XBAR_ENC_DIR_REGISTER_1 GPR20
87+
#define XBAR_ENC_DIR_OFFSET_2 (32)
88+
#define XBAR_ENC_DIR_REGISTER_2 GPR21
89+
#define XBAR_OUT_MIN (4)
90+
#define XBAR_OUT_MAX (42)
91+
#define XBAR_STRING "XBAR1_INOUT"
92+
#define XBAR_STRING_LEN strlen(XBAR_STRING)
93+
94+
static encoder_xbar_signal_t xbar_signal_table[FSL_FEATURE_SOC_ENC_COUNT] = {
95+
{ kXBARA1_OutputDec1Phasea,
96+
kXBARA1_OutputDec1Phaseb,
97+
kXBARA1_OutputDec1Index,
98+
kXBARA1_OutputDec1Home,
99+
kXBARA1_OutputDec1Trigger,
100+
kXBARA1_InputDec1PosMatch },
101+
102+
{ kXBARA1_OutputDec2Phasea,
103+
kXBARA1_OutputDec2Phaseb,
104+
kXBARA1_OutputDec2Index,
105+
kXBARA1_OutputDec2Home,
106+
kXBARA1_OutputDec2Trigger,
107+
kXBARA1_InputDec2PosMatch },
108+
109+
{ kXBARA1_OutputDec3Phasea,
110+
kXBARA1_OutputDec3Phaseb,
111+
kXBARA1_OutputDec3Index,
112+
kXBARA1_OutputDec3Home,
113+
kXBARA1_OutputDec3Trigger,
114+
kXBARA1_InputDec3PosMatch },
115+
116+
{ kXBARA1_OutputDec4Phasea,
117+
kXBARA1_OutputDec4Phaseb,
118+
kXBARA1_OutputDec4Index,
119+
kXBARA1_OutputDec4Home,
120+
kXBARA1_OutputDec4Trigger,
121+
kXBARA1_InputDec4PosMatch },
122+
};
123+
124+
#else // defined MIMXRT117x_SERIES
125+
126+
#if !defined(XBAR_ENC_DIR_OFFSET)
127+
#define XBAR_ENC_DIR_OFFSET (12)
128+
#define XBAR_ENC_DIR_REGISTER GPR6
129+
#define XBAR_OUT_MIN (4)
130+
#define XBAR_OUT_MAX (19)
131+
#endif
132+
#define XBAR_STRING "XBAR_INOUT"
133+
#define XBAR_STRING_LEN strlen(XBAR_STRING)
134+
89135
static encoder_xbar_signal_t xbar_signal_table[FSL_FEATURE_SOC_ENC_COUNT] = {
90136
{ kXBARA1_OutputEnc1PhaseAInput,
91137
kXBARA1_OutputEnc1PhaseBInput,
@@ -122,6 +168,7 @@ static encoder_xbar_signal_t xbar_signal_table[FSL_FEATURE_SOC_ENC_COUNT] = {
122168
#endif
123169
#endif
124170
};
171+
#endif // defined MIMXRT117x_SERIES
125172

126173
static machine_encoder_obj_t *encoder_table[FSL_FEATURE_SOC_ENC_COUNT];
127174
static ENC_Type *enc_instances[] = ENC_BASE_PTRS;
@@ -185,13 +232,14 @@ STATIC const machine_pin_af_obj_t *af_name_decode_xbar(const machine_pin_af_obj_
185232
xbar_input_signal_t *io_number) {
186233
const char *str;
187234
size_t len;
235+
size_t xlen = XBAR_STRING_LEN;
188236
str = (char *)qstr_data(af_obj->name, &len);
189-
// test for the name starting with XBAR_INOUT
190-
if (len < 12 || strncmp(str, "XBAR_INOUT", 10) != 0) {
237+
// test for the name starting with XBAR
238+
if (len < (xlen + 2) || strncmp(str, XBAR_STRING, xlen) != 0) {
191239
return NULL;
192240
}
193241
// Get I/O number, e.g. XBAR_INOUT03
194-
*io_number = (str[10] - '0') * 10 + (str[11] - '0');
242+
*io_number = (str[xlen] - '0') * 10 + (str[xlen + 1] - '0');
195243
return af_obj;
196244
}
197245

@@ -215,12 +263,26 @@ STATIC uint8_t connect_pin_to_encoder(mp_obj_t desc, xbar_output_signal_t encode
215263
XBARA_SetSignalsConnection(XBARA1, xbar_pin, encoder_signal);
216264
} else {
217265
// No API here, so do basic Register access.
266+
#if defined MIMXRT117x_SERIES
267+
if (xbar_pin >= XBAR_OUT_MIN && xbar_pin <= XBAR_OUT_MAX) {
268+
if (xbar_pin < XBAR_ENC_DIR_OFFSET_2) {
269+
IOMUXC_GPR->XBAR_ENC_DIR_REGISTER_1 |= 1 << (xbar_pin - XBAR_ENC_DIR_OFFSET_1);
270+
XBARA_SetSignalsConnection(XBARA1, encoder_signal, xbar_pin);
271+
} else {
272+
IOMUXC_GPR->XBAR_ENC_DIR_REGISTER_2 |= 1 << (xbar_pin - XBAR_ENC_DIR_OFFSET_2);
273+
XBARA_SetSignalsConnection(XBARA1, encoder_signal, xbar_pin);
274+
}
275+
} else {
276+
mp_raise_ValueError(MP_ERROR_TEXT("invalid match Pin"));
277+
}
278+
#else
218279
if (xbar_pin >= XBAR_OUT_MIN && xbar_pin <= XBAR_OUT_MAX) {
219280
IOMUXC_GPR->XBAR_ENC_DIR_REGISTER |= 1 << (xbar_pin + XBAR_ENC_DIR_OFFSET); // Compare the offset 12 with other MCU
220281
XBARA_SetSignalsConnection(XBARA1, encoder_signal, xbar_pin);
221282
} else {
222283
mp_raise_ValueError(MP_ERROR_TEXT("invalid match Pin"));
223284
}
285+
#endif // defined MIMXRT117x_SERIES
224286
}
225287
return xbar_pin;
226288
}
@@ -239,7 +301,12 @@ STATIC void clear_encoder_registers(machine_encoder_obj_t *self) {
239301
//
240302
STATIC uint32_t calc_filter(uint32_t filter_ns, uint16_t *count, uint16_t *period) {
241303

304+
#if defined MIMXRT117x_SERIES
305+
uint32_t freq_khz = CLOCK_GetRootClockFreq(kCLOCK_Root_Bus) / 1000;
306+
#else
242307
uint32_t freq_khz = CLOCK_GetIpgFreq() / 1000;
308+
#endif
309+
243310
uint32_t cycles = (filter_ns * (freq_khz / 1000)) / 1000;
244311
if (cycles == 0) {
245312
// Set filter off
@@ -277,7 +344,15 @@ STATIC void mp_machine_encoder_init_helper_common(machine_encoder_obj_t *self,
277344
self->match_pin = connect_pin_to_encoder(args[ARG_match_pin].u_obj, xbar_signal_table[self->id].enc_match, XBAR_OUT);
278345
} else {
279346
// Disconnect the XBAR from the output by switching it to an input.
347+
#if defined MIMXRT117x_SERIES
348+
if (self->match_pin < XBAR_ENC_DIR_OFFSET_2) {
349+
IOMUXC_GPR->XBAR_ENC_DIR_REGISTER_1 &= ~(1 << (self->match_pin - XBAR_ENC_DIR_OFFSET_1));
350+
} else {
351+
IOMUXC_GPR->XBAR_ENC_DIR_REGISTER_2 &= ~(1 << (self->match_pin - XBAR_ENC_DIR_OFFSET_2));
352+
}
353+
#else
280354
IOMUXC_GPR->XBAR_ENC_DIR_REGISTER &= ~(1 << (self->match_pin + XBAR_ENC_DIR_OFFSET));
355+
#endif
281356
}
282357
}
283358

@@ -321,6 +396,7 @@ STATIC void mp_machine_encoder_init_helper_common(machine_encoder_obj_t *self,
321396
ENC_Init(self->instance, enc_config);
322397
clear_encoder_registers(self);
323398
ENC_ClearStatusFlags(self->instance, 0xff); // Clear all status flags
399+
self->active = true;
324400
}
325401

326402
STATIC void mp_machine_encoder_init_helper(machine_encoder_obj_t *self,
@@ -420,15 +496,26 @@ STATIC mp_obj_t mp_machine_encoder_make_new(const mp_obj_type_t *type, size_t n_
420496
}
421497

422498
STATIC void encoder_deinit_single(machine_encoder_obj_t *self) {
423-
if (self->irq->handler) {
424-
DisableIRQ(enc_irqn[self->id + 1]);
425-
ENC_DisableInterrupts(self->instance, ENCODER_ALL_INTERRUPTS);
426-
}
427-
if (self->match_pin != 0) {
428-
// Disconnect the XBAR from the output by switching it to an input.
429-
IOMUXC_GPR->XBAR_ENC_DIR_REGISTER &= ~(1 << (self->match_pin + XBAR_ENC_DIR_OFFSET));
499+
if (self->active) {
500+
if (self->irq && self->irq->handler) {
501+
DisableIRQ(enc_irqn[self->id + 1]);
502+
ENC_DisableInterrupts(self->instance, ENCODER_ALL_INTERRUPTS);
503+
}
504+
if (self->match_pin != 0) {
505+
// Disconnect the XBAR from the output by switching it to an input.
506+
#if defined MIMXRT117x_SERIES
507+
if (self->match_pin < XBAR_ENC_DIR_OFFSET_2) {
508+
IOMUXC_GPR->XBAR_ENC_DIR_REGISTER_1 &= ~(1 << (self->match_pin - XBAR_ENC_DIR_OFFSET_1));
509+
} else {
510+
IOMUXC_GPR->XBAR_ENC_DIR_REGISTER_2 &= ~(1 << (self->match_pin - XBAR_ENC_DIR_OFFSET_2));
511+
}
512+
#else
513+
IOMUXC_GPR->XBAR_ENC_DIR_REGISTER &= ~(1 << (self->match_pin + XBAR_ENC_DIR_OFFSET));
514+
#endif
515+
}
516+
ENC_Deinit(self->instance);
430517
}
431-
ENC_Deinit(self->instance);
518+
self->active = false;
432519
}
433520

434521
// encoder_deinit_all()
@@ -458,6 +545,9 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_encoder_status_obj, machine_encoder_sta
458545
// encoder.value([value])
459546
STATIC mp_obj_t machine_encoder_value(size_t n_args, const mp_obj_t *args) {
460547
machine_encoder_obj_t *self = MP_OBJ_TO_PTR(args[0]);
548+
if (!self->active) {
549+
mp_raise_ValueError(MP_ERROR_TEXT("device stopped"));
550+
}
461551
uint32_t actual_value = ENC_GetPositionValue(self->instance);
462552
if (n_args > 1) {
463553
// Set the encoder position value and clear the rev counter.
@@ -481,6 +571,10 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_encoder_value_obj, 1, 2, mach
481571
// encoder.cycles([value])
482572
STATIC mp_obj_t machine_encoder_cycles(size_t n_args, const mp_obj_t *args) {
483573
machine_encoder_obj_t *self = MP_OBJ_TO_PTR(args[0]);
574+
if (!self->active) {
575+
mp_raise_ValueError(MP_ERROR_TEXT("device stopped"));
576+
}
577+
484578
int16_t cycles = (int16_t)ENC_GetRevolutionValue(self->instance);
485579
if (n_args > 1) {
486580
// Set the revolution value
@@ -502,6 +596,9 @@ STATIC mp_obj_t machine_encoder_irq(size_t n_args, const mp_obj_t *pos_args, mp_
502596
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
503597
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
504598
machine_encoder_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
599+
if (!self->active) {
600+
mp_raise_ValueError(MP_ERROR_TEXT("device stopped"));
601+
}
505602

506603
if (self->irq == NULL) {
507604
self->irq = m_new_obj(mp_irq_obj_t);

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