851 lines
22 KiB
C++
851 lines
22 KiB
C++
#include "ads131m08.h"
|
|
|
|
namespace esphome {
|
|
namespace ads131m08 {
|
|
|
|
static const char *const TAG = "ads131m08";
|
|
|
|
|
|
void ADS131M08Hub::setup()
|
|
{
|
|
// Initialize SPI with correct settings for ADS131M08
|
|
// SPI mode 1: CPOL=0, CPHA=1
|
|
this->spi_setup();
|
|
// not sure if next few lines are needed here or is it handled in spi_setup()
|
|
SPI.begin();
|
|
SPI.setDataMode(SPI_MODE1);
|
|
SPI.setBitOrder(MSBFIRST);
|
|
SPI.setClockDivider(SPI_CLOCK_DIV8); // Adjust clock speed as needed
|
|
this->drdy_pin_->setup();
|
|
this->drdy_pin_->pin_mode(esphome::gpio::FLAG_INPUT | esphome::gpio::FLAG_PULLUP);
|
|
this->drdy_pin_->attach_interrupt(&ADS131M08Hub::isr, this, gpio::INTERRUPT_FALLING_EDGE);
|
|
this->initialize_ads131m08();
|
|
}
|
|
|
|
void ADS131M08Hub::initialize_ads131m08()
|
|
{
|
|
// Send RESET command
|
|
SPI.transfer(0x06);
|
|
delay(1);
|
|
|
|
// Send UNLOCK command
|
|
SPI.transfer(0x55);
|
|
SPI.transfer(0x55);
|
|
|
|
// Configure registers as needed (example: set gain, etc.)
|
|
// Write to MODE register for continuous conversion, disable internal reference (use external MAX6070AAUT12+T at 1.25V)
|
|
write_register(0x02, 0x0000); // MODE register, continuous mode, INTREF_EN = 0
|
|
|
|
// Wait for external reference to settle
|
|
delay(100);
|
|
|
|
// Start conversions
|
|
SPI.transfer(0x08); // START command
|
|
}
|
|
|
|
void ADS131M08Hub::write_register(uint8_t reg, uint16_t value)
|
|
{
|
|
SPI.transfer(0x40 | reg); // WREG command
|
|
SPI.transfer(0x00); // Number of registers - 1 (0 for one register)
|
|
SPI.transfer((value >> 8) & 0xFF);
|
|
SPI.transfer(value & 0xFF);
|
|
}
|
|
|
|
void IRAM_ATTR ADS131M08Hub::isr(ADS131M08Hub *arg)
|
|
{
|
|
arg->txf_init(); // implementing datasheet recommended TXF init in ISR
|
|
arg->data_ready_ = true;
|
|
}
|
|
|
|
void ADS131M08Hub::loop()
|
|
{
|
|
if (this->data_ready_) {
|
|
this->data_ready_ = false;
|
|
this->read_data_();
|
|
}
|
|
}
|
|
|
|
// ********************** from datasheet ************************
|
|
void ADS131M08Hub::txf_init()
|
|
{
|
|
if (firstRead) {
|
|
// Clear the ADC's 2-deep FIFO on the first read
|
|
for (int i = 0; i <numFrameWords; i++) {
|
|
SPI.write(spiDummyWord + i);
|
|
}
|
|
for(int i = 0; i < numFrameWords; i++) {
|
|
SPI.read();
|
|
}
|
|
firstRead = false; // Clear the flag
|
|
DMA.enable(); // Let the DMA start sending ADC data to memory
|
|
}
|
|
for (int i = 0; i < numFrameWords; i++) {// Send the dummy data to the ADC to get the ADC data
|
|
SPI.write(spiDummyWord + i);
|
|
}
|
|
}
|
|
|
|
void ADS131M08Hub::initialize_ads131m08_datasheet()
|
|
{
|
|
// enableSupplies();
|
|
// GPIO.inputEnable('input'); // Enable GPIO connected to DRDY
|
|
// clkout.enable(8192000); // Enable 8.192 MHz clock to CLKIN
|
|
// SPI.enable(); // Enable SPI port
|
|
// SPI.wordLengthSet(24); // ADC default word length is 24 bits
|
|
// SPI.configCS(STAY_ASSERTED);// Configure CS to remain asserted until frame is complete
|
|
while(!GPIO.read()){} // Wait for DRDY to go high indicating it is ok to talk to ADC
|
|
adcRegisterWrite(REG_CLOCK, MASK_CLOCK_ALL_CH_DISABLE | OSR_1024 | PM_HIGH_RESOLUTION, 24); // Write CLOCK register; Turn off all channels so short frames can be written during config; // Re-write defaults for other bits in CLOCK register
|
|
adcRegisterWrite(REG_MODE, MODE_NO_RESET | DRDY_FMT_PULSE | WLENGTH_24_BITS | TIMEOUT_ENABLED, 24); // Write MODE register; Clear the RESET flag, make DRDY active low pulse; Re-write defaults for other bits in MODE register
|
|
adcRegisterWrite(REG_GAIN1, PGAGAIN3_32 | PGAGAIN1_32, 24); // Write GAIN1 register; Set channels 1 and 3 PGA gain to 32 in this example; Leave channels 0 and 2 at default gain of 1
|
|
adcRegisterWrite(REG_THRSHLD_LSB, 0x09, 24); // Write THRSHLD_LSB register; Set DCBLOCK filter to have a corner frequency of 622 mHz
|
|
DMA.triggerSet(SPI);// Configure DMA to trigger when data comes in on the MCU SPI port
|
|
DMA.txAddrSet(SPI.rxAddr());// Set the DMA to take from the incoming SPI port
|
|
DMA.rxAddrSet(&adcData);// Set the DMA to send ADC data to a predefined memory location
|
|
adcRegisterWrite(REG_MODE, WLENGTH_32_BITS_MSB_SIGN_EXTEND | DRDY_FMT_PULSE | TIMEOUT_ENABLED, 24); // Write MODE register; Make ADC word size 32 bits to accommodate DMA; Re-write other set bits in MODE register
|
|
SPI.wordLengthSet(32); // Set SPI word size to 32 bits to accomodate DMA
|
|
adcRegisterWrite(REG_CLOCK, MASK_CLOCK_ALL_CH_ENABLE | OSR_1024 | PM_HIGH_RESOLUTION, 32); // Write CLOCK register; Turn on all ADC channels; Re-write defaults for other bits in CLOCK register
|
|
GPIO.interuptEnable();// Enable DRDY interrupt and begin streaming data
|
|
}
|
|
|
|
|
|
/* adcRegisterWrite
|
|
Short function that writes one ADC register at a time.
|
|
Blocks return until SPI is idle.
|
|
Returns false if the word length is wrong.
|
|
param
|
|
addrMask: 16-bit register address mask
|
|
data: data to write adcWord
|
|
Length: word length which ADC expects. Either 16, 24 or 32.
|
|
return true if word length was valid false if not
|
|
*/
|
|
bool ADS131M08Hub::adcRegisterWrite(unsigned short addrMask, unsigned short data, unsigned char adcWordLength)
|
|
{
|
|
unsigned char shiftValue; // Stores the amount of bit shift based on ADC word length
|
|
if(adcWordLength == 16) {
|
|
shiftValue = 0; // If length is 16, no shift
|
|
}
|
|
else if(adcWordLength == 24) {
|
|
shiftValue = 8; // If length is 24, shift left by 8
|
|
}
|
|
else if(adcWordLength == 32) {
|
|
shiftValue = 16; // If length is 32, shift left by 16
|
|
} else {
|
|
return false; // If not, invalid length
|
|
}
|
|
SPI.write((CMD_WREG | addrMask) << shiftValue); // Write address and opcode; Shift to accommodate ADC word length
|
|
SPI.write(data << shiftValue); // Write register data
|
|
while(SPI.isBusy()); // Wait for data to complete sending
|
|
return true;
|
|
}
|
|
|
|
// ********************** end of from datasheet ************************
|
|
|
|
/*
|
|
void ADS131M08Hub::read_all_channels()
|
|
{
|
|
// Send RDATA command or read data directly
|
|
SPI.transfer(0x12); // RDATA command
|
|
|
|
// Read 24 bytes (3 bytes per channel for 8 channels)
|
|
for (int i = 0; i < 24; i++) {
|
|
data_buffer_[i] = SPI.transfer(0x00);
|
|
}
|
|
|
|
// Convert to voltages for all channels
|
|
//Sensor *channels[8] = {channel1, channel2, channel3, channel4, channel5, channel6, channel7, channel8};
|
|
for (int ch = 0; ch < 8; ch++) {
|
|
if (this->sensors_[ch] != nullptr) {
|
|
int offset = ch * 3;
|
|
int32_t raw = (data_buffer_[offset] << 16) | (data_buffer_[offset + 1] << 8) | data_buffer_[offset + 2];
|
|
if (raw & 0x800000)
|
|
raw |= 0xFF000000; // Sign extend
|
|
float v = (raw / 8388608.0) * this->reference_voltage_; // 2^23 = 8388608, Vref = 1.25V (MAX6070AAUT12+T)
|
|
this->sensors_[ch]->publish_state(v);
|
|
}
|
|
}
|
|
}
|
|
*/
|
|
void ADS131M08Hub::read_data_()
|
|
{
|
|
this->enable();
|
|
// ADS131M08 Frame: 1 Status Word + 8 Channel Words + 1 CRC Word (24-bit words)
|
|
uint8_t frame[30]; // 10 words * 3 bytes
|
|
this->read_array(frame, 30);
|
|
this->disable();
|
|
|
|
for (int i = 0; i < 8; i++) {
|
|
if (this->sensors_[i] != nullptr) {
|
|
// Convert 24-bit two's complement to float (Simplified)
|
|
int32_t raw = (frame[3+(i*3)] << 16) | (frame[4+(i*3)] << 8) | frame[5+(i*3)];
|
|
if (raw & 0x800000)
|
|
raw |= 0xFF000000; // Sign extend
|
|
this->sensors_[i]->publish_state(raw * (this->reference_voltage_ / 8388608.0)); // 2^23 = 8388608, Vref = 1.25V ( for MAX6070AAUT12+T )
|
|
}
|
|
}
|
|
}
|
|
|
|
// =============== from tpcorrea =================
|
|
ADS131M08Hub::ADS131M08Hub() : csPin(0), drdyPin(0), clkPin(0), misoPin(0), mosiPin(0), resetPin(0)
|
|
{
|
|
for( uint16_t i = 0U; i < 8; i++){
|
|
fullScale.ch[i].f = 1.2; // +-1.2V
|
|
pgaGain[i] = ADS131M08_PgaGain::PGA_1;
|
|
resultFloat.ch[i].f = 0.0;
|
|
resultRaw.ch[i].u[0] = 0U;
|
|
resultRaw.ch[i].u[1] = 0U;
|
|
}
|
|
|
|
}
|
|
|
|
uint8_t ADS131M08Hub::writeRegister(uint8_t address, uint16_t value)
|
|
{
|
|
uint16_t res;
|
|
uint8_t addressRcv;
|
|
uint8_t bytesRcv;
|
|
uint16_t cmd = 0;
|
|
|
|
digitalWrite(csPin, LOW);
|
|
delayMicroseconds(1);
|
|
|
|
cmd = (CMD_WRITE_REG) | (address << 7) | 0;
|
|
|
|
//res = spi.transfer16(cmd);
|
|
spi.transfer16(cmd);
|
|
spi.transfer(0x00);
|
|
|
|
spi.transfer16(value);
|
|
spi.transfer(0x00);
|
|
|
|
for(int i = 0; i < 8; i++)
|
|
{
|
|
spi.transfer16(0x0000);
|
|
spi.transfer(0x00);
|
|
}
|
|
|
|
res = spi.transfer16(0x0000);
|
|
spi.transfer(0x00);
|
|
|
|
for(int i = 0; i < 9; i++)
|
|
{
|
|
spi.transfer16(0x0000);
|
|
spi.transfer(0x00);
|
|
}
|
|
|
|
delayMicroseconds(1);
|
|
digitalWrite(csPin, HIGH);
|
|
|
|
addressRcv = (res & REGMASK_CMD_READ_REG_ADDRESS) >> 7;
|
|
bytesRcv = (res & REGMASK_CMD_READ_REG_BYTES);
|
|
|
|
if (addressRcv == address)
|
|
{
|
|
return bytesRcv + 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void ADS131M08Hub::writeRegisterMasked(uint8_t address, uint16_t value, uint16_t mask)
|
|
{
|
|
// Escribe un valor en el registro, aplicando la mascara para tocar unicamente los bits necesarios.
|
|
// No realiza el corrimiento de bits (shift), hay que pasarle ya el valor corrido a la posicion correcta
|
|
|
|
// Leo el contenido actual del registro
|
|
uint16_t register_contents = readRegister(address);
|
|
|
|
// Cambio bit aa bit la mascara (queda 1 en los bits que no hay que tocar y 0 en los bits a modificar)
|
|
// Se realiza un AND co el contenido actual del registro. Quedan "0" en la parte a modificar
|
|
register_contents = register_contents & ~mask;
|
|
|
|
// se realiza un OR con el valor a cargar en el registro. Ojo, valor debe estar en el posicion (shitf) correcta
|
|
register_contents = register_contents | value;
|
|
|
|
// Escribo nuevamente el registro
|
|
writeRegister(address, register_contents);
|
|
}
|
|
|
|
uint16_t ADS131M08Hub::readRegister(uint8_t address)
|
|
{
|
|
uint16_t cmd;
|
|
uint16_t data;
|
|
|
|
cmd = CMD_READ_REG | (address << 7 | 0);
|
|
|
|
digitalWrite(csPin, LOW);
|
|
delayMicroseconds(1);
|
|
|
|
//data = spi.transfer16(cmd);
|
|
spi.transfer16(cmd);
|
|
spi.transfer(0x00);
|
|
|
|
for(int i = 0; i < 9; i++)
|
|
{
|
|
spi.transfer16(0x0000);
|
|
spi.transfer(0x00);
|
|
}
|
|
|
|
data = spi.transfer16(0x0000);
|
|
spi.transfer(0x00);
|
|
|
|
for(int i = 0; i < 9; i++)
|
|
{
|
|
spi.transfer16(0x0000);
|
|
spi.transfer(0x00);
|
|
}
|
|
|
|
delayMicroseconds(1);
|
|
digitalWrite(csPin, HIGH);
|
|
return data;
|
|
}
|
|
|
|
void ADS131M08Hub::begin(uint8_t clk_pin, uint8_t miso_pin, uint8_t mosi_pin, uint8_t cs_pin, uint8_t drdy_pin, uint8_t reset_pin)
|
|
{
|
|
// Set pins up
|
|
csPin = cs_pin;
|
|
drdyPin = drdy_pin;
|
|
clkPin = clk_pin;
|
|
misoPin = miso_pin;
|
|
mosiPin = mosi_pin;
|
|
resetPin = reset_pin;
|
|
|
|
spi = SPIClass(mosi_pin, miso_pin, clk_pin, cs_pin);
|
|
spi.begin();
|
|
spi.beginTransaction(settings);
|
|
// Configure chip select as an output
|
|
pinMode(csPin, OUTPUT);
|
|
pinMode(resetPin, OUTPUT);
|
|
// Configure DRDY as an input
|
|
pinMode(drdyPin, INPUT);
|
|
}
|
|
|
|
int8_t ADS131M08Hub::isDataReadySoft(byte channel)
|
|
{
|
|
if (channel == 0)
|
|
{
|
|
return (readRegister(REG_STATUS) & REGMASK_STATUS_DRDY0);
|
|
}
|
|
else if (channel == 1)
|
|
{
|
|
return (readRegister(REG_STATUS) & REGMASK_STATUS_DRDY1);
|
|
}
|
|
else if (channel == 2)
|
|
{
|
|
return (readRegister(REG_STATUS) & REGMASK_STATUS_DRDY2);
|
|
}
|
|
else if (channel == 3)
|
|
{
|
|
return (readRegister(REG_STATUS) & REGMASK_STATUS_DRDY3);
|
|
}
|
|
else if (channel == 4)
|
|
{
|
|
return (readRegister(REG_STATUS) & REGMASK_STATUS_DRDY4);
|
|
}
|
|
else if (channel == 5)
|
|
{
|
|
return (readRegister(REG_STATUS) & REGMASK_STATUS_DRDY5);
|
|
}
|
|
else if (channel == 6)
|
|
{
|
|
return (readRegister(REG_STATUS) & REGMASK_STATUS_DRDY6);
|
|
}
|
|
else if (channel == 7)
|
|
{
|
|
return (readRegister(REG_STATUS) & REGMASK_STATUS_DRDY7);
|
|
}
|
|
else
|
|
{
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
bool ADS131M08Hub::isResetStatus(void)
|
|
{
|
|
return (readRegister(REG_STATUS) & REGMASK_STATUS_RESET);
|
|
}
|
|
|
|
bool ADS131M08Hub::isLockSPI(void)
|
|
{
|
|
return (readRegister(REG_STATUS) & REGMASK_STATUS_LOCK);
|
|
}
|
|
|
|
bool ADS131M08Hub::setDrdyFormat(uint8_t drdyFormat)
|
|
{
|
|
if (drdyFormat > 1)
|
|
{
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
writeRegisterMasked(REG_MODE, drdyFormat, REGMASK_MODE_DRDY_FMT);
|
|
return true;
|
|
}
|
|
}
|
|
|
|
bool ADS131M08Hub::setDrdyStateWhenUnavailable(uint8_t drdyState)
|
|
{
|
|
if (drdyState > 1)
|
|
{
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
writeRegisterMasked(REG_MODE, drdyState < 1, REGMASK_MODE_DRDY_HiZ);
|
|
return true;
|
|
}
|
|
}
|
|
|
|
bool ADS131M08Hub::setPowerMode(uint8_t powerMode)
|
|
{
|
|
if (powerMode > 3)
|
|
{
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
writeRegisterMasked(REG_CLOCK, powerMode, REGMASK_CLOCK_PWR);
|
|
return true;
|
|
}
|
|
}
|
|
|
|
bool ADS131M08Hub::setOsr(uint16_t osr)
|
|
{
|
|
if (osr > 7)
|
|
{
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
writeRegisterMasked(REG_CLOCK, osr << 2 , REGMASK_CLOCK_OSR);
|
|
return true;
|
|
}
|
|
}
|
|
|
|
void ADS131M08Hub::setFullScale(uint8_t channel, float scale)
|
|
{
|
|
if (channel > 7) {
|
|
return;
|
|
}
|
|
|
|
this->fullScale.ch[channel].f = scale;
|
|
|
|
}
|
|
|
|
float ADS131M08Hub::getFullScale(uint8_t channel)
|
|
{
|
|
if (channel > 7) {
|
|
return 0.0;
|
|
}
|
|
|
|
return this->fullScale.ch[channel].f;
|
|
|
|
}
|
|
|
|
void ADS131M08Hub::reset()
|
|
{
|
|
digitalWrite(this->resetPin, LOW);
|
|
delay(10);
|
|
digitalWrite(this->resetPin, HIGH);
|
|
}
|
|
|
|
bool ADS131M08Hub::setChannelEnable(uint8_t channel, uint16_t enable)
|
|
{
|
|
if (channel > 7)
|
|
{
|
|
return false;
|
|
}
|
|
if (channel == 0)
|
|
{
|
|
writeRegisterMasked(REG_CLOCK, enable << 8, REGMASK_CLOCK_CH0_EN);
|
|
return true;
|
|
}
|
|
else if (channel == 1)
|
|
{
|
|
writeRegisterMasked(REG_CLOCK, enable << 9, REGMASK_CLOCK_CH1_EN);
|
|
return true;
|
|
}
|
|
else if (channel == 2)
|
|
{
|
|
writeRegisterMasked(REG_CLOCK, enable << 10, REGMASK_CLOCK_CH2_EN);
|
|
return true;
|
|
}
|
|
else if (channel == 3)
|
|
{
|
|
writeRegisterMasked(REG_CLOCK, enable << 11, REGMASK_CLOCK_CH3_EN);
|
|
return true;
|
|
}
|
|
else if (channel == 4)
|
|
{
|
|
writeRegisterMasked(REG_CLOCK, enable << 11, REGMASK_CLOCK_CH4_EN);
|
|
return true;
|
|
}
|
|
else if (channel == 5)
|
|
{
|
|
writeRegisterMasked(REG_CLOCK, enable << 11, REGMASK_CLOCK_CH5_EN);
|
|
return true;
|
|
}
|
|
else if (channel == 6)
|
|
{
|
|
writeRegisterMasked(REG_CLOCK, enable << 11, REGMASK_CLOCK_CH6_EN);
|
|
return true;
|
|
}
|
|
else if (channel == 7)
|
|
{
|
|
writeRegisterMasked(REG_CLOCK, enable << 11, REGMASK_CLOCK_CH7_EN);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool ADS131M08Hub::setChannelPGA(uint8_t channel, ADS131M08_PgaGain pga)
|
|
{ uint16_t pgaCode = (uint16_t) pga;
|
|
|
|
if (channel > 7)
|
|
{
|
|
return false;
|
|
}
|
|
if (channel == 0)
|
|
{
|
|
writeRegisterMasked(REG_GAIN1, pgaCode, REGMASK_GAIN_PGAGAIN0);
|
|
this->pgaGain[0] = pga;
|
|
return true;
|
|
}
|
|
else if (channel == 1)
|
|
{
|
|
writeRegisterMasked(REG_GAIN1, pgaCode << 4, REGMASK_GAIN_PGAGAIN1);
|
|
this->pgaGain[1] = pga;
|
|
return true;
|
|
}
|
|
else if (channel == 2)
|
|
{
|
|
writeRegisterMasked(REG_GAIN1, pgaCode << 8, REGMASK_GAIN_PGAGAIN2);
|
|
this->pgaGain[2] = pga;
|
|
return true;
|
|
}
|
|
else if (channel == 3)
|
|
{
|
|
writeRegisterMasked(REG_GAIN1, pgaCode << 12, REGMASK_GAIN_PGAGAIN3);
|
|
this->pgaGain[3] = pga;
|
|
return true;
|
|
}
|
|
if (channel == 4)
|
|
{
|
|
writeRegisterMasked(REG_GAIN2, pgaCode, REGMASK_GAIN_PGAGAIN4);
|
|
this->pgaGain[4] = pga;
|
|
return true;
|
|
}
|
|
else if (channel == 5)
|
|
{
|
|
writeRegisterMasked(REG_GAIN2, pgaCode << 4, REGMASK_GAIN_PGAGAIN5);
|
|
this->pgaGain[5] = pga;
|
|
return true;
|
|
}
|
|
else if (channel == 6)
|
|
{
|
|
writeRegisterMasked(REG_GAIN2, pgaCode << 8, REGMASK_GAIN_PGAGAIN6);
|
|
this->pgaGain[6] = pga;
|
|
return true;
|
|
}
|
|
else if (channel == 7)
|
|
{
|
|
writeRegisterMasked(REG_GAIN2, pgaCode << 12, REGMASK_GAIN_PGAGAIN7);
|
|
this->pgaGain[7] = pga;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
ADS131M08_PgaGain ADS131M08Hub::getChannelPGA(uint8_t channel)
|
|
{
|
|
if(channel > 7)
|
|
{
|
|
return ADS131M08_PgaGain::PGA_INVALID;
|
|
}
|
|
return this->pgaGain[channel];
|
|
}
|
|
|
|
void ADS131M08Hub::setGlobalChop(uint16_t global_chop)
|
|
{
|
|
writeRegisterMasked(REG_CFG, global_chop << 8, REGMASK_CFG_GC_EN);
|
|
}
|
|
|
|
void ADS131M08Hub::setGlobalChopDelay(uint16_t delay)
|
|
{
|
|
writeRegisterMasked(REG_CFG, delay << 9, REGMASK_CFG_GC_DLY);
|
|
}
|
|
|
|
bool ADS131M08Hub::setInputChannelSelection(uint8_t channel, uint8_t input)
|
|
{
|
|
if (channel > 3)
|
|
{
|
|
return false;
|
|
}
|
|
if (channel == 0)
|
|
{
|
|
writeRegisterMasked(REG_CH0_CFG, input, REGMASK_CHX_CFG_MUX);
|
|
return true;
|
|
}
|
|
else if (channel == 1)
|
|
{
|
|
writeRegisterMasked(REG_CH1_CFG, input, REGMASK_CHX_CFG_MUX);
|
|
return true;
|
|
}
|
|
else if (channel == 2)
|
|
{
|
|
writeRegisterMasked(REG_CH2_CFG, input, REGMASK_CHX_CFG_MUX);
|
|
return true;
|
|
}
|
|
else if (channel == 3)
|
|
{
|
|
writeRegisterMasked(REG_CH3_CFG, input, REGMASK_CHX_CFG_MUX);
|
|
return true;
|
|
}
|
|
else if (channel == 4)
|
|
{
|
|
writeRegisterMasked(REG_CH4_CFG, input, REGMASK_CHX_CFG_MUX);
|
|
return true;
|
|
}
|
|
else if (channel == 5)
|
|
{
|
|
writeRegisterMasked(REG_CH5_CFG, input, REGMASK_CHX_CFG_MUX);
|
|
return true;
|
|
}
|
|
else if (channel == 6)
|
|
{
|
|
writeRegisterMasked(REG_CH6_CFG, input, REGMASK_CHX_CFG_MUX);
|
|
return true;
|
|
}
|
|
else if (channel == 7)
|
|
{
|
|
writeRegisterMasked(REG_CH7_CFG, input, REGMASK_CHX_CFG_MUX);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool ADS131M08Hub::setChannelOffsetCalibration(uint8_t channel, int32_t offset)
|
|
{
|
|
|
|
uint16_t MSB = offset >> 8;
|
|
uint8_t LSB = offset;
|
|
|
|
if (channel > 7)
|
|
{
|
|
return false;
|
|
}
|
|
if (channel == 0)
|
|
{
|
|
writeRegisterMasked(REG_CH0_OCAL_MSB, MSB, 0xFFFF);
|
|
writeRegisterMasked(REG_CH0_OCAL_LSB, LSB << 8, REGMASK_CHX_OCAL0_LSB);
|
|
return true;
|
|
}
|
|
else if (channel == 1)
|
|
{
|
|
writeRegisterMasked(REG_CH1_OCAL_MSB, MSB, 0xFFFF);
|
|
writeRegisterMasked(REG_CH1_OCAL_LSB, LSB << 8, REGMASK_CHX_OCAL0_LSB);
|
|
return true;
|
|
}
|
|
else if (channel == 2)
|
|
{
|
|
writeRegisterMasked(REG_CH2_OCAL_MSB, MSB, 0xFFFF);
|
|
writeRegisterMasked(REG_CH2_OCAL_LSB, LSB << 8, REGMASK_CHX_OCAL0_LSB);
|
|
return true;
|
|
}
|
|
else if (channel == 3)
|
|
{
|
|
writeRegisterMasked(REG_CH3_OCAL_MSB, MSB, 0xFFFF);
|
|
writeRegisterMasked(REG_CH3_OCAL_LSB, LSB << 8 , REGMASK_CHX_OCAL0_LSB);
|
|
return true;
|
|
}
|
|
else if (channel == 4)
|
|
{
|
|
writeRegisterMasked(REG_CH4_OCAL_MSB, MSB, 0xFFFF);
|
|
writeRegisterMasked(REG_CH4_OCAL_LSB, LSB << 8 , REGMASK_CHX_OCAL0_LSB);
|
|
return true;
|
|
}
|
|
else if (channel == 5)
|
|
{
|
|
writeRegisterMasked(REG_CH5_OCAL_MSB, MSB, 0xFFFF);
|
|
writeRegisterMasked(REG_CH5_OCAL_LSB, LSB << 8 , REGMASK_CHX_OCAL0_LSB);
|
|
return true;
|
|
}
|
|
else if (channel == 6)
|
|
{
|
|
writeRegisterMasked(REG_CH6_OCAL_MSB, MSB, 0xFFFF);
|
|
writeRegisterMasked(REG_CH6_OCAL_LSB, LSB << 8 , REGMASK_CHX_OCAL0_LSB);
|
|
return true;
|
|
}
|
|
else if (channel == 7)
|
|
{
|
|
writeRegisterMasked(REG_CH7_OCAL_MSB, MSB, 0xFFFF);
|
|
writeRegisterMasked(REG_CH7_OCAL_LSB, LSB << 8 , REGMASK_CHX_OCAL0_LSB);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool ADS131M08Hub::setChannelGainCalibration(uint8_t channel, uint32_t gain)
|
|
{
|
|
|
|
uint16_t MSB = gain >> 8;
|
|
uint8_t LSB = gain;
|
|
|
|
if (channel > 7)
|
|
{
|
|
return false;
|
|
}
|
|
if (channel == 0)
|
|
{
|
|
writeRegisterMasked(REG_CH0_GCAL_MSB, MSB, 0xFFFF);
|
|
writeRegisterMasked(REG_CH0_GCAL_LSB, LSB << 8, REGMASK_CHX_GCAL0_LSB);
|
|
return true;
|
|
}
|
|
else if (channel == 1)
|
|
{
|
|
writeRegisterMasked(REG_CH1_GCAL_MSB, MSB, 0xFFFF);
|
|
writeRegisterMasked(REG_CH1_GCAL_LSB, LSB << 8, REGMASK_CHX_GCAL0_LSB);
|
|
return true;
|
|
}
|
|
else if (channel == 2)
|
|
{
|
|
writeRegisterMasked(REG_CH2_GCAL_MSB, MSB, 0xFFFF);
|
|
writeRegisterMasked(REG_CH2_GCAL_LSB, LSB << 8, REGMASK_CHX_GCAL0_LSB);
|
|
return true;
|
|
}
|
|
else if (channel == 3)
|
|
{
|
|
writeRegisterMasked(REG_CH3_GCAL_MSB, MSB, 0xFFFF);
|
|
writeRegisterMasked(REG_CH3_GCAL_LSB, LSB << 8, REGMASK_CHX_GCAL0_LSB);
|
|
return true;
|
|
}
|
|
else if (channel == 4)
|
|
{
|
|
writeRegisterMasked(REG_CH4_GCAL_MSB, MSB, 0xFFFF);
|
|
writeRegisterMasked(REG_CH4_GCAL_LSB, LSB << 8, REGMASK_CHX_GCAL0_LSB);
|
|
return true;
|
|
}
|
|
else if (channel == 5)
|
|
{
|
|
writeRegisterMasked(REG_CH5_GCAL_MSB, MSB, 0xFFFF);
|
|
writeRegisterMasked(REG_CH5_GCAL_LSB, LSB << 8, REGMASK_CHX_GCAL0_LSB);
|
|
return true;
|
|
}
|
|
else if (channel == 6)
|
|
{
|
|
writeRegisterMasked(REG_CH6_GCAL_MSB, MSB, 0xFFFF);
|
|
writeRegisterMasked(REG_CH6_GCAL_LSB, LSB << 8, REGMASK_CHX_GCAL0_LSB);
|
|
return true;
|
|
}
|
|
else if (channel == 7)
|
|
{
|
|
writeRegisterMasked(REG_CH7_GCAL_MSB, MSB, 0xFFFF);
|
|
writeRegisterMasked(REG_CH7_GCAL_LSB, LSB << 8, REGMASK_CHX_GCAL0_LSB);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool ADS131M08Hub::isDataReady()
|
|
{
|
|
if (digitalRead(drdyPin) == HIGH)
|
|
{
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
uint16_t ADS131M08Hub::getId()
|
|
{
|
|
return readRegister(REG_ID);
|
|
}
|
|
|
|
uint16_t ADS131M08Hub::getModeReg()
|
|
{
|
|
return readRegister(REG_MODE);
|
|
}
|
|
|
|
uint16_t ADS131M08Hub::getClockReg()
|
|
{
|
|
return readRegister(REG_CLOCK);
|
|
}
|
|
|
|
uint16_t ADS131M08Hub::getCfgReg()
|
|
{
|
|
return readRegister(REG_CFG);
|
|
}
|
|
|
|
AdcOutput ADS131M08Hub::readAdcRaw(void)
|
|
{
|
|
uint8_t x = 0;
|
|
uint8_t x2 = 0;
|
|
uint8_t x3 = 0;
|
|
int32_t aux;
|
|
AdcOutput res;
|
|
|
|
digitalWrite(csPin, LOW);
|
|
delayMicroseconds(1);
|
|
|
|
x = spi.transfer(0x00);
|
|
x2 = spi.transfer(0x00);
|
|
spi.transfer(0x00);
|
|
|
|
this->resultRaw.status = ((x << 8) | x2);
|
|
|
|
for(int i = 0; i<8; i++)
|
|
{
|
|
x = spi.transfer(0x00);
|
|
x2 = spi.transfer(0x00);
|
|
x3 = spi.transfer(0x00);
|
|
|
|
aux = (((x << 16) | (x2 << 8) | x3) & 0x00FFFFFF);
|
|
if (aux > 0x7FFFFF)
|
|
{
|
|
this->resultRaw.ch[i].i = ((~(aux)&0x00FFFFFF) + 1) * -1;
|
|
}
|
|
else
|
|
{
|
|
this->resultRaw.ch[i].i = aux;
|
|
}
|
|
}
|
|
|
|
delayMicroseconds(1);
|
|
digitalWrite(csPin, HIGH);
|
|
|
|
return this->resultRaw;
|
|
}
|
|
|
|
float ADS131M08Hub::scaleResult(uint8_t num)
|
|
{
|
|
if( num >= 8) {
|
|
return 0.0;
|
|
}
|
|
|
|
return this->resultFloat.ch[num].f = (float)(this->resultRaw.ch[num].i * rawToVolts * this->fullScale.ch[num].f);
|
|
}
|
|
|
|
AdcOutput ADS131M08Hub::scaleResult(void)
|
|
{
|
|
// update status
|
|
this->resultFloat.status = this->resultRaw.status;
|
|
// Scale all channels
|
|
for(int i = 0; i<8; i++)
|
|
{
|
|
this->scaleResult(i);
|
|
}
|
|
|
|
return this->resultFloat;
|
|
}
|
|
|
|
AdcOutput ADS131M08Hub::readAdcFloat(void)
|
|
{
|
|
this->readAdcRaw();
|
|
return this->scaleResult();
|
|
}
|
|
// end of from tpcorrea
|
|
void ADS131M08Hub::dump_config()
|
|
{
|
|
ESP_LOGCONFIG(TAG, "ADS131M08:");
|
|
LOG_PIN(" CS Pin:", this->cs_);
|
|
LOG_PIN(" DRDY Pin:", this->drdy_pin_);
|
|
ESP_LOGCONFIG(TAG, " Reference Voltage: %.2fV", this->reference_voltage_);
|
|
}
|
|
|
|
} // namespace ads131m08
|
|
} // namespace esphome
|