|
#include <iostream> |
|
#include <chrono> |
|
#include <thread> |
|
#include <lgpio.h> |
|
#include <chrono> |
|
#include <iomanip> |
|
#include <functional> |
|
#include <mutex> |
|
#include <condition_variable> |
|
|
|
const int RST_PIN = 18; |
|
const int CS_PIN = 22; |
|
const int DRDY_PIN = 17; |
|
|
|
#define DEBUG_MODE 0 |
|
|
|
#define LOG(msg) \ |
|
if (DEBUG_MODE) \ |
|
{ \ |
|
msg; \ |
|
} |
|
|
|
#define CHECK_ERROR(error) \ |
|
if ((error) < 0) \ |
|
{ \ |
|
const char *error_str = lguErrorText(error); \ |
|
throw std::runtime_error("lguErrorText: " + std::string(error_str)); \ |
|
} |
|
|
|
void delay_ms(int ms) |
|
{ |
|
std::this_thread::sleep_for(std::chrono::milliseconds(ms)); |
|
} |
|
|
|
// void ADS1263_reset(int chip) |
|
// { |
|
// int error; |
|
// CHECK_ERROR(lgGpioWrite(chip, RST_PIN, 1)); |
|
// delay_ms(200); |
|
// CHECK_ERROR(lgGpioWrite(chip, RST_PIN, 0)); |
|
// delay_ms(200); |
|
// CHECK_ERROR(lgGpioWrite(chip, RST_PIN, 1)); |
|
// delay_ms(200); |
|
// } |
|
|
|
// void digital_write(int chip, int pin, int value) |
|
// { |
|
// CHECK_ERROR(lgGpioWrite(chip, pin, value)); |
|
// } |
|
|
|
// int digital_read(int chip, int pin) |
|
// { |
|
// int value = lgGpioRead(chip, pin); |
|
// CHECK_ERROR(value); |
|
// return value; |
|
// } |
|
|
|
// void ADS1263_ReadData(int chip, spi, int reg) |
|
// { |
|
// int error; |
|
// digital_write(chip, CS_PIN, 0); |
|
// lgSpiWrite(spiHandle) |
|
// } |
|
|
|
void afunc(int e, lgGpioAlert_p evt, void *data); |
|
|
|
class Config |
|
{ |
|
public: |
|
Config() |
|
{ |
|
int spiDevice = 0; |
|
int spiChannel = 0; |
|
int spiBaud = 2000000; |
|
spiHandle = lgSpiOpen(spiDevice, spiChannel, spiBaud, 1); |
|
CHECK_ERROR(spiHandle); |
|
|
|
chip = lgGpiochipOpen(4); |
|
CHECK_ERROR(chip); |
|
|
|
lgChipInfo_s chipInfo; |
|
CHECK_ERROR(lgGpioGetChipInfo(chip, &chipInfo)); |
|
LOG(std::cout << "Chip: " << chipInfo.name << std::endl); |
|
LOG(std::cout << " - lines: " << chipInfo.lines << std::endl); |
|
LOG(std::cout << " - label: " << chipInfo.label << std::endl); |
|
|
|
LOG(std::cout << "Config initialized" << std::endl); |
|
} |
|
|
|
static Config& getInstance() |
|
{ |
|
static Config config; |
|
return config; |
|
} |
|
|
|
void digital_write(int pin, int value) |
|
{ |
|
LOG(std::cout << " * digital_write(" << pin << ", " << value << ") at: " << chip << std::endl); |
|
LOG(std::cout << " - chip: " << chip << std::endl); |
|
|
|
lgLineInfo_t lineInfo; |
|
CHECK_ERROR(lgGpioGetLineInfo(chip, pin, &lineInfo)); |
|
LOG(std::cout << " - lineInfo: " << lineInfo.name << std::endl); |
|
|
|
CHECK_ERROR(lgGpioWrite(chip, pin, value)); |
|
LOG(std::cout << " - DONE" << std::endl); |
|
} |
|
|
|
int digital_read(int pin) |
|
{ |
|
// std::cout << " * digital_read" << std::endl; |
|
int value = lgGpioRead(chip, pin); |
|
CHECK_ERROR(value); |
|
return value; |
|
} |
|
|
|
void delay_ms(int ms) |
|
{ |
|
std::this_thread::sleep_for(std::chrono::milliseconds(ms)); |
|
} |
|
|
|
void spi_writebytes(std::initializer_list<uint8_t> data) |
|
{ |
|
LOG(std::cout << " * spi_writebytes" << std::endl); |
|
char *txBuf = (char *)malloc(data.size()); |
|
std::copy(data.begin(), data.end(), txBuf); |
|
CHECK_ERROR(lgSpiWrite(spiHandle, txBuf, data.size())); |
|
free((void *)txBuf); |
|
} |
|
|
|
char *spi_readbytes(int n_bytes) |
|
{ |
|
LOG(std::cout << " * spi_readbytes" << std::endl); |
|
char *rxBuf = (char *)malloc(n_bytes); |
|
int n_bytes_read = lgSpiRead(spiHandle, rxBuf, n_bytes); |
|
CHECK_ERROR(n_bytes_read); |
|
if (n_bytes_read != n_bytes) |
|
{ |
|
printf("Failed to read %d bytes\n", n_bytes); |
|
std::exit(1); |
|
} |
|
return rxBuf; |
|
} |
|
|
|
void spi_readbytes_n(uint8_t *rxBuf, unsigned int n) |
|
{ |
|
int n_bytes_read = lgSpiRead(spiHandle, (char *)rxBuf, n); |
|
CHECK_ERROR(n_bytes_read); |
|
if (n_bytes_read != n) |
|
{ |
|
printf("Failed to read %d bytes\n", n); |
|
std::exit(1); |
|
} |
|
} |
|
|
|
void receive_alert(int e, lgGpioAlert_p evt, void *data) |
|
{ |
|
int i; |
|
int userdata = *(int *)data; |
|
|
|
for (i = 0; i < e; i++) |
|
{ |
|
LOG(printf("u=%d t=%" PRIu64 " c=%d g=%d l=%d f=%d (%d of %d)\n", |
|
userdata, evt[i].report.timestamp, evt[i].report.chip, |
|
evt[i].report.gpio, evt[i].report.level, |
|
evt[i].report.flags, i + 1, e)); |
|
// if (evt[i].report.chip != chip) |
|
// continue; |
|
if (evt[i].report.gpio != DRDY_PIN) |
|
continue; |
|
if (evt[i].report.flags != 0) |
|
continue; |
|
|
|
{ |
|
std::lock_guard<std::mutex> lock(m); |
|
is_ready = evt[i].report.level == 0; |
|
cv.notify_all(); |
|
} |
|
} |
|
} |
|
void module_init() |
|
{ |
|
int lFlags = 0; |
|
CHECK_ERROR(lgGpioClaimOutput(chip, lFlags, RST_PIN, 0)); |
|
CHECK_ERROR(lgGpioClaimOutput(chip, lFlags, CS_PIN, 0)); |
|
CHECK_ERROR(lgGpioClaimInput(chip, LG_SET_PULL_UP, DRDY_PIN)); |
|
|
|
is_ready = digital_read(DRDY_PIN) == 0; |
|
|
|
static int userdata = 123; |
|
// Create a static function wrapper to handle the bind |
|
CHECK_ERROR(lgGpioSetAlertsFunc(chip, DRDY_PIN, afunc, this)); |
|
CHECK_ERROR(lgGpioClaimAlert(chip, 0, LG_SET_PULL_UP | LG_BOTH_EDGES, DRDY_PIN, -1)); |
|
} |
|
|
|
void wait_for_ready() |
|
{ |
|
std::unique_lock<std::mutex> lock(m); |
|
cv.wait(lock, [this]() { return is_ready; }); |
|
} |
|
|
|
void describe_pin(int pin) |
|
{ |
|
lgLineInfo_t lineInfo; |
|
CHECK_ERROR(lgGpioGetLineInfo(chip, pin, &lineInfo)); |
|
LOG(std::cout << " * describe_pin(" << pin << ") at: " << chip << " " << lineInfo.name << std::endl); |
|
} |
|
|
|
// ~Config() |
|
// { |
|
// if (chip != std::numeric_limits<int>::max()) |
|
// { |
|
// lgGpiochipClose(chip); |
|
// } |
|
// if (spiHandle != std::numeric_limits<int>::max()) |
|
// { |
|
// lgSpiClose(spiHandle); |
|
// } |
|
// } |
|
|
|
private: |
|
int spiHandle = std::numeric_limits<int>::max(); |
|
int chip = std::numeric_limits<int>::max(); |
|
|
|
std::mutex m; |
|
std::condition_variable cv; |
|
|
|
bool is_ready = false; |
|
}; |
|
|
|
void afunc(int e, lgGpioAlert_p evt, void *data) { |
|
Config& config = Config::getInstance(); |
|
config.receive_alert(e, evt, data); |
|
} |
|
|
|
|
|
void print_sbc_name() |
|
{ |
|
char *sbcName = (char *)malloc(100); |
|
int error = lguSbcName(sbcName, 100); |
|
CHECK_ERROR(error); |
|
printf("SBC name: %s\n", sbcName); |
|
free(sbcName); |
|
} |
|
|
|
uint8_t ADS1263_CMD_RESET = 0x06; |
|
uint8_t ADS1263_CMD_START1 = 0x08; |
|
uint8_t ADS1263_CMD_STOP1 = 0x0A; |
|
uint8_t ADS1263_CMD_START2 = 0x0C; |
|
uint8_t ADS1263_CMD_STOP2 = 0x0E; |
|
uint8_t ADS1263_CMD_RDATA1 = 0x12; |
|
uint8_t ADS1263_CMD_RDATA2 = 0x14; |
|
uint8_t ADS1263_CMD_SYOCAL1 = 0x16; |
|
uint8_t ADS1263_CMD_SYGCAL1 = 0x17; |
|
uint8_t ADS1263_CMD_SFOCAL1 = 0x19; |
|
uint8_t ADS1263_CMD_SYOCAL2 = 0x1B; |
|
uint8_t ADS1263_CMD_SYGCAL2 = 0x1C; |
|
uint8_t ADS1263_CMD_SFOCAL2 = 0x1E; |
|
uint8_t ADS1263_CMD_RREG = 0x20; |
|
uint8_t ADS1263_CMD_RREG2 = 0x00; |
|
uint8_t ADS1263_CMD_WREG = 0x40; |
|
uint8_t ADS1263_CMD_WREG2 = 0x00; |
|
|
|
uint8_t ADS1263_REG_ID = 0x00; |
|
uint8_t ADS1263_REG_POWER = 0x01; |
|
uint8_t ADS1263_REG_INTERFACE = 0x02; |
|
uint8_t ADS1263_REG_MODE0 = 0x03; |
|
uint8_t ADS1263_REG_MODE1 = 0x04; |
|
uint8_t ADS1263_REG_MODE2 = 0x05; |
|
uint8_t ADS1263_REG_INPMUX = 0x06; |
|
uint8_t ADS1263_REG_OFCAL0 = 0x07; |
|
uint8_t ADS1263_REG_OFCAL1 = 0x08; |
|
uint8_t ADS1263_REG_OFCAL2 = 0x09; |
|
uint8_t ADS1263_REG_FSCAL0 = 0x0A; |
|
uint8_t ADS1263_REG_FSCAL1 = 0x0B; |
|
uint8_t ADS1263_REG_FSCAL2 = 0x0C; |
|
uint8_t ADS1263_REG_IDACMUX = 0x0D; |
|
uint8_t ADS1263_REG_IDACMAG = 0x0E; |
|
uint8_t ADS1263_REG_REFMUX = 0x0F; |
|
uint8_t ADS1263_REG_TDACP = 0x10; |
|
uint8_t ADS1263_REG_TDACN = 0x11; |
|
uint8_t ADS1263_REG_GPIOCON = 0x12; |
|
/* ... */ |
|
|
|
uint8_t ADS1263_DRATE_38400SPS = 0xF; |
|
uint8_t ADS1263_DRATE_19200SPS = 0xE; |
|
uint8_t ADS1263_DRATE_14400SPS = 0xD; |
|
uint8_t ADS1263_DRATE_7200SPS = 0xC; |
|
uint8_t ADS1263_DRATE_4800SPS = 0xB; |
|
uint8_t ADS1263_DRATE_2400SPS = 0xA; |
|
uint8_t ADS1263_DRATE_1200SPS = 0x9; |
|
uint8_t ADS1263_DRATE_400SPS = 0x8; |
|
uint8_t ADS1263_DRATE_100SPS = 0x7; |
|
uint8_t ADS1263_DRATE_60SPS = 0x6; |
|
uint8_t ADS1263_DRATE_50SPS = 0x5; |
|
uint8_t ADS1263_DRATE_20SPS = 0x4; |
|
uint8_t ADS1263_DRATE_16d6SPS = 0x3; |
|
uint8_t ADS1263_DRATE_10SPS = 0x2; |
|
uint8_t ADS1263_DRATE_5SPS = 0x1; |
|
uint8_t ADS1263_DRATE_2d5SPS = 0x0; |
|
|
|
uint8_t ADS1263_GAIN_1 = 0; // GAIN 1 |
|
uint8_t ADS1263_GAIN_2 = 1; // GAIN 2 |
|
uint8_t ADS1263_GAIN_4 = 2; // GAIN 4 |
|
uint8_t ADS1263_GAIN_8 = 3; // GAIN 8 |
|
uint8_t ADS1263_GAIN_16 = 4; // GAIN 16 |
|
uint8_t ADS1263_GAIN_32 = 5; // GAIN 32 |
|
uint8_t ADS1263_GAIN_64 = 6; // GAIN 64 |
|
|
|
uint8_t ADS1263_DELAY_0s = 0; |
|
uint8_t ADS1263_DELAY_8d7us = 1; |
|
uint8_t ADS1263_DELAY_17us = 2; |
|
uint8_t ADS1263_DELAY_35us = 3; |
|
uint8_t ADS1263_DELAY_169us = 4; |
|
uint8_t ADS1263_DELAY_139us = 5; |
|
uint8_t ADS1263_DELAY_278us = 6; |
|
uint8_t ADS1263_DELAY_555us = 7; |
|
uint8_t ADS1263_DELAY_1d1ms = 8; |
|
uint8_t ADS1263_DELAY_2d2ms = 9; |
|
uint8_t ADS1263_DELAY_4d4ms = 10; |
|
uint8_t ADS1263_DELAY_8d8ms = 11; |
|
|
|
class ADS1263 |
|
{ |
|
public: |
|
ADS1263(bool use_active_wait = false) |
|
{ |
|
LOG(std::cout << "ADS1263 initialized" << std::endl); |
|
ScanMode = 1; |
|
use_active_wait = use_active_wait; |
|
} |
|
|
|
void ADS1263_reset() |
|
{ |
|
LOG(std::cout << "ADS1263_reset" << std::endl); |
|
Config& config = Config::getInstance(); |
|
config.digital_write(RST_PIN, 1); |
|
delay_ms(200); |
|
config.digital_write(RST_PIN, 0); |
|
delay_ms(200); |
|
config.digital_write(RST_PIN, 1); |
|
delay_ms(200); |
|
} |
|
|
|
char *ADS1263_ReadData(uint8_t reg) |
|
{ |
|
LOG(std::cout << "ADS1263_ReadData" << std::endl); |
|
Config& config = Config::getInstance(); |
|
LOG(std::cout << " * digital_write(CS_PIN, 0)" << std::endl); |
|
config.digital_write(CS_PIN, 0); |
|
LOG(std::cout << " * spi_writebytes" << std::endl); |
|
config.spi_writebytes({static_cast<uint8_t>(ADS1263_CMD_RREG | reg), 0x00}); |
|
LOG(std::cout << " * spi_readbytes" << std::endl); |
|
char *data = config.spi_readbytes(1); |
|
LOG(std::cout << " * digital_write(CS_PIN, 1)" << std::endl); |
|
config.digital_write(CS_PIN, 1); |
|
return data; |
|
} |
|
|
|
void ADS1263_WriteCmd(uint8_t cmd) |
|
{ |
|
LOG(std::cout << "ADS1263_WriteCmd" << std::endl); |
|
Config& config = Config::getInstance(); |
|
config.digital_write(CS_PIN, 0); |
|
config.spi_writebytes({cmd}); |
|
config.digital_write(CS_PIN, 1); |
|
} |
|
|
|
void ADS1263_WriteReg(uint8_t reg, uint8_t data) |
|
{ |
|
LOG(std::cout << "ADS1263_WriteReg" << std::endl); |
|
Config& config = Config::getInstance(); |
|
config.digital_write(CS_PIN, 0); |
|
config.spi_writebytes({static_cast<uint8_t>(ADS1263_CMD_WREG | reg), 0x00, data}); |
|
config.digital_write(CS_PIN, 1); |
|
} |
|
|
|
void ADS1263_ConfigADC(uint8_t gain, uint8_t drate) |
|
{ |
|
LOG(std::cout << "ADS1263_ConfigADC" << std::endl); |
|
|
|
uint8_t mode2 = 0x80; // 0x80:PGA bypassed, 0x00:PGA enabled |
|
mode2 |= (gain << 4) | drate; |
|
ADS1263_WriteReg(ADS1263_REG_MODE2, mode2); |
|
auto mode2_read = ADS1263_ReadData(ADS1263_REG_MODE2); |
|
if (mode2_read[0] == mode2) |
|
{ |
|
LOG(std::cout << "REG_MODE2 success" << std::endl); |
|
} |
|
else |
|
{ |
|
LOG(std::cout << "REG_MODE2 failed" << std::endl); |
|
} |
|
|
|
uint8_t refmux = 0x00; // 0x00:+-2.5V as REF, 0x24:VDD,VSS as REF |
|
ADS1263_WriteReg(ADS1263_REG_REFMUX, refmux); |
|
auto refmux_read = ADS1263_ReadData(ADS1263_REG_REFMUX); |
|
if (refmux_read[0] == refmux) |
|
{ |
|
LOG(std::cout << "REG_REFMUX success" << std::endl); |
|
} |
|
else |
|
{ |
|
LOG(std::cout << "REG_REFMUX failed" << std::endl); |
|
} |
|
|
|
uint8_t mode0 = ADS1263_DELAY_35us; |
|
ADS1263_WriteReg(ADS1263_REG_MODE0, mode0); |
|
auto mode0_read = ADS1263_ReadData(ADS1263_REG_MODE0); |
|
if (mode0_read[0] == mode0) |
|
{ |
|
LOG(std::cout << "REG_MODE0 success" << std::endl); |
|
} |
|
else |
|
{ |
|
LOG(std::cout << "REG_MODE0 failed" << std::endl); |
|
} |
|
|
|
uint8_t mode1 = 0x84; // Digital Filter; 0x84:FIR, 0x64:Sinc4, 0x44:Sinc3, 0x24:Sinc2, 0x04:Sinc1 |
|
ADS1263_WriteReg(ADS1263_REG_MODE1, mode1); |
|
auto mode1_read = ADS1263_ReadData(ADS1263_REG_MODE1); |
|
if (mode1_read[0] == mode1) |
|
{ |
|
LOG(std::cout << "REG_MODE1 success" << std::endl); |
|
} |
|
else |
|
{ |
|
LOG(std::cout << "REG_MODE1 failed" << std::endl); |
|
} |
|
} |
|
|
|
void ADS1263_SetDiffChannal(uint8_t channal) |
|
{ |
|
uint8_t inpmux = 0x00; |
|
switch (channal) |
|
{ |
|
case 0: |
|
inpmux = (0 << 4) | 1; // DiffChannal AIN0-AIN1 |
|
break; |
|
case 1: |
|
inpmux = (2 << 4) | 3; // DiffChannal AIN2-AIN3 |
|
break; |
|
case 2: |
|
inpmux = (4 << 4) | 5; // DiffChannal AIN4-AIN5 |
|
break; |
|
case 3: |
|
inpmux = (6 << 4) | 7; // DiffChannal AIN6-AIN7 |
|
break; |
|
case 4: |
|
inpmux = (8 << 4) | 9; // DiffChannal AIN8-AIN9 |
|
break; |
|
} |
|
ADS1263_WriteReg(ADS1263_REG_INPMUX, inpmux); |
|
auto inpmux_read = ADS1263_ReadData(ADS1263_REG_INPMUX); |
|
if (inpmux_read[0] == inpmux) |
|
{ |
|
LOG(std::cout << "REG_INPMUX success" << std::endl); |
|
} |
|
else |
|
{ |
|
LOG(std::cout << "REG_INPMUX failed" << std::endl); |
|
} |
|
} |
|
|
|
void ADS1263_SetChannel(uint8_t channel) |
|
{ |
|
if (channel > 10) |
|
{ |
|
return; |
|
} |
|
uint8_t inpmux = (channel << 4) | 0x0a; |
|
ADS1263_WriteReg(ADS1263_REG_INPMUX, inpmux); |
|
auto inpmux_read = ADS1263_ReadData(ADS1263_REG_INPMUX); |
|
if (inpmux_read[0] == inpmux) |
|
{ |
|
LOG(std::cout << "REG_INPMUX success" << std::endl); |
|
} |
|
else |
|
{ |
|
LOG(std::cout << "REG_INPMUX failed" << std::endl); |
|
} |
|
} |
|
|
|
int ADS1263_ReadChipID() |
|
{ |
|
LOG(std::cout << "ADS1263_ReadChipID" << std::endl); |
|
char *id = ADS1263_ReadData(ADS1263_REG_ID); |
|
int chip_id = id[0] >> 5; |
|
free(id); |
|
return chip_id; |
|
} |
|
|
|
void ADS1263_SetMode(uint8_t mode) |
|
{ |
|
ScanMode = mode; |
|
} |
|
|
|
void ADS1263_SetUseActiveWait(bool use_active_wait) |
|
{ |
|
this->use_active_wait = use_active_wait; |
|
} |
|
|
|
void ADS1263_WaitDRDY() |
|
{ |
|
if (use_active_wait) |
|
{ |
|
Config& config = Config::getInstance(); |
|
for (uint64_t i = 0;; i++) |
|
{ |
|
if (config.digital_read(DRDY_PIN) == 0) |
|
{ |
|
break; |
|
} |
|
if (i == 400000) |
|
{ |
|
LOG(std::cout << "Time out ... " << std::endl); |
|
break; |
|
} |
|
} |
|
} |
|
else |
|
{ |
|
Config& config = Config::getInstance(); |
|
config.wait_for_ready(); |
|
} |
|
|
|
|
|
} |
|
|
|
uint32_t ADS1263_CheckSum(uint64_t val, uint64_t byt) |
|
{ |
|
uint8_t sum = 0; |
|
uint8_t mask = 0xff; |
|
while (val) |
|
{ |
|
sum += val & mask; |
|
val = val >> 8; |
|
} |
|
sum += 0x9b; |
|
return (sum & 0xff) ^ byt; |
|
} |
|
|
|
uint32_t ADS1263_Read_ADC_Data(bool *is_error = nullptr) |
|
{ |
|
Config& config = Config::getInstance(); |
|
config.digital_write(CS_PIN, 0); |
|
while (true) |
|
{ |
|
config.spi_writebytes({ADS1263_CMD_RDATA1}); |
|
if ((config.spi_readbytes(1)[0] & 0x40) != 0) |
|
{ |
|
break; |
|
} |
|
} |
|
uint8_t buf[5]; |
|
// auto *buf = config.spi_readbytes(5); |
|
config.spi_readbytes_n(buf, 5); |
|
config.digital_write(CS_PIN, 1); |
|
uint32_t read = (buf[0] << 24) & 0xff000000; |
|
read |= (buf[1] << 16) & 0xff0000; |
|
read |= (buf[2] << 8) & 0xff00; |
|
read |= (buf[3]) & 0xff; |
|
uint8_t CRC = buf[4]; |
|
if (ADS1263_CheckSum(read, CRC) != 0) |
|
{ |
|
LOG(std::cout << "ADC1 data read error!" << std::endl); |
|
if (is_error != nullptr) |
|
{ |
|
*is_error = true; |
|
} |
|
return read; |
|
} |
|
if (is_error != nullptr) |
|
{ |
|
*is_error = false; |
|
} |
|
return read; |
|
} |
|
|
|
uint32_t ADS1263_GetChannalValue(uint8_t channel, bool *is_error = nullptr) |
|
{ |
|
if (ScanMode == 0) |
|
{ // # 0 Single-ended input 10 channel Differential input 5 channel |
|
if (channel > 10) |
|
{ |
|
LOG(std::cout << "The number of channels must be less than 10" << std::endl); |
|
return 0; |
|
} |
|
ADS1263_SetChannel(channel); |
|
ADS1263_WaitDRDY(); |
|
return ADS1263_Read_ADC_Data(is_error); |
|
} |
|
else |
|
{ |
|
if (channel > 4) |
|
{ |
|
LOG(std::cout << "The number of channels must be less than 5" << std::endl); |
|
return 0; |
|
} |
|
ADS1263_SetDiffChannal(channel); |
|
ADS1263_WaitDRDY(); |
|
return ADS1263_Read_ADC_Data(is_error); |
|
} |
|
} |
|
|
|
void ADS1263_init_ADC1(uint8_t rate) |
|
{ |
|
LOG(std::cout << "ADS1263_init_ADC1" << std::endl); |
|
ADS1263_reset(); |
|
int id = ADS1263_ReadChipID(); |
|
LOG(std::cout << "Chip ID: " << id << std::endl); |
|
if (id == 0x01) |
|
{ |
|
LOG(std::cout << "ID Read success" << std::endl); |
|
} |
|
else |
|
{ |
|
LOG(std::cout << "ID Read failed" << std::endl); |
|
} |
|
|
|
Config& config = Config::getInstance(); |
|
|
|
ADS1263_WriteCmd(ADS1263_CMD_STOP1); |
|
ADS1263_ConfigADC(ADS1263_GAIN_1, rate); |
|
ADS1263_WriteCmd(ADS1263_CMD_START1); |
|
} |
|
|
|
private: |
|
int ScanMode; |
|
bool use_active_wait; |
|
}; |
|
|
|
int main() |
|
{ |
|
print_sbc_name(); |
|
|
|
Config& config = Config::getInstance(); |
|
config.module_init(); |
|
config.describe_pin(RST_PIN); |
|
config.describe_pin(CS_PIN); |
|
config.describe_pin(DRDY_PIN); |
|
|
|
ADS1263 ads1263; |
|
ads1263.ADS1263_SetUseActiveWait(false); |
|
ads1263.ADS1263_init_ADC1(ADS1263_DRATE_14400SPS); |
|
|
|
|
|
ads1263.ADS1263_SetDiffChannal(0); |
|
|
|
auto start = std::chrono::high_resolution_clock::now(); |
|
|
|
ads1263.ADS1263_WaitDRDY(); |
|
|
|
uint64_t ok_counter = 0; |
|
uint64_t error_counter = 0; |
|
|
|
for (uint64_t i = 0;; ++i) |
|
{ |
|
bool is_error = false; |
|
ads1263.ADS1263_WaitDRDY(); |
|
auto value = ads1263.ADS1263_Read_ADC_Data(&is_error); |
|
// auto value = ads1263.ADS1263_GetChannalValue(0, &is_error); |
|
if (is_error) |
|
{ |
|
// std::cout << "Error" << std::endl; |
|
// continue; |
|
error_counter++; |
|
} |
|
else |
|
{ |
|
ok_counter++; |
|
} |
|
// std::cout << "Value " << i << ": " << value << std::endl; |
|
double ref = 2.5; |
|
|
|
if (value >> 23 == 1) |
|
{ |
|
double v = (ref * 2.0 - double(value) * ref / 0x80000000); |
|
// std::cout << "Value: " << v << std::endl; |
|
} |
|
else |
|
{ |
|
double v = double(value) * ref / 0x7fffffff; |
|
// std::cout << "Value: " << v; |
|
// if (is_error) { |
|
// std::cout << " (Error)"; |
|
// } |
|
// std::cout << std::endl; |
|
} |
|
|
|
if (i % 1000 == 0) |
|
{ |
|
auto end = std::chrono::high_resolution_clock::now(); |
|
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start); |
|
double sps = 1000.0 / (duration.count() / 1000.0); |
|
std::cout << "Time: " << std::fixed << std::setfill(' ') << std::setw(7) << std::setprecision(2) << double(duration.count()) / 1000.0 << " seconds." << std::endl; |
|
std::cout << "SPS: " << std::fixed << std::setfill(' ') << std::setw(7) << std::setprecision(0) << sps << std::endl; |
|
std::cout << "OK: " << std::fixed << std::setfill(' ') << std::setw(7) << std::setprecision(0) << ok_counter << std::endl; |
|
std::cout << "Error: " << std::fixed << std::setfill(' ') << std::setw(7) << std::setprecision(0) << error_counter << std::endl; |
|
|
|
ok_counter = 0; |
|
error_counter = 0; |
|
|
|
start = end; |
|
} |
|
} |
|
|
|
return 0; |
|
} |