From 10f8026c6d6698b0f727d17fcdae37d0c0de023d Mon Sep 17 00:00:00 2001 From: Emanuele Trabattoni Date: Wed, 22 Apr 2026 12:07:39 +0200 Subject: [PATCH] enable disable interrupts on adc drdy only when needed (only for cycle read now) fixed useless delays --- RotaxMonitor/lib/ADS1256/ADS1256.cpp | 126 +++++++++++++++------------ RotaxMonitor/lib/ADS1256/ADS1256.h | 25 ++---- 2 files changed, 76 insertions(+), 75 deletions(-) diff --git a/RotaxMonitor/lib/ADS1256/ADS1256.cpp b/RotaxMonitor/lib/ADS1256/ADS1256.cpp index 836fa2c..7c827ff 100644 --- a/RotaxMonitor/lib/ADS1256/ADS1256.cpp +++ b/RotaxMonitor/lib/ADS1256/ADS1256.cpp @@ -66,14 +66,16 @@ 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; } - + 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. + CS_LOW(); // CS must stay LOW during the entire sequence [Ref: P34, T24] - _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 - + 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 + _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. + CS_LOW(); // CS must stay LOW during the entire sequence [Ref: P34, T24] - _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 - + _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) { @@ -800,4 +780,36 @@ inline void ADS1256::CS_HIGH() { digitalWrite(m_CS_pin, HIGH); } -} \ No newline at end of file +} + +// 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); +} diff --git a/RotaxMonitor/lib/ADS1256/ADS1256.h b/RotaxMonitor/lib/ADS1256/ADS1256.h index 5670d5a..4e4fd11 100644 --- a/RotaxMonitor/lib/ADS1256/ADS1256.h +++ b/RotaxMonitor/lib/ADS1256/ADS1256.h @@ -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 #include @@ -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 \ No newline at end of file