ADC.h
/* Teensy 4, 3.x, LC ADC library
* https://github.com/pedvide/ADC
* Copyright (c) 2019 Pedro Villanueva
*
* 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.
*/
/* TODO
* - Function to measure more that 1 pin consecutively (stream?)
*
* bugs:
* - comparison values in 16 bit differential mode are twice what they should be
*/
#ifndef ADC_H
#define ADC_H
#define ADC_0 0
#define ADC_1 1
//enum class ADC_NUM {ADC_0, ADC_1}; // too verbose, but it'd avoid some mistakes
// include ADC module class
#include "ADC_Module.h"
#ifdef __cplusplus
extern "C" {
#endif
class ADC
{
protected:
private:
// ADCs objects
ADC_Module adc0_obj;
#ifdef ADC_DUAL_ADCS
ADC_Module adc1_obj;
#endif
const uint8_t num_ADCs = ADC_NUM_ADCS;
public:
ADC();
// create both adc objects
ADC_Module *const adc0 = &adc0_obj; // adc object pointer
#ifdef ADC_DUAL_ADCS
ADC_Module *const adc1 = &adc1_obj; // adc object pointer
#endif
#ifdef ADC_SINGLE_ADC
ADC_Module *const adc[ADC_NUM_ADCS] = {adc0};
#else
ADC_Module *const adc[ADC_NUM_ADCS] = {adc0, adc1};
#endif
int analogRead(uint8_t pin, int8_t adc_num = -1);
int analogRead(ADC_INTERNAL_SOURCE pin, int8_t adc_num = -1) __attribute__((always_inline)) {
return analogRead(static_cast<uint8_t>(pin), adc_num);
}
#if ADC_DIFF_PAIRS > 0
int analogReadDifferential(uint8_t pinP, uint8_t pinN, int8_t adc_num = -1);
#endif
bool startSingleRead(uint8_t pin, int8_t adc_num = -1);
#if ADC_DIFF_PAIRS > 0
bool startSingleDifferential(uint8_t pinP, uint8_t pinN, int8_t adc_num = -1);
#endif
int readSingle(int8_t adc_num = -1);
bool startContinuous(uint8_t pin, int8_t adc_num = -1);
#if ADC_DIFF_PAIRS > 0
bool startContinuousDifferential(uint8_t pinP, uint8_t pinN, int8_t adc_num = -1);
#endif
int analogReadContinuous(int8_t adc_num = -1);
void stopContinuous(int8_t adc_num = -1);
#ifdef ADC_DUAL_ADCS
struct Sync_result{
int32_t result_adc0, result_adc1;
};
Sync_result analogSynchronizedRead(uint8_t pin0, uint8_t pin1);
Sync_result analogSyncRead(uint8_t pin0, uint8_t pin1) __attribute__((always_inline)) {return analogSynchronizedRead(pin0, pin1);}
#if ADC_DIFF_PAIRS > 0
Sync_result analogSynchronizedReadDifferential(uint8_t pin0P, uint8_t pin0N, uint8_t pin1P, uint8_t pin1N);
Sync_result analogSyncReadDifferential(uint8_t pin0P, uint8_t pin0N, uint8_t pin1P, uint8_t pin1N) __attribute__((always_inline)) {
return analogSynchronizedReadDifferential(pin0P, pin0N, pin1P, pin1N);
}
#endif
bool startSynchronizedSingleRead(uint8_t pin0, uint8_t pin1);
#if ADC_DIFF_PAIRS > 0
bool startSynchronizedSingleDifferential(uint8_t pin0P, uint8_t pin0N, uint8_t pin1P, uint8_t pin1N);
#endif
Sync_result readSynchronizedSingle();
bool startSynchronizedContinuous(uint8_t pin0, uint8_t pin1);
#if ADC_DIFF_PAIRS > 0
bool startSynchronizedContinuousDifferential(uint8_t pin0P, uint8_t pin0N, uint8_t pin1P, uint8_t pin1N);
#endif
Sync_result readSynchronizedContinuous();
void stopSynchronizedContinuous();
#endif
void resetError() {
for(int i=0; i< ADC_NUM_ADCS; i++) {
adc[i]->resetError();
}
}
// should this be a constexpr?
static const uint8_t channel2sc1aADC0[ADC_MAX_PIN+1];
#ifdef ADC_DUAL_ADCS
static const uint8_t channel2sc1aADC1[ADC_MAX_PIN+1];
#endif
static const uint8_t sc1a2channelADC0[ADC_MAX_PIN+1];
#ifdef ADC_DUAL_ADCS
static const uint8_t sc1a2channelADC1[ADC_MAX_PIN+1];
#endif
#if ADC_DIFF_PAIRS > 0
static const ADC_Module::ADC_NLIST diff_table_ADC0[ADC_DIFF_PAIRS];
#ifdef ADC_DUAL_ADCS
static const ADC_Module::ADC_NLIST diff_table_ADC1[ADC_DIFF_PAIRS];
#endif
#endif
};
#ifdef __cplusplus
}
#endif
#endif // ADC_H
ADC::adc0
ADC_Module *const adc0
Object to control the ADC0.
Definition: ADC.h:92
ADC::readSynchronizedContinuous
Sync_result readSynchronizedContinuous()
Returns the values of both ADCs.
ADC::adc
ADC_Module *const adc[ADC_NUM_ADCS]
Array with the ADC Modules.
Definition: ADC.h:103
ADC::startSynchronizedContinuous
bool startSynchronizedContinuous(uint8_t pin0, uint8_t pin1)
Starts a continuous conversion in both ADCs simultaneously.
ADC::analogReadContinuous
int analogReadContinuous(int8_t adc_num=-1)
Reads the analog value of a continuous conversion.
ADC::analogSynchronizedRead
Sync_result analogSynchronizedRead(uint8_t pin0, uint8_t pin1)
Returns the analog values of both pins, measured at the same time by the two ADC modules.
ADC::startContinuous
bool startContinuous(uint8_t pin, int8_t adc_num=-1)
Starts continuous conversion on the pin.
ADC_Module::resetError
void resetError()
Resets all errors from the ADC, if any.
Definition: ADC_Module.h:659
ADC::readSingle
int readSingle(int8_t adc_num=-1)
Reads the analog value of a single conversion.
ADC::channel2sc1aADC0
static const uint8_t channel2sc1aADC0[ADC_MAX_PIN+1]
Translate pin number to SC1A nomenclature.
Definition: ADC.h:358
ADC::readSynchronizedSingle
Sync_result readSynchronizedSingle()
Reads the analog value of a single conversion.
ADC::analogRead
int analogRead(ADC_INTERNAL_SOURCE pin, int8_t adc_num=-1)
Returns the analog value of the special internal source, such as the temperature sensor.
Definition: ADC.h:133
ADC_Module
Definition: ADC_Module.h:54
ADC::sc1a2channelADC1
static const uint8_t sc1a2channelADC1[ADC_MAX_PIN+1]
Translate pin number to SC1A nomenclature for differential pins.
Definition: ADC.h:368
ADC::analogSyncRead
Sync_result analogSyncRead(uint8_t pin0, uint8_t pin1)
Same as analogSynchronizedRead.
Definition: ADC.h:253
ADC::startSynchronizedSingleRead
bool startSynchronizedSingleRead(uint8_t pin0, uint8_t pin1)
Starts an analog measurement at the same time on the two ADC modules.
ADC
Definition: ADC.h:68
ADC::adc1
ADC_Module *const adc1
Object to control the ADC1.
Definition: ADC.h:95
ADC::channel2sc1aADC1
static const uint8_t channel2sc1aADC1[ADC_MAX_PIN+1]
Translate pin number to SC1A nomenclature.
Definition: ADC.h:361
ADC::stopSynchronizedContinuous
void stopSynchronizedContinuous()
Stops synchronous continuous conversion.
ADC::ADC
ADC()
ADC_settings::ADC_INTERNAL_SOURCE
ADC_INTERNAL_SOURCE
Definition: settings_defines.h:241
ADC::stopContinuous
void stopContinuous(int8_t adc_num=-1)
Stops continuous conversion.
ADC::resetError
void resetError()
Definition: ADC.h:349
ADC::analogRead
int analogRead(uint8_t pin, int8_t adc_num=-1)
Returns the analog value of the pin.
ADC::Sync_result
Struct for synchronous measurements.
Definition: ADC.h:230
ADC::sc1a2channelADC0
static const uint8_t sc1a2channelADC0[ADC_MAX_PIN+1]
Translate pin number to SC1A nomenclature for differential pins.
Definition: ADC.h:365
ADC::startSingleRead
bool startSingleRead(uint8_t pin, int8_t adc_num=-1)
Starts an analog measurement on the pin and enables interrupts.