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

ADd i2c files

parent 547c7135
No related branches found
No related tags found
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.
Finish editing this message first!
Please register or to comment