Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
S
Software
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Container Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Dmytro Levit
Software
Commits
b140d4fb
Commit
b140d4fb
authored
6 years ago
by
Patrick Robbe
Browse files
Options
Downloads
Patches
Plain Diff
ADd i2c files
parent
547c7135
No related branches found
No related tags found
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
Lib/src/ltc2990/i2c_ltc2990_lib.c
+0
-294
0 additions, 294 deletions
Lib/src/ltc2990/i2c_ltc2990_lib.c
Lib/src/minipods/i2cDriver.c
+656
-0
656 additions, 0 deletions
Lib/src/minipods/i2cDriver.c
with
656 additions
and
294 deletions
Lib/src/ltc2990/i2c_ltc2990_lib.c
deleted
100644 → 0
+
0
−
294
View file @
547c7135
/****************************************************************************************//**
* \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
=
0
b11111
;
factor
=
0
.
0625
;
}
else
{
mask
=
0
b1111111
;
factor
=
0
.
0003051
8
;
}
// 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
.
00001
942
;
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
=
(
0
b10000000
)
&
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.
Click to expand it.
Lib/src/minipods/i2cDriver.c
0 → 100644
+
656
−
0
View file @
b140d4fb
/****************************************************************************************//**
* \file i2cDriver.c
*
* \brief This unit is a simple driver library for I2C bus based on the Open-Core I2C-master.
*
* \author PYD : 12/6/2013
* \version 0.1
* \date 12/6/2013
* PYD : 12/6/2013 initial version
* PYD : 01/10/2018 remove code for ES12 and ES3 versions
*//******************************************************************************************/
#include
<stdio.h>
#include
<error.h>
#include
<stdlib.h>
#include
<unistd.h>
#include
<sys/types.h>
#include
<sys/stat.h>
#include
<fcntl.h>
#define offsetReg(r) (r*4)
//========================= SYSTEM CONFIGURATION =================================
#include
<systemConfig.h>
#include
<ecs.h>
//================================================================================
// USER ORIENTED PROCEDURES FOR EXTERNAL USE
#include
<i2cDriver.h>
//===============================================================================
//#define I2C_FREQ 0xc7 ;#(199dec) value for 100MHz clock to match 100kHz SCL
//#define I2C_FREQ 0x31 ;#(49dec) value for 100MHz clock to match 400kHz SCL
//#define I2C_FREQ 0x18 ;#(24dec) value for 100MHz clock to match 800kHz SCL
// addresses of I2C registers (start at 0xa40 in qsys)
#define I2C_PRELOREG 0x0
#define I2C_PREHIREG 0x1
#define I2C_CTRLREG 0x2
#define I2C_TSMTREG 0x3
#define I2C_RCVREG 0x3
#define I2C_CMDREG 0x4
#define I2C_STATREG 0x4
// Control register
#define I2C_ENA 0x80
#define I2C_DIS 0x00
// Command register bits
#define I2C_STA 0x80
#define I2C_STO 0x40
#define I2C_RD 0x20
#define I2C_WR 0x10
#define I2C_NACK 0x08
#define I2C_IACK 0x01
// Status register bits
#define I2C_TIP 0x02
#define I2C_BUSY 0x40
/***********************************************************************//**
* \fn int unsigned I2C_MakeAvagoAdd(compNb)
* \brief Function to build a device address
*
* For TX(pair) the address is 0101hjkx (hjk is hard add) (x is 1=R 0=W)
*
* For RX(odd) the address is 0110hjkx (hjk is hard add) (x is 1=R 0=W)
*
* NOTE the x is added in Read/Write function
*
* \return the I2c address
*//***********************************************************************/
/*
static unsigned i2c_MakeAvagoAdd(int compNb) {
unsigned i2cAdd;
// partern 0 + 0101/TX or 0110/RX + fixAdd on 3digits
if (compNb%2)
i2cAdd = 5<<3;
else
i2cAdd = 6<<3;
i2cAdd = i2cAdd + compNb;
return(i2cAdd);
}
*/
unsigned
lastSetInCLK
[
MAX_DEV
];
unsigned
LastSetSCLfreq
[
MAX_DEV
];
static
int
getBusBase
(
int
bus
){
switch
(
bus
){
case
I2C_BUS_TEMPERATURES
:
return
(
I2C_BUS_BASE_TEMPERATURES
);
break
;
case
I2C_BUS_PLL_CLEANER1
:
return
(
I2C_BUS_BASE_PLL_CLEANER1
);
break
;
case
I2C_BUS_PLL_CLEANER2
:
return
(
I2C_BUS_BASE_PLL_CLEANER2
);
break
;
case
I2C_BUS_PLL_TFC
:
return
(
I2C_BUS_BASE_PLL_TFC
);
break
;
case
I2C_BUS_SFP1
:
return
(
I2C_BUS_BASE_SFP1
);
break
;
case
I2C_BUS_SFP2
:
return
(
I2C_BUS_BASE_SFP2
);
break
;
case
I2C_BUS_MINIPODS
:
return
(
I2C_BUS_BASE_MINIPODS
);
break
;
case
I2C_BUS_TEMP_MEZZANINE
:
return
(
I2C_BUS_BASE_TEMP_MEZZANINE
);
break
;
case
I2C_BUS_CURRENT1
:
return
(
I2C_BUS_BASE_CURRENT1
);
break
;
case
I2C_BUS_CURRENT2
:
return
(
I2C_BUS_BASE_CURRENT2
);
break
;
case
I2C_BUS_FANOUT
:
return
(
I2C_BUS_BASE_FANOUT
);
break
;
case
I2C_BUS_FPGA_EEPROM
:
return
(
I2C_BUS_BASE_FPGA_EEPROM
);
default:
printf
(
"ERROR: unknown i2c bus number %d in file %s line %d
\n
"
,
bus
,
__FILE__
,
__LINE__
);
return
(
99
);
}
}
/***********************************************************************//**
* \fn void i2c_enable(int dev, int bus)
* \brief Function to activate the i2c-opencore IP.
* \param dev: the board number
* \param bus: the target i2c bus number
*//***********************************************************************/
static
void
i2c_enable
(
int
dev
,
int
bus
)
{
unsigned
cval
=
I2C_ENA
;
ecs_iowrI2c_slow
(
dev
,
getBusBase
(
bus
)
+
(
I2C_CTRLREG
*
4
),
&
cval
);
}
/***********************************************************************//**
* \fn void i2c_disable(int dev,int bus)
* \param dev: the board number
* \brief Function to deactivate the i2c-opencore IP.
* \param bus: the target i2c bus number
*//***********************************************************************/
static
void
i2c_disable
(
int
dev
,
int
bus
)
{
unsigned
cval
=
I2C_DIS
;
ecs_iowrI2c_slow
(
dev
,
getBusBase
(
bus
)
+
(
I2C_CTRLREG
*
4
),
&
cval
);
}
/***********************************************************************//**
* \fn void i2c_stop(int dev,int bus)
* \param dev: the board number
* \brief Function to generate the stop condition on the i2c bus.
* \param bus: the target i2c bus number
*//***********************************************************************/
static
void
i2c_stop
(
int
dev
,
int
bus
)
{
unsigned
cval
=
I2C_STO
;
ecs_iowrI2c_slow
(
dev
,
getBusBase
(
bus
)
+
(
I2C_CMDREG
*
4
),
&
cval
);
}
/****************************************************************************//**
* \fn void i2c_setSpeed(int dev, int bus, int value)
* \brief Function to program the prescale the SCL clock line. Should be called
* before the I2C use.
* \param dev: the board number
* \param bus: the target i2c bus number
* \param value: the value to write in the prescale register
*//**************************************************************************/
static
void
i2c_setSpeed
(
int
dev
,
int
bus
,
int
value
)
{
unsigned
cval
=
value
>>
8
;
int
base
=
getBusBase
(
bus
);
ecs_iowrI2c_slow
(
dev
,
base
+
(
I2C_PREHIREG
*
4
),
&
cval
);
cval
=
value
&
0xFF
;
ecs_iowrI2c_slow
(
dev
,
base
+
(
I2C_PRELOREG
*
4
),
&
cval
);
}
/****************************************************************************//**
* \fn int i2c_init(int dev, int bus, unsigned inCLK, unsigned SCLfreq)
* \brief Function to open access to i2c opencore and set speed
* \ if it is specified
* \param dev: the board number
* \param bus: the target i2c bus number
* \param inCLK: the input system clock ferquency in Hz
* \param SCLfreq: the target SCL clock frequency in Hz
* \return 0 success,-1 error
*//**************************************************************************/
int
i2c_init
(
int
dev
,
int
bus
,
unsigned
inCLK
,
unsigned
SCLfreq
)
{
long
int
prescale
;
// printf("Simulation init with clock %d fequency %d \n",inCLK, SCLfreq); return(0);
if
(
ecs_openLli
(
dev
)
<
0
){
printf
(
"ERROR: Can't init I2C
\n
"
);
return
(
-
1
);
}
i2c_stop
(
dev
,
bus
);
i2c_disable
(
dev
,
bus
);
i2c_enable
(
dev
,
bus
);
// set prescale register
if
(
inCLK
!=
0
&&
SCLfreq
!=
0
){
prescale
=
(
inCLK
/
(
5
*
SCLfreq
))
-
1
;
// printf("PYD i2c i2c_init() bus %d applied speed is %ld\n", bus, prescale);
i2c_setSpeed
(
dev
,
bus
,
prescale
);
lastSetInCLK
[
dev
]
=
inCLK
;
LastSetSCLfreq
[
dev
]
=
SCLfreq
;
}
return
(
0
);
}
/****************************************************************************//**
* \fn int i2c_getInit(int dev, int bus, unsigned &inCLK, unsigned &SCLfreq)
* \brief Read the last values in the prescale of the SCL clock line.
*
* \param dev: the board number
* \param bus: the target i2c bus number
* \param inCLK: the system clock ferquency in Hz
* \param SCLfreq: the target SCL clock frequency in Hz
*//**************************************************************************/
void
i2c_getInit
(
int
dev
,
int
bus
,
unsigned
*
inCLK
,
unsigned
*
SCLfreq
)
{
*
inCLK
=
lastSetInCLK
[
dev
];
*
SCLfreq
=
LastSetSCLfreq
[
dev
];
}
/***********************************************************************************//**
* \fn int _waitTIP()
* \brief function to wait for the status register TIP bit value 0 "transfer complete"
*
* \param dev: the borad number
* \param bus: the target i2c bus number
* \return 0 success,-1 error
*//********************************************************************************/
static
int
i2c_waitTIP
(
int
dev
,
int
bus
)
{
unsigned
val
,
step
=
0
;
int
base
=
getBusBase
(
bus
);
while
(
1
){
usleep
(
10
);
//MJ POUR TEMPO_FERNAND LE 12 SEPT 2017
// printf("step %d\n", step);
step
=
step
+
1
;
if
(
ecs_iordI2c_slow
(
dev
,
base
+
(
I2C_STATREG
*
4
),
&
val
)
==
0
){
// printf("PYD status 0x%x\n", val);
if
((
val
&
I2C_TIP
)
==
0
){
//transfer complete
return
(
0
);
}
else
{
// transfer in progress
if
(
step
>
500
){
printf
(
"ERROR: timeout in i2c_waitTIP()
\n
"
);
return
(
-
1
);
}
else
{
usleep
(
10
);
// printf("PYD wait %d\n", step);
// for (i=0; i<loop; i++) dum++;
}
}
}
else
{
// read error
printf
(
"i2c_waitTIP firmware level read error KO
\n
"
);
return
(
-
1
);
}
}
//while
}
/***********************************************************************//**
* \fn int i2c_readMem(int dev, int bus, unsigned slaveAdd, unsigned regIndex, unsigned *val)
* \brief Function to read one single register
*
* \param dev: the board number
* \param bus: the target i2c bus number
* \param slaveAdd: the address of the device to write in the I2C space
* \param regIndex: the number of the register in the component
* \param val : a pointer to receive the read value
* \return 0 success,-1 error
*//***********************************************************************/
int
i2c_readMem
(
int
dev
,
int
bus
,
unsigned
slaveAdd
,
unsigned
regIndex
,
unsigned
*
val
)
{
unsigned
cval
;
int
base
=
getBusBase
(
bus
);
// generate start command
// write $slaveAdd (slaveAdd+WR bit) in transmitReg
//
// printf("PYD bus=%d i2c_readMem() at base 0x%x subadd 0x%x register %d\n", bus, base, slaveAdd, regIndex);
// printf("Simulation\n"); *val=0x55; return(0);
cval
=
slaveAdd
<<
1
;
ecs_iowrI2c_slow
(
dev
,
base
+
(
I2C_TSMTREG
*
4
),
&
cval
);
// set STA bit and WR bit in commandReg
cval
=
I2C_STA
|
I2C_WR
;
ecs_iowrI2c_slow
(
dev
,
base
+
(
I2C_CMDREG
*
4
),
&
cval
);
// wait fir TIP flaf in statusReg
if
(
i2c_waitTIP
(
dev
,
bus
)
!=
0
)
return
(
-
1
);
// read statusReg to verify RxACK=0
ecs_iordI2c_slow
(
dev
,
base
+
(
I2C_STATREG
*
4
),
&
cval
);
if
((
cval
&
I2C_NACK
)
==
I2C_NACK
){
printf
(
"ERROR: bus=%d i2c_readMem() first transaction slave address not acknowledge in I2C_Write
\n
"
,
bus
);
return
(
-
1
);
}
//
// write $regIndex in transmitReg
//
cval
=
regIndex
;
ecs_iowrI2c_slow
(
dev
,
base
+
(
I2C_TSMTREG
*
4
),
&
cval
);
// set WR bit in commandReg
cval
=
I2C_WR
;
ecs_iowrI2c_slow
(
dev
,
base
+
(
I2C_CMDREG
*
4
),
&
cval
);
// wait fir TIP flaf in statusReg
if
(
i2c_waitTIP
(
dev
,
bus
)
!=
0
)
return
(
-
1
);
// read statusReg to verify RxACK=0
ecs_iordI2c_slow
(
dev
,
base
+
(
I2C_STATREG
*
4
),
&
cval
);
if
((
cval
&
I2C_NACK
)
==
I2C_NACK
){
printf
(
"ERROR:bus %d i2c_readMem() second transaction slave address not acknowledge in I2C_Write
\n
"
,
bus
);
return
(
-
1
);
}
//
// write $slaveAdd (slaveAdd+RD bit) in transmitReg
//
cval
=
slaveAdd
<<
1
|
1
;
ecs_iowrI2c_slow
(
dev
,
base
+
(
I2C_TSMTREG
*
4
),
&
cval
);
// set STA bit and WR bit in commandReg
cval
=
I2C_STA
|
I2C_WR
;
ecs_iowrI2c_slow
(
dev
,
base
+
(
I2C_CMDREG
*
4
),
&
cval
);
// wait fir TIP flaf in statusReg
if
(
i2c_waitTIP
(
dev
,
bus
)
!=
0
)
return
(
-
1
);
// read statusReg to verify RxACK=0
if
((
cval
&
I2C_NACK
)
==
I2C_NACK
){
printf
(
"ERROR: bus %d i2c_readMem() third transaction slave address not acknowledge in I2C_Write
\n
"
,
bus
);
return
(
-
1
);
}
//
// set RD bit, set ACK bit =1(NACK) set STO bit in commandReg
//
cval
=
I2C_RD
|
I2C_NACK
|
I2C_STO
;
ecs_iowrI2c_slow
(
dev
,
base
+
(
I2C_CMDREG
*
4
),
&
cval
);
// wait for TIP flag in statusReg
if
(
i2c_waitTIP
(
dev
,
bus
)
!=
0
)
return
(
-
1
);
return
(
ecs_iordI2c_slow
(
dev
,
base
+
(
I2C_RCVREG
*
4
),
val
)
);
}
/***********************************************************************//**
* \fn int i2c_writeMem(int dev, int bus, unsigned slaveAdd, unsigned regIndex, unsigned *val)
* \brief Function to write a value in a register
*
* \param dev: the board number
* \param bus: the target i2c bus number
* \param slaveAdd: the address of the device to write in the I2C space
* \param regIndex: the number of the register in the component
* \param val : a pointer to the value to write
* \return 0 success,-1 error
*//***********************************************************************/
int
i2c_writeMem
(
int
dev
,
int
bus
,
unsigned
slaveAdd
,
unsigned
regIndex
,
unsigned
*
val
){
unsigned
cval
;
int
base
=
getBusBase
(
bus
);
// generate start command
// printf("bus %d i2c_writeMem() at add 0x%x register %d val %x\n", bus, slaveAdd, regIndex, *val);
// printf("Simulation\n"); return(0);
// write $slaveAdd (slaveAdd+WR bit) in transmitReg
cval
=
slaveAdd
<<
1
;
ecs_iowrI2c_slow
(
dev
,
base
+
(
I2C_TSMTREG
*
4
),
&
cval
);
// set STA bit and WR bit in commandReg
cval
=
I2C_STA
|
I2C_WR
;
ecs_iowrI2c_slow
(
dev
,
base
+
(
I2C_CMDREG
*
4
),
&
cval
);
// wait fir TIP flaf in statusReg
if
(
i2c_waitTIP
(
dev
,
bus
)
!=
0
)
return
(
-
1
);
// read statusReg to verify RxACK=0
ecs_iordI2c_slow
(
dev
,
base
+
(
I2C_STATREG
*
4
),
&
cval
);
if
((
cval
&
I2C_NACK
)
==
I2C_NACK
){
printf
(
"ERROR: bus %d slave address not acknowledge in I2C_Write
\n
"
,
bus
);
return
(
-
1
);
}
//
// write $regIndex in transmitReg
//
cval
=
regIndex
;
ecs_iowrI2c_slow
(
dev
,
base
+
(
I2C_TSMTREG
*
4
),
&
cval
);
// set WR bit in commandReg
cval
=
I2C_WR
;
ecs_iowrI2c_slow
(
dev
,
base
+
(
I2C_CMDREG
*
4
),
&
cval
);
// wait fir TIP flaf in statusReg
if
(
i2c_waitTIP
(
dev
,
bus
)
!=
0
)
return
(
-
1
);
// read statusReg to verify RxACK=0
ecs_iordI2c_slow
(
dev
,
base
+
(
I2C_STATREG
*
4
),
&
cval
);
if
((
cval
&
I2C_NACK
)
==
I2C_NACK
){
printf
(
"ERROR: bus %d slave address not acknowledge in I2C_Write
\n
"
,
bus
);
return
(
-
1
);
}
//
// write $slaveAdd (slaveAdd+RD bit) in transmitReg
//
ecs_iowrI2c_slow
(
dev
,
base
+
(
I2C_TSMTREG
*
4
),
val
);
// set STA bit and WR bit in commandReg
cval
=
I2C_STO
|
I2C_WR
;
ecs_iowrI2c_slow
(
dev
,
base
+
(
I2C_CMDREG
*
4
),
&
cval
);
// wait fir TIP flaf in statusReg
if
(
i2c_waitTIP
(
dev
,
bus
)
!=
0
)
return
(
-
1
);
return
(
0
);
}
/***********************************************************************//**
* \fn int i2c_multReadMemInit(int dev, int bus, unsigned slaveAdd, unsigned regIndex)
* \brief Function to initialize a multiread sequence from slave at
* i2c address slaveAdd starting at device internal register regIndex
*
* \param dev: the board number
* \param bus: the target i2c bus number
* \param slaveAdd: the address of the device to read from in the I2C space
* \param regIndex: the number of the first register in the sequence to read
* \return 0 success,-1 error
*//***********************************************************************/
static
int
i2c_multReadMemInit
(
int
dev
,
int
bus
,
unsigned
slaveAdd
,
unsigned
regIndex
)
{
unsigned
cval
;
int
base
=
getBusBase
(
bus
);
// generate start command
// write $slaveAdd (slaveAdd+WR bit) in transmitReg
//
// printf("PYD start i2c_multReadMemInit\n");
cval
=
slaveAdd
<<
1
;
ecs_iowrI2c_slow
(
dev
,
base
+
(
I2C_TSMTREG
*
4
),
&
cval
);
// set STA bit and WR bit in commandReg
cval
=
I2C_STA
|
I2C_WR
;
ecs_iowrI2c_slow
(
dev
,
base
+
(
I2C_CMDREG
*
4
),
&
cval
);
// printf("PYD wait for TIP flag in statusReg\n");
// wait for TIP flag in statusReg
if
(
i2c_waitTIP
(
dev
,
bus
)
!=
0
)
return
(
-
1
);
// read statusReg to verify RxACK=0
// printf("PYD read statusReg to verify RxACK=0\n");
ecs_iordI2c_slow
(
dev
,
base
+
(
I2C_STATREG
*
4
),
&
cval
);
if
((
cval
&
I2C_NACK
)
==
I2C_NACK
){
printf
(
"ERROR: bus %d slave address not acknowledge in I2C_Write
\n
"
,
bus
);
return
(
-
1
);
}
//
// write $regIndex in transmitReg
//
// printf("PYD write $regIndex in transmitReg\n");
cval
=
regIndex
;
ecs_iowrI2c_slow
(
dev
,
base
+
(
I2C_TSMTREG
*
4
),
&
cval
);
// set WR bit in commandReg
cval
=
I2C_WR
;
ecs_iowrI2c_slow
(
dev
,
base
+
(
I2C_CMDREG
*
4
),
&
cval
);
// wait fir TIP flaf in statusReg
if
(
i2c_waitTIP
(
dev
,
bus
)
!=
0
)
return
(
-
1
);
// read statusReg to verify RxACK=0
ecs_iordI2c_slow
(
dev
,
base
+
(
I2C_STATREG
*
4
),
&
cval
);
if
((
cval
&
I2C_NACK
)
==
I2C_NACK
){
printf
(
"ERROR: bus %d slave address not acknowledge in I2C_Write
\n
"
,
bus
);
return
(
-
1
);
}
//
// write $slaveAdd (slaveAdd+RD bit) in transmitReg
//
// printf("PYD write $slaveAdd (slaveAdd+RD bit) in transmitReg\n");
cval
=
slaveAdd
<<
1
|
1
;
ecs_iowrI2c_slow
(
dev
,
base
+
(
I2C_TSMTREG
*
4
),
&
cval
);
// set STA bit and WR bit in commandReg
cval
=
I2C_STA
|
I2C_WR
;
ecs_iowrI2c_slow
(
dev
,
base
+
(
I2C_CMDREG
*
4
),
&
cval
);
// wait fir TIP flaf in statusReg
if
(
i2c_waitTIP
(
dev
,
bus
)
!=
0
)
return
(
-
1
);
// printf("PYD end i2c_multReadMemInit\n");
return
(
0
);
}
/******************************************************************************//**
* \fn int i2c_multReadMem(int dev, int bus, unsigned slaveAdd, unsigned regIndex, int nb)
* \brief Function to read/print a sequence of nb conscecutive registers from slave at
* i2c address slaveAdd starting at device internal register regIndex
* Used with nb=1 is a function to read one register value
*
* This function allocate the array to store the read data in. The user
* should free it after use.
*
* \param dev: the board number
* \param bus: the target i2c bus number
* \param slaveAdd: the address of the device to read from in the I2C space
* \param regIndex: the number of the first register in the sequence to read
* \param nb : the number of conscecutives registers to read
* \param data : a pointer to receive the data array reference
* \return 0 success,-1 error
*//******************************************************************************/
int
i2c_multReadMem
(
int
dev
,
int
bus
,
unsigned
slaveAdd
,
unsigned
regIndex
,
int
nb
,
unsigned
**
data
)
{
unsigned
cval
;
int
i
;
unsigned
*
bloc
;
int
base
=
getBusBase
(
bus
);
if
(
i2c_multReadMemInit
(
dev
,
bus
,
slaveAdd
,
regIndex
)
!=
0
)
return
(
-
1
);
bloc
=
malloc
(
nb
*
sizeof
(
unsigned
));
if
(
bloc
==
0
){
perror
(
"Can't malloc in i2c_multReadMem()
\n
"
);
return
(
-
1
);
}
/* printf("Reading bytes at slave add 0x%x (%d) starting at internal address 0x%x (%d)\n",
slaveAdd, slaveAdd, regIndex, regIndex);
*/
// Read and display values
cval
=
I2C_RD
;
// printf("PYD read loop\n");
for
(
i
=
0
;
i
<
(
nb
-
1
);
i
++
){
ecs_iowrI2c_slow
(
dev
,
base
+
(
I2C_CMDREG
*
4
),
&
cval
);
// wait for TIP flag in statusReg
if
(
i2c_waitTIP
(
dev
,
bus
)
!=
0
)
return
(
-
1
);
ecs_iordI2c_slow
(
dev
,
base
+
(
I2C_RCVREG
*
4
),
&
bloc
[
i
]);
// printf("PYD 0x%x ");
}
// printf("PYD\n");
// last byte to transfer
cval
=
I2C_RD
|
I2C_NACK
|
I2C_STO
;
ecs_iowrI2c_slow
(
dev
,
base
+
(
I2C_CMDREG
*
4
),
&
cval
);
// wait for TIP flag in statusReg
if
(
i2c_waitTIP
(
dev
,
bus
)
!=
0
)
return
(
-
1
);
ecs_iordI2c_slow
(
dev
,
base
+
(
I2C_RCVREG
*
4
),
&
bloc
[
nb
-
1
]);
*
data
=
bloc
;
return
(
0
);
}
#ifdef MAIN_DRIVER
int
main
(){
unsigned
val
,
i2cAdd
;
unsigned
cval
[
3
];
int
i
,
loop
;
unsigned
val1
[]
=
{
0x4
,
0x5
,
0xc0
};
unsigned
val2
[]
=
{
0xa
,
0xb
,
0x00
};
unsigned
i2cAddTab
[]
=
{
0x28
,
0x31
,
0x2A
,
0x33
,
0x2C
,
0x35
};
unsigned
*
data
;
int
base
;
int
dev
=
0
;
if
(
ecs_openLli
(
dev
)
!=
0
){
perror
(
"Can't access i2c ocore
\n
"
);
exit
(
0
);
}
printf
(
"TEST on PCIe access to ocore regsiters
\n
"
);
printf
(
"======================================
\n
"
);
base
=
I2C_BASE_0
;
// raw test for pcie access to opencore registers
ecs_iordI2c
(
dev
,
base
+
(
I2C_PRELOREG
*
4
),
&
cval
[
0
]);
ecs_iordI2c
(
dev
,
base
+
(
I2C_PREHIREG
*
4
),
&
cval
[
1
]);
ecs_iordI2c
(
dev
,
base
+
(
I2C_CTRLREG
*
4
),
&
cval
[
2
]);
printf
(
"Before ...
\n
"
);
for
(
i
=
0
;
i
<
3
;
i
++
)
printf
(
"Ox%x "
,
cval
[
i
]);
printf
(
"
\n
"
);
ecs_iowrI2c
(
dev
,
base
+
(
I2C_PRELOREG
*
4
),
&
val1
[
0
]);
ecs_iowrI2c
(
dev
,
base
+
(
I2C_PREHIREG
*
4
),
&
val1
[
1
]);
ecs_iowrI2c
(
dev
,
base
+
(
I2C_CTRLREG
*
4
),
&
val1
[
2
]);
printf
(
"After first loop ... should be equal
\n
"
);
ecs_iordI2c
(
dev
,
base
+
(
I2C_PRELOREG
*
4
),
&
cval
[
0
]);
ecs_iordI2c
(
dev
,
base
+
(
I2C_PREHIREG
*
4
),
&
cval
[
1
]);
ecs_iordI2c
(
dev
,
base
+
(
I2C_CTRLREG
*
4
),
&
cval
[
2
]);
for
(
i
=
0
;
i
<
3
;
i
++
)
printf
(
" Ox%x =?= 0x%x |"
,
cval
[
i
],
val1
[
i
]);
printf
(
"
\n
"
);
exit
(
0
);
ecs_iowrI2c
(
dev
,
base
+
(
I2C_PRELOREG
*
4
),
&
val2
[
0
]);
ecs_iowrI2c
(
dev
,
base
+
(
I2C_PREHIREG
*
4
),
&
val2
[
1
]);
ecs_iowrI2c
(
dev
,
base
+
(
I2C_CTRLREG
*
4
),
&
val2
[
2
]);
printf
(
"After second loop ... should be equal
\n
"
);
ecs_iordI2c
(
dev
,
base
+
(
I2C_PRELOREG
*
4
),
&
cval
[
0
]);
ecs_iordI2c
(
dev
,
base
+
(
I2C_PREHIREG
*
4
),
&
cval
[
1
]);
ecs_iordI2c
(
dev
,
base
+
(
I2C_CTRLREG
*
4
),
&
cval
[
2
]);
for
(
i
=
0
;
i
<
3
;
i
++
)
printf
(
"Ox%x =?= 0x%x |"
,
cval
[
i
],
val2
[
i
]);
printf
(
"
\n
"
);
printf
(
"
\n
TEST on I2C access to avago registers
\n
"
);
printf
(
"=====================================
\n
"
);
// init and set address for TX 0
// i2c_init(dev, 100000000, 100000); // for TCL/TK because jtag master set this clock
i2c_init
(
dev
,
125000000
,
100000
);
// fast clock with PCI
// i2c_init(dev, 62500000, 100000); // slow clock with PCI
// set i2c address of avago number 0 (a TX)
printf
(
"Select avago number 0 (a TX) as target
\n
"
);
i2cAdd
=
5
<<
3
;
// comp 0 TX
printf
(
"Read register 0 should be 0x00 ---> read "
);
val
=
0xaa
;
i2c_readMem
(
dev
,
i2cAdd
,
0
,
&
val
);
printf
(
"(0x%x)
\n
"
,
val
);
printf
(
"Write NULL in page select register
\n
"
);
val
=
0
;
// select page 0
i2c_writeMem
(
dev
,
i2cAdd
,
127
,
&
val
);
printf
(
"Read read page select register should be NULL ---> read "
);
val
=
0xaa
;
i2c_readMem
(
dev
,
i2cAdd
,
127
,
&
val
);
printf
(
"(0x%x)
\n
"
,
val
);
printf
(
"Write 1 in page select register
\n
"
);
val
=
1
;
// select page 0
i2c_writeMem
(
dev
,
i2cAdd
,
127
,
&
val
);
printf
(
"Read read page select register should be 1 ---> read "
);
val
=
0xaa
;
i2c_readMem
(
dev
,
i2cAdd
,
127
,
&
val
);
printf
(
"(0x%x)
\n
"
,
val
);
printf
(
"Write NULL in page select register
\n
"
);
val
=
0
;
// select page 0
i2c_writeMem
(
dev
,
i2cAdd
,
127
,
&
val
);
printf
(
"Read read page select register should be NULL ---> read "
);
val
=
0xaa
;
i2c_readMem
(
dev
,
i2cAdd
,
127
,
&
val
);
printf
(
"(0x%x)
\n
"
,
val
);
printf
(
"Write 0xff in register 94 squelch
\n
"
);
val
=
0xff
;
// select page 0
i2c_writeMem
(
dev
,
i2cAdd
,
94
,
&
val
);
printf
(
"Read squelch ---> read "
);
val
=
0xaa
;
i2c_readMem
(
dev
,
i2cAdd
,
94
,
&
val
);
printf
(
"(0x%x)
\n
"
,
val
);
printf
(
"Write 0xff in register 95 squelch
\n
"
);
val
=
0xff
;
// select page 0
i2c_writeMem
(
dev
,
i2cAdd
,
95
,
&
val
);
printf
(
"Read squelch ---> read "
);
val
=
0xaa
;
i2c_readMem
(
dev
,
i2cAdd
,
95
,
&
val
);
printf
(
"(0x%x)
\n
"
,
val
);
printf
(
"Read Vendor Name
\n
"
);
loop
=
16
;
// test to read vendor name at reg 152 to 167 (16bytes)
// in module at address 0
for
(
i
=
0
;
i
<
loop
;
i
++
){
val
=
1
;
i2c_readMem
(
dev
,
i2cAdd
,
152
+
i
,
&
val
);
// printf("0x%x %c ", val, (char)val);
printf
(
"%c"
,
(
char
)
val
);
}
printf
(
"
\n
"
);
i2c_multReadMem
(
dev
,
i2cAdd
,
152
,
16
,
&
data
);
for
(
i
=
0
;
i
<
loop
;
i
++
)
printf
(
"%c"
,
(
char
)
data
[
i
]);
printf
(
"
\n
"
);
return
(
0
);
}
#endif
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment