Fix ctb slow adc fw (#713)

Firmware updated. spi moved to firmware. In Software, configuring, then a pulse to start, wait for done bit and convert the values read from a regiter.
This commit is contained in:
Dhanya Thattil
2023-04-12 11:25:41 +02:00
committed by GitHub
parent b442b17415
commit cab2b335dc
10 changed files with 210 additions and 327 deletions

View File

@ -10,7 +10,6 @@ add_executable(ctbDetectorServer_virtual
../slsDetectorServer/src/commonServerFunctions.c
../slsDetectorServer/src/communication_funcs_UDP.c
../slsDetectorServer/src/UDPPacketHeaderGenerator.c
../slsDetectorServer/src/AD7689.c
../slsDetectorServer/src/AD9257.c
../slsDetectorServer/src/ALTERA_PLL.c
../slsDetectorServer/src/I2C.c

View File

@ -16,7 +16,7 @@ DESTDIR ?= bin
INSTMODE = 0777
SRCS = slsDetectorFunctionList.c
SRCS += $(main_src)slsDetectorServer.c $(main_src)slsDetectorServer_funcs.c $(main_src)communication_funcs.c $(main_src)blackfin.c $(main_src)common.c $(main_src)commonServerFunctions.c $(main_src)communication_funcs_UDP.c $(main_src)UDPPacketHeaderGenerator.c $(main_src)AD7689.c $(main_src)AD9257.c $(main_src)ALTERA_PLL.c $(main_src)I2C.c $(main_src)INA226.c $(main_src)LTC2620.c $(main_src)MAX1932.c $(main_src)programViaBlackfin.c $(main_src)/sharedMemory.c $(main_src)/loadPattern.c $(md5_dir)md5.c
SRCS += $(main_src)slsDetectorServer.c $(main_src)slsDetectorServer_funcs.c $(main_src)communication_funcs.c $(main_src)blackfin.c $(main_src)common.c $(main_src)commonServerFunctions.c $(main_src)communication_funcs_UDP.c $(main_src)UDPPacketHeaderGenerator.c $(main_src)AD9257.c $(main_src)ALTERA_PLL.c $(main_src)I2C.c $(main_src)INA226.c $(main_src)LTC2620.c $(main_src)MAX1932.c $(main_src)programViaBlackfin.c $(main_src)/sharedMemory.c $(main_src)/loadPattern.c $(md5_dir)md5.c
OBJS = $(SRCS:.c=.o)

View File

@ -184,12 +184,6 @@
#define POWER_STATUS_ALRT_OFST (27)
#define POWER_STATUS_ALRT_MSK (0x0000001F << POWER_STATUS_ALRT_OFST)
/* DAC Value Out RO register */
//#define DAC_VAL_OUT_REG (0x2A << MEM_MAP_SHIFT)
/* Slow ADC SPI Value RO register */
#define ADC_SPI_SLOW_VAL_REG (0x2B << MEM_MAP_SHIFT)
/* FIFO Digital In Status RO register */
#define FIFO_DIN_STATUS_REG (0x3B << MEM_MAP_SHIFT)
#define FIFO_DIN_STATUS_FIFO_FULL_OFST (30)
@ -228,12 +222,6 @@
#define ADC_SPI_SRL_DT_OTPT_MSK (0x00000001 << ADC_SPI_SRL_DT_OTPT_OFST)
#define ADC_SPI_SRL_CS_OTPT_OFST (2)
#define ADC_SPI_SRL_CS_OTPT_MSK (0x0000000F << ADC_SPI_SRL_CS_OTPT_OFST)
#define ADC_SPI_SLOW_SRL_DT_OFST (8)
#define ADC_SPI_SLOW_SRL_DT_MSK (0x00000001 << ADC_SPI_SLOW_SRL_DT_OFST)
#define ADC_SPI_SLOW_SRL_CLK_OFST (9)
#define ADC_SPI_SLOW_SRL_CLK_MSK (0x00000001 << ADC_SPI_SLOW_SRL_CLK_OFST)
#define ADC_SPI_SLOW_SRL_CNV_OFST (10)
#define ADC_SPI_SLOW_SRL_CNV_MSK (0x00000001 << ADC_SPI_SLOW_SRL_CNV_OFST)
/* ADC Offset RW register */
#define ADC_OFFSET_REG (0x42 << MEM_MAP_SHIFT)
@ -634,6 +622,98 @@
#define PATTERN_WAIT_TIMER_5_LSB_REG (0x91 << MEM_MAP_SHIFT)
#define PATTERN_WAIT_TIMER_5_MSB_REG (0x92 << MEM_MAP_SHIFT)
/* Slow ADC SPI Value RO register */
#define ADC_SLOW_DATA_REG (0x93 << MEM_MAP_SHIFT)
/* Slow ADC SPI Value Config register */
#define ADC_SLOW_CFG_REG (0x94 << MEM_MAP_SHIFT)
/** Read back CFG Register */
#define ADC_SLOW_CFG_RB_OFST (2)
#define ADC_SLOW_CFG_RB_MSK (0x00000001 << ADC_SLOW_CFG_RB_OFST)
/** Channel sequencer */
#define ADC_SLOW_CFG_SEQ_OFST (3)
#define ADC_SLOW_CFG_SEQ_MSK (0x00000003 << ADC_SLOW_CFG_SEQ_OFST)
#define ADC_SLOW_CFG_SEQ_DSBLE_VAL \
((0x0 << ADC_SLOW_CFG_SEQ_OFST) & ADC_SLOW_CFG_SEQ_MSK)
#define ADC_SLOW_CFG_SEQ_UPDTE_DRNG_SQNCE_VAL \
((0x1 << ADC_SLOW_CFG_SEQ_OFST) & ADC_SLOW_CFG_SEQ_MSK)
#define ADC_SLOW_CFG_SEQ_SCN_WTH_TMP_VAL \
((0x2 << ADC_SLOW_CFG_SEQ_OFST) & ADC_SLOW_CFG_SEQ_MSK)
#define ADC_SLOW_CFG_SEQ_SCN_WTHT_TMP_VAL \
((0x3 << ADC_SLOW_CFG_SEQ_OFST) & ADC_SLOW_CFG_SEQ_MSK)
/** Reference/ buffer selection */
#define ADC_SLOW_CFG_REF_OFST (5)
#define ADC_SLOW_CFG_REF_MSK (0x00000007 << ADC_SLOW_CFG_REF_OFST)
/** Internal reference. REF = 2.5V buffered output. Temperature sensor enabled.
*/
#define ADC_SLOW_CFG_REF_INT_2500MV_VAL \
((0x0 << ADC_SLOW_CFG_REF_OFST) & ADC_SLOW_CFG_REF_OFST)
/** Internal reference. REF = 4.096V buffered output. Temperature sensor
* enabled. */
#define ADC_SLOW_CFG_REF_INT_4096MV_VAL \
((0x1 << ADC_SLOW_CFG_REF_OFST) & ADC_SLOW_CFG_REF_MSK)
/** External reference. Temperature sensor enabled. Internal buffer disabled. */
#define ADC_SLOW_CFG_REF_EXT_TMP_VAL \
((0x2 << ADC_SLOW_CFG_REF_OFST) & ADC_SLOW_CFG_REF_MSK)
/** External reference. Temperature sensor enabled. Internal buffer enabled. */
#define ADC_SLOW_CFG_REF_EXT_TMP_INTBUF_VAL \
((0x3 << ADC_SLOW_CFG_REF_OFST) & ADC_SLOW_CFG_REF_MSK)
/** External reference. Temperature sensor disabled. Internal buffer disabled.
*/
#define ADC_SLOW_CFG_REF_EXT_VAL \
((0x6 << ADC_SLOW_CFG_REF_OFST) & ADC_SLOW_CFG_REF_MSK)
/** External reference. Temperature sensor disabled. Internal buffer enabled. */
#define ADC_SLOW_CFG_REF_EXT_INTBUF_VAL \
((0x7 << ADC_SLOW_CFG_REF_OFST) & ADC_SLOW_CFG_REF_MSK)
/** bandwidth of low pass filter */
#define ADC_SLOW_CFG_BW_OFST (8)
#define ADC_SLOW_CFG_BW_MSK (0x00000001 << ADC_SLOW_CFG_REF_OFST)
#define ADC_SLOW_CFG_BW_ONE_FOURTH_VAL \
((0x0 << ADC_SLOW_CFG_BW_OFST) & ADC_SLOW_CFG_BW_MSK)
#define ADC_SLOW_CFG_BW_FULL_VAL ((0x1 << ADC_SLOW_CFG_BW_OFST) & ADC_SLOW_CFG_BW_MSK)
/** input channel selection IN0 - IN7 */
#define ADC_SLOW_CFG_IN_OFST (9)
#define ADC_SLOW_CFG_IN_MSK (0x00000007 << ADC_SLOW_CFG_IN_OFST)
/** input channel configuration */
#define ADC_SLOW_CFG_INCC_OFST (12)
#define ADC_SLOW_CFG_INCC_MSK (0x00000007 << ADC_SLOW_CFG_INCC_OFST)
#define ADC_SLOW_CFG_INCC_BPLR_DFFRNTL_PRS_VAL \
((0x0 << ADC_SLOW_CFG_INCC_OFST) & ADC_SLOW_CFG_INCC_MSK)
#define ADC_SLOW_CFG_INCC_BPLR_IN_COM_VAL \
((0x2 << ADC_SLOW_CFG_INCC_OFST) & ADC_SLOW_CFG_INCC_MSK)
#define ADC_SLOW_CFG_INCC_TMP_VAL \
((0x3 << ADC_SLOW_CFG_INCC_OFST) & ADC_SLOW_CFG_INCC_MSK)
#define ADC_SLOW_CFG_INCC_UNPLR_DFFRNTL_PRS_VAL \
((0x4 << ADC_SLOW_CFG_INCC_OFST) & ADC_SLOW_CFG_INCC_MSK)
#define ADC_SLOW_CFG_INCC_UNPLR_IN_COM_VAL \
((0x6 << ADC_SLOW_CFG_INCC_OFST) & ADC_SLOW_CFG_INCC_MSK)
#define ADC_SLOW_CFG_INCC_UNPLR_IN_GND_VAL \
((0x7 << ADC_SLOW_CFG_INCC_OFST) & ADC_SLOW_CFG_INCC_MSK)
/** configuration update */
#define ADC_SLOW_CFG_CFG_OFST (15)
#define ADC_SLOW_CFG_CFG_MSK (0x00000001 << ADC_SLOW_CFG_CFG_OFST)
#define ADC_SLOW_CFG_CFG_NO_UPDATE_VAL \
((0x0 << ADC_SLOW_CFG_CFG_OFST) & ADC_SLOW_CFG_CFG_MSK)
#define ADC_SLOW_CFG_CFG_OVRWRTE_VAL \
((0x1 << ADC_SLOW_CFG_CFG_OFST) & ADC_SLOW_CFG_CFG_MSK)
/* Slow ADC SPI Value Control register */
#define ADC_SLOW_CTRL_REG (0x95 << MEM_MAP_SHIFT)
#define ADC_SLOW_CTRL_STRT_OFST (0)
#define ADC_SLOW_CTRL_STRT_MSK (0x00000001 << ADC_SLOW_CTRL_STRT_OFST)
#define ADC_SLOW_CTRL_DONE_OFST (1)
#define ADC_SLOW_CTRL_DONE_MSK (0x00000001 << ADC_SLOW_CTRL_DONE_OFST)
/** I2C Control register */
#define I2C_TRANSFER_COMMAND_FIFO_REG (0x100 << MEM_MAP_SHIFT)
#define I2C_RX_DATA_FIFO_REG (0x101 << MEM_MAP_SHIFT)

View File

@ -5,7 +5,6 @@
#include "sharedMemory.h"
#include "sls/versionAPI.h"
#include "AD7689.h" // slow adcs
#include "ALTERA_PLL.h" // pll
#include "INA226.h" // i2c
#include "LTC2620.h" // dacs
@ -534,13 +533,6 @@ void setupDetector() {
AD9257_Disable();
AD9257_Configure();
// slow adcs
AD7689_SetDefines(ADC_SPI_REG, ADC_SPI_SLOW_VAL_REG,
ADC_SPI_SLOW_SRL_CNV_MSK, ADC_SPI_SLOW_SRL_CLK_MSK,
ADC_SPI_SLOW_SRL_DT_MSK, ADC_SPI_SLOW_SRL_DT_OFST);
AD7689_Disable();
AD7689_Configure();
// dacs
LTC2620_SetDefines(SPI_REG, SPI_DAC_SRL_CS_OTPT_MSK,
SPI_DAC_SRL_CLK_OTPT_MSK, SPI_DAC_SRL_DGTL_OTPT_MSK,
@ -1473,7 +1465,7 @@ int getADC(enum ADCINDEX ind) {
// slow adcs
case S_TMP:
LOG(logDEBUG1, ("Reading Slow ADC Temperature\n"));
return AD7689_GetTemperature();
return getSlowADCTemperature();
case S_ADC0:
case S_ADC1:
case S_ADC2:
@ -1483,13 +1475,120 @@ int getADC(enum ADCINDEX ind) {
case S_ADC6:
case S_ADC7:
LOG(logDEBUG1, ("Reading Slow ADC Channel %d\n", (int)ind - S_ADC0));
return AD7689_GetChannel((int)ind - S_ADC0);
return getSlowADC((int)ind - S_ADC0);
default:
LOG(logERROR, ("Adc Index %d not defined \n", (int)ind));
return -1;
}
}
int getSlowADC(int ichan) {
LOG(logDEBUG1, ("Getting slow adc channel %d\n", ichan));
// configure for channel
bus_w(ADC_SLOW_CFG_REG,
// don't read back config reg
ADC_SLOW_CFG_RB_MSK |
// disable sequencer (different from config)
ADC_SLOW_CFG_SEQ_DSBLE_VAL |
// Internal reference. REF = 2.5V buffered output. Temperature sensor
// enabled.
ADC_SLOW_CFG_REF_INT_2500MV_VAL |
// full bandwidth of low pass filter
ADC_SLOW_CFG_BW_FULL_VAL |
// specific channel (different from config)
((ichan << ADC_SLOW_CFG_IN_OFST) & ADC_SLOW_CFG_IN_MSK) |
// input channel configuration (unipolar. inx to gnd)
ADC_SLOW_CFG_INCC_UNPLR_IN_GND_VAL |
// overwrite configuration
ADC_SLOW_CFG_CFG_OVRWRTE_VAL);
// start converting
bus_w(ADC_SLOW_CTRL_REG, bus_r(ADC_SLOW_CTRL_REG) | ADC_SLOW_CTRL_STRT_MSK);
bus_w(ADC_SLOW_CTRL_REG, bus_r(ADC_SLOW_CTRL_REG) & ~ADC_SLOW_CTRL_STRT_MSK);
// wait for it to be done
volatile int done = ((bus_r(ADC_SLOW_CTRL_REG) & ADC_SLOW_CTRL_DONE_MSK) >> ADC_SLOW_CTRL_DONE_OFST);
while (!done) {
done = ((bus_r(ADC_SLOW_CTRL_REG) & ADC_SLOW_CTRL_DONE_MSK) >> ADC_SLOW_CTRL_DONE_OFST);
}
// readout
int regval = bus_r(ADC_SLOW_DATA_REG);
// value in uV
int refMaxuv = 2500 * 1000;
int regMinuv = 0;
int maxSteps = 0xFFFF + 1;
int retval = 0;
if (ConvertToDifferentRange(0, maxSteps, regMinuv, refMaxuv, regval, &retval) == FAIL) {
LOG(logERROR, ("Could not convert slow adc channel (regval:0x%x) to uv\n", regval));
return -1;
}
LOG(logINFO,
("\tRead slow adc [%d]: %d uV (reg: 0x%x)\n", ichan, retval, regval));
return retval;
}
int getSlowADCTemperature() {
LOG(logDEBUG1, ("Getting slow adc temperature\n"));
// configure for channel
bus_w(ADC_SLOW_CFG_REG,
// don't read back config reg
ADC_SLOW_CFG_RB_MSK |
// disable sequencer (different from config)
ADC_SLOW_CFG_SEQ_DSBLE_VAL |
// Internal reference. REF = 2.5V buffered output. Temperature sensor
// enabled.
ADC_SLOW_CFG_REF_INT_2500MV_VAL |
// full bandwidth of low pass filter
ADC_SLOW_CFG_BW_FULL_VAL |
// all channels
ADC_SLOW_CFG_IN_MSK |
// temp sensor
ADC_SLOW_CFG_INCC_TMP_VAL |
// overwrite configuration
ADC_SLOW_CFG_CFG_OVRWRTE_VAL);
// start converting
bus_w(ADC_SLOW_CTRL_REG, bus_r(ADC_SLOW_CTRL_REG) | ADC_SLOW_CTRL_STRT_MSK);
bus_w(ADC_SLOW_CTRL_REG, bus_r(ADC_SLOW_CTRL_REG) & ~ADC_SLOW_CTRL_STRT_MSK);
// wait for it to be done
volatile int done = ((bus_r(ADC_SLOW_CTRL_REG) & ADC_SLOW_CTRL_DONE_MSK) >> ADC_SLOW_CTRL_DONE_OFST);
while (!done) {
done = ((bus_r(ADC_SLOW_CTRL_REG) & ADC_SLOW_CTRL_DONE_MSK) >> ADC_SLOW_CTRL_DONE_OFST);
}
// readout
int regval = bus_r(ADC_SLOW_DATA_REG);
// value in mV FIXME: page 17? reference voltage temperature coefficient or
// t do with -40 to 85 °C
int retval = 0;
int maxSteps = 0xFFFF + 1;
int minmv = 0;
int maxmv = 2500;
if (ConvertToDifferentRange(0, maxSteps, minmv,
maxmv, regval, &retval) == FAIL) {
LOG(logERROR, ("Could not convert slow adc temp (regval:0x%x) to uv\n", regval));
return -1;
}
LOG(logDEBUG1, ("voltage read for temp: %d mV\n", retval));
// value in °C
double tempCFor1mv = (25.00 / 283.00);
double tempValue = tempCFor1mv * (double)retval;
LOG(logINFO, ("\tTemp slow adc : %f °C (reg: %d)\n", tempValue, regval));
return tempValue;
}
int setHighVoltage(int val) {
// setting hv
if (val >= 0) {

View File

@ -5,7 +5,7 @@
#include "sls/sls_detector_defs.h"
#define MIN_REQRD_VRSN_T_RD_API 0x181130
#define REQRD_FRMWR_VRSN 0x221205
#define REQRD_FRMWR_VRSN 0x230403
#define NUM_HARDWARE_VERSIONS (1)
#define HARDWARE_VERSION_NUMBERS \

View File

@ -1,52 +0,0 @@
// SPDX-License-Identifier: LGPL-3.0-or-other
// Copyright (C) 2021 Contributors to the SLS Detector Package
#pragma once
#include <inttypes.h>
/**
* Set Defines
* @param reg spi register
* @param roreg spi readout register
* @param cmsk conversion mask
* @param clkmsk clock output mask
* @param dmsk digital output mask
* @param dofst digital output offset
*/
void AD7689_SetDefines(uint32_t reg, uint32_t roreg, uint32_t cmsk,
uint32_t clkmsk, uint32_t dmsk, int dofst);
/**
* Disable SPI
*/
void AD7689_Disable();
/**
* Set SPI reg value
* @param codata value to be set
*/
void AD7689_Set(uint32_t codata);
/**
* Get SPI reg value
* @returns SPI reg value
*/
uint16_t AD7689_Get();
/**
* Get temperature
* @returns temperature in °C
*/
int AD7689_GetTemperature();
/**
* Reads channels voltage
* @param ichan channel number from 0 to 7
* @returns channel voltage in mV
*/
int AD7689_GetChannel(int ichan);
/**
* Configure
*/
void AD7689_Configure();

View File

@ -389,6 +389,10 @@ int getADC(enum ADCINDEX ind, int *value);
#else
int getADC(enum ADCINDEX ind);
#endif
#ifdef CHIPTESTBOARDD
int getSlowADC(int ichan);
int getSlowADCTemperature();
#endif
int setHighVoltage(int val);

View File

@ -1,242 +0,0 @@
// SPDX-License-Identifier: LGPL-3.0-or-other
// Copyright (C) 2021 Contributors to the SLS Detector Package
#include "AD7689.h"
#include "blackfin.h"
#include "clogger.h"
#include "common.h"
#include "commonServerFunctions.h" // blackfin.h, ansi.h
/* AD7689 ADC DEFINES */
/** Read back CFG Register */
#define AD7689_CFG_RB_OFST (0)
#define AD7689_CFG_RB_MSK (0x00000001 << AD7689_CFG_RB_OFST)
/** Channel sequencer */
#define AD7689_CFG_SEQ_OFST (1)
#define AD7689_CFG_SEQ_MSK (0x00000003 << AD7689_CFG_SEQ_OFST)
#define AD7689_CFG_SEQ_DSBLE_VAL \
((0x0 << AD7689_CFG_SEQ_OFST) & AD7689_CFG_SEQ_MSK)
#define AD7689_CFG_SEQ_UPDTE_DRNG_SQNCE_VAL \
((0x1 << AD7689_CFG_SEQ_OFST) & AD7689_CFG_SEQ_MSK)
#define AD7689_CFG_SEQ_SCN_WTH_TMP_VAL \
((0x2 << AD7689_CFG_SEQ_OFST) & AD7689_CFG_SEQ_MSK)
#define AD7689_CFG_SEQ_SCN_WTHT_TMP_VAL \
((0x3 << AD7689_CFG_SEQ_OFST) & AD7689_CFG_SEQ_MSK)
/** Reference/ buffer selection */
#define AD7689_CFG_REF_OFST (3)
#define AD7689_CFG_REF_MSK (0x00000007 << AD7689_CFG_REF_OFST)
/** Internal reference. REF = 2.5V buffered output. Temperature sensor enabled.
*/
#define AD7689_CFG_REF_INT_2500MV_VAL \
((0x0 << AD7689_CFG_REF_OFST) & AD7689_CFG_REF_OFST)
/** Internal reference. REF = 4.096V buffered output. Temperature sensor
* enabled. */
#define AD7689_CFG_REF_INT_4096MV_VAL \
((0x1 << AD7689_CFG_REF_OFST) & AD7689_CFG_REF_MSK)
/** External reference. Temperature sensor enabled. Internal buffer disabled. */
#define AD7689_CFG_REF_EXT_TMP_VAL \
((0x2 << AD7689_CFG_REF_OFST) & AD7689_CFG_REF_MSK)
/** External reference. Temperature sensor enabled. Internal buffer enabled. */
#define AD7689_CFG_REF_EXT_TMP_INTBUF_VAL \
((0x3 << AD7689_CFG_REF_OFST) & AD7689_CFG_REF_MSK)
/** External reference. Temperature sensor disabled. Internal buffer disabled.
*/
#define AD7689_CFG_REF_EXT_VAL \
((0x6 << AD7689_CFG_REF_OFST) & AD7689_CFG_REF_MSK)
/** External reference. Temperature sensor disabled. Internal buffer enabled. */
#define AD7689_CFG_REF_EXT_INTBUF_VAL \
((0x7 << AD7689_CFG_REF_OFST) & AD7689_CFG_REF_MSK)
/** bandwidth of low pass filter */
#define AD7689_CFG_BW_OFST (6)
#define AD7689_CFG_BW_MSK (0x00000001 << AD7689_CFG_REF_OFST)
#define AD7689_CFG_BW_ONE_FOURTH_VAL \
((0x0 << AD7689_CFG_BW_OFST) & AD7689_CFG_BW_MSK)
#define AD7689_CFG_BW_FULL_VAL ((0x1 << AD7689_CFG_BW_OFST) & AD7689_CFG_BW_MSK)
/** input channel selection IN0 - IN7 */
#define AD7689_CFG_IN_OFST (7)
#define AD7689_CFG_IN_MSK (0x00000007 << AD7689_CFG_IN_OFST)
/** input channel configuration */
#define AD7689_CFG_INCC_OFST (10)
#define AD7689_CFG_INCC_MSK (0x00000007 << AD7689_CFG_INCC_OFST)
#define AD7689_CFG_INCC_BPLR_DFFRNTL_PRS_VAL \
((0x0 << AD7689_CFG_INCC_OFST) & AD7689_CFG_INCC_MSK)
#define AD7689_CFG_INCC_BPLR_IN_COM_VAL \
((0x2 << AD7689_CFG_INCC_OFST) & AD7689_CFG_INCC_MSK)
#define AD7689_CFG_INCC_TMP_VAL \
((0x3 << AD7689_CFG_INCC_OFST) & AD7689_CFG_INCC_MSK)
#define AD7689_CFG_INCC_UNPLR_DFFRNTL_PRS_VAL \
((0x4 << AD7689_CFG_INCC_OFST) & AD7689_CFG_INCC_MSK)
#define AD7689_CFG_INCC_UNPLR_IN_COM_VAL \
((0x6 << AD7689_CFG_INCC_OFST) & AD7689_CFG_INCC_MSK)
#define AD7689_CFG_INCC_UNPLR_IN_GND_VAL \
((0x7 << AD7689_CFG_INCC_OFST) & AD7689_CFG_INCC_MSK)
/** configuration update */
#define AD7689_CFG_CFG_OFST (13)
#define AD7689_CFG_CFG_MSK (0x00000001 << AD7689_CFG_CFG_OFST)
#define AD7689_CFG_CFG_NO_UPDATE_VAL \
((0x0 << AD7689_CFG_CFG_OFST) & AD7689_CFG_CFG_MSK)
#define AD7689_CFG_CFG_OVRWRTE_VAL \
((0x1 << AD7689_CFG_CFG_OFST) & AD7689_CFG_CFG_MSK)
#define AD7689_ADC_CFG_NUMBITS (14)
#define AD7689_ADC_DATA_NUMBITS (16)
#define AD7689_NUM_CHANNELS (8)
#define AD7689_NUM_INVALID_CONVERSIONS (3)
#define AD7689_INT_REF_MAX_MV \
(2500) // chosen using reference buffer selection in config reg
#define AD7689_INT_REF_MIN_MV (0)
#define AD7689_INT_REF_MAX_UV (2500 * 1000)
#define AD7689_INT_REF_MIN_UV (0)
#define AD7689_INT_MAX_STEPS (0xFFFF + 1)
#define AD7689_TMP_C_FOR_1_MV (25.00 / 283.00)
// Definitions from the fpga
uint32_t AD7689_Reg = 0x0;
uint32_t AD7689_ROReg = 0x0;
uint32_t AD7689_CnvMask = 0x0;
uint32_t AD7689_ClkMask = 0x0;
uint32_t AD7689_DigMask = 0x0;
int AD7689_DigOffset = 0x0;
void AD7689_SetDefines(uint32_t reg, uint32_t roreg, uint32_t cmsk,
uint32_t clkmsk, uint32_t dmsk, int dofst) {
LOG(logDEBUG, ("AD7689: reg:0x%x roreg:0x%x cmsk:0x%x clkmsk:0x%x "
"dmsk:0x%x dofst:%d\n",
reg, roreg, cmsk, clkmsk, dmsk, dofst));
AD7689_Reg = reg;
AD7689_ROReg = roreg;
AD7689_CnvMask = cmsk;
AD7689_ClkMask = clkmsk;
AD7689_DigMask = dmsk;
AD7689_DigOffset = dofst;
}
void AD7689_Disable() {
bus_w(AD7689_Reg, (bus_r(AD7689_Reg) & ~(AD7689_CnvMask) & ~AD7689_ClkMask &
~(AD7689_DigMask)));
}
void AD7689_Set(uint32_t codata) {
LOG(logINFO,
("\tSetting ADC SPI Register. Writing 0x%08x to Config Reg\n", codata));
serializeToSPI(AD7689_Reg, codata, AD7689_CnvMask, AD7689_ADC_CFG_NUMBITS,
AD7689_ClkMask, AD7689_DigMask, AD7689_DigOffset, 1);
}
uint16_t AD7689_Get() {
LOG(logINFO, ("\tGetting ADC SPI Register.\n"));
return (uint16_t)serializeFromSPI(AD7689_Reg, AD7689_CnvMask,
AD7689_ADC_DATA_NUMBITS, AD7689_ClkMask,
AD7689_DigMask, AD7689_ROReg, 1);
}
int AD7689_GetTemperature() {
AD7689_Set(
// read back
AD7689_CFG_RB_MSK |
// disable sequencer (different from config)
AD7689_CFG_SEQ_DSBLE_VAL |
// Internal reference. REF = 2.5V buffered output. Temperature sensor
// enabled.
AD7689_CFG_REF_INT_2500MV_VAL |
// full bandwidth of low pass filter
AD7689_CFG_BW_FULL_VAL |
// all channel (different from config)
AD7689_CFG_IN_MSK |
// temperature sensor (different from config)
AD7689_CFG_INCC_TMP_VAL |
// overwrite configuration
AD7689_CFG_CFG_OVRWRTE_VAL);
int regval = AD7689_Get();
// value in mV FIXME: page 17? reference voltage temperature coefficient or
// t do with -40 to 85 °C
int retval = 0;
ConvertToDifferentRange(0, AD7689_INT_MAX_STEPS, AD7689_INT_REF_MIN_MV,
AD7689_INT_REF_MAX_MV, regval, &retval);
LOG(logDEBUG1, ("voltage read for temp: %d mV\n", retval));
// value in °C
double tempValue = AD7689_TMP_C_FOR_1_MV * (double)retval;
LOG(logINFO, ("\ttemp read : %f °C (%d unit)\n", tempValue, regval));
return tempValue;
}
int AD7689_GetChannel(int ichan) {
// filter channels val
if (ichan < 0 || ichan >= AD7689_NUM_CHANNELS) {
LOG(logERROR, ("Cannot get slow adc channel. "
"%d out of bounds (0 to %d)\n",
ichan, AD7689_NUM_CHANNELS - 1));
return -1;
}
AD7689_Set(
// read back
AD7689_CFG_RB_MSK |
// disable sequencer (different from config)
AD7689_CFG_SEQ_DSBLE_VAL |
// Internal reference. REF = 2.5V buffered output. Temperature sensor
// enabled.
AD7689_CFG_REF_INT_2500MV_VAL |
// full bandwidth of low pass filter
AD7689_CFG_BW_FULL_VAL |
// specific channel (different from config)
((ichan << AD7689_CFG_IN_OFST) & AD7689_CFG_IN_MSK) |
// input channel configuration (unipolar. inx to gnd)
AD7689_CFG_INCC_UNPLR_IN_GND_VAL |
// overwrite configuration
AD7689_CFG_CFG_OVRWRTE_VAL);
int regval = AD7689_Get();
// value in uV
int retval = ((double)(regval - 0) *
(double)(AD7689_INT_REF_MAX_UV - AD7689_INT_REF_MIN_UV)) /
(double)(AD7689_INT_MAX_STEPS - 0) +
AD7689_INT_REF_MIN_UV;
/*ConvertToDifferentRange(0, AD7689_INT_MAX_STEPS,
AD7689_INT_REF_MIN_MV, AD7689_INT_REF_MAX_MV,
regval, &retval);*/
LOG(logINFO, ("\tvoltage read for chan %d: %d uV (regVal: %d)\n", ichan,
retval, regval));
return retval;
}
void AD7689_Configure() {
LOG(logINFOBLUE, ("Configuring AD7689 (Slow ADCs): \n"));
// from power up, 3 invalid conversions
LOG(logINFO,
("\tConfiguring %d x due to invalid conversions from power up\n",
AD7689_NUM_INVALID_CONVERSIONS));
for (int i = 0; i < AD7689_NUM_INVALID_CONVERSIONS; ++i) {
AD7689_Set(
// read back
AD7689_CFG_RB_MSK |
// scan sequence IN0-IN7 then temperature sensor
AD7689_CFG_SEQ_SCN_WTH_TMP_VAL |
// Internal reference. REF = 2.5V buffered output. Temperature
// sensor enabled.
AD7689_CFG_REF_INT_2500MV_VAL |
// full bandwidth of low pass filter
AD7689_CFG_BW_FULL_VAL |
// scan upto channel 7
AD7689_CFG_IN_MSK |
// input channel configuration (unipolar. inx to gnd)
AD7689_CFG_INCC_UNPLR_IN_GND_VAL |
// overwrite configuration
AD7689_CFG_CFG_OVRWRTE_VAL);
}
}