wip: grbl: add support for ADC
diff --git a/grbl/adc.c b/grbl/adc.c
new file mode 100644
index 0000000..660ab3f
--- /dev/null
+++ b/grbl/adc.c
@@ -0,0 +1,559 @@
+/*
+  adc.c - Low level functions for enabling ADC (Analog Digital Converter)
+  functionalities
+  Part of Grbl
+
+  Copyright (c) 2019 Luigi Santivetti
+
+  Grbl 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.
+
+  Grbl 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 Grbl.  If not, see <http://www.gnu.org/licenses/>.
+
+  Conventions:
+   - DEFAULT_ADC_ prefix is reserved for defines from defaults.h
+   - _ prefix for defines function-like
+   - __ prefix for defines variable-like
+   - Switch cases tend to have inline break clause
+   - Fill column size is 80, tab width is 2, always untabified
+   - Single line comment doesn't have trailing full stop
+   - Badly enough, defines are indented, for consistency reasons
+*/
+
+#include "grbl.h"
+
+// First available channel, this is always valid
+#define ADC_DEFAULT_CHANNEL 0
+
+// Max and min number of readings allowed per channel
+#define ADC_MIN_READINGS 1
+#define ADC_MAX_READINGS 16
+#define ADC_MSK_READINGS (DEFAULT_ADC_READINGS - 1)
+
+// Track the ADC status. These are mutually exclusive states
+#define ADC_STATUS_INIT bit(14)
+#define ADC_STATUS_STOP bit(15)
+#define _adc_get_status_module(XX) bit_istrue(adc->s, XX)
+
+// Mutually exclusive states, always clear them first
+#define _adc_set_status_module(XX)                   \
+  do {                                               \
+    adc->s &= ~(ADC_STATUS_INIT | ADC_STATUS_STOP);  \
+    bit_true(adc->s, XX);                            \
+  } while (0)
+
+// Flag data as reliable
+#define _adc_set_status_channel()     \
+  do {                                \
+    bit_true(adc->s, bit(adc->i_c));  \
+  } while (0)
+
+// Alias current channel being stored in the ADC buffer
+#define __adc_current_channel_avr adc->b[adc->i_c].avr
+
+#ifdef ADC_CONFIG_SYSTEM_ALARM
+  #define __adc_current_channel_min adc->b[adc->i_c].min
+  #define __adc_current_channel_max adc->b[adc->i_c].max
+#endif
+
+#if DEFAULT_ADC_READINGS > 1
+  // isr_next_callback_id is always either 1 or 0, updated dynamically avoids
+  // the need for if-else runtime decision making in the ISR.
+  #define __isr_next_callback_id (adc->i_r & bit(0))
+
+  // Alias for consistency with adc_current_channel_avr
+  #define __adc_current_channel_sum adc->sum
+
+  // Right shift the current reading index, is reset to when reaches bit(0) and
+  // is initialized at DEFAULT_ADC_READINGS.
+  #define _adc_update_index_reading() \
+    do { adc->i_r = adc->i_r >> 1; } while (0)
+
+  // Reset current reading index when beginning reading a new channel
+  #define _adc_reset_index_reading() \
+    do { adc->i_r = DEFAULT_ADC_READINGS; } while (0)
+#endif
+
+// Validate DEFAULT_ADC_READINGS range
+#if (DEFAULT_ADC_READINGS > ADC_MAX_READINGS) || \
+  (DEFAULT_ADC_READINGS < ADC_MIN_READINGS)
+  #error "Invalid DEFAULT_ADC_READINGS"
+
+// Reading once per channel isn't ideal
+#elif DEFAULT_ADC_READINGS == 1
+  #warning "One shot reading is unreliable"
+
+// For accumulation 10 bit (max resolution) times DEFAULT_ADC_READINGS must fit
+// in uint16_t.
+#elif (0x3FF * DEFAULT_ADC_READINGS) >> 16
+  #error "Invalid DEFAULT_ADC_READINGS"
+
+// DEFAULT_ADC_READINGS must be a power of 2
+#elif DEFAULT_ADC_READINGS & ADC_MSK_READINGS
+  #error "Invalid DEFAULT_ADC_READINGS"
+#endif
+
+// DEFAULT_ADC_RESOLUTION allowed value is an interger number of bits
+#if   DEFAULT_ADC_RESOLUTION == 8
+#elif DEFAULT_ADC_RESOLUTION == 10
+#else
+  #error "Invalid DEFAULT_ADC_RESOLUTION"
+#endif
+
+// DEFAULT_ADC_CHANNELS_MASK, 11-bit, bitmask.
+// The ADC has 11 channels, i-th bit for enabling i-th channel.
+// i.e.
+//        00000001001, enable first and fourth channel,
+//        00000100010, enable second and sixth channel.
+#if !defined(DEFAULT_ADC_CHANNELS_MASK) || (DEFAULT_ADC_CHANNELS_MASK == 0) || \
+  (DEFAULT_ADC_CHANNELS_MASK >> ADC_CONFIG_CHANNELS_COUNT)
+  #error "Invalid DEFAULT_ADC_CHANNELS_MASK"
+#endif
+
+// Available and supported modes. Extend this for supporting new modes
+#define MODE0 ADC_CONFIG_MODE_SW_TRIGGER
+#define MODE1 ADC_CONFIG_MODE_HW_TRIGGER
+#if   DEFAULT_ADC_MODE == MODE0
+#elif DEFAULT_ADC_MODE == MODE1
+  // In this mode, although possible, isn't reliable to dinamically switch
+  // channel, only allow one channel.
+  #if ADC_CHANNELS_ENABLED_COUNT > 1
+    #error "Invalid ADC_CHANNELS_ENABLED_COUNT"
+  #endif
+#else
+  // None of the above is invalid
+  #error "Invalid DEFAULT_ADC_MODE"
+#endif
+
+// Available ADC clocks. These are the only allowed and implemented
+#if   DEFAULT_ADC_CLOCK == 125
+#elif DEFAULT_ADC_CLOCK == 250
+#elif DEFAULT_ADC_CLOCK == 500
+#elif DEFAULT_ADC_CLOCK == 1000
+#elif DEFAULT_ADC_CLOCK == 2000
+#elif DEFAULT_ADC_CLOCK == 4000
+#elif DEFAULT_ADC_CLOCK == 8000
+#else
+  // None of the above is invalid
+  #error "Invalid DEFAULT_ADC_CLOCK"
+#endif
+
+// If the ADC uses 10 bit, only clocks >50Hz and <200Khz are allowed
+#if (DEFAULT_ADC_RESOLUTION != 8) && (DEFAULT_ADC_CLOCK != CLK_125KHZ)
+  #error "Invalid DEFAULT_ADC_CLOCK"
+#endif
+
+// Available ADC inputs for reference voltage. Edit this for supporting new vref
+#if   DEFAULT_ADC_REFERENCE == ADC_CONFIG_REFERENCE_INTERNAL_1VREF
+#elif DEFAULT_ADC_REFERENCE == ADC_CONFIG_REFERENCE_INTERNAL_5VREF
+#elif DEFAULT_ADC_REFERENCE == ADC_CONFIG_REFERENCE_EXTERNAL_AVCC
+#else
+  #error "Invalid DEFAULT_ADC_MODE"
+#endif
+
+// Track power reduction status at the moment the ADC module is started
+static uint8_t prr_need_restart;
+adc_data *adc_global;
+
+#ifdef ADC_CONFIG_SYSTEM_ALARM
+// FIXME: move range initialization to settings.c
+//
+// This should really be done in settings.c, as in, min and max should be
+// defined in settings_t. However, for the time being, do NOT write this
+// data to EEPROM, which means rebuild if needed.
+
+#define _set_channel_range(channel, number, MIN, MAX, FLAG)           \
+  do {                                                                \
+    adc->b[channel].min = (adc_value) (FLAG ? DEFAULT_ADC_RANGE_CHANNEL_ ## number ## _MIN : MIN); \
+    adc->b[channel].max = (adc_value) (FLAG ? DEFAULT_ADC_RANGE_CHANNEL_ ## number ## _MAX : MAX); \
+   } while (0)
+
+static inline void adc_init_range_channel(adc_data *adc)
+{
+  #if ADC_CHANNEL_00_ENABLED
+    _set_channel_range(ADC0, 0, 0, 0, 0);
+  #endif
+  #if ADC_CHANNEL_01_ENABLED
+    _set_channel_range(ADC1, 1, 0, 0, 0);
+  #endif
+  #if ADC_CHANNEL_02_ENABLED
+    _set_channel_range(ADC2, 2, 0, 0, 0);
+  #endif
+  #if ADC_CHANNEL_03_ENABLED
+    _set_channel_range(ADC3, 3, 0, 0, 0);
+  #endif
+  #if ADC_CHANNEL_04_ENABLED
+    _set_channel_range(ADC4, 4, 0, 0, 0);
+  #endif
+  #if ADC_CHANNEL_05_ENABLED
+    _set_channel_range(ADC5, 5, 0, 0, 0);
+  #endif
+  #if ADC_CHANNEL_06_ENABLED
+    _set_channel_range(ADC6, 6, 0, 0, 0);
+  #endif
+  #if ADC_CHANNEL_07_ENABLED
+    _set_channel_range(ADC7, 7, 0, 0, 0);
+  #endif
+  #if ADC_CHANNEL_08_ENABLED
+    _set_channel_range(ADC8, 8, 0, 0, 0);
+  #endif
+  #if ADC_CHANNEL_09_ENABLED
+    _set_channel_range(ADC9, 9, 0, 0, 0);
+  #endif
+  #if ADC_CHANNEL_10_ENABLED
+    _set_channel_range(ADC10, 10, 0, 0, 0);
+  #endif
+}
+#endif
+
+// Switching mode can start a conversion. Check ATMega328p, 7810D–AVR–01/15,
+// page 220. Auto triggering is enabled by setting the ADC auto trigger enable
+// bit, ADATE in ADCSRA. The trigger source is selected by setting the ADC
+// trigger, select bits, ADTS in ADCSRB.
+static inline void adc_init_mode(const int mode)
+{
+  // Trigger bit must be set for any mode but when the next conversion is started
+  // in software.
+  bit_true(ADC_ST1_REG, bit(ADC_ST1_TRIGGER_BIT));
+
+  switch (mode) {
+  case MODE0:
+    bit_false(ADC_ST1_REG, bit(ADC_ST1_TRIGGER_BIT)); break;
+  case MODE1:
+    bit_false(ADC_ST2_REG, ADC_ST2_MODEFR_MASK); break;
+  }
+}
+
+// If the user has a fixed voltage source connected to the AREF pin, the user
+// may not use the other reference voltage options in the application, as they
+// will be shorted to the external voltage.
+static inline void adc_init_reference(const int ref)
+{
+  // Clear all reference bits
+  bit_false(ADC_MUX_REG, ADC_MUX_REFALL_MASK);
+
+  // ATMega328p, 7810D–AVR–01/15, Table 23-3:
+  switch (ref) {
+  case ADC_CONFIG_REFERENCE_INTERNAL_1VREF:
+    bit_true(ADC_MUX_REG, ADC_MUX_REFALL_MASK); break;
+  case ADC_CONFIG_REFERENCE_INTERNAL_5VREF:
+    bit_true(ADC_MUX_REG, ADC_MUX_REFAVC_MASK); break;
+  case ADC_CONFIG_REFERENCE_EXTERNAL_AVCC:
+    bit_true(ADC_MUX_REG, ADC_MUX_REFEXT_MASK); break;
+  }
+}
+
+// ATMega328p, 7810D–AVR–01/15, page 208 says:
+// the successive approximation circuitry requires an input clock frequency
+// between 50kHz and 200kHz to get maximum resolution.
+static inline void adc_init_clock(const int clock)
+{
+  // Clear all clock bits
+  bit_false(ADC_ST1_REG, ADC_ST1_CLKALL_MASK);
+
+  // ATMega328p, 7810D–AVR–01/15, Table 23-5:
+  switch (clock) {
+  case 125:  bit_true(ADC_ST1_REG, ADC_ST1_125KHZ_MASK); break;
+  case 250:  bit_true(ADC_ST1_REG, ADC_ST1_250KHZ_MASK); break;
+  case 500:  bit_true(ADC_ST1_REG, ADC_ST1_500KHZ_MASK); break;
+  case 1000: bit_true(ADC_ST1_REG, ADC_ST1_001MHZ_MASK); break;
+  case 2000: bit_true(ADC_ST1_REG, ADC_ST1_002MHZ_MASK); break;
+  case 4000: bit_true(ADC_ST1_REG, ADC_ST1_004MHZ_MASK); break;
+  case 8000: bit_true(ADC_ST1_REG, ADC_ST1_008MHZ_MASK); break;
+  }
+}
+
+// Check ATMega328p, 7810D–AVR–01/15, page 210, 23.5 and 23.5.1
+static inline void adc_set_channel(const int channel)
+{
+  // Clear all channel bits
+  bit_false(ADC_MUX_REG, ADC_MUX_CHALL_MASK);
+
+  // ATMega328p, 7810D–AVR–01/15, Table 23-4:
+  switch (channel) {
+  #if ADC_CHANNEL_00_ENABLED
+    case ADC0: bit_true(ADC_MUX_REG, ADC_MUX_CH0_MASK); break;
+  #endif
+  #if ADC_CHANNEL_01_ENABLED
+    case ADC1: bit_true(ADC_MUX_REG, ADC_MUX_CH1_MASK); break;
+  #endif
+  #if ADC_CHANNEL_02_ENABLED
+    case ADC2: bit_true(ADC_MUX_REG, ADC_MUX_CH2_MASK); break;
+  #endif
+  #if ADC_CHANNEL_03_ENABLED
+    case ADC3: bit_true(ADC_MUX_REG, ADC_MUX_CH3_MASK); break;
+  #endif
+  #if ADC_CHANNEL_04_ENABLED
+    case ADC4: bit_true(ADC_MUX_REG, ADC_MUX_CH4_MASK); break;
+  #endif
+  #if ADC_CHANNEL_05_ENABLED
+    case ADC5: bit_true(ADC_MUX_REG, ADC_MUX_CH5_MASK); break;
+  #endif
+  #if ADC_CHANNEL_06_ENABLED
+    case ADC6: bit_true(ADC_MUX_REG, ADC_MUX_CH6_MASK); break;
+  #endif
+  #if ADC_CHANNEL_07_ENABLED
+    case ADC7: bit_true(ADC_MUX_REG, ADC_MUX_CH7_MASK); break;
+  #endif
+  #if ADC_CHANNEL_08_ENABLED
+    case ADC8: bit_true(ADC_MUX_REG, ADC_MUX_CHTMP_MASK); break;
+  #endif
+  #if ADC_CHANNEL_09_ENABLED
+    case ADC9: bit_true(ADC_MUX_REG, ADC_MUX_CHGND_MASK); break;
+  #endif
+  #if ADC_CHANNEL_10_ENABLED
+    case ADC10: bit_true(ADC_MUX_REG, ADC_MUX_CHVBG_MASK); break;
+  #endif
+  }
+}
+
+// ATMega328p, 7810D–AVR–01/15, page 208 says:
+// When ADCL is read, the ADC data register is not updated until ADCH is read.
+// Consequently, if the result is left adjusted and no more than 8-bit
+// precision is required, it is sufficient to read ADCH. Otherwise, ADCL must
+// be read first, then ADCH.
+#if DEFAULT_ADC_RESOLUTION == 8
+  static inline uint8_t adc_merge_registers()
+  {
+    return ADC_HGH_REG;
+  }
+#else
+  static inline uint16_t adc_merge_registers()
+  {
+    uint8_t low = ADC_LOW_REG;
+    uint16_t hgh = ((uint16_t) ADC_HGH_REG) << 8;
+    return  hgh | low;
+  }
+#endif
+
+#if DEFAULT_ADC_READINGS > 1
+  static inline adc_value adc_get_average(const adc_data *adc)
+  {
+    return (adc_value) (__adc_current_channel_sum / DEFAULT_ADC_READINGS);
+  }
+#else
+  static inline adc_value adc_get_average(const adc_data *adc)
+  {
+    (void)adc;
+
+    return (adc_value) adc_merge_registers();
+  }
+#endif
+
+#if DEFAULT_ADC_MODE == MODE0
+  static inline void adc_set_next_channel(adc_data *adc)
+  {
+    #if ADC_CHANNELS_ENABLED_COUNT & (ADC_CHANNELS_ENABLED_COUNT - 1)
+      adc->i_c = adc->i_c + 1;
+      adc->i_c = adc->i_c % ADC_CHANNELS_ENABLED_COUNT;
+    #else
+      adc->i_c = (adc->i_c + 1) & (ADC_CHANNELS_ENABLED_COUNT - 1);
+    #endif
+    adc_set_channel(adc->i_c);
+  }
+#endif
+
+static inline void adc_kick_conversion()
+{
+  prr_need_restart = ADC_PRR_REG_cpu;
+
+  // Disable power reduction. Note: this register is outside the ADC block
+  bit_false(ADC_PRR_REG_cpu, bit(ADC_PRR_cpu_PRADC_BIT));
+
+  // How long this takes depends on the mode. In single conversion 13.5 cycles
+  bit_true(ADC_ST1_REG, bit(ADC_ST1_START_BIT));
+}
+
+#ifdef ADC_CONFIG_SYSTEM_ALARM
+static inline int adc_need_alarm(const adc_data *adc)
+{
+  const adc_value channel_avr = __adc_current_channel_avr;
+
+  if (channel_avr >= __adc_current_channel_max ||
+      channel_avr <= __adc_current_channel_min)
+    return 1;
+
+  return 0;
+}
+
+static inline void adc_flag_system_alarm(const adc_data *adc)
+{
+  if (sys.state != STATE_ALARM)
+    if (!sys_rt_exec_alarm && adc_need_alarm(adc)) {
+	mc_reset();
+	system_set_exec_alarm(EXEC_ALARM_ADC);
+    }
+}
+#endif
+
+static inline void adc_isr_update_channel_avr(adc_data *adc)
+{
+  // Work out reliable data, not quite so when one-shot reading. Note, change this in
+  // order to use a different method (i.e. filtering).
+  __adc_current_channel_avr = adc_get_average(adc);
+
+  #ifdef ADC_CONFIG_SYSTEM_ALARM
+    // This is called only once every DEFAULT_ADC_READINGS times, data is reliable,
+    // it's a good time to raise an alarm, if any.
+    adc_flag_system_alarm(adc);
+  #endif
+
+  #if DEFAULT_ADC_READINGS > 1
+    // Reset previous sum, prepare for the next channel
+    __adc_current_channel_sum = 0;
+
+    // Wrap reading index for the next channel
+    _adc_reset_index_reading();
+  #endif
+
+  // FIXME: maybe needed for dummy values
+  // Flag data for this channel as reliable
+  _adc_set_status_channel();
+
+  #if DEFAULT_ADC_MODE == MODE0
+    adc_set_next_channel(adc);
+  #endif
+}
+
+static inline void adc_isr_call_read_op(adc_data *adc)
+{
+  #if DEFAULT_ADC_READINGS > 1
+    // Select and call back from the adc struct, do not bother in checking. In
+    // case of abnormal and trusted data this will flag directly the main system
+    // alarm flag, otherwise keep reading until the current channel is drained.
+    adc->isr[__isr_next_callback_id](adc);
+  #else
+    adc_isr_update_channel_avr(adc);
+  #endif
+}
+
+static inline void adc_isr_call_reset_op(adc_data *adc)
+{
+  #if (DEFAULT_ADC_READINGS > 1) && (DEFAULT_ADC_MODE == MODE0)
+    // Start next conversion
+    adc->isr[ADC_ISR_PFN_RST_ID](adc);
+  #elif DEFAULT_ADC_MODE == MODE0
+    (void)adc;
+    // Start next conversion
+    adc_kick_conversion();
+  #endif
+  // No need reset if HW triggering
+}
+
+#if DEFAULT_ADC_READINGS > 1
+  // Callback for ADC_ISR_PFN_SUM_ID
+  static void adc_isr_callback_sum(adc_data *adc)
+  {
+    // Acquire new data
+    __adc_current_channel_sum += adc_merge_registers();
+    _adc_update_index_reading();
+  }
+
+  // Callback for ADC_ISR_PFN_AVR_ID
+  static void adc_isr_callback_avr(adc_data *adc)
+  {
+    adc_isr_update_channel_avr(adc);
+  }
+
+  // Callbacks for ADC_ISR_PFN_RST_ID, only available if SW triggering
+  #if DEFAULT_ADC_MODE == MODE0
+    static void adc_isr_callback_rst(adc_data *adc)
+    {
+      adc_kick_conversion();
+    }
+
+    static void adc_isr_callback_noop() { return; }
+  #endif
+#endif
+
+adc_value adc_read_unsigned(const adc_data *adc, const adc_channel c)
+{
+  return adc->b[c].avr;
+}
+
+void adc_deinit(adc_data *adc)
+{
+  #if (DEFAULT_ADC_MODE == MODE0) && (DEFAULT_ADC_READINGS > 1)
+    // Prevent starting a new conversion in case an IRQ kicks in
+    adc->isr[ADC_ISR_PFN_RST_ID] = adc_isr_callback_noop;
+  #endif
+
+  // Do not turn it back on if it wasn't originally
+  if (bit_istrue(prr_need_restart, bit(ADC_PRR_cpu_PRADC_BIT)))
+    bit_true(ADC_PRR_REG_cpu, bit(ADC_PRR_cpu_PRADC_BIT));
+
+  // Disable the ADC interrupt
+  bit_false(ADC_ST1_REG, bit(ADC_ST1_IRQ_BIT));
+
+  // Disable ADC module
+  bit_false(ADC_ST1_REG, bit(ADC_ST1_ENABLE_BIT));
+}
+
+void adc_init(adc_data *adc)
+{
+  uint8_t i;
+
+  // Init global reference to adc
+  adc_global = adc;
+
+  adc_init_reference(DEFAULT_ADC_REFERENCE);
+  adc_init_clock(DEFAULT_ADC_CLOCK);  
+  adc_init_mode(DEFAULT_ADC_MODE);
+
+  #ifdef ADC_CONFIG_SYSTEM_ALARM
+    adc_init_range_channel(adc);
+  #endif
+
+  adc_set_channel(ADC_DEFAULT_CHANNEL);
+
+  #if DEFAULT_ADC_RESOLUTION == 8
+    // Left adjust so to fit in one register only
+    bit_true(ADC_ST1_REG, bit(ADC_ST1_LEFTSHIFT_BIT));
+  #else
+    bit_false(ADC_ST1_REG, bit(ADC_ST1_LEFTSHIFT_BIT));
+  #endif
+
+  #if DEFAULT_ADC_READINGS > 1
+    // i_r is a bit-mask and 1 is left-shifted for DEFAULT_ADC_READINGS
+    // number of times.
+    adc->i_r = DEFAULT_ADC_READINGS;
+    adc->isr[ADC_ISR_PFN_SUM_ID] = adc_isr_callback_sum;
+    adc->isr[ADC_ISR_PFN_AVR_ID] = adc_isr_callback_avr;
+    adc->sum = 0;
+
+    #if (DEFAULT_ADC_MODE == MODE0)
+      adc->isr[ADC_ISR_PFN_RST_ID] = adc_isr_callback_rst;
+    #endif
+  #endif
+
+  adc->i_c = ADC_DEFAULT_CHANNEL;
+  adc->s = ADC_STATUS_INIT;
+
+  // Enable the ADC interrupt
+  bit_true(ADC_ST1_REG, bit(ADC_ST1_IRQ_BIT));
+
+  // This instruction takes 12 ADC clocks to execute
+  bit_true(ADC_ST1_REG, bit(ADC_ST1_ENABLE_BIT));
+
+  // reset buffer's avr, in case of a sys reset and adc_init is called again
+  for (i = 0; i < ADC_CHANNELS_ENABLED_COUNT; i++)
+    adc->b[i].avr = 0;
+
+  // Start the first conversion
+  adc_kick_conversion();
+}
+
+ISR(ADC_vect)
+{
+  adc_isr_call_read_op(adc_global);
+
+  adc_isr_call_reset_op(adc_global);
+}
diff --git a/grbl/adc.h b/grbl/adc.h
new file mode 100644
index 0000000..9e84a38
--- /dev/null
+++ b/grbl/adc.h
@@ -0,0 +1,182 @@
+/*
+  adc.h - Low level header for exposing ADC (Analog Digital Converter)
+  functionalities
+  Part of Grbl
+
+  Copyright (c) 2019 Luigi Santivetti
+
+  Grbl 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.
+
+  Grbl 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 Grbl.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef adc_h
+#define adc_h
+
+#define ADC_CHANNEL_00_ENABLED ((DEFAULT_ADC_CHANNELS_MASK & bit(0)) >> 0)
+#define ADC_CHANNEL_01_ENABLED ((DEFAULT_ADC_CHANNELS_MASK & bit(1)) >> 1)
+#define ADC_CHANNEL_02_ENABLED ((DEFAULT_ADC_CHANNELS_MASK & bit(2)) >> 2)
+#define ADC_CHANNEL_03_ENABLED ((DEFAULT_ADC_CHANNELS_MASK & bit(3)) >> 3)
+#define ADC_CHANNEL_04_ENABLED ((DEFAULT_ADC_CHANNELS_MASK & bit(4)) >> 4)
+#define ADC_CHANNEL_05_ENABLED ((DEFAULT_ADC_CHANNELS_MASK & bit(5)) >> 5)
+#define ADC_CHANNEL_06_ENABLED ((DEFAULT_ADC_CHANNELS_MASK & bit(6)) >> 6)
+#define ADC_CHANNEL_07_ENABLED ((DEFAULT_ADC_CHANNELS_MASK & bit(7)) >> 7)
+#define ADC_CHANNEL_08_ENABLED ((DEFAULT_ADC_CHANNELS_MASK & bit(8)) >> 8)
+#define ADC_CHANNEL_09_ENABLED ((DEFAULT_ADC_CHANNELS_MASK & bit(9)) >> 9)
+#define ADC_CHANNEL_10_ENABLED ((DEFAULT_ADC_CHANNELS_MASK & bit(10)) >> 10)
+
+#if DEFAULT_ADC_READINGS > 1
+// ADC ISR callbacks
+  #define ADC_ISR_PFN_SUM_ID 0
+  #define ADC_ISR_PFN_AVR_ID 1
+  #if DEFAULT_ADC_MODE == MODE0
+    #define ADC_ISR_PFN_RST_ID 2
+    #define ADC_ISR_APFN_COUNT 3
+  #else
+    #define ADC_ISR_APFN_COUNT 2
+  #endif
+#endif
+
+// Number of enabled channels
+#define ADC_CHANNELS_ENABLED_COUNT                                            \
+  (ADC_CHANNEL_00_ENABLED + ADC_CHANNEL_01_ENABLED + ADC_CHANNEL_02_ENABLED + \
+   ADC_CHANNEL_03_ENABLED + ADC_CHANNEL_04_ENABLED + ADC_CHANNEL_05_ENABLED + \
+   ADC_CHANNEL_06_ENABLED + ADC_CHANNEL_07_ENABLED + ADC_CHANNEL_08_ENABLED + \
+   ADC_CHANNEL_09_ENABLED + ADC_CHANNEL_10_ENABLED)
+
+// Holding ADC readings
+#if DEFAULT_ADC_RESOLUTION == 8
+  typedef uint8_t adc_value;
+#else
+  typedef uint16_t adc_value;
+#endif
+
+typedef struct _adc_data adc_data;
+
+#ifdef ADC_CONFIG_SYSTEM_ALARM
+  #define ADC_INVALID_RANGE_CHANNEL(NUMBER)                                       \
+    ((!defined(DEFAULT_ADC_RANGE_CHANNEL_ ## NUMBER ## _MIN) ||                   \
+      !defined(DEFAULT_ADC_RANGE_CHANNEL_ ## NUMBER ## _MAX)) ||                  \
+     ((DEFAULT_ADC_RANGE_CHANNEL_ ## NUMBER ## _MIN >> DEFAULT_ADC_RESOLUTION) || \
+      (DEFAULT_ADC_RANGE_CHANNEL_ ## NUMBER ## _MAX >> DEFAULT_ADC_RESOLUTION)))
+
+  #if ADC_CHANNEL_00_ENABLED && ADC_INVALID_RANGE_CHANNEL(0)
+    #error "Invalid ADC00 range"
+  #endif
+  #if ADC_CHANNEL_01_ENABLED && ADC_INVALID_RANGE_CHANNEL(1)
+    #error "Invalid ADC01 range"
+  #endif
+  #if ADC_CHANNEL_02_ENABLED && ADC_INVALID_RANGE_CHANNEL(2)
+    #error "Invalid ADC02 range"
+  #endif
+  #if ADC_CHANNEL_03_ENABLED && ADC_INVALID_RANGE_CHANNEL(3)
+    #error "Invalid ADC03 range"
+  #endif
+  #if ADC_CHANNEL_04_ENABLED && ADC_INVALID_RANGE_CHANNEL(4)
+    #error "Invalid ADC04 range"
+  #endif
+  #if ADC_CHANNEL_05_ENABLED && ADC_INVALID_RANGE_CHANNEL(5)
+    #error "Invalid ADC05 range"
+  #endif
+  #if ADC_CHANNEL_06_ENABLED && ADC_INVALID_RANGE_CHANNEL(6)
+    #error "Invalid ADC06 range"
+  #endif
+  #if ADC_CHANNEL_07_ENABLED && ADC_INVALID_RANGE_CHANNEL(7)
+    #error "Invalid ADC07 range"
+  #endif
+  #if ADC_CHANNEL_08_ENABLED && ADC_INVALID_RANGE_CHANNEL(8)
+    #error "Invalid ADC08 range"
+  #endif
+  #if ADC_CHANNEL_09_ENABLED && ADC_INVALID_RANGE_CHANNEL(9)
+    #error "Invalid ADC09 range"
+  #endif
+  #if ADC_CHANNEL_10_ENABLED && ADC_INVALID_RANGE_CHANNEL(10)
+    #error "Invalid ADC10 range"
+  #endif
+#endif
+
+typedef enum {
+  #if ADC_CHANNEL_00_ENABLED
+    ADC0,
+  #endif
+  #if ADC_CHANNEL_01_ENABLED
+    ADC1,
+  #endif
+  #if ADC_CHANNEL_02_ENABLED
+    ADC2,
+  #endif
+  #if ADC_CHANNEL_03_ENABLED
+    ADC3,
+  #endif
+  #if ADC_CHANNEL_04_ENABLED
+    ADC4,
+  #endif
+  #if ADC_CHANNEL_05_ENABLED
+    ADC5,
+  #endif
+  #if ADC_CHANNEL_06_ENABLED
+    ADC6,
+  #endif
+  #if ADC_CHANNEL_07_ENABLED
+    ADC7,
+  #endif
+  #if ADC_CHANNEL_08_ENABLED
+    ADC8, // Internal temperature
+  #endif
+  #if ADC_CHANNEL_09_ENABLED
+    ADC9, // Minimum voltage
+  #endif
+  #if ADC_CHANNEL_10_ENABLED
+    ADC10, // Bendgap voltage
+  #endif
+} adc_channel;
+
+struct _adc_data {
+  #if DEFAULT_ADC_READINGS > 1
+    // Array of function pointers called back from the ADC ISR and void if-else
+    void (* isr[ADC_ISR_APFN_COUNT])(adc_data *adc);
+
+    // Store partial updates per channel
+    uint16_t sum;
+
+    // Index tracking the current number of reading
+    uint8_t i_r;
+  #endif
+
+  // Index for the current channel to be stored in the buffer
+  volatile adc_channel i_c;
+
+  // Bitmask for the current status. The first 11 bit are reserved, where the
+  // i-bit set to 1 flags the i-th channel is drained and the buffer holds
+  // reliable data. The last 3 bits are for regular ADC ops signalling.
+  volatile uint16_t s;
+
+  // Buffer holding readings per channel
+  struct {
+    volatile adc_value avr;
+    #ifdef ADC_CONFIG_SYSTEM_ALARM
+      adc_value min;
+      adc_value max;
+    #endif
+  } __attribute__ ((packed)) b[ADC_CHANNELS_ENABLED_COUNT];
+} __attribute__ ((packed));
+
+// Setup the ADC with DEFAULTS, enable it and kick a conversion
+void adc_init(adc_data *adc);
+
+// Teardown ADC, need to reinit afterwards
+void adc_deinit(adc_data *adc);
+
+// Read unsigned ADC buffer value for channel
+adc_value adc_read_unsigned(const adc_data *adc, const adc_channel c);
+
+#endif
diff --git a/grbl/cpu_map_adc.h b/grbl/cpu_map_adc.h
new file mode 100644
index 0000000..67ac0d5
--- /dev/null
+++ b/grbl/cpu_map_adc.h
@@ -0,0 +1,96 @@
+/*
+  cpu_map_adc.h - ADC pin mapping configuration file
+  Part of Grbl
+
+  Copyright (c) 2019 Luigi Santivetti <luigi.santivetti@gmail.com>
+
+  Grbl 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.
+
+  Grbl 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 Grbl.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/* The cpu_map_adc.h files serve as a central pin mapping selection file for the ADC
+   module for different processor types or alternative pin layouts. This version of
+   Grbl officially supports only the Arduino Mega328p. */
+
+#ifndef cpu_map_adc_h
+#define cpu_map_adc_h
+
+#ifdef CPU_MAP_ATMEGA328P
+
+// Define ADC registers
+#define ADC_ST1_REG                ADCSRA
+#define ADC_ST2_REG                ADCSRB
+#define ADC_MUX_REG                ADMUX
+#define ADC_HGH_REG                ADCH
+#define ADC_LOW_REG                ADCL
+#define ADC_PRR_REG_cpu            PRR // Outside the ADC block
+
+// Set to enable in hardware conversion triggering (auto-trigger)
+#define ADC_ST1_TRIGGER_BIT        ADATE
+// Set to start a conversion (manual-trigger)
+#define ADC_ST1_START_BIT          ADSC
+// Set to left adjust converted values as follows:
+// +--------------------------+--------------------------+
+// |           ADCH           |           ADCL           |
+// +--------------------------+--------------------------+
+// |  X  X  X  X  X  X  X  X  |                          | <-  8 bit value
+// |                    X  X  |  X  X  X  X  X  X  X  X  | <- 10 bit value
+// +--------------------------+--------------------------+
+// |  7  6  5  4  3  2  1  0  |  7  6  5  4  3  2  1  0  |
+// |  ^MSB              LSB^  |  ^MSB              LSB^  |
+// +--------------------------+--------------------------+
+#define ADC_ST1_LEFTSHIFT_BIT      ADLAR
+// Set to enable interrupt
+#define ADC_ST1_IRQ_BIT            ADIE
+// Set to switch the ADC on (it requires also power saving to be disabled)
+#define ADC_ST1_ENABLE_BIT         ADEN
+// Set to enable power reduction
+#define ADC_PRR_cpu_PRADC_BIT      PRADC
+
+// Supported modes. Modes are set at compile time. It isn't possible to
+// switch mode dynamically. Add more modes below.
+#define ADC_ST2_MODEFR_MASK        ((1<<ADTS2)|(1<<ADTS1)|(1<<ADTS0))
+
+// Reference voltage
+#define ADC_MUX_REFAVC_MASK        (1<<REFS0)
+#define ADC_MUX_REFALL_MASK        ((1<<REFS1)|ADC_MUX_REFAVC_MASK)
+#define ADC_MUX_REFEXT_MASK        ADC_MUX_REFALL_MASK
+
+// Onboard inputs
+#define ADC_MUX_CHTMP_MASK         (1<<MUX3)
+#define ADC_MUX_CHALL_MASK         (ADC_MUX_CHTMP_MASK|(1<<MUX2)|(1<<MUX1)|(1<<MUX0))
+#define ADC_MUX_CHGND_MASK         ADC_MUX_CHALL_MASK
+#define ADC_MUX_CHVBG_MASK         (ADC_MUX_CHTMP_MASK|(1<<MUX2)|(1<<MUX1))
+
+// Optional free inputs
+#define ADC_MUX_CH0_MASK           ADC_MUX_CHALL_MASK
+#define ADC_MUX_CH1_MASK           (1<<MUX0)
+#define ADC_MUX_CH2_MASK           (1<<MUX1)
+#define ADC_MUX_CH3_MASK           ((1<<MUX1)|(1<<MUX0))
+#define ADC_MUX_CH4_MASK           (1<<MUX2)
+#define ADC_MUX_CH5_MASK           ((1<<MUX2)|(1<<MUX0))
+#define ADC_MUX_CH6_MASK           ((1<<MUX2)|(1<<MUX1))
+#define ADC_MUX_CH7_MASK           ((1<<MUX2)|(1<<MUX1)|(1<<MUX0))
+
+// Available clocks
+#define ADC_ST1_CLKALL_MASK        ((1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0))
+#define ADC_ST1_125KHZ_MASK        ADC_ST1_CLKALL_MASK
+#define ADC_ST1_250KHZ_MASK        ((1<<ADPS2)|(1<<ADPS1))
+#define ADC_ST1_500KHZ_MASK        ((1<<ADPS2)|(1<<ADPS0))
+#define ADC_ST1_001MHZ_MASK        (1<<ADPS2)
+#define ADC_ST1_002MHZ_MASK        ((1<<ADPS1)|(1<<ADPS0))
+#define ADC_ST1_004MHZ_MASK        (1<<ADPS1)
+#define ADC_ST1_008MHZ_MASK        ADC_ST1_CLKALL_MASK
+
+#endif // CPU_MAP_ATMEGA328P
+#endif // cpu_map_adc_h