//============================================================================
/*! \file NxI2c.cxx
* \author W.F.J.Mueller/GSI, based on earlier work of Norbert Abel/KIP, Modified for gosipcmd by Joern Adamczewski-Musch/GSI
*/
//============================================================================
#include "NxI2c.h"
/*!
* \class nxyter::NxI2c
* \brief Represents the I2C interface of an nXYTER.
*
* This class represents the I2C interface of an nXYTER. It is derived from
* roc::I2cDevice and provides
* \li a probe() method to check whether an xXYTER is connected
* \li methods to write/read a complete register context to/from an nXYTER,
* see setContext() and getContext()
* \li a method to access the error counters, see getCounters()
* \li a convenience method to manipulate configuration bits,
* see setTestModes()
* \li some convenient methods to write/read the main registers and the
* trim-daq (shift) register.
*
* \note The nxyter::NxContext class represents the nXYTER register context,
* while this class mediates the access to the nXYTER.
*/
//----------------------------------------------------------------------------
//! Constructor with full addressing path information.
/*!
* Sets up \c NxI2c object with full addressing information
* \param board ROC board pointer
* \param port the \ref glo_roc_port (equivalent to the I2C bus interface port)
* \param addr the I2C device slave address
*/
nxyter::NxI2c::NxI2c(NyxorGui* parent, uint8_t id): fOwner(parent),fNxId(id)
{
}
//----------------------------------------------------------------------------
nxyter::NxI2c::~NxI2c()
{
}
//----------------------------------------------------------------------------
//! Write the part or full context to nXYTER with optional readback verify.
/*!
* Updates nXYTER registers with the values given by the context \a cntx.
* The \a domask allows to enable separately whether the mask, core or
* trim part of the register set is written.
* If \a veri is \c true, the context is readback and compared.
*
* \param cntx nXYTER register context container
* \param domask one or several of the mask bits nxyter::kDoMask,
* nxyter::kDoCore, or nxyter::kDoTrim
* \param veri if \c true readback verification done (default is \c true)
* \returns see \ref roc_board_opererr.
*
* \note for the readback verification of a write of the mask register part
* the test trigger mode will temporarily disabled in case it is active.
* This might interfere with data taking and should therefore be avoided
* when DAQ is active.
*
* \sa getContext()
*/
int nxyter::NxI2c::setContext(NxContext& cntx, int domask, bool veri)
{
int rc;
NxContext data;
if (domask & kDoMask) {
rc = setRegMask(cntx.dataRegisterMain());
if (rc) return rc;
}
if (domask & kDoCore) {
rc = setRegCore(cntx.dataRegisterMain());
if (rc) return -1;//Board::operErrBuildInc(rc, 16);
}
if (domask & kDoTrim) {
rc = setRegTrim(cntx.dataRegisterTrim());
if (rc) return -2;//Board::operErrBuildInc(rc, 128);
}
if (veri) {
rc = getContext(data, domask);
if (rc) return -3;//Board::operErrBuildInc(rc, 1000);
if (!cntx.equal(data, domask))
return -4;//Board::operErrBuild(Board::kOperVerifyErr,2000);
}
return 0;
}
//----------------------------------------------------------------------------
//! Read the part or full context from nXYTER.
/*!
* The \a domask allows to enable separately whether the mask, core or
* trim part of the register set is written.
* \param cntx nXYTER register context container
* \param domask one or several of the mask bits nxyter::kDoMask,
* nxyter::kDoCore, or nxyter::kDoTrim
* \returns see \ref roc_board_opererr
*
* \note the two nXYTER error counters are not accessed, to read them use the
* getCounters() method.
* \note for the read of the mask register part the test trigger mode will
* temporarily disabled in case it is active. This might interfere with
* data taking and should therefore be avoided when DAQ is active.
*
* \sa setContext()
*/
int nxyter::NxI2c::getContext(NxContext& cntx, int domask)
{
int rc;
if (domask & kDoMask) {
rc = getRegMask(cntx.dataRegisterMain());
if (rc) return rc;
}
if (domask & kDoCore) {
rc = getRegCore(cntx.dataRegisterMain());
if (rc) return -1;//Board::operErrBuildInc(rc, 16);
}
if (domask & kDoTrim) {
rc = getRegTrim(cntx.dataRegisterTrim());
if (rc) return -2;//Board::operErrBuildInc(rc, 128);
}
return 0;
}
//----------------------------------------------------------------------------
//! Read and clear the error counters from nXYTER.
/*!
* Returns the values of the two error counters of the nXYTER. Note that they
* are read-only and the read access is implemened as read and clear.
* \param overflow Overflow counter
* \param tokenmiss Missing token counter
* \returns see \ref roc_board_opererr
*/
int nxyter::NxI2c::getCounters(uint16_t& overflow, uint16_t& tokenmiss)
{
int rc;
uint8_t data[4];
overflow = 0;
tokenmiss = 0;
rc = getRegisterArray(34, data, 4); // read 34 - 37
if (rc) return rc;
overflow = data[0] + (uint16_t(data[1]) << 8); // reg 34/35
tokenmiss = data[2] + (uint16_t(data[3]) << 8); // reg 36/37
return 0;
}
//----------------------------------------------------------------------------
//! Setup test pulser and test trigger mode.
/*!
* The test pulse input of the nXYTER can be used to
* \li fire a test pulse, coupled into a quarter of the channels
* \li force a hit on all channels
*
* This defines four operation modes, all of which have useful applications.
* This method sets the kNxC0TestPulsEnable and kNxC0TestTrigEnable bits
* in register kNxRegConfig0 according to the arguments \a testpuls and
* \a testtrig. The test pulse polarity, controlled by bit
* kNxC0TestPulsPolarity, is set according to the already configured front-end
* polarity, given by kNxC1FrontEndPolarity in register kNxRegConfig1.
*
* The four possible choices of channel group receiving the test pulse are
* selected by \a calselect and written into the kNxC1CalibSelectMask bits
* of register kNxRegConfig1.
*
* \param testpuls determines whether test pulser mode is enabled
* \param testtrig determines whether test trigger mode is enabled
* \param calselect determines which channel group receives the test pulse. Only
* the 2 LSBs are used:
* \li 0 will select channels 0,4,8,...,124
* \li 1 will select channels 1,5,9,...,125
* \li 2 will select channels 2,6,10,...,126
* \li 3 will select channels 3,7,11,...,127
* \returns see \ref roc_board_opererr
*/
int nxyter::NxI2c::setTestModes(bool testpuls, bool testtrig,
int calselect)
{
int rc;
uint8_t conf0;
uint8_t conf1;
rc = getRegister(kNxRegConfig0, conf0);
if (rc) return -1;//Board::operErrBuild(rc, 0);
rc = getRegister(kNxRegConfig1, conf1);
if (rc) return -2;//Board::operErrBuild(rc, 1);
if (testpuls) {
conf0 |= kNxC0TestPulsEnable;
} else {
conf0 &= ~kNxC0TestPulsEnable;
}
if (testtrig) {
conf0 |= kNxC0TestTrigEnable;
} else {
conf0 &= ~kNxC0TestTrigEnable;
}
if (conf1 & kNxC1FrontEndPolarity) {
conf0 |= kNxC0TestPulsPolarity;
} else {
conf0 &= ~kNxC0TestPulsPolarity;
}
conf1 &= ~kNxC1CalibSelectMask;
conf1 |= uint8_t(calselect) & kNxC1CalibSelectMask;
rc = setRegister(kNxRegConfig0, conf0, true);
if (rc) return -1;//Board::operErrBuild(rc, 2);
rc = setRegister(kNxRegConfig1, conf1, true);
if (rc) return -2;//Board::operErrBuild(rc, 3);
return 0;
}
//----------------------------------------------------------------------------
//! Probe whether an nXYTER exists.
/*!
* This method tries to test in a reliable but as much as possible
* non-intrusive way whether an nXYTER chip is accessible under the
* port and slave address setup for the object. The probe procedure
* uses the registers
* \li 24: test pulse amplitue
* \li 38: test pulse delay
* \li 39: test trigger delay
*
* and performs four steps
* \li read these registers
* \li write distinct values into these registers
* \li read back and check the distinct values
* \li restore the initial settings (saved in first step)
*
* The method aborts and returns with a non-zero return code when any of
* the above operation or tests fail. In case of success the nXYTER chip
* is in the same state as before.
*
* The probe is \e mostly non-intrusive because only registers used in test
* pulse/trigger modes are used, and should therefore not disput normal
* operation.
*
* \note the obvious simple probe, using the mask registers, doesn't work
* because a read to register 0-15 does not return the mask registers when
* the chip is in test trigger mode ! Therefore the registers 24,38, and
* 39 are used.
*
* \returns 0 on success and non-zero if any step fails. See
* \ref roc_board_opererr for details. The index refers to the 12 get and
* set operations and thus allows to precisely pinpoint at what point the
* probe aborted.
*/
int nxyter::NxI2c::probe()
{
int rc(0), res(0);
uint8_t regs[3] = {kNxRegcal, kNxRegdelayTestPuls, kNxRegdelayTestTrig};
uint8_t save[3];
uint8_t back[3];
uint8_t patt[3] = {0x55, 0xaa, 0x5f};
// read and save registers
for (int i=0; i<3; i++) {
rc = getRegister(regs[i], save[i]);
if (rc) return -1;//Board::operErrBuild(rc, i);
}
// write pattern
for (int i=0; i<3; i++) {
rc = setRegister(regs[i], patt[i]);
if (rc && (res==0)) res = -1;//Board::operErrBuild(rc, 3+i);
}
// read and check pattern
for (int i=0; i<3; i++) {
rc = getRegister(regs[i], back[i]);
if (rc && (res==0)) res = -2;//Board::operErrBuild(rc, 6+i);
if ((back[i] != patt[i]) && (res==0))
res = -3;//Board::operErrBuild(Board::kOperVerifyErr, 6+i);
}
// restore registers in any case
for (int i=0; i<3; i++)
setRegister(regs[i], save[i], true);
return res;
}
//----------------------------------------------------------------------------
//! Write default values into nXYTER registers.
/*!
* Constructs a context with default values with and writes these values
* into the associated nXYTER. See documentation of
* NxContext::setToDefault() for description of the parameters
* \a ispos, \a maskon, and \a poweron.
* \returns see \ref roc_board_opererr
*/
int nxyter::NxI2c::setToDefault(bool ispos, int maskon, int poweron)
{
nxyter::NxContext cntx;
cntx.setToDefault(ispos, maskon, poweron);
return setContext(cntx);
}
//----------------------------------------------------------------------------
//! Read nXYTER registers and print to stream \a os.
/*!
* Reads full register context with getContext() and prints them with
* NxContext::print(). For details consult the documentation of these
* two methods.
*/
void nxyter::NxI2c::printRegisters(std::ostream& os, int domask)
{
nxyter::NxContext cntx;
int rc = getContext(cntx, domask);
if (rc) {
os << std::dec;
os << "Failed to read nx context id: " << (int) fNxId
// << " addr: " << std::dec << uint16_t(getSlaveAddr())
// << " " //<< Board::operErrToString(rc)
<< std::endl;
} else {
cntx.print(os, domask);
}
}
//----------------------------------------------------------------------------
//! Write the mask nXYTER register set.
/*!
* Writes the mask registers.
* \param val array with 46 values
* \returns see \ref roc_board_opererr
* \note consider to use setContext().
* \sa getRegMask()
*/
int nxyter::NxI2c::setRegMask(const uint8_t *val)
{
return setRegisterArray(0, val, 16); // regs 0 - 15
}
//----------------------------------------------------------------------------
//! Write the core nXYTER register set.
/*!
* Writes the core registers, this is all except the mask and trim registers
* and the read-only overflow and missing token counter registers, thus
* 16-29,32,33,38,39,43-45.
* \param val array with 46 values
* \returns see \ref roc_board_opererr
* \sa getRegCore()
* \note consider to use setContext().
*/
int nxyter::NxI2c::setRegCore(const uint8_t *val)
{
int rc;
rc = setRegisterArray(16, val+16, 14); // regs 16 - 29
if (rc) return rc;
rc = setRegisterArray(32, val+32, 2); // regs 32 - 33
if (rc) return -1;//Board::operErrBuildInc(rc, 14);
rc = setRegisterArray(38, val+38, 2); // regs 38 - 39
if (rc) return rc;//Board::operErrBuildInc(rc, 16);
rc = setRegisterArray(43, val+43, 3); // regs 43 - 45
if (rc) return rc;//Board::operErrBuildInc(rc, 19);
return 0;
}
//----------------------------------------------------------------------------
//! Write 129 8 bit data values to the trim-daq register 42.
/*!
* \param val array with 129 values, [0..127] holds channel 0 to 127
* and [128] the test channel value.
* \returns see \ref roc_board_opererr
*
* \note consider to use setContext().
* \note \a val and nXYTER storage order differ, the test channel data
* is in \a val[128] while it is the first value to be written into the chip.
* \sa getRegTrim()
*/
int nxyter::NxI2c::setRegTrim(const uint8_t *val)
{
int rc;
rc = setRegister(kNxRegTrimDAQPower, val[128]);
if (rc) return rc;//Board::operErrBuild(rc, 128);
rc = setMailboxRegister(kNxRegTrimDAQPower, val, 128);
if (rc) return rc;//Board::operErrBuildInc(rc, 1);
return 0;
}
//----------------------------------------------------------------------------
//! Read the mask nXYTER register set.
/*!
* Reads the mask registers.
* \param val array with 46 values
* \returns see \ref roc_board_opererr
* \note consider to use getContext().
* \note for the read of the mask register part the test trigger mode will
* temporarily disabled in case it is active. This might interfere with
* data taking and should therefore be avoided when DAQ is active. To
* retrieve the mask bits directly use getRegisterArray().
* \sa setRegMask()
*/
int nxyter::NxI2c::getRegMask(uint8_t *val)
{
int rc;
uint8_t conf0;
rc = getRegister(kNxRegConfig0, conf0);
if (rc) return rc;
if (conf0 & kNxC0TestTrigEnable) { // temporary test trigger disable
rc = setRegister(kNxRegConfig0, (conf0 & ~kNxC0TestTrigEnable));
if (rc) return rc;
}
rc = getRegisterArray(0, val, 16); // regs 0 - 15
if (rc) return rc;
if (conf0 & kNxC0TestTrigEnable) { // reenable test trigger
rc = setRegister(kNxRegConfig0, conf0);
if (rc) return rc;
}
return 0;
}
//----------------------------------------------------------------------------
//! Read the core nXYTER register set.
/*!
* Reads the core registers, this is all except the mask and trim registers
* and the read-only overflow and missing token counter registers, thus
* 16-29,32,33,38,39,43-45.
* \param val array with 46 values
* \returns see \ref roc_board_opererr
* \sa setRegCore()
* \note consider to use getContext().
*/
int nxyter::NxI2c::getRegCore(uint8_t *val)
{
int rc;
rc = getRegisterArray(16, val+16, 14); // regs 16 - 29
if (rc) return rc;
rc = getRegisterArray(32, val+32, 2); // regs 32 - 33
if (rc) return -1;//Board::operErrBuildInc(rc, 14);
rc = getRegisterArray(38, val+38, 2); // regs 38 - 39
if (rc) return -2;//Board::operErrBuildInc(rc, 16);
rc = getRegisterArray(43, val+43, 3); // regs 43 - 45
if (rc) return -3;// Board::operErrBuildInc(rc, 19);
return 0;
}
//----------------------------------------------------------------------------
//! Read 129 8 bit data values from the trim-daq register 42.
/*!
* \param val array with 129 values, [0..127] holds channel 0 to 127
* and [128] the test channel value.
* \returns see \ref roc_board_opererr
* \bug This implementation is currently not atomic ! Two concurrent executions
* of this method will destroy the content of the nXYTER trim-daq
* register !
*
* \note consider to use getContext().
* \note \a val and nXYTER storage order differ, the test channel data
* is in \a val[128] while it is the first value to be read from the chip.
* \sa setRegTrim()
*/
int nxyter::NxI2c::getRegTrim(uint8_t *val)
{
int rc;
// The trimdaq register is a 129 stage shift register
// Reg 42 must be read and rewritten 129 times to retrieve the contents
// The code below uses setRegisterVerify() to combine a write and read
// into a single transaction and gain thus some speed.
rc = getRegister(kNxRegTrimDAQPower, val[128]);
if (rc) return -1;//Board::operErrBuild(rc, 128);
uint8_t valrewrite = val[128];
for (int i=0; i<128; i++) {
rc = setRegisterVerify(kNxRegTrimDAQPower, valrewrite, val[i]);
valrewrite = val[i];
if (rc) return -2;//Board::operErrBuild(rc, i);
}
rc = setRegister(kNxRegTrimDAQPower, valrewrite);
if (rc) return -3; //Board::operErrBuild(rc, 127);
return 0;
}
//----------------------------------------------------------------------------
//! Returns name for register \a reg (or "" if undefined).
const char* nxyter::NxI2c::registerName(int reg)
{
static const char* names[46] = {"mask_000_007", // reg 0
"mask_008_015",
"mask_016_023",
"mask_024_031",
"mask_032_039",
"mask_040_047",
"mask_048_055",
"mask_056_063",
"mask_064_071", // reg 7
"mask_072_079",
"mask_080_087",
"mask_088_095",
"mask_096_103",
"mask_104_111",
"mask_112_119",
"mask_120_127",
"Vcg", // reg 16
"Icgfoll", // reg 17
"Vth", // reg 18
"Vbfb", // reg 19
"VbiasF", // reg 20
"VbiasS", // reg 21
"VbiasS2", // reg 22
"Vcm", // reg 23
"cal", // reg 24
"iCOMP", // reg 25
"iDUR", // reg 26
"iINV", // reg 27
"iPDH", // reg 28
"iTWC", // reg 29
"", // reg 30
"", // reg 31
"Config0", // reg 32
"Config1", // reg 33
"OverflowLSB", // reg 34
"OverflowMSB", // reg 35
"MissTokenLSB", // reg 36
"MissTokenMSB", // reg 37
"delayTestPuls",// reg 38
"delayTestTrig",// reg 39
"", // reg 40
"", // reg 41
"TrimDAQ-Power",// reg 42
"delayClock1", // reg 43
"delayClock2", // reg 44
"delayClock3" // reg 45
};
if (reg < 0 || reg >=46) return "";
return names[reg];
}
//----------------------------------------------------------------------------
//! Returns descriptive string for configuration bit \a bit.
/*!
* The nXYTER has two configuration registers (32 and 33). For the purpose
* of method the bits are number through, bit 0 is LSB of register 32,
* bit 8 is LSB of register 33.
*/
const char* nxyter::NxI2c::configurationBitName(int bit)
{
static const char* names[12] = {"test pulse enable", // 0-0
"test pulse synchronize", // 0-1
"test pulse polarity", // 0-2
"test trigger enable", // 0-3
"test trigger synchronize", // 0-4
"disable 32MHz clock", // 0-5
"disable 128 MHz clock", // 0-6
"TS LSB clock select", // 0-7
"calibration select bit 0", // 1-0
"calibration select bit 1", // 1-1
"front-end polarity", // 1-2
"readout clock select" // 1-3
};
if (bit < 0 || bit >=12) return "";
return names[bit];
}
//----------------------------------------------------------------------------
//! Convert delay to a nXYTER delay buffer setting
/*!
* The nXYTER delay buffer settings represent the switch settings of the
* internal delay elements. This method converts a nominal delay value,
* given as an integer number in the range 0 to 80, into a delay buffer
* setting suitable to be written into an nXYTER register.
* \param delay delay value, between 0 and 80
* \returns 8 bit setting, ready to be written to delay buffer register
* \sa settingToDelay()
* \note data taken from nXYTER Manual version: 1.40 (DRAFT) May 25, 2009
*/
uint8_t nxyter::NxI2c::delayToSetting(uint8_t delay)
{
static const uint8_t d2s[81] = {
0, 1, 3, 4, 16, 64, 48, 5, 12, 17,
192, 65, 7, 19, 49, 67, 68, 13, 51, 20,
193, 195, 80, 196, 15, 69, 52, 76, 21, 71,
81, 112, 208, 197, 23, 204, 53, 83, 77, 28,
199, 55, 113, 84, 209, 79, 205, 240, 115, 211,
29, 60, 207, 85, 212, 31, 116, 241, 87, 61,
243, 92, 213, 117, 63, 244, 215, 119, 93, 220,
124, 245, 95, 221, 247, 125, 223, 252, 127, 253,
255
};
return (delay <= 80) ? d2s[delay] : 0xff;
}
//----------------------------------------------------------------------------
//! Convert nXYTER delay buffer setting into a delay
/*!
* The nXYTER delay buffer settings represent the switch settings of the
* internal delay elements. This method converts this setting into a number
* which should correspond to the delay. It is the inverse of delayToSetting().
* It will return 0xff for settings not produced by delayToSetting().
* \param val 8 bit setting, as read from delay buffer register
* \returns delay value, or 0xff of non-recommended setting seen.
* \sa delayToSetting()
*/
uint8_t nxyter::NxI2c::settingToDelay(uint8_t val)
{
for (uint8_t delay=0; delay<=80; delay++) {
if (delayToSetting(delay) == val) return delay;
}
return 0xff;
}
//----------------------------------------------------------------------------
/////////////////////////////////////////////////////////////////////////////////////////////
int nxyter::NxI2c::setRegister(uint8_t reg, uint8_t val, bool veri)
{
// JAM here we use gosipcmd script interface in the owner NyxorGUI class
//std::cout <<"NxI2c, id:"<< fNxId<<" setRegister("<<(int)reg<<","<< (int)val<<","<WriteNyxorI2c(fNxId, reg,val,veri);
return 0;
}
//----------------------------------------------------------------------------
//! Read 8 bit from device register.
/*!
* Reads an 8bit value from device register \a reg and checks
* I2C status for error flags.
*
* \param reg device register number
* \param val value
* \returns see \ref roc_board_opererr
*
* \sa setRegister()
*/
int nxyter::NxI2c::getRegister(uint8_t reg, uint8_t& val)
{
// JAM we first use gosipcmd script interface in the owner NyxorGUI class
val=fOwner->ReadNyxorI2c(fNxId,reg);
// std::cout <<"NxI2c, id:"<< (int)fNxId<<" getRegister("<< (int) reg<<")="<<(int) val << std::endl;
return 0;
}
//----------------------------------------------------------------------------
//! Read 16 bit from device register.
/*!
* Reads an 16bit value from device register \a reg and checks
* I2C status for error flags.
*
* \param reg device register number
* \param val value
* \returns see \ref roc_board_opererr
*
*/
int nxyter::NxI2c::getRegister16(uint8_t reg, uint16_t& val)
{
// bool isput[7];
// uint32_t addr[7];
// uint32_t data[7];
// int rc;
//
// isput[0] = true; addr[0] = ROC_NX_I2C_SWITCH; data[0] = fPort;
// isput[1] = true; addr[1] = ROC_NX_I2C_SLAVEADDR; data[1] = fSlaveAddr;
// isput[2] = true; addr[2] = ROC_NX_I2C_REGISTER; data[2] = reg;
// isput[3] = true; addr[3] = ROC_NX_I2C_READ16; data[3] = 1;
// isput[4] = false; addr[4] = ROC_NX_I2C_DATA;
// isput[5] = false; addr[5] = ROC_NX_I2C_ERROR;
// isput[6] = true; addr[6] = ROC_NX_I2C_READ16; data[6] = 0;
//
// rc = board().operGen(isput, addr, data, 7);
//
// val = uint16_t(data[4]);
//
// if (rc == 0 && data[5] != 0) { // check I2C bus error on get
// rc = Board::kOperBusErr;
// }
return 0;
}
//----------------------------------------------------------------------------
//! Write to device register and return the readback value.
/*!
* Writes the 8bit value \a valset to device register \a reg, reads
* it back and returns the readback value in \a valget.
* The I2C status is checked for error flags after the write and read cycle.
*
* \param reg device register number
* \param valset value to be written
* \param valget value returned from readback
* \returns see \ref roc_board_opererr
*
* \note The method just returns the readback value and does not test whether
* \a valget equals \a valset, thus never returns a Board::kOperVerifyErr
* return code.
*
* \sa setRegister(), getRegister()
*/
int nxyter::NxI2c::setRegisterVerify(uint8_t reg, uint8_t valset,
uint8_t& valget)
{
// JAM implement this since it is needed for shift register handling
//std::cout <<"NxI2c, id:"<< fNxId<<" setRegisterVerify("<<(int)reg<<","<< (int)valset<<","<WriteNyxorI2c(fNxId, reg,valset);
valget=fOwner->ReadNyxorI2c(fNxId, reg);
// bool isput[7];
// uint32_t addr[7];
// uint32_t data[7];
// int rc;
//
// isput[0] = true; addr[0] = ROC_NX_I2C_SWITCH; data[0] = fPort;
// isput[1] = true; addr[1] = ROC_NX_I2C_SLAVEADDR; data[1] = fSlaveAddr;
// isput[2] = true; addr[2] = ROC_NX_I2C_REGISTER; data[2] = reg;
// isput[3] = true; addr[3] = ROC_NX_I2C_DATA; data[3] = valset;
// isput[4] = false; addr[4] = ROC_NX_I2C_ERROR;
// isput[5] = false; addr[5] = ROC_NX_I2C_DATA;
// isput[6] = false; addr[6] = ROC_NX_I2C_ERROR;
//
// rc = board().operGen(isput, addr, data, 7);
//
// valget = uint8_t(data[5]);
//
// if (rc == 0 && data[4] != 0) { // check I2C bus error on put
// rc = -1;//Board::operErrBuild(Board::kOperBusErr, 0);
// }
// if (rc == 0 && data[6] != 0) { // check I2C bus error on readback
// rc = Board::operErrBuild(Board::kOperBusErr, 1);
// }
return 0;
}
//----------------------------------------------------------------------------
//! Write to device register array with optional readback verification.
/*!
* Writes the \a nreg 8bit values from array \a val to an array of device
* registers starting at register number \a reg. When \a veri is \c true,
* each value is readback and verified.
* The I2C error flags are checked for each transfer, writing is stopped
* when the first error is detected.
*
* \param reg first device register number
* \param val value array
* \param nreg number of registers to write
* \param veri if \c true readback verification done (default is \c false)
* \returns see \ref roc_board_opererr
*
* \sa getRegisterArray()
*/
int nxyter::NxI2c::setRegisterArray(uint8_t reg, const uint8_t *val, int nreg,
bool veri)
{
for (int i=0; iEnableI2CRead(fNxId); // this one without reset?
}
void nxyter::NxI2c::disableI2C()
{
fOwner->DisableI2C();
}