From 2b07661ee64ef3ad40d9faac51403e0a23352662 Mon Sep 17 00:00:00 2001 From: Alon Bar-Lev Date: Sat, 9 Aug 2025 19:29:07 +0300 Subject: [PATCH] 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 --- ports/mimxrt/boards/make-pins.py | 17 ++++++++++++----- ports/mimxrt/boards/mimxrt_prefix.c | 5 +++-- ports/mimxrt/machine_adc.c | 22 ++++++++++++++++++++-- ports/mimxrt/pin.h | 1 + 4 files changed, 36 insertions(+), 9 deletions(-) diff --git a/ports/mimxrt/boards/make-pins.py b/ports/mimxrt/boards/make-pins.py index 55c7f5bd02..6ad60f0545 100644 --- a/ports/mimxrt/boards/make-pins.py +++ b/ports/mimxrt/boards/make-pins.py @@ -61,18 +61,23 @@ class MimxrtPin(boardgen.Pin): elif af_name == "ADC": adc_regex = r"ADC(?P\d*)_IN(?P\d*)" - lpadc_regex = r"ADC(?P\d*)_CH(?P\d*)" # LPADC for MIMXRT11xx chips + lpadc_regex = r"ADC(?P\d*)_CH(?P\d*)(?P.*)" # 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) diff --git a/ports/mimxrt/boards/mimxrt_prefix.c b/ports/mimxrt/boards/mimxrt_prefix.c index 49d6e67dc4..e6bba18b9f 100644 --- a/ports/mimxrt/boards/mimxrt_prefix.c +++ b/ports/mimxrt/boards/mimxrt_prefix.c @@ -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) \ diff --git a/ports/mimxrt/machine_adc.c b/ports/mimxrt/machine_adc.c index da5b20a8c7..1ebfe52861 100644 --- a/ports/mimxrt/machine_adc.c +++ b/ports/mimxrt/machine_adc.c @@ -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 diff --git a/ports/mimxrt/pin.h b/ports/mimxrt/pin.h index 7ee2841465..94cd3cad4d 100644 --- a/ports/mimxrt/pin.h +++ b/ports/mimxrt/pin.h @@ -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 {