enable disable interrupts on adc drdy only when needed (only for cycle read now) fixed useless delays

This commit is contained in:
2026-04-22 12:07:39 +02:00
parent dc56990f1e
commit 10f8026c6d
2 changed files with 76 additions and 75 deletions

View File

@@ -66,7 +66,8 @@ ADS1256::ADS1256(const int8_t DRDY_pin, const int8_t RESET_pin, const int8_t SYN
m_drdyHigh = xSemaphoreCreateBinary(); m_drdyHigh = xSemaphoreCreateBinary();
m_drdyLow = xSemaphoreCreateBinary(); m_drdyLow = xSemaphoreCreateBinary();
if (!m_drdyHigh || !m_drdyLow) { if (!m_drdyHigh || !m_drdyLow)
{
LOG_ERROR("ADC Unable to create interrupt semaphores"); LOG_ERROR("ADC Unable to create interrupt semaphores");
return; return;
} }
@@ -74,6 +75,7 @@ ADS1256::ADS1256(const int8_t DRDY_pin, const int8_t RESET_pin, const int8_t SYN
xSemaphoreGive(m_drdyHigh); xSemaphoreGive(m_drdyHigh);
xSemaphoreGive(m_drdyLow); xSemaphoreGive(m_drdyLow);
attachInterruptArg(DRDY_pin, drdyCallback, (void *)this, CHANGE); attachInterruptArg(DRDY_pin, drdyCallback, (void *)this, CHANGE);
disableInterrupt(DRDY_pin);
} }
// Initialization // Initialization
@@ -86,7 +88,7 @@ void ADS1256::InitializeADC()
if (m_RESET_pin != PIN_UNUSED) if (m_RESET_pin != PIN_UNUSED)
{ {
digitalWrite(m_RESET_pin, LOW); digitalWrite(m_RESET_pin, LOW);
delay(200); delayMicroseconds(500);
digitalWrite(m_RESET_pin, HIGH); // RESET is set to high digitalWrite(m_RESET_pin, HIGH); // RESET is set to high
delay(1000); delay(1000);
} }
@@ -99,42 +101,46 @@ void ADS1256::InitializeADC()
// Applying arbitrary default values to speed up the starting procedure if the user just want to get quick readouts // Applying arbitrary default values to speed up the starting procedure if the user just want to get quick readouts
// We both pass values to the variables and then send those values to the corresponding registers // We both pass values to the variables and then send those values to the corresponding registers
delay(200); delayMicroseconds(500);
m_STATUS = 0b00110110; // BUFEN and ACAL enabled, Order is MSB, rest is read only m_STATUS = 0b00110110; // BUFEN and ACAL enabled, Order is MSB, rest is read only
writeRegister(STATUS_REG, m_STATUS); writeRegister(STATUS_REG, m_STATUS);
delay(200); delayMicroseconds(500);
m_MUX = DIFF_0_1; // MUX AIN0+AIN1 m_MUX = DIFF_0_1; // MUX AIN0+AIN1
writeRegister(MUX_REG, m_MUX); writeRegister(MUX_REG, m_MUX);
delay(200); delayMicroseconds(500);
m_ADCON = WAKEUP; // ADCON - CLK: OFF, SDCS: OFF, PGA = 0 (+/- 5 V) m_ADCON = WAKEUP; // ADCON - CLK: OFF, SDCS: OFF, PGA = 0 (+/- 5 V)
writeRegister(ADCON_REG, m_ADCON); writeRegister(ADCON_REG, m_ADCON);
delay(200); delayMicroseconds(500);
updateConversionParameter(); updateConversionParameter();
m_DRATE = DRATE_100SPS; // 100SPS m_DRATE = DRATE_100SPS; // 100SPS
writeRegister(DRATE_REG, m_DRATE); writeRegister(DRATE_REG, m_DRATE);
delay(200); delayMicroseconds(500);
sendDirectCommand(SELFCAL); // Offset and self-gain calibration sendDirectCommand(SELFCAL); // Offset and self-gain calibration
delay(200); delayMicroseconds(500);
m_isAcquisitionRunning = false; // MCU will be waiting to start a continuous acquisition m_isAcquisitionRunning = false; // MCU will be waiting to start a continuous acquisition
} }
void ADS1256::waitForLowDRDY() void ADS1256::waitForLowDRDY()
{ {
// while(digitalRead(m_DRDY_pin) == HIGH) {vTaskDelay(1);}; if (!m_isAcquisitionRunning)
while (digitalRead(m_DRDY_pin) == HIGH)
; // wait in loop only for single shot modes
xSemaphoreTake(m_drdyLow, pdMS_TO_TICKS(10)); xSemaphoreTake(m_drdyLow, pdMS_TO_TICKS(10));
xSemaphoreGive(m_drdyLow); xSemaphoreGive(m_drdyLow);
} }
void ADS1256::waitForHighDRDY() void ADS1256::waitForHighDRDY()
{ {
// while(digitalRead(m_DRDY_pin) == LOW) {vTaskDelay(1);}; if (!m_isAcquisitionRunning)
while (digitalRead(m_DRDY_pin) == LOW)
; // wait in loop only for single shot modes
xSemaphoreTake(m_drdyHigh, pdMS_TO_TICKS(10)); xSemaphoreTake(m_drdyHigh, pdMS_TO_TICKS(10));
xSemaphoreGive(m_drdyHigh); xSemaphoreGive(m_drdyHigh);
} }
@@ -147,20 +153,21 @@ void ADS1256::stopConversion() // Sending SDATAC to stop the continuous conversi
_spi->endTransaction(); _spi->endTransaction();
m_isAcquisitionRunning = false; // Reset to false, so the MCU will be able to start a new conversion m_isAcquisitionRunning = false; // Reset to false, so the MCU will be able to start a new conversion
disableDRDYinterrupt();
} }
void ADS1256::setDRATE(uint8_t drate) // Setting DRATE (sampling frequency) void ADS1256::setDRATE(uint8_t drate) // Setting DRATE (sampling frequency)
{ {
writeRegister(DRATE_REG, drate); writeRegister(DRATE_REG, drate);
m_DRATE = drate; m_DRATE = drate;
delay(200); delayMicroseconds(500);
} }
void ADS1256::setMUX(uint8_t mux) // Setting MUX (input channel) void ADS1256::setMUX(uint8_t mux) // Setting MUX (input channel)
{ {
writeRegister(MUX_REG, mux); writeRegister(MUX_REG, mux);
m_MUX = mux; m_MUX = mux;
delay(200); delayMicroseconds(500);
} }
void ADS1256::setPGA(uint8_t pga) // Setting PGA (input voltage range) void ADS1256::setPGA(uint8_t pga) // Setting PGA (input voltage range)
@@ -171,7 +178,7 @@ void ADS1256::setPGA(uint8_t pga) // Setting PGA (input voltage range)
m_ADCON = (m_ADCON & 0b11111000) | (m_PGA & 0b00000111); // Clearing and then setting bits 2-0 based on pga m_ADCON = (m_ADCON & 0b11111000) | (m_PGA & 0b00000111); // Clearing and then setting bits 2-0 based on pga
writeRegister(ADCON_REG, m_ADCON); writeRegister(ADCON_REG, m_ADCON);
delay(200); delayMicroseconds(500);
updateConversionParameter(); // Update the multiplier according top the new PGA value updateConversionParameter(); // Update the multiplier according top the new PGA value
} }
@@ -219,7 +226,6 @@ void ADS1256::setCLKOUT(uint8_t clkout) // Setting CLKOUT
} }
writeRegister(ADCON_REG, m_ADCON); writeRegister(ADCON_REG, m_ADCON);
delay(100);
} }
void ADS1256::setSDCS(uint8_t sdcs) // Setting SDCS void ADS1256::setSDCS(uint8_t sdcs) // Setting SDCS
@@ -257,7 +263,6 @@ void ADS1256::setSDCS(uint8_t sdcs) // Setting SDCS
} }
writeRegister(ADCON_REG, m_ADCON); writeRegister(ADCON_REG, m_ADCON);
delay(100);
} }
void ADS1256::setByteOrder(uint8_t byteOrder) // Setting byte order (MSB/LSB) void ADS1256::setByteOrder(uint8_t byteOrder) // Setting byte order (MSB/LSB)
@@ -281,7 +286,6 @@ void ADS1256::setByteOrder(uint8_t byteOrder) // Setting byte order (MSB/LSB)
} }
writeRegister(STATUS_REG, m_STATUS); writeRegister(STATUS_REG, m_STATUS);
delay(100);
} }
uint8_t ADS1256::getByteOrder() // Getting byte order (MSB/LSB) uint8_t ADS1256::getByteOrder() // Getting byte order (MSB/LSB)
@@ -312,7 +316,6 @@ void ADS1256::setAutoCal(uint8_t acal) // Setting ACAL (Automatic SYSCAL)
} }
writeRegister(STATUS_REG, m_STATUS); writeRegister(STATUS_REG, m_STATUS);
delay(100);
} }
uint8_t ADS1256::getAutoCal() // Getting ACAL (Automatic SYSCAL) uint8_t ADS1256::getAutoCal() // Getting ACAL (Automatic SYSCAL)
@@ -343,7 +346,6 @@ void ADS1256::setBuffer(uint8_t bufen) // Setting input buffer (Input impedance)
} }
writeRegister(STATUS_REG, m_STATUS); writeRegister(STATUS_REG, m_STATUS);
delay(100);
} }
uint8_t ADS1256::getBuffer() // Getting input buffer (Input impedance) uint8_t ADS1256::getBuffer() // Getting input buffer (Input impedance)
@@ -407,7 +409,6 @@ void ADS1256::setGPIO(uint8_t dir0, uint8_t dir1, uint8_t dir2, uint8_t dir3) //
//----------------------------------------------------- //-----------------------------------------------------
writeRegister(IO_REG, m_GPIO); writeRegister(IO_REG, m_GPIO);
delay(100);
} }
void ADS1256::writeGPIO(uint8_t dir0value, uint8_t dir1value, uint8_t dir2value, uint8_t dir3value) // Writing GPIO void ADS1256::writeGPIO(uint8_t dir0value, uint8_t dir1value, uint8_t dir2value, uint8_t dir3value) // Writing GPIO
@@ -465,7 +466,6 @@ void ADS1256::writeGPIO(uint8_t dir0value, uint8_t dir1value, uint8_t dir2value,
//----------------------------------------------------- //-----------------------------------------------------
writeRegister(IO_REG, m_GPIO); writeRegister(IO_REG, m_GPIO);
delay(100);
} }
uint8_t ADS1256::readGPIO(uint8_t gpioPin) // Reading GPIO uint8_t ADS1256::readGPIO(uint8_t gpioPin) // Reading GPIO
@@ -480,8 +480,6 @@ uint8_t ADS1256::readGPIO(uint8_t gpioPin) // Reading GPIO
GPIO_bit1 = bitRead(m_GPIO, 1); GPIO_bit1 = bitRead(m_GPIO, 1);
GPIO_bit0 = bitRead(m_GPIO, 0); GPIO_bit0 = bitRead(m_GPIO, 0);
delay(100);
switch (gpioPin) // Selecting which value should be returned switch (gpioPin) // Selecting which value should be returned
{ {
case 0: case 0:
@@ -526,45 +524,32 @@ float ADS1256::convertToVoltage(int32_t rawData) // Converting the 24-bit data i
void ADS1256::writeRegister(uint8_t registerAddress, uint8_t registerValueToWrite) void ADS1256::writeRegister(uint8_t registerAddress, uint8_t registerValueToWrite)
{ {
waitForLowDRDY(); waitForLowDRDY();
_spi->beginTransaction(SPISettings(SPI_FREQ, MSBFIRST, SPI_MODE1)); // SPI_MODE1 = output edge: rising, data capture: falling; clock polarity: 0, clock phase: 1.
CS_LOW(); // CS must stay LOW during the entire sequence [Ref: P34, T24]
_spi->beginTransaction(SPISettings(SPI_FREQ, MSBFIRST, SPI_MODE1)); delayMicroseconds(5); // see t6 in the datasheet
// SPI_MODE1 = output edge: rising, data capture: falling; clock polarity: 0, clock phase: 1.
CS_LOW(); // CS must stay LOW during the entire sequence [Ref: P34, T24]
delayMicroseconds(5); // see t6 in the datasheet
_spi->transfer(WREG | registerAddress); // 0x50 = 01010000 = WREG _spi->transfer(WREG | registerAddress); // 0x50 = 01010000 = WREG
_spi->transfer(0x00); // 2nd (empty) command byte
_spi->transfer(0x00); // 2nd (empty) command byte _spi->transfer(registerValueToWrite); // pass the value to the register
_spi->transfer(registerValueToWrite); // pass the value to the register
CS_HIGH(); CS_HIGH();
_spi->endTransaction(); _spi->endTransaction();
delay(100);
} }
long ADS1256::readRegister(uint8_t registerAddress) // Reading a register long ADS1256::readRegister(uint8_t registerAddress) // Reading a register
{ {
waitForLowDRDY(); waitForLowDRDY();
_spi->beginTransaction(SPISettings(SPI_FREQ, MSBFIRST, SPI_MODE1)); // SPI_MODE1 = output edge: rising, data capture: falling; clock polarity: 0, clock phase: 1.
CS_LOW(); // CS must stay LOW during the entire sequence [Ref: P34, T24]
_spi->beginTransaction(SPISettings(SPI_FREQ, MSBFIRST, SPI_MODE1)); _spi->transfer(RREG | registerAddress); // 0x10 = 0001000 = RREG - OR together the two numbers (command + address)
// SPI_MODE1 = output edge: rising, data capture: falling; clock polarity: 0, clock phase: 1. _spi->transfer(0x00); // 2nd (empty) command byte
delayMicroseconds(5); // see t6 in the datasheet
CS_LOW(); // CS must stay LOW during the entire sequence [Ref: P34, T24]
_spi->transfer(RREG | registerAddress); // 0x10 = 0001000 = RREG - OR together the two numbers (command + address)
_spi->transfer(0x00); // 2nd (empty) command byte
delayMicroseconds(5); // see t6 in the datasheet
uint8_t regValue = _spi->transfer(0x00); // read out the register value uint8_t regValue = _spi->transfer(0x00); // read out the register value
CS_HIGH(); CS_HIGH();
_spi->endTransaction(); _spi->endTransaction();
delay(100);
return regValue; return regValue;
} }
@@ -594,6 +579,7 @@ long ADS1256::readSingleContinuous() // Reads the recently selected input channe
{ {
if (m_isAcquisitionRunning == false) if (m_isAcquisitionRunning == false)
{ {
enableDRDYinterrupt();
m_isAcquisitionRunning = true; m_isAcquisitionRunning = true;
_spi->beginTransaction(SPISettings(SPI_FREQ, MSBFIRST, SPI_MODE1)); _spi->beginTransaction(SPISettings(SPI_FREQ, MSBFIRST, SPI_MODE1));
CS_LOW(); // REF: P34: "CS must stay low during the entire command sequence" CS_LOW(); // REF: P34: "CS must stay low during the entire command sequence"
@@ -622,6 +608,7 @@ long ADS1256::cycleSingle()
{ {
if (m_isAcquisitionRunning == false) if (m_isAcquisitionRunning == false)
{ {
enableDRDYinterrupt();
m_isAcquisitionRunning = true; m_isAcquisitionRunning = true;
m_cycle = 0; m_cycle = 0;
_spi->beginTransaction(SPISettings(SPI_FREQ, MSBFIRST, SPI_MODE1)); _spi->beginTransaction(SPISettings(SPI_FREQ, MSBFIRST, SPI_MODE1));
@@ -631,9 +618,6 @@ long ADS1256::cycleSingle()
_spi->transfer(SING_0); // AIN0+AINCOM _spi->transfer(SING_0); // AIN0+AINCOM
delayMicroseconds(250); delayMicroseconds(250);
} }
else
{
}
if (m_cycle < 8) if (m_cycle < 8)
{ {
@@ -706,20 +690,16 @@ long ADS1256::cycleDifferential()
{ {
if (m_isAcquisitionRunning == false) if (m_isAcquisitionRunning == false)
{ {
enableDRDYinterrupt();
m_cycle = 0; m_cycle = 0;
m_isAcquisitionRunning = true; m_isAcquisitionRunning = true;
_spi->beginTransaction(SPISettings(SPI_FREQ, MSBFIRST, SPI_MODE1)); _spi->beginTransaction(SPISettings(SPI_FREQ, MSBFIRST, SPI_MODE1));
// Set the AIN0+AIN1 as inputs manually
CS_LOW(); // CS must stay LOW during the entire sequence [Ref: P34, T24] CS_LOW(); // CS must stay LOW during the entire sequence [Ref: P34, T24]
_spi->transfer(WREG | MUX_REG); // 0x50 = WREG //1 = MUX _spi->transfer(WREG | MUX_REG); // 0x50 = WREG //1 = MUX
_spi->transfer(0x00); _spi->transfer(0x00);
_spi->transfer(DIFF_0_1); // AIN0+AIN1 _spi->transfer(DIFF_0_1); // Set the AIN0+AIN1 as inputs manually
delayMicroseconds(250); delayMicroseconds(250);
} }
else
{
}
if (m_cycle < 4) if (m_cycle < 4)
{ {
@@ -801,3 +781,35 @@ inline void ADS1256::CS_HIGH()
digitalWrite(m_CS_pin, HIGH); digitalWrite(m_CS_pin, HIGH);
} }
} }
// functions for callback
inline uint8_t ADS1256::getDRDYpin()
{
return m_DRDY_pin;
}
inline SemaphoreHandle_t ADS1256::getDRDYsemaphoreHigh()
{
return m_drdyHigh;
}
inline SemaphoreHandle_t ADS1256::getDRDYsemaphoreLow()
{
return m_drdyLow;
}
inline void ADS1256::enableDRDYinterrupt()
{
// release semaphores to avoid deadlock
xSemaphoreGive(m_drdyHigh);
xSemaphoreGive(m_drdyLow);
enableInterrupt(m_DRDY_pin);
}
inline void ADS1256::disableDRDYinterrupt()
{
// release semaphores to avoid deadlock
disableInterrupt(m_DRDY_pin);
xSemaphoreGive(m_drdyHigh);
xSemaphoreGive(m_drdyLow);
}

View File

@@ -10,8 +10,7 @@
Benjamin Pelletier for pointing out and fixing an issue around the handling of the DRDY signal Benjamin Pelletier for pointing out and fixing an issue around the handling of the DRDY signal
*/ */
#ifndef _ADS1256_h #pragma once
#define _ADS1256_h
#include <SPI.h> #include <SPI.h>
#include <Arduino.h> #include <Arduino.h>
@@ -159,21 +158,10 @@ public:
// Stop AD // Stop AD
void stopConversion(); void stopConversion();
// functions for callback // functions for callback, public to be accessed by static callback
inline uint8_t getDRDYpin() inline uint8_t getDRDYpin();
{ inline SemaphoreHandle_t getDRDYsemaphoreHigh();
return m_DRDY_pin; inline SemaphoreHandle_t getDRDYsemaphoreLow();
}
SemaphoreHandle_t getDRDYsemaphoreHigh()
{
return m_drdyHigh;
}
SemaphoreHandle_t getDRDYsemaphoreLow()
{
return m_drdyLow;
}
private: private:
SPIClass *_spi; // Pointer to an SPIClass object SPIClass *_spi; // Pointer to an SPIClass object
@@ -183,6 +171,8 @@ private:
void updateMUX(uint8_t muxValue); void updateMUX(uint8_t muxValue);
inline void CS_LOW(); inline void CS_LOW();
inline void CS_HIGH(); inline void CS_HIGH();
inline void enableDRDYinterrupt();
inline void disableDRDYinterrupt();
void updateConversionParameter(); // Refresh the conversion parameter based on the PGA void updateConversionParameter(); // Refresh the conversion parameter based on the PGA
@@ -212,4 +202,3 @@ private:
SemaphoreHandle_t m_drdyHigh; SemaphoreHandle_t m_drdyHigh;
SemaphoreHandle_t m_drdyLow; SemaphoreHandle_t m_drdyLow;
}; };
#endif