ctb: power regulators (set dac, get dac, get adc of voltage and current) works

This commit is contained in:
2019-02-20 08:45:34 +01:00
parent c93f88b7e5
commit 69f361468e
10 changed files with 286 additions and 104 deletions

View File

@ -1,6 +1,6 @@
CROSS = bfin-uclinux-
CC = $(CROSS)gcc
CFLAGS += -Wall -DCHIPTESTBOARDD -DSTOP_SERVER -DDEBUG1 #-DJCTB -DVERBOSEI #-DVERBOSE
CFLAGS += -Wall -DCHIPTESTBOARDD -DSTOP_SERVER #-DDEBUG1 #-DJCTB -DVERBOSEI #-DVERBOSE
LDLIBS += -lm -lstdc++
PROGS = ctbDetectorServer

View File

@ -523,7 +523,9 @@
/** I2C Control register */
#define I2C_TRANSFER_COMMAND_FIFO_REG (0x100 << MEM_MAP_SHIFT)
#define I2C_RX_DATA_FIFO_REG (0x101 << MEM_MAP_SHIFT)
#define I2C_CONTROL_REG (0x102 << MEM_MAP_SHIFT)
#define I2C_STATUS_REG (0x105 << MEM_MAP_SHIFT)
#define I2C_RX_DATA_FIFO_LEVEL_REG (0x107 << MEM_MAP_SHIFT)
#define I2C_SCL_LOW_COUNT_REG (0x108 << MEM_MAP_SHIFT)
#define I2C_SCL_HIGH_COUNT_REG (0x109 << MEM_MAP_SHIFT)

View File

@ -1,9 +1,9 @@
Path: slsDetectorPackage/slsDetectorServers/ctbDetectorServer
URL: origin git@github.com:slsdetectorgroup/slsDetectorPackage.git
Repository Root: origin git@github.com:slsdetectorgroup/slsDetectorPackage.git
Repsitory UUID: 501c579f6b5d63ceee66cd10285890bf65e44e8e
Revision: 17
Repsitory UUID: c93f88b7e5afe231ec43c47d60278c6acdb520af
Revision: 19
Branch: refactor
Last Changed Author: Dhanya_Thattil
Last Changed Rev: 4331
Last Changed Date: 2019-02-14 09:37:20.000000002 +0100 ./RegisterDefs.h
Last Changed Rev: 4333
Last Changed Date: 2019-02-20 08:12:50.000000002 +0100 ./RegisterDefs.h

View File

@ -1,6 +1,6 @@
#define GITURL "git@github.com:slsdetectorgroup/slsDetectorPackage.git"
#define GITREPUUID "501c579f6b5d63ceee66cd10285890bf65e44e8e"
#define GITREPUUID "c93f88b7e5afe231ec43c47d60278c6acdb520af"
#define GITAUTH "Dhanya_Thattil"
#define GITREV 0x4331
#define GITDATE 0x20190214
#define GITREV 0x4333
#define GITDATE 0x20190220
#define GITBRANCH "refactor"

View File

@ -515,7 +515,7 @@ void setupDetector() {
// power regulators
// I2C
INA226_ConfigureI2CCore(I2C_SHUNT_RESISTER_OHMS, I2C_CONTROL_REG, I2C_RX_DATA_FIFO_LEVEL_REG, I2C_SCL_LOW_COUNT_REG, I2C_SCL_HIGH_COUNT_REG, I2C_SDA_HOLD_REG, I2C_TRANSFER_COMMAND_FIFO_REG);
INA226_ConfigureI2CCore(I2C_SHUNT_RESISTER_OHMS, I2C_CONTROL_REG, I2C_STATUS_REG, I2C_RX_DATA_FIFO_REG, I2C_RX_DATA_FIFO_LEVEL_REG, I2C_SCL_LOW_COUNT_REG, I2C_SCL_HIGH_COUNT_REG, I2C_SDA_HOLD_REG, I2C_TRANSFER_COMMAND_FIFO_REG);
INA226_CalibrateCurrentRegister(I2C_POWER_VIO_DEVICE_ID);
INA226_CalibrateCurrentRegister(I2C_POWER_VA_DEVICE_ID);
INA226_CalibrateCurrentRegister(I2C_POWER_VB_DEVICE_ID);
@ -1138,6 +1138,7 @@ void setVchip(int val) {
}
int getVChipToSet(enum DACINDEX ind, int val) {
FILE_LOG(logDEBUG1, ("Calculating vchip to set\n"));
// validate index & get adc index
int adcIndex = getADCIndexFromDACIndex(ind);
if (adcIndex == -1) {
@ -1286,15 +1287,17 @@ void setPower(enum DACINDEX ind, int val) {
// get vchip to set vchip (calculated now before switching off power enable)
int vchip = getVChipToSet(ind, val);
FILE_LOG(logDEBUG1, ("Vchip to set: %d\n", vchip));
// index problem of vchip calculation problem
if (vchip == -1)
return;
// Switch off power enable
FILE_LOG(logDEBUG1, ("Switching off power enable\n"));
bus_w(addr, bus_r(addr) & ~(mask));
// power down dac
FILE_LOG(logINFO, ("Powering off P%d (DAC %d)\n", adcIndex, ind));
FILE_LOG(logDEBUG1, ("Powering off P%d (DAC %d)\n", adcIndex, ind));
setDAC(ind, LTC2620_PWR_DOWN_VAL, 0);
// set vchip
@ -1310,6 +1313,11 @@ void setPower(enum DACINDEX ind, int val) {
// convert it to dac (power off is anyway done with power enable)
if (val != LTC2620_PWR_DOWN_VAL) {
FILE_LOG(logDEBUG1, ("Convert Power of %d mV to dac units\n", val));
/*
val = (double)val * 0.95;
FILE_LOG(logDEBUG1, ("Convert new Power of %d mV to dac units\n", val));
*/
int dacval = -1;
// convert voltage to dac
if (ConvertToDifferentRange(POWER_RGLTR_MIN, POWER_RGLTR_MAX, LTC2620_MAX_VAL, LTC2620_MIN_VAL,
@ -1318,17 +1326,23 @@ void setPower(enum DACINDEX ind, int val) {
ind, val, POWER_RGLTR_MIN, vchip - VCHIP_POWER_INCRMNT));
return;
}
/*
if (dacval > LTC2620_MAX_VAL)
dacval = LTC2620_MAX_VAL;
FILE_LOG(logDEBUG1, ("Converted new dac val: %d\n", dacval));
*/
// set and power on/ update dac
FILE_LOG(logINFO, ("Setting P%d (DAC %d): %d dac (%d mV)\n", adcIndex, ind, dacval, val));
setDAC(ind, dacval, 0);
// to be sure of valid conversion
if (dacval >= 0)
if (dacval >= 0) {
FILE_LOG(logDEBUG1, ("Switching on power enable\n"));
bus_w(addr, bus_r(addr) | mask);
}
}
}
}
void powerOff() {
uint32_t addr = POWER_REG;

View File

@ -1,6 +1,7 @@
#pragma once
#include "commonServerFunctions.h" // blackfin.h, ansi.h
#include "common.h"
/* AD7689 ADC DEFINES */
@ -62,8 +63,10 @@
#define AD7689_ADC_DATA_NUMBITS (16)
#define AD7689_NUM_CHANNELS (7)
#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_MAX_STEPS (0xFFFF + 1)
#define AD7689_TMP_C_FOR_1_MV (25.00 / 283)
@ -144,17 +147,17 @@ int AD7689_GetTemperature() {
AD7689_CFG_CFG_OVRWRTE_VAL);
// FIXME: do we have to read it 8 times?? (sequencer is disabled anyway) or are we sequencing, then we read only last channel
uint16_t regval = AD7689_Get();
int regval = AD7689_Get();
// value in mV FIXME: page 17? reference voltage temperature coefficient or t do with -40 to 85 °C
uint16_t vmin = AD7689_INT_REF_MIN_MV;
uint16_t vmax = AD7689_INT_REF_MAX_MV;
uint16_t nsteps = (2 ^ AD7689_ADC_DATA_NUMBITS);
uint16_t retval = (vmin + (vmax - vmin) * regval / (nsteps - 1));
int retval = 0;
ConvertToDifferentRange(0, AD7689_INT_MAX_STEPS,
AD7689_INT_REF_MIN_MV, AD7689_INT_REF_MAX_MV,
regval, &retval);
FILE_LOG(logDEBUG1, ("\tvoltage read for temp: 0x%d mV\n", retval));
// value in °C
uint16_t temp = AD7689_TMP_C_FOR_1_MV * retval;
int temp = AD7689_TMP_C_FOR_1_MV * retval;
FILE_LOG(logDEBUG1, ("\ttemp read: 0x%d °C\n", temp));
return temp;
@ -191,13 +194,13 @@ int AD7689_GetChannel(int ichan) {
AD7689_CFG_CFG_OVRWRTE_VAL);
// FIXME: do we have to read it 8 times?? (sequencer is disabled anyway) or are we sequencing, then we read only last channel
uint16_t regval = AD7689_Get();
int regval = AD7689_Get();
// value in mV
uint16_t vmin = AD7689_INT_REF_MIN_MV;
uint16_t vmax = AD7689_INT_REF_MAX_MV;
uint16_t nsteps = (2 ^ AD7689_ADC_DATA_NUMBITS);
uint16_t retval = (vmin + (vmax - vmin) * regval / (nsteps - 1));
int retval = 0;
ConvertToDifferentRange(0, AD7689_INT_MAX_STEPS,
AD7689_INT_REF_MIN_MV, AD7689_INT_REF_MAX_MV,
regval, &retval);
FILE_LOG(logINFO, ("\tvoltage read for chan %d: 0x%d mV\n", retval));
return retval;
@ -210,7 +213,7 @@ void AD7689_Configure(){
FILE_LOG(logINFOBLUE, ("Configuring AD7689 (Slow ADCs): \n"));
// from power up, 3 invalid conversions
FILE_LOG(logINFO, ("3 times due to invalid conversions from power up\n"));
FILE_LOG(logINFO, ("\tConfiguring %d x due to invalid conversions from power up\n", AD7689_NUM_INVALID_CONVERSIONS));
int i = 0;
for (i = 0; i < AD7689_NUM_INVALID_CONVERSIONS; ++i) {
AD7689_Set(

View File

@ -1,8 +1,11 @@
#pragma once
#include "blackfin.h"
#include <unistd.h> // usleep
/**
* Intel: Embedded Peripherals IP User Guide
* https://www.intel.com/content/dam/www/programmable/us/en/pdfs/literature/ug/ug_embedded_ip.pdf
* To be defined
*
* (in blackfin.h)
@ -13,8 +16,10 @@
* I2C_SCL_HIGH_COUNT_REG
* I2C_SDA_HOLD_REG
* I2C_CONTROL_REG
* I2C_STATUS_REG
* I2C_TRANSFER_COMMAND_FIFO_REG
* I2C_RX_DATA_FIFO_LEVEL_REG
* I2C_RX_DATA_FIFO_REG
*/
@ -53,12 +58,37 @@
#define I2C_TFR_CMD_DATA_FR_WR_OFST (0)
#define I2C_TFR_CMD_DATA_FR_WR_MSK (0x000000FF << I2C_TFR_CMD_DATA_FR_WR_OFST)
#define I2C_TFR_CMD_STOP_OFST (8)
#define I2C_TFR_CMD_STOP_MSK (0x00000001 << I2C_TFR_CMD_ADDR_OFST)
#define I2C_TFR_CMD_STOP_MSK (0x00000001 << I2C_TFR_CMD_STOP_OFST)
#define I2C_TFR_CMD_RPTD_STRT_OFST (9)
#define I2C_TFR_CMD_RPTD_STRT_MSK (0x00000001 << I2C_TFR_CMD_RPTD_STRT_OFST)
/** Receive DataFifo register */
#define I2C_RX_DATA_FIFO_RXDATA_OFST (0)
#define I2C_RX_DATA_FIFO_RXDATA_MSK (0x000000FF << I2C_RX_DATA_FIFO_RXDATA_OFST)
/** Status register */
#define I2C_STATUS_BUSY_OFST (0)
#define I2C_STATUS_BUSY_MSK (0x00000001 << I2C_STATUS_BUSY_OFST)
/** SCL Low Count register */
#define I2C_SCL_LOW_COUNT_PERIOD_OFST (0)
#define I2C_SCL_LOW_COUNT_PERIOD_MSK (0x0000FFFF << I2C_SCL_LOW_COUNT_PERIOD_OFST)
/** SCL High Count register */
#define I2C_SCL_HIGH_COUNT_PERIOD_OFST (0)
#define I2C_SCL_HIGH_COUNT_PERIOD_MSK (0x0000FFFF << I2C_SCL_HIGH_COUNT_PERIOD_OFST)
/** SDA Hold Count register */
#define I2C_SDA_HOLD_COUNT_PERIOD_OFST (0)
#define I2C_SDA_HOLD_COUNT_PERIOD_MSK (0x0000FFFF << I2C_SDA_HOLD_COUNT_PERIOD_OFST)
/** Receive Data Fifo Level register */
//#define I2C_RX_DATA_FIFO_LVL_OFST (0)
//#define I2C_RX_DATA_FIFO_LVL_MSK (0x000000FF << I2C_RX_DATA_FIFO_LVL_OFST)
uint32_t I2C_Control_Reg = 0x0;
uint32_t I2C_Status_Reg = 0x0;
uint32_t I2C_Rx_Data_Fifo_Reg = 0x0;
uint32_t I2C_Rx_Data_Fifo_Level_Reg = 0x0;
uint32_t I2C_Scl_Low_Count_Reg = 0x0;
uint32_t I2C_Scl_High_Count_Reg = 0x0;
@ -70,24 +100,34 @@ uint32_t I2C_Transfer_Command_Fifo_Reg = 0x0;
* Enable core and
* Calibrate the calibration register for current readout
* @param creg control register (defined in RegisterDefs.h)
* @param rreg rx data fifo level register (defined in RegisterDefs.h)
* @param sreg status register (defined in RegisterDefs.h)
* @param rreg rx data fifo register (defined in RegisterDefs.h)
* @param rlvlreg rx data fifo level register (defined in RegisterDefs.h)
* @param slreg scl low count register (defined in RegisterDefs.h)
* @param shreg scl high count register (defined in RegisterDefs.h)
* @param sdreg sda hold register (defined in RegisterDefs.h)
* @param treg transfer command fifo register (defined in RegisterDefs.h)
*/
void I2C_ConfigureI2CCore(uint32_t creg, uint32_t rreg, uint32_t slreg, uint32_t shreg, uint32_t sdreg, uint32_t treg) {
void I2C_ConfigureI2CCore(uint32_t creg, uint32_t sreg,
uint32_t rreg, uint32_t rlvlreg,
uint32_t slreg, uint32_t shreg, uint32_t sdreg, uint32_t treg) {
FILE_LOG(logINFO, ("\tConfiguring I2C Core for %d kbps:\n", I2C_DATA_RATE_KBPS));
FILE_LOG(logDEBUG1,("controlreg,:0x%x, statusreg,:0x%x, "
"rxrdatafiforeg: 0x%x, rxdatafifocountreg,:0x%x, "
"scllow,:0x%x, sclhighreg,:0x%x, sdaholdreg,:0x%x, transfercmdreg,:0x%x\n",
creg, sreg, rreg, rlvlreg, slreg, shreg, sdreg, treg));
I2C_Control_Reg = creg;
I2C_Rx_Data_Fifo_Level_Reg = rreg;
I2C_Status_Reg = sreg;
I2C_Rx_Data_Fifo_Reg = rreg;
I2C_Rx_Data_Fifo_Level_Reg = rlvlreg;
I2C_Scl_Low_Count_Reg = slreg;
I2C_Scl_High_Count_Reg = shreg;
I2C_Sda_Hold_Reg = sdreg;
I2C_Transfer_Command_Fifo_Reg = treg;
// calculate scl low and high period count
uint32_t sclPeriodNs = ((1000.00 * 1000.00) / (double)I2C_DATA_RATE_KBPS);
uint32_t sclPeriodNs = ((1000.00 * 1000.00 * 1000.00) / ((double)I2C_DATA_RATE_KBPS * 1000.00));
// scl low period same as high period
uint32_t sclLowPeriodNs = sclPeriodNs / 2;
// convert to us, then to clock (defined in blackfin.h)
@ -99,16 +139,25 @@ void I2C_ConfigureI2CCore(uint32_t creg, uint32_t rreg, uint32_t slreg, uint32_t
uint32_t sdaDataHoldCount = ((sdaDataHoldTimeNs / 1000.00) * I2C_CLOCK_MHZ);
FILE_LOG(logINFO, ("\tSetting SCL Low Period: %d ns (%d clocks)\n", sclLowPeriodNs, sclLowPeriodCount));
bus_w(I2C_Scl_Low_Count_Reg, sclLowPeriodCount);
bus_w(I2C_Scl_Low_Count_Reg, bus_r(I2C_Scl_Low_Count_Reg) |
((sclLowPeriodCount << I2C_SCL_LOW_COUNT_PERIOD_OFST) & I2C_SCL_LOW_COUNT_PERIOD_MSK));
FILE_LOG(logDEBUG1, ("SCL Low reg:0x%x\n", bus_r(I2C_Scl_Low_Count_Reg)));
FILE_LOG(logINFO, ("\tSetting SCL High Period: %d ns (%d clocks)\n", sclLowPeriodNs, sclLowPeriodCount));
bus_w(I2C_Scl_High_Count_Reg, sclLowPeriodCount);
bus_w(I2C_Scl_High_Count_Reg, bus_r(I2C_Scl_High_Count_Reg) |
((sclLowPeriodCount << I2C_SCL_HIGH_COUNT_PERIOD_OFST) & I2C_SCL_HIGH_COUNT_PERIOD_MSK));
FILE_LOG(logDEBUG1, ("SCL High reg:0x%x\n", bus_r(I2C_Scl_High_Count_Reg)));
FILE_LOG(logINFO, ("\tSetting SDA Hold Time: %d ns (%d clocks)\n", sdaDataHoldTimeNs, sdaDataHoldCount));
bus_w(I2C_Sda_Hold_Reg, (uint32_t)sdaDataHoldCount);
bus_w(I2C_Sda_Hold_Reg, bus_r(I2C_Sda_Hold_Reg) |
((sdaDataHoldCount << I2C_SDA_HOLD_COUNT_PERIOD_OFST) & I2C_SDA_HOLD_COUNT_PERIOD_MSK));
FILE_LOG(logDEBUG1, ("SDA Hold reg:0x%x\n", bus_r(I2C_Sda_Hold_Reg)));
FILE_LOG(logINFO, ("\tEnabling core\n"));
bus_w(I2C_Control_Reg, I2C_CTRL_ENBLE_CORE_MSK | I2C_CTRL_BUS_SPEED_FAST_400_VAL);// fixme: (works?)
FILE_LOG(logINFO, ("\tEnabling core and bus speed to fast (up to 400 kbps)\n"));
bus_w(I2C_Control_Reg, bus_r(I2C_Control_Reg) |
I2C_CTRL_ENBLE_CORE_MSK | I2C_CTRL_BUS_SPEED_FAST_400_VAL);// fixme: (works?)
FILE_LOG(logDEBUG1, ("Control reg:0x%x\n", bus_r(I2C_Control_Reg)));
//The INA226 supports the transmission protocol for fast mode (1 kHz to 400 kHz) and high-speed mode (1 kHz to 2.94 MHz).
}
/**
@ -118,27 +167,59 @@ void I2C_ConfigureI2CCore(uint32_t creg, uint32_t rreg, uint32_t slreg, uint32_t
* @returns value read from register
*/
uint32_t I2C_Read(uint32_t devId, uint32_t addr) {
FILE_LOG(logDEBUG1, ("\tReading from I2C device 0x%x and reg 0x%x\n", devId, addr));
FILE_LOG(logDEBUG1, (" ================================================\n"));
FILE_LOG(logDEBUG1, (" Reading from I2C device 0x%x and reg 0x%x\n", devId, addr));
// device Id mask
uint32_t devIdMask = ((devId << I2C_TFR_CMD_ADDR_OFST) & I2C_TFR_CMD_ADDR_MSK);
FILE_LOG(logDEBUG1, (" devId:0x%x\n", devIdMask));
// write I2C ID
bus_w(I2C_Transfer_Command_Fifo_Reg, (devIdMask & ~(I2C_TFR_CMD_RW_MSK)));
FILE_LOG(logDEBUG1, (" write devID and R/-W:0x%x\n", (devIdMask & ~(I2C_TFR_CMD_RW_MSK))));
// write register addr
bus_w(I2C_Transfer_Command_Fifo_Reg, addr);
FILE_LOG(logDEBUG1, (" write addr:0x%x\n", addr));
// repeated start with read
// repeated start with read (repeated start needed here because it was in write operation mode earlier, for the device ID)
bus_w(I2C_Transfer_Command_Fifo_Reg, (devIdMask | I2C_TFR_CMD_RPTD_STRT_MSK | I2C_TFR_CMD_RW_READ_VAL));
FILE_LOG(logDEBUG1, (" repeated start:0x%x\n", (devIdMask | I2C_TFR_CMD_RPTD_STRT_MSK | I2C_TFR_CMD_RW_READ_VAL)));
// continue reading
bus_w(I2C_Transfer_Command_Fifo_Reg, 0x0);
FILE_LOG(logDEBUG1, (" continue reading:0x%x\n", 0x0));
// stop reading
bus_w(I2C_Transfer_Command_Fifo_Reg, I2C_TFR_CMD_STOP_MSK);
FILE_LOG(logDEBUG1, (" stop reading:0x%x\n", I2C_TFR_CMD_STOP_MSK));
// read value
return bus_r(I2C_Rx_Data_Fifo_Level_Reg);
uint32_t retval = 0;
//In case one wants to do something more general (INA226 receives only 2 bytes)
// wait till status is idle
int status = 1;
while(status) {
status = bus_r(I2C_Status_Reg) & I2C_STATUS_BUSY_MSK;
FILE_LOG(logDEBUG1, (" status:%d\n", status));
usleep(0);
}
// get rx fifo level (get number of bytes to be received)
int level = bus_r(I2C_Rx_Data_Fifo_Level_Reg);
FILE_LOG(logDEBUG1, (" level:%d\n", level));
int iloop = level - 1;
// level bytes to read, read 1 byte at a time
for (iloop = level - 1; iloop >= 0; --iloop) {
u_int16_t byte = bus_r(I2C_Rx_Data_Fifo_Reg) & I2C_RX_DATA_FIFO_RXDATA_MSK;
FILE_LOG(logDEBUG1, (" byte nr %d:0x%x\n", iloop, byte));
// push by 1 byte at a time
retval |= (byte << (8 * iloop));
}
FILE_LOG(logDEBUG1, (" retval:0x%x\n", retval));
FILE_LOG(logDEBUG1, (" ================================================\n"));
return retval;
}
/**
@ -148,27 +229,34 @@ uint32_t I2C_Read(uint32_t devId, uint32_t addr) {
* @param data data to be written (16 bit)
*/
void I2C_Write(uint32_t devId, uint32_t addr, uint16_t data) {
FILE_LOG(logDEBUG1, (" ================================================\n"));
FILE_LOG(logDEBUG1, (" Writing to I2C (Device:0x%x, reg:0x%x, data:%d)\n", devId, addr, data));
// device Id mask
uint32_t devIdMask = ((devId << I2C_TFR_CMD_ADDR_OFST) & I2C_TFR_CMD_ADDR_MSK);
FILE_LOG(logDEBUG1, (" devId:0x%x\n", devId));
// write I2C ID
bus_w(I2C_Transfer_Command_Fifo_Reg, (devIdMask & ~(I2C_TFR_CMD_RW_MSK)));
FILE_LOG(logDEBUG1, (" write devID and R/-W:0x%x\n", (devIdMask & ~(I2C_TFR_CMD_RW_MSK))));
// write register addr
bus_w(I2C_Transfer_Command_Fifo_Reg, addr);
FILE_LOG(logDEBUG1, (" write addr:0x%x\n", addr));
// repeated start with write
bus_w(I2C_Transfer_Command_Fifo_Reg, ((devIdMask | I2C_TFR_CMD_RPTD_STRT_MSK) & ~(I2C_TFR_CMD_RW_MSK)));
// do not do the repeated start as it is already in write operation mode (else it wont work)
uint8_t msb = (uint8_t)((data & 0xFF00) >> 8);
uint8_t lsb = (uint8_t)(data & 0x00FF);
FILE_LOG(logDEBUG1, (" msb:0x%02x, lsb:0x%02x\n", msb, lsb));
// writing data MSB
bus_w(I2C_Transfer_Command_Fifo_Reg, ((msb << I2C_TFR_CMD_DATA_FR_WR_OFST) & I2C_TFR_CMD_DATA_FR_WR_MSK));
FILE_LOG(logDEBUG1, (" write msb:0x%02x\n", ((msb << I2C_TFR_CMD_DATA_FR_WR_OFST) & I2C_TFR_CMD_DATA_FR_WR_MSK)));
// writing data LSB and stop writing bit
bus_w(I2C_Transfer_Command_Fifo_Reg, ((lsb << I2C_TFR_CMD_DATA_FR_WR_OFST) & I2C_TFR_CMD_DATA_FR_WR_MSK) | I2C_TFR_CMD_STOP_MSK);
FILE_LOG(logDEBUG1, (" write lsb and stop writing:0x%x\n", ((lsb << I2C_TFR_CMD_DATA_FR_WR_OFST) & I2C_TFR_CMD_DATA_FR_WR_MSK) | I2C_TFR_CMD_STOP_MSK));
FILE_LOG(logDEBUG1, (" ================================================\n"));
}

View File

@ -29,10 +29,18 @@
#define INA226_BUS_VOLTAGE_MX_STPS (0x7FFF + 1)
#define INA226_BUS_VOLTAGE_VMAX_UV (INA226_BUS_VOLTAGE_VMIN_UV * INA226_BUS_VOLTAGE_MX_STPS) // 40960000uV, 40.96V
/** current register */
/** shunt voltage register */
#define INA226_SHUNT_VOLTAGE_VMIN_NV (2500) // 2.5uV
#define INA226_SHUNT_VOLTAGE_MX_STPS (0x7FFF + 1)
#define INA226_SHUNT_VOLTAGE_VMAX_NV (INA226_SHUNT_VOLTAGE_VMIN_NV * INA226_SHUNT_VOLTAGE_MX_STPS) // 81920000nV, 81.92mV
#define INA226_SHUNT_NEGATIVE_MSK (1 << 15)
#define INA226_SHUNT_ABS_VALUE_MSK (0x7FFF)
/** current precision for calibration register */
#define INA226_CURRENT_IMIN_UA (100) //100uA can be changed
#define INA226_CURRENT_MX_STPS (0x7FFF + 1)
#define INA226_CURRENT_IMAX_UA (INA226_CURRENT_IMIN_UA * INA226_CURRENT_MX_STPS)
/** calibration register */
#define INA226_CALIBRATION_MSK (0x7FFF)
@ -41,7 +49,7 @@
#define INA226_getCalibrationValue(rOhm) (0.00512 /(INA226_CURRENT_IMIN_UA * 1e-6 * rOhm))
/** get current unit */
#define INA226_getConvertedCurrentUnits(shuntVReg, calibReg) (shuntVReg * calibReg / 2048)
#define INA226_getConvertedCurrentUnits(shuntV, calibReg) ((double)shuntV * (double)calibReg / (double)2048)
double INA226_Shunt_Resistor_Ohm = 0.0;
@ -50,18 +58,22 @@ double INA226_Shunt_Resistor_Ohm = 0.0;
* Configure the I2C core and Enable core
* @param rOhm shunt resister value in Ohms (defined in slsDetectorServer_defs.h)
* @param creg control register (defined in RegisterDefs.h)
* @param rreg rx data fifo level register (defined in RegisterDefs.h)
* @param sreg status register (defined in RegisterDefs.h)
* @param rreg rx data fifo register (defined in RegisterDefs.h)
* @param rlvlreg rx data fifo level register (defined in RegisterDefs.h)
* @param slreg scl low count register (defined in RegisterDefs.h)
* @param shreg scl high count register (defined in RegisterDefs.h)
* @param sdreg sda hold register (defined in RegisterDefs.h)
* @param treg transfer command fifo register (defined in RegisterDefs.h)
*/
void INA226_ConfigureI2CCore(double rOhm, uint32_t creg, uint32_t rreg, uint32_t slreg, uint32_t shreg, uint32_t sdreg, uint32_t treg) {
void INA226_ConfigureI2CCore(double rOhm, uint32_t creg, uint32_t sreg,
uint32_t rreg, uint32_t rlvlreg,
uint32_t slreg, uint32_t shreg, uint32_t sdreg, uint32_t treg) {
FILE_LOG(logINFOBLUE, ("Configuring INA226\n"));
FILE_LOG(logDEBUG1, ("Shunt ohm resistor: %f\n", rOhm));
INA226_Shunt_Resistor_Ohm = rOhm;
I2C_ConfigureI2CCore(creg, rreg, slreg, shreg, sdreg, treg);
I2C_ConfigureI2CCore(creg, sreg, rreg, rlvlreg, slreg, shreg, sdreg, treg);
}
/**
@ -76,6 +88,12 @@ void INA226_CalibrateCurrentRegister(uint32_t deviceId) {
// calibrate current register
I2C_Write(deviceId, INA226_CALIBRATION_REG, calVal);
// read back calibration register
int retval = I2C_Read(deviceId, INA226_CALIBRATION_REG);
if (retval != calVal) {
FILE_LOG(logERROR, ("Cannot set calibration register for I2C. Set 0x%x, read 0x%x\n", calVal, retval));
}
}
/**
@ -84,24 +102,23 @@ void INA226_CalibrateCurrentRegister(uint32_t deviceId) {
* @returns voltage in mV
*/
int INA226_ReadVoltage(uint32_t deviceId) {
FILE_LOG(logDEBUG1, ("\tReading voltage\n"));
FILE_LOG(logDEBUG1, (" Reading voltage\n"));
uint32_t regval = I2C_Read(deviceId, INA226_BUS_VOLTAGE_REG);
FILE_LOG(logDEBUG1, ("\tvoltage read: 0x%08x\n", regval));
// value converted in mv
uint32_t vmin = INA226_BUS_VOLTAGE_VMIN_UV;
uint32_t vmax = INA226_BUS_VOLTAGE_VMAX_UV;
uint32_t nsteps = INA226_BUS_VOLTAGE_MX_STPS;
FILE_LOG(logDEBUG1, (" bus voltage reg: 0x%08x\n", regval));
// value in uV
int retval = (vmin + (vmax - vmin) * regval / (nsteps - 1));
FILE_LOG(logDEBUG1, ("\tvoltage read: 0x%d uV\n", retval));
int voltageuV = 0;
ConvertToDifferentRange(0, INA226_BUS_VOLTAGE_MX_STPS,
INA226_BUS_VOLTAGE_VMIN_UV, INA226_BUS_VOLTAGE_VMAX_UV,
regval, &voltageuV);
FILE_LOG(logDEBUG1, (" voltage: 0x%d uV\n", voltageuV));
// value in mV
retval /= 1000;
FILE_LOG(logDEBUG1, ("\tvoltage read: %d mV\n", retval));
int voltagemV = voltageuV / 1000;
FILE_LOG(logDEBUG1, (" voltage: %d mV\n", voltagemV));
FILE_LOG(logINFO, ("Voltage via I2C (Device: 0x%x): %d mV\n", deviceId, voltagemV));
return retval;
return voltagemV;
}
/**
@ -110,29 +127,79 @@ int INA226_ReadVoltage(uint32_t deviceId) {
* @returns current in mA
*/
int INA226_ReadCurrent(uint32_t deviceId) {
FILE_LOG(logDEBUG1, ("\tReading current\n"));
FILE_LOG(logDEBUG1, (" Reading current\n"));
// read shunt voltage register
FILE_LOG(logDEBUG1, ("\tReading shunt voltage reg\n"));
FILE_LOG(logDEBUG1, (" Reading shunt voltage reg\n"));
uint32_t shuntVoltageRegVal = I2C_Read(deviceId, INA226_SHUNT_VOLTAGE_REG);
FILE_LOG(logDEBUG1, ("\tshunt voltage reg: 0x%08x\n", shuntVoltageRegVal));
FILE_LOG(logDEBUG1, (" shunt voltage reg: 0x%x\n", shuntVoltageRegVal));
// read it once more as this error has occured once
if (shuntVoltageRegVal == 0xFFFF) {
FILE_LOG(logDEBUG1, (" Reading shunt voltage reg again\n"));
shuntVoltageRegVal = I2C_Read(deviceId, INA226_SHUNT_VOLTAGE_REG);
FILE_LOG(logDEBUG1, (" shunt voltage reg: 0x%x\n", shuntVoltageRegVal));
}
// get absolute value and if negative
int negative = (shuntVoltageRegVal & INA226_SHUNT_NEGATIVE_MSK) ? 1: 0;
int shuntabsnV = shuntVoltageRegVal & INA226_SHUNT_ABS_VALUE_MSK;
FILE_LOG(logDEBUG1, (" negative: %d, absolute: 0x%x\n", negative, shuntabsnV));
// negative, convert absolute to 2s complement
if (negative) {
shuntabsnV = ((~shuntabsnV) + 1);
FILE_LOG(logDEBUG1, (" new absolute for negative (2's comple): 0x%x\n", shuntabsnV));
}
// calculate shunt voltage
int shuntVoltagenV = 0;
ConvertToDifferentRange(0, INA226_SHUNT_VOLTAGE_MX_STPS,
INA226_SHUNT_VOLTAGE_VMIN_NV, INA226_SHUNT_VOLTAGE_VMAX_NV,
shuntabsnV, &shuntVoltagenV);
// if negative, put the sign
if (negative)
shuntVoltagenV = -(shuntVoltagenV);
FILE_LOG(logDEBUG1, (" shunt voltage: %d nV\n", shuntVoltagenV));
int shuntVoltageUV = shuntVoltagenV / 1000;
FILE_LOG(logDEBUG1, (" shunt voltage: %d uV\n\n", shuntVoltageUV));
// read calibration register
FILE_LOG(logDEBUG1, ("\tReading calibration reg\n"));
FILE_LOG(logDEBUG1, (" Reading calibration reg\n"));
uint32_t calibrationRegVal = I2C_Read(deviceId, INA226_CALIBRATION_REG);
FILE_LOG(logDEBUG1, ("\tcalibration reg: 0x%08x\n", calibrationRegVal));
FILE_LOG(logDEBUG1, (" calibration reg: 0x%08x\n\n", calibrationRegVal));
// read it once more as this error has occured once
if (calibrationRegVal == 0xFFFF) {
FILE_LOG(logDEBUG1, (" Reading calibration reg again\n"));
calibrationRegVal = I2C_Read(deviceId, INA226_CALIBRATION_REG);
FILE_LOG(logDEBUG1, (" calibration reg: 0x%x\n", calibrationRegVal));
}
// value for current
uint32_t retval = INA226_getConvertedCurrentUnits(shuntVoltageRegVal, calibrationRegVal);
FILE_LOG(logDEBUG1, ("\tcurrent unit value: %d\n", retval));
int retval = INA226_getConvertedCurrentUnits(shuntVoltageUV, calibrationRegVal);
FILE_LOG(logDEBUG1, (" current unit value: %d\n", retval));
FILE_LOG(logDEBUG1, (" To TEST: should be same as curent unit value\n"
" Reading current reg\n"));
int cuurentRegVal = I2C_Read(deviceId, INA226_CURRENT_REG);
FILE_LOG(logDEBUG1, (" current reg: 0x%x\n", cuurentRegVal));
// read it once more as this error has occured once
if (cuurentRegVal >= 0xFFF0) {
FILE_LOG(logDEBUG1, (" Reading current reg again\n"));
cuurentRegVal = I2C_Read(deviceId, INA226_CURRENT_REG);
FILE_LOG(logDEBUG1, (" current reg: 0x%x\n", cuurentRegVal));
}
// current in uA
retval *= INA226_CURRENT_IMIN_UA;
FILE_LOG(logDEBUG1, ("\tcurrent: %d uA\n", retval));
int currentuA = retval * INA226_CURRENT_IMIN_UA;
FILE_LOG(logDEBUG1, (" current: %d uA\n", currentuA));
// current in mA
retval /= 1000;
FILE_LOG(logDEBUG1, ("\tcurrent: %d mA\n", retval));
int currentmA = currentuA / 1000;
FILE_LOG(logDEBUG1, (" current: %d mA\n", currentmA));
return retval;
FILE_LOG(logINFO, ("Current via I2C (Device: 0x%x): %d mA\n", deviceId, currentmA));
return currentmA;
}

View File

@ -29,7 +29,7 @@ int ConvertToDifferentRange(int inputMin, int inputMax, int outputMin, int outpu
return FAIL;
}
double value = (double)((inputValue - inputMin) * (outputMax - outputMin))
double value = ((double)(inputValue - inputMin) * (double)(outputMax - outputMin))
/ (double)(inputMax - inputMin) + outputMin;
// double to integer conversion (if decimal places, round to integer)

View File

@ -3742,19 +3742,25 @@ std::string slsDetectorCommand::cmdDAC(int narg, char *args[], int action, int d
dac = E_Vis;
else if (cmd == "iodelay")
dac = IO_DELAY;
else if (cmd == "v_a")
else if (cmd == "v_a") {
dac = V_POWER_A;
else if (cmd == "v_b")
mode = 1;
} else if (cmd == "v_b") {
dac = V_POWER_B;
else if (cmd == "v_c")
mode = 1;
} else if (cmd == "v_c") {
dac = V_POWER_C;
else if (cmd == "v_d")
mode = 1;
} else if (cmd == "v_d") {
dac = V_POWER_D;
else if (cmd == "v_io")
mode = 1;
} else if (cmd == "v_io") {
dac = V_POWER_IO;
else if (cmd == "v_chip")
mode = 1;
} else if (cmd == "v_chip") {
dac = V_POWER_CHIP;
else if (cmd == "v_limit")
mode = 1;
} else if (cmd == "v_limit")
dac = V_LIMIT;
else if (cmd == "vIpre")
dac = M_vIpre;
@ -3803,10 +3809,10 @@ std::string slsDetectorCommand::cmdDAC(int narg, char *args[], int action, int d
myDet->setDAC(val, dac, mode, detPos);
}
else if (narg >= 2)
if (!strcasecmp(args[1], "mv"))
// get (dacs in dac units or mV)
else if ((narg >= 2) && (!strcasecmp(args[1], "mv"))) {
mode = 1;
}
sprintf(answer, "%d", myDet->setDAC(-1, dac, mode, detPos));
if (mode)
@ -4065,6 +4071,8 @@ std::string slsDetectorCommand::cmdADC(int narg, char *args[], int action, int d
//if ((adc == TEMPERATURE_ADC) || (adc == TEMPERATURE_FPGA))
if (adc < 100 || adc == SLOW_ADC_TEMP)
strcat(answer," °C");
else if (adc == I_POWER_A || adc == I_POWER_B || adc == I_POWER_C || adc == I_POWER_D || adc == I_POWER_IO)
strcat(answer," mA");
else
strcat(answer," mV");