mirror of
https://github.com/slsdetectorgroup/slsDetectorPackage.git
synced 2026-01-16 14:39:00 +01:00
merging refactor (replacing)
This commit is contained in:
238
slsDetectorServers/slsDetectorServer/AD7689.h
Executable file
238
slsDetectorServers/slsDetectorServer/AD7689.h
Executable file
@@ -0,0 +1,238 @@
|
||||
#pragma once
|
||||
|
||||
#include "commonServerFunctions.h" // blackfin.h, ansi.h
|
||||
#include "common.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_MAX_STEPS (0xFFFF + 1)
|
||||
#define AD7689_TMP_C_FOR_1_MV (25.00 / 283.00)
|
||||
|
||||
|
||||
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;
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
FILE_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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable SPI
|
||||
*/
|
||||
void AD7689_Disable() {
|
||||
bus_w(AD7689_Reg, (bus_r(AD7689_Reg)
|
||||
&~(AD7689_CnvMask)
|
||||
&~AD7689_ClkMask
|
||||
&~(AD7689_DigMask)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set SPI reg value
|
||||
* @param codata value to be set
|
||||
*/
|
||||
void AD7689_Set(u_int32_t codata) {
|
||||
FILE_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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get SPI reg value
|
||||
* @returns SPI reg value
|
||||
*/
|
||||
uint16_t AD7689_Get() {
|
||||
FILE_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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get temperature
|
||||
* @returns temperature in °C
|
||||
*/
|
||||
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);
|
||||
|
||||
// FIXME: do we have to read it 8 times?? (sequencer is disabled anyway) or are we sequencing, then we read only last channel
|
||||
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);
|
||||
FILE_LOG(logDEBUG1, ("voltage read for temp: %d mV\n", retval));
|
||||
|
||||
// value in °C
|
||||
double tempValue = AD7689_TMP_C_FOR_1_MV * (double)retval;
|
||||
|
||||
FILE_LOG(logINFO, ("\ttemp read : %f °C\n", tempValue));
|
||||
|
||||
return tempValue;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads channels voltage
|
||||
* @param ichan channel number from 0 to 7
|
||||
* @returns channel voltage in mV
|
||||
*/
|
||||
int AD7689_GetChannel(int ichan) {
|
||||
// filter channels val
|
||||
if (ichan < 0 || ichan >= AD7689_NUM_CHANNELS) {
|
||||
FILE_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);
|
||||
|
||||
// FIXME: do we have to read it 8 times?? (sequencer is disabled anyway) or are we sequencing, then we read only last channel
|
||||
int regval = AD7689_Get();
|
||||
|
||||
// value in mV
|
||||
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: %d mV\n", ichan, retval));
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure
|
||||
*/
|
||||
void AD7689_Configure(){
|
||||
FILE_LOG(logINFOBLUE, ("Configuring AD7689 (Slow ADCs): \n"));
|
||||
|
||||
// from power up, 3 invalid conversions
|
||||
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(
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
197
slsDetectorServers/slsDetectorServer/AD9252.h
Executable file
197
slsDetectorServers/slsDetectorServer/AD9252.h
Executable file
@@ -0,0 +1,197 @@
|
||||
#pragma once
|
||||
|
||||
#include "commonServerFunctions.h" // blackfin.h, ansi.h
|
||||
#ifdef GOTTHARDD
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
/* AD9252 ADC DEFINES */
|
||||
#define AD9252_ADC_NUMBITS (24)
|
||||
|
||||
// default value is 0xF
|
||||
#define AD9252_DEV_IND_2_REG (0x04)
|
||||
#define AD9252_CHAN_H_OFST (0)
|
||||
#define AD9252_CHAN_H_MSK (0x00000001 << AD9252_CHAN_H_OFST)
|
||||
#define AD9252_CHAN_G_OFST (1)
|
||||
#define AD9252_CHAN_G_MSK (0x00000001 << AD9252_CHAN_G_OFST)
|
||||
#define AD9252_CHAN_F_OFST (2)
|
||||
#define AD9252_CHAN_F_MSK (0x00000001 << AD9252_CHAN_F_OFST)
|
||||
#define AD9252_CHAN_E_OFST (3)
|
||||
#define AD9252_CHAN_E_MSK (0x00000001 << AD9252_CHAN_E_OFST)
|
||||
|
||||
// default value is 0x0F
|
||||
#define AD9252_DEV_IND_1_REG (0x05)
|
||||
#define AD9252_CHAN_D_OFST (0)
|
||||
#define AD9252_CHAN_D_MSK (0x00000001 << AD9252_CHAN_D_OFST)
|
||||
#define AD9252_CHAN_C_OFST (1)
|
||||
#define AD9252_CHAN_C_MSK (0x00000001 << AD9252_CHAN_C_OFST)
|
||||
#define AD9252_CHAN_B_OFST (2)
|
||||
#define AD9252_CHAN_B_MSK (0x00000001 << AD9252_CHAN_B_OFST)
|
||||
#define AD9252_CHAN_A_OFST (3)
|
||||
#define AD9252_CHAN_A_MSK (0x00000001 << AD9252_CHAN_A_OFST)
|
||||
#define AD9252_CLK_CH_DCO_OFST (4)
|
||||
#define AD9252_CLK_CH_DCO_MSK (0x00000001 << AD9252_CLK_CH_DCO_OFST)
|
||||
#define AD9252_CLK_CH_IFCO_OFST (5)
|
||||
#define AD9252_CLK_CH_IFCO_MSK (0x00000001 << AD9252_CLK_CH_IFCO_OFST)
|
||||
|
||||
// default value is 0x00
|
||||
#define AD9252_POWER_MODE_REG (0x08)
|
||||
#define AD9252_POWER_INTERNAL_OFST (0)
|
||||
#define AD9252_POWER_INTERNAL_MSK (0x00000007 << AD9252_POWER_INTERNAL_OFST)
|
||||
#define AD9252_INT_CHIP_RUN_VAL ((0x0 << AD9252_POWER_INTERNAL_OFST) & AD9252_POWER_INTERNAL_MSK)
|
||||
#define AD9252_INT_FULL_PWR_DWN_VAL ((0x1 << AD9252_POWER_INTERNAL_OFST) & AD9252_POWER_INTERNAL_MSK)
|
||||
#define AD9252_INT_STANDBY_VAL ((0x2 << AD9252_POWER_INTERNAL_OFST) & AD9252_POWER_INTERNAL_MSK)
|
||||
#define AD9252_INT_RESET_VAL ((0x3 << AD9252_POWER_INTERNAL_OFST) & AD9252_POWER_INTERNAL_MSK)
|
||||
|
||||
|
||||
// default value is 0x0
|
||||
#define AD9252_TEST_MODE_REG (0x0D)
|
||||
#define AD9252_OUT_TEST_OFST (0)
|
||||
#define AD9252_OUT_TEST_MSK (0x0000000F << AD9252_OUT_TEST_OFST)
|
||||
#define AD9252_TST_OFF_VAL ((0x0 << AD9252_OUT_TEST_OFST) & AD9252_OUT_TEST_MSK)
|
||||
#define AD9252_TST_MDSCL_SHRT_VAL ((0x1 << AD9252_OUT_TEST_OFST) & AD9252_OUT_TEST_MSK)
|
||||
#define AD9252_TST_PSTV_FS_VAL ((0x2 << AD9252_OUT_TEST_OFST) & AD9252_OUT_TEST_MSK)
|
||||
#define AD9252_TST_NGTV_FS_VAL ((0x3 << AD9252_OUT_TEST_OFST) & AD9252_OUT_TEST_MSK)
|
||||
#define AD9252_TST_ALTRNTNG_CHKRBRD_VAL ((0x4 << AD9252_OUT_TEST_OFST) & AD9252_OUT_TEST_MSK)
|
||||
#define AD9252_TST_PN_23_SQNC_VAL ((0x5 << AD9252_OUT_TEST_OFST) & AD9252_OUT_TEST_MSK)
|
||||
#define AD9252_TST_PN_9_SQNC__VAL ((0x6 << AD9252_OUT_TEST_OFST) & AD9252_OUT_TEST_MSK)
|
||||
#define AD9252_TST_1_0_WRD_TGGL_VAL ((0x7 << AD9252_OUT_TEST_OFST) & AD9252_OUT_TEST_MSK)
|
||||
#define AD9252_TST_USR_INPT_VAL ((0x8 << AD9252_OUT_TEST_OFST) & AD9252_OUT_TEST_MSK)
|
||||
#define AD9252_TST_1_0_BT_TGGL_VAL ((0x9 << AD9252_OUT_TEST_OFST) & AD9252_OUT_TEST_MSK)
|
||||
#define AD9252_TST_1_x_SYNC_VAL ((0xa << AD9252_OUT_TEST_OFST) & AD9252_OUT_TEST_MSK)
|
||||
#define AD9252_TST_1_BIT_HGH_VAL ((0xb << AD9252_OUT_TEST_OFST) & AD9252_OUT_TEST_MSK)
|
||||
#define AD9252_TST_MXD_BT_FRQ_VAL ((0xc << AD9252_OUT_TEST_OFST) & AD9252_OUT_TEST_MSK)
|
||||
#define AD9252_TST_RST_SHRT_GN_OFST (4)
|
||||
#define AD9252_TST_RST_SHRT_GN_MSK (0x00000001 << AD9252_TST_RST_SHRT_GN_OFST)
|
||||
#define AD9252_TST_RST_LNG_GN_OFST (5)
|
||||
#define AD9252_TST_RST_LNG_GN_MSK (0x00000001 << AD9252_TST_RST_LNG_GN_OFST)
|
||||
#define AD9252_USER_IN_MODE_OFST (6)
|
||||
#define AD9252_USER_IN_MODE_MSK (0x00000003 << AD9252_USER_IN_MODE_OFST)
|
||||
#define AD9252_USR_IN_SNGL_VAL ((0x0 << AD9252_USER_IN_MODE_OFST) & AD9252_USER_IN_MODE_MSK)
|
||||
#define AD9252_USR_IN_ALTRNT_VAL ((0x1 << AD9252_USER_IN_MODE_OFST) & AD9252_USER_IN_MODE_MSK)
|
||||
#define AD9252_USR_IN_SNGL_ONC_VAL ((0x2 << AD9252_USER_IN_MODE_OFST) & AD9252_USER_IN_MODE_MSK)
|
||||
#define AD9252_USR_IN_ALTRNT_ONC_VAL ((0x3 << AD9252_USER_IN_MODE_OFST) & AD9252_USER_IN_MODE_MSK)
|
||||
|
||||
// default value is 0x00
|
||||
#define AD9252_OUT_MODE_REG (0x14)
|
||||
#define AD9252_OUT_FORMAT_OFST (0)
|
||||
#define AD9252_OUT_FORMAT_MSK (0x00000003 << AD9252_OUT_FORMAT_OFST)
|
||||
#define AD9252_OUT_BINARY_OFST_VAL ((0x0 << AD9252_OUT_FORMAT_OFST) & AD9252_OUT_FORMAT_MSK)
|
||||
#define AD9252_OUT_TWOS_COMPL_VAL ((0x1 << AD9252_OUT_FORMAT_OFST) & AD9252_OUT_FORMAT_MSK)
|
||||
#define AD9252_OUT_OTPT_INVRT_OFST (2)
|
||||
#define AD9252_OUT_OTPT_INVRT_MSK (0x00000001 << AD9252_OUT_OTPT_INVRT_OFST)
|
||||
#define AD9252_OUT_LVDS_OPT_OFST (6)
|
||||
#define AD9252_OUT_LVDS_OPT_MSK (0x00000001 << AD9252_OUT_LVDS_OPT_OFST)
|
||||
#define AD9252_OUT_LVDS_ANSI_VAL ((0x0 << AD9252_OUT_LVDS_OPT_OFST) & AD9252_OUT_LVDS_OPT_MSK)
|
||||
#define AD9252_OUT_LVDS_IEEE_VAL ((0x1 << AD9252_OUT_LVDS_OPT_OFST) & AD9252_OUT_LVDS_OPT_MSK)
|
||||
|
||||
// default value is 0x3
|
||||
#define AD9252_OUT_PHASE_REG (0x16)
|
||||
#define AD9252_OUT_CLK_OFST (0)
|
||||
#define AD9252_OUT_CLK_MSK (0x0000000F << AD9252_OUT_CLK_OFST)
|
||||
#define AD9252_OUT_CLK_0_VAL ((0x0 << AD9252_OUT_CLK_OFST) & AD9252_OUT_CLK_MSK)
|
||||
#define AD9252_OUT_CLK_60_VAL ((0x1 << AD9252_OUT_CLK_OFST) & AD9252_OUT_CLK_MSK)
|
||||
#define AD9252_OUT_CLK_120_VAL ((0x2 << AD9252_OUT_CLK_OFST) & AD9252_OUT_CLK_MSK)
|
||||
#define AD9252_OUT_CLK_180_VAL ((0x3 << AD9252_OUT_CLK_OFST) & AD9252_OUT_CLK_MSK)
|
||||
#define AD9252_OUT_CLK_300_VAL ((0x5 << AD9252_OUT_CLK_OFST) & AD9252_OUT_CLK_MSK)
|
||||
#define AD9252_OUT_CLK_360_VAL ((0x6 << AD9252_OUT_CLK_OFST) & AD9252_OUT_CLK_MSK)
|
||||
#define AD9252_OUT_CLK_480_VAL ((0x8 << AD9252_OUT_CLK_OFST) & AD9252_OUT_CLK_MSK)
|
||||
#define AD9252_OUT_CLK_540_VAL ((0x9 << AD9252_OUT_CLK_OFST) & AD9252_OUT_CLK_MSK)
|
||||
#define AD9252_OUT_CLK_600_VAL ((0xa << AD9252_OUT_CLK_OFST) & AD9252_OUT_CLK_MSK)
|
||||
#define AD9252_OUT_CLK_660_VAL ((0xb << AD9252_OUT_CLK_OFST) & AD9252_OUT_CLK_MSK) // 0xb - 0xf is 660
|
||||
|
||||
uint32_t AD9252_Reg = 0x0;
|
||||
uint32_t AD9252_CsMask = 0x0;
|
||||
uint32_t AD9252_ClkMask = 0x0;
|
||||
uint32_t AD9252_DigMask = 0x0;
|
||||
int AD9252_DigOffset = 0x0;
|
||||
|
||||
/**
|
||||
* Set Defines
|
||||
* @param reg spi register
|
||||
* @param cmsk chip select mask
|
||||
* @param clkmsk clock output mask
|
||||
* @param dmsk digital output mask
|
||||
* @param dofst digital output offset
|
||||
*/
|
||||
void AD9252_SetDefines(uint32_t reg, uint32_t cmsk, uint32_t clkmsk, uint32_t dmsk, int dofst) {
|
||||
AD9252_Reg = reg;
|
||||
AD9252_CsMask = cmsk;
|
||||
AD9252_ClkMask = clkmsk;
|
||||
AD9252_DigMask = dmsk;
|
||||
AD9252_DigOffset = dofst;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable SPI
|
||||
*/
|
||||
void AD9252_Disable() {
|
||||
bus_w(AD9252_Reg, (bus_r(AD9252_Reg)
|
||||
| AD9252_CsMask
|
||||
| AD9252_ClkMask)
|
||||
&~(AD9252_DigMask));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set SPI reg value
|
||||
* @param codata value to be set
|
||||
*/
|
||||
void AD9252_Set(int addr, int val) {
|
||||
|
||||
u_int32_t codata;
|
||||
codata = val + (addr << 8);
|
||||
FILE_LOG(logINFO, ("\tSetting ADC SPI Register. Wrote 0x%04x at 0x%04x\n", val, addr));
|
||||
serializeToSPI(AD9252_Reg, codata, AD9252_CsMask, AD9252_ADC_NUMBITS,
|
||||
AD9252_ClkMask, AD9252_DigMask, AD9252_DigOffset, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure
|
||||
*/
|
||||
void AD9252_Configure(){
|
||||
FILE_LOG(logINFOBLUE, ("Configuring ADC9252:\n"));
|
||||
|
||||
//power mode reset
|
||||
FILE_LOG(logINFO, ("\tPower mode reset\n"));
|
||||
AD9252_Set(AD9252_POWER_MODE_REG, AD9252_INT_RESET_VAL);
|
||||
|
||||
//power mode chip run
|
||||
FILE_LOG(logINFO, ("\tPower mode chip run\n"));
|
||||
AD9252_Set(AD9252_POWER_MODE_REG, AD9252_INT_CHIP_RUN_VAL);
|
||||
|
||||
// binary offset
|
||||
FILE_LOG(logINFO, ("\tBinary offset\n"));
|
||||
AD9252_Set(AD9252_OUT_MODE_REG, AD9252_OUT_BINARY_OFST_VAL);
|
||||
|
||||
//output clock phase
|
||||
#ifdef GOTTHARDD
|
||||
FILE_LOG(logINFO, ("\tOutput clock phase is at default: 180\n"));
|
||||
#else
|
||||
FILE_LOG(logINFO, ("\tOutput clock phase: 60\n"));
|
||||
AD9257_Set(AD9257_OUT_PHASE_REG, AD9257_OUT_CLK_60_VAL);
|
||||
#endif
|
||||
|
||||
// lvds-iee reduced , binary offset
|
||||
FILE_LOG(logINFO, ("\tLvds-iee reduced, binary offset\n"));
|
||||
AD9252_Set(AD9252_OUT_MODE_REG, AD9252_OUT_LVDS_IEEE_VAL);
|
||||
|
||||
// all devices on chip to receive next command
|
||||
FILE_LOG(logINFO, ("\tAll devices on chip to receive next command\n"));
|
||||
AD9252_Set(AD9252_DEV_IND_2_REG,
|
||||
AD9252_CHAN_H_MSK | AD9252_CHAN_G_MSK | AD9252_CHAN_F_MSK | AD9252_CHAN_E_MSK);
|
||||
AD9252_Set(AD9252_DEV_IND_1_REG,
|
||||
AD9252_CHAN_D_MSK | AD9252_CHAN_C_MSK | AD9252_CHAN_B_MSK | AD9252_CHAN_A_MSK |
|
||||
AD9252_CLK_CH_DCO_MSK | AD9252_CLK_CH_IFCO_MSK);
|
||||
|
||||
// no test mode
|
||||
FILE_LOG(logINFO, ("\tNo test mode\n"));
|
||||
AD9252_Set(AD9252_TEST_MODE_REG, AD9252_TST_OFF_VAL);
|
||||
|
||||
#ifdef TESTADC
|
||||
FILE_LOG(logINFOBLUE, ("Putting ADC in Test Mode!\n");
|
||||
// mixed bit frequency test mode
|
||||
FILE_LOG(logINFO, ("\tMixed bit frequency test mode\n"));
|
||||
AD9252_Set(AD9252_TEST_MODE_REG, AD9252_TST_MXD_BT_FRQ_VAL);
|
||||
#endif
|
||||
}
|
||||
|
||||
247
slsDetectorServers/slsDetectorServer/AD9257.h
Executable file
247
slsDetectorServers/slsDetectorServer/AD9257.h
Executable file
@@ -0,0 +1,247 @@
|
||||
#pragma once
|
||||
|
||||
#include "commonServerFunctions.h" // blackfin.h, ansi.h
|
||||
#ifdef GOTTHARDD
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
/* AD9257 ADC DEFINES */
|
||||
#define AD9257_ADC_NUMBITS (24)
|
||||
|
||||
// default value is 0xF
|
||||
#define AD9257_DEV_IND_2_REG (0x04)
|
||||
#define AD9257_CHAN_H_OFST (0)
|
||||
#define AD9257_CHAN_H_MSK (0x00000001 << AD9257_CHAN_H_OFST)
|
||||
#define AD9257_CHAN_G_OFST (1)
|
||||
#define AD9257_CHAN_G_MSK (0x00000001 << AD9257_CHAN_G_OFST)
|
||||
#define AD9257_CHAN_F_OFST (2)
|
||||
#define AD9257_CHAN_F_MSK (0x00000001 << AD9257_CHAN_F_OFST)
|
||||
#define AD9257_CHAN_E_OFST (3)
|
||||
#define AD9257_CHAN_E_MSK (0x00000001 << AD9257_CHAN_E_OFST)
|
||||
|
||||
// default value is 0x3F
|
||||
#define AD9257_DEV_IND_1_REG (0x05)
|
||||
#define AD9257_CHAN_D_OFST (0)
|
||||
#define AD9257_CHAN_D_MSK (0x00000001 << AD9257_CHAN_D_OFST)
|
||||
#define AD9257_CHAN_C_OFST (1)
|
||||
#define AD9257_CHAN_C_MSK (0x00000001 << AD9257_CHAN_C_OFST)
|
||||
#define AD9257_CHAN_B_OFST (2)
|
||||
#define AD9257_CHAN_B_MSK (0x00000001 << AD9257_CHAN_B_OFST)
|
||||
#define AD9257_CHAN_A_OFST (3)
|
||||
#define AD9257_CHAN_A_MSK (0x00000001 << AD9257_CHAN_A_OFST)
|
||||
#define AD9257_CLK_CH_DCO_OFST (4)
|
||||
#define AD9257_CLK_CH_DCO_MSK (0x00000001 << AD9257_CLK_CH_DCO_OFST)
|
||||
#define AD9257_CLK_CH_IFCO_OFST (5)
|
||||
#define AD9257_CLK_CH_IFCO_MSK (0x00000001 << AD9257_CLK_CH_IFCO_OFST)
|
||||
|
||||
// default value is 0x00
|
||||
#define AD9257_POWER_MODE_REG (0x08)
|
||||
#define AD9257_POWER_INTERNAL_OFST (0)
|
||||
#define AD9257_POWER_INTERNAL_MSK (0x00000003 << AD9257_POWER_INTERNAL_OFST)
|
||||
#define AD9257_INT_CHIP_RUN_VAL ((0x0 << AD9257_POWER_INTERNAL_OFST) & AD9257_POWER_INTERNAL_MSK)
|
||||
#define AD9257_INT_FULL_PWR_DWN_VAL ((0x1 << AD9257_POWER_INTERNAL_OFST) & AD9257_POWER_INTERNAL_MSK)
|
||||
#define AD9257_INT_STANDBY_VAL ((0x2 << AD9257_POWER_INTERNAL_OFST) & AD9257_POWER_INTERNAL_MSK)
|
||||
#define AD9257_INT_RESET_VAL ((0x3 << AD9257_POWER_INTERNAL_OFST) & AD9257_POWER_INTERNAL_MSK)
|
||||
#define AD9257_POWER_EXTERNAL_OFST (5)
|
||||
#define AD9257_POWER_EXTERNAL_MSK (0x00000001 << AD9257_POWER_EXTERNAL_OFST)
|
||||
#define AD9257_EXT_FULL_POWER_VAL ((0x0 << AD9257_POWER_EXTERNAL_OFST) & AD9257_POWER_EXTERNAL_MSK)
|
||||
#define AD9257_EXT_STANDBY_VAL ((0x1 << AD9257_POWER_EXTERNAL_OFST) & AD9257_POWER_EXTERNAL_MSK)
|
||||
|
||||
// default value is 0x0
|
||||
#define AD9257_TEST_MODE_REG (0x0D)
|
||||
#define AD9257_OUT_TEST_OFST (0)
|
||||
#define AD9257_OUT_TEST_MSK (0x0000000F << AD9257_OUT_TEST_OFST)
|
||||
#define AD9257_TST_OFF_VAL ((0x0 << AD9257_OUT_TEST_OFST) & AD9257_OUT_TEST_MSK)
|
||||
#define AD9257_TST_MDSCL_SHRT_VAL ((0x1 << AD9257_OUT_TEST_OFST) & AD9257_OUT_TEST_MSK)
|
||||
#define AD9257_TST_PSTV_FS_VAL ((0x2 << AD9257_OUT_TEST_OFST) & AD9257_OUT_TEST_MSK)
|
||||
#define AD9257_TST_NGTV_FS_VAL ((0x3 << AD9257_OUT_TEST_OFST) & AD9257_OUT_TEST_MSK)
|
||||
#define AD9257_TST_ALTRNTNG_CHKRBRD_VAL ((0x4 << AD9257_OUT_TEST_OFST) & AD9257_OUT_TEST_MSK)
|
||||
#define AD9257_TST_PN_23_SQNC_VAL ((0x5 << AD9257_OUT_TEST_OFST) & AD9257_OUT_TEST_MSK)
|
||||
#define AD9257_TST_PN_9_SQNC__VAL ((0x6 << AD9257_OUT_TEST_OFST) & AD9257_OUT_TEST_MSK)
|
||||
#define AD9257_TST_1_0_WRD_TGGL_VAL ((0x7 << AD9257_OUT_TEST_OFST) & AD9257_OUT_TEST_MSK)
|
||||
#define AD9257_TST_USR_INPT_VAL ((0x8 << AD9257_OUT_TEST_OFST) & AD9257_OUT_TEST_MSK)
|
||||
#define AD9257_TST_1_0_BT_TGGL_VAL ((0x9 << AD9257_OUT_TEST_OFST) & AD9257_OUT_TEST_MSK)
|
||||
#define AD9257_TST_1_x_SYNC_VAL ((0xa << AD9257_OUT_TEST_OFST) & AD9257_OUT_TEST_MSK)
|
||||
#define AD9257_TST_1_BIT_HGH_VAL ((0xb << AD9257_OUT_TEST_OFST) & AD9257_OUT_TEST_MSK)
|
||||
#define AD9257_TST_MXD_BT_FRQ_VAL ((0xc << AD9257_OUT_TEST_OFST) & AD9257_OUT_TEST_MSK)
|
||||
#define AD9257_TST_RST_SHRT_GN_OFST (4)
|
||||
#define AD9257_TST_RST_SHRT_GN_MSK (0x00000001 << AD9257_TST_RST_SHRT_GN_OFST)
|
||||
#define AD9257_TST_RST_LNG_GN_OFST (5)
|
||||
#define AD9257_TST_RST_LNG_GN_MSK (0x00000001 << AD9257_TST_RST_LNG_GN_OFST)
|
||||
#define AD9257_USER_IN_MODE_OFST (6)
|
||||
#define AD9257_USER_IN_MODE_MSK (0x00000003 << AD9257_USER_IN_MODE_OFST)
|
||||
#define AD9257_USR_IN_SNGL_VAL ((0x0 << AD9257_USER_IN_MODE_OFST) & AD9257_USER_IN_MODE_MSK)
|
||||
#define AD9257_USR_IN_ALTRNT_VAL ((0x1 << AD9257_USER_IN_MODE_OFST) & AD9257_USER_IN_MODE_MSK)
|
||||
#define AD9257_USR_IN_SNGL_ONC_VAL ((0x2 << AD9257_USER_IN_MODE_OFST) & AD9257_USER_IN_MODE_MSK)
|
||||
#define AD9257_USR_IN_ALTRNT_ONC_VAL ((0x3 << AD9257_USER_IN_MODE_OFST) & AD9257_USER_IN_MODE_MSK)
|
||||
|
||||
// default value is 0x01
|
||||
#define AD9257_OUT_MODE_REG (0x14)
|
||||
#define AD9257_OUT_FORMAT_OFST (0)
|
||||
#define AD9257_OUT_FORMAT_MSK (0x00000001 << AD9257_OUT_FORMAT_OFST)
|
||||
#define AD9257_OUT_BINARY_OFST_VAL ((0x0 << AD9257_OUT_FORMAT_OFST) & AD9257_OUT_FORMAT_MSK)
|
||||
#define AD9257_OUT_TWOS_COMPL_VAL ((0x1 << AD9257_OUT_FORMAT_OFST) & AD9257_OUT_FORMAT_MSK)
|
||||
#define AD9257_OUT_OTPT_INVRT_OFST (2)
|
||||
#define AD9257_OUT_OTPT_INVRT_MSK (0x00000001 << AD9257_OUT_OTPT_INVRT_OFST)
|
||||
#define AD9257_OUT_LVDS_OPT_OFST (6)
|
||||
#define AD9257_OUT_LVDS_OPT_MSK (0x00000001 << AD9257_OUT_LVDS_OPT_OFST)
|
||||
#define AD9257_OUT_LVDS_ANSI_VAL ((0x0 << AD9257_OUT_LVDS_OPT_OFST) & AD9257_OUT_LVDS_OPT_MSK)
|
||||
#define AD9257_OUT_LVDS_IEEE_VAL ((0x1 << AD9257_OUT_LVDS_OPT_OFST) & AD9257_OUT_LVDS_OPT_MSK)
|
||||
|
||||
// default value is 0x3
|
||||
#define AD9257_OUT_PHASE_REG (0x16)
|
||||
#define AD9257_OUT_CLK_OFST (0)
|
||||
#define AD9257_OUT_CLK_MSK (0x0000000F << AD9257_OUT_CLK_OFST)
|
||||
#define AD9257_OUT_CLK_0_VAL ((0x0 << AD9257_OUT_CLK_OFST) & AD9257_OUT_CLK_MSK)
|
||||
#define AD9257_OUT_CLK_60_VAL ((0x1 << AD9257_OUT_CLK_OFST) & AD9257_OUT_CLK_MSK)
|
||||
#define AD9257_OUT_CLK_120_VAL ((0x2 << AD9257_OUT_CLK_OFST) & AD9257_OUT_CLK_MSK)
|
||||
#define AD9257_OUT_CLK_180_VAL ((0x3 << AD9257_OUT_CLK_OFST) & AD9257_OUT_CLK_MSK)
|
||||
#define AD9257_OUT_CLK_240_VAL ((0x4 << AD9257_OUT_CLK_OFST) & AD9257_OUT_CLK_MSK)
|
||||
#define AD9257_OUT_CLK_300_VAL ((0x5 << AD9257_OUT_CLK_OFST) & AD9257_OUT_CLK_MSK)
|
||||
#define AD9257_OUT_CLK_360_VAL ((0x6 << AD9257_OUT_CLK_OFST) & AD9257_OUT_CLK_MSK)
|
||||
#define AD9257_OUT_CLK_420_VAL ((0x7 << AD9257_OUT_CLK_OFST) & AD9257_OUT_CLK_MSK)
|
||||
#define AD9257_OUT_CLK_480_VAL ((0x8 << AD9257_OUT_CLK_OFST) & AD9257_OUT_CLK_MSK)
|
||||
#define AD9257_OUT_CLK_540_VAL ((0x9 << AD9257_OUT_CLK_OFST) & AD9257_OUT_CLK_MSK)
|
||||
#define AD9257_OUT_CLK_600_VAL ((0xa << AD9257_OUT_CLK_OFST) & AD9257_OUT_CLK_MSK)
|
||||
#define AD9257_OUT_CLK_660_VAL ((0xb << AD9257_OUT_CLK_OFST) & AD9257_OUT_CLK_MSK)
|
||||
#define AD9257_IN_CLK_OFST (4)
|
||||
#define AD9257_IN_CLK_MSK (0x00000007 << AD9257_IN_CLK_OFST)
|
||||
#define AD9257_IN_CLK_0_VAL ((0x0 << AD9257_IN_CLK_OFST) & AD9257_IN_CLK_MSK)
|
||||
#define AD9257_IN_CLK_1_VAL ((0x1 << AD9257_IN_CLK_OFST) & AD9257_IN_CLK_MSK)
|
||||
#define AD9257_IN_CLK_2_VAL ((0x2 << AD9257_IN_CLK_OFST) & AD9257_IN_CLK_MSK)
|
||||
#define AD9257_IN_CLK_3_VAL ((0x3 << AD9257_IN_CLK_OFST) & AD9257_IN_CLK_MSK)
|
||||
#define AD9257_IN_CLK_4_VAL ((0x4 << AD9257_IN_CLK_OFST) & AD9257_IN_CLK_MSK)
|
||||
#define AD9257_IN_CLK_5_VAL ((0x5 << AD9257_IN_CLK_OFST) & AD9257_IN_CLK_MSK)
|
||||
#define AD9257_IN_CLK_6_VAL ((0x6 << AD9257_IN_CLK_OFST) & AD9257_IN_CLK_MSK)
|
||||
#define AD9257_IN_CLK_7_VAL ((0x7 << AD9257_IN_CLK_OFST) & AD9257_IN_CLK_MSK)
|
||||
|
||||
// default value is 0x4
|
||||
#define AD9257_VREF_REG (0x18)
|
||||
#define AD9257_VREF_OFST (0)
|
||||
#define AD9257_VREF_MSK (0x00000007 << AD9257_VREF_OFST)
|
||||
#define AD9257_VREF_1_0_VAL ((0x0 << AD9257_VREF_OFST) & AD9257_VREF_MSK)
|
||||
#define AD9257_VREF_1_14_VAL ((0x1 << AD9257_VREF_OFST) & AD9257_VREF_MSK)
|
||||
#define AD9257_VREF_1_33_VAL ((0x2 << AD9257_VREF_OFST) & AD9257_VREF_MSK)
|
||||
#define AD9257_VREF_1_6_VAL ((0x3 << AD9257_VREF_OFST) & AD9257_VREF_MSK)
|
||||
#define AD9257_VREF_2_0_VAL ((0x4 << AD9257_VREF_OFST) & AD9257_VREF_MSK)
|
||||
|
||||
uint32_t AD9257_Reg = 0x0;
|
||||
uint32_t AD9257_CsMask = 0x0;
|
||||
uint32_t AD9257_ClkMask = 0x0;
|
||||
uint32_t AD9257_DigMask = 0x0;
|
||||
int AD9257_DigOffset = 0x0;
|
||||
|
||||
/**
|
||||
* Set Defines
|
||||
* @param reg spi register
|
||||
* @param cmsk chip select mask
|
||||
* @param clkmsk clock output mask
|
||||
* @param dmsk digital output mask
|
||||
* @param dofst digital output offset
|
||||
*/
|
||||
void AD9257_SetDefines(uint32_t reg, uint32_t cmsk, uint32_t clkmsk, uint32_t dmsk, int dofst) {
|
||||
AD9257_Reg = reg;
|
||||
AD9257_CsMask = cmsk;
|
||||
AD9257_ClkMask = clkmsk;
|
||||
AD9257_DigMask = dmsk;
|
||||
AD9257_DigOffset = dofst;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable SPI
|
||||
*/
|
||||
void AD9257_Disable() {
|
||||
bus_w(AD9257_Reg, (bus_r(AD9257_Reg)
|
||||
| AD9257_CsMask
|
||||
| AD9257_ClkMask)
|
||||
& ~(AD9257_DigMask));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get max valid vref value
|
||||
* @param get max vref voltage unit (4 for 2.0V)
|
||||
*/
|
||||
int AD9257_GetMaxValidVref() {
|
||||
return 0x4;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set vref voltage
|
||||
* @param val voltage to be set (0 for 1.0V, 1 for 1.14V, 2 for 1.33V, 3 for 1.6V, 4 for 2.0V
|
||||
*/
|
||||
void AD9257_SetVrefVoltage(int val) {
|
||||
AD9257_Set(AD9257_VREF_REG, val);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set SPI reg value
|
||||
* @param codata value to be set
|
||||
*/
|
||||
void AD9257_Set(int addr, int val) {
|
||||
|
||||
u_int32_t codata;
|
||||
codata = val + (addr << 8);
|
||||
FILE_LOG(logINFO, ("\tSetting ADC SPI Register. Wrote 0x%04x at 0x%04x\n", val, addr));
|
||||
serializeToSPI(AD9257_Reg, codata, AD9257_CsMask, AD9257_ADC_NUMBITS,
|
||||
AD9257_ClkMask, AD9257_DigMask, AD9257_DigOffset, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure
|
||||
*/
|
||||
void AD9257_Configure(){
|
||||
FILE_LOG(logINFOBLUE, ("Configuring ADC9257:\n"));
|
||||
|
||||
//power mode reset
|
||||
FILE_LOG(logINFO, ("\tPower mode reset\n"));
|
||||
AD9257_Set(AD9257_POWER_MODE_REG, AD9257_INT_RESET_VAL);
|
||||
|
||||
//power mode chip run
|
||||
FILE_LOG(logINFO, ("\tPower mode chip run\n"));
|
||||
AD9257_Set(AD9257_POWER_MODE_REG, AD9257_INT_CHIP_RUN_VAL);
|
||||
|
||||
// binary offset
|
||||
FILE_LOG(logINFO, ("\tBinary offset\n"));
|
||||
AD9257_Set(AD9257_OUT_MODE_REG, AD9257_OUT_BINARY_OFST_VAL);
|
||||
|
||||
//output clock phase
|
||||
#if defined(GOTTHARDD) || defined(JUNGFRAUD)
|
||||
FILE_LOG(logINFO, ("\tOutput clock phase is at default: 180\n"));
|
||||
#else
|
||||
FILE_LOG(logINFO, ("\tOutput clock phase: 60\n"));
|
||||
AD9257_Set(AD9257_OUT_PHASE_REG, AD9257_OUT_CLK_60_VAL);
|
||||
#endif
|
||||
|
||||
// lvds-iee reduced , binary offset
|
||||
FILE_LOG(logINFO, ("\tLvds-iee reduced, binary offset\n"));
|
||||
AD9257_Set(AD9257_OUT_MODE_REG, AD9257_OUT_LVDS_IEEE_VAL);
|
||||
|
||||
// all devices on chip to receive next command
|
||||
FILE_LOG(logINFO, ("\tAll devices on chip to receive next command\n"));
|
||||
AD9257_Set(AD9257_DEV_IND_2_REG,
|
||||
AD9257_CHAN_H_MSK | AD9257_CHAN_G_MSK | AD9257_CHAN_F_MSK | AD9257_CHAN_E_MSK);
|
||||
|
||||
AD9257_Set(AD9257_DEV_IND_1_REG,
|
||||
AD9257_CHAN_D_MSK | AD9257_CHAN_C_MSK | AD9257_CHAN_B_MSK | AD9257_CHAN_A_MSK |
|
||||
AD9257_CLK_CH_DCO_MSK | AD9257_CLK_CH_IFCO_MSK);
|
||||
|
||||
// vref
|
||||
#ifdef GOTTHARDD
|
||||
FILE_LOG(logINFO, ("\tVref default at 2.0\n"));
|
||||
#else
|
||||
FILE_LOG(logINFO, ("\tVref 1.33\n"));
|
||||
AD9257_Set(AD9257_VREF_REG, AD9257_VREF_1_33_VAL);
|
||||
#endif
|
||||
|
||||
// no test mode
|
||||
FILE_LOG(logINFO, ("\tNo test mode\n"));
|
||||
AD9257_Set(AD9257_TEST_MODE_REG, AD9257_TST_OFF_VAL);
|
||||
|
||||
#ifdef TESTADC
|
||||
FILE_LOG(logINFOBLUE, ("Putting ADC in Test Mode!\n");
|
||||
// mixed bit frequency test mode
|
||||
FILE_LOG(logINFO, ("\tMixed bit frequency test mode\n"));
|
||||
AD9257_Set(AD9257_TEST_MODE_REG, AD9257_TST_MXD_BT_FRQ_VAL);
|
||||
#endif
|
||||
|
||||
}
|
||||
240
slsDetectorServers/slsDetectorServer/ALTERA_PLL.h
Executable file
240
slsDetectorServers/slsDetectorServer/ALTERA_PLL.h
Executable file
@@ -0,0 +1,240 @@
|
||||
#pragma once
|
||||
|
||||
#include <unistd.h> // usleep
|
||||
|
||||
/* Altera PLL DEFINES */
|
||||
|
||||
/** PLL Reconfiguration Registers */
|
||||
//https://www.altera.com/documentation/mcn1424769382940.html
|
||||
#define ALTERA_PLL_MODE_REG (0x00)
|
||||
|
||||
#define ALTERA_PLL_MODE_WT_RQUST_VAL (0)
|
||||
#define ALTERA_PLL_MODE_PLLNG_MD_VAL (1)
|
||||
|
||||
#define ALTERA_PLL_STATUS_REG (0x01)
|
||||
#define ALTERA_PLL_START_REG (0x02)
|
||||
#define ALTERA_PLL_N_COUNTER_REG (0x03)
|
||||
#define ALTERA_PLL_M_COUNTER_REG (0x04)
|
||||
#define ALTERA_PLL_C_COUNTER_REG (0x05)
|
||||
|
||||
#define ALTERA_PLL_C_COUNTER_LW_CNT_OFST (0)
|
||||
#define ALTERA_PLL_C_COUNTER_LW_CNT_MSK (0x000000FF << ALTERA_PLL_C_COUNTER_LW_CNT_OFST)
|
||||
#define ALTERA_PLL_C_COUNTER_HGH_CNT_OFST (8)
|
||||
#define ALTERA_PLL_C_COUNTER_HGH_CNT_MSK (0x000000FF << ALTERA_PLL_C_COUNTER_HGH_CNT_OFST)
|
||||
/* total_div = lw_cnt + hgh_cnt */
|
||||
#define ALTERA_PLL_C_COUNTER_BYPSS_ENBL_OFST (16)
|
||||
#define ALTERA_PLL_C_COUNTER_BYPSS_ENBL_MSK (0x00000001 << ALTERA_PLL_C_COUNTER_BYPSS_ENBL_OFST)
|
||||
/* if bypss_enbl = 0, fout = f(vco)/total_div; else fout = f(vco) (c counter is bypassed) */
|
||||
#define ALTERA_PLL_C_COUNTER_ODD_DVSN_OFST (17)
|
||||
#define ALTERA_PLL_C_COUNTER_ODD_DVSN_MSK (0x00000001 << ALTERA_PLL_C_COUNTER_ODD_DVSN_OFST)
|
||||
/** if odd_dvsn = 0 (even), duty cycle = hgh_cnt/ total_div; else duty cycle = (hgh_cnt - 0.5) / total_div */
|
||||
#define ALTERA_PLL_C_COUNTER_SLCT_OFST (18)
|
||||
#define ALTERA_PLL_C_COUNTER_SLCT_MSK (0x0000001F << ALTERA_PLL_C_COUNTER_SLCT_OFST)
|
||||
|
||||
#define ALTERA_PLL_PHASE_SHIFT_REG (0x06)
|
||||
|
||||
#define ALTERA_PLL_SHIFT_NUM_SHIFTS_OFST (0)
|
||||
#define ALTERA_PLL_SHIFT_NUM_SHIFTS_MSK (0x0000FFFF << ALTERA_PLL_SHIFT_NUM_SHIFTS_OFST)
|
||||
|
||||
#define ALTERA_PLL_SHIFT_CNT_SELECT_OFST (16)
|
||||
#define ALTERA_PLL_SHIFT_CNT_SELECT_MSK (0x0000001F << ALTERA_PLL_SHIFT_CNT_SELECT_OFST)
|
||||
#define ALTERA_PLL_SHIFT_CNT_SLCT_C0_VAL ((0x0 << ALTERA_PLL_SHIFT_CNT_SELECT_OFST) & ALTERA_PLL_SHIFT_CNT_SELECT_MSK)
|
||||
#define ALTERA_PLL_SHIFT_CNT_SLCT_C1_VAL ((0x1 << ALTERA_PLL_SHIFT_CNT_SELECT_OFST) & ALTERA_PLL_SHIFT_CNT_SELECT_MSK)
|
||||
#define ALTERA_PLL_SHIFT_CNT_SLCT_C2_VAL ((0x2 << ALTERA_PLL_SHIFT_CNT_SELECT_OFST) & ALTERA_PLL_SHIFT_CNT_SELECT_MSK)
|
||||
#define ALTERA_PLL_SHIFT_CNT_SLCT_C3_VAL ((0x3 << ALTERA_PLL_SHIFT_CNT_SELECT_OFST) & ALTERA_PLL_SHIFT_CNT_SELECT_MSK)
|
||||
#define ALTERA_PLL_SHIFT_CNT_SLCT_C4_VAL ((0x4 << ALTERA_PLL_SHIFT_CNT_SELECT_OFST) & ALTERA_PLL_SHIFT_CNT_SELECT_MSK)
|
||||
#define ALTERA_PLL_SHIFT_CNT_SLCT_C5_VAL ((0x5 << ALTERA_PLL_SHIFT_CNT_SELECT_OFST) & ALTERA_PLL_SHIFT_CNT_SELECT_MSK)
|
||||
#define ALTERA_PLL_SHIFT_CNT_SLCT_C6_VAL ((0x6 << ALTERA_PLL_SHIFT_CNT_SELECT_OFST) & ALTERA_PLL_SHIFT_CNT_SELECT_MSK)
|
||||
#define ALTERA_PLL_SHIFT_CNT_SLCT_C7_VAL ((0x7 << ALTERA_PLL_SHIFT_CNT_SELECT_OFST) & ALTERA_PLL_SHIFT_CNT_SELECT_MSK)
|
||||
#define ALTERA_PLL_SHIFT_CNT_SLCT_C8_VAL ((0x8 << ALTERA_PLL_SHIFT_CNT_SELECT_OFST) & ALTERA_PLL_SHIFT_CNT_SELECT_MSK)
|
||||
#define ALTERA_PLL_SHIFT_CNT_SLCT_C9_VAL ((0x9 << ALTERA_PLL_SHIFT_CNT_SELECT_OFST) & ALTERA_PLL_SHIFT_CNT_SELECT_MSK)
|
||||
#define ALTERA_PLL_SHIFT_CNT_SLCT_C10_VAL ((0x10 << ALTERA_PLL_SHIFT_CNT_SELECT_OFST) & ALTERA_PLL_SHIFT_CNT_SELECT_MSK)
|
||||
#define ALTERA_PLL_SHIFT_CNT_SLCT_C11_VAL ((0x11 << ALTERA_PLL_SHIFT_CNT_SELECT_OFST) & ALTERA_PLL_SHIFT_CNT_SELECT_MSK)
|
||||
#define ALTERA_PLL_SHIFT_CNT_SLCT_C12_VAL ((0x12 << ALTERA_PLL_SHIFT_CNT_SELECT_OFST) & ALTERA_PLL_SHIFT_CNT_SELECT_MSK)
|
||||
#define ALTERA_PLL_SHIFT_CNT_SLCT_C13_VAL ((0x13 << ALTERA_PLL_SHIFT_CNT_SELECT_OFST) & ALTERA_PLL_SHIFT_CNT_SELECT_MSK)
|
||||
#define ALTERA_PLL_SHIFT_CNT_SLCT_C14_VAL ((0x14 << ALTERA_PLL_SHIFT_CNT_SELECT_OFST) & ALTERA_PLL_SHIFT_CNT_SELECT_MSK)
|
||||
#define ALTERA_PLL_SHIFT_CNT_SLCT_C15_VAL ((0x15 << ALTERA_PLL_SHIFT_CNT_SELECT_OFST) & ALTERA_PLL_SHIFT_CNT_SELECT_MSK)
|
||||
#define ALTERA_PLL_SHIFT_CNT_SLCT_C16_VAL ((0x16 << ALTERA_PLL_SHIFT_CNT_SELECT_OFST) & ALTERA_PLL_SHIFT_CNT_SELECT_MSK)
|
||||
#define ALTERA_PLL_SHIFT_CNT_SLCT_C17_VAL ((0x17 << ALTERA_PLL_SHIFT_CNT_SELECT_OFST) & ALTERA_PLL_SHIFT_CNT_SELECT_MSK)
|
||||
|
||||
#define ALTERA_PLL_SHIFT_UP_DOWN_OFST (21)
|
||||
#define ALTERA_PLL_SHIFT_UP_DOWN_MSK (0x00000001 << ALTERA_PLL_SHIFT_UP_DOWN_OFST)
|
||||
#define ALTERA_PLL_SHIFT_UP_DOWN_NEG_VAL ((0x0 << ALTERA_PLL_SHIFT_UP_DOWN_OFST) & ALTERA_PLL_SHIFT_UP_DOWN_MSK)
|
||||
#define ALTERA_PLL_SHIFT_UP_DOWN_POS_VAL ((0x1 << ALTERA_PLL_SHIFT_UP_DOWN_OFST) & ALTERA_PLL_SHIFT_UP_DOWN_MSK)
|
||||
|
||||
#define ALTERA_PLL_K_COUNTER_REG (0x07)
|
||||
#define ALTERA_PLL_BANDWIDTH_REG (0x08)
|
||||
#define ALTERA_PLL_CHARGEPUMP_REG (0x09)
|
||||
#define ALTERA_PLL_VCO_DIV_REG (0x1c)
|
||||
#define ALTERA_PLL_MIF_REG (0x1f)
|
||||
|
||||
|
||||
#define ALTERA_PLL_WAIT_TIME_US (10 * 1000)
|
||||
|
||||
|
||||
uint32_t ALTERA_PLL_Cntrl_Reg = 0x0;
|
||||
uint32_t ALTERA_PLL_Param_Reg = 0x0;
|
||||
uint32_t ALTERA_PLL_Cntrl_RcnfgPrmtrRstMask = 0x0;
|
||||
uint32_t ALTERA_PLL_Cntrl_WrPrmtrMask = 0x0;
|
||||
uint32_t ALTERA_PLL_Cntrl_PLLRstMask = 0x0;
|
||||
uint32_t ALTERA_PLL_Cntrl_AddrMask = 0x0;
|
||||
int ALTERA_PLL_Cntrl_AddrOfst = 0;
|
||||
|
||||
|
||||
/**
|
||||
* Set Defines
|
||||
* @param creg control register
|
||||
* @param preg parameter register
|
||||
* @param rprmsk reconfig parameter reset mask
|
||||
* @param wpmsk write parameter mask
|
||||
* @param prmsk pll reset mask
|
||||
* @param amsk address mask
|
||||
* @param aofst address offset
|
||||
*/
|
||||
void ALTERA_PLL_SetDefines(uint32_t creg, uint32_t preg, uint32_t rprmsk, uint32_t wpmsk, uint32_t prmsk, uint32_t amsk, int aofst) {
|
||||
ALTERA_PLL_Cntrl_Reg = creg;
|
||||
ALTERA_PLL_Param_Reg = preg;
|
||||
ALTERA_PLL_Cntrl_RcnfgPrmtrRstMask = rprmsk;
|
||||
ALTERA_PLL_Cntrl_WrPrmtrMask = wpmsk;
|
||||
ALTERA_PLL_Cntrl_PLLRstMask = prmsk;
|
||||
ALTERA_PLL_Cntrl_AddrMask = amsk;
|
||||
ALTERA_PLL_Cntrl_AddrOfst = aofst;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset only PLL
|
||||
*/
|
||||
void ALTERA_PLL_ResetPLL () {
|
||||
FILE_LOG(logINFO, ("Resetting only PLL\n"));
|
||||
|
||||
FILE_LOG(logDEBUG2, ("pllrstmsk:0x%x\n", ALTERA_PLL_Cntrl_PLLRstMask));
|
||||
|
||||
bus_w(ALTERA_PLL_Cntrl_Reg, bus_r(ALTERA_PLL_Cntrl_Reg) | ALTERA_PLL_Cntrl_PLLRstMask);
|
||||
FILE_LOG(logDEBUG2, ("Set PLL Reset mSk: ALTERA_PLL_Cntrl_Reg:0x%x\n", bus_r(ALTERA_PLL_Cntrl_Reg)));
|
||||
|
||||
usleep(ALTERA_PLL_WAIT_TIME_US);
|
||||
|
||||
bus_w(ALTERA_PLL_Cntrl_Reg, bus_r(ALTERA_PLL_Cntrl_Reg) & ~ALTERA_PLL_Cntrl_PLLRstMask);
|
||||
FILE_LOG(logDEBUG2, ("UnSet PLL Reset mSk: ALTERA_PLL_Cntrl_Reg:0x%x\n", bus_r(ALTERA_PLL_Cntrl_Reg)));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset PLL Reconfiguration and PLL
|
||||
*/
|
||||
void ALTERA_PLL_ResetPLLAndReconfiguration () {
|
||||
FILE_LOG(logINFO, ("Resetting PLL and Reconfiguration\n"));
|
||||
|
||||
bus_w(ALTERA_PLL_Cntrl_Reg, bus_r(ALTERA_PLL_Cntrl_Reg) | ALTERA_PLL_Cntrl_RcnfgPrmtrRstMask | ALTERA_PLL_Cntrl_PLLRstMask);
|
||||
usleep(ALTERA_PLL_WAIT_TIME_US);
|
||||
bus_w(ALTERA_PLL_Cntrl_Reg, bus_r(ALTERA_PLL_Cntrl_Reg) & ~ALTERA_PLL_Cntrl_RcnfgPrmtrRstMask & ~ALTERA_PLL_Cntrl_PLLRstMask);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set PLL Reconfig register
|
||||
* @param reg register
|
||||
* @param val value
|
||||
*/
|
||||
void ALTERA_PLL_SetPllReconfigReg(uint32_t reg, uint32_t val) {
|
||||
FILE_LOG(logDEBUG1, ("Setting PLL Reconfig Reg, reg:0x%x, val:0x%x)\n", reg, val));
|
||||
|
||||
FILE_LOG(logDEBUG2, ("pllparamreg:0x%x pllcontrolreg:0x%x addrofst:%d addrmsk:0x%x wrmask:0x%x\n",
|
||||
ALTERA_PLL_Param_Reg, ALTERA_PLL_Cntrl_Reg, ALTERA_PLL_Cntrl_AddrOfst, ALTERA_PLL_Cntrl_AddrMask, ALTERA_PLL_Cntrl_WrPrmtrMask));
|
||||
|
||||
// set parameter
|
||||
bus_w(ALTERA_PLL_Param_Reg, val);
|
||||
FILE_LOG(logDEBUG2, ("Set Parameter: ALTERA_PLL_Param_Reg:0x%x\n", bus_r(ALTERA_PLL_Param_Reg)));
|
||||
usleep(ALTERA_PLL_WAIT_TIME_US);
|
||||
|
||||
// set address
|
||||
bus_w(ALTERA_PLL_Cntrl_Reg, (reg << ALTERA_PLL_Cntrl_AddrOfst) & ALTERA_PLL_Cntrl_AddrMask);
|
||||
FILE_LOG(logDEBUG2, ("Set Address: ALTERA_PLL_Cntrl_Reg:0x%x\n", bus_r(ALTERA_PLL_Cntrl_Reg)));
|
||||
usleep(ALTERA_PLL_WAIT_TIME_US);
|
||||
|
||||
//write parameter
|
||||
bus_w(ALTERA_PLL_Cntrl_Reg, bus_r(ALTERA_PLL_Cntrl_Reg) | ALTERA_PLL_Cntrl_WrPrmtrMask);
|
||||
FILE_LOG(logDEBUG2, ("Set WR bit: ALTERA_PLL_Cntrl_Reg:0x%x\n", bus_r(ALTERA_PLL_Cntrl_Reg)));
|
||||
|
||||
usleep(ALTERA_PLL_WAIT_TIME_US);
|
||||
|
||||
bus_w(ALTERA_PLL_Cntrl_Reg, bus_r(ALTERA_PLL_Cntrl_Reg) & ~ALTERA_PLL_Cntrl_WrPrmtrMask);
|
||||
FILE_LOG(logDEBUG2, ("Unset WR bit: ALTERA_PLL_Cntrl_Reg:0x%x\n", bus_r(ALTERA_PLL_Cntrl_Reg)));
|
||||
|
||||
usleep(ALTERA_PLL_WAIT_TIME_US);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write Phase Shift
|
||||
* @param phase phase shift
|
||||
* @param clkIndex clock index
|
||||
* @param pos 1 if up down direction of shift is positive, else 0
|
||||
*/
|
||||
void ALTERA_PLL_SetPhaseShift(int32_t phase, int clkIndex, int pos) {
|
||||
FILE_LOG(logINFO, ("\tWriting PLL Phase Shift\n"));
|
||||
uint32_t value = (((phase << ALTERA_PLL_SHIFT_NUM_SHIFTS_OFST) & ALTERA_PLL_SHIFT_NUM_SHIFTS_MSK) |
|
||||
((clkIndex << ALTERA_PLL_SHIFT_CNT_SELECT_OFST) & ALTERA_PLL_SHIFT_CNT_SELECT_MSK) |
|
||||
(pos ? ALTERA_PLL_SHIFT_UP_DOWN_POS_VAL : ALTERA_PLL_SHIFT_UP_DOWN_NEG_VAL));
|
||||
|
||||
FILE_LOG(logDEBUG1, ("C%d phase word:0x%08x\n", clkIndex, value));
|
||||
|
||||
// write phase shift
|
||||
ALTERA_PLL_SetPllReconfigReg(ALTERA_PLL_PHASE_SHIFT_REG, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set PLL mode register to polling mode
|
||||
*/
|
||||
void ALTERA_PLL_SetModePolling() {
|
||||
FILE_LOG(logINFO, ("\tSetting Polling Mode\n"));
|
||||
ALTERA_PLL_SetPllReconfigReg(ALTERA_PLL_MODE_REG, ALTERA_PLL_MODE_PLLNG_MD_VAL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate and write output frequency
|
||||
* @param clkIndex clock index
|
||||
* @param pllVCOFreqMhz PLL VCO Frequency in Mhz
|
||||
* @param value frequency to set to
|
||||
* @param frequency set
|
||||
*/
|
||||
int ALTERA_PLL_SetOuputFrequency (int clkIndex, int pllVCOFreqMhz, int value) {
|
||||
FILE_LOG(logDEBUG1, ("C%d: Setting output frequency to %d (pllvcofreq: %dMhz)\n", clkIndex, value, pllVCOFreqMhz));
|
||||
|
||||
// calculate output frequency
|
||||
float total_div = (float)pllVCOFreqMhz / (float)value;
|
||||
|
||||
// assume 50% duty cycle
|
||||
uint32_t low_count = total_div / 2;
|
||||
uint32_t high_count = low_count;
|
||||
uint32_t odd_division = 0;
|
||||
|
||||
// odd division
|
||||
if (total_div > (float)(2 * low_count)) {
|
||||
++high_count;
|
||||
odd_division = 1;
|
||||
}
|
||||
FILE_LOG(logINFO, ("\tC%d: Low:%d, High:%d, Odd:%d\n", clkIndex, low_count, high_count, odd_division));
|
||||
|
||||
// command to set output frequency
|
||||
uint32_t val = (((low_count << ALTERA_PLL_C_COUNTER_LW_CNT_OFST) & ALTERA_PLL_C_COUNTER_LW_CNT_MSK) |
|
||||
((high_count << ALTERA_PLL_C_COUNTER_HGH_CNT_OFST) & ALTERA_PLL_C_COUNTER_HGH_CNT_MSK) |
|
||||
((odd_division << ALTERA_PLL_C_COUNTER_ODD_DVSN_OFST) & ALTERA_PLL_C_COUNTER_ODD_DVSN_MSK) |
|
||||
((clkIndex << ALTERA_PLL_C_COUNTER_SLCT_OFST) & ALTERA_PLL_C_COUNTER_SLCT_MSK));
|
||||
FILE_LOG(logDEBUG1, ("C%d word:0x%08x\n", clkIndex, val));
|
||||
|
||||
// write frequency (post-scale output counter C)
|
||||
ALTERA_PLL_SetPllReconfigReg(ALTERA_PLL_C_COUNTER_REG, val);
|
||||
|
||||
// reset required to keep the phase
|
||||
ALTERA_PLL_ResetPLL ();
|
||||
|
||||
/*double temp = ((double)pllVCOFreqMhz / (double)(low_count + high_count));
|
||||
if ((temp - (int)temp) > 0.0001) {
|
||||
temp += 0.5;
|
||||
}
|
||||
return (int)temp;
|
||||
*/
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
262
slsDetectorServers/slsDetectorServer/I2C.h
Executable file
262
slsDetectorServers/slsDetectorServer/I2C.h
Executable file
@@ -0,0 +1,262 @@
|
||||
#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)
|
||||
* I2C_CLOCK_MHZ
|
||||
*
|
||||
* (RegisterDefs.h)
|
||||
* I2C_SCL_LOW_COUNT_REG
|
||||
* 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
|
||||
*/
|
||||
|
||||
|
||||
#define I2C_DATA_RATE_KBPS (200)
|
||||
|
||||
/** Control Register */
|
||||
#define I2C_CTRL_ENBLE_CORE_OFST (0)
|
||||
#define I2C_CTRL_ENBLE_CORE_MSK (0x00000001 << I2C_CTRL_ENBLE_CORE_OFST)
|
||||
#define I2C_CTRL_BUS_SPEED_OFST (1)
|
||||
#define I2C_CTRL_BUS_SPEED_MSK (0x00000001 << I2C_CTRL_BUS_SPEED_OFST)
|
||||
#define I2C_CTRL_BUS_SPEED_STNDRD_100_VAL ((0x0 << I2C_CTRL_BUS_SPEED_OFST) & I2C_CTRL_BUS_SPEED_MSK) // standard mode (up to 100 kbps)
|
||||
#define I2C_CTRL_BUS_SPEED_FAST_400_VAL ((0x1 << I2C_CTRL_BUS_SPEED_OFST) & I2C_CTRL_BUS_SPEED_MSK) // fast mode (up to 400 kbps)
|
||||
/** if actual level of transfer command fifo <= thd level, TX_READY interrupt asserted */
|
||||
#define I2C_CTRL_TFR_CMD_FIFO_THD_OFST (2)
|
||||
#define I2C_CTRL_TFR_CMD_FIFO_THD_MSK (0x00000003 << I2C_CTRL_TFR_CMD_FIFO_THD_OFST)
|
||||
#define I2C_CTRL_TFR_CMD_EMPTY_VAL ((0x0 << I2C_CTRL_TFR_CMD_FIFO_THD_OFST) & I2C_CTRL_TFR_CMD_FIFO_THD_MSK)
|
||||
#define I2C_CTRL_TFR_CMD_ONE_FOURTH_VAL ((0x1 << I2C_CTRL_TFR_CMD_FIFO_THD_OFST) & I2C_CTRL_TFR_CMD_FIFO_THD_MSK)
|
||||
#define I2C_CTRL_TFR_CMD_ONE_HALF_VAL ((0x2 << I2C_CTRL_TFR_CMD_FIFO_THD_OFST) & I2C_CTRL_TFR_CMD_FIFO_THD_MSK)
|
||||
#define I2C_CTRL_TFR_CMD_NOT_FULL_VAL ((0x3 << I2C_CTRL_TFR_CMD_FIFO_THD_OFST) & I2C_CTRL_TFR_CMD_FIFO_THD_MSK)
|
||||
/** if actual level of receive data fifo <= thd level, RX_READY interrupt asserted */
|
||||
#define I2C_CTRL_RX_DATA_FIFO_THD_OFST (4)
|
||||
#define I2C_CTRL_RX_DATA_FIFO_THD_MSK (0x00000003 << I2C_CTRL_RX_DATA_FIFO_THD_OFST)
|
||||
#define I2C_CTRL_RX_DATA_1_VALID_ENTRY_VAL ((0x0 << I2C_CTRL_RX_DATA_FIFO_THD_OFST) & I2C_CTRL_RX_DATA_FIFO_THD_MSK)
|
||||
#define I2C_CTRL_RX_DATA_ONE_FOURTH_VAL ((0x1 << I2C_CTRL_RX_DATA_FIFO_THD_OFST) & I2C_CTRL_RX_DATA_FIFO_THD_MSK)
|
||||
#define I2C_CTRL_RX_DATA_ONE_HALF_VAL ((0x2 << I2C_CTRL_RX_DATA_FIFO_THD_OFST) & I2C_CTRL_RX_DATA_FIFO_THD_MSK)
|
||||
#define I2C_CTRL_RX_DATA_FULL_VAL ((0x3 << I2C_CTRL_RX_DATA_FIFO_THD_OFST) & I2C_CTRL_RX_DATA_FIFO_THD_MSK)
|
||||
|
||||
/** Transfer Command Fifo register */
|
||||
#define I2C_TFR_CMD_RW_OFST (0)
|
||||
#define I2C_TFR_CMD_RW_MSK (0x00000001 << I2C_TFR_CMD_RW_OFST)
|
||||
#define I2C_TFR_CMD_RW_WRITE_VAL ((0x0 << I2C_TFR_CMD_RW_OFST) & I2C_TFR_CMD_RW_MSK)
|
||||
#define I2C_TFR_CMD_RW_READ_VAL ((0x1 << I2C_TFR_CMD_RW_OFST) & I2C_TFR_CMD_RW_MSK)
|
||||
#define I2C_TFR_CMD_ADDR_OFST (1)
|
||||
#define I2C_TFR_CMD_ADDR_MSK (0x0000007F << I2C_TFR_CMD_ADDR_OFST)
|
||||
/** when writing, rw and addr converts to data to be written mask */
|
||||
#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_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;
|
||||
uint32_t I2C_Sda_Hold_Reg = 0x0;
|
||||
uint32_t I2C_Transfer_Command_Fifo_Reg = 0x0;
|
||||
|
||||
/**
|
||||
* Configure the I2C core,
|
||||
* Enable core and
|
||||
* Calibrate the calibration register for current readout
|
||||
* @param creg control 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 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_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 * 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)
|
||||
uint32_t sclLowPeriodCount = (sclLowPeriodNs / 1000.00) * I2C_CLOCK_MHZ;
|
||||
|
||||
// calculate sda hold data count
|
||||
uint32_t sdaDataHoldTimeNs = (sclLowPeriodNs / 2); // scl low period same as high period
|
||||
// convert to us, then to clock (defined in blackfin.h)
|
||||
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, 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, 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, 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 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).
|
||||
}
|
||||
|
||||
/**
|
||||
* Read register
|
||||
* @param deviceId device Id
|
||||
* @param addr register address
|
||||
* @returns value read from register
|
||||
*/
|
||||
uint32_t I2C_Read(uint32_t devId, uint32_t addr) {
|
||||
FILE_LOG(logDEBUG2, (" ================================================\n"));
|
||||
FILE_LOG(logDEBUG2, (" 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(logDEBUG2, (" devId:0x%x\n", devIdMask));
|
||||
|
||||
// write I2C ID
|
||||
bus_w(I2C_Transfer_Command_Fifo_Reg, (devIdMask & ~(I2C_TFR_CMD_RW_MSK)));
|
||||
FILE_LOG(logDEBUG2, (" 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(logDEBUG2, (" write addr:0x%x\n", addr));
|
||||
|
||||
// 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(logDEBUG2, (" 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(logDEBUG2, (" continue reading:0x%x\n", 0x0));
|
||||
|
||||
// stop reading
|
||||
bus_w(I2C_Transfer_Command_Fifo_Reg, I2C_TFR_CMD_STOP_MSK);
|
||||
FILE_LOG(logDEBUG2, (" stop reading:0x%x\n", I2C_TFR_CMD_STOP_MSK));
|
||||
|
||||
// read value
|
||||
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(logDEBUG2, (" 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(logDEBUG2, (" 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(logDEBUG2, (" byte nr %d:0x%x\n", iloop, byte));
|
||||
// push by 1 byte at a time
|
||||
retval |= (byte << (8 * iloop));
|
||||
}
|
||||
FILE_LOG(logDEBUG2, (" retval:0x%x\n", retval));
|
||||
FILE_LOG(logDEBUG2, (" ================================================\n"));
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write register (16 bit value)
|
||||
* @param deviceId device Id
|
||||
* @param addr register address
|
||||
* @param data data to be written (16 bit)
|
||||
*/
|
||||
void I2C_Write(uint32_t devId, uint32_t addr, uint16_t data) {
|
||||
FILE_LOG(logDEBUG2, (" ================================================\n"));
|
||||
FILE_LOG(logDEBUG2, (" 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(logDEBUG2, (" devId:0x%x\n", devId));
|
||||
|
||||
// write I2C ID
|
||||
bus_w(I2C_Transfer_Command_Fifo_Reg, (devIdMask & ~(I2C_TFR_CMD_RW_MSK)));
|
||||
FILE_LOG(logDEBUG2, (" 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(logDEBUG2, (" write addr:0x%x\n", addr));
|
||||
|
||||
// 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(logDEBUG2, (" 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(logDEBUG2, (" 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(logDEBUG2, (" 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(logDEBUG2, (" ================================================\n"));
|
||||
}
|
||||
|
||||
|
||||
180
slsDetectorServers/slsDetectorServer/INA226.h
Executable file
180
slsDetectorServers/slsDetectorServer/INA226.h
Executable file
@@ -0,0 +1,180 @@
|
||||
#pragma once
|
||||
|
||||
#include "I2C.h"
|
||||
#include "math.h"
|
||||
|
||||
/**
|
||||
* To be defined in
|
||||
*
|
||||
* (slsDetectorServer_defs.h)
|
||||
* I2C_SHUNT_RESISTER_OHMS
|
||||
* device ids that are passed as arguments
|
||||
*/
|
||||
|
||||
/** INA226 defines */
|
||||
|
||||
/** Register set */
|
||||
#define INA226_CONFIGURATION_REG (0x00) //R/W
|
||||
#define INA226_SHUNT_VOLTAGE_REG (0x01) //R
|
||||
#define INA226_BUS_VOLTAGE_REG (0x02) //R
|
||||
#define INA226_POWER_REG (0x03) //R
|
||||
#define INA226_CURRENT_REG (0x04) //R
|
||||
#define INA226_CALIBRATION_REG (0x05) //R/W
|
||||
#define INA226_MASK_ENABLE_REG (0x06) //R/W
|
||||
#define INA226_ALERT_LIMIT_REG (0x07) //R/W
|
||||
#define INA226_MANUFACTURER_ID_REG (0xFE) //R
|
||||
#define INA226_DIE_ID_REG (0xFF) //R
|
||||
|
||||
/** bus voltage register */
|
||||
#define INA226_BUS_VOLTAGE_VMIN_UV (1250) // 1.25mV
|
||||
#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
|
||||
|
||||
|
||||
/** 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
|
||||
|
||||
/** calibration register */
|
||||
#define INA226_CALIBRATION_MSK (0x7FFF)
|
||||
|
||||
/** get calibration register value to be set */
|
||||
#define INA226_getCalibrationValue(rOhm) (0.00512 /(INA226_CURRENT_IMIN_UA * 1e-6 * rOhm))
|
||||
|
||||
/** get current unit */
|
||||
#define INA226_getConvertedCurrentUnits(shuntV, calibReg) ((double)shuntV * (double)calibReg / (double)2048)
|
||||
|
||||
double INA226_Shunt_Resistor_Ohm = 0.0;
|
||||
int INA226_Calibration_Register_Value = 0;
|
||||
|
||||
#define INA226_CALIBRATION_CURRENT_TOLERANCE (1.2268)
|
||||
|
||||
|
||||
/**
|
||||
* 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 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 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, sreg, rreg, rlvlreg, slreg, shreg, sdreg, treg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calibrate resolution of current register
|
||||
* @param deviceId device Id (defined in slsDetectorServer_defs.h)
|
||||
*/
|
||||
void INA226_CalibrateCurrentRegister(uint32_t deviceId) {
|
||||
FILE_LOG(logINFO, ("Calibrating Current Register for Device ID: 0x%x\n", deviceId));
|
||||
// get calibration value based on shunt resistor
|
||||
uint16_t calVal = ((uint16_t)INA226_getCalibrationValue(INA226_Shunt_Resistor_Ohm)) & INA226_CALIBRATION_MSK;
|
||||
FILE_LOG(logINFO, ("\tCalculated calibration reg value: 0x%0x (%d)\n", calVal, calVal));
|
||||
|
||||
calVal = ((double)calVal / INA226_CALIBRATION_CURRENT_TOLERANCE) + 0.5;
|
||||
FILE_LOG(logINFO, ("\tRealculated (for tolerance) calibration reg value: 0x%0x (%d)\n", calVal, calVal));
|
||||
INA226_Calibration_Register_Value = calVal;
|
||||
|
||||
// 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));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Read voltage of device
|
||||
* @param deviceId device Id
|
||||
* @returns voltage in mV
|
||||
*/
|
||||
int INA226_ReadVoltage(uint32_t deviceId) {
|
||||
FILE_LOG(logDEBUG1, (" Reading voltage\n"));
|
||||
uint32_t regval = I2C_Read(deviceId, INA226_BUS_VOLTAGE_REG);
|
||||
FILE_LOG(logDEBUG1, (" bus voltage reg: 0x%08x\n", regval));
|
||||
|
||||
// value in uV
|
||||
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
|
||||
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 voltagemV;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read current
|
||||
* @param deviceId device Id
|
||||
* @returns current in mA
|
||||
*/
|
||||
int INA226_ReadCurrent(uint32_t deviceId) {
|
||||
FILE_LOG(logDEBUG1, (" Reading current\n"));
|
||||
|
||||
// read shunt voltage register
|
||||
FILE_LOG(logDEBUG1, (" Reading shunt voltage reg\n"));
|
||||
uint32_t shuntVoltageRegVal = I2C_Read(deviceId, INA226_SHUNT_VOLTAGE_REG);
|
||||
FILE_LOG(logDEBUG1, (" shunt voltage reg: %d\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: %d\n", shuntVoltageRegVal));
|
||||
}
|
||||
// value for current
|
||||
int retval = INA226_getConvertedCurrentUnits(shuntVoltageRegVal, INA226_Calibration_Register_Value);
|
||||
FILE_LOG(logDEBUG1, (" current unit value: %d\n", retval));
|
||||
|
||||
|
||||
// reading directly the current reg
|
||||
FILE_LOG(logDEBUG1, (" Reading current reg\n"));
|
||||
int cuurentRegVal = I2C_Read(deviceId, INA226_CURRENT_REG);
|
||||
FILE_LOG(logDEBUG1, (" current reg: %d\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: %d\n", cuurentRegVal));
|
||||
}
|
||||
|
||||
// should be the same
|
||||
FILE_LOG(logDEBUG1, (" ===============current reg: %d, current unit cal:%d=================================\n", cuurentRegVal, retval));
|
||||
// current in uA
|
||||
int currentuA = cuurentRegVal * INA226_CURRENT_IMIN_UA;
|
||||
FILE_LOG(logDEBUG1, (" current: %d uA\n", currentuA));
|
||||
|
||||
// current in mA
|
||||
int currentmA = (currentuA / 1000.00) + 0.5;
|
||||
FILE_LOG(logDEBUG1, (" current: %d mA\n", currentmA));
|
||||
|
||||
FILE_LOG(logINFO, ("Current via I2C (Device: 0x%x): %d mA\n", deviceId, currentmA));
|
||||
|
||||
return currentmA;
|
||||
}
|
||||
311
slsDetectorServers/slsDetectorServer/LTC2620.h
Executable file
311
slsDetectorServers/slsDetectorServer/LTC2620.h
Executable file
@@ -0,0 +1,311 @@
|
||||
#pragma once
|
||||
|
||||
#include "commonServerFunctions.h" // blackfin.h, ansi.h
|
||||
#include "common.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/* LTC2620 DAC DEFINES */
|
||||
// first 4 bits are 0 as this is a 12 bit dac
|
||||
#define LTC2620_DAC_DATA_OFST (4)
|
||||
#define LTC2620_DAC_DATA_MSK (0x00000FFF << LTC2620_DAC_DATA_OFST)
|
||||
#define LTC2620_DAC_ADDR_OFST (16)
|
||||
#define LTC2620_DAC_ADDR_MSK (0x0000000F << LTC2620_DAC_ADDR_OFST)
|
||||
#define LTC2620_DAC_CMD_OFST (20)
|
||||
#define LTC2620_DAC_CMD_MSK (0x0000000F << LTC2620_DAC_CMD_OFST)
|
||||
|
||||
#define LTC2620_DAC_CMD_WR_IN_VAL ((0x0 << LTC2620_DAC_CMD_OFST) & LTC2620_DAC_CMD_MSK) // write to input register
|
||||
#define LTC2620_DAC_CMD_UPDTE_DAC_VAL ((0x1 << LTC2620_DAC_CMD_OFST) & LTC2620_DAC_CMD_MSK) // update dac (power up)
|
||||
#define LTC2620_DAC_CMD_WR_IN_UPDTE_DAC_VAL ((0x2 << LTC2620_DAC_CMD_OFST) & LTC2620_DAC_CMD_MSK) // write to input register and update dac (power up)
|
||||
#define LTC2620_DAC_CMD_WR_UPDTE_DAC_VAL ((0x3 << LTC2620_DAC_CMD_OFST) & LTC2620_DAC_CMD_MSK) // write to and update dac (power up)
|
||||
#define LTC2620_DAC_CMD_PWR_DWN_VAL ((0x4 << LTC2620_DAC_CMD_OFST) & LTC2620_DAC_CMD_MSK)
|
||||
#define LTC2620_DAC_CMD_NO_OPRTN_VAL ((0xF << LTC2620_DAC_CMD_OFST) & LTC2620_DAC_CMD_MSK)
|
||||
|
||||
#define LTC2620_NUMBITS (24)
|
||||
#define LTC2620_DAISY_CHAIN_NUMBITS (32) // due to shift register FIXME: was 33 earlier
|
||||
#define LTC2620_NUMCHANNELS (8)
|
||||
#define LTC2620_PWR_DOWN_VAL (-100)
|
||||
#define LTC2620_MIN_VAL (0)
|
||||
#define LTC2620_MAX_VAL (4095) // 12 bits
|
||||
#define LTC2620_MAX_STEPS (LTC2620_MAX_VAL + 1)
|
||||
|
||||
uint32_t LTC2620_Reg = 0x0;
|
||||
uint32_t LTC2620_CsMask = 0x0;
|
||||
uint32_t LTC2620_ClkMask = 0x0;
|
||||
uint32_t LTC2620_DigMask = 0x0;
|
||||
int LTC2620_DigOffset = 0x0;
|
||||
int LTC2620_Ndac = 0;
|
||||
int LTC2620_MinVoltage = 0;
|
||||
int LTC2620_MaxVoltage = 0;
|
||||
|
||||
/**
|
||||
* Set Defines
|
||||
* @param reg spi register
|
||||
* @param cmsk chip select mask
|
||||
* @param clkmsk clock output mask
|
||||
* @param dmsk digital output mask
|
||||
* @param dofst digital output offset
|
||||
* @param nd total number of dacs for this board (for dac channel and daisy chain chip id)
|
||||
* @param minMV minimum voltage determined by hardware
|
||||
* @param maxMV maximum voltage determined by hardware
|
||||
*/
|
||||
void LTC2620_SetDefines(uint32_t reg, uint32_t cmsk, uint32_t clkmsk, uint32_t dmsk, int dofst, int nd, int minMV, int maxMV) {
|
||||
LTC2620_Reg = reg;
|
||||
LTC2620_CsMask = cmsk;
|
||||
LTC2620_ClkMask = clkmsk;
|
||||
LTC2620_DigMask = dmsk;
|
||||
LTC2620_DigOffset = dofst;
|
||||
LTC2620_Ndac = nd;
|
||||
LTC2620_MinVoltage = minMV;
|
||||
LTC2620_MaxVoltage = maxMV;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Disable SPI
|
||||
*/
|
||||
void LTC2620_Disable() {
|
||||
bus_w(LTC2620_Reg, (bus_r(LTC2620_Reg)
|
||||
| LTC2620_CsMask
|
||||
| LTC2620_ClkMask)
|
||||
& ~(LTC2620_DigMask));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Convert voltage to dac units
|
||||
* @param voltage value in mv
|
||||
* @param dacval pointer to value converted to dac units
|
||||
* @returns FAIL when voltage outside limits, OK if conversion successful
|
||||
*/
|
||||
int LTC2620_VoltageToDac(int voltage, int* dacval) {
|
||||
return ConvertToDifferentRange(LTC2620_MinVoltage, LTC2620_MaxVoltage,
|
||||
LTC2620_MIN_VAL, LTC2620_MAX_VAL,
|
||||
voltage, dacval);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Convert dac units to voltage
|
||||
* @param dacval dac units
|
||||
* @param voltage pointer to value converted to mV
|
||||
* @returns FAIL when voltage outside limits, OK if conversion successful
|
||||
*/
|
||||
int LTC2620_DacToVoltage(int dacval, int* voltage) {
|
||||
return ConvertToDifferentRange( LTC2620_MIN_VAL, LTC2620_MAX_VAL,
|
||||
LTC2620_MinVoltage, LTC2620_MaxVoltage,
|
||||
dacval, voltage);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set a single chip (all non ctb detectors use this)
|
||||
* when max dac is 8
|
||||
* @param cmd command
|
||||
* @param data dac value to be set
|
||||
* @param dacaddr dac channel number in chip
|
||||
*/
|
||||
void LTC2620_SetSingle(int cmd, int data, int dacaddr) {
|
||||
FILE_LOG(logDEBUG2, ("(Single) dac addr:%d, dac value:%d, cmd:%d\n", dacaddr, data, cmd));
|
||||
|
||||
uint32_t codata = (((data << LTC2620_DAC_DATA_OFST) & LTC2620_DAC_DATA_MSK) |
|
||||
((dacaddr << LTC2620_DAC_ADDR_OFST) & LTC2620_DAC_ADDR_MSK) |
|
||||
cmd);
|
||||
FILE_LOG(logDEBUG2, ("codata: 0x%x\n", codata));
|
||||
|
||||
serializeToSPI (LTC2620_Reg, codata, LTC2620_CsMask, LTC2620_NUMBITS,
|
||||
LTC2620_ClkMask, LTC2620_DigMask, LTC2620_DigOffset, 0);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* bit bang the data into all the chips daisy fashion
|
||||
* @param valw current value of register while bit banging
|
||||
* @param val data to be sent (data, dac addr and command)
|
||||
*/
|
||||
void LTC2620_SendDaisyData(uint32_t* valw, uint32_t val) {
|
||||
sendDataToSPI(valw, LTC2620_Reg, val, LTC2620_DAISY_CHAIN_NUMBITS,
|
||||
LTC2620_ClkMask, LTC2620_DigMask, LTC2620_DigOffset);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set a single chip (all non ctb detectors use this)
|
||||
* when max dac is 8
|
||||
* @param cmd command
|
||||
* @param data dac value to be set
|
||||
* @param dacaddr dac channel number in chip
|
||||
* @param chipIndex index of the chip
|
||||
*/
|
||||
void LTC2620_SetDaisy(int cmd, int data, int dacaddr, int chipIndex) {
|
||||
|
||||
int nchip = LTC2620_Ndac / LTC2620_NUMCHANNELS;
|
||||
uint32_t valw = 0;
|
||||
int ichip = 0;
|
||||
|
||||
FILE_LOG(logDEBUG2, ("(Daisy) desired chip index:%d, nchip:%d, dac ch:%d, val:%d, cmd:0x%x \n",
|
||||
chipIndex, nchip, dacaddr, data, cmd));
|
||||
|
||||
// data to be bit banged
|
||||
uint32_t codata = (((data << LTC2620_DAC_DATA_OFST) & LTC2620_DAC_DATA_MSK) |
|
||||
((dacaddr << LTC2620_DAC_ADDR_OFST) & LTC2620_DAC_ADDR_MSK) |
|
||||
cmd);
|
||||
FILE_LOG(logDEBUG2, ("codata: 0x%x\n", codata));
|
||||
|
||||
// select all chips (ctb daisy chain; others 1 chip)
|
||||
FILE_LOG(logDEBUG2, ("Selecting LTC2620\n"));
|
||||
SPIChipSelect (&valw, LTC2620_Reg, LTC2620_CsMask, LTC2620_ClkMask, LTC2620_DigMask, 0);
|
||||
|
||||
// send same data to all
|
||||
if (chipIndex < 0) {
|
||||
FILE_LOG(logDEBUG2, ("Send same data to all\n"));
|
||||
for (ichip = 0; ichip < nchip; ++ichip) {
|
||||
FILE_LOG(logDEBUG2, ("Send data (0x%x) to ichip %d\n", codata, ichip));
|
||||
LTC2620_SendDaisyData(&valw, codata);
|
||||
}
|
||||
}
|
||||
|
||||
// send to one chip, nothing to others
|
||||
else {
|
||||
// send nothing to subsequent ichips (daisy chain) (if any chips after desired chip)
|
||||
for (ichip = chipIndex + 1; ichip < nchip; ++ichip) {
|
||||
FILE_LOG(logDEBUG2, ("Send nothing to ichip %d\n", ichip));
|
||||
LTC2620_SendDaisyData(&valw, LTC2620_DAC_CMD_NO_OPRTN_VAL);
|
||||
}
|
||||
|
||||
// send data to desired chip
|
||||
FILE_LOG(logDEBUG2, ("Send data (0x%x) to ichip %d\n", codata, chipIndex));
|
||||
LTC2620_SendDaisyData(&valw, codata);
|
||||
|
||||
// send nothing to preceding ichips (daisy chain) (if any chips in front of desired chip)
|
||||
for (ichip = 0; ichip < chipIndex; ++ichip) {
|
||||
FILE_LOG(logDEBUG2, ("Send nothing to ichip %d\n", ichip));
|
||||
LTC2620_SendDaisyData(&valw, LTC2620_DAC_CMD_NO_OPRTN_VAL);
|
||||
}
|
||||
}
|
||||
|
||||
// deselect all chips (ctb daisy chain; others 1 chip)
|
||||
FILE_LOG(logDEBUG2, ("Deselecting LTC2620\n"));
|
||||
SPIChipDeselect(&valw, LTC2620_Reg, LTC2620_CsMask, LTC2620_ClkMask, LTC2620_DigMask, 0);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets a single chip (LTC2620_SetSingle) or multiple chip (LTC2620_SetDaisy)
|
||||
* multiple chip is only for ctb where the multiple chips are connected in daisy fashion
|
||||
* @param cmd command to send
|
||||
* @param data dac value to be set
|
||||
* @param dacaddr dac channel number for the chip
|
||||
* @param chipIndex the chip to be set
|
||||
*/
|
||||
void LTC2620_Set(int cmd, int data, int dacaddr, int chipIndex) {
|
||||
FILE_LOG(logDEBUG1, ("cmd:0x%x, data:%d, dacaddr:%d, chipIndex:%d\n", cmd, data, dacaddr, chipIndex));
|
||||
FILE_LOG(logDEBUG2, (" ================================================\n"));
|
||||
// ctb
|
||||
if (LTC2620_Ndac > LTC2620_NUMCHANNELS)
|
||||
LTC2620_SetDaisy(cmd, data, dacaddr, chipIndex);
|
||||
// others
|
||||
else
|
||||
LTC2620_SetSingle(cmd, data, dacaddr);
|
||||
FILE_LOG(logDEBUG2, (" ================================================\n"));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Configure (obtains dacaddr, command and ichip and calls LTC2620_Set)
|
||||
*/
|
||||
void LTC2620_Configure(){
|
||||
FILE_LOG(logINFOBLUE, ("Configuring LTC2620\n"));
|
||||
|
||||
// dac channel - all channels
|
||||
int addr = (LTC2620_DAC_ADDR_MSK >> LTC2620_DAC_ADDR_OFST);
|
||||
|
||||
// data (any random low value, just writing to power up)
|
||||
int data = 0x6;
|
||||
|
||||
// command
|
||||
int cmd = LTC2620_DAC_CMD_WR_IN_VAL; //FIXME: should be command update and not write(does not power up)
|
||||
// also why do we need to power up (for jctb, we power down next)
|
||||
|
||||
LTC2620_Set(cmd, data, addr, -1);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set Dac (obtains dacaddr, command and ichip and calls LTC2620_Set)
|
||||
* @param dacnum dac number
|
||||
* @param data dac value to set
|
||||
*/
|
||||
void LTC2620_SetDAC (int dacnum, int data) {
|
||||
FILE_LOG(logDEBUG1, ("Setting dac %d to %d\n", dacnum, data));
|
||||
// LTC2620 index
|
||||
int ichip = dacnum / LTC2620_NUMCHANNELS;
|
||||
|
||||
// dac channel
|
||||
int addr = dacnum % LTC2620_NUMCHANNELS;
|
||||
|
||||
// command
|
||||
int cmd = LTC2620_DAC_CMD_WR_UPDTE_DAC_VAL;
|
||||
|
||||
// power down mode, value is ignored
|
||||
if (data == LTC2620_PWR_DOWN_VAL) {
|
||||
cmd = LTC2620_DAC_CMD_PWR_DWN_VAL;
|
||||
FILE_LOG(logDEBUG1, ("POWER DOWN\n"));
|
||||
} else {
|
||||
FILE_LOG(logDEBUG1,("Write to Input Register and Update\n"));
|
||||
}
|
||||
|
||||
LTC2620_Set(cmd, data, addr, ichip);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set dac in dac units or mV
|
||||
* @param dacnum dac index
|
||||
* @param val value in dac units or mV
|
||||
* @param mV 0 for dac units and 1 for mV unit
|
||||
* @param dacval pointer to value in dac units
|
||||
* @returns OK or FAIL for success of operation
|
||||
*/
|
||||
int LTC2620_SetDACValue (int dacnum, int val, int mV, int* dacval) {
|
||||
FILE_LOG(logDEBUG1, ("dacnum:%d, val:%d, ismV:%d\n", dacnum, val, mV));
|
||||
// validate index
|
||||
if (dacnum < 0 || dacnum >= LTC2620_Ndac) {
|
||||
FILE_LOG(logERROR, ("Dac index %d is out of bounds (0 to %d)\n", dacnum, LTC2620_Ndac - 1));
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
// get
|
||||
if (val < 0 && val != LTC2620_PWR_DOWN_VAL)
|
||||
return FAIL;
|
||||
|
||||
// convert to dac or get mV value
|
||||
*dacval = val;
|
||||
int dacmV = val;
|
||||
int ret = OK;
|
||||
int ndacsonly = LTC2620_Ndac;
|
||||
#ifdef CHIPTESTBOARDD
|
||||
ndacsonly = NDAC_ONLY;
|
||||
#endif
|
||||
if (mV) {
|
||||
ret = LTC2620_VoltageToDac(val, dacval);
|
||||
} else if (val >= 0 && dacnum <= ndacsonly) {
|
||||
// do not convert power down dac val
|
||||
//(if not ndacsonly (pwr/vchip): dont need to print mV value as it will be wrong (wrong limits))
|
||||
ret = LTC2620_DacToVoltage(val, &dacmV);
|
||||
}
|
||||
|
||||
// conversion out of bounds
|
||||
if (ret == FAIL) {
|
||||
FILE_LOG(logERROR, ("Setting Dac %d %s is out of bounds\n", dacnum, (mV ? "mV" : "dac units")));
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
// set
|
||||
if ( (*dacval >= 0) || (*dacval == LTC2620_PWR_DOWN_VAL)) {
|
||||
#ifndef CHIPTESTBOARDD
|
||||
FILE_LOG(logINFO, ("Setting DAC %d: %d dac (%d mV)\n",dacnum, *dacval, dacmV));
|
||||
#endif
|
||||
LTC2620_SetDAC(dacnum, *dacval);
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
97
slsDetectorServers/slsDetectorServer/MAX1932.h
Executable file
97
slsDetectorServers/slsDetectorServer/MAX1932.h
Executable file
@@ -0,0 +1,97 @@
|
||||
#pragma once
|
||||
|
||||
#include "commonServerFunctions.h" // blackfin.h, ansi.h
|
||||
|
||||
/* MAX1932 HV DEFINES */
|
||||
|
||||
#define MAX1932_HV_NUMBITS (8)
|
||||
#define MAX1932_HV_DATA_OFST (0)
|
||||
#define MAX1932_HV_DATA_MSK (0x000000FF << MAX1932_HV_DATA_OFST)
|
||||
// higher voltage requires lower dac value, 0 is off
|
||||
#define MAX1932_MIN_DAC_VAL (0xFF)
|
||||
#define MAX1932_MAX_DAC_VAL (0x1)
|
||||
#define MAX1932_POWER_OFF_DAC_VAL (0x0)
|
||||
|
||||
uint32_t MAX1932_Reg = 0x0;
|
||||
uint32_t MAX1932_CsMask = 0x0;
|
||||
uint32_t MAX1932_ClkMask = 0x0;
|
||||
uint32_t MAX1932_DigMask = 0x0;
|
||||
int MAX1932_DigOffset = 0x0;
|
||||
int MAX1932_MinVoltage = 0;
|
||||
int MAX1932_MaxVoltage = 0;
|
||||
|
||||
|
||||
/**
|
||||
* Set Defines
|
||||
* @param reg spi register
|
||||
* @param cmsk chip select mask
|
||||
* @param clkmsk clock output mask
|
||||
* @param dmsk digital output mask
|
||||
* @param dofst digital output offset
|
||||
* @param minMV minimum voltage determined by hardware
|
||||
* @param maxMV maximum voltage determined by hardware
|
||||
*/
|
||||
void MAX1932_SetDefines(uint32_t reg, uint32_t cmsk, uint32_t clkmsk, uint32_t dmsk, int dofst,
|
||||
int minMV, int maxMV) {
|
||||
FILE_LOG(logINFOBLUE, ("Configuring High Voltage\n"));
|
||||
MAX1932_Reg = reg;
|
||||
MAX1932_CsMask = cmsk;
|
||||
MAX1932_ClkMask = clkmsk;
|
||||
MAX1932_DigMask = dmsk;
|
||||
MAX1932_DigOffset = dofst;
|
||||
MAX1932_MinVoltage = minMV;
|
||||
MAX1932_MaxVoltage = maxMV;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Disable SPI
|
||||
*/
|
||||
void MAX1932_Disable() {
|
||||
bus_w(MAX1932_Reg, (bus_r(MAX1932_Reg)
|
||||
| MAX1932_CsMask
|
||||
| MAX1932_ClkMask)
|
||||
& ~(MAX1932_DigMask));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set value
|
||||
* @param val value to set
|
||||
* @return OK or FAIL
|
||||
*/
|
||||
int MAX1932_Set (int val) {
|
||||
FILE_LOG(logDEBUG1, ("Setting high voltage to %d\n", val));
|
||||
if (val < 0)
|
||||
return FAIL;
|
||||
|
||||
int dacvalue = 0;
|
||||
|
||||
// limit values (normally < 60 => 0 (off))
|
||||
if (val < MAX1932_MinVoltage) {
|
||||
dacvalue = MAX1932_POWER_OFF_DAC_VAL;
|
||||
val = 0;
|
||||
}
|
||||
// limit values (normally > 200 => 0x1 (max))
|
||||
else if (val > MAX1932_MaxVoltage) {
|
||||
dacvalue = MAX1932_MAX_DAC_VAL;
|
||||
val = MAX1932_MaxVoltage;
|
||||
}
|
||||
// convert value
|
||||
else {
|
||||
// no failure in conversion as limits handled (range from 0x1 to 0xFF)
|
||||
ConvertToDifferentRange(MAX1932_MinVoltage, MAX1932_MaxVoltage,
|
||||
MAX1932_MIN_DAC_VAL, MAX1932_MAX_DAC_VAL,
|
||||
val, &dacvalue);
|
||||
dacvalue &= MAX1932_HV_DATA_MSK;
|
||||
}
|
||||
|
||||
FILE_LOG(logINFO, ("\t%dV (dacval %d)\n", val, dacvalue));
|
||||
serializeToSPI(MAX1932_Reg, dacvalue, MAX1932_CsMask, MAX1932_HV_NUMBITS,
|
||||
MAX1932_ClkMask, MAX1932_DigMask, MAX1932_DigOffset, 0);
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
105
slsDetectorServers/slsDetectorServer/UDPPacketHeaderGenerator.h
Executable file
105
slsDetectorServers/slsDetectorServer/UDPPacketHeaderGenerator.h
Executable file
@@ -0,0 +1,105 @@
|
||||
#pragma once
|
||||
|
||||
#include "logger.h"
|
||||
#include "sls_detector_defs.h"
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <netdb.h>
|
||||
|
||||
extern const enum detectorType myDetectorType;
|
||||
extern int nSamples;
|
||||
extern int dataBytes;
|
||||
extern int nframes;
|
||||
extern char* ramValues;
|
||||
|
||||
#define UDP_PACKET_HEADER_VERSION (0x1)
|
||||
|
||||
|
||||
uint32_t udpPacketNumber = 0;
|
||||
uint64_t udpFrameNumber = 0;
|
||||
|
||||
int numSamplesPerPacket = 0;
|
||||
int dataBytesPerSample = 0;
|
||||
int dataBytesPerPacket = 0;
|
||||
int udpHeaderOffset = 0;
|
||||
|
||||
uint32_t getUDPPacketNumber() {
|
||||
return udpPacketNumber;
|
||||
}
|
||||
|
||||
uint64_t getUDPFrameNumber() {
|
||||
return udpFrameNumber;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Called for each UDP packet header creation
|
||||
*
|
||||
*/
|
||||
void createUDPPacketHeader(char* buffer, uint16_t id) {
|
||||
memset(buffer, 0, sizeof(sls_detector_header));
|
||||
sls_detector_header* header = (sls_detector_header*)(buffer);
|
||||
|
||||
header->modId = id;
|
||||
// row and column remains 0 (only used by ctb now)
|
||||
// uint64_t timestamp FIXME: needed?
|
||||
header->detType = (uint16_t)myDetectorType;
|
||||
header->version = UDP_PACKET_HEADER_VERSION;
|
||||
|
||||
// reset offset
|
||||
udpHeaderOffset = 0;
|
||||
// reset frame number
|
||||
udpFrameNumber = 0;
|
||||
}
|
||||
|
||||
|
||||
int fillUDPPacket(char* buffer) {
|
||||
FILE_LOG(logDEBUG2, ("Databytes:%d offset:%d\n", dataBytes, udpHeaderOffset));
|
||||
// reached end of data for one frame
|
||||
if (udpHeaderOffset >= dataBytes) {
|
||||
// reset offset
|
||||
udpHeaderOffset = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
sls_detector_header* header = (sls_detector_header*)(buffer);
|
||||
|
||||
// update frame number, starts at 1 (reset packet number)
|
||||
if (udpHeaderOffset == 0) {
|
||||
++udpFrameNumber;
|
||||
header->frameNumber = udpFrameNumber;
|
||||
udpPacketNumber = -1;
|
||||
}
|
||||
|
||||
// increment and copy udp packet number (starts at 0)
|
||||
++udpPacketNumber;
|
||||
header->packetNumber = udpPacketNumber;
|
||||
FILE_LOG(logDEBUG2, ("Creating packet number %d (fnum:%lld)\n", udpPacketNumber, (long long int) udpFrameNumber));
|
||||
|
||||
// calculate number of bytes to copy
|
||||
int numBytesToCopy = ((udpHeaderOffset + UDP_PACKET_DATA_BYTES) <= dataBytes) ?
|
||||
UDP_PACKET_DATA_BYTES : (dataBytes - udpHeaderOffset);
|
||||
|
||||
// copy data
|
||||
memcpy(buffer + sizeof(sls_detector_header), ramValues + udpHeaderOffset, numBytesToCopy);
|
||||
// pad last packet if extra space
|
||||
if (numBytesToCopy < UDP_PACKET_DATA_BYTES) {
|
||||
int bytes = UDP_PACKET_DATA_BYTES - numBytesToCopy;
|
||||
FILE_LOG(logDEBUG1, ("Padding %d bytes for fnum:%lld pnum:%d\n", bytes, (long long int)udpFrameNumber, udpPacketNumber));
|
||||
memset(buffer + sizeof(sls_detector_header) + numBytesToCopy, 0, bytes);
|
||||
}
|
||||
|
||||
// increment offset
|
||||
udpHeaderOffset += numBytesToCopy;
|
||||
|
||||
return UDP_PACKET_DATA_BYTES + sizeof(sls_detector_header);
|
||||
}
|
||||
174
slsDetectorServers/slsDetectorServer/blackfin.h
Executable file
174
slsDetectorServers/slsDetectorServer/blackfin.h
Executable file
@@ -0,0 +1,174 @@
|
||||
#pragma once
|
||||
|
||||
#include "ansi.h"
|
||||
|
||||
#include <fcntl.h> // open
|
||||
#include <sys/mman.h> // mmap
|
||||
|
||||
|
||||
/* global variables */
|
||||
u_int64_t CSP0BASE = 0;
|
||||
#define CSP0 0x20200000
|
||||
#define MEM_SIZE 0x100000
|
||||
|
||||
|
||||
/** I2C defines */
|
||||
#define I2C_CLOCK_MHZ (131.25)
|
||||
|
||||
/**
|
||||
* Write into a 16 bit register
|
||||
* @param offset address offset
|
||||
* @param data 16 bit data
|
||||
*/
|
||||
void bus_w16(u_int32_t offset, u_int16_t data) {
|
||||
volatile u_int16_t *ptr1;
|
||||
ptr1=(u_int16_t*)(CSP0BASE+offset*2);
|
||||
*ptr1=data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read from a 16 bit register
|
||||
* @param offset address offset
|
||||
* @retuns 16 bit data read
|
||||
*/
|
||||
u_int16_t bus_r16(u_int32_t offset){
|
||||
volatile u_int16_t *ptr1;
|
||||
ptr1=(u_int16_t*)(CSP0BASE+offset*2);
|
||||
return *ptr1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write into a 32 bit register
|
||||
* @param offset address offset
|
||||
* @param data 32 bit data
|
||||
*/
|
||||
void bus_w(u_int32_t offset, u_int32_t data) {
|
||||
volatile u_int32_t *ptr1;
|
||||
ptr1=(u_int32_t*)(CSP0BASE+offset*2);
|
||||
*ptr1=data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read from a 32 bit register
|
||||
* @param offset address offset
|
||||
* @retuns 32 bit data read
|
||||
*/
|
||||
u_int32_t bus_r(u_int32_t offset) {
|
||||
volatile u_int32_t *ptr1;
|
||||
ptr1=(u_int32_t*)(CSP0BASE+offset*2);
|
||||
return *ptr1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read from a 64 bit register
|
||||
* @param aLSB LSB offset address
|
||||
* @param aMSB MSB offset address
|
||||
* @returns 64 bit data read
|
||||
*/
|
||||
int64_t get64BitReg(int aLSB, int aMSB){
|
||||
int64_t v64;
|
||||
u_int32_t vLSB,vMSB;
|
||||
vLSB=bus_r(aLSB);
|
||||
vMSB=bus_r(aMSB);
|
||||
v64=vMSB;
|
||||
v64=(v64<<32) | vLSB;
|
||||
FILE_LOG(logDEBUG5, (" reg64(%x,%x) %x %x %llx\n", aLSB, aMSB, vLSB, vMSB, (long long unsigned int)v64));
|
||||
return v64;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write into a 64 bit register
|
||||
* @param value 64 bit data
|
||||
* @param aLSB LSB offset address
|
||||
* @param aMSB MSB offset address
|
||||
* @returns 64 bit data read
|
||||
*/
|
||||
int64_t set64BitReg(int64_t value, int aLSB, int aMSB){
|
||||
int64_t v64;
|
||||
u_int32_t vLSB,vMSB;
|
||||
if (value!=-1) {
|
||||
vLSB=value&(0xffffffff);
|
||||
bus_w(aLSB,vLSB);
|
||||
v64=value>> 32;
|
||||
vMSB=v64&(0xffffffff);
|
||||
bus_w(aMSB,vMSB);
|
||||
}
|
||||
return get64BitReg(aLSB, aMSB);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Read from a 32 bit register (literal register value provided by client)
|
||||
* @param offset address offset
|
||||
* @retuns 32 bit data read
|
||||
*/
|
||||
u_int32_t readRegister(u_int32_t offset) {
|
||||
return bus_r(offset << MEM_MAP_SHIFT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write into a 32 bit register (literal register value provided by client)
|
||||
* @param offset address offset
|
||||
* @param data 32 bit data
|
||||
*/
|
||||
u_int32_t writeRegister(u_int32_t offset, u_int32_t data) {
|
||||
bus_w(offset << MEM_MAP_SHIFT, data);
|
||||
return readRegister(offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read from a 16 bit register (literal register value provided by client)
|
||||
* @param offset address offset
|
||||
* @retuns 16 bit data read
|
||||
*/
|
||||
u_int32_t readRegister16(u_int32_t offset) {
|
||||
return (u_int32_t)bus_r16(offset << MEM_MAP_SHIFT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Write into a 16 bit register (literal register value provided by client)
|
||||
* @param offset address offset
|
||||
* @param data 16 bit data
|
||||
*/
|
||||
u_int32_t writeRegister16(u_int32_t offset, u_int32_t data) {
|
||||
bus_w16(offset << MEM_MAP_SHIFT, (u_int16_t)data);
|
||||
return readRegister16(offset);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Map FPGA
|
||||
*/
|
||||
int mapCSP0(void) {
|
||||
// if not mapped
|
||||
if (CSP0BASE == 0) {
|
||||
FILE_LOG(logINFO, ("Mapping memory\n"));
|
||||
#ifdef VIRTUAL
|
||||
CSP0BASE = malloc(MEM_SIZE);
|
||||
if (CSP0BASE == NULL) {
|
||||
FILE_LOG(logERROR, ("Could not allocate virtual memory.\n"));
|
||||
return FAIL;
|
||||
}
|
||||
FILE_LOG(logINFO, ("memory allocated\n"));
|
||||
#else
|
||||
int fd;
|
||||
fd = open("/dev/mem", O_RDWR | O_SYNC, 0);
|
||||
if (fd == -1) {
|
||||
FILE_LOG(logERROR, ("Can't find /dev/mem\n"));
|
||||
return FAIL;
|
||||
}
|
||||
FILE_LOG(logDEBUG1, ("/dev/mem opened\n"));
|
||||
CSP0BASE = mmap(0, MEM_SIZE, PROT_READ|PROT_WRITE, MAP_FILE|MAP_SHARED, fd, CSP0);
|
||||
if (CSP0BASE == MAP_FAILED) {
|
||||
FILE_LOG(logERROR, ("Can't map memmory area\n"));
|
||||
return FAIL;
|
||||
}
|
||||
#endif
|
||||
FILE_LOG(logINFO, ("CSPOBASE mapped from 0x%llx to 0x%llx\n",
|
||||
(long long unsigned int)CSP0BASE,
|
||||
(long long unsigned int)(CSP0BASE+MEM_SIZE)));
|
||||
FILE_LOG(logINFO, ("Status Register: %08x\n", bus_r(STATUS_REG)));
|
||||
}else
|
||||
FILE_LOG(logINFO, ("Memory already mapped before\n"));
|
||||
return OK;
|
||||
}
|
||||
44
slsDetectorServers/slsDetectorServer/common.h
Executable file
44
slsDetectorServers/slsDetectorServer/common.h
Executable file
@@ -0,0 +1,44 @@
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* Convert a value from a range to a different range (eg voltage to dac or vice versa)
|
||||
* @param inputMin input minimum
|
||||
* @param inputMax input maximum
|
||||
* @param outputMin output minimum
|
||||
* @param outputMax output maximum
|
||||
* @param inputValue input value
|
||||
* @param outputValue pointer to output value
|
||||
* @returns FAIL if input value is out of bounds, else OK
|
||||
*/
|
||||
int ConvertToDifferentRange(int inputMin, int inputMax, int outputMin, int outputMax,
|
||||
int inputValue, int* outputValue) {
|
||||
FILE_LOG(logDEBUG1, (" Input Value: %d (Input:(%d - %d), Output:(%d - %d))\n",
|
||||
inputValue, inputMin, inputMax, outputMin, outputMax));
|
||||
|
||||
// validate within bounds
|
||||
// eg. MAX1932 range is v(60 - 200) to dac(255 - 1), here inputMin > inputMax (when dac to voltage)
|
||||
int smaller = inputMin;
|
||||
int bigger = inputMax;
|
||||
if (smaller > bigger) {
|
||||
smaller = inputMax;
|
||||
bigger = inputMin;
|
||||
}
|
||||
if ((inputValue < smaller) || (inputValue > bigger)) {
|
||||
FILE_LOG(logERROR, ("Input Value is outside bounds (%d to %d): %d\n", inputValue, smaller, bigger));
|
||||
*outputValue = -1;
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
double value = ((double)(inputValue - inputMin) * (double)(outputMax - outputMin))
|
||||
/ (double)(inputMax - inputMin) + outputMin;
|
||||
|
||||
// double to integer conversion (if decimal places, round to integer)
|
||||
if ((value - (int)value) > 0.0001) {
|
||||
value += 0.5;
|
||||
}
|
||||
*outputValue = value;
|
||||
|
||||
FILE_LOG(logDEBUG1, (" Converted Output Value: %d\n", *outputValue));
|
||||
return OK;
|
||||
}
|
||||
|
||||
145
slsDetectorServers/slsDetectorServer/commonServerFunctions.h
Executable file
145
slsDetectorServers/slsDetectorServer/commonServerFunctions.h
Executable file
@@ -0,0 +1,145 @@
|
||||
#pragma once
|
||||
|
||||
#include "blackfin.h"
|
||||
#include <unistd.h> // usleep
|
||||
|
||||
void SPIChipSelect (uint32_t* valw, uint32_t addr, uint32_t csmask, uint32_t clkmask, uint32_t digoutmask, int convBit) {
|
||||
FILE_LOG(logDEBUG2, ("SPI chip select. valw:0x%08x addr:0x%x csmask:0x%x, clkmask:0x%x digmask:0x%x convbit:%d\n",
|
||||
*valw, addr, csmask, clkmask, digoutmask, convBit));
|
||||
|
||||
// needed for the slow adcs for apprx 20 ns before and after rising of convbit (usleep val is vague assumption)
|
||||
if (convBit)
|
||||
usleep(20);
|
||||
|
||||
// start point
|
||||
(*valw) = ((bus_r(addr) | csmask | clkmask) &(~digoutmask));
|
||||
bus_w (addr, (*valw));
|
||||
FILE_LOG(logDEBUG2, ("startpoint. valw:0x%08x\n", *valw));
|
||||
|
||||
// needed for the slow adcs for apprx 10 ns before and after rising of convbit (usleep val is vague assumption)
|
||||
if (convBit)
|
||||
usleep(10);
|
||||
|
||||
// chip sel bar down
|
||||
(*valw) &= ~csmask;
|
||||
bus_w (addr, (*valw));
|
||||
FILE_LOG(logDEBUG2, ("chip sel bar down. valw:0x%08x\n", *valw));
|
||||
}
|
||||
|
||||
|
||||
void SPIChipDeselect (uint32_t* valw, uint32_t addr, uint32_t csmask, uint32_t clkmask, uint32_t digoutmask, int convBit) {
|
||||
FILE_LOG(logDEBUG2, ("SPI chip deselect. valw:0x%08x addr:0x%x csmask:0x%x, clkmask:0x%x digmask:0x%x convbit:%d\n",
|
||||
*valw, addr, csmask, clkmask, digoutmask, convBit));
|
||||
|
||||
// needed for the slow adcs for apprx 20 ns before and after rising of convbit (usleep val is vague assumption)
|
||||
if (convBit)
|
||||
usleep(20);
|
||||
|
||||
// chip sel bar up
|
||||
(*valw) |= csmask;
|
||||
bus_w (addr, (*valw));
|
||||
FILE_LOG(logDEBUG2, ("chip sel bar up. valw:0x%08x\n", *valw));
|
||||
|
||||
// needed for the slow adcs for apprx 10 ns before and after rising of convbit (usleep val is vague assumption)
|
||||
if (convBit)
|
||||
usleep(10);
|
||||
|
||||
//clk down
|
||||
(*valw) &= ~clkmask;
|
||||
bus_w (addr, (*valw));
|
||||
FILE_LOG(logDEBUG2, ("clk down. valw:0x%08x\n", *valw));
|
||||
|
||||
// stop point = start point of course
|
||||
(*valw) &= ~digoutmask;
|
||||
// slow adcs use convBit (has to go high and then low) instead of csmask
|
||||
if (convBit) {
|
||||
(*valw) &= ~csmask;
|
||||
} else {
|
||||
(*valw) |= csmask;
|
||||
}
|
||||
bus_w (addr, (*valw)); //FIXME: for ctb slow adcs, might need to set it to low again
|
||||
FILE_LOG(logDEBUG2, ("stop point. valw:0x%08x\n", *valw));
|
||||
}
|
||||
|
||||
void sendDataToSPI (uint32_t* valw, uint32_t addr, uint32_t val, int numbitstosend, uint32_t clkmask, uint32_t digoutmask, int digofset) {
|
||||
FILE_LOG(logDEBUG2, ("SPI send data. valw:0x%08x addr:0x%x val:0x%x, numbitstosend:%d, clkmask:0x%x digmask:0x%x digofst:%d\n",
|
||||
*valw, addr, val, numbitstosend, clkmask, digoutmask, digofset));
|
||||
|
||||
int i = 0;
|
||||
for (i = 0; i < numbitstosend; ++i) {
|
||||
|
||||
// clk down
|
||||
(*valw) &= ~clkmask;
|
||||
bus_w (addr, (*valw));
|
||||
FILE_LOG(logDEBUG2, ("clk down. valw:0x%08x\n", *valw));
|
||||
|
||||
// write data (i)
|
||||
(*valw) = (((*valw) & ~digoutmask) + // unset bit
|
||||
(((val >> (numbitstosend - 1 - i)) & 0x1) << digofset)); // each bit from val starting from msb
|
||||
bus_w (addr, (*valw));
|
||||
FILE_LOG(logDEBUG2, ("write data %d. valw:0x%08x\n", i, *valw));
|
||||
|
||||
// clk up
|
||||
(*valw) |= clkmask ;
|
||||
bus_w (addr, (*valw));
|
||||
FILE_LOG(logDEBUG2, ("clk up. valw:0x%08x\n", *valw));
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t receiveDataFromSPI (uint32_t* valw, uint32_t addr, int numbitstoreceive, uint32_t clkmask, uint32_t readaddr) {
|
||||
FILE_LOG(logDEBUG2, ("SPI send data. valw:0x%08x addr:0x%x numbitstoreceive:%d, clkmask:0x%x readaddr:0x%x \n",
|
||||
*valw, addr, numbitstoreceive, clkmask, readaddr));
|
||||
|
||||
uint32_t retval = 0;
|
||||
int i = 0;
|
||||
for (i = 0; i < numbitstoreceive; ++i) {
|
||||
|
||||
// clk down
|
||||
(*valw) &= ~clkmask;
|
||||
bus_w (addr, (*valw));
|
||||
FILE_LOG(logDEBUG2, ("clk down. valw:0x%08x\n", *valw));
|
||||
|
||||
// read data (i)
|
||||
retval |= ((bus_r(readaddr) & 0x1) << (numbitstoreceive - 1 - i));
|
||||
FILE_LOG(logDEBUG2, ("read data %d. retval:0x%08x\n", i, retval));
|
||||
|
||||
// clk up
|
||||
(*valw) |= clkmask ;
|
||||
bus_w (addr, (*valw));
|
||||
FILE_LOG(logDEBUG2, ("clk up. valw:0x%08x\n", *valw));
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
void serializeToSPI(uint32_t addr, uint32_t val, uint32_t csmask, int numbitstosend, uint32_t clkmask, uint32_t digoutmask, int digofset, int convBit) {
|
||||
if (numbitstosend == 16) {
|
||||
FILE_LOG(logDEBUG2, ("Writing to SPI Register: 0x%04x\n", val));
|
||||
} else {
|
||||
FILE_LOG(logDEBUG2, ("Writing to SPI Register: 0x%08x\n", val));
|
||||
}
|
||||
uint32_t valw;
|
||||
|
||||
SPIChipSelect (&valw, addr, csmask, clkmask, digoutmask, convBit);
|
||||
|
||||
sendDataToSPI(&valw, addr, val, numbitstosend, clkmask, digoutmask, digofset);
|
||||
|
||||
SPIChipDeselect(&valw, addr, csmask, clkmask, digoutmask, convBit);
|
||||
}
|
||||
|
||||
uint32_t serializeFromSPI(uint32_t addr, uint32_t csmask, int numbitstoreceive, uint32_t clkmask, uint32_t digoutmask, uint32_t readaddr, int convBit) {
|
||||
|
||||
uint32_t valw;
|
||||
|
||||
SPIChipSelect (&valw, addr, csmask, clkmask, digoutmask, convBit);
|
||||
|
||||
uint32_t retval = receiveDataFromSPI(&valw, addr, numbitstoreceive, clkmask, readaddr);
|
||||
|
||||
SPIChipDeselect(&valw, addr, csmask, clkmask, digoutmask, convBit); // moving this before bringin up earlier changes temp of slow adc
|
||||
|
||||
if (numbitstoreceive == 16) {
|
||||
FILE_LOG(logDEBUG2, ("Read From SPI Register: 0x%04x\n", retval));
|
||||
} else {
|
||||
FILE_LOG(logDEBUG2, ("Read From SPI Register: 0x%08x\n", retval));
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
522
slsDetectorServers/slsDetectorServer/communication_funcs.c
Executable file
522
slsDetectorServers/slsDetectorServer/communication_funcs.c
Executable file
@@ -0,0 +1,522 @@
|
||||
#include "communication_funcs.h"
|
||||
#include "logger.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define SEND_REC_MAX_SIZE 4096
|
||||
#define DEFAULT_PORTNO 1952
|
||||
#define DEFAULT_BACKLOG 5
|
||||
|
||||
// blackfin limits
|
||||
#define CPU_DRVR_SND_LMT (30000) // rough limit
|
||||
#define CPU_RSND_PCKT_LOOP (10)
|
||||
#define CPU_RSND_WAIT_US (1)
|
||||
|
||||
|
||||
// Global variables from errno.h
|
||||
extern int errno;
|
||||
|
||||
// Variables that will be exported
|
||||
int lockStatus = 0;
|
||||
char lastClientIP[INET_ADDRSTRLEN] = "";
|
||||
char thisClientIP[INET_ADDRSTRLEN] = "";
|
||||
int differentClients = 0;
|
||||
int isControlServer = 1;
|
||||
int ret = FAIL;
|
||||
int fnum = 0;
|
||||
char mess[MAX_STR_LENGTH];
|
||||
|
||||
// Local variables
|
||||
char dummyClientIP[INET_ADDRSTRLEN] = "";
|
||||
int myport = -1;
|
||||
// socket descriptor set
|
||||
fd_set readset, tempset;
|
||||
// number of socket descrptor listening to
|
||||
int isock = 0;
|
||||
// value of socket descriptor,
|
||||
//becomes max value of socket descriptor (listen) and file descriptor (accept)
|
||||
int maxfd = 0;
|
||||
|
||||
|
||||
int bindSocket(unsigned short int port_number) {
|
||||
ret = FAIL;
|
||||
int socketDescriptor = -1;
|
||||
int i = 0;
|
||||
struct sockaddr_in addressS;
|
||||
|
||||
// same port
|
||||
if (myport == port_number) {
|
||||
sprintf(mess, "Cannot create %s socket with port %d. Already in use before.\n",
|
||||
(isControlServer ? "control":"stop"), port_number);
|
||||
FILE_LOG(logERROR, (mess));
|
||||
}
|
||||
// port ok
|
||||
else {
|
||||
|
||||
// create socket
|
||||
socketDescriptor = socket(AF_INET, SOCK_STREAM,0);
|
||||
// socket error
|
||||
if (socketDescriptor < 0) {
|
||||
sprintf(mess, "Cannot create %s socket with port %d\n",
|
||||
(isControlServer ? "control":"stop"), port_number);
|
||||
FILE_LOG(logERROR, (mess));
|
||||
}
|
||||
// socket success
|
||||
else {
|
||||
i = 1;
|
||||
// set port reusable
|
||||
setsockopt(socketDescriptor, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(i));
|
||||
// Set some fields in the serverAddress structure
|
||||
addressS.sin_family = AF_INET;
|
||||
addressS.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
addressS.sin_port = htons(port_number);
|
||||
|
||||
// bind socket error
|
||||
if(bind(socketDescriptor,(struct sockaddr *) &addressS,sizeof(addressS)) < 0){
|
||||
sprintf(mess, "Cannot bind %s socket to port %d.\n",
|
||||
(isControlServer ? "control":"stop"), port_number);
|
||||
FILE_LOG(logERROR, (mess));
|
||||
}
|
||||
// bind socket ok
|
||||
else {
|
||||
|
||||
// listen to socket
|
||||
if (listen(socketDescriptor, DEFAULT_BACKLOG) == 0) {
|
||||
// clear set of descriptors. set of descriptors needed?
|
||||
if (isock == 0) {
|
||||
FD_ZERO(&readset);
|
||||
}
|
||||
// add a socket descriptor from listen
|
||||
FD_SET(socketDescriptor, &readset);
|
||||
isock++;
|
||||
maxfd = socketDescriptor;
|
||||
// success
|
||||
myport = port_number;
|
||||
ret = OK;
|
||||
FILE_LOG(logDEBUG1, ("%s socket bound: isock=%d, port=%d, fd=%d\n",
|
||||
(isControlServer ? "Control":"Stop"), isock, port_number, socketDescriptor));
|
||||
|
||||
}
|
||||
// listen socket error
|
||||
else {
|
||||
sprintf(mess, "Cannot bind %s socket to port %d.\n",
|
||||
(isControlServer ? "control":"stop"), port_number);
|
||||
FILE_LOG(logERROR, (mess));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return socketDescriptor;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int acceptConnection(int socketDescriptor) {
|
||||
int j;
|
||||
struct sockaddr_in addressC;
|
||||
int file_des = -1;
|
||||
struct timeval tv;
|
||||
socklen_t address_length = sizeof(struct sockaddr_in);
|
||||
|
||||
if (socketDescriptor < 0)
|
||||
return -1;
|
||||
|
||||
// copy file descriptor set temporarily
|
||||
memcpy(&tempset, &readset, sizeof(tempset));
|
||||
|
||||
// set time out as 2777.77 hours?
|
||||
tv.tv_sec = 10000000;
|
||||
tv.tv_usec = 0;
|
||||
|
||||
// monitor file descrptors
|
||||
int result = select(maxfd + 1, &tempset, NULL, NULL, &tv);
|
||||
|
||||
// timeout
|
||||
if (result == 0) {
|
||||
FILE_LOG(logDEBUG3, ("%s socket select() timed out!\n",
|
||||
(isControlServer ? "control":"stop"), myport));
|
||||
}
|
||||
|
||||
// error (not signal caught)
|
||||
else if (result < 0 && errno != EINTR) {
|
||||
FILE_LOG(logERROR, ("%s socket select() error: %s\n",
|
||||
(isControlServer ? "control":"stop"), myport, strerror(errno)));
|
||||
}
|
||||
|
||||
// activity in descriptor set
|
||||
else if (result > 0) {
|
||||
FILE_LOG(logDEBUG3, ("%s select returned!\n", (isControlServer ? "control":"stop")));
|
||||
|
||||
// loop through the file descriptor set
|
||||
for (j = 0; j < maxfd + 1; ++j) {
|
||||
|
||||
// checks if file descriptor part of set
|
||||
if (FD_ISSET(j, &tempset)) {
|
||||
FILE_LOG(logDEBUG3, ("fd %d is set\n",j));
|
||||
|
||||
// clear the temporary set
|
||||
FD_CLR(j, &tempset);
|
||||
|
||||
// accept connection (if error)
|
||||
if ((file_des = accept(j,(struct sockaddr *) &addressC, &address_length)) < 0) {
|
||||
FILE_LOG(logERROR, ("%s socket accept() error. Connection refused.\n",
|
||||
"Error Number: %d, Message: %s\n",
|
||||
(isControlServer ? "control":"stop"),
|
||||
myport, errno, strerror(errno)));
|
||||
switch(errno) {
|
||||
case EWOULDBLOCK:
|
||||
FILE_LOG(logERROR, ("ewouldblock eagain"));
|
||||
break;
|
||||
case EBADF:
|
||||
FILE_LOG(logERROR, ("ebadf\n"));
|
||||
break;
|
||||
case ECONNABORTED:
|
||||
FILE_LOG(logERROR, ("econnaborted\n"));
|
||||
break;
|
||||
case EFAULT:
|
||||
FILE_LOG(logERROR, ("efault\n"));
|
||||
break;
|
||||
case EINTR:
|
||||
FILE_LOG(logERROR, ("eintr\n"));
|
||||
break;
|
||||
case EINVAL:
|
||||
FILE_LOG(logERROR, ("einval\n"));
|
||||
break;
|
||||
case EMFILE:
|
||||
FILE_LOG(logERROR, ("emfile\n"));
|
||||
break;
|
||||
case ENFILE:
|
||||
FILE_LOG(logERROR, ("enfile\n"));
|
||||
break;
|
||||
case ENOTSOCK:
|
||||
FILE_LOG(logERROR, ("enotsock\n"));
|
||||
break;
|
||||
case EOPNOTSUPP:
|
||||
FILE_LOG(logERROR, ("eOPNOTSUPP\n"));
|
||||
break;
|
||||
case ENOBUFS:
|
||||
FILE_LOG(logERROR, ("ENOBUFS\n"));
|
||||
break;
|
||||
case ENOMEM:
|
||||
FILE_LOG(logERROR, ("ENOMEM\n"));
|
||||
break;
|
||||
case ENOSR:
|
||||
FILE_LOG(logERROR, ("ENOSR\n"));
|
||||
break;
|
||||
case EPROTO:
|
||||
FILE_LOG(logERROR, ("EPROTO\n"));
|
||||
break;
|
||||
default:
|
||||
FILE_LOG(logERROR, ("unknown error\n"));
|
||||
}
|
||||
}
|
||||
// accept success
|
||||
else {
|
||||
inet_ntop(AF_INET, &(addressC.sin_addr), dummyClientIP, INET_ADDRSTRLEN);
|
||||
FILE_LOG(logDEBUG3, ("%s socket accepted connection, fd= %d\n",
|
||||
(isControlServer ? "control":"stop"), file_des));
|
||||
// add the file descriptor from accept
|
||||
FD_SET(file_des, &readset);
|
||||
maxfd = (maxfd < file_des)?file_des:maxfd;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return file_des;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void closeConnection(int file_des) {
|
||||
if(file_des >= 0)
|
||||
close(file_des);
|
||||
// remove file descriptor from set
|
||||
FD_CLR(file_des, &readset);
|
||||
}
|
||||
|
||||
void exitServer(int socketDescriptor) {
|
||||
if (socketDescriptor >= 0)
|
||||
close(socketDescriptor);
|
||||
FILE_LOG(logINFO, ("Closing %s server\n", (isControlServer ? "control":"stop")));
|
||||
FD_CLR(socketDescriptor, &readset);
|
||||
isock--;
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void swapData(void* val,int length,intType itype){
|
||||
int i;
|
||||
int16_t* c = (int16_t*)val;
|
||||
int32_t* a = (int32_t*)val;
|
||||
int64_t* b = (int64_t*)val;
|
||||
for(i = 0; length > 0; i++){
|
||||
switch(itype){
|
||||
case INT16:
|
||||
c[i] = ((c[i] & 0x00FF) << 8) | ((c[i] & 0xFF00) >> 8);
|
||||
length -= sizeof(int16_t);
|
||||
break;
|
||||
case INT32:
|
||||
a[i] = ((a[i] << 8) & 0xFF00FF00) | ((a[i] >> 8) & 0xFF00FF );
|
||||
a[i] = (a[i] << 16) | ((a[i] >> 16) & 0xFFFF);
|
||||
length -= sizeof(int32_t);
|
||||
break;
|
||||
case INT64:
|
||||
b[i] = ((b[i] << 8) & 0xFF00FF00FF00FF00ULL ) | ((b[i] >> 8) & 0x00FF00FF00FF00FFULL );
|
||||
b[i] = ((b[i] << 16) & 0xFFFF0000FFFF0000ULL ) | ((b[i] >> 16) & 0x0000FFFF0000FFFFULL );
|
||||
b[i] = (b[i] << 32) | ((b[i] >> 32) & 0xFFFFFFFFULL);
|
||||
length -= sizeof(int64_t);
|
||||
break;
|
||||
default:
|
||||
length = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int sendData(int file_des, void* buf,int length, intType itype){
|
||||
#ifndef PCCOMPILE
|
||||
#ifdef EIGERD
|
||||
swapData(buf, length, itype);
|
||||
#endif
|
||||
#endif
|
||||
return sendDataOnly(file_des, buf, length);
|
||||
}
|
||||
|
||||
|
||||
int receiveData(int file_des, void* buf,int length, intType itype){
|
||||
int lret = receiveDataOnly(file_des, buf, length);
|
||||
#ifndef PCCOMPILE
|
||||
#ifdef EIGERD
|
||||
if (lret >= 0) swapData(buf, length, itype);
|
||||
#endif
|
||||
#endif
|
||||
return lret;
|
||||
}
|
||||
|
||||
|
||||
int sendDataOnly(int file_des, void* buf,int length) {
|
||||
if (!length)
|
||||
return 0;
|
||||
|
||||
|
||||
int bytesSent = 0;
|
||||
int retry = 0; // retry index when buffer is blocked (write returns 0)
|
||||
while (bytesSent < length) {
|
||||
|
||||
// setting a max packet size for blackfin driver (and network driver does not do a check if packets sent)
|
||||
int bytesToSend = length - bytesSent;
|
||||
if (bytesToSend > CPU_DRVR_SND_LMT)
|
||||
bytesToSend = CPU_DRVR_SND_LMT;
|
||||
|
||||
// send
|
||||
int rc = write(file_des, (char*)((char*)buf + bytesSent), bytesToSend);
|
||||
// error
|
||||
if (rc < 0) {
|
||||
FILE_LOG(logERROR, ("Could not write to %s socket. Possible socket crash\n",
|
||||
(isControlServer ? "control":"stop")));
|
||||
return bytesSent;
|
||||
}
|
||||
// also error, wrote nothing, buffer blocked up, too fast sending for client
|
||||
if (rc == 0) {
|
||||
FILE_LOG(logERROR, ("Could not write to %s socket. Buffer full. Retry: %d\n",
|
||||
(isControlServer ? "control":"stop"), retry));
|
||||
++retry;
|
||||
// wrote nothing for many loops
|
||||
if (retry >= CPU_RSND_PCKT_LOOP) {
|
||||
FILE_LOG(logERROR, ("Could not write to %s socket. Buffer full! Too fast! No more.\n",
|
||||
(isControlServer ? "control":"stop")));
|
||||
return bytesSent;
|
||||
}
|
||||
usleep(CPU_RSND_WAIT_US);
|
||||
}
|
||||
// wrote something, reset retry
|
||||
else {
|
||||
retry = 0;
|
||||
if (rc != bytesToSend) {
|
||||
FILE_LOG(logWARNING, ("Only partial write to %s socket. Expected to write %d bytes, wrote %d\n",
|
||||
(isControlServer ? "control":"stop"), bytesToSend, rc));
|
||||
}
|
||||
}
|
||||
bytesSent += rc;
|
||||
}
|
||||
|
||||
return bytesSent;
|
||||
}
|
||||
|
||||
|
||||
int receiveDataOnly(int file_des, void* buf,int length) {
|
||||
|
||||
int total_received = 0;
|
||||
int nreceiving;
|
||||
int nreceived;
|
||||
if (file_des<0) return -1;
|
||||
FILE_LOG(logDEBUG3, ("want to receive %d Bytes to %s server\n",
|
||||
length, (isControlServer ? "control":"stop")));
|
||||
|
||||
while(length > 0) {
|
||||
nreceiving = (length>SEND_REC_MAX_SIZE) ? SEND_REC_MAX_SIZE:length; // (condition) ? if_true : if_false
|
||||
nreceived = read(file_des,(char*)buf+total_received,nreceiving);
|
||||
if(!nreceived){
|
||||
if(!total_received) {
|
||||
return -1; //to handle it
|
||||
}
|
||||
break;
|
||||
}
|
||||
length -= nreceived;
|
||||
total_received += nreceived;
|
||||
}
|
||||
|
||||
if (total_received>0)
|
||||
strcpy(thisClientIP,dummyClientIP);
|
||||
|
||||
if (strcmp(lastClientIP,thisClientIP)) {
|
||||
differentClients = 1;
|
||||
}
|
||||
else
|
||||
differentClients = 0;
|
||||
|
||||
return total_received;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
int sendModule(int file_des, sls_detector_module *myMod) {
|
||||
int ts = 0, n = 0;
|
||||
n = sendData(file_des,&(myMod->serialnumber),sizeof(myMod->serialnumber),INT32);
|
||||
if (!n) return -1; ts += n;
|
||||
n = sendData(file_des,&(myMod->nchan), sizeof(myMod->nchan), INT32);
|
||||
if (!n) return -1; ts += n;
|
||||
n = sendData(file_des,&(myMod->nchip), sizeof(myMod->nchip), INT32);
|
||||
if (!n) return -1; ts += n;
|
||||
n = sendData(file_des,&(myMod->ndac), sizeof(myMod->ndac), INT32);
|
||||
if (!n) return -1; ts += n;
|
||||
n = sendData(file_des,&(myMod->reg), sizeof(myMod->reg), INT32);
|
||||
if (!n) return -1; ts += n;
|
||||
n = sendData(file_des,&(myMod->iodelay), sizeof(myMod->iodelay), INT32);
|
||||
if (!n) return -1; ts += n;
|
||||
n = sendData(file_des,&(myMod->tau), sizeof(myMod->tau), INT32);
|
||||
if (!n) return -1; ts += n;
|
||||
n = sendData(file_des,&(myMod->eV), sizeof(myMod->eV), INT32);
|
||||
if (!n) return -1; ts += n;
|
||||
// dacs
|
||||
n = sendData(file_des,myMod->dacs, sizeof(int)*(myMod->ndac), INT32);
|
||||
if (!n) return -1; ts += n;
|
||||
// channels
|
||||
#ifdef EIGERD
|
||||
n = sendData(file_des,myMod->chanregs, sizeof(int) * (myMod->nchan), INT32);
|
||||
if (!n) return -1; ts += n;
|
||||
#endif
|
||||
FILE_LOG(logDEBUG1, ("module of size %d sent register %x\n", ts, myMod->reg));
|
||||
return ts;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int receiveModule(int file_des, sls_detector_module* myMod) {
|
||||
enum TLogLevel level = logDEBUG1;
|
||||
FILE_LOG(level, ("Receiving Module\n"));
|
||||
int ts = 0, n = 0;
|
||||
int nDacs = myMod->ndac;
|
||||
#ifdef EIGERD
|
||||
int nChans = myMod->nchan; // can be zero for no trimbits
|
||||
FILE_LOG(level, ("nChans: %d\n",nChans));
|
||||
#endif
|
||||
n = receiveData(file_des,&(myMod->serialnumber), sizeof(myMod->serialnumber), INT32);
|
||||
if (!n) return -1; ts += n;
|
||||
FILE_LOG(level, ("serialno received. %d bytes. serialno: %d\n", n, myMod->serialnumber));
|
||||
n = receiveData(file_des,&(myMod->nchan), sizeof(myMod->nchan), INT32);
|
||||
if (!n) return -1; ts += n;
|
||||
FILE_LOG(level, ("nchan received. %d bytes. nchan: %d\n", n, myMod->nchan));
|
||||
n = receiveData(file_des,&(myMod->nchip), sizeof(myMod->nchip), INT32);
|
||||
if (!n) return -1; ts += n;
|
||||
FILE_LOG(level, ("nchip received. %d bytes. nchip: %d\n", n, myMod->nchip));
|
||||
n = receiveData(file_des,&(myMod->ndac), sizeof(myMod->ndac), INT32);
|
||||
if (!n) return -1; ts += n;
|
||||
FILE_LOG(level, ("ndac received. %d bytes. ndac: %d\n", n, myMod->ndac));
|
||||
n = receiveData(file_des,&(myMod->reg), sizeof(myMod->reg), INT32);
|
||||
if (!n) return -1; ts += n;
|
||||
FILE_LOG(level, ("reg received. %d bytes. reg: %d\n", n, myMod->reg));
|
||||
n = receiveData(file_des,&(myMod->iodelay), sizeof(myMod->iodelay), INT32);
|
||||
if (!n) return -1; ts += n;
|
||||
FILE_LOG(level, ("iodelay received. %d bytes. iodelay: %d\n", n, myMod->iodelay));
|
||||
n = receiveData(file_des,&(myMod->tau), sizeof(myMod->tau), INT32);
|
||||
if (!n) return -1; ts += n;
|
||||
FILE_LOG(level, ("tau received. %d bytes. tau: %d\n", n, myMod->tau));
|
||||
n = receiveData(file_des,&(myMod->eV), sizeof(myMod->eV), INT32);
|
||||
if (!n) return -1; ts += n;
|
||||
FILE_LOG(level, ("eV received. %d bytes. eV: %d\n", n, myMod->eV));
|
||||
// dacs
|
||||
if (nDacs != (myMod->ndac)) {
|
||||
FILE_LOG(logERROR, ("received wrong number of dacs. "
|
||||
"Expected %d, got %d\n", nDacs, myMod->ndac));
|
||||
return 0;
|
||||
}
|
||||
n = receiveData(file_des, myMod->dacs, sizeof(int) * (myMod->ndac), INT32);
|
||||
if (!n) return -1; ts += n;
|
||||
FILE_LOG(level, ("dacs received. %d bytes.\n", n));
|
||||
// channels
|
||||
#ifdef EIGERD
|
||||
if (((myMod->nchan) != 0 ) && // no trimbits
|
||||
(nChans != (myMod->nchan))) { // with trimbits
|
||||
FILE_LOG(logERROR, ("received wrong number of channels. "
|
||||
"Expected %d, got %d\n", nChans, (myMod->nchan)));
|
||||
return 0;
|
||||
}
|
||||
n = receiveData(file_des, myMod->chanregs, sizeof(int) * (myMod->nchan), INT32);
|
||||
FILE_LOG(level, ("chanregs received. %d bytes.\n", n));
|
||||
if (!n) return -1; ts += n;
|
||||
#endif
|
||||
FILE_LOG(level, ("received module of size %d register %x\n",ts,myMod->reg));
|
||||
return ts;
|
||||
}
|
||||
|
||||
|
||||
void Server_LockedError() {
|
||||
ret = FAIL;
|
||||
sprintf(mess,"Detector locked by %s\n", lastClientIP);
|
||||
FILE_LOG(logWARNING, (mess));
|
||||
}
|
||||
|
||||
|
||||
int Server_VerifyLock() {
|
||||
if (differentClients && lockStatus)
|
||||
Server_LockedError();
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int Server_SendResult(int fileDes, intType itype, int update, void* retval, int retvalSize) {
|
||||
|
||||
// update if different clients (ret can be ok or acquisition finished), not fail to not overwrite e message
|
||||
if (update && isControlServer && ret != FAIL && differentClients)
|
||||
ret = FORCE_UPDATE;
|
||||
|
||||
// send success of operation
|
||||
int ret1 = ret;
|
||||
sendData(fileDes, &ret1,sizeof(ret1), INT32);
|
||||
if(ret == FAIL) {
|
||||
// send error message
|
||||
if (strlen(mess))
|
||||
sendData(fileDes, mess, MAX_STR_LENGTH, OTHER);
|
||||
// debugging feature. should not happen.
|
||||
else
|
||||
FILE_LOG(logERROR, ("No error message provided for this failure in %s "
|
||||
"server. Will mess up TCP.\n",
|
||||
(isControlServer ? "control":"stop")));
|
||||
}
|
||||
// send return value
|
||||
sendData(fileDes, retval, retvalSize, itype);
|
||||
|
||||
return ret;
|
||||
}
|
||||
55
slsDetectorServers/slsDetectorServer/communication_funcs.h
Executable file
55
slsDetectorServers/slsDetectorServer/communication_funcs.h
Executable file
@@ -0,0 +1,55 @@
|
||||
#ifndef COMMUNICATION_FUNCS_H
|
||||
#define COMMUNICATION_FUNCS_H
|
||||
|
||||
|
||||
#include "sls_detector_defs.h"
|
||||
|
||||
typedef enum{
|
||||
INT16,
|
||||
INT32,
|
||||
INT64,
|
||||
OTHER
|
||||
}intType;
|
||||
|
||||
|
||||
int bindSocket(unsigned short int port_number);
|
||||
int acceptConnection(int socketDescriptor);
|
||||
void closeConnection(int file_Des);
|
||||
void exitServer(int socketDescriptor);
|
||||
|
||||
void swapData(void* val,int length,intType itype);
|
||||
int sendData(int file_des, void* buf,int length, intType itype);
|
||||
int receiveData(int file_des, void* buf,int length, intType itype);
|
||||
int sendDataOnly(int file_des, void* buf,int length);
|
||||
int receiveDataOnly(int file_des, void* buf,int length);
|
||||
|
||||
int sendModule(int file_des, sls_detector_module *myMod);
|
||||
int receiveModule(int file_des, sls_detector_module* myMod);
|
||||
|
||||
/**
|
||||
* Servers sets and prints error message for locked server
|
||||
* @returns success of operaton
|
||||
*/
|
||||
void Server_LockedError();
|
||||
|
||||
|
||||
/**
|
||||
* Server verifies if it is unlocked,
|
||||
* sets and prints appropriate message if it is locked and different clients
|
||||
* @returns success of operaton
|
||||
*/
|
||||
int Server_VerifyLock();
|
||||
|
||||
|
||||
/**
|
||||
* Server sends result to client (also set ret to force_update if different clients)
|
||||
* @param fileDes file descriptor for the socket
|
||||
* @param itype 32 or 64 or others to determine to swap data from big endian to little endian
|
||||
* @param update 1 if one must update if different clients, else 0
|
||||
* @param retval pointer to result
|
||||
* @param retvalSize size of result
|
||||
* @returns result of operation
|
||||
*/
|
||||
int Server_SendResult(int fileDes, intType itype, int update, void* retval, int retvalSize);
|
||||
|
||||
#endif
|
||||
116
slsDetectorServers/slsDetectorServer/communication_funcs_UDP.h
Executable file
116
slsDetectorServers/slsDetectorServer/communication_funcs_UDP.h
Executable file
@@ -0,0 +1,116 @@
|
||||
#pragma once
|
||||
|
||||
#include "logger.h"
|
||||
#include "sls_detector_defs.h"
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <netdb.h>
|
||||
|
||||
int udpSockfd = -1;
|
||||
struct addrinfo* udpServerAddrInfo = 0;
|
||||
unsigned short int udpDestinationPort = 0;
|
||||
char udpDestinationIp[MAX_STR_LENGTH] = "";
|
||||
|
||||
//DEFAULT_TX_UDP_PORT;// src port
|
||||
int getUdPSocketDescriptor() {
|
||||
return udpSockfd;
|
||||
}
|
||||
|
||||
int setUDPDestinationDetails(const char* ip, unsigned short int port) {
|
||||
udpDestinationPort = port;
|
||||
size_t len = strlen(ip);
|
||||
strncpy(udpDestinationIp, ip, len > MAX_STR_LENGTH ? MAX_STR_LENGTH : len );
|
||||
|
||||
if (udpServerAddrInfo) {
|
||||
freeaddrinfo(udpServerAddrInfo);
|
||||
udpServerAddrInfo = 0;
|
||||
}
|
||||
|
||||
// convert ip to internet address
|
||||
struct addrinfo hints;
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
hints.ai_family = AF_UNSPEC;
|
||||
hints.ai_socktype = SOCK_DGRAM;
|
||||
hints.ai_flags = 0;
|
||||
hints.ai_protocol = 0;
|
||||
char sport[100];
|
||||
memset(sport, 0, 100);
|
||||
sprintf(sport, "%d", udpDestinationPort);
|
||||
int err = getaddrinfo(udpDestinationIp, sport, &hints, &udpServerAddrInfo);
|
||||
if (err != 0) {
|
||||
FILE_LOG(logERROR, ("Failed to resolve remote socket address %s at port %d. "
|
||||
"(Error code:%d, %s)\n", udpDestinationIp, udpDestinationPort, err, gai_strerror(err)));
|
||||
return FAIL;
|
||||
}
|
||||
if (udpServerAddrInfo == NULL) {
|
||||
FILE_LOG(logERROR, ("Failed to resolve remote socket address %s at port %d "
|
||||
"(getaddrinfo returned NULL)\n", udpDestinationIp, udpDestinationPort));
|
||||
udpServerAddrInfo = 0;
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int createUDPSocket() {
|
||||
FILE_LOG(logDEBUG2, ("Creating UDP Socket\n"));
|
||||
if (!strlen(udpDestinationIp)) {
|
||||
FILE_LOG(logERROR, ("No destination UDP ip specified.\n"));
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
if (udpSockfd != -1) {
|
||||
FILE_LOG(logERROR, ("Strange that Udp socket was still open. Closing it to create a new one\n"));
|
||||
close(udpSockfd);
|
||||
udpSockfd = -1;
|
||||
}
|
||||
|
||||
// Creating socket file descriptor
|
||||
udpSockfd = socket(udpServerAddrInfo->ai_family, udpServerAddrInfo->ai_socktype, udpServerAddrInfo->ai_protocol);
|
||||
if (udpSockfd == -1 ) {
|
||||
FILE_LOG(logERROR, ("UDP socket at port %d failed. (Error code:%d, %s)\n",
|
||||
udpDestinationPort, errno, gai_strerror(errno)));
|
||||
return FAIL;
|
||||
}
|
||||
FILE_LOG(logINFO, ("Udp client socket created for server (port %d, ip:%s)\n",
|
||||
udpDestinationPort, udpDestinationIp));
|
||||
|
||||
// connecting allows to use "send/write" instead of "sendto", avoiding checking for server address for each packet
|
||||
// using write without a connect will end in segv
|
||||
if (connect(udpSockfd,udpServerAddrInfo->ai_addr, udpServerAddrInfo->ai_addrlen)==-1) {
|
||||
FILE_LOG(logERROR, ("Could not connect to UDP server at ip:%s, port:%d. (Error code:%d, %s)\n",
|
||||
udpDestinationIp, udpDestinationPort, errno, gai_strerror(errno)));
|
||||
}
|
||||
FILE_LOG(logINFO, ("Udp client socket connected\n",
|
||||
udpDestinationPort, udpDestinationIp));
|
||||
return OK;
|
||||
}
|
||||
|
||||
int sendUDPPacket(const char* buf, int length) {
|
||||
int n = write(udpSockfd, buf, length);
|
||||
// udp sends atomically, no need to handle partial data
|
||||
if (n == -1) {
|
||||
FILE_LOG(logERROR, ("Could not send udp packet. (Error code:%d, %s)\n",
|
||||
n, errno, gai_strerror(errno)));
|
||||
} else {
|
||||
FILE_LOG(logDEBUG2, ("%d bytes sent\n", n));
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
void closeUDPSocket() {
|
||||
if (udpSockfd != -1) {
|
||||
FILE_LOG(logINFO, ("Udp client socket closed\n"));
|
||||
close(udpSockfd);
|
||||
udpSockfd = -1;
|
||||
}
|
||||
}
|
||||
67
slsDetectorServers/slsDetectorServer/logger.h
Executable file
67
slsDetectorServers/slsDetectorServer/logger.h
Executable file
@@ -0,0 +1,67 @@
|
||||
#pragma once
|
||||
|
||||
#include "ansi.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
|
||||
#ifdef FIFODEBUG
|
||||
#define FILELOG_MAX_LEVEL logDEBUG5
|
||||
#elif VERYVERBOSE
|
||||
#define FILELOG_MAX_LEVEL logDEBUG4
|
||||
#elif VERBOSE
|
||||
#define FILELOG_MAX_LEVEL logDEBUG
|
||||
#elif DEBUG1
|
||||
#define FILELOG_MAX_LEVEL logDEBUG1
|
||||
#endif
|
||||
|
||||
#ifndef FILELOG_MAX_LEVEL
|
||||
#define FILELOG_MAX_LEVEL logINFO
|
||||
#endif
|
||||
|
||||
enum TLogLevel{
|
||||
logERROR, logWARNING, logINFOBLUE, logINFOGREEN, logINFORED, logINFO,
|
||||
logDEBUG, logDEBUG1, logDEBUG2, logDEBUG3, logDEBUG4, logDEBUG5
|
||||
};
|
||||
|
||||
#define ERROR_MSG_LENGTH 1000
|
||||
|
||||
#define FILE_LOG(lvl, fmt, ...) \
|
||||
if (lvl > FILELOG_MAX_LEVEL); \
|
||||
else {char* temp = FILELOG_BuildLog fmt; FILELOG_PrintLog(lvl, temp);free(temp);}
|
||||
|
||||
static inline void FILELOG_PrintLog(enum TLogLevel level, char* m) {
|
||||
switch(level) {
|
||||
case logERROR: cprintf(RED BOLD, "ERROR: %s", m); break;
|
||||
case logWARNING: cprintf(YELLOW BOLD, "WARNING: %s", m); break;
|
||||
case logINFOBLUE: cprintf(BLUE, "INFO: %s", m); break;
|
||||
case logINFOGREEN: cprintf(GREEN, "INFO: %s", m); break;
|
||||
case logINFORED: cprintf(RED, "INFO: %s", m); break;
|
||||
case logINFO: cprintf(RESET, "INFO: %s", m); break;
|
||||
case logDEBUG: cprintf(MAGENTA, "DEBUG: %s", m); break;
|
||||
case logDEBUG1: cprintf(MAGENTA, "DEBUG1: %s", m); break;
|
||||
case logDEBUG2: cprintf(MAGENTA, "DEBUG2: %s", m); break;
|
||||
case logDEBUG3: cprintf(MAGENTA, "DEBUG3: %s", m); break;
|
||||
case logDEBUG4: cprintf(MAGENTA, "DEBUG4: %s", m); break;
|
||||
case logDEBUG5: cprintf(MAGENTA, "DEBUG5: %s", m); break;
|
||||
}
|
||||
}
|
||||
|
||||
static inline char* FILELOG_BuildLog(const char* fmt, ...) {
|
||||
char* p;
|
||||
va_list ap;
|
||||
p = malloc(ERROR_MSG_LENGTH);
|
||||
va_start(ap, fmt);
|
||||
int ret = vsnprintf(p, ERROR_MSG_LENGTH, fmt, ap);
|
||||
va_end(ap);
|
||||
if (ret < 0 || ret >= ERROR_MSG_LENGTH) {
|
||||
FILELOG_PrintLog(logERROR, ("Could not print the "
|
||||
"complete error message in the next print.\n"));
|
||||
}
|
||||
return p;
|
||||
};
|
||||
|
||||
|
||||
|
||||
170
slsDetectorServers/slsDetectorServer/programfpga.h
Executable file
170
slsDetectorServers/slsDetectorServer/programfpga.h
Executable file
@@ -0,0 +1,170 @@
|
||||
#pragma once
|
||||
|
||||
#include "ansi.h"
|
||||
|
||||
#include <unistd.h> // usleep
|
||||
#include <string.h>
|
||||
|
||||
|
||||
/* global variables */
|
||||
#define MTDSIZE 10
|
||||
|
||||
int gpioDefined = 0;
|
||||
char mtdvalue[MTDSIZE] = {0};
|
||||
|
||||
|
||||
/**
|
||||
* Define GPIO pins if not defined
|
||||
*/
|
||||
void defineGPIOpins(){
|
||||
if (!gpioDefined) {
|
||||
//define the gpio pins
|
||||
system("echo 7 > /sys/class/gpio/export");
|
||||
system("echo 9 > /sys/class/gpio/export");
|
||||
//define their direction
|
||||
system("echo in > /sys/class/gpio/gpio7/direction");
|
||||
system("echo out > /sys/class/gpio/gpio9/direction");
|
||||
FILE_LOG(logINFO, ("gpio pins defined\n"));
|
||||
gpioDefined = 1;
|
||||
}else FILE_LOG(logDEBUG1, ("gpio pins already defined earlier\n"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify FPGA to not touch flash
|
||||
*/
|
||||
void FPGAdontTouchFlash(){
|
||||
//tell FPGA to not touch flash
|
||||
system("echo 0 > /sys/class/gpio/gpio9/value");
|
||||
//usleep(100*1000);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Notify FPGA to program from flash
|
||||
*/
|
||||
void FPGATouchFlash(){
|
||||
//tell FPGA to touch flash to program itself
|
||||
system("echo 1 > /sys/class/gpio/gpio9/value");
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset FPGA
|
||||
*/
|
||||
void resetFPGA(){
|
||||
FILE_LOG(logINFOBLUE, ("Reseting FPGA\n"));
|
||||
FPGAdontTouchFlash();
|
||||
FPGATouchFlash();
|
||||
usleep(CTRL_SRVR_INIT_TIME_US);
|
||||
}
|
||||
|
||||
/**
|
||||
* Erasing flash
|
||||
*/
|
||||
void eraseFlash(){
|
||||
FILE_LOG(logDEBUG1, ("Erasing Flash\n"));
|
||||
char command[255];
|
||||
memset(command, 0, 255);
|
||||
sprintf(command,"flash_eraseall %s",mtdvalue);
|
||||
system(command);
|
||||
FILE_LOG(logINFO, ("Flash erased\n"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Open the drive to copy program and
|
||||
* notify FPGA not to touch the program
|
||||
* @param filefp pointer to flash
|
||||
* @return 0 for success, 1 for fail (cannot open file for writing program)
|
||||
*/
|
||||
int startWritingFPGAprogram(FILE** filefp){
|
||||
FILE_LOG(logDEBUG1, ("Start Writing of FPGA program\n"));
|
||||
|
||||
//getting the drive
|
||||
char output[255];
|
||||
memset(output, 0, 255);
|
||||
FILE* fp = popen("awk \'$4== \"\\\"bitfile(spi)\\\"\" {print $1}\' /proc/mtd", "r");
|
||||
if (fp == NULL) {
|
||||
FILE_LOG(logERROR, ("popen returned NULL. Need that to get mtd drive.\n"));
|
||||
return 1;
|
||||
}
|
||||
if (fgets(output, sizeof(output), fp) == NULL) {
|
||||
FILE_LOG(logERROR, ("fgets returned NULL. Need that to get mtd drive.\n"));
|
||||
return 1;
|
||||
}
|
||||
pclose(fp);
|
||||
memset(mtdvalue, 0, MTDSIZE);
|
||||
strcpy(mtdvalue,"/dev/");
|
||||
char* pch = strtok(output,":");
|
||||
if(pch == NULL){
|
||||
FILE_LOG(logERROR, ("Could not get mtd value\n"));
|
||||
return 1;
|
||||
}
|
||||
strcat(mtdvalue,pch);
|
||||
FILE_LOG(logINFO, ("Flash drive found: %s\n", mtdvalue));
|
||||
|
||||
FPGAdontTouchFlash();
|
||||
|
||||
//writing the program to flash
|
||||
*filefp = fopen(mtdvalue, "w");
|
||||
if(*filefp == NULL){
|
||||
FILE_LOG(logERROR, ("Unable to open %s in write mode\n", mtdvalue));
|
||||
return 1;
|
||||
}
|
||||
FILE_LOG(logINFO, ("Flash ready for writing\n"));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* When done writing the program, close file pointer and
|
||||
* notify FPGA to pick up the program from flash
|
||||
* @param filefp pointer to flash
|
||||
*/
|
||||
void stopWritingFPGAprogram(FILE* filefp){
|
||||
FILE_LOG(logDEBUG1, ("Stopping of writing FPGA program\n"));
|
||||
|
||||
int wait = 0;
|
||||
if(filefp!= NULL){
|
||||
fclose(filefp);
|
||||
wait = 1;
|
||||
}
|
||||
|
||||
//touch and program
|
||||
FPGATouchFlash();
|
||||
|
||||
if(wait){
|
||||
FILE_LOG(logDEBUG1, ("Waiting for FPGA to program from flash\n"));
|
||||
//waiting for success or done
|
||||
char output[255];
|
||||
int res=0;
|
||||
while(res == 0){
|
||||
FILE* sysFile = popen("cat /sys/class/gpio/gpio7/value", "r");
|
||||
fgets(output, sizeof(output), sysFile);
|
||||
pclose(sysFile);
|
||||
sscanf(output,"%d",&res);
|
||||
FILE_LOG(logDEBUG1, ("gpi07 returned %d\n", res));
|
||||
}
|
||||
}
|
||||
FILE_LOG(logINFO, ("FPGA has picked up the program from flash\n"));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Write FPGA Program to flash
|
||||
* @param fpgasrc source program
|
||||
* @param fsize size of program
|
||||
* @param filefp pointer to flash
|
||||
* @return 0 for success, 1 for fail (cannot write)
|
||||
*/
|
||||
int writeFPGAProgram(char* fpgasrc, size_t fsize, FILE* filefp){
|
||||
FILE_LOG(logDEBUG1, ("Writing of FPGA Program\n"
|
||||
"\taddress of fpgasrc:%p\n"
|
||||
"\tfsize:%lu\n\tpointer:%p\n",
|
||||
(void *)fpgasrc, fsize, (void*)filefp));
|
||||
|
||||
if(fwrite((void*)fpgasrc , sizeof(char) , fsize , filefp )!= fsize){
|
||||
FILE_LOG(logERROR, ("Could not write FPGA source to flash (size:%lu)\n", fsize));
|
||||
return 1;
|
||||
}
|
||||
FILE_LOG(logDEBUG1, ("program written to flash\n"));
|
||||
return 0;
|
||||
}
|
||||
371
slsDetectorServers/slsDetectorServer/slsDetectorFunctionList.h
Executable file
371
slsDetectorServers/slsDetectorServer/slsDetectorFunctionList.h
Executable file
@@ -0,0 +1,371 @@
|
||||
#include "sls_detector_defs.h"
|
||||
#include "slsDetectorServer_defs.h" // DAC_INDEX, ADC_INDEX, also include RegisterDefs.h
|
||||
#ifdef GOTTHARDD
|
||||
#include "logger.h" // runState(enum TLogLevel)
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h> // FILE
|
||||
|
||||
|
||||
/****************************************************
|
||||
This functions are used by the slsDetectroServer_funcs interface.
|
||||
Here are the definitions, but the actual implementation should be done for each single detector.
|
||||
|
||||
****************************************************/
|
||||
|
||||
|
||||
// basic tests
|
||||
int isFirmwareCheckDone();
|
||||
int getFirmwareCheckResult(char** mess);
|
||||
void basictests();
|
||||
#if defined(GOTTHARDD) || defined(JUNGFRAUD) || defined(CHIPTESTBOARDD) || defined(MOENCHD)
|
||||
int checkType();
|
||||
int testFpga();
|
||||
int testBus();
|
||||
#endif
|
||||
|
||||
#ifdef GOTTHARDD
|
||||
int detectorTest(enum digitalTestMode arg, int ival);
|
||||
#elif defined(JUNGFRAUD) || defined(CHIPTESTBOARDD) || defined(MOENCHD)
|
||||
int detectorTest(enum digitalTestMode arg);
|
||||
#endif
|
||||
|
||||
// Ids
|
||||
int64_t getDetectorId(enum idMode arg);
|
||||
u_int64_t getFirmwareVersion();
|
||||
u_int64_t getFirmwareAPIVersion();
|
||||
#if defined(JUNGFRAUD) || defined(CHIPTESTBOARDD) || defined(MOENCHD)
|
||||
u_int16_t getHardwareVersionNumber();
|
||||
u_int16_t getHardwareSerialNumber();
|
||||
#endif
|
||||
u_int32_t getDetectorNumber();
|
||||
u_int64_t getDetectorMAC();
|
||||
u_int32_t getDetectorIP();
|
||||
#ifdef GOTTHARDD
|
||||
u_int32_t getBoardRevision();
|
||||
#endif
|
||||
|
||||
|
||||
// initialization
|
||||
void initControlServer();
|
||||
void initStopServer();
|
||||
#ifdef EIGERD
|
||||
void getModuleConfiguration();
|
||||
#endif
|
||||
|
||||
// set up detector
|
||||
#ifdef EIGERD
|
||||
void allocateDetectorStructureMemory();
|
||||
#endif
|
||||
void setupDetector();
|
||||
#if defined(CHIPTESTBOARDD) || defined(MOENCHD)
|
||||
int allocateRAM();
|
||||
void updateDataBytes();
|
||||
int getChannels();
|
||||
#endif
|
||||
|
||||
#if defined(GOTTHARDD) || defined(JUNGFRAUD)
|
||||
int setDefaultDacs();
|
||||
#endif
|
||||
|
||||
|
||||
// advanced read/write reg
|
||||
#ifdef EIGERD
|
||||
uint32_t writeRegister(uint32_t offset, uint32_t data);
|
||||
uint32_t readRegister(uint32_t offset);
|
||||
#elif GOTTHARDD
|
||||
uint32_t writeRegister16And32(uint32_t offset, uint32_t data); //FIXME its not there in ctb or moench?
|
||||
uint32_t readRegister16And32(uint32_t offset);
|
||||
#else
|
||||
extern u_int32_t writeRegister(u_int32_t offset, u_int32_t data); // blackfin.h
|
||||
extern u_int32_t readRegister(u_int32_t offset); // blackfin.h
|
||||
#endif
|
||||
|
||||
|
||||
// firmware functions (resets)
|
||||
#ifdef JUNGFRAUD
|
||||
void cleanFifos();
|
||||
void resetCore();
|
||||
void resetPeripheral();
|
||||
#elif GOTTHARDD
|
||||
void setPhaseShiftOnce();
|
||||
void setPhaseShift(int numphaseshift);
|
||||
void cleanFifos();
|
||||
void setADCSyncRegister();
|
||||
void setDAQRegister();
|
||||
void setChipOfInterestRegister(int adc);
|
||||
void setROIADC(int adc);
|
||||
void setGbitReadout();
|
||||
int readConfigFile();
|
||||
void setMasterSlaveConfiguration();
|
||||
#elif CHIPTESTBOARDD
|
||||
void cleanFifos();
|
||||
void resetCore();
|
||||
void resetPeripheral();
|
||||
#elif MOENCHD
|
||||
void cleanFifos();
|
||||
void resetCore();
|
||||
void resetPeripheral();
|
||||
#endif
|
||||
|
||||
// parameters - dr, roi
|
||||
int setDynamicRange(int dr);
|
||||
#if defined(GOTTHARDD) || defined(CHIPTESTBOARDD) || defined(MOENCHD)
|
||||
ROI* setROI(int n, ROI arg[], int *retvalsize, int *ret);
|
||||
#endif
|
||||
|
||||
// parameters - readout
|
||||
#if defined(CHIPTESTBOARDD) || defined(MOENCHD) || defined(JUNGFRAUD)
|
||||
void setSpeed(enum speedVariable ind, int val, int mode);
|
||||
int getSpeed(enum speedVariable ind, int mode);
|
||||
#else
|
||||
void setSpeed(enum speedVariable ind, int val);
|
||||
int getSpeed(enum speedVariable ind);
|
||||
#endif
|
||||
|
||||
#if defined(EIGERD) || defined(CHIPTESTBOARDD)
|
||||
enum readOutFlags setReadOutFlags(enum readOutFlags val);
|
||||
#endif
|
||||
|
||||
// parameters - timer
|
||||
#ifdef JUNGFRAUD
|
||||
int selectStoragecellStart(int pos);
|
||||
#endif
|
||||
int64_t setTimer(enum timerIndex ind, int64_t val);
|
||||
int64_t getTimeLeft(enum timerIndex ind);
|
||||
#if defined(JUNGFRAUD) || defined(GOTTHARDD) || defined(CHIPTESTBOARDD) || defined(MOENCHD)
|
||||
int validateTimer(enum timerIndex ind, int64_t val, int64_t retval);
|
||||
#endif
|
||||
|
||||
// parameters - module, settings
|
||||
#if (!defined(CHIPTESTBOARDD)) && (!defined(MOENCHD))
|
||||
int setModule(sls_detector_module myMod, char* mess);
|
||||
int getModule(sls_detector_module *myMod);
|
||||
enum detectorSettings setSettings(enum detectorSettings sett);
|
||||
#endif
|
||||
enum detectorSettings getSettings();
|
||||
|
||||
// parameters - threshold
|
||||
#ifdef EIGERD
|
||||
int getThresholdEnergy();
|
||||
int setThresholdEnergy(int ev);
|
||||
#endif
|
||||
|
||||
// parameters - dac, adc, hv
|
||||
#ifdef GOTTHARDD
|
||||
extern void AD9252_Set(int addr, int val); // AD9252.h (old board)
|
||||
#endif
|
||||
#if defined(GOTTHARDD) || defined(JUNGFRAUD) || defined(CHIPTESTBOARDD) || defined(MOENCHD)
|
||||
extern void AD9257_Set(int addr, int val); // AD9257.h
|
||||
#endif
|
||||
#if defined(CHIPTESTBOARDD) || defined(MOENCHD)
|
||||
extern int AD9257_GetMaxValidVref(); // AD9257.h
|
||||
extern void AD9257_SetVrefVoltage(int val); // AD9257.h
|
||||
#endif
|
||||
|
||||
void setDAC(enum DACINDEX ind, int val, int mV);
|
||||
int getDAC(enum DACINDEX ind, int mV);
|
||||
int getMaxDacSteps();
|
||||
#if defined(CHIPTESTBOARDD) || defined(MOENCHD)
|
||||
int dacToVoltage(int dac);
|
||||
int checkVLimitCompliant(int mV);
|
||||
int checkVLimitDacCompliant(int dac);
|
||||
int getVLimit();
|
||||
void setVLimit(int l);
|
||||
#endif
|
||||
|
||||
#ifdef CHIPTESTBOARDD
|
||||
int isVchipValid(int val);
|
||||
int getVchip();
|
||||
void setVchip(int val);
|
||||
int getVChipToSet(enum DACINDEX ind, int val);
|
||||
int getDACIndexFromADCIndex(enum ADCINDEX ind);
|
||||
int getADCIndexFromDACIndex(enum DACINDEX ind);
|
||||
int isPowerValid(enum DACINDEX ind, int val);
|
||||
int getPower();
|
||||
void setPower(enum DACINDEX ind, int val);
|
||||
void powerOff();
|
||||
#endif
|
||||
|
||||
#ifndef MOENCHD
|
||||
int getADC(enum ADCINDEX ind);
|
||||
#endif
|
||||
|
||||
int setHighVoltage(int val);
|
||||
|
||||
|
||||
|
||||
// parameters - timing, extsig
|
||||
void setTiming( enum externalCommunicationMode arg);
|
||||
enum externalCommunicationMode getTiming();
|
||||
#ifdef GOTTHARDD
|
||||
void setExtSignal(enum externalSignalFlag mode);
|
||||
int getExtSignal();
|
||||
#endif
|
||||
|
||||
// configure mac
|
||||
#ifdef GOTTHARDD
|
||||
void calcChecksum(mac_conf* mac, int sourceip, int destip);
|
||||
#endif
|
||||
#if defined(CHIPTESTBOARDD) || defined(MOENCHD)
|
||||
long int calcChecksum(int sourceip, int destip);
|
||||
#endif
|
||||
#ifdef GOTTHARDD
|
||||
int getAdcConfigured();
|
||||
#endif
|
||||
|
||||
#ifdef EIGERD
|
||||
int configureMAC(uint32_t destip, uint64_t destmac, uint64_t sourcemac, uint32_t sourceip, uint32_t udpport, uint32_t udpport2);
|
||||
#elif JUNGFRAUD
|
||||
int configureMAC(int numInterfaces, int selInterface,
|
||||
uint32_t destip, uint64_t destmac, uint64_t sourcemac, uint32_t sourceip, uint32_t udpport,
|
||||
uint32_t destip2, uint64_t destmac2, uint64_t sourcemac2, uint32_t sourceip2, uint32_t udpport2);
|
||||
#else
|
||||
int configureMAC(uint32_t destip, uint64_t destmac, uint64_t sourcemac, uint32_t sourceip, uint32_t udpport);
|
||||
#endif
|
||||
|
||||
#if defined(JUNGFRAUD) || defined(EIGERD)
|
||||
int setDetectorPosition(int pos[]);
|
||||
#endif
|
||||
#if defined(CHIPTESTBOARDD) || defined(MOENCHD) || defined(EIGERD)
|
||||
int enableTenGigabitEthernet(int val);
|
||||
#endif
|
||||
|
||||
|
||||
// very detector specific
|
||||
|
||||
// moench specific - powerchip
|
||||
#ifdef MOENCHD
|
||||
int powerChip (int on);
|
||||
#endif
|
||||
|
||||
// chip test board or moench specific - configure frequency, phase, pll, flashing firmware
|
||||
#if defined(CHIPTESTBOARDD) || defined(MOENCHD)
|
||||
void configurePhase(enum CLKINDEX ind, int val, int degrees);
|
||||
int getPhase(enum CLKINDEX ind, int degrees);
|
||||
int getMaxPhase(enum CLKINDEX ind);
|
||||
int validatePhaseinDegrees(enum speedVariable ind, int val, int retval);
|
||||
void configureFrequency(enum CLKINDEX ind, int val);
|
||||
int getFrequency(enum CLKINDEX ind);
|
||||
void configureSyncFrequency(enum CLKINDEX ind);
|
||||
void setAdcOffsetRegister(int adc, int val);
|
||||
int getAdcOffsetRegister(int adc);
|
||||
extern void eraseFlash(); // programfpga.h
|
||||
extern int startWritingFPGAprogram(FILE** filefp); // programfpga.h
|
||||
extern void stopWritingFPGAprogram(FILE* filefp); // programfpga.h
|
||||
extern int writeFPGAProgram(char* fpgasrc, size_t fsize, FILE* filefp); // programfpga.h
|
||||
// patterns
|
||||
uint64_t writePatternIOControl(uint64_t word);
|
||||
uint64_t writePatternClkControl(uint64_t word);
|
||||
uint64_t readPatternWord(int addr);
|
||||
uint64_t writePatternWord(int addr, uint64_t word);
|
||||
int setPatternWaitAddress(int level, int addr);
|
||||
uint64_t setPatternWaitTime(int level, uint64_t t);
|
||||
void setPatternLoop(int level, int *startAddr, int *stopAddr, int *nLoop);
|
||||
int setLEDEnable(int enable);
|
||||
void setDigitalIODelay(uint64_t pinMask, int delay);
|
||||
void setPatternMask(uint64_t mask);
|
||||
uint64_t getPatternMask();
|
||||
void setPatternBitMask(uint64_t mask);
|
||||
uint64_t getPatternBitMask();
|
||||
#endif
|
||||
|
||||
// gotthard specific - image, pedestal
|
||||
#ifdef GOTTHARDD
|
||||
void loadImage(enum imageType index, short int imageVals[]);
|
||||
int readCounterBlock(int startACQ, short int counterVals[]);
|
||||
int resetCounterBlock(int startACQ);
|
||||
|
||||
// jungfrau specific - powerchip, autocompdisable, clockdiv, asictimer, clock, pll, flashing firmware
|
||||
#elif JUNGFRAUD
|
||||
int powerChip (int on);
|
||||
int autoCompDisable(int on);
|
||||
void configureASICTimer();
|
||||
void setClockDivider(int val);
|
||||
int getClockDivider();
|
||||
void setAdcPhase(int val, int degrees);
|
||||
int getPhase(int degrees);
|
||||
int getMaxPhaseShift();
|
||||
int validatePhaseinDegrees(int val, int retval);
|
||||
int setThresholdTemperature(int val);
|
||||
int setTemperatureControl(int val);
|
||||
int setTemperatureEvent(int val);
|
||||
extern void eraseFlash(); // programfpga.h
|
||||
extern int startWritingFPGAprogram(FILE** filefp); // programfpga.h
|
||||
extern void stopWritingFPGAprogram(FILE* filefp); // programfpga.h
|
||||
extern int writeFPGAProgram(char* fpgasrc, size_t fsize, FILE* filefp); // programfpga.h
|
||||
void alignDeserializer();
|
||||
|
||||
// eiger specific - iodelay, pulse, rate, temp, activate, delay nw parameter
|
||||
#elif EIGERD
|
||||
int setIODelay(int val);
|
||||
int setCounterBit(int val);
|
||||
int pulsePixel(int n, int x, int y);
|
||||
int pulsePixelNMove(int n, int x, int y);
|
||||
int pulseChip(int n);
|
||||
int64_t setRateCorrection(int64_t custom_tau_in_nsec);
|
||||
int getRateCorrectionEnable();
|
||||
int getDefaultSettingsTau_in_nsec();
|
||||
void setDefaultSettingsTau_in_nsec(int t);
|
||||
int64_t getCurrentTau();
|
||||
void setExternalGating(int enable[]);
|
||||
int setAllTrimbits(int val);
|
||||
int getAllTrimbits();
|
||||
int getBebFPGATemp();
|
||||
int activate(int enable);
|
||||
#endif
|
||||
|
||||
#if defined(JUNGFRAUD) || defined(EIGERD)
|
||||
int setNetworkParameter(enum NETWORKINDEX mode, int value);
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
// aquisition
|
||||
#ifdef EIGERD
|
||||
int prepareAcquisition();
|
||||
#endif
|
||||
int startStateMachine();
|
||||
#ifdef VIRTUAL
|
||||
void* start_timer(void* arg);
|
||||
#endif
|
||||
int stopStateMachine();
|
||||
#ifdef EIGERD
|
||||
int softwareTrigger();
|
||||
#endif
|
||||
|
||||
#ifdef EIGERD
|
||||
int startReadOut();
|
||||
#endif
|
||||
enum runStatus getRunStatus();
|
||||
void readFrame(int *ret, char *mess);
|
||||
#if defined(CHIPTESTBOARDD) || defined(MOENCHD)
|
||||
void readandSendUDPFrames(int *ret, char *mess);
|
||||
void unsetFifoReadStrobes();
|
||||
void readSample(int ns);
|
||||
uint32_t checkDataInFifo();
|
||||
int checkFifoForEndOfAcquisition();
|
||||
int readFrameFromFifo();
|
||||
#endif
|
||||
|
||||
#if defined(GOTTHARDD) || defined(JUNGFRAUD) || defined(CHIPTESTBOARDD) || defined(MOENCHD)
|
||||
u_int32_t runBusy();
|
||||
#endif
|
||||
|
||||
#ifdef GOTTHARDD
|
||||
u_int32_t runState(enum TLogLevel lev);
|
||||
#endif
|
||||
|
||||
|
||||
//common
|
||||
#ifdef EIGERD
|
||||
int copyModule(sls_detector_module *destMod, sls_detector_module *srcMod);
|
||||
#endif
|
||||
int calculateDataBytes();
|
||||
int getTotalNumberOfChannels();
|
||||
int getNumberOfChips();
|
||||
int getNumberOfDACs();
|
||||
int getNumberOfChannelsPerChip();
|
||||
|
||||
|
||||
145
slsDetectorServers/slsDetectorServer/slsDetectorServer.c
Executable file
145
slsDetectorServers/slsDetectorServer/slsDetectorServer.c
Executable file
@@ -0,0 +1,145 @@
|
||||
/* A simple server in the internet domain using TCP
|
||||
The port number is passed as an argument */
|
||||
|
||||
#include "sls_detector_defs.h"
|
||||
#include "logger.h"
|
||||
#include "communication_funcs.h"
|
||||
#include "slsDetectorServer_funcs.h"
|
||||
#include "slsDetectorServer_defs.h"
|
||||
#include "versionAPI.h"
|
||||
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
// Global variables from communication_funcs
|
||||
extern int isControlServer;
|
||||
extern int ret;
|
||||
|
||||
// Global variables from slsDetectorServer_funcs
|
||||
extern int sockfd;
|
||||
extern int debugflag;
|
||||
|
||||
// Global variables from slsDetectorFunctionList
|
||||
#ifdef GOTTHARDD
|
||||
extern int phaseShift;
|
||||
#endif
|
||||
|
||||
void error(char *msg){
|
||||
perror(msg);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]){
|
||||
|
||||
// print version
|
||||
if (argc > 1 && !strcasecmp(argv[1], "-version")) {
|
||||
int version = 0;
|
||||
#ifdef GOTTHARDD
|
||||
version = APIGOTTHARD;
|
||||
#elif EIGERD
|
||||
version = APIEIGER;
|
||||
#elif JUNGFRAUD
|
||||
version = APIJUNGFRAU;
|
||||
#elif CHIPTESTBOARDD
|
||||
version = APICTB;
|
||||
#elif MOENCHD
|
||||
version = APIMOENCH;
|
||||
#endif
|
||||
FILE_LOG(logINFO, ("SLS Detector Server %s (0x%x)\n", GITBRANCH, version));
|
||||
}
|
||||
|
||||
int portno = DEFAULT_PORTNO;
|
||||
int retval = OK;
|
||||
int fd = 0;
|
||||
|
||||
// if socket crash, ignores SISPIPE, prevents global signal handler
|
||||
// subsequent read/write to socket gives error - must handle locally
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
|
||||
// circumvent the basic tests
|
||||
{
|
||||
int i;
|
||||
for (i = 1; i < argc; ++i) {
|
||||
if(!strcasecmp(argv[i],"-stopserver")) {
|
||||
FILE_LOG(logINFO, ("Detected stop server\n"));
|
||||
isControlServer = 0;
|
||||
}
|
||||
else if(!strcasecmp(argv[i],"-devel")){
|
||||
FILE_LOG(logINFO, ("Detected developer mode\n"));
|
||||
debugflag = 1;
|
||||
}
|
||||
#ifdef GOTTHARDD
|
||||
else if(!strcasecmp(argv[i],"-phaseshift")){
|
||||
if ((i + 1) >= argc) {
|
||||
FILE_LOG(logERROR, ("no phase shift value given. Exiting.\n"));
|
||||
return -1;
|
||||
}
|
||||
if (sscanf(argv[i + 1], "%d", &phaseShift) == 0) {
|
||||
FILE_LOG(logERROR, ("cannot decode phase shift value %s. Exiting.\n", argv[i + 1]));
|
||||
return -1;
|
||||
}
|
||||
FILE_LOG(logINFO, ("Detected phase shift of %d\n", phaseShift));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef STOP_SERVER
|
||||
char cmd[100];
|
||||
memset(cmd, 0, 100);
|
||||
#endif
|
||||
if (isControlServer) {
|
||||
portno = DEFAULT_PORTNO;
|
||||
FILE_LOG(logINFO, ("Opening control server on port %d \n", portno));
|
||||
#ifdef STOP_SERVER
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < argc; ++i)
|
||||
sprintf(cmd, "%s %s", cmd, argv[i]);
|
||||
sprintf(cmd,"%s -stopserver&", cmd);
|
||||
FILE_LOG(logDEBUG1, ("Command to start stop server:%s\n", cmd));
|
||||
system(cmd);
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
portno = DEFAULT_PORTNO + 1;
|
||||
FILE_LOG(logINFO,("Opening stop server on port %d \n", portno));
|
||||
}
|
||||
|
||||
init_detector();
|
||||
|
||||
{ // bind socket
|
||||
sockfd = bindSocket(portno);
|
||||
if (ret == FAIL)
|
||||
return -1;
|
||||
}
|
||||
|
||||
// assign function table
|
||||
function_table();
|
||||
|
||||
if (isControlServer) {
|
||||
FILE_LOG(logINFOBLUE, ("Control Server Ready...\n\n"));
|
||||
} else {
|
||||
FILE_LOG(logINFO, ("Stop Server Ready...\n\n"));
|
||||
}
|
||||
|
||||
// waits for connection
|
||||
while(retval != GOODBYE && retval != REBOOT) {
|
||||
fd = acceptConnection(sockfd);
|
||||
if (fd > 0) {
|
||||
retval = decode_function(fd);
|
||||
closeConnection(fd);
|
||||
}
|
||||
}
|
||||
|
||||
exitServer(sockfd);
|
||||
|
||||
if (retval == REBOOT) {
|
||||
FILE_LOG(logINFOBLUE,("Rebooting!\n"));
|
||||
fflush(stdout);
|
||||
system("reboot");
|
||||
}
|
||||
FILE_LOG(logINFO,("Goodbye!\n"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
3856
slsDetectorServers/slsDetectorServer/slsDetectorServer_funcs.c
Executable file
3856
slsDetectorServers/slsDetectorServer/slsDetectorServer_funcs.c
Executable file
File diff suppressed because it is too large
Load Diff
95
slsDetectorServers/slsDetectorServer/slsDetectorServer_funcs.h
Executable file
95
slsDetectorServers/slsDetectorServer/slsDetectorServer_funcs.h
Executable file
@@ -0,0 +1,95 @@
|
||||
#pragma once
|
||||
#include "sls_detector_defs.h"
|
||||
#include "logger.h"
|
||||
|
||||
enum numberMode {DEC, HEX};
|
||||
#define GOODBYE (-200)
|
||||
#define REBOOT (-400)
|
||||
|
||||
// initialization functions
|
||||
int printSocketReadError();
|
||||
void init_detector();
|
||||
int decode_function(int);
|
||||
const char* getRetName();
|
||||
const char* getTimerName(enum timerIndex ind);
|
||||
const char* getSpeedName(enum speedVariable ind);
|
||||
const char* getFunctionName(enum detFuncs func);
|
||||
void function_table();
|
||||
void functionNotImplemented();
|
||||
void modeNotImplemented(char* modename, int mode);
|
||||
void validate(int arg, int retval, char* modename, enum numberMode nummode);
|
||||
void validate64(int64_t arg, int64_t retval, char* modename, enum numberMode nummode);
|
||||
int executeCommand(char* command, char* result, enum TLogLevel level);
|
||||
int M_nofunc(int);
|
||||
int M_nofuncMode(int);
|
||||
|
||||
// functions called by client
|
||||
int exec_command(int);
|
||||
int get_detector_type(int);
|
||||
int set_external_signal_flag(int);
|
||||
int set_external_communication_mode(int);
|
||||
int get_id(int);
|
||||
int digital_test(int);
|
||||
int set_dac(int);
|
||||
int get_adc(int);
|
||||
int write_register(int);
|
||||
int read_register(int);
|
||||
int set_module(int);
|
||||
int get_module(int);
|
||||
int set_settings(int);
|
||||
int get_threshold_energy(int);
|
||||
int start_acquisition(int);
|
||||
int stop_acquisition(int);
|
||||
int start_readout(int);
|
||||
int get_run_status(int);
|
||||
int start_and_read_all(int);
|
||||
int read_all(int);
|
||||
int set_timer(int);
|
||||
int get_time_left(int);
|
||||
int set_dynamic_range(int);
|
||||
int set_readout_flags(int);
|
||||
int set_roi(int);
|
||||
int set_speed(int);
|
||||
int exit_server(int);
|
||||
int lock_server(int);
|
||||
int get_last_client_ip(int);
|
||||
int set_port(int);
|
||||
int update_client(int);
|
||||
int send_update(int);
|
||||
int configure_mac(int);
|
||||
int load_image(int);
|
||||
int read_counter_block(int);
|
||||
int reset_counter_block(int);
|
||||
int calibrate_pedestal(int);
|
||||
int enable_ten_giga(int);
|
||||
int set_all_trimbits(int);
|
||||
int set_pattern(int);
|
||||
int set_pattern_mask(int);
|
||||
int get_pattern_mask(int);
|
||||
int set_pattern_bit_mask(int);
|
||||
int get_pattern_bit_mask(int);
|
||||
int write_adc_register(int);
|
||||
int set_counter_bit(int);
|
||||
int pulse_pixel(int);
|
||||
int pulse_pixel_and_move(int);
|
||||
int pulse_chip(int);
|
||||
int set_rate_correct(int);
|
||||
int get_rate_correct(int);
|
||||
int set_network_parameter(int);
|
||||
int program_fpga(int);
|
||||
int reset_fpga(int);
|
||||
int power_chip(int);
|
||||
int set_activate(int);
|
||||
int prepare_acquisition(int);
|
||||
int threshold_temp(int);
|
||||
int temp_control(int);
|
||||
int temp_event(int);
|
||||
int auto_comp_disable(int);
|
||||
int storage_cell_start(int);
|
||||
int check_version(int);
|
||||
int software_trigger(int);
|
||||
int led(int);
|
||||
int digital_io_delay(int);
|
||||
int copy_detector_server(int);
|
||||
int reboot_controller(int);
|
||||
|
||||
Reference in New Issue
Block a user