mimxrt/machine_adc: Support ADC channel groups on rt117x.

The rt117x uses the LPADC peripheral which supports both A-side and B-side
channel inputs, e.g. ADC1_CH1A and ADC1_CH1B.

Previously, only `kLPADC_SampleChannelSingleEndSideA` was being used during
capture, while the pin may be in side B.  The fix in this commit detects
the side based on the pin configuration and sets `sampleChannelMode`
appropriately.

Signed-off-by: Alon Bar-Lev <alon.barlev@gmail.com>
This commit is contained in:
Alon Bar-Lev
2025-08-09 19:29:07 +03:00
committed by Damien George
parent 85e9d7596a
commit 2b07661ee6
4 changed files with 36 additions and 9 deletions

View File

@@ -61,18 +61,23 @@ class MimxrtPin(boardgen.Pin):
elif af_name == "ADC":
adc_regex = r"ADC(?P<instance>\d*)_IN(?P<channel>\d*)"
lpadc_regex = r"ADC(?P<instance>\d*)_CH(?P<channel>\d*)" # LPADC for MIMXRT11xx chips
lpadc_regex = r"ADC(?P<instance>\d*)_CH(?P<channel>\d*)(?P<channel_group>.*)" # LPADC for MIMXRT11xx chips
matches = re.finditer(adc_regex, af, re.MULTILINE)
for match in matches:
self._adc_fns.append(
(int(match.group("instance")), int(match.group("channel")), "ADC")
(int(match.group("instance")), int(match.group("channel")), 0, "ADC")
)
matches = re.finditer(lpadc_regex, af, re.MULTILINE)
for match in matches:
self._adc_fns.append(
(int(match.group("instance")), int(match.group("channel")), "LPADC")
(
int(match.group("instance")),
int(match.group("channel")),
ord(match.group("channel_group")[0]) - ord("A"),
"LPADC",
)
)
# Use the PIN() macro defined in samd_prefix.c for defining the pin
@@ -122,9 +127,11 @@ class MimxrtPin(boardgen.Pin):
"static const machine_pin_adc_obj_t pin_{:s}_adc[] = {{".format(self.name()),
file=out_source,
)
for instance, channel, peripheral in self._adc_fns:
for instance, channel, channel_group, peripheral in self._adc_fns:
print(
" PIN_ADC({:s}{:d}, {:d}),".format(peripheral, instance, channel),
" PIN_ADC({:s}{:d}, {:d}, {:d}),".format(
peripheral, instance, channel, channel_group
),
file=out_source,
)
print("};", file=out_source)

View File

@@ -16,10 +16,11 @@
.pad_config = (uint32_t)(_pad_config), \
} \
#define PIN_ADC(_instance, _channel) \
#define PIN_ADC(_instance, _channel, _channel_group) \
{ \
.instance = (_instance), \
.channel = (_channel) \
.channel = (_channel), \
.channel_group = (_channel_group), \
} \
#define PIN(_name, _gpio, _pin, _af_list, _adc_list_len, _adc_list) \

View File

@@ -64,7 +64,19 @@ static void mp_machine_adc_print(const mp_print_t *print, mp_obj_t self_in, mp_p
// Get ADC adc id
for (int i = 1; i < sizeof(adc_bases) / sizeof(ADC_Type *); ++i) {
if (adc_bases[i] == self->adc) {
mp_printf(print, "ADC(%u, channel=%u)", i, self->channel);
mp_printf(
print,
"ADC(%u, channel=%u"
#if defined(MIMXRT117x_SERIES)
", channel_input=%u"
#endif
")",
i,
self->channel
#if defined(MIMXRT117x_SERIES)
, self->channel_group
#endif
);
break;
}
}
@@ -83,12 +95,13 @@ static mp_obj_t mp_machine_adc_make_new(const mp_obj_type_t *type, size_t n_args
// Extract arguments
ADC_Type *adc_instance = pin->adc_list[0].instance; // NOTE: we only use the first ADC assignment - multiple assignments are not supported for now
uint8_t channel = pin->adc_list[0].channel;
uint8_t channel_group = pin->adc_list[0].channel_group;
// Create ADC Instance
machine_adc_obj_t *o = mp_obj_malloc(machine_adc_obj_t, &machine_adc_type);
o->adc = adc_instance;
o->channel = (uint8_t)channel;
o->channel_group = 0;
o->channel_group = channel_group;
o->resolution = 4096; // NOTE: currently only 12bit resolution supported
return MP_OBJ_FROM_PTR(o);
@@ -104,6 +117,11 @@ static mp_int_t mp_machine_adc_read_u16(machine_adc_obj_t *self) {
LPADC_GetDefaultConvCommandConfig(&adc_config);
adc_config.channelNumber = self->channel;
adc_config.sampleScaleMode = kLPADC_SamplePartScale;
if (self->channel_group == 0) {
adc_config.sampleChannelMode = kLPADC_SampleChannelSingleEndSideA;
} else {
adc_config.sampleChannelMode = kLPADC_SampleChannelSingleEndSideB;
}
LPADC_SetConvCommandConfig(self->adc, 1, &adc_config);
// Set Trigger mode

View File

@@ -117,6 +117,7 @@ typedef struct {
typedef struct {
ADC_Type *instance;
uint8_t channel;
uint8_t channel_group;
} machine_pin_adc_obj_t;
typedef struct {