summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/library/machine.ADCBlock.rst9
-rw-r--r--extmod/extmod.cmake1
-rw-r--r--extmod/extmod.mk1
-rw-r--r--extmod/machine_adc_block.c128
-rw-r--r--extmod/modmachine.h2
-rw-r--r--ports/esp32/adc.c92
-rw-r--r--ports/esp32/adc.h60
-rw-r--r--ports/esp32/esp32_common.cmake2
-rw-r--r--ports/esp32/machine_adc.c10
-rw-r--r--ports/esp32/machine_adc.h16
-rw-r--r--ports/esp32/machine_adc_block.c72
-rw-r--r--ports/esp32/machine_adcblock.c204
-rw-r--r--ports/esp32/machine_adcblock.h22
-rw-r--r--ports/esp32/modmachine.c4
-rw-r--r--ports/esp32/modmachine.h1
-rw-r--r--ports/esp32/mpconfigport.h3
-rw-r--r--ports/renesas-ra/modmachine.h1
17 files changed, 371 insertions, 257 deletions
diff --git a/docs/library/machine.ADCBlock.rst b/docs/library/machine.ADCBlock.rst
index 56a468dd6..eb94362d5 100644
--- a/docs/library/machine.ADCBlock.rst
+++ b/docs/library/machine.ADCBlock.rst
@@ -39,9 +39,9 @@ Methods
Configure the ADC peripheral. *bits* will set the resolution of the
conversion process.
-.. method:: ADCBlock.connect(channel)
- ADCBlock.connect(source)
- ADCBlock.connect(channel, source)
+.. method:: ADCBlock.connect(channel, *, ...)
+ ADCBlock.connect(source, *, ...)
+ ADCBlock.connect(channel, source, *, ...)
Connect up a channel on the ADC peripheral so it is ready for sampling,
and return an :ref:`ADC <machine.ADC>` object that represents that connection.
@@ -56,3 +56,6 @@ Methods
If both *channel* and *source* are given then they are connected together
and made ready for sampling.
+
+ Any additional keyword arguments are used to configure the returned ADC object,
+ via its :meth:`init <machine.ADC.init>` method.
diff --git a/extmod/extmod.cmake b/extmod/extmod.cmake
index a1a0a9f73..5bfdf6551 100644
--- a/extmod/extmod.cmake
+++ b/extmod/extmod.cmake
@@ -8,6 +8,7 @@ set(MICROPY_SOURCE_EXTMOD
${MICROPY_DIR}/shared/libc/printf.c
${MICROPY_EXTMOD_DIR}/btstack/modbluetooth_btstack.c
${MICROPY_EXTMOD_DIR}/machine_adc.c
+ ${MICROPY_EXTMOD_DIR}/machine_adc_block.c
${MICROPY_EXTMOD_DIR}/machine_bitstream.c
${MICROPY_EXTMOD_DIR}/machine_i2c.c
${MICROPY_EXTMOD_DIR}/machine_i2s.c
diff --git a/extmod/extmod.mk b/extmod/extmod.mk
index c4b2c3d9c..a04856bce 100644
--- a/extmod/extmod.mk
+++ b/extmod/extmod.mk
@@ -3,6 +3,7 @@
SRC_EXTMOD_C += \
extmod/machine_adc.c \
+ extmod/machine_adc_block.c \
extmod/machine_bitstream.c \
extmod/machine_i2c.c \
extmod/machine_i2s.c \
diff --git a/extmod/machine_adc_block.c b/extmod/machine_adc_block.c
new file mode 100644
index 000000000..f80e2dae4
--- /dev/null
+++ b/extmod/machine_adc_block.c
@@ -0,0 +1,128 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2021 Jonathan Hogg
+ * Copyright (c) 2023 Damien P. George
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "py/runtime.h"
+
+#if MICROPY_PY_MACHINE_ADC_BLOCK
+
+#include "py/mphal.h"
+#include "extmod/modmachine.h"
+
+// The port must provide implementations of these low-level ADCBlock functions.
+STATIC void mp_machine_adc_block_print(const mp_print_t *print, machine_adc_block_obj_t *self);
+STATIC machine_adc_block_obj_t *mp_machine_adc_block_get(mp_int_t unit);
+STATIC void mp_machine_adc_block_bits_set(machine_adc_block_obj_t *self, mp_int_t bits);
+STATIC machine_adc_obj_t *mp_machine_adc_block_connect(machine_adc_block_obj_t *self, mp_int_t channel_id, mp_hal_pin_obj_t pin, mp_map_t *kw_args);
+
+// The port provides implementations of the above in this file.
+#include MICROPY_PY_MACHINE_ADC_BLOCK_INCLUDEFILE
+
+STATIC void machine_adc_block_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
+ machine_adc_block_obj_t *self = MP_OBJ_TO_PTR(self_in);
+ mp_machine_adc_block_print(print, self);
+}
+
+STATIC void machine_adc_block_init_helper(machine_adc_block_obj_t *self, size_t n_pos_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
+ enum {
+ ARG_bits,
+ };
+
+ static const mp_arg_t allowed_args[] = {
+ { MP_QSTR_bits, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -1} },
+ };
+
+ mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
+ mp_arg_parse_all(n_pos_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
+
+ mp_int_t bits = args[ARG_bits].u_int;
+ mp_machine_adc_block_bits_set(self, bits);
+}
+
+STATIC mp_obj_t machine_adc_block_make_new(const mp_obj_type_t *type, size_t n_pos_args, size_t n_kw_args, const mp_obj_t *args) {
+ mp_arg_check_num(n_pos_args, n_kw_args, 1, MP_OBJ_FUN_ARGS_MAX, true);
+ mp_int_t unit = mp_obj_get_int(args[0]);
+ machine_adc_block_obj_t *self = mp_machine_adc_block_get(unit);
+ if (self == NULL) {
+ mp_raise_ValueError(MP_ERROR_TEXT("invalid block id"));
+ }
+
+ mp_map_t kw_args;
+ mp_map_init_fixed_table(&kw_args, n_kw_args, args + n_pos_args);
+ machine_adc_block_init_helper(self, n_pos_args - 1, args + 1, &kw_args);
+
+ return MP_OBJ_FROM_PTR(self);
+}
+
+STATIC mp_obj_t machine_adc_block_init(size_t n_pos_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
+ machine_adc_block_obj_t *self = pos_args[0];
+ machine_adc_block_init_helper(self, n_pos_args - 1, pos_args + 1, kw_args);
+ return mp_const_none;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_KW(machine_adc_block_init_obj, 1, machine_adc_block_init);
+
+STATIC mp_obj_t machine_adc_block_connect(size_t n_pos_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
+ machine_adc_block_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
+ mp_int_t channel_id = -1;
+ mp_hal_pin_obj_t pin = -1;
+ if (n_pos_args == 2) {
+ if (mp_obj_is_int(pos_args[1])) {
+ channel_id = mp_obj_get_int(pos_args[1]);
+ } else {
+ pin = mp_hal_get_pin_obj(pos_args[1]);
+ }
+ } else if (n_pos_args == 3) {
+ channel_id = mp_obj_get_int(pos_args[1]);
+ pin = mp_hal_get_pin_obj(pos_args[2]);
+ } else {
+ mp_raise_TypeError(MP_ERROR_TEXT("too many positional args"));
+ }
+
+ machine_adc_obj_t *adc = mp_machine_adc_block_connect(self, channel_id, pin, kw_args);
+ if (adc == NULL) {
+ mp_raise_ValueError(MP_ERROR_TEXT("no matching ADC"));
+ }
+
+ return MP_OBJ_FROM_PTR(adc);
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_KW(machine_adc_block_connect_obj, 2, machine_adc_block_connect);
+
+STATIC const mp_rom_map_elem_t machine_adc_block_locals_dict_table[] = {
+ { MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&machine_adc_block_init_obj) },
+ { MP_ROM_QSTR(MP_QSTR_connect), MP_ROM_PTR(&machine_adc_block_connect_obj) },
+};
+STATIC MP_DEFINE_CONST_DICT(machine_adc_block_locals_dict, machine_adc_block_locals_dict_table);
+
+MP_DEFINE_CONST_OBJ_TYPE(
+ machine_adc_block_type,
+ MP_QSTR_ADCBlock,
+ MP_TYPE_FLAG_NONE,
+ make_new, machine_adc_block_make_new,
+ print, machine_adc_block_print,
+ locals_dict, &machine_adc_block_locals_dict
+ );
+
+#endif // MICROPY_PY_MACHINE_ADC_BLOCK
diff --git a/extmod/modmachine.h b/extmod/modmachine.h
index 6cace4f85..0744ef788 100644
--- a/extmod/modmachine.h
+++ b/extmod/modmachine.h
@@ -128,6 +128,7 @@
// A port must provide these types, but they are otherwise opaque.
typedef struct _machine_adc_obj_t machine_adc_obj_t;
+typedef struct _machine_adc_block_obj_t machine_adc_block_obj_t;
typedef struct _machine_i2s_obj_t machine_i2s_obj_t;
typedef struct _machine_pwm_obj_t machine_pwm_obj_t;
typedef struct _machine_uart_obj_t machine_uart_obj_t;
@@ -200,6 +201,7 @@ extern const machine_mem_obj_t machine_mem32_obj;
// Their Python bindings are implemented in extmod, and their implementation
// is provided by a port.
extern const mp_obj_type_t machine_adc_type;
+extern const mp_obj_type_t machine_adc_block_type;
extern const mp_obj_type_t machine_i2c_type;
extern const mp_obj_type_t machine_i2s_type;
extern const mp_obj_type_t machine_mem_type;
diff --git a/ports/esp32/adc.c b/ports/esp32/adc.c
new file mode 100644
index 000000000..c5886624e
--- /dev/null
+++ b/ports/esp32/adc.c
@@ -0,0 +1,92 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2017 Nick Moore
+ * Copyright (c) 2021 Jonathan Hogg
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "py/mphal.h"
+#include "adc.h"
+#include "driver/adc.h"
+
+#define DEFAULT_VREF 1100
+
+void madcblock_bits_helper(machine_adc_block_obj_t *self, mp_int_t bits) {
+ switch (bits) {
+ #if CONFIG_IDF_TARGET_ESP32
+ case 9:
+ self->width = ADC_WIDTH_BIT_9;
+ break;
+ case 10:
+ self->width = ADC_WIDTH_BIT_10;
+ break;
+ case 11:
+ self->width = ADC_WIDTH_BIT_11;
+ break;
+ #endif
+ #if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3
+ case 12:
+ self->width = ADC_WIDTH_BIT_12;
+ break;
+ #endif
+ #if CONFIG_IDF_TARGET_ESP32S2
+ case 13:
+ self->width = ADC_WIDTH_BIT_13;
+ break;
+ #endif
+ default:
+ mp_raise_ValueError(MP_ERROR_TEXT("invalid bits"));
+ }
+ self->bits = bits;
+
+ if (self->unit_id == ADC_UNIT_1) {
+ adc1_config_width(self->width);
+ }
+ for (adc_atten_t atten = ADC_ATTEN_DB_0; atten < ADC_ATTEN_MAX; atten++) {
+ if (self->characteristics[atten] != NULL) {
+ esp_adc_cal_characterize(self->unit_id, atten, self->width, DEFAULT_VREF, self->characteristics[atten]);
+ }
+ }
+}
+
+mp_int_t madcblock_read_helper(machine_adc_block_obj_t *self, adc_channel_t channel_id) {
+ int raw;
+ if (self->unit_id == ADC_UNIT_1) {
+ raw = adc1_get_raw(channel_id);
+ } else {
+ check_esp_err(adc2_get_raw(channel_id, self->width, &raw));
+ }
+ return raw;
+}
+
+mp_int_t madcblock_read_uv_helper(machine_adc_block_obj_t *self, adc_channel_t channel_id, adc_atten_t atten) {
+ int raw = madcblock_read_helper(self, channel_id);
+ esp_adc_cal_characteristics_t *adc_chars = self->characteristics[atten];
+ if (adc_chars == NULL) {
+ adc_chars = malloc(sizeof(esp_adc_cal_characteristics_t));
+ esp_adc_cal_characterize(self->unit_id, atten, self->width, DEFAULT_VREF, adc_chars);
+ self->characteristics[atten] = adc_chars;
+ }
+ mp_int_t uv = esp_adc_cal_raw_to_voltage(raw, adc_chars) * 1000;
+ return uv;
+}
diff --git a/ports/esp32/adc.h b/ports/esp32/adc.h
new file mode 100644
index 000000000..ae5c0d3c3
--- /dev/null
+++ b/ports/esp32/adc.h
@@ -0,0 +1,60 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * Development of the code in this file was sponsored by Microbric Pty Ltd
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2023 Damien P. George
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#ifndef MICROPY_INCLUDED_ESP32_ADC_H
+#define MICROPY_INCLUDED_ESP32_ADC_H
+
+#include "py/runtime.h"
+#include "esp_adc_cal.h"
+
+#define ADC_ATTEN_MAX SOC_ADC_ATTEN_NUM
+
+typedef struct _machine_adc_block_obj_t {
+ mp_obj_base_t base;
+ adc_unit_t unit_id;
+ mp_int_t bits;
+ adc_bits_width_t width;
+ esp_adc_cal_characteristics_t *characteristics[ADC_ATTEN_MAX];
+} machine_adc_block_obj_t;
+
+typedef struct _machine_adc_obj_t {
+ mp_obj_base_t base;
+ machine_adc_block_obj_t *block;
+ adc_channel_t channel_id;
+ gpio_num_t gpio_id;
+} machine_adc_obj_t;
+
+extern machine_adc_block_obj_t madcblock_obj[];
+
+void madcblock_bits_helper(machine_adc_block_obj_t *self, mp_int_t bits);
+mp_int_t madcblock_read_helper(machine_adc_block_obj_t *self, adc_channel_t channel_id);
+mp_int_t madcblock_read_uv_helper(machine_adc_block_obj_t *self, adc_channel_t channel_id, adc_atten_t atten);
+
+const machine_adc_obj_t *madc_search_helper(machine_adc_block_obj_t *block, adc_channel_t channel_id, gpio_num_t gpio_id);
+void madc_init_helper(const machine_adc_obj_t *self, size_t n_pos_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
+
+#endif // MICROPY_INCLUDED_ESP32_ADC_H
diff --git a/ports/esp32/esp32_common.cmake b/ports/esp32/esp32_common.cmake
index f66c59e34..40ae98822 100644
--- a/ports/esp32/esp32_common.cmake
+++ b/ports/esp32/esp32_common.cmake
@@ -53,6 +53,7 @@ list(APPEND MICROPY_SOURCE_DRIVERS
)
list(APPEND MICROPY_SOURCE_PORT
+ adc.c
main.c
ppp_set_auth.c
uart.c
@@ -66,7 +67,6 @@ list(APPEND MICROPY_SOURCE_PORT
machine_timer.c
machine_pin.c
machine_touchpad.c
- machine_adcblock.c
machine_dac.c
machine_i2c.c
modmachine.c
diff --git a/ports/esp32/machine_adc.c b/ports/esp32/machine_adc.c
index 42746cb4b..b5233e4dd 100644
--- a/ports/esp32/machine_adc.c
+++ b/ports/esp32/machine_adc.c
@@ -28,13 +28,9 @@
// This file is never compiled standalone, it's included directly from
// extmod/machine_adc.c via MICROPY_PY_MACHINE_ADC_INCLUDEFILE.
-#include "esp_log.h"
-
-#include "driver/gpio.h"
-#include "driver/adc.h"
-
#include "py/mphal.h"
-#include "machine_adc.h"
+#include "adc.h"
+#include "driver/adc.h"
#define ADCBLOCK1 (&madcblock_obj[0])
#define ADCBLOCK2 (&madcblock_obj[1])
@@ -136,7 +132,7 @@ static inline void madc_atten_set(const machine_adc_obj_t *self, adc_atten_t att
madc_obj_atten[self - &madc_obj[0]] = atten + 1;
}
-const machine_adc_obj_t *madc_search_helper(madcblock_obj_t *block, adc_channel_t channel_id, gpio_num_t gpio_id) {
+const machine_adc_obj_t *madc_search_helper(machine_adc_block_obj_t *block, adc_channel_t channel_id, gpio_num_t gpio_id) {
for (int i = 0; i < MP_ARRAY_SIZE(madc_obj); i++) {
const machine_adc_obj_t *adc = &madc_obj[i];
if ((block == NULL || block == adc->block) && (channel_id == -1 || channel_id == adc->channel_id) && (gpio_id == -1 || gpio_id == adc->gpio_id)) {
diff --git a/ports/esp32/machine_adc.h b/ports/esp32/machine_adc.h
deleted file mode 100644
index 6d06486c3..000000000
--- a/ports/esp32/machine_adc.h
+++ /dev/null
@@ -1,16 +0,0 @@
-#ifndef MICROPY_INCLUDED_MACHINE_ADC_H
-#define MICROPY_INCLUDED_MACHINE_ADC_H
-
-#include "machine_adcblock.h"
-
-typedef struct _machine_adc_obj_t {
- mp_obj_base_t base;
- madcblock_obj_t *block;
- adc_channel_t channel_id;
- gpio_num_t gpio_id;
-} machine_adc_obj_t;
-
-const machine_adc_obj_t *madc_search_helper(madcblock_obj_t *block, adc_channel_t channel_id, gpio_num_t gpio_id);
-void madc_init_helper(const machine_adc_obj_t *self, size_t n_pos_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
-
-#endif // MICROPY_INCLUDED_MACHINE_ADC_H
diff --git a/ports/esp32/machine_adc_block.c b/ports/esp32/machine_adc_block.c
new file mode 100644
index 000000000..f2975ff2f
--- /dev/null
+++ b/ports/esp32/machine_adc_block.c
@@ -0,0 +1,72 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2021 Jonathan Hogg
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+// This file is never compiled standalone, it's included directly from
+// extmod/machine_adc_block.c via MICROPY_PY_MACHINE_ADC_BLOCK_INCLUDEFILE.
+
+#include "py/mphal.h"
+#include "adc.h"
+#include "driver/adc.h"
+
+machine_adc_block_obj_t madcblock_obj[] = {
+ #if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3
+ {{&machine_adc_block_type}, ADC_UNIT_1, 12, -1, {0}},
+ {{&machine_adc_block_type}, ADC_UNIT_2, 12, -1, {0}},
+ #elif CONFIG_IDF_TARGET_ESP32S2
+ {{&machine_adc_block_type}, ADC_UNIT_1, 13, -1, {0}},
+ {{&machine_adc_block_type}, ADC_UNIT_2, 13, -1, {0}},
+ #endif
+};
+
+STATIC void mp_machine_adc_block_print(const mp_print_t *print, machine_adc_block_obj_t *self) {
+ mp_printf(print, "ADCBlock(%u, bits=%u)", self->unit_id, self->bits);
+}
+
+STATIC void mp_machine_adc_block_bits_set(machine_adc_block_obj_t *self, mp_int_t bits) {
+ if (bits != -1) {
+ madcblock_bits_helper(self, bits);
+ } else if (self->width == -1) {
+ madcblock_bits_helper(self, self->bits);
+ }
+}
+
+STATIC machine_adc_block_obj_t *mp_machine_adc_block_get(mp_int_t unit) {
+ for (int i = 0; i < MP_ARRAY_SIZE(madcblock_obj); i++) {
+ if (unit == madcblock_obj[i].unit_id) {
+ return &madcblock_obj[i];
+ }
+ }
+ return NULL;
+}
+
+STATIC machine_adc_obj_t *mp_machine_adc_block_connect(machine_adc_block_obj_t *self, mp_int_t channel_id, mp_hal_pin_obj_t gpio_id, mp_map_t *kw_args) {
+ const machine_adc_obj_t *adc = madc_search_helper(self, channel_id, gpio_id);
+ if (adc == NULL) {
+ return NULL;
+ }
+ madc_init_helper(adc, 0, NULL, kw_args);
+ return (machine_adc_obj_t *)adc;
+}
diff --git a/ports/esp32/machine_adcblock.c b/ports/esp32/machine_adcblock.c
deleted file mode 100644
index 8d5296e2e..000000000
--- a/ports/esp32/machine_adcblock.c
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- * This file is part of the MicroPython project, http://micropython.org/
- *
- * The MIT License (MIT)
- *
- * Copyright (c) 2021 Jonathan Hogg
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include <stdio.h>
-
-#include "esp_log.h"
-
-#include "driver/gpio.h"
-#include "driver/adc.h"
-
-#include "py/runtime.h"
-#include "py/mphal.h"
-#include "modmachine.h"
-#include "machine_adc.h"
-#include "machine_adcblock.h"
-
-#define DEFAULT_VREF 1100
-
-madcblock_obj_t madcblock_obj[] = {
- #if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3
- {{&machine_adcblock_type}, ADC_UNIT_1, 12, -1, {0}},
- {{&machine_adcblock_type}, ADC_UNIT_2, 12, -1, {0}},
- #elif CONFIG_IDF_TARGET_ESP32S2
- {{&machine_adcblock_type}, ADC_UNIT_1, 13, -1, {0}},
- {{&machine_adcblock_type}, ADC_UNIT_2, 13, -1, {0}},
- #endif
-};
-
-STATIC void madcblock_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
- madcblock_obj_t *self = MP_OBJ_TO_PTR(self_in);
- mp_printf(print, "ADCBlock(%u, bits=%u)", self->unit_id, self->bits);
-}
-
-void madcblock_bits_helper(madcblock_obj_t *self, mp_int_t bits) {
- switch (bits) {
- #if CONFIG_IDF_TARGET_ESP32
- case 9:
- self->width = ADC_WIDTH_BIT_9;
- break;
- case 10:
- self->width = ADC_WIDTH_BIT_10;
- break;
- case 11:
- self->width = ADC_WIDTH_BIT_11;
- break;
- #endif
- #if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3
- case 12:
- self->width = ADC_WIDTH_BIT_12;
- break;
- #endif
- #if CONFIG_IDF_TARGET_ESP32S2
- case 13:
- self->width = ADC_WIDTH_BIT_13;
- break;
- #endif
- default:
- mp_raise_ValueError(MP_ERROR_TEXT("invalid bits"));
- }
- self->bits = bits;
-
- if (self->unit_id == ADC_UNIT_1) {
- adc1_config_width(self->width);
- }
- for (adc_atten_t atten = ADC_ATTEN_DB_0; atten < ADC_ATTEN_MAX; atten++) {
- if (self->characteristics[atten] != NULL) {
- esp_adc_cal_characterize(self->unit_id, atten, self->width, DEFAULT_VREF, self->characteristics[atten]);
- }
- }
-}
-
-STATIC void madcblock_init_helper(madcblock_obj_t *self, size_t n_pos_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
- enum {
- ARG_bits,
- };
-
- static const mp_arg_t allowed_args[] = {
- { MP_QSTR_bits, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = -1} },
- };
-
- mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
- mp_arg_parse_all(n_pos_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
-
- mp_int_t bits = args[ARG_bits].u_int;
- if (bits != -1) {
- madcblock_bits_helper(self, bits);
- } else if (self->width == -1) {
- madcblock_bits_helper(self, self->bits);
- }
-}
-
-STATIC mp_obj_t madcblock_make_new(const mp_obj_type_t *type, size_t n_pos_args, size_t n_kw_args, const mp_obj_t *args) {
- mp_arg_check_num(n_pos_args, n_kw_args, 1, MP_OBJ_FUN_ARGS_MAX, true);
- adc_unit_t unit = mp_obj_get_int(args[0]);
- madcblock_obj_t *self = NULL;
- for (int i = 0; i < MP_ARRAY_SIZE(madcblock_obj); i++) {
- if (unit == madcblock_obj[i].unit_id) {
- self = &madcblock_obj[i];
- break;
- }
- }
- if (!self) {
- mp_raise_ValueError(MP_ERROR_TEXT("invalid block id"));
- }
-
- mp_map_t kw_args;
- mp_map_init_fixed_table(&kw_args, n_kw_args, args + n_pos_args);
- madcblock_init_helper(self, n_pos_args - 1, args + 1, &kw_args);
-
- return MP_OBJ_FROM_PTR(self);
-}
-
-STATIC mp_obj_t madcblock_init(size_t n_pos_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
- madcblock_obj_t *self = pos_args[0];
- madcblock_init_helper(self, n_pos_args - 1, pos_args + 1, kw_args);
- return mp_const_none;
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_KW(madcblock_init_obj, 1, madcblock_init);
-
-STATIC mp_obj_t madcblock_connect(size_t n_pos_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
- madcblock_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
- adc_channel_t channel_id = -1;
- gpio_num_t gpio_id = -1;
- if (n_pos_args == 2) {
- if (mp_obj_is_int(pos_args[1])) {
- channel_id = mp_obj_get_int(pos_args[1]);
- } else {
- gpio_id = machine_pin_get_id(pos_args[1]);
- }
- } else if (n_pos_args == 3) {
- channel_id = mp_obj_get_int(pos_args[1]);
- gpio_id = machine_pin_get_id(pos_args[2]);
- } else {
- mp_raise_TypeError(MP_ERROR_TEXT("too many positional args"));
- }
-
- const machine_adc_obj_t *adc = madc_search_helper(self, channel_id, gpio_id);
- if (adc != NULL) {
- madc_init_helper(adc, 0, pos_args + n_pos_args, kw_args);
- return MP_OBJ_FROM_PTR(adc);
- }
- mp_raise_ValueError(MP_ERROR_TEXT("no matching ADC"));
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_KW(madcblock_connect_obj, 2, madcblock_connect);
-
-mp_int_t madcblock_read_helper(madcblock_obj_t *self, adc_channel_t channel_id) {
- int raw;
- if (self->unit_id == ADC_UNIT_1) {
- raw = adc1_get_raw(channel_id);
- } else {
- check_esp_err(adc2_get_raw(channel_id, self->width, &raw));
- }
- return raw;
-}
-
-mp_int_t madcblock_read_uv_helper(madcblock_obj_t *self, adc_channel_t channel_id, adc_atten_t atten) {
- int raw = madcblock_read_helper(self, channel_id);
- esp_adc_cal_characteristics_t *adc_chars = self->characteristics[atten];
- if (adc_chars == NULL) {
- adc_chars = malloc(sizeof(esp_adc_cal_characteristics_t));
- esp_adc_cal_characterize(self->unit_id, atten, self->width, DEFAULT_VREF, adc_chars);
- self->characteristics[atten] = adc_chars;
- }
- mp_int_t uv = esp_adc_cal_raw_to_voltage(raw, adc_chars) * 1000;
- return uv;
-}
-
-STATIC const mp_rom_map_elem_t madcblock_locals_dict_table[] = {
- { MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&madcblock_init_obj) },
- { MP_ROM_QSTR(MP_QSTR_connect), MP_ROM_PTR(&madcblock_connect_obj) },
-};
-STATIC MP_DEFINE_CONST_DICT(madcblock_locals_dict, madcblock_locals_dict_table);
-
-MP_DEFINE_CONST_OBJ_TYPE(
- machine_adcblock_type,
- MP_QSTR_ADCBlock,
- MP_TYPE_FLAG_NONE,
- make_new, madcblock_make_new,
- print, madcblock_print,
- locals_dict, &madcblock_locals_dict
- );
diff --git a/ports/esp32/machine_adcblock.h b/ports/esp32/machine_adcblock.h
deleted file mode 100644
index 7c9249b07..000000000
--- a/ports/esp32/machine_adcblock.h
+++ /dev/null
@@ -1,22 +0,0 @@
-#ifndef MICROPY_INCLUDED_MACHINE_ADCBLOCK_H
-#define MICROPY_INCLUDED_MACHINE_ADCBLOCK_H
-
-#include "esp_adc_cal.h"
-
-#define ADC_ATTEN_MAX SOC_ADC_ATTEN_NUM
-
-typedef struct _madcblock_obj_t {
- mp_obj_base_t base;
- adc_unit_t unit_id;
- mp_int_t bits;
- adc_bits_width_t width;
- esp_adc_cal_characteristics_t *characteristics[ADC_ATTEN_MAX];
-} madcblock_obj_t;
-
-extern madcblock_obj_t madcblock_obj[];
-
-extern void madcblock_bits_helper(madcblock_obj_t *self, mp_int_t bits);
-extern mp_int_t madcblock_read_helper(madcblock_obj_t *self, adc_channel_t channel_id);
-extern mp_int_t madcblock_read_uv_helper(madcblock_obj_t *self, adc_channel_t channel_id, adc_atten_t atten);
-
-#endif // MICROPY_INCLUDED_MACHINE_ADCBLOCK_H
diff --git a/ports/esp32/modmachine.c b/ports/esp32/modmachine.c
index 1e83935a8..461ddacda 100644
--- a/ports/esp32/modmachine.c
+++ b/ports/esp32/modmachine.c
@@ -312,7 +312,9 @@ STATIC const mp_rom_map_elem_t machine_module_globals_table[] = {
#if MICROPY_PY_MACHINE_ADC
{ MP_ROM_QSTR(MP_QSTR_ADC), MP_ROM_PTR(&machine_adc_type) },
#endif
- { MP_ROM_QSTR(MP_QSTR_ADCBlock), MP_ROM_PTR(&machine_adcblock_type) },
+ #if MICROPY_PY_MACHINE_ADC_BLOCK
+ { MP_ROM_QSTR(MP_QSTR_ADCBlock), MP_ROM_PTR(&machine_adc_block_type) },
+ #endif
#if MICROPY_PY_MACHINE_DAC
{ MP_ROM_QSTR(MP_QSTR_DAC), MP_ROM_PTR(&machine_dac_type) },
#endif
diff --git a/ports/esp32/modmachine.h b/ports/esp32/modmachine.h
index 7b26df609..06a1d7b0e 100644
--- a/ports/esp32/modmachine.h
+++ b/ports/esp32/modmachine.h
@@ -10,7 +10,6 @@ typedef enum {
} wake_type_t;
extern const mp_obj_type_t machine_touchpad_type;
-extern const mp_obj_type_t machine_adcblock_type;
extern const mp_obj_type_t machine_dac_type;
extern const mp_obj_type_t machine_sdcard_type;
diff --git a/ports/esp32/mpconfigport.h b/ports/esp32/mpconfigport.h
index b4ec08209..706baae5b 100644
--- a/ports/esp32/mpconfigport.h
+++ b/ports/esp32/mpconfigport.h
@@ -99,10 +99,11 @@
#define MICROPY_PY_MACHINE_ADC (1)
#define MICROPY_PY_MACHINE_ADC_INCLUDEFILE "ports/esp32/machine_adc.c"
#define MICROPY_PY_MACHINE_ADC_ATTEN_WIDTH (1)
-#define MICROPY_PY_MACHINE_ADC_BLOCK (1)
#define MICROPY_PY_MACHINE_ADC_INIT (1)
#define MICROPY_PY_MACHINE_ADC_READ (1)
#define MICROPY_PY_MACHINE_ADC_READ_UV (1)
+#define MICROPY_PY_MACHINE_ADC_BLOCK (1)
+#define MICROPY_PY_MACHINE_ADC_BLOCK_INCLUDEFILE "ports/esp32/machine_adc_block.c"
#define MICROPY_PY_MACHINE_PIN_MAKE_NEW mp_pin_make_new
#define MICROPY_PY_MACHINE_BITSTREAM (1)
#define MICROPY_PY_MACHINE_PULSE (1)
diff --git a/ports/renesas-ra/modmachine.h b/ports/renesas-ra/modmachine.h
index 9bb3196b3..22d1fc475 100644
--- a/ports/renesas-ra/modmachine.h
+++ b/ports/renesas-ra/modmachine.h
@@ -30,7 +30,6 @@
#include "py/obj.h"
extern const mp_obj_type_t machine_touchpad_type;
-extern const mp_obj_type_t machine_adcblock_type;
extern const mp_obj_type_t machine_dac_type;
extern const mp_obj_type_t machine_sdcard_type;