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_drdyLow = xSemaphoreCreateBinary();
if (!m_drdyHigh || !m_drdyLow) {
if (!m_drdyHigh || !m_drdyLow)
{
LOG_ERROR("ADC Unable to create interrupt semaphores");
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_drdyLow);
attachInterruptArg(DRDY_pin, drdyCallback, (void *)this, CHANGE);
disableInterrupt(DRDY_pin);
}
// Initialization
@@ -86,7 +88,7 @@ void ADS1256::InitializeADC()
if (m_RESET_pin != PIN_UNUSED)
{
digitalWrite(m_RESET_pin, LOW);
delay(200);
delayMicroseconds(500);
digitalWrite(m_RESET_pin, HIGH); // RESET is set to high
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
// 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
writeRegister(STATUS_REG, m_STATUS);
delay(200);
delayMicroseconds(500);
m_MUX = DIFF_0_1; // MUX AIN0+AIN1
writeRegister(MUX_REG, m_MUX);
delay(200);
delayMicroseconds(500);
m_ADCON = WAKEUP; // ADCON - CLK: OFF, SDCS: OFF, PGA = 0 (+/- 5 V)
writeRegister(ADCON_REG, m_ADCON);
delay(200);
delayMicroseconds(500);
updateConversionParameter();
m_DRATE = DRATE_100SPS; // 100SPS
writeRegister(DRATE_REG, m_DRATE);
delay(200);
delayMicroseconds(500);
sendDirectCommand(SELFCAL); // Offset and self-gain calibration
delay(200);
delayMicroseconds(500);
m_isAcquisitionRunning = false; // MCU will be waiting to start a continuous acquisition
}
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));
xSemaphoreGive(m_drdyLow);
}
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));
xSemaphoreGive(m_drdyHigh);
}
@@ -147,20 +153,21 @@ void ADS1256::stopConversion() // Sending SDATAC to stop the continuous conversi
_spi->endTransaction();
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)
{
writeRegister(DRATE_REG, drate);
m_DRATE = drate;
delay(200);
delayMicroseconds(500);
}
void ADS1256::setMUX(uint8_t mux) // Setting MUX (input channel)
{
writeRegister(MUX_REG, mux);
m_MUX = mux;
delay(200);
delayMicroseconds(500);
}
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
writeRegister(ADCON_REG, m_ADCON);
delay(200);
delayMicroseconds(500);
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);
delay(100);
}
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);
delay(100);
}
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);
delay(100);
}
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);
delay(100);
}
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);
delay(100);
}
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);
delay(100);
}
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);
delay(100);
}
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_bit0 = bitRead(m_GPIO, 0);
delay(100);
switch (gpioPin) // Selecting which value should be returned
{
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)
{
waitForLowDRDY();
_spi->beginTransaction(SPISettings(SPI_FREQ, MSBFIRST, SPI_MODE1));
// SPI_MODE1 = output edge: rising, data capture: falling; clock polarity: 0, clock phase: 1.
_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]
delayMicroseconds(5); // see t6 in the datasheet
_spi->transfer(WREG | registerAddress); // 0x50 = 01010000 = WREG
_spi->transfer(0x00); // 2nd (empty) command byte
_spi->transfer(registerValueToWrite); // pass the value to the register
CS_HIGH();
_spi->endTransaction();
delay(100);
}
long ADS1256::readRegister(uint8_t registerAddress) // Reading a register
{
waitForLowDRDY();
_spi->beginTransaction(SPISettings(SPI_FREQ, MSBFIRST, SPI_MODE1));
// SPI_MODE1 = output edge: rising, data capture: falling; clock polarity: 0, clock phase: 1.
_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->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
CS_HIGH();
_spi->endTransaction();
delay(100);
return regValue;
}
@@ -594,6 +579,7 @@ long ADS1256::readSingleContinuous() // Reads the recently selected input channe
{
if (m_isAcquisitionRunning == false)
{
enableDRDYinterrupt();
m_isAcquisitionRunning = true;
_spi->beginTransaction(SPISettings(SPI_FREQ, MSBFIRST, SPI_MODE1));
CS_LOW(); // REF: P34: "CS must stay low during the entire command sequence"
@@ -622,6 +608,7 @@ long ADS1256::cycleSingle()
{
if (m_isAcquisitionRunning == false)
{
enableDRDYinterrupt();
m_isAcquisitionRunning = true;
m_cycle = 0;
_spi->beginTransaction(SPISettings(SPI_FREQ, MSBFIRST, SPI_MODE1));
@@ -631,9 +618,6 @@ long ADS1256::cycleSingle()
_spi->transfer(SING_0); // AIN0+AINCOM
delayMicroseconds(250);
}
else
{
}
if (m_cycle < 8)
{
@@ -706,20 +690,16 @@ long ADS1256::cycleDifferential()
{
if (m_isAcquisitionRunning == false)
{
enableDRDYinterrupt();
m_cycle = 0;
m_isAcquisitionRunning = true;
_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]
_spi->transfer(WREG | MUX_REG); // 0x50 = WREG //1 = MUX
_spi->transfer(0x00);
_spi->transfer(DIFF_0_1); // AIN0+AIN1
_spi->transfer(DIFF_0_1); // Set the AIN0+AIN1 as inputs manually
delayMicroseconds(250);
}
else
{
}
if (m_cycle < 4)
{
@@ -801,3 +781,35 @@ inline void ADS1256::CS_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
*/
#ifndef _ADS1256_h
#define _ADS1256_h
#pragma once
#include <SPI.h>
#include <Arduino.h>
@@ -159,21 +158,10 @@ public:
// Stop AD
void stopConversion();
// functions for callback
inline uint8_t getDRDYpin()
{
return m_DRDY_pin;
}
SemaphoreHandle_t getDRDYsemaphoreHigh()
{
return m_drdyHigh;
}
SemaphoreHandle_t getDRDYsemaphoreLow()
{
return m_drdyLow;
}
// functions for callback, public to be accessed by static callback
inline uint8_t getDRDYpin();
inline SemaphoreHandle_t getDRDYsemaphoreHigh();
inline SemaphoreHandle_t getDRDYsemaphoreLow();
private:
SPIClass *_spi; // Pointer to an SPIClass object
@@ -183,6 +171,8 @@ private:
void updateMUX(uint8_t muxValue);
inline void CS_LOW();
inline void CS_HIGH();
inline void enableDRDYinterrupt();
inline void disableDRDYinterrupt();
void updateConversionParameter(); // Refresh the conversion parameter based on the PGA
@@ -212,4 +202,3 @@ private:
SemaphoreHandle_t m_drdyHigh;
SemaphoreHandle_t m_drdyLow;
};
#endif