Skip to content
Snippets Groups Projects
Commit b140d4fb authored by Patrick Robbe's avatar Patrick Robbe
Browse files

ADd i2c files

parent 547c7135
Branches
Tags
No related merge requests found
/****************************************************************************************//**
* \file i2c_ltc2990_lib.c
*
* \brief This file contains the user driver to control the 3 ltc2990 ADC components.
*
* \author MJ/PYD
* \version 0.1
* \date : 15/03/2016
* \copyright (c) Copyright CERN for the benefit of the LHCb Collaboration.
* Distributed under the terms of the GNU General Public Licence V3.
* ana.py script is free and open source software.
*
* CHANGELOG
* PYD : 15/03/2016 initial version
* PYD : 16/09/2016 use multiple boards
*//********************************************************************************************/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <systemConfig.h>
#include <i2cDriver.h>
#include <ltc2990.h>
// Temporisation Fernand Raynaud pour basculer entre 2 modes
//TEMPO_FERNAND 0.3
#define BUS_DELAY 300000
// usefull for configuration functions
# define trigger 0x7F
/***********************************************************************//**
* \fn int setConfig(int dev, int bus, unsigned add, unsigned config)
* \brief Function to configure the component
*
* 1) Apply the configuration
* 2) Déclenchement du trigger : on met nimporte quelle valeur dans
* TRIGGER_REGISTER, par exemple 0x7F
* je dis 0x7F car apparement le bit 7 du TRIGGER_REGISTER reste
* toujours à 0, donc la relecture est erronee...
*
* 3) 13/01/2015 : on met une tempo car lorsque l'on change de mode,
* car on a observé que l'on doit attendre un certain temps
* (au sens etymologique de fernand raynaud...) pour basculer
*
* \param bus : the i2c bus number
* \param add : the component add on the i2c bus
* \param config : the value of the config word
* \return 1 success, 0 error
*//***********************************************************************/
static int setConfig(int dev, int bus, unsigned add, unsigned config){
unsigned val = trigger;
// int i2c_writeMem(int bus, unsigned slaveAdd, unsigned regIndex, unsigned *val)
if ( (i2c_writeMem(dev, bus, add, CONTROL_REGISTER_ADDRESS, &config) == -1)
||(i2c_writeMem(dev, bus, add, TRIGGER_REGISTER_ADDRESS, &val ) == -1) ){
printf("Configuration is not OK!!!\n");
return(0);
}
else {
usleep(BUS_DELAY);
// time.sleep(TEMPO_FERNAND)
// printf("Configuration is OK\n");
return(1);
}
}
/***********************************************************************//**
* \fn int setConfig2TR(int dev, int bus, int add)
* \brief Function to configure the component for 2 differential temperature,
* \brief probes, mode repeat, temperature en Celsius
*
* CONTROL_REGISTER= 0x1D (0001 1101), c'est à dire:
* Mode[2:0] = 101 = TR1,TR2
* Mode[4:3] = 11 = All Measurements per Mode[2:0], lectures de registres
* fixees sur TR1,TR2
* Temperature Format = 0 (Temperature reported in Celsius)
* Repeat/Single = 0 (Repeat Acquisition)
*
* \param bus : the i2c bus number
* \param add : the component add on the i2c bus
* \return 1 success, 0 error
*//***********************************************************************/
int Config2TR(int dev, int bus, int add){
printf("ltc2990: onfiguration for 2 TR sensor temperature is running....\n");
return setConfig(dev, bus, add, 0x1D);
}
/***********************************************************************//**
* \fn int setConfig2TR(int bus, int add)
* \brief Function to configure the component for 2 differential tension reading,
* \brief mode repeat, temperature en Celsius
*
* CONTROL_REGISTER= 0x1E (0001 1110), c'est à dire:
* Mode[2:0] = 101 = lecture de V1-V2, V3-V4
* Mode[4:3] = 11 = All Measurements per Mode[2:0],lectures de registres
* fixees sur V1-V2, V3-V4
* Temperature Format = 0 = Temperature reported in Celsius
* Repeat/Single = 0 = Repeat Acquisition
*
* \param bus : the i2c bus number
* \param add : the component add on the i2c bus
* \return 1 success, 0 error
*//***********************************************************************/
int Config2VoltDif(int dev, int bus, int add){
printf("ltc2990: ltc2990 configuration for 2 differential voltage is running....\n");
return setConfig(dev, bus, add, 0x1E);
}
/***********************************************************************//**
* \fn int Config4VoltSingleEnded(int bus, int add)
* \brief Function to configure the component to read 4 tensions single ended,
* \brief mode repeat, temperature en Celsius
*
* CONTROL_REGISTER= 0x1F = 0001 1111, c'est à dire:
* Mode[2:0] = 111 = lecture de V1,V2,V3,V4
* Mode[4:3] = 11 = All Measurements per Mode[2:0],lectures de registres
* fixées sur V1,V2, V3,V4
* Temperature Format = 0 = Temperature reported in Celsius
* Repeat/Single = 0 = Repeat Acquisition
*
* Note : it is important to select Celsius temp because even in this config
* we read the circuit internal temperature
*
* \param bus : the i2c bus number
* \param add : the component add on the i2c bus
* \return 1 success, 0 error
*//***********************************************************************/
int Config4VoltSingleEnded(int dev, int bus, int add){
printf("ltc2990: configuration for 4 single ended voltage is running..\n");
return setConfig(dev, bus, add, 0x1F);
}
/****************************************************************************//**
* \fn int two_comp13(int nb13bits)
* \brief Function to present the right way a complemented to two in 13 bits value,
*
* All temperatures -internal or TR1 or TR2) are in 13bits complemented to 2.
* So we need this conversion function
*
* \return : the converted value
*//*****************************************************************************/
//static int two_comp13(int nb13bits){
static unsigned two_comp13(unsigned nb13bits){
if (nb13bits > 8191){
printf("ltc2990: ERROR number is greater than 8191!!!\n");
nb13bits = 8191;
}
if (nb13bits <= 4095)
return(nb13bits);
else
return(nb13bits-8192);
}
/****************************************************************************//**
* \fn int two_comp15(int nb15bits)
* \brief Function to present the right way a complemented to two in 15 bits value,
*
* All single-ended (V1,V2,V3,V4) or differential (V1-V2, V3-V4) tensions
* are in 15bits complemented to 2.
* So we need this conversion function
*
* \return : the converted value
*//*****************************************************************************/
static int two_comp15(int nb15bits){
if (nb15bits > 32767){
printf("ltc2990: ERROR number is greater than 32767!!!\n");
nb15bits = 32767;
}
if (nb15bits <= 16383)
return(nb15bits);
else
return(nb15bits-32768);
}
/*************************************************************************************************//**
* \fn float ReadTempOrTension(int bus, int add, int msbReg, int lsbReg, int measureType, int inversion)
* \brief Function to read the temperature or tension in the component
*
* We loop reading the MSB register untill bit 7 switch to 1.
* We apply the mask:
* - when temperature reading to extract D8-D12 bits
* - when tension reading D8-D13 and D14 (sign)
* We read the LSB register to concatenate the two words to get the full value
* We then complement the value to 2 and multiply by a constant factor
* - factor = 0.0625 for temp
* - factor = 0.00030518 for tensions
*
* \param bus : the i2c bus number on the board
* \param add : the component i2c address
* \param msbReg : the msb register index
* \param lsbReg : the lsb register index
* \param measureType : type of measure TEMP or VOLT
* \param inversion : for some components the tension is inverted (1 or 0)
*
* \return read value or 0 if failed
*//*************************************************************************************************/
static float ReadTempOrTension(int dev, int bus, unsigned add, unsigned msbReg, unsigned lsbReg, enum type_measure measureType, int inversion){
unsigned mask;
int cpt_timeout = 0;
int DataValidBit = 0;
float factor, RSHUNT, LSB_DIFFERENTIAL;
unsigned LocalTempMSB, dataMSB, dataLSB, dataInteger16;
if (measureType == TEMP){
mask = 0b11111;
factor = 0.0625;
}
else {
mask = 0b1111111;
factor = 0.00030518;
}
// On divise ensuite par la valeur de la resistance de shunt (
// supposee egale a 0.003 ohm) pour avoir la valeur du courant IPEX09V
if (inversion == 1){
RSHUNT = 0.003;
LSB_DIFFERENTIAL = 0.00001942;
factor = LSB_DIFFERENTIAL/RSHUNT;
}
while (!(DataValidBit)){
// int i2c_readMem(int bus, unsigned slaveAdd, unsigned regIndex, unsigned *val)
if (i2c_readMem(dev, bus, add, msbReg, &LocalTempMSB) != 0){
printf("ReadTempOrTension : error readihg i2c register\n");
return(0);
}
// LocalTempMSB = i2c.read(bus, add, msbReg)[1]
DataValidBit = (0b10000000) & LocalTempMSB;
cpt_timeout = cpt_timeout + 1;
if (cpt_timeout > 1000){
printf("ReadTempOrTension : Error Timeout to read\n");
break;
}
}
dataMSB = LocalTempMSB & mask;
// dataLSB = i2c.read(bus, add, lsbReg)[1]
if (i2c_readMem(dev, bus, add, lsbReg, &dataLSB) != 0){
printf("ReadTempOrTension : error readihg i2c register\n");
return(0);
}
dataInteger16 = dataMSB*256 + dataLSB;
if (measureType == TEMP){
return(two_comp13(dataInteger16)*factor);
}
else {
if (inversion == 1)
return (-two_comp15(dataInteger16)*factor);
else
return (two_comp15(dataInteger16)*factor);
}
}
float ReadLocalTemperature(int dev, int bus, unsigned add){
enum type_measure temp = TEMP;
return(ReadTempOrTension(dev, bus, add, TINTMSB_REGISTER_ADDRESS, TINTLSB_REGISTER_ADDRESS, temp, 0));
}
float ReadTR1(int dev, int bus,unsigned add){
enum type_measure temp = TEMP;
return(ReadTempOrTension(dev, bus, add, V1MSB_REGISTER_ADDRESS, V1LSB_REGISTER_ADDRESS, temp, 0));
}
float ReadTR2(int dev, int bus,unsigned add){
enum type_measure temp = TEMP;
return (ReadTempOrTension(dev, bus, add, V3MSB_REGISTER_ADDRESS, V3LSB_REGISTER_ADDRESS, temp, 0));
}
float ReadV1(int dev, int bus,unsigned add){
enum type_measure tens = VOLT;
return(ReadTempOrTension(dev, bus, add, V1MSB_REGISTER_ADDRESS, V1LSB_REGISTER_ADDRESS, tens, 0));
}
float ReadV2(int dev, int bus,unsigned add){
enum type_measure tens = VOLT;
return(ReadTempOrTension(dev, bus, add, V2MSB_REGISTER_ADDRESS, V2LSB_REGISTER_ADDRESS, tens, 0));
}
float ReadV3(int dev, int bus,unsigned add){
enum type_measure tens = VOLT;
return(ReadTempOrTension(dev, bus, add, V3MSB_REGISTER_ADDRESS, V3LSB_REGISTER_ADDRESS, tens, 0));
}
float ReadV4(int dev, int bus,unsigned add){
enum type_measure tens = VOLT;
return(ReadTempOrTension(dev, bus, add, V4MSB_REGISTER_ADDRESS, V4LSB_REGISTER_ADDRESS, tens, 0));
}
float ReadIPEX09V(int dev, int bus,unsigned add){
// Entering this function we have to be in read differential tension mode.
enum type_measure tens = VOLT;
return(ReadTempOrTension(dev, bus, add, V1minV2MSB_REGISTER_ADDRESS, V1minV2LSB_REGISTER_ADDRESS, tens, 1));
}
float ReadIPEX09VDDA(int dev, int bus,unsigned add){
// Entering this function we have to be in read differential tension mode.
enum type_measure tens = VOLT;
return (ReadTempOrTension(dev, bus, add, V3minV4MSB_REGISTER_ADDRESS, V3minV4LSB_REGISTER_ADDRESS, tens, 1));
}
This diff is collapsed.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment