diff --git a/openrtx/include/peripherals/adc.h b/openrtx/include/peripherals/adc.h
new file mode 100644
index 00000000..eb16ac64
--- /dev/null
+++ b/openrtx/include/peripherals/adc.h
@@ -0,0 +1,97 @@
+/***************************************************************************
+ * Copyright (C) 2024 by Silvano Seva IU2KWO *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 3 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, see *
+ ***************************************************************************/
+
+#ifndef ADC_H
+#define ADC_H
+
+#include
+#include
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+struct Adc;
+
+/**
+ * Sample one ADC channel returning the raw converted value.
+ *
+ * @param adc: pointer to ADC device handle.
+ * @param channel: channel number.
+ * @return channel raw value, zero if channel is out of range.
+ */
+typedef uint16_t (*adc_sample_impl)(const struct Adc *adc, const uint32_t channel);
+
+/**
+ * ADC device handle.
+ */
+struct Adc
+{
+ const adc_sample_impl sample; ///< Device-specific implementation of the ADC sample function
+ const void *priv; ///< Pointer to device driver private data
+ const pthread_mutex_t *mutex; ///< Pointer to mutex, can be NULL
+ const uint32_t countsTouV; ///< Conversion factor from counts to uV
+};
+
+/**
+ * Compute conversion factor from ADC counts to uV expressed in Q16.16 format.
+ *
+ * @param vref: ADC reference voltage, in uV.
+ * @param resolution: ADC resolution, in bits.
+ * @return conversion factor.
+ */
+#define ADC_COUNTS_TO_UV(vref, resolution) (vref << (16 - resolution))
+
+/**
+ * Sample one ADC channel returning the raw converted value.
+ *
+ * @param adc: pointer to ADC device handle.
+ * @param channel: channel number.
+ * @return channel raw value, zero if channel is out of range.
+ */
+static inline uint16_t adc_getRawSample(const struct Adc *adc, const uint32_t channel)
+{
+ if(adc->mutex != NULL)
+ pthread_mutex_lock((pthread_mutex_t *) adc->mutex);
+
+ uint16_t sample = adc->sample(adc, channel);
+
+ if(adc->mutex != NULL)
+ pthread_mutex_unlock((pthread_mutex_t *) adc->mutex);
+
+ return sample;
+}
+
+/**
+ * Sample one ADC channel returning the voltage, in uV.
+ *
+ * @param adc: pointer to ADC device handle.
+ * @param channel: channel number.
+ * @return channel voltage, zero if channel is out of range.
+ */
+static inline uint32_t adc_getVoltage(const struct Adc *adc, const uint32_t channel)
+{
+ uint64_t value = adc_getRawSample(adc, channel);
+ return (value * adc->countsTouV) >> 16;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ADC_H */