Add Arduino SAM compatible analogReadResolution and Non-Blocking ADC api
connected to: https://github.com/espressif/arduino-esp32/issues/220 and https://github.com/espressif/arduino-esp32/issues/161
This commit is contained in:
parent
8fb8478431
commit
eb46978a8d
@ -28,12 +28,16 @@ static uint8_t __analogCycles = 8;
|
|||||||
static uint8_t __analogSamples = 0;//1 sample
|
static uint8_t __analogSamples = 0;//1 sample
|
||||||
static uint8_t __analogClockDiv = 1;
|
static uint8_t __analogClockDiv = 1;
|
||||||
|
|
||||||
|
// Width of returned answer ()
|
||||||
|
static uint8_t __analogReturnedWidth = 12;
|
||||||
|
|
||||||
void __analogSetWidth(uint8_t bits){
|
void __analogSetWidth(uint8_t bits){
|
||||||
if(bits < 9){
|
if(bits < 9){
|
||||||
bits = 9;
|
bits = 9;
|
||||||
} else if(bits > 12){
|
} else if(bits > 12){
|
||||||
bits = 12;
|
bits = 12;
|
||||||
}
|
}
|
||||||
|
__analogReturnedWidth = bits;
|
||||||
__analogWidth = bits - 9;
|
__analogWidth = bits - 9;
|
||||||
SET_PERI_REG_BITS(SENS_SAR_START_FORCE_REG, SENS_SAR1_BIT_WIDTH, __analogWidth, SENS_SAR1_BIT_WIDTH_S);
|
SET_PERI_REG_BITS(SENS_SAR_START_FORCE_REG, SENS_SAR1_BIT_WIDTH, __analogWidth, SENS_SAR1_BIT_WIDTH_S);
|
||||||
SET_PERI_REG_BITS(SENS_SAR_READ_CTRL_REG, SENS_SAR1_SAMPLE_BIT, __analogWidth, SENS_SAR1_SAMPLE_BIT_S);
|
SET_PERI_REG_BITS(SENS_SAR_READ_CTRL_REG, SENS_SAR1_SAMPLE_BIT, __analogWidth, SENS_SAR1_SAMPLE_BIT_S);
|
||||||
@ -124,14 +128,14 @@ void __analogSetPinAttenuation(uint8_t pin, adc_attenuation_t attenuation)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t IRAM_ATTR __analogRead(uint8_t pin)
|
bool IRAM_ATTR __adcAttachPin(uint8_t pin){
|
||||||
{
|
|
||||||
int8_t channel = digitalPinToAnalogChannel(pin);
|
int8_t channel = digitalPinToAnalogChannel(pin);
|
||||||
if(channel < 0){
|
if(channel < 0){
|
||||||
return 0;//not adc pin
|
return false;//not adc pin
|
||||||
}
|
}
|
||||||
int8_t pad = digitalPinToTouchChannel(pin);
|
|
||||||
|
|
||||||
|
int8_t pad = digitalPinToTouchChannel(pin);
|
||||||
if(pad >= 0){
|
if(pad >= 0){
|
||||||
uint32_t touch = READ_PERI_REG(SENS_SAR_TOUCH_ENABLE_REG);
|
uint32_t touch = READ_PERI_REG(SENS_SAR_TOUCH_ENABLE_REG);
|
||||||
if(touch & (1 << pad)){
|
if(touch & (1 << pad)){
|
||||||
@ -149,22 +153,84 @@ uint16_t IRAM_ATTR __analogRead(uint8_t pin)
|
|||||||
pinMode(pin, ANALOG);
|
pinMode(pin, ANALOG);
|
||||||
|
|
||||||
__analogInit();
|
__analogInit();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if(channel > 7){
|
bool IRAM_ATTR __adcStart(uint8_t pin){
|
||||||
channel -= 10;
|
|
||||||
|
|
||||||
SET_PERI_REG_BITS(SENS_SAR_MEAS_START2_REG, SENS_SAR2_EN_PAD, (1 << channel), SENS_SAR2_EN_PAD_S);
|
int8_t channel = digitalPinToAnalogChannel(pin);
|
||||||
CLEAR_PERI_REG_MASK(SENS_SAR_MEAS_START2_REG, SENS_MEAS2_START_SAR_M);
|
if(channel < 0){
|
||||||
SET_PERI_REG_MASK(SENS_SAR_MEAS_START2_REG, SENS_MEAS2_START_SAR_M);
|
return false;//not adc pin
|
||||||
while (GET_PERI_REG_MASK(SENS_SAR_MEAS_START2_REG, SENS_MEAS2_DONE_SAR) == 0) {}; //read done
|
|
||||||
return GET_PERI_REG_BITS2(SENS_SAR_MEAS_START2_REG, SENS_MEAS2_DATA_SAR, SENS_MEAS2_DATA_SAR_S);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SET_PERI_REG_BITS(SENS_SAR_MEAS_START1_REG, SENS_SAR1_EN_PAD, (1 << channel), SENS_SAR1_EN_PAD_S);
|
if(channel > 9){
|
||||||
CLEAR_PERI_REG_MASK(SENS_SAR_MEAS_START1_REG, SENS_MEAS1_START_SAR_M);
|
channel -= 10;
|
||||||
SET_PERI_REG_MASK(SENS_SAR_MEAS_START1_REG, SENS_MEAS1_START_SAR_M);
|
CLEAR_PERI_REG_MASK(SENS_SAR_MEAS_START2_REG, SENS_MEAS2_START_SAR_M);
|
||||||
while (GET_PERI_REG_MASK(SENS_SAR_MEAS_START1_REG, SENS_MEAS1_DONE_SAR) == 0) {}; //read done
|
SET_PERI_REG_BITS(SENS_SAR_MEAS_START2_REG, SENS_SAR2_EN_PAD, (1 << channel), SENS_SAR2_EN_PAD_S);
|
||||||
return GET_PERI_REG_BITS2(SENS_SAR_MEAS_START1_REG, SENS_MEAS1_DATA_SAR, SENS_MEAS1_DATA_SAR_S);
|
SET_PERI_REG_MASK(SENS_SAR_MEAS_START2_REG, SENS_MEAS2_START_SAR_M);
|
||||||
|
} else {
|
||||||
|
CLEAR_PERI_REG_MASK(SENS_SAR_MEAS_START1_REG, SENS_MEAS1_START_SAR_M);
|
||||||
|
SET_PERI_REG_BITS(SENS_SAR_MEAS_START1_REG, SENS_SAR1_EN_PAD, (1 << channel), SENS_SAR1_EN_PAD_S);
|
||||||
|
SET_PERI_REG_MASK(SENS_SAR_MEAS_START1_REG, SENS_MEAS1_START_SAR_M);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IRAM_ATTR __adcBusy(uint8_t pin){
|
||||||
|
|
||||||
|
int8_t channel = digitalPinToAnalogChannel(pin);
|
||||||
|
if(channel < 0){
|
||||||
|
return false;//not adc pin
|
||||||
|
}
|
||||||
|
|
||||||
|
if(channel > 7){
|
||||||
|
return (GET_PERI_REG_MASK(SENS_SAR_MEAS_START2_REG, SENS_MEAS2_DONE_SAR) == 0);
|
||||||
|
}
|
||||||
|
return (GET_PERI_REG_MASK(SENS_SAR_MEAS_START1_REG, SENS_MEAS1_DONE_SAR) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t IRAM_ATTR __adcEnd(uint8_t pin)
|
||||||
|
{
|
||||||
|
|
||||||
|
uint16_t value = 0;
|
||||||
|
int8_t channel = digitalPinToAnalogChannel(pin);
|
||||||
|
if(channel < 0){
|
||||||
|
return 0;//not adc pin
|
||||||
|
}
|
||||||
|
if(channel > 7){
|
||||||
|
while (GET_PERI_REG_MASK(SENS_SAR_MEAS_START2_REG, SENS_MEAS2_DONE_SAR) == 0); //wait for conversion
|
||||||
|
value = GET_PERI_REG_BITS2(SENS_SAR_MEAS_START2_REG, SENS_MEAS2_DATA_SAR, SENS_MEAS2_DATA_SAR_S);
|
||||||
|
} else {
|
||||||
|
while (GET_PERI_REG_MASK(SENS_SAR_MEAS_START1_REG, SENS_MEAS1_DONE_SAR) == 0); //wait for conversion
|
||||||
|
value = GET_PERI_REG_BITS2(SENS_SAR_MEAS_START1_REG, SENS_MEAS1_DATA_SAR, SENS_MEAS1_DATA_SAR_S);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Shift result if necessary
|
||||||
|
uint8_t from = __analogWidth + 9;
|
||||||
|
if (from == __analogReturnedWidth) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
if (from > __analogReturnedWidth) {
|
||||||
|
return value >> (from - __analogReturnedWidth);
|
||||||
|
}
|
||||||
|
return value << (__analogReturnedWidth - from);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t IRAM_ATTR __analogRead(uint8_t pin)
|
||||||
|
{
|
||||||
|
if(!__adcAttachPin(pin) || !__adcStart(pin)){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return __adcEnd(pin);
|
||||||
|
}
|
||||||
|
|
||||||
|
void __analogReadResolution(uint8_t bits)
|
||||||
|
{
|
||||||
|
if(!bits || bits > 16){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
__analogSetWidth(bits); // hadware from 9 to 12
|
||||||
|
__analogReturnedWidth = bits; // software from 1 to 16
|
||||||
}
|
}
|
||||||
|
|
||||||
int __hallRead() //hall sensor without LNA
|
int __hallRead() //hall sensor without LNA
|
||||||
@ -192,6 +258,7 @@ int __hallRead() //hall sensor without LNA
|
|||||||
}
|
}
|
||||||
|
|
||||||
extern uint16_t analogRead(uint8_t pin) __attribute__ ((weak, alias("__analogRead")));
|
extern uint16_t analogRead(uint8_t pin) __attribute__ ((weak, alias("__analogRead")));
|
||||||
|
extern void analogReadResolution(uint8_t bits) __attribute__ ((weak, alias("__analogReadResolution")));
|
||||||
extern void analogSetWidth(uint8_t bits) __attribute__ ((weak, alias("__analogSetWidth")));
|
extern void analogSetWidth(uint8_t bits) __attribute__ ((weak, alias("__analogSetWidth")));
|
||||||
extern void analogSetCycles(uint8_t cycles) __attribute__ ((weak, alias("__analogSetCycles")));
|
extern void analogSetCycles(uint8_t cycles) __attribute__ ((weak, alias("__analogSetCycles")));
|
||||||
extern void analogSetSamples(uint8_t samples) __attribute__ ((weak, alias("__analogSetSamples")));
|
extern void analogSetSamples(uint8_t samples) __attribute__ ((weak, alias("__analogSetSamples")));
|
||||||
@ -199,3 +266,8 @@ extern void analogSetClockDiv(uint8_t clockDiv) __attribute__ ((weak, alias("__a
|
|||||||
extern void analogSetAttenuation(adc_attenuation_t attenuation) __attribute__ ((weak, alias("__analogSetAttenuation")));
|
extern void analogSetAttenuation(adc_attenuation_t attenuation) __attribute__ ((weak, alias("__analogSetAttenuation")));
|
||||||
extern void analogSetPinAttenuation(uint8_t pin, adc_attenuation_t attenuation) __attribute__ ((weak, alias("__analogSetPinAttenuation")));
|
extern void analogSetPinAttenuation(uint8_t pin, adc_attenuation_t attenuation) __attribute__ ((weak, alias("__analogSetPinAttenuation")));
|
||||||
extern int hallRead() __attribute__ ((weak, alias("__hallRead")));
|
extern int hallRead() __attribute__ ((weak, alias("__hallRead")));
|
||||||
|
|
||||||
|
extern bool adcAttachPin(uint8_t pin) __attribute__ ((weak, alias("__adcAttachPin")));
|
||||||
|
extern bool adcStart(uint8_t pin) __attribute__ ((weak, alias("__adcStart")));
|
||||||
|
extern bool adcBusy(uint8_t pin) __attribute__ ((weak, alias("__adcBusy")));
|
||||||
|
extern uint16_t adcEnd(uint8_t pin) __attribute__ ((weak, alias("__adcEnd")));
|
||||||
|
@ -39,7 +39,16 @@ typedef enum {
|
|||||||
uint16_t analogRead(uint8_t pin);
|
uint16_t analogRead(uint8_t pin);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Sets the sample bits
|
* Set the resolution of analogRead return values. Default is 12 bits (range from 0 to 4096).
|
||||||
|
* If between 9 and 12, it will equal the set hardware resolution, else value will be shifted.
|
||||||
|
* Range is 1 - 16
|
||||||
|
*
|
||||||
|
* Note: compatibility with Arduino SAM
|
||||||
|
*/
|
||||||
|
void analogReadResolution(uint8_t bits);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sets the sample bits and read resolution
|
||||||
* Default is 12bit (0 - 4095)
|
* Default is 12bit (0 - 4095)
|
||||||
* Range is 9 - 12
|
* Range is 9 - 12
|
||||||
* */
|
* */
|
||||||
@ -88,6 +97,35 @@ void analogSetPinAttenuation(uint8_t pin, adc_attenuation_t attenuation);
|
|||||||
* */
|
* */
|
||||||
int hallRead();
|
int hallRead();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Non-Blocking API (almost)
|
||||||
|
*
|
||||||
|
* Note: ADC conversion can run only for single pin at a time.
|
||||||
|
* That means that if you want to run ADC on two pins on the same bus,
|
||||||
|
* you need to run them one after another. Probably the best use would be
|
||||||
|
* to start conversion on both buses in parallel.
|
||||||
|
* */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Attach pin to ADC (will also clear any other analog mode that could be on)
|
||||||
|
* */
|
||||||
|
bool adcAttachPin(uint8_t pin);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Start ADC conversion on attached pin's bus
|
||||||
|
* */
|
||||||
|
bool adcStart(uint8_t pin);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check if conversion on the pin's ADC bus is currently running
|
||||||
|
* */
|
||||||
|
bool adcBusy(uint8_t pin);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get the result of the conversion (will wait if it have not finished)
|
||||||
|
* */
|
||||||
|
uint16_t adcEnd(uint8_t pin);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user