Added datasheet example code and some arduino git code from tpcorrea. Still WIP.
This commit is contained in:
parent
81c179b556
commit
76fd7fa443
@ -1,74 +1,28 @@
|
|||||||
#include "ads131m08.h"
|
#include "ads131m08.h"
|
||||||
/*
|
|
||||||
namespace esphome {
|
namespace esphome {
|
||||||
namespace ads131m08 {
|
namespace ads131m08 {
|
||||||
|
|
||||||
static const char *const TAG = "ads131m08";
|
static const char *const TAG = "ads131m08";
|
||||||
|
|
||||||
ADS131M08::ADS131M08(esphome::gpio::GPIOPin *pin)
|
|
||||||
: drdy_pin_(pin)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void ADS131M08::set_drdy_pin(InternalGPIOPin *pin)
|
void ADS131M08Hub::setup()
|
||||||
{
|
|
||||||
drdy_pin_ = pin;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ADS131M08::set_sensor(int channel, sensor::Sensor *s)
|
|
||||||
{
|
|
||||||
channels_[channel] = s;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ADS131M08::set_reference_voltage(float reference_voltage)
|
|
||||||
{
|
|
||||||
this->reference_voltage_ = reference_voltage;
|
|
||||||
}
|
|
||||||
|
|
||||||
float ADS131M08::get_setup_priority() const
|
|
||||||
{
|
|
||||||
return setup_priority::HARDWARE;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ADS131M08::setup()
|
|
||||||
{
|
{
|
||||||
// Initialize SPI with correct settings for ADS131M08
|
// Initialize SPI with correct settings for ADS131M08
|
||||||
// SPI mode 1: CPOL=0, CPHA=1
|
// SPI mode 1: CPOL=0, CPHA=1
|
||||||
//this->spi_setup();
|
this->spi_setup();
|
||||||
|
// not sure if next few lines are needed here or is it handled in spi_setup()
|
||||||
SPI.begin();
|
SPI.begin();
|
||||||
SPI.setDataMode(SPI_MODE1);
|
SPI.setDataMode(SPI_MODE1);
|
||||||
SPI.setBitOrder(MSBFIRST);
|
SPI.setBitOrder(MSBFIRST);
|
||||||
SPI.setClockDivider(SPI_CLOCK_DIV8); // Adjust clock speed as needed
|
SPI.setClockDivider(SPI_CLOCK_DIV8); // Adjust clock speed as needed
|
||||||
|
this->drdy_pin_->setup();
|
||||||
// Configure DRDY pin
|
this->drdy_pin_->pin_mode(esphome::gpio::FLAG_INPUT | esphome::gpio::FLAG_PULLUP);
|
||||||
drdy_pin_->setup();
|
this->drdy_pin_->attach_interrupt(&ADS131M08Hub::isr, this, gpio::INTERRUPT_FALLING_EDGE);
|
||||||
drdy_pin_->pin_mode(esphome::gpio::FLAG_INPUT | esphome::gpio::FLAG_PULLUP);
|
this->initialize_ads131m08();
|
||||||
|
|
||||||
// Attach interrupt on falling edge of DRDY
|
|
||||||
// esphome::gpio::attach_interrupt(drdy_pin_, esphome::gpio::INTERRUPT_FALLING_EDGE, [this]() {
|
|
||||||
// this->data_ready_ = true;
|
|
||||||
// });
|
|
||||||
this->drdy_pin_->attach_interrupt(&ADS131M08Component::handle_drdy, this, gpio::INTERRUPT_FALLING_EDGE);
|
|
||||||
|
|
||||||
// Initialize ADS131M08
|
|
||||||
initialize_ads131m08();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// interrupt handler
|
void ADS131M08Hub::initialize_ads131m08()
|
||||||
void ADS131M08::handle_drdy(ADS131M08Component *arg)
|
|
||||||
{
|
|
||||||
arg->data_ready_ = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ADS131M08::loop()
|
|
||||||
{
|
|
||||||
if (data_ready_) {
|
|
||||||
data_ready_ = false;
|
|
||||||
read_all_channels();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ADS131M08::initialize_ads131m08()
|
|
||||||
{
|
{
|
||||||
// Send RESET command
|
// Send RESET command
|
||||||
SPI.transfer(0x06);
|
SPI.transfer(0x06);
|
||||||
@ -89,7 +43,7 @@ void ADS131M08::initialize_ads131m08()
|
|||||||
SPI.transfer(0x08); // START command
|
SPI.transfer(0x08); // START command
|
||||||
}
|
}
|
||||||
|
|
||||||
void ADS131M08::write_register(uint8_t reg, uint16_t value)
|
void ADS131M08Hub::write_register(uint8_t reg, uint16_t value)
|
||||||
{
|
{
|
||||||
SPI.transfer(0x40 | reg); // WREG command
|
SPI.transfer(0x40 | reg); // WREG command
|
||||||
SPI.transfer(0x00); // Number of registers - 1 (0 for one register)
|
SPI.transfer(0x00); // Number of registers - 1 (0 for one register)
|
||||||
@ -97,6 +51,99 @@ void ADS131M08::write_register(uint8_t reg, uint16_t value)
|
|||||||
SPI.transfer(value & 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ********************** end of from datasheet ************************
|
||||||
|
|
||||||
|
/*
|
||||||
void ADS131M08::read_all_channels()
|
void ADS131M08::read_all_channels()
|
||||||
{
|
{
|
||||||
// Send RDATA command or read data directly
|
// Send RDATA command or read data directly
|
||||||
@ -120,52 +167,7 @@ void ADS131M08::read_all_channels()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
float ADS131M08::read_data(uint8_t channel)
|
|
||||||
{
|
|
||||||
// This function assumes read_all_channels() has been called and data is in data_buffer_
|
|
||||||
int offset = channel * 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)
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ADS131M08::dump_config() {
|
|
||||||
ESP_LOGCONFIG(TAG, "ADS131M08:");
|
|
||||||
LOG_PIN(" CS Pin:", this->cs_);
|
|
||||||
ESP_LOGCONFIG(TAG, " Reference Voltage: %.2fV", this->reference_voltage_);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace ads131m08
|
|
||||||
} // namespace esphome
|
|
||||||
*/
|
|
||||||
namespace esphome {
|
|
||||||
namespace ads131m08 {
|
|
||||||
|
|
||||||
static const char *const TAG = "ads131m08";
|
|
||||||
|
|
||||||
void ADS131M08Hub::setup()
|
|
||||||
{
|
|
||||||
this->spi_setup();
|
|
||||||
this->drdy_pin_->setup();
|
|
||||||
this->drdy_pin_->attach_interrupt(&ADS131M08Hub::isr, this, gpio::INTERRUPT_FALLING_EDGE);
|
|
||||||
}
|
|
||||||
|
|
||||||
void IRAM_ATTR ADS131M08Hub::isr(ADS131M08Hub *arg)
|
|
||||||
{
|
|
||||||
arg->data_ready_ = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ADS131M08Hub::loop()
|
|
||||||
{
|
|
||||||
if (this->data_ready_) {
|
|
||||||
this->data_ready_ = false;
|
|
||||||
this->read_data_();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ADS131M08Hub::read_data_()
|
void ADS131M08Hub::read_data_()
|
||||||
{
|
{
|
||||||
this->enable();
|
this->enable();
|
||||||
|
|||||||
@ -8,6 +8,422 @@
|
|||||||
namespace esphome {
|
namespace esphome {
|
||||||
namespace ads131m08 {
|
namespace ads131m08 {
|
||||||
|
|
||||||
|
typedef union {
|
||||||
|
|
||||||
|
int32_t i;
|
||||||
|
float f;
|
||||||
|
uint16_t u[2];
|
||||||
|
uint8_t b[4];
|
||||||
|
} flex32_t;
|
||||||
|
|
||||||
|
|
||||||
|
/* Adc Structure. Ch can be read as int32 or float*/
|
||||||
|
struct AdcOutput
|
||||||
|
{
|
||||||
|
uint16_t status;
|
||||||
|
flex32_t ch[8];
|
||||||
|
};
|
||||||
|
|
||||||
|
enum ADS131M08_DRDY_STATE
|
||||||
|
{
|
||||||
|
DS_LOGIC_HIGH = 0, // DEFAULT
|
||||||
|
DS_HI_Z = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
enum ADS131M08_POWERMODE
|
||||||
|
{
|
||||||
|
PM_VERY_LOW_POWER = 0,
|
||||||
|
PM_LOW_POWER = 1,
|
||||||
|
PM_HIGH_RESOLUTION = 2 // DEFAULT
|
||||||
|
};
|
||||||
|
|
||||||
|
enum ADS131M08_PGA_GAIN
|
||||||
|
{
|
||||||
|
PGA_1 = 0,
|
||||||
|
PGA_2 = 1,
|
||||||
|
PGA_4 = 2,
|
||||||
|
PGA_8 = 3,
|
||||||
|
PGA_16 = 4,
|
||||||
|
PGA_32 = 5,
|
||||||
|
PGA_64 = 6,
|
||||||
|
PGA_128 = 7,
|
||||||
|
PGA_INVALID
|
||||||
|
};
|
||||||
|
|
||||||
|
enum ADS131M08_INPUT_CHANNEL_MUX
|
||||||
|
{
|
||||||
|
ICM_AIN0P_AIN0N = 0, // DEFAULT
|
||||||
|
ICM_INPUT_SHORTED = 1,
|
||||||
|
ICM_POSITIVE_DC_TEST_SIGNAL = 2,
|
||||||
|
ICM_NEGATIVE_DC_TEST_SIGNAL = 3,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum ADS131M08_OVERSAMPLING_RATIO
|
||||||
|
{
|
||||||
|
OSR_128 = 0,
|
||||||
|
OSR_256 = 1,
|
||||||
|
OSR_512 = 2,
|
||||||
|
OSR_1024 = 3, // default
|
||||||
|
OSR_2048 = 4,
|
||||||
|
OSR_4096 = 5,
|
||||||
|
OSR_8192 = 6,
|
||||||
|
OSR_16384 = 7
|
||||||
|
};
|
||||||
|
|
||||||
|
enum ADS131M08_WAIT_TIME
|
||||||
|
{
|
||||||
|
WT_128 = 856,
|
||||||
|
WT_256 = 1112,
|
||||||
|
WT_512 = 1624,
|
||||||
|
WT_1024 = 2648,
|
||||||
|
WT_2048 = 4696,
|
||||||
|
WT_4096 = 8792,
|
||||||
|
WT_8192 = 16984,
|
||||||
|
WT_16384 = 33368
|
||||||
|
};
|
||||||
|
|
||||||
|
// MODE Register
|
||||||
|
enum ADS131M08_RESET : uint16_t
|
||||||
|
{
|
||||||
|
MODE_NO_RESET = 0x0000, // DEFAULT
|
||||||
|
MODE_RESET_HAPPENED = 0x0400
|
||||||
|
};
|
||||||
|
|
||||||
|
enum ADS131M08_CRC_TYPE : uint16_t
|
||||||
|
{
|
||||||
|
CRC_CCITT_16BIT = 0x0000, // DEFAULT
|
||||||
|
CRC_ANSI_16BIT = 0x0800
|
||||||
|
};
|
||||||
|
|
||||||
|
enum ADS131M08_WORD_LENGTH : uint16_t
|
||||||
|
{
|
||||||
|
WLENGTH_16_BITS = 0x0000,
|
||||||
|
WLENGTH_24_BITS = 0x0100, // DEFAULT
|
||||||
|
WLENGTH_32_BITS_LSB_ZERO_PADDING = 0x0200,
|
||||||
|
WLENGTH_32_BITS_MSB_SIGN_EXTEND = 0x0300
|
||||||
|
};
|
||||||
|
|
||||||
|
enum ADS131M08_TIMEOUT : uint16_t
|
||||||
|
{
|
||||||
|
TIMEOUT_DISABLED = 0x0000,
|
||||||
|
TIMEOUT_ENABLED = 0x0010 // DEFAULT
|
||||||
|
};
|
||||||
|
|
||||||
|
enum ADS131M08_DRDY_SELECTION : uint16_t
|
||||||
|
{
|
||||||
|
DRDY_SEL_MOST_LAGGING = 0x0000, // DEFAULT
|
||||||
|
DRDY_SEL_LOGICAL_OR = 0x0004,
|
||||||
|
DRDY_SEL_MOST_LEADING_CHAN = 0x0008,
|
||||||
|
DRDY_SEL_MOST_LEADING_CHAN = 0x000C
|
||||||
|
};
|
||||||
|
enum ADS131M08_DRDY_FORMAT : uint16_t
|
||||||
|
{
|
||||||
|
DRDY_FMT_LEVEL = 0x0000, // Logic low (default)
|
||||||
|
DRDY_FMT_PULSE = 0x0001 // Low pulse with a fixed duration
|
||||||
|
};
|
||||||
|
// end of MODE Register
|
||||||
|
|
||||||
|
// GAIN1 Register
|
||||||
|
enum ADS131M08_GAIN1_CHANNEL_PGA : uint16_t {
|
||||||
|
PGAGAIN0_1 = 0x0000, // default
|
||||||
|
PGAGAIN0_2 = 0x0001,
|
||||||
|
PGAGAIN0_4 = 0x0002,
|
||||||
|
PGAGAIN0_8 = 0x0003,
|
||||||
|
PGAGAIN0_16 = 0x0004,
|
||||||
|
PGAGAIN0_32 = 0x0005,
|
||||||
|
PGAGAIN0_64 = 0x0006,
|
||||||
|
PGAGAIN0_128 = 0x0007,
|
||||||
|
PGAGAIN1_1 = 0x0000, // default
|
||||||
|
PGAGAIN1_2 = 0x0010,
|
||||||
|
PGAGAIN1_4 = 0x0020,
|
||||||
|
PGAGAIN1_8 = 0x0030,
|
||||||
|
PGAGAIN1_16 = 0x0040,
|
||||||
|
PGAGAIN1_32 = 0x0050,
|
||||||
|
PGAGAIN1_64 = 0x0060,
|
||||||
|
PGAGAIN1_128 = 0x0070,
|
||||||
|
PGAGAIN2_1 = 0x0000, // default
|
||||||
|
PGAGAIN2_2 = 0x0100,
|
||||||
|
PGAGAIN2_4 = 0x0200,
|
||||||
|
PGAGAIN2_8 = 0x0300,
|
||||||
|
PGAGAIN2_16 = 0x0400,
|
||||||
|
PGAGAIN2_32 = 0x0500,
|
||||||
|
PGAGAIN2_64 = 0x0600,
|
||||||
|
PGAGAIN2_128 = 0x0700,
|
||||||
|
PGAGAIN3_1 = 0x0000, // default
|
||||||
|
PGAGAIN3_2 = 0x1000,
|
||||||
|
PGAGAIN3_4 = 0x2000,
|
||||||
|
PGAGAIN3_8 = 0x3000,
|
||||||
|
PGAGAIN3_16 = 0x4000,
|
||||||
|
PGAGAIN3_32 = 0x5000, // Set PGA gain to 32 for channel
|
||||||
|
PGAGAIN3_64 = 0x6000,
|
||||||
|
PGAGAIN3_128 = 0x7000
|
||||||
|
};
|
||||||
|
// end of GAIN1 Register
|
||||||
|
|
||||||
|
// GAIN2 Register
|
||||||
|
enum ADS131M08_GAIN2_CHANNEL_PGA : uint16_t {
|
||||||
|
PGAGAIN4_1 = 0x0000, // default
|
||||||
|
PGAGAIN4_2 = 0x0001,
|
||||||
|
PGAGAIN4_4 = 0x0002,
|
||||||
|
PGAGAIN4_8 = 0x0003,
|
||||||
|
PGAGAIN4_16 = 0x0004,
|
||||||
|
PGAGAIN4_32 = 0x0005,
|
||||||
|
PGAGAIN4_64 = 0x0006,
|
||||||
|
PGAGAIN4_128 = 0x0007,
|
||||||
|
PGAGAIN5_1 = 0x0000, // default
|
||||||
|
PGAGAIN5_2 = 0x0010,
|
||||||
|
PGAGAIN5_4 = 0x0020,
|
||||||
|
PGAGAIN5_8 = 0x0030,
|
||||||
|
PGAGAIN5_16 = 0x0040,
|
||||||
|
PGAGAIN5_32 = 0x0050,
|
||||||
|
PGAGAIN5_64 = 0x0060,
|
||||||
|
PGAGAIN5_128 = 0x0070,
|
||||||
|
PGAGAIN6_1 = 0x0000, // default
|
||||||
|
PGAGAIN6_2 = 0x0100,
|
||||||
|
PGAGAIN6_4 = 0x0200,
|
||||||
|
PGAGAIN6_8 = 0x0300,
|
||||||
|
PGAGAIN6_16 = 0x0400,
|
||||||
|
PGAGAIN6_32 = 0x0500,
|
||||||
|
PGAGAIN6_64 = 0x0600,
|
||||||
|
PGAGAIN6_128 = 0x0700,
|
||||||
|
PGAGAIN7_1 = 0x0000, // default
|
||||||
|
PGAGAIN7_2 = 0x1000,
|
||||||
|
PGAGAIN7_4 = 0x2000,
|
||||||
|
PGAGAIN7_8 = 0x3000,
|
||||||
|
PGAGAIN7_16 = 0x4000,
|
||||||
|
PGAGAIN7_32 = 0x5000,
|
||||||
|
PGAGAIN7_64 = 0x6000,
|
||||||
|
PGAGAIN7_128 = 0x7000
|
||||||
|
};
|
||||||
|
// end of GAIN2 Register
|
||||||
|
|
||||||
|
|
||||||
|
// Commands
|
||||||
|
enum ADS131M08_COMMANDS : uint16_t {
|
||||||
|
CMD_NULL = 0x0000, // No operation; used to read STATUS register
|
||||||
|
CMD_RESET = 0x0011, // RESET the device
|
||||||
|
CMD_STANDBY = 0x0022, // Place the device into standby mode
|
||||||
|
CMD_WAKEUP = 0x0033, // Wake up device from standby mode to conversion mode
|
||||||
|
CMD_LOCK = 0x0555, // Lock the interface such that only the NULL, UNLOCK, and RREG commands are valid
|
||||||
|
CMD_UNLOCK = 0x0655, // Unlock the interface after the interface is locked
|
||||||
|
CMD_RREG = 0xA000, // Read register command base; number of registers to read added to lower byte; register address to upper byte
|
||||||
|
CMD_WREG = 0x6000, // Write register command base; number of registers to write added to lower byte; register address to upper byte
|
||||||
|
};
|
||||||
|
|
||||||
|
// Responses
|
||||||
|
enum ADS131M08_RESPONSES : uint16_t {
|
||||||
|
RSP_RESET_OK = 0xFF28,
|
||||||
|
RSP_RESET_NOK = 0x0011
|
||||||
|
};
|
||||||
|
|
||||||
|
enum ADS131M08_REG {
|
||||||
|
REG_ID = 0x00,
|
||||||
|
REG_STATUS = 0x01,
|
||||||
|
REG_MODE = 0x02,
|
||||||
|
REG_CLOCK = 0x03,
|
||||||
|
REG_GAIN1 = 0x04,
|
||||||
|
REG_GAIN2 = 0x05,
|
||||||
|
REG_CFG = 0x06,
|
||||||
|
REG_THRSHLD_MSB = 0x07,
|
||||||
|
REG_THRSHLD_LSB = 0x08,
|
||||||
|
REG_CH0_CFG = 0x09,
|
||||||
|
REG_CH0_OCAL_MSB = 0x0A,
|
||||||
|
REG_CH0_OCAL_LSB = 0x0B,
|
||||||
|
REG_CH0_GCAL_MSB = 0x0C,
|
||||||
|
REG_CH0_GCAL_LSB = 0x0D,
|
||||||
|
REG_CH1_CFG = 0x0E,
|
||||||
|
REG_CH1_OCAL_MSB = 0x0F,
|
||||||
|
REG_CH1_OCAL_LSB = 0x10,
|
||||||
|
REG_CH1_GCAL_MSB = 0x11,
|
||||||
|
REG_CH1_GCAL_LSB = 0x12,
|
||||||
|
REG_CH2_CFG = 0x13,
|
||||||
|
REG_CH2_OCAL_MSB= 0x14,
|
||||||
|
REG_CH2_OCAL_LSB= 0x15,
|
||||||
|
REG_CH2_GCAL_MSB= 0x16,
|
||||||
|
REG_CH2_GCAL_LSB= 0x17,
|
||||||
|
REG_CH3_CFG = 0x18,
|
||||||
|
REG_CH3_OCAL_MSB= 0x19,
|
||||||
|
REG_CH3_OCAL_LSB= 0x1A,
|
||||||
|
REG_CH3_GCAL_MSB= 0x1B,
|
||||||
|
REG_CH3_GCAL_LSB= 0x1C,
|
||||||
|
REG_CH4_CFG = 0x1D,
|
||||||
|
REG_CH4_OCAL_MSB= 0x1E,
|
||||||
|
REG_CH4_OCAL_LSB= 0x1F,
|
||||||
|
REG_CH4_GCAL_MSB= 0x20,
|
||||||
|
REG_CH4_GCAL_LSB= 0x21,
|
||||||
|
REG_CH5_CFG = 0x22,
|
||||||
|
REG_CH5_OCAL_MSB= 0x23,
|
||||||
|
REG_CH5_OCAL_LSB= 0x24,
|
||||||
|
REG_CH5_GCAL_MSB= 0x25,
|
||||||
|
REG_CH5_GCAL_LSB= 0x26,
|
||||||
|
REG_CH6_CFG = 0x27,
|
||||||
|
REG_CH6_OCAL_MSB= 0x28,
|
||||||
|
REG_CH6_OCAL_LSB= 0x29,
|
||||||
|
REG_CH6_GCAL_MSB= 0x2A,
|
||||||
|
REG_CH6_GCAL_LSB= 0x2B,
|
||||||
|
REG_CH7_CFG = 0x2C,
|
||||||
|
REG_CH7_OCAL_MSB= 0x2D,
|
||||||
|
REG_CH7_OCAL_LSB= 0x2E,
|
||||||
|
REG_CH7_GCAL_MSB= 0x2F,
|
||||||
|
REG_CH7_GCAL_LSB= 0x30,
|
||||||
|
REGMAP_CRC = 0x3E,
|
||||||
|
};
|
||||||
|
// Mask READ_REG
|
||||||
|
static constexpr uint16_t MASK_CMD_READ_REG_ADDRESS = 0x1F80;
|
||||||
|
static constexpr uint16_t MASK_CMD_READ_REG_BYTES = 0x007F;
|
||||||
|
|
||||||
|
// Mask Register STATUS
|
||||||
|
static constexpr uint16_t MASK_STATUS_LOCK = 0x8000;
|
||||||
|
static constexpr uint16_t MASK_STATUS_RESYNC = 0x4000;
|
||||||
|
static constexpr uint16_t MASK_STATUS_REGMAP = 0x2000;
|
||||||
|
static constexpr uint16_t MASK_STATUS_CRC_ERR = 0x1000;
|
||||||
|
static constexpr uint16_t MASK_STATUS_CRC_TYPE = 0x0800;
|
||||||
|
static constexpr uint16_t MASK_STATUS_RESET = 0x0400;
|
||||||
|
static constexpr uint16_t MASK_STATUS_WLENGTH = 0x0300;
|
||||||
|
static constexpr uint16_t MASK_STATUS_DRDY7 = 0x0080;
|
||||||
|
static constexpr uint16_t MASK_STATUS_DRDY6 = 0x0040;
|
||||||
|
static constexpr uint16_t MASK_STATUS_DRDY5 = 0x0020;
|
||||||
|
static constexpr uint16_t MASK_STATUS_DRDY4 = 0x0010;
|
||||||
|
static constexpr uint16_t MASK_STATUS_DRDY3 = 0x0008;
|
||||||
|
static constexpr uint16_t MASK_STATUS_DRDY2 = 0x0004;
|
||||||
|
static constexpr uint16_t MASK_STATUS_DRDY1 = 0x0002;
|
||||||
|
static constexpr uint16_t MASK_STATUS_DRDY0 = 0x0001;
|
||||||
|
|
||||||
|
// Mask Register MODE
|
||||||
|
static constexpr uint16_t MASK_MODE_REG_CRC_EN = 0x2000;
|
||||||
|
static constexpr uint16_t MASK_MODE_RX_CRC_EN = 0x1000;
|
||||||
|
static constexpr uint16_t MASK_MODE_CRC_TYPE = 0x0800;
|
||||||
|
static constexpr uint16_t MASK_MODE_RESET = 0x0400;
|
||||||
|
static constexpr uint16_t MASK_MODE_WLENGTH = 0x0300;
|
||||||
|
static constexpr uint16_t MASK_MODE_TIMEOUT = 0x0010;
|
||||||
|
static constexpr uint16_t MASK_MODE_DRDY_SEL = 0x000C;
|
||||||
|
static constexpr uint16_t MASK_MODE_DRDY_HiZ = 0x0002;
|
||||||
|
static constexpr uint16_t MASK_MODE_DRDY_FMT = 0x0001;
|
||||||
|
|
||||||
|
// Mask Register CLOCK
|
||||||
|
static constexpr uint16_t MASK_CLOCK_CH7_EN = 0x8000;
|
||||||
|
static constexpr uint16_t MASK_CLOCK_CH6_EN = 0x4000;
|
||||||
|
static constexpr uint16_t MASK_CLOCK_CH5_EN = 0x2000;
|
||||||
|
static constexpr uint16_t MASK_CLOCK_CH4_EN = 0x1000;
|
||||||
|
static constexpr uint16_t MASK_CLOCK_CH3_EN = 0x0800;
|
||||||
|
static constexpr uint16_t MASK_CLOCK_CH2_EN = 0x0400;
|
||||||
|
static constexpr uint16_t MASK_CLOCK_CH1_EN = 0x0200;
|
||||||
|
static constexpr uint16_t MASK_CLOCK_CH0_EN = 0x0100;
|
||||||
|
static constexpr uint16_t MASK_CLOCK_OSR = 0x001C;
|
||||||
|
static constexpr uint16_t MASK_CLOCK_PWR = 0x0003;
|
||||||
|
static constexpr uint32_t MASK_CLOCK_ALL_CH_DISABLE = 0x0000;
|
||||||
|
static constexpr uint32_t MASK_CLOCK_ALL_CH_ENABLE = 0xFF00;
|
||||||
|
// Mask Register GAIN
|
||||||
|
static constexpr uint16_t MASK_GAIN_PGAGAIN7 = 0x7000;
|
||||||
|
static constexpr uint16_t MASK_GAIN_PGAGAIN6 = 0x0700;
|
||||||
|
static constexpr uint16_t MASK_GAIN_PGAGAIN5 = 0x0070;
|
||||||
|
static constexpr uint16_t MASK_GAIN_PGAGAIN4 = 0x0007;
|
||||||
|
static constexpr uint16_t MASK_GAIN_PGAGAIN3 = 0x7000;
|
||||||
|
static constexpr uint16_t MASK_GAIN_PGAGAIN2 = 0x0700;
|
||||||
|
static constexpr uint16_t MASK_GAIN_PGAGAIN1 = 0x0070;
|
||||||
|
static constexpr uint16_t MASK_GAIN_PGAGAIN0 = 0x0007;
|
||||||
|
|
||||||
|
// Mask Register CFG
|
||||||
|
static constexpr uint16_t MASK_CFG_GC_DLY = 0x1E00;
|
||||||
|
static constexpr uint16_t MASK_CFG_GC_EN = 0x0100;
|
||||||
|
static constexpr uint16_t MASK_CFG_CD_ALLCH = 0x0080;
|
||||||
|
static constexpr uint16_t MASK_CFG_CD_NUM = 0x0070;
|
||||||
|
static constexpr uint16_t MASK_CFG_CD_LEN = 0x000E;
|
||||||
|
static constexpr uint16_t MASK_CFG_CD_EN = 0x0001;
|
||||||
|
|
||||||
|
// Mask Register THRSHLD_MSB - dummy, for completeness
|
||||||
|
static constexpr uint16_t MASK_THRSHLD_MSB_CD_TH_MSB = 0xFFFF;
|
||||||
|
|
||||||
|
// Mask Register THRSHLD_LSB
|
||||||
|
static constexpr uint16_t MASK_THRSHLD_LSB_CD_TH_LSB = 0xFF00;
|
||||||
|
static constexpr uint16_t MASK_THRSHLD_LSB_DCBLOCK = 0x000F;
|
||||||
|
|
||||||
|
// Mask Register CHX_CFG
|
||||||
|
static constexpr uint16_t MASK_CHX_CFG_PHASE = 0xFFC0;
|
||||||
|
static constexpr uint16_t MASK_CHX_CFG_DCBLKX_DIS = 0x0004;
|
||||||
|
static constexpr uint16_t MASK_CHX_CFG_MUX = 0x0003;
|
||||||
|
|
||||||
|
// Mask Register CHX_OCAL_MSB - dummy, for completeness
|
||||||
|
static constexpr uint16_t MASK_CHX_OCAL_MSB = 0xFFFF;
|
||||||
|
|
||||||
|
// Mask Register CHX_OCAL_LSB
|
||||||
|
static constexpr uint16_t MASK_CHX_OCAL_LSB = 0xFF00;
|
||||||
|
|
||||||
|
// Mask Register CHX_GCAL_MSB - dummy, for completeness
|
||||||
|
static constexpr uint16_t MASK_CHX_GCAL_MSB = 0xFFFF;
|
||||||
|
|
||||||
|
// Mask Register CHX_GCAL_LSB
|
||||||
|
static constexpr uint16_t MASK_CHX_GCAL_LSB = 0xFF00;
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Conversion modes
|
||||||
|
static constexpr uint16_t CONVERSION_MODE_CONT = 0;
|
||||||
|
static constexpr uint16_t CONVERSION_MODE_SINGLE = 1;
|
||||||
|
|
||||||
|
// Data Format
|
||||||
|
static constexpr uint16_t DATA_FORMAT_TWO_COMPLEMENT = 0;
|
||||||
|
static constexpr uint16_t DATA_FORMAT_BINARY = 1;
|
||||||
|
|
||||||
|
// Measure Mode
|
||||||
|
static constexpr uint8_t MEASURE_UNIPOLAR = 1;
|
||||||
|
static constexpr uint8_t MEASURE_BIPOLAR = 0;
|
||||||
|
|
||||||
|
// Clock Type
|
||||||
|
static constexpr uint8_t CLOCK_EXTERNAL = 1;
|
||||||
|
static constexpr uint8_t CLOCK_INTERNAL = 0;
|
||||||
|
|
||||||
|
// PGA Gain
|
||||||
|
// static constexpr uint16_t PGA_GAIN_1 = 0;
|
||||||
|
// static constexpr uint16_t PGA_GAIN_2 = 1;
|
||||||
|
// static constexpr uint16_t PGA_GAIN_4 = 2;
|
||||||
|
// static constexpr uint16_t PGA_GAIN_8 = 3;
|
||||||
|
// static constexpr uint16_t PGA_GAIN_16 = 4;
|
||||||
|
// static constexpr uint16_t PGA_GAIN_32 = 5;
|
||||||
|
// static constexpr uint16_t PGA_GAIN_64 = 6;
|
||||||
|
// static constexpr uint16_t PGA_GAIN_128 = 7;
|
||||||
|
|
||||||
|
// Input Filter
|
||||||
|
static constexpr uint16_t FILTER_SYNC = 0;
|
||||||
|
static constexpr uint16_t FILTER_FIR = 2;
|
||||||
|
static constexpr uint16_t FILTER_FIR_IIR = 3;
|
||||||
|
|
||||||
|
// Data Mode
|
||||||
|
static constexpr uint8_t DATA_MODE_24BITS = 0;
|
||||||
|
static constexpr uint8_t DATA_MODE_32BITS = 1;
|
||||||
|
|
||||||
|
// Data Rate
|
||||||
|
static constexpr uint8_t DATA_RATE_0 = 0;
|
||||||
|
static constexpr uint8_t DATA_RATE_1 = 1;
|
||||||
|
static constexpr uint8_t DATA_RATE_2 = 2;
|
||||||
|
static constexpr uint8_t DATA_RATE_3 = 3;
|
||||||
|
static constexpr uint8_t DATA_RATE_4 = 4;
|
||||||
|
static constexpr uint8_t DATA_RATE_5 = 5;
|
||||||
|
static constexpr uint8_t DATA_RATE_6 = 6;
|
||||||
|
static constexpr uint8_t DATA_RATE_7 = 7;
|
||||||
|
static constexpr uint8_t DATA_RATE_8 = 8;
|
||||||
|
static constexpr uint8_t DATA_RATE_9 = 9;
|
||||||
|
static constexpr uint8_t DATA_RATE_10 = 10;
|
||||||
|
static constexpr uint8_t DATA_RATE_11 = 11;
|
||||||
|
static constexpr uint8_t DATA_RATE_12 = 12;
|
||||||
|
static constexpr uint8_t DATA_RATE_13 = 13;
|
||||||
|
static constexpr uint8_t DATA_RATE_14 = 14;
|
||||||
|
static constexpr uint8_t DATA_RATE_15 = 15;
|
||||||
|
// Sync Mpdes
|
||||||
|
static constexpr uint16_t SYNC_CONTINUOUS = 1;
|
||||||
|
static constexpr uint16_t SYNC_PULSE = 0;
|
||||||
|
|
||||||
|
// DIO Config Mode
|
||||||
|
static constexpr uint8_t DIO_OUTPUT = 1;
|
||||||
|
static constexpr uint8_t DIO_INPUT = 0;
|
||||||
|
|
||||||
|
static constexpr uint8_t SPI_MASTER_DUMMY = 0xFF;
|
||||||
|
static constexpr uint16_t SPI_MASTER_DUMMY16 = 0xFFFF;
|
||||||
|
static constexpr uint32_t SPI_MASTER_DUMMY32 = 0xFFFFFFFF;
|
||||||
|
|
||||||
|
|
||||||
|
// end of from datasheet
|
||||||
|
|
||||||
class ADS131M08Sensor : public sensor::Sensor, public Component
|
class ADS131M08Sensor : public sensor::Sensor, public Component
|
||||||
{
|
{
|
||||||
};
|
};
|
||||||
@ -15,6 +431,28 @@ class ADS131M08Sensor : public sensor::Sensor, public Component
|
|||||||
class ADS131M08Hub : public Component, public spi::SPIDevice<spi::BIT_ORDER_MSB_FIRST, spi::CLOCK_POLARITY_LOW, spi::CLOCK_PHASE_TRAILING, spi::DATA_RATE_8MHZ>
|
class ADS131M08Hub : public Component, public spi::SPIDevice<spi::BIT_ORDER_MSB_FIRST, spi::CLOCK_POLARITY_LOW, spi::CLOCK_PHASE_TRAILING, spi::DATA_RATE_8MHZ>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
// from datasheet pg. 93:
|
||||||
|
const int numFrameWords = 10; // Number of words in a full ADS131M08 SPI frame
|
||||||
|
unsigned long spiDummyWord[10 /*numFrameWords*/] = {
|
||||||
|
0x00000000,
|
||||||
|
0x00000000,
|
||||||
|
0x00000000,
|
||||||
|
0x00000000,
|
||||||
|
0x00000000,
|
||||||
|
0x00000000,
|
||||||
|
0x00000000,
|
||||||
|
0x00000000,
|
||||||
|
0x00000000,
|
||||||
|
0x00000000
|
||||||
|
}; // Dummy word frame to write ADC during ADC data reads
|
||||||
|
bool firstRead = true; // Flag to tell us if we are reading ADC data for the first time
|
||||||
|
signed long adcData; // Location where DMA will store ADC data in memory, length defined elsewhere
|
||||||
|
void txf_init();
|
||||||
|
bool adcRegisterWrite(unsigned short addrMask, unsigned short data, unsigned char adcWordLength);
|
||||||
|
void initialize_ads131m08_datasheet();
|
||||||
|
// end of from datasheet
|
||||||
|
|
||||||
|
bool setChannelPGA(uint8_t channel, uint8_t pga);
|
||||||
void setup() override;
|
void setup() override;
|
||||||
void loop() override;
|
void loop() override;
|
||||||
void set_drdy_pin(InternalGPIOPin *pin) { drdy_pin_ = pin; }
|
void set_drdy_pin(InternalGPIOPin *pin) { drdy_pin_ = pin; }
|
||||||
@ -22,6 +460,34 @@ class ADS131M08Hub : public Component, public spi::SPIDevice<spi::BIT_ORDER_MSB_
|
|||||||
void set_reference_voltage(float reference_voltage) { this->reference_voltage_ = reference_voltage; }
|
void set_reference_voltage(float reference_voltage) { this->reference_voltage_ = reference_voltage; }
|
||||||
void dump_config() override;
|
void dump_config() override;
|
||||||
|
|
||||||
|
// from tpcorrea
|
||||||
|
void 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);
|
||||||
|
int8_t isDataReadySoft(uint8_t channel);
|
||||||
|
bool isDataReady(void);
|
||||||
|
bool isResetStatus(void);
|
||||||
|
bool isLockSPI(void);
|
||||||
|
bool setDrdyFormat(uint8_t drdyFormat);
|
||||||
|
bool setDrdyStateWhenUnavailable(uint8_t drdyState);
|
||||||
|
bool setPowerMode(uint8_t powerMode);
|
||||||
|
bool setChannelEnable(uint8_t channel, uint16_t enable);
|
||||||
|
bool setChannelPGA(uint8_t channel, ADS131M08_PGA_GAIN pga);
|
||||||
|
ADS131M08_PGA_GAIN getChannelPGA(uint8_t channel);
|
||||||
|
void setGlobalChop(uint16_t global_chop);
|
||||||
|
void setGlobalChopDelay(uint16_t delay);
|
||||||
|
bool setInputChannelSelection(uint8_t channel, uint8_t input);
|
||||||
|
bool setChannelOffsetCalibration(uint8_t channel, int32_t offset);
|
||||||
|
bool setChannelGainCalibration(uint8_t channel, uint32_t gain);
|
||||||
|
bool setOsr(uint16_t osr);
|
||||||
|
void setFullScale(uint8_t channel, float scale);
|
||||||
|
float getFullScale(uint8_t channel);
|
||||||
|
void reset();
|
||||||
|
uint16_t getId();
|
||||||
|
uint16_t getModeReg();
|
||||||
|
uint16_t getClockReg();
|
||||||
|
uint16_t getCfgReg();
|
||||||
|
AdcOutput readAdcRaw(void);
|
||||||
|
AdcOutput readAdcFloat(void);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
float reference_voltage_;
|
float reference_voltage_;
|
||||||
InternalGPIOPin *drdy_pin_;
|
InternalGPIOPin *drdy_pin_;
|
||||||
@ -29,6 +495,8 @@ class ADS131M08Hub : public Component, public spi::SPIDevice<spi::BIT_ORDER_MSB_
|
|||||||
volatile bool data_ready_{false};
|
volatile bool data_ready_{false};
|
||||||
static void isr(ADS131M08Hub *arg);
|
static void isr(ADS131M08Hub *arg);
|
||||||
void read_data_();
|
void read_data_();
|
||||||
|
void write_register(uint8_t reg, uint16_t value);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ads131m08
|
} // namespace ads131m08
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user