FastArduino v1.10
C++ library to build fast but small Arduino/AVR projects
Loading...
Searching...
No Matches
analog_input.h
Go to the documentation of this file.
1// Copyright 2016-2023 Jean-Francois Poilpret
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
16
21#ifndef ANALOGINPUT_HH
22#define ANALOGINPUT_HH
23
24#include "boards/board_traits.h"
25#include "time.h"
26
30namespace analog
31{
32 //TODO LATER: add class (or namespace?) with general methods enable/disable ADC...
33
48 template<board::AnalogPin APIN_, typename SAMPLE_TYPE_ = uint16_t,
49 board::AnalogReference AREF_ = board::AnalogReference::AVCC,
50 board::AnalogClock MAXFREQ_ = board::AnalogClock::MAX_FREQ_200KHz>
52 {
53 public:
58 static constexpr const board::AnalogPin APIN = APIN_;
62 static constexpr const board::AnalogReference AREF = AREF_;
66 using SAMPLE_TYPE = SAMPLE_TYPE_;
71 static constexpr const board::AnalogClock MAXFREQ = MAXFREQ_;
72
73 private:
74 using TRAIT = board_traits::AnalogPin_trait<APIN>;
75 using GLOBAL_TRAIT = board_traits::GlobalAnalogPin_trait;
76 using AREF_TRAIT = board_traits::AnalogReference_trait<AREF>;
77 using TYPE_TRAIT = board_traits::AnalogSampleType_trait<SAMPLE_TYPE>;
78 using FREQ_TRAIT = board_traits::AnalogClock_trait<MAXFREQ>;
79
80 static constexpr const uint16_t BG_STABILIZATION_DELAY_US = 400;
81
82 public:
83 AnalogInput() = default;
84 AnalogInput(const AnalogInput&) = delete;
85 AnalogInput& operator=(const AnalogInput&) = delete;
86
91
96 static constexpr const uint8_t PRESCALER = FREQ_TRAIT::PRESCALER;
97
105 {
106 // First ensure that any pending sampling is finished
107 GLOBAL_TRAIT::ADCSRA_.loop_until_bit_clear(ADSC);
108 // Setup multiplexer selection and start conversion
109 GLOBAL_TRAIT::ADMUX_ = AREF_TRAIT::MASK | TYPE_TRAIT::ADLAR1 | TRAIT::MUX_MASK1;
110 GLOBAL_TRAIT::ADCSRB_ = TRAIT::MUX_MASK2 | TYPE_TRAIT::ADLAR2;
111
112 // The following delay is necessary for bandgap ADC, strangely 70us should be enough (datasheet)
113 // but this works only when no other ADC is used "at the same time"
114 // In this situation, a delay of minimum 400us seems necessary to ensure bandgap reference voltage is stabilized
115 if (TRAIT::IS_BANDGAP) time::delay_us(BG_STABILIZATION_DELAY_US);
116
117 GLOBAL_TRAIT::ADCSRA_ = bits::BV8(ADEN, ADSC) | TRAIT::MUX_MASK2 | FREQ_TRAIT::PRESCALER_MASK;
118 // Wait until sampling is done
119 GLOBAL_TRAIT::ADCSRA_.loop_until_bit_clear(ADSC);
120 // Should we synchronize ADC reading?
121 return TYPE_TRAIT::ADC_;
122 }
123 };
124
133 template<board::AnalogPin BANDGAP_ = board::AnalogPin::BANDGAP>
135 : public AnalogInput<BANDGAP_, uint16_t, board::AnalogReference::AVCC, board::AnalogClock::MAX_FREQ_50KHz>
136 {
137 public:
141 static constexpr const board::AnalogPin BANDGAP = BANDGAP_;
142
143 private:
144 using TRAIT = board_traits::AnalogPin_trait<BANDGAP>;
145 static_assert(TRAIT::IS_BANDGAP, "BANDGAP_ parameter must be a bandgap ADC input");
146 static constexpr const uint16_t REFERENCE_MV = TRAIT::BANDGAP_VOLTAGE_MV;
147
148 public:
149 PowerVoltage() = default;
150 PowerVoltage(const PowerVoltage&) = delete;
151 PowerVoltage& operator=(const PowerVoltage&) = delete;
152
158 uint16_t voltage_mV()
159 {
160 // Get sample
161 uint16_t rate = this->template sample();
162 // Do the maths to find out Vcc from rate:
163 return REFERENCE_MV * 1024L / rate;
164 }
165 };
166
167 //TODO LATER: need ISR also
168 // Find better class name
169 //TODO Implement mechanism to ensure only DeferredAnalogInput can be registered
170 // (need sth like one AnalogInputManager?)
171 // template<board::AnalogPin APIN, board::AnalogReference AREF = board::AnalogReference::AVCC,
172 // typename SAMPLE_TYPE = uint16_t>
173 // class DeferredAnalogInput
174 // {
175 // public:
176 // DeferredAnalogInput();
177 // void start();
178 // void stop();
179 // SAMPLE_TYPE sample();
180 // //Other API? eg sample_ready? sample_changed?
181
182 // private:
183 // SAMPLE_TYPE sample_;
184 // };
185}
186
187#endif /* ANALOGINPUT_HH */
API that handles a given analog input pin of the target MCU.
Definition: analog_input.h:52
static constexpr const board::AnalogPin APIN
The analog pin for this AnalogInput; this may also not be a real pin but an internal sensor (e....
Definition: analog_input.h:58
static constexpr const uint8_t PRESCALER
The prescaler used by ADC circuitry, calculated from MAXFREQ template parameter.
Definition: analog_input.h:96
SAMPLE_TYPE sample()
Start an analog-digital conversion for this analog input pin and return sample value.
Definition: analog_input.h:104
static constexpr const board::AnalogClock MAXFREQ
The maximum input clock frequency of the ADC circuit; higher frequencies imply lower precision of sam...
Definition: analog_input.h:71
static constexpr const board::AnalogReference AREF
The analog reference to use for that analog input.
Definition: analog_input.h:62
SAMPLE_TYPE TYPE
The type of samples returned by sample().
Definition: analog_input.h:90
SAMPLE_TYPE_ SAMPLE_TYPE
The type of samples returned by sample().
Definition: analog_input.h:66
API that uses bandgap feature to calculate current voltage fed to the MCU.
Definition: analog_input.h:136
uint16_t voltage_mV()
Get the voltage, in mV, feeding the MCU.
Definition: analog_input.h:158
static constexpr const board::AnalogPin BANDGAP
The bandgap analog pin of the MCU target, used for this PowerVoltage.
Definition: analog_input.h:141
Defines all API to manipulate analog input/output.
static constexpr uint8_t BV8(uint8_t bit)
Create a uint8_t bitmask for the given bit number.
Definition: bits.h:41
AnalogClock
Defines available clocks of the target MCU, used for analog input.
Definition: empty.h:63
AnalogPin
Defines all available analog input pins of the target MCU.
Definition: empty.h:77
AnalogReference
Defines available voltage references of the target MCU, used for analog input.
Definition: empty.h:70
void delay_us(uint16_t us) INLINE
Delay program execution for the given amount of microseconds.
Definition: time.h:334
Simple time utilities.