Skip to content

Commit

Permalink
Use maximum ADC resolution, Array bounds checks
Browse files Browse the repository at this point in the history
  • Loading branch information
tttapa committed Oct 12, 2019
1 parent 4549007 commit 3c01c7d
Show file tree
Hide file tree
Showing 17 changed files with 145 additions and 60 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ set(CMAKE_CPP_FLAGS "${CMAKE_CPP_FLAGS} \

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} \
-g3 -ggdb -O0 -Wall -Wextra -Werror \
-fno-inline-functions \
-fdiagnostics-show-option -Wsuggest-override \
-Wdouble-promotion \
-Wswitch-default -Wswitch-enum -Wimplicit-fallthrough=3 \
Expand Down
4 changes: 2 additions & 2 deletions examples/6.Hardware/FilteredAnalog/FilteredAnalog.ino
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@

// Create a filtered analog object on pin A0:
FilteredAnalog<10, // Output precision in bits
4, // How many bits to upsample
2, // The amount of filtering
uint16_t // The integer type for the calculations
>
Expand All @@ -47,7 +46,6 @@ FilteredAnalog<10, // Output precision in bits
// The number of bits required for the intermediate calculations increases if
// you do so, so you have to use a larger type as well.
FilteredAnalog<10, // Output precision in bits
4, // How many bits to upsample
6, // The amount of filtering
uint32_t // The integer type for the calculations
>
Expand All @@ -61,6 +59,8 @@ void setup() {
Serial.begin(115200);
while (!Serial)
;
// Select the correct ADC resolution
FilteredAnalog<>::setupADC();
// If you want, you can add mapping functions to invert the input, for example
analog.invert();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ MCU::AnalogVUDisplay vu_display_R = {
// ========================================================================== //

constexpr float maxGain = 5;
FilteredAnalog<7> gainKnob = A1;
FilteredAnalog<> gainKnob = A1;

// --------------------------------- Setup ---------------------------------- //
// ========================================================================== //
Expand All @@ -184,6 +184,7 @@ void setup() {
// The default SPI MOSI pin (11) is used for I²S, so we need to use the
// alternative MOSI pin (7)
SPI.setMOSI(7);
FilteredAnalog<>::setupADC();
display_L.begin();
display_R.begin();
}
Expand Down
2 changes: 1 addition & 1 deletion src/Audio/VolumeControl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ class VolumeControl : public Updatable<Potentiometer> {

private:
Array<AudioMixer4 *, N> mixers;
FilteredAnalog<7> filteredAnalog;
FilteredAnalog<> filteredAnalog;
const float maxGain;
};

Expand Down
5 changes: 2 additions & 3 deletions src/Control_Surface/Control_Surface_Class.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "Control_Surface_Class.hpp"
#include <Hardware/ExtendedInputOutput/ExtendedIOElement.hpp>
#include <Hardware/FilteredAnalog.hpp>
#include <MIDI_Constants/Control_Change.hpp>
#include <MIDI_Inputs/MIDIInputElementCC.hpp>
#include <MIDI_Inputs/MIDIInputElementChannelPressure.hpp>
Expand All @@ -22,9 +23,7 @@ void Control_Surface_::begin() {
DEBUG_OUT.begin(defaultBaudRate);
delay(250);
#endif
#ifdef ARDUINO_ARCH_ESP32
analogReadResolution(10);
#endif
FilteredAnalog<>::setupADC();
ExtendedIOElement::beginAll();
MIDI().begin(); // initialize the MIDI interface
MIDI().setCallbacks(this);
Expand Down
3 changes: 0 additions & 3 deletions src/Def/Def.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,6 @@

BEGIN_CS_NAMESPACE

/// The bit depth of the ADC (Analog to Digital Converter).
constexpr static uint8_t ADC_BITS = 10;

/// The type returned from analogRead and similar functions.
using analog_t = uint16_t;
/// The type for Arduino pins (and ExtendedIOElement pins).
Expand Down
18 changes: 14 additions & 4 deletions src/Hardware/FilteredAnalog.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <Helpers/EMA.hpp>
#include <Helpers/Hysteresis.hpp>
#include <Helpers/IncreaseBitDepth.hpp>
#include <Helpers/MinMaxFix.hpp>
#include <Settings/SettingsWrapper.hpp>

BEGIN_CS_NAMESPACE
Expand All @@ -21,8 +22,6 @@ BEGIN_CS_NAMESPACE
*
* @tparam Precision
* The number of bits of precision the output should have.
* @tparam Upsample
* The number of bits to upsample the analog reading to.
* @tparam FilterShiftFactor
* The number of bits used for the EMA filter.
* The pole location is
Expand All @@ -34,12 +33,17 @@ BEGIN_CS_NAMESPACE
* Should be at least
* @f$ 10 + \mathrm{Upsample} + \mathrm{FilterShiftFactor} @f$
* bits (@f$10@f$ is the number of bits of the ADC).
* @tparam Upsample
* The number of bits to upsample the analog reading by.
*
* @ingroup HardwareUtils
*/
template <uint8_t Precision = ADC_BITS, uint8_t Upsample = ANALOG_UPSAMPLE,
template <uint8_t Precision = 10,
uint8_t FilterShiftFactor = ANALOG_FILTER_SHIFT_FACTOR,
class FilterType = ANALOG_FILTER_TYPE>
class FilterType = ANALOG_FILTER_TYPE,
uint8_t Upsample =
min(sizeof(FilterType) * CHAR_BIT - ADC_BITS - FilterShiftFactor,
sizeof(analog_t) * CHAR_BIT - ADC_BITS)>
class FilteredAnalog {
public:
/**
Expand Down Expand Up @@ -127,6 +131,12 @@ class FilteredAnalog {
analog_t>(ExtIO::analogRead(analogPin));
}

static void setupADC() {
#if HAS_ANALOG_READ_RESOLUTION
analogReadResolution(ADC_BITS);
#endif
}

private:
const pin_t analogPin;

Expand Down
68 changes: 68 additions & 0 deletions src/Helpers/ADCConfig.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
#pragma once

/**
* @file
* @brief This file contains the platform-specific ADC resolutions.
* By default, the library automatically selects the maximum supported
* resolution for known boards, otherwise, it falls back to 10 bits.
* @see ADC_BITS
*/

#include <Arduino.h>

#if defined(ADC_RESOLUTION)
#define HAS_ANALOG_READ_RESOLUTION 1

// Teensy
//------------------------------------------------------------------------------
#elif defined(TEENSYDUINO) && !defined(DOXYGEN)

#if defined(__AVR__) // Teensy 2.x
#define ADC_RESOLUTION 10
#define HAS_ANALOG_READ_RESOLUTION 0

#elif defined(__MK20DX128__) // Teensy 3.0
#define ADC_RESOLUTION 13
#define HAS_ANALOG_READ_RESOLUTION 1

#elif defined(__MK20DX256__) // Teensy 3.1/3.2
#define ADC_RESOLUTION 13
#define HAS_ANALOG_READ_RESOLUTION 1

#elif defined(__MKL26Z64__) // Teensy LC
#define ADC_RESOLUTION 12
#define HAS_ANALOG_READ_RESOLUTION 1

#elif defined(__MK64FX512__) // Teensy 3.5
#define ADC_RESOLUTION 13
#define HAS_ANALOG_READ_RESOLUTION 1

#elif defined(__MK66FX1M0__) // Teensy 3.6
#define ADC_RESOLUTION 13
#define HAS_ANALOG_READ_RESOLUTION 1

#elif defined(__IMXRT1062__) || defined(__IMXRT1052__) // Teensy 4.0
#define ADC_RESOLUTION 12
#define HAS_ANALOG_READ_RESOLUTION 1

#else
#warning "Unknown Teensy board, please open an issue on GitHub" \
"https://github.com/tttapa/Control-Surface"
#endif

// ESP32
//------------------------------------------------------------------------------
#elif defined(ESP32)

#define ADC_RESOLUTION 12
#define HAS_ANALOG_READ_RESOLUTION 1

// Unknown/Default
//------------------------------------------------------------------------------
#else
/// The actual maximum resolution of the built-in ADC.
#define ADC_RESOLUTION 10
/// Whether the platform supports the `analogReadResolution` function.
#define HAS_ANALOG_READ_RESOLUTION 0

#endif
22 changes: 7 additions & 15 deletions src/Helpers/Array.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

#pragma once

#include <Arduino.h>
#include <Helpers/Error.hpp>
#include <stddef.h>

/**
Expand All @@ -21,41 +21,33 @@ struct Array {
/**
* @brief Get the element at the given index.
*
* @note No bounds checking is performed.
* @note Bounds checking is performed. If fatal errors are disabled, the
* last element is returned if the index is out of bounds.
*
* @param index
* The (zero-based) index of the element to return.
*/
T &operator[](size_t index) {
if (index >= N) { // TODO
Serial.println(__PRETTY_FUNCTION__);
Serial.print(F("Index out of bounds: "));
Serial.println(index);
ERROR(F("Index out of bounds: ") << index << F("") << N, 0xEDED);
index = N - 1;
#ifdef ARDUINO
delay(5000);
#endif
}
return data[index];
}

/**
* @brief Get the element at the given index.
*
* @note No bounds checking is performed.
* @note Bounds checking is performed. If fatal errors are disabled, the
* last element is returned if the index is out of bounds.
*
* @param index
* The (zero-based) index of the element to return.
*/
const T &operator[](size_t index) const {
if (index >= N) { // TODO
Serial.println(__PRETTY_FUNCTION__);
Serial.print(F("Index out of bounds: "));
Serial.println(index);
ERROR(F("Index out of bounds: ") << index << F("") << N, 0xEDED);
index = N - 1;
#ifdef ARDUINO
delay(5000);
#endif
}
return data[index];
}
Expand Down
11 changes: 7 additions & 4 deletions src/Helpers/MinMaxFix.hpp
Original file line number Diff line number Diff line change
@@ -1,19 +1,22 @@
#pragma once

#include <Arduino.h>
#include <Settings/NamespaceSettings.hpp>

BEGIN_CS_NAMESPACE
#ifdef min
#undef min
#endif
template <class T, class U>
auto min(const T &a, const U &b) -> decltype(b < a ? b : a) {
constexpr auto min(const T &a, const U &b) -> decltype(b < a ? b : a) {
return b < a ? b : a;
}
#endif

#ifdef max
#undef max
#endif
template <class T, class U>
auto max(const T &a, const U &b) -> decltype(b < a ? b : a) {
constexpr auto max(const T &a, const U &b) -> decltype(b < a ? b : a) {
return a < b ? b : a;
}
#endif
END_CS_NAMESPACE
4 changes: 2 additions & 2 deletions src/MIDI_Inputs/MIDIInputElement.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ class MIDIInputElement {
* that use data1 as an address (i.e. Note On, Note Off, Polyphonic
* Key Pressure and Control Change).
*/
virtual inline MIDICNChannelAddress
virtual MIDICNChannelAddress
getTarget(const ChannelMessageMatcher &midimsg) const {
return {int8_t(midimsg.data1), Channel(midimsg.channel), midimsg.CN};
}
Expand All @@ -69,7 +69,7 @@ class MIDIInputElement {
* @note This base version of the function is only valid for non-Bankable
* MIDI input elements.
*/
virtual inline bool match(const MIDICNChannelAddress &target) const {
virtual bool match(const MIDICNChannelAddress &target) const {
return MIDICNChannelAddress::matchSingle(this->address, target);
}

Expand Down
4 changes: 1 addition & 3 deletions src/MIDI_Inputs/MIDIInputElementNote.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,6 @@ BEGIN_CS_NAMESPACE
class MIDIInputElementNote : public MIDIInputElement,
public DoublyLinkable<MIDIInputElementNote> {
protected:
MIDIInputElementNote() {} // not used, only for virtual inheritance

public:
/**
* @brief Constructor.
* @todo Documentation.
Expand All @@ -33,6 +30,7 @@ class MIDIInputElementNote : public MIDIInputElement,
elements.append(this);
}

public:
/**
* @brief Destructor.
* @todo Documentation.
Expand Down
8 changes: 2 additions & 6 deletions src/MIDI_Outputs/Abstract/MIDIFilteredAnalog.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,7 @@ class MIDIFilteredAnalogAddressable : public MIDIOutputElement {
analog_t getValue() const { return filteredAnalog.getValue(); }

private:
FilteredAnalog<Sender::precision(), 16 - ADC_BITS,
ANALOG_FILTER_SHIFT_FACTOR, uint32_t>
filteredAnalog;
FilteredAnalog<Sender::precision()> filteredAnalog;
const MIDICNChannelAddress address;

public:
Expand Down Expand Up @@ -135,9 +133,7 @@ class MIDIFilteredAnalog : public MIDIOutputElement {
analog_t getValue() const { return filteredAnalog.getValue(); }

private:
FilteredAnalog<Sender::precision(), 16 - ADC_BITS,
ANALOG_FILTER_SHIFT_FACTOR, uint32_t>
filteredAnalog;
FilteredAnalog<Sender::precision()> filteredAnalog;
const MIDICNChannelAddress address;

public:
Expand Down
8 changes: 2 additions & 6 deletions src/MIDI_Outputs/Bankable/Abstract/MIDIFilteredAnalog.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,7 @@ class MIDIFilteredAnalogAddressable : public MIDIOutputElement {

private:
BankAddress address;
FilteredAnalog<Sender::precision(), 16 - ADC_BITS,
ANALOG_FILTER_SHIFT_FACTOR, uint32_t>
filteredAnalog;
FilteredAnalog<Sender::precision()> filteredAnalog;

public:
Sender sender;
Expand Down Expand Up @@ -139,9 +137,7 @@ class MIDIFilteredAnalog : public MIDIOutputElement {

private:
BankAddress address;
FilteredAnalog<Sender::precision(), 16 - ADC_BITS,
ANALOG_FILTER_SHIFT_FACTOR, uint32_t>
filteredAnalog;
FilteredAnalog<Sender::precision()> filteredAnalog;

public:
Sender sender;
Expand Down
1 change: 1 addition & 0 deletions src/MIDI_Parsers/MIDI_Parser.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <stdint.h>
#include <stdlib.h>

#include <Def/Def.hpp>
#include <Settings/SettingsWrapper.hpp>

BEGIN_CS_NAMESPACE
Expand Down
Loading

0 comments on commit 3c01c7d

Please sign in to comment.