From 56601df6184c282695c8c2654a4e5fb1df253e85 Mon Sep 17 00:00:00 2001
From: Patrick Robbe <robbe@lal.in2p3.fr>
Date: Tue, 11 Jun 2019 18:46:10 +0900
Subject: [PATCH] New structure

---
 Pcie40DriverLibraries/pcie40_driverlib.c |   7 +
 Pcie40DriverLibraries/pcie40_driverlib.h |   8 +
 Pcie40DriverLibraries/rules.mk           | 318 +++++++++++
 Pcie40Libraries/Makefile                 | 127 +++++
 Pcie40Libraries/Makefile.conf            |  26 +
 Pcie40Libraries/i2cDriver.c              | 656 +++++++++++++++++++++++
 Pcie40Libraries/i2cDriver.h              |  19 +
 Pcie40Libraries/pcie40_ecs.c             | 351 ++++++++++++
 Pcie40Libraries/pcie40_ecs.h             |  55 ++
 Pcie40Libraries/systemConfig.h           |  61 +++
 10 files changed, 1628 insertions(+)
 create mode 100644 Pcie40DriverLibraries/pcie40_driverlib.c
 create mode 100644 Pcie40DriverLibraries/pcie40_driverlib.h
 create mode 100644 Pcie40DriverLibraries/rules.mk
 create mode 100644 Pcie40Libraries/Makefile
 create mode 100644 Pcie40Libraries/Makefile.conf
 create mode 100644 Pcie40Libraries/i2cDriver.c
 create mode 100644 Pcie40Libraries/i2cDriver.h
 create mode 100644 Pcie40Libraries/pcie40_ecs.c
 create mode 100644 Pcie40Libraries/pcie40_ecs.h
 create mode 100644 Pcie40Libraries/systemConfig.h

diff --git a/Pcie40DriverLibraries/pcie40_driverlib.c b/Pcie40DriverLibraries/pcie40_driverlib.c
new file mode 100644
index 0000000..f938c4f
--- /dev/null
+++ b/Pcie40DriverLibraries/pcie40_driverlib.c
@@ -0,0 +1,7 @@
+#include "pcie40_driverlib.h"
+#include <stdio.h>
+
+int p40_get_devname(int dev, const char* suffix, char *dst, size_t dstlen)
+{
+  return snprintf(dst, dstlen, "/dev/pcie40_%d_%s", dev, suffix);
+}
diff --git a/Pcie40DriverLibraries/pcie40_driverlib.h b/Pcie40DriverLibraries/pcie40_driverlib.h
new file mode 100644
index 0000000..9f8430e
--- /dev/null
+++ b/Pcie40DriverLibraries/pcie40_driverlib.h
@@ -0,0 +1,8 @@
+#ifndef __PCIE40_H
+#define __PCIE40_H
+
+#include <stdlib.h>
+
+int p40_get_devname(int dev, const char *suffix, char *dst, size_t dstlen);
+
+#endif//__PCIE40_H
diff --git a/Pcie40DriverLibraries/rules.mk b/Pcie40DriverLibraries/rules.mk
new file mode 100644
index 0000000..3847904
--- /dev/null
+++ b/Pcie40DriverLibraries/rules.mk
@@ -0,0 +1,318 @@
+BUILD_PREFIX ?=
+LIBDIR_SUFFIX ?=64
+FLEX ?=flex
+LFLAGS ?=
+CFLAGS +=-Wall -g -O3
+CXXFLAGS +=-Wall -g -O3
+DOCRA ?=docra
+ASCIIDOCTOR ?=asciidoctor
+
+define INST_template #file, dst, mode
+INSTALL +=$(BUILD_PREFIX)$(2)/$(notdir $(1))
+ifeq (,$(wildcard $(HERE)/$(1)))
+# Installing using absolute path
+$(BUILD_PREFIX)$(2)/$(notdir $(1)): $(1)
+	@install -m 755 -d $(BUILD_PREFIX)$(2)
+	install -m $(3) $$< $(BUILD_PREFIX)$(2)
+else
+# Installing using relative path
+$(BUILD_PREFIX)$(2)/$(notdir $(1)): $(HERE)/$(1)
+	@install -m 755 -d $(BUILD_PREFIX)$(2)
+	install -m $(3) $$< $(BUILD_PREFIX)$(2)
+endif
+endef
+
+%.out/_dir: $(HERE)/Makefile $(TOP)/rules.mk $(TOP)/flags.mk
+	mkdir -p $*.out && touch $@
+
+define ODIR_template #var, [nodefault]
+ifneq ($(2),nodefault)
+	DEFAULT +=$$($(1))
+endif
+$(1)_ODIR :=$$($(1)).out
+$(1)_ODOT :=$$($(1)_ODIR)/_dir
+
+-include $$(addprefix $$($(1)_ODIR)/,$$($(1)_OBJS:.o=.d))
+
+ODIRS +=$$($(1)_ODIR)
+
+ifeq (,$(wildcard $(shell pwd)/Makefile))
+# Out-of-tree build, external libraries are built locally
+ifdef $(1)_LIBS_S
+$$($(1)): $$(notdir $$($(1)_LIBS_S))
+endif
+else
+# In-tree build, external libraries are in their source dir
+$$($(1)): $$($(1)_LIBS_S)
+endif
+
+ifdef $(1)_DEPS
+$$($(1)): $$($(1)_DEPS)
+endif
+
+######################
+ifdef $(1)_CXXFLAGS
+$(1)_CXXFLAGS +=-I$$($(1)_ODIR)
+
+$$($(1)_ODIR)/%.d $$($(1)_ODIR)/%.pic.d: $(HERE)/%.cpp $$($(1)_ODOT)
+	$$(CXX) $$($(1)_CXXFLAGS) -MM -MT $$(@:.d=.o) $$< > $$@
+
+$$($(1)_ODIR)/%.d $$($(1)_ODIR)/%.pic.d: %.cpp $$($(1)_ODOT)
+	$$(CXX) $$($(1)_CXXFLAGS) -MM -MT $$(@:.d=.o) $$< > $$@
+
+$$($(1)_ODIR)/%.d $$($(1)_ODIR)/%.pic.d: $$($(1)_ODIR)/%.cpp $$($(1)_ODOT)
+	$$(CXX) $$($(1)_CXXFLAGS) -MM -MT $$(@:.d=.o) $$< > $$@
+
+$$($(1)_ODIR)/%.o: %.cpp $$($(1)_ODOT)
+	$$(CXX) $$($(1)_CXXFLAGS) -c -o $$@ $$<
+
+$$($(1)_ODIR)/%.pic.o: %.cpp $$($(1)_ODOT)
+	$$(CXX) $$($(1)_CXXFLAGS) -fPIC -c -o $$@ $$<
+
+$$($(1)_ODIR)/%.o: $(HERE)/%.cpp $$($(1)_ODOT)
+	$$(CXX) $$($(1)_CXXFLAGS) -c -o $$@ $$<
+
+$$($(1)_ODIR)/%.pic.o: $(HERE)/%.cpp $$($(1)_ODOT)
+	$$(CXX) $$($(1)_CXXFLAGS) -fPIC -c -o $$@ $$<
+
+$$($(1)_ODIR)/%.o: $$($(1)_ODIR)/%.cpp $$($(1)_ODOT)
+	$$(CXX) $$($(1)_CXXFLAGS) -c -o $$@ $$<
+
+$$($(1)_ODIR)/%.pic.o: $$($(1)_ODIR)/%.cpp $$($(1)_ODOT)
+	$$(CXX) $$($(1)_CXXFLAGS) -fPIC -c -o $$@ $$<
+
+$$($(1)_ODIR)/%.o: %.c $$($(1)_ODOT)
+	$$(CXX) $$($(1)_CXXFLAGS) -c -o $$@ $$<
+
+$$($(1)_ODIR)/%.pic.o: %.c $$($(1)_ODOT)
+	$$(CXX) $$($(1)_CXXFLAGS) -fPIC -c -o $$@ $$<
+
+$$($(1)_ODIR)/%.o: $(HERE)/%.c $$($(1)_ODOT)
+	$$(CXX) $$($(1)_CXXFLAGS) -c -o $$@ $$<
+
+$$($(1)_ODIR)/%.pic.o: $(HERE)/%.c $$($(1)_ODOT)
+	$$(CXX) $$($(1)_CXXFLAGS) -fPIC -c -o $$@ $$<
+
+$$($(1)_ODIR)/%.o: $$($(1)_ODIR)/%.c $$($(1)_ODOT)
+	$$(CXX) $$($(1)_CXXFLAGS) -c -o $$@ $$<
+
+$$($(1)_ODIR)/%.pic.o: $$($(1)_ODIR)/%.c $$($(1)_ODOT)
+	$$(CXX) $$($(1)_CXXFLAGS) -fPIC -c -o $$@ $$<
+
+$$($(1)_ODIR)/%.l.cpp $$($(1)_ODIR)/%.l.hpp: $(HERE)/%.lpp $$($(1)_ODOT)
+	$(FLEX) $(LFLAGS) --outfile=$$($(1)_ODIR)/$$*.l.cpp --header-file=$$($(1)_ODIR)/$$*.l.hpp $$<
+
+$$($(1)_ODIR)/%.l.o: $$($(1)_ODIR)/%.l.cpp $$($(1)_ODOT)
+	$$(CXX) $$($(1)_CXXFLAGS) -Wno-sign-compare -c -o $$@ $$<
+
+$$($(1)_ODIR)/%.l.pic.o: $$($(1)_ODIR)/%.l.cpp $$($(1)_ODOT)
+	$$(CXX) $$($(1)_CXXFLAGS) -fPIC -Wno-sign-compare -c -o $$@ $$<
+
+ifeq (,$(wildcard $(shell pwd)/Makefile))
+# Out-of-tree build, external libraries are built locally
+ifdef $(1)_LIBS_S
+$$($(1)): $$(notdir $$($(1)_LIBS_S))
+endif
+else
+# In-tree build, external libraries are in their source dir
+$$($(1)): $$($(1)_LIBS_S)
+endif
+
+ifdef $(1)_DEPS
+$$($(1)): $$($(1)_DEPS)
+endif
+
+ifdef $(1)_ARFLAGS
+$$($(1)): $$(addprefix $$($(1)_ODIR)/,$$($(1)_OBJS))
+	$(AR) $$($(1)_ARFLAGS) $$@ $$(filter %.o %.a,$$^)
+else
+$$($(1)): $$(addprefix $$($(1)_ODIR)/,$$($(1)_OBJS))
+	$(CXX) $$($(1)_CXXFLAGS) $$(filter %.o %.a,$$^) -o $$@ $$($(1)_LDFLAGS)
+endif
+
+######################
+else ifdef $(1)_CFLAGS
+$(1)_CFLAGS +=-I$$($(1)_ODIR)
+
+$$($(1)_ODIR)/%.d $$($(1)_ODIR)/%.pic.d: $(HERE)/%.c $$($(1)_ODOT)
+	$$(CC) $$($(1)_CFLAGS) -MM -MT $$(@:.d=.o) $$< > $$@
+
+$$($(1)_ODIR)/%.d $$($(1)_ODIR)/%.pic.d: %.c $$($(1)_ODOT)
+	$$(CC) $$($(1)_CFLAGS) -MM -MT $$(@:.d=.o) $$< > $$@
+
+$$($(1)_ODIR)/%.d $$($(1)_ODIR)/%.pic.d: $$($(1)_ODIR)/%.c $$($(1)_ODOT)
+	$$(CC) $$($(1)_CFLAGS) -MM -MT $$(@:.d=.o) $$< > $$@
+
+$$($(1)_ODIR)/%.o: %.c $$($(1)_ODOT)
+	$$(CC) $$($(1)_CFLAGS) -c -o $$@ $$<
+
+$$($(1)_ODIR)/%.pic.o: %.c $$($(1)_ODOT)
+	$$(CC) $$($(1)_CFLAGS) -fPIC -c -o $$@ $$<
+
+$$($(1)_ODIR)/%.o: $(HERE)/%.c $$($(1)_ODOT)
+	$$(CC) $$($(1)_CFLAGS) -c -o $$@ $$<
+
+$$($(1)_ODIR)/%.pic.o: $(HERE)/%.c $$($(1)_ODOT)
+	$$(CC) $$($(1)_CFLAGS) -fPIC -c -o $$@ $$<
+
+$$($(1)_ODIR)/%.o: $$($(1)_ODIR)/%.c $$($(1)_ODOT)
+	$$(CC) $$($(1)_CFLAGS) -c -o $$@ $$<
+
+$$($(1)_ODIR)/%.pic.o: $$($(1)_ODIR)/%.c $$($(1)_ODOT)
+	$$(CC) $$($(1)_CFLAGS) -fPIC -c -o $$@ $$<
+
+$$($(1)_ODIR)/%.l.c $$($(1)_ODIR)/%.l.h: $(HERE)/%.lpp $$($(1)_ODOT)
+	$(FLEX) $(LFLAGS) --outfile=$$($(1)_ODIR)/$$*.l.c --header-file=$$($(1)_ODIR)/$$*.l.h $$<
+
+$$($(1)_ODIR)/%.l.o: $$($(1)_ODIR)/%.l.c $$($(1)_ODOT)
+	$$(CC) $$($(1)_CFLAGS) -fPIC -Wno-sign-compare -c -o $$@ $$<
+
+$$($(1)_ODIR)/%.l.pic.o: $$($(1)_ODIR)/%.l.c $$($(1)_ODOT)
+	$$(CC) $$($(1)_CFLAGS) -Wno-sign-compare -c -o $$@ $$<
+
+ifdef $(1)_ARFLAGS
+$$($(1)): $$(addprefix $$($(1)_ODIR)/,$$($(1)_OBJS))
+	$(AR) $$($(1)_ARFLAGS) $$@ $$^
+else
+$$($(1)): $$(addprefix $$($(1)_ODIR)/,$$($(1)_OBJS))
+	$(CC) $$($(1)_CFLAGS) $$^ -o $$@ $$($(1)_LDFLAGS)
+endif
+
+######################
+else
+#$$(error no compilation flags defined for target $(1))
+endif
+
+ifdef $(1)_INSTALL
+ifdef $(1)_ARFLAGS
+$$(eval $$(call INST_template,$($(1)),$($(1)_INSTALL),644))
+else
+$$(eval $$(call INST_template,$($(1)),$($(1)_INSTALL),755))
+endif
+endif
+endef
+
+define HDRS_template #var
+	$(foreach hdr,$($(1)_HDRS),$(eval $(call INST_template,$(hdr),$($(1)_HDRS_INSTALL),644)))
+endef
+
+define COPY_template #var, chmod
+	$(foreach hdr,$($(1)),$(eval $(call INST_template,$(hdr),$($(1)_INSTALL),$(2))))
+endef
+
+define LINK_template #var
+INSTALL +=$(BUILD_PREFIX)$($(1)_INSTALL)/$($(1))
+$(BUILD_PREFIX)$($(1)_INSTALL)/$($(1)): $(BUILD_PREFIX)$($(1)_LINK)
+	@install -m 755 -d $(BUILD_PREFIX)$($(1)_INSTALL)
+	ln -s $($(1)_LINK) $$@
+endef
+
+define DEP_template #file
+DEP_DIRS +=$(dir $(1))
+
+ifeq (,$(wildcard $(shell pwd)/Makefile))
+# Out-of-tree build, all targets go to the local folder
+DEFAULT +=$(notdir $(1))
+$(notdir $(1)):
+	$(MAKE) $(notdir $(1)) -f $(dir $(1))Makefile
+.PHONY: $(notdir $(1))
+else
+# In-tree build, each target goes into its source folder
+DEFAULT +=$(1)
+$(1):
+	$(MAKE) $(notdir $(1)) -C $(dir $(1))
+.PHONY: $(1)
+endif
+endef
+
+define MAN_template #var, mansection
+$(1)_ODIR :=$$($(1)).out
+$(1)_ODOT :=$$($(1)_ODIR)/_dir
+$(1)_MAN.ADOC :=$$($(1)_ODIR)/$$(patsubst %.dcrt,%.adoc,$$(notdir $$($(1)_MAN_DCRT)))
+$(1)_MAN :=$$($(1)_ODIR)/$$($(1)).$(2)
+$(1)_MAN.GZ :=$$($(1)_ODIR)/$$($(1)).$(2).gz
+
+MAN +=$$($(1)_MAN.GZ)
+
+ifeq ($(ENABLE_DOCRA), true)
+$$($(1)_MAN.ADOC): $$($(1)_ODOT)
+	docra -l 0 -o $$($(1)_ODIR) $$($(1)_MAN_FLAGS) $$(dir $$($(1)_MAN_DCRT)) $$($(1)_MAN_DCRT)
+
+$$($(1)_MAN): $$($(1)_MAN.ADOC)
+	$(ASCIIDOCTOR) -b manpage $$<
+
+$$($(1)_MAN.GZ): $$($(1)_MAN)
+	gzip -f $$^
+
+ifdef $(1)_MAN_INSTALL
+MANINSTALL +=$(BUILD_PREFIX)$($(1)_MAN_INSTALL)/man$(2)/$$($(1)).$(2).gz
+$(BUILD_PREFIX)$$($(1)_MAN_INSTALL)/man$(2)/$$($(1)).$(2).gz: $$($(1)_MAN.GZ)
+	@install -m 755 -d $(BUILD_PREFIX)$$($(1)_MAN_INSTALL)/man$(2)
+	@cp -v $$< $$@
+endif
+
+endif
+
+.PHONY: $$($(1)_MAN.ADOC) $$($(1)_MAN) $$($(1)_MAN.GZ)
+endef
+
+define ALIAS_template #aliasvar, var, mansection
+
+ifdef $(2)_INSTALL
+INSTALL +=$(BUILD_PREFIX)$($(2)_INSTALL)/$($(1))
+$(BUILD_PREFIX)$$($(2)_INSTALL)/$($(1)):
+	@install -m 755 -d $(BUILD_PREFIX)$$($(2)_INSTALL)
+	ln -s $$($(2)_INSTALL)/$$($(2)) $$@
+endif
+
+ifdef $(2)_MAN_INSTALL
+MANINSTALL +=$(BUILD_PREFIX)$($(2)_MAN_INSTALL)/man$(3)/$($(1)).$(3).gz
+$(BUILD_PREFIX)$$($(2)_MAN_INSTALL)/man$(3)/$$($(1)).$(3).gz:
+	@install -m 755 -d $(BUILD_PREFIX)$$($(2)_MAN_INSTALL)/man$(3)
+	ln -s $$($(2)_MAN_INSTALL)/man$(3)/$$($(2)).$(3).gz $$@
+endif
+
+endef
+
+#dg`make.sub` Each subfolder containing a ``Makefile`` can be build individually by simply issuing ``make`` from there. Dependencies on targets built in other subfolders will be built automatically. This can be used during development to quickly iterate on a single subproject.
+# By default, a sub-project ``Makefile`` implements at least the following targets: _
+# *default*::
+# Builds all library and executable targets.
+# *install*::
+# Copies installable files to their destination.
+# *uninstall*::
+# Removes files copied by both *install* and *maninstall*.
+# *man*::
+# Builds man pages.
+# *maninstall*::
+# Installs man pages under ``$(PREFIX)/share/man``.
+# *clean*::
+# Cleans build directory and deletes final targets.
+# *depclean*::
+# Makes the *clean* target in every dependency of this subproject.
+
+define DEFAULT_template
+default: $$(DEFAULT)
+
+install: $$(INSTALL)
+
+uninstall:
+	$$(RM) $$(INSTALL) $$(MANINSTALL)
+
+man: $$(MAN)
+
+maninstall: $$(MANINSTALL)
+
+clean:
+	$(RM) -r *.out/ $(ODIRS)
+	$(RM) $(DEFAULT)
+
+depclean:
+	for dep_dir in ${DEP_DIRS}; do $(MAKE) -C $$$${dep_dir} clean; done
+
+.PHONY: install uninstall man maninstall clean depclean
+endef
+
+default:
+
+.PHONY: default
diff --git a/Pcie40Libraries/Makefile b/Pcie40Libraries/Makefile
new file mode 100644
index 0000000..333c2da
--- /dev/null
+++ b/Pcie40Libraries/Makefile
@@ -0,0 +1,127 @@
+CC=gcc -fPIC -g
+CFLAGS= -c -Wall 
+LDFLAGS=
+
+#defined global variables and programs to build
+include Makefile.conf
+
+PCIE40_DYN_LIB=../Pcie40DriverLibraries
+PCIE40_INC_DIR=../Pcie40DriverLibraries
+
+OBJ_DIR=obj/
+INC_DIR=inc/
+LIB_DIR=lib/
+
+
+#Files ------------------------------------------------------------------------
+
+#ECS
+ECS_SRC= pcie40_ecs.c
+ECS_OBJ=$(ECS_SRC:%.c=$(OBJ_DIR)%.o)
+
+#Minipods
+MINIPODS_SRC= i2cDriver.c
+MINIPODS_OBJ=$(MINIPODS_SRC:%.c=$(OBJ_DIR)%.o)
+
+#User
+USER_SRC= 
+USER_OBJ=$(USER_SRC:$(SRC_DIR)$(USER_DIR)%.c=$(OBJ_DIR)%.o)
+
+#LTC2990
+LTC2990_SRC= 
+LTC2990_OBJ=$(LTC2990_SRC:$(SRC_DIR)$(LTC2990_DIR)%.c=$(OBJ_DIR)%.o)
+
+# static libraries
+ECS_LIB= libecs.a
+MINIPODS_LIB= libminipods.a
+USER_LIB= libuser.a
+LTC2990_LIB= libltc2990.a
+# dynamic libraries
+USER_DYNLIB= libuser-dyn.so
+LLI_DYNLIB= libpcie40.so
+
+
+all: $(ECS_OBJ) $(ECS_LIB) $(MINIPODS_OBJ) $(MINIPODS_LIB) $(LTC2990_OBJ) $(LTC2990_LIB) $(LLI_DYNLIB) $(USER_LIB) $(USER_DYNLIB)
+
+$(ECS_OBJ): $(OBJ_DIR)%.o : %.c
+	@echo "Construction of ecs objects $@ from $<"
+	mkdir -p obj
+	$(CC) $(CFLAGS) -I . -I $(PCIE40_INC_DIR)  $< -o $@	
+
+$(ECS_LIB) : $(ECS_OBJ)
+	@echo "Construction of ECS Library"
+	mkdir -p lib
+	ar -q $(LIB_DIR)$(ECS_LIB) $(ECS_OBJ)
+	@echo ""
+
+$(MINIPODS_OBJ): $(OBJ_DIR)%.o : $(SRC_DIR)%.c
+	@echo "Construction of $@ from $<"
+	$(CC) $(CFLAGS) -I . -I $(INC_DIR)$(SYSTEM_DIR) -I $(PCIE40_INC_DIR) $< -o $@
+	@echo ""
+
+$(MINIPODS_LIB) : $(MINIPODS_OBJ)
+	@echo "Construction of MINIPODS Library"
+	ar -q $(LIB_DIR)$(MINIPODS_LIB) $(MINIPODS_OBJ)
+	@echo ""
+
+$(LTC2990_OBJ): $(OBJ_DIR)%.o : $(SRC_DIR)$(LTC2990_DIR)%.c
+	@echo "Construction of $@ from $<"
+	$(CC) $(CFLAGS) -I $(INC_DIR)$(PLL_DIR) -I $(INC_DIR)$(LTC2990_DIR) -I $(INC_DIR)$(SYSTEM_DIR) -I $(INC_DIR)$(MINIPODS_DIR)  -I $(INC_DIR)$(LTC2990_DIR)  -I $(PCIE40_INC_DIR) $< -o $@
+	@echo ""
+
+$(LTC2990_LIB) : $(LTC2990_OBJ)
+	@echo "Construction of LTC2990 Library"
+	ar -q $(LIB_DIR)$(LTC2990_LIB) $(LTC2990_OBJ)
+	@echo ""
+
+$(USER_OBJ): $(OBJ_DIR)%.o : $(SRC_DIR)$(USER_DIR)%.c
+	@echo "Construction of $@ from $<"
+	$(CC) $(CFLAGS) -I $(INC_DIR)$(USER_DIR) -I $(INC_DIR)$(SYSTEM_DIR) -I $(INC_DIR)$(ECS_DIR)  -I $(PCIE40_INC_DIR) $< -o $@
+	@echo ""
+
+$(USER_LIB) : $(USER_OBJ)
+	@echo "Construction of USER Library"
+	ar -q $(LIB_DIR)$(USER_LIB) $(USER_OBJ) $(ECS_OBJ)
+	@echo ""
+
+$(USER_DYNLIB) : $(USER_OBJ)
+	@echo "Construction of dynamic USER Library"
+	$(CC) -o $(LIB_DIR)$(USER_DYNLIB) -shared $(USER_OBJ) $(ECS_OBJ)
+	@echo 
+
+$(LLI_DYNLIB) : $(ECS_OBJ) $(MINIPODS_OBJ)
+	@echo "Construction of dynamic LLI technical Library for V2"
+	mkdir -p lib
+	$(CC) -o $(LIB_DIR)$(LLI_DYNLIB) -shared $(ECS_OBJ) $(PLL_OBJ) $(MINIPODS_OBJ) -L $(PCIE40_DYN_LIB) -lpcie40driver_ecs
+	@echo 
+
+clean: mrproper
+	@echo "removing lli objects"
+	-rm $(OBJ_DIR)*.o
+	@echo ""
+
+	@echo "removing $(ECS_LIB)"
+	-rm $(LIB_DIR)$(ECS_LIB)
+	@echo ""
+
+	@echo "removing $(MINIPODS_LIB)"
+	-rm $(LIB_DIR)$(MINIPODS_LIB)
+	@echo ""
+
+	@echo "removing $(LTC2990_LIB)"
+	-rm $(LIB_DIR)$(LTC2990_LIB)
+	@echo ""
+
+	@echo "removing $(USER_LIB)"
+	-rm $(LIB_DIR)$(USER_LIB)
+	-rm $(LIB_DIR)$(USER_DYNLIB)
+	-rm $(LIB_DIR)$(LLI_DYNLIB)
+	-rm -r $(LIB_DIR)
+
+	@echo ""
+
+mrproper:
+	@echo "Removing all *~ files"
+	-find . -name "*~" -exec rm {} \;
+	@echo ""
+
diff --git a/Pcie40Libraries/Makefile.conf b/Pcie40Libraries/Makefile.conf
new file mode 100644
index 0000000..7584010
--- /dev/null
+++ b/Pcie40Libraries/Makefile.conf
@@ -0,0 +1,26 @@
+
+# +----------------------------------------------------+"
+# | Library Construction, flags                        |"
+# +----------------------------------------------------+"
+
+path=$(PWD)
+libdir=$(path)/lli/lib/$(ES)
+includedir=$(path)/lli/inc
+ecsdir=ecs  
+systemdir=system
+minipodsdir=minipods
+ltc2990dir=ltc2990
+
+LLI_CFLAGS=  -I/usr/include/lhcb  -I$(includedir)/$(ecsdir) -I$(includedir)/$(systemdir) -I$(includedir)/$(minipodsdir) -I$(includedir)/$(ltc2990dir) 
+LLI_LIBS= -L${libdir} -lminipods -lecs -lpcie40_ecs
+
+userdir=user
+LLI_USER_LIBS= -L$(libdir) -luser
+
+LLI_USER_CFLAGS= -I$(includedir)/$(userdir)
+   
+export LLI_LIBS
+export LLI_CFLAGS
+export LLI_USER_LIBS
+export LLI_USER_CFLAGS
+
diff --git a/Pcie40Libraries/i2cDriver.c b/Pcie40Libraries/i2cDriver.c
new file mode 100644
index 0000000..7c1ba4a
--- /dev/null
+++ b/Pcie40Libraries/i2cDriver.c
@@ -0,0 +1,656 @@
+/****************************************************************************************//**
+* \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 <pcie40_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("\nTEST 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
+
+
diff --git a/Pcie40Libraries/i2cDriver.h b/Pcie40Libraries/i2cDriver.h
new file mode 100644
index 0000000..43994f9
--- /dev/null
+++ b/Pcie40Libraries/i2cDriver.h
@@ -0,0 +1,19 @@
+/****************************************************************************************//**
+* \file				i2cDriver.h
+*
+* \brief This unit is the includes for 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 : 12/6/2015 add a second bus for PCIe40
+*//******************************************************************************************/
+//                  USER ORIENTED PROCEDURES FOR EXTERNAL USE
+int i2c_init(int dev, int bus, unsigned inCLK, unsigned SCLfreq);
+void i2c_getInit(int dev, int bus, unsigned *inCLK, unsigned *SCLfreq);
+int i2c_readMem(int dev, int bus, unsigned slaveAdd, unsigned regIndex, unsigned *val);
+int i2c_writeMem(int dev, int bus, unsigned slaveAdd, unsigned regIndex, unsigned *val);
+int i2c_multReadMem(int dev, int bus, unsigned slaveAdd, unsigned regIndex, int nb, unsigned **data);
diff --git a/Pcie40Libraries/pcie40_ecs.c b/Pcie40Libraries/pcie40_ecs.c
new file mode 100644
index 0000000..5bad326
--- /dev/null
+++ b/Pcie40Libraries/pcie40_ecs.c
@@ -0,0 +1,351 @@
+/****************************************************************************************//**
+* \file				ecs.c
+*
+* \brief This file contains the user library to access PCI driver.
+* 
+* \author JM : 02/11/2013
+* \version 1.0
+* \date 08/11/2013
+
+* \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
+    JM : 02/11/2013 Initial version
+    JM/PYD : 04/11/2013 PYD code integration
+    PYD : adapt for Paolo driver with its library and add multiple board choice
+*/
+/**************************************************************************************************
+The *Bar*() type of functions concentrate the conditional code which depends of the driver type.
+
+The ecs_*Lli() or ecs_*User() type of functions are driver blind and used to match user registers
+or lli registers.
+
+ecs_openUser()		ecs_openLli()
+ecs_iordUser()		ecs_iordLli()
+ecs_iowrUser()		ecs_iowrLli()
+ecs_iordBlocUser()	ecs_iordBlocLli()
+ecs_iowrBlocUser()	ecs_iowrBlocLli()
+ecs_closeUser()		ecs_closeLli()			
+************************************************************************************************/
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include <linux/ioctl.h>
+#include <sys/ioctl.h>
+
+#include <pcie40_ecs.h>
+#include <systemConfig.h>
+
+// rpm includes
+// PYD 20/03/2018 force the use of rpm for all borads types
+#include <ecs_driverlib.h>
+
+/**
+ *  \var ecs_userFile
+ *  \brief ecs_open function return a file description which is stored on userFile for bar 0.
+*/
+static int ecs_userFile[MAX_DEV];
+
+/**
+ *  \var ecs_lliFile
+ *  \brief ecs_open function return a file description which is stored on lliFile for bar 2.
+*/
+static int ecs_lliFile[MAX_DEV];
+/**
+ *  \var ecs_bar2_mm
+ *  \brief ecs_open function for bar 2 mmaps registers area from a start address.
+*/
+static unsigned *ecs_bar1_mm[MAX_DEV]; // bar1 start add of mmap
+static unsigned *ecs_bar2_mm[MAX_DEV]; // bar2 start add of mmap
+
+/******************************************************//**
+ * \fn int ecs_close(int dev, int bar)
+ * \brief Function to close bar file
+ *
+ * \param dev: the selected board number
+ * \param bar: the bar number
+ *//******************************************************/
+void ecs_close(int dev, int bar){
+	if (bar==2){
+		p40_ecs_close(ecs_lliFile[dev],ecs_bar2_mm[dev]);
+	}
+	else if (bar==0){
+		p40_ecs_close(ecs_lliFile[dev],ecs_bar1_mm[dev]);
+	}
+}
+
+/******************************************************//**
+ * \fn int ecs_open(int dev, int bar)
+ * \brief Function to open bar file
+ *
+ * \param dev: the selected board number
+ * \param bar: number of bar
+ * \return -1 error / file descriptor
+ *//******************************************************/
+int ecs_open(int dev,int bar){
+	if (bar==2){
+		ecs_lliFile[dev] = p40_ecs_open(dev,bar,&(ecs_bar2_mm[dev]));
+		return ecs_lliFile[dev];
+	}
+	else if (bar==0){
+		ecs_userFile[dev] = p40_ecs_open(dev,bar,&(ecs_bar1_mm[dev]));
+		return ecs_userFile[dev];
+	}
+return -1;
+}
+
+int ecs_write(int dev, int bar, unsigned add, int val){
+	if (add%4 != 0)
+		return(-1);
+	
+	if (bar==2){
+		p40_ecs_w32(ecs_bar2_mm[dev],add,val);
+	}
+	else if (bar==0){
+		p40_ecs_w32(ecs_bar1_mm[dev],add,val);
+	}	
+	return(0);
+}
+
+unsigned ecs_read(int dev, int bar, unsigned add){
+	uint32_t val;
+	if (add%4 != 0)
+		return(-1);
+	if (bar==2){
+		val = p40_ecs_r32(ecs_bar2_mm[dev],add);
+	}
+	else if (bar==0){
+		val = p40_ecs_r32(ecs_bar1_mm[dev],add);
+	}	
+	return val;
+}
+
+int ecs_iowrBar(int dev, int bar, unsigned add, unsigned *val){
+	if (add%4 != 0)
+		return(-1);	
+	if (bar==2){
+		if (ecs_lliFile[dev] == 0) ecs_open(dev,bar);
+	}
+	else if (bar==0){
+		if (ecs_userFile[dev] == 0) ecs_open(dev,bar);
+	}	
+    ecs_write(dev,bar,add,*val);
+	return(0);
+}
+
+int ecs_iordBar(int dev, int bar, unsigned add, unsigned *val){
+	if (add%4 != 0)
+		return(-1);
+	if (bar==2){
+		if (ecs_lliFile[dev] == 0) ecs_open(dev,bar);
+	}
+	else if (bar==0){
+		if (ecs_userFile[dev] == 0) ecs_open(dev,bar);
+	}	
+        *val = ecs_read(dev,bar,add);
+	return(0);
+}
+int ecs_writeBloc(int dev, int bar, unsigned add, int size, unsigned *val){
+	int i;	
+	unsigned wd;
+	if (add%sizeof(unsigned) != 0)
+		return(-1);
+	for (i=0; i<size; i = i + 1){
+		wd = val[i];
+		ecs_write(dev,bar, add+i*sizeof(unsigned), wd);
+	}
+	return 0;
+}
+
+int ecs_readBloc(int dev, int bar, unsigned add, int size, unsigned *val){
+	int i;
+	if (add%4 != 0)
+		return(-1);
+	for (i=0; i<size; i = i + 1){
+		val[i] = ecs_read(dev,bar,add+i*sizeof(unsigned));
+	}
+	return 0;
+}
+int ecs_iowrBarBloc(int dev, int bar, unsigned add, int size, unsigned *val){
+    ecs_writeBloc(dev,bar,add,size,val);
+return 0;
+}
+
+int ecs_iordBarBloc(int dev, int bar, unsigned add, int size, unsigned *val){
+	ecs_readBloc(dev,bar,add,size,val);
+return 0;
+}
+
+/***********************************************************************//**
+ * \fn int ecs_printSetup()
+ * \brief Function to print BAR configurations for checking
+ *       
+ *//***********************************************************************/
+void ecs_printSetup(){
+	printf("-------------------------------------------------\n");
+	printf("driver type     = MMAP (PCIe40 daq) version\n");
+	printf("-------------------------------------------------\n");
+	printf("BAR user        = BAR%d\n",BAR_USER);
+	printf("BAR i2c         = BAR%d\n",BAR_I2C);
+
+	printf("BASE i2c bus %d TEMPERATURES   = 0x%08x\n", I2C_BUS_TEMPERATURES,   I2C_BUS_BASE_TEMPERATURES);
+	printf("BASE i2c bus %d CLEANER1       = 0x%08x\n", I2C_BUS_PLL_CLEANER1,   I2C_BUS_BASE_PLL_CLEANER1);
+	printf("BASE i2c bus %d CLEANER2       = 0x%08x\n", I2C_BUS_PLL_CLEANER2,   I2C_BUS_BASE_PLL_CLEANER2);
+	printf("BASE i2c bus %d PLL_TFC        = 0x%08x\n", I2C_BUS_PLL_TFC,        I2C_BUS_BASE_PLL_TFC);
+	printf("BASE i2c bus %d SFP1           = 0x%08x\n", I2C_BUS_SFP1,           I2C_BUS_BASE_SFP1);
+	printf("BASE i2c bus %d SFP2           = 0x%08x\n", I2C_BUS_SFP2,           I2C_BUS_BASE_SFP2);
+	printf("BASE i2c bus %d MINIPODS       = 0x%08x\n", I2C_BUS_MINIPODS,       I2C_BUS_BASE_MINIPODS);
+	printf("BASE i2c bus %d TEMP_MEZZANINE = 0x%08x\n", I2C_BUS_TEMP_MEZZANINE, I2C_BUS_BASE_TEMP_MEZZANINE);
+	printf("BASE i2c bus %d CURRENT1       = 0x%08x\n", I2C_BUS_CURRENT1,       I2C_BUS_BASE_CURRENT1);
+	printf("BASE i2c bus %d CURRENT2       = 0x%08x\n", I2C_BUS_CURRENT2,       I2C_BUS_BASE_CURRENT2);
+}
+
+// Usefull for python wrappers when memory is allocated by the lli C libs
+// it should be freed after python module has used it.
+void ecs_free( int *data) {
+	free(data);
+}
+/***********************************************************************//**
+ * \fn int ecs_openUser(int dev)
+ * \brief Function to init the ecs pcie bus accesses for user space
+ *      Thus function has to be done before any access.
+ *       
+ * Here we have a detailed description of the function 
+ *
+ * \param : dev the board number
+ * \return 0 success, -1 error
+ *//***********************************************************************/
+int ecs_openUser(int dev){
+	return ecs_open(dev,0);
+}
+
+/***********************************************************************//**
+ * \fn int ecs_closeUser(int dev)
+ * \brief Function to disconnect from the ecs user space.
+ *        A new ecs_open() should be done before any new read or write
+ *       
+ * \param : dev the board number
+ *//***********************************************************************/
+void ecs_closeUser(int dev){
+  ecs_close(dev,0);
+}
+
+/***********************************************************************//**
+ * \fn int ecs_openLli(int dev)
+ * \brief Function to init the ecs pcie bus accesses for LLI devices
+ *      Thus function has to be done before any access.
+ *       
+ * \param : dev the board number
+ * \return 0 success, -1 error
+ *//***********************************************************************/
+int ecs_openLli(int dev){
+	return ecs_open(dev,2);
+}
+
+/***********************************************************************//**
+ * \fn int ecs_closeLli(int dev)
+ * \brief Function to disconnect from the LLI devices io.
+ *        A new ecs_openLli() should be done before any new read or write
+ *       
+ * \param : dev the board number
+ *//***********************************************************************/
+void ecs_closeLli(int dev){
+	ecs_close(dev,2);
+}
+
+/***********************************************************************//**
+ * \fn int ecs_iordLli(int dev, unsigned add, unsigned *val)
+ * \brief Function to read a word at offset add in the lli registers space.
+ *
+ * \param : dev the board number
+ * \param add the offset of the word to read in the lli register space
+ * \param val a pointer to receive the read value in case of success
+ * \return 0 success,-1 error
+ *//***********************************************************************/
+int ecs_iordLli(int dev, unsigned add, unsigned *val){
+	return ecs_iordBar(dev, 2, add, val);
+}
+
+/***********************************************************************//**
+ * \fn int ecs_iowrLli(int dev, unsigned add, unsigned *val)
+ * \brief Function to write a word at offset add in the Lli registers space.
+ *
+ * \param : dev the board number
+ * \param add the offset of the word to write in the Lli registers space
+ * \param val a pointer to the value to write
+ * \return 0 success,-1 error
+ *//***********************************************************************/
+int ecs_iowrLli(int dev, unsigned add, unsigned *val){
+	return ecs_iowrBar(dev, 2, add, val);
+}
+
+/***********************************************************************//**
+ * \fn int ecs_iordBlocLli(unsigned add, int size, unsigned *val)
+ * \brief Function to read size words at offset add in the lli registers space.
+ *
+ * \param : dev the board number
+ * \param add  : the offset of the word to read in the lli register space
+ * \param size : number of bytes to read
+ * \param val  : a pointer to receive the read value in case of success
+ * \return 0 success,-1 error
+ *//***********************************************************************/
+int ecs_iordBlocLli(int dev, unsigned add, int size, unsigned *val){
+	return ecs_iordBarBloc(dev, 2, add, size, val);
+}
+
+/***********************************************************************//**
+ * \fn int ecs_iowrBlocLli(unsigned add, int size, unsigned *val)
+ * \brief Function to write size words at offset add in the Lli registers space.
+ *
+ * \param : dev the board number
+ * \param add  : the offset of the word to write in the Lli registers space
+ * \param size : number of bytes to write
+ * \param val  : a pointer to the value to write
+ * \return 0 success,-1 error
+ *//***********************************************************************/
+int ecs_iowrBlocLli(int dev, unsigned add, int size, unsigned *val){
+	return ecs_iowrBarBloc(dev, 2, add, size, val);
+}
+
+/***********************************************************************//**
+ * \fn int ecs_iordI2c(int dev, unsigned add, unsigned *val)
+ * \brief Function to read a word at offset add in the I2C core registers space.
+ *
+ * \param : dev the board number
+ * \param add the offset of the word to read in the I2C core register space
+ * \param val a pointer to receive the read value in case of success
+ * \return 0 success,-1 error
+ *//***********************************************************************/
+int ecs_iordI2c(int dev, unsigned add, unsigned *val){
+	return ecs_iordLli(dev, add, val);
+}
+int ecs_iordI2c_slow(int dev, unsigned add, unsigned *val){
+   int dat = ecs_iordLli(dev, add, val);
+   usleep(0);
+	return dat;
+}
+/***********************************************************************//**
+ * \fn int ecs_iowrI2c(unsigned add, unsigned *val)
+ * \brief Function to write a word at offset add in the I2C core registers space.
+ *
+ * \param : dev the board number
+ * \param add the offset of the word to write in the I2C core registers space
+ * \param val a pointer to the value to write
+ * \return 0 success,-1 error
+ *//***********************************************************************/
+int ecs_iowrI2c(int dev, unsigned add, unsigned *val){
+	return ecs_iowrLli(dev, add, val);
+}
+int ecs_iowrI2c_slow(int dev, unsigned add, unsigned *val){
+   int dat = ecs_iowrLli(dev, add, val);
+   usleep(0);
+	return dat;
+}
diff --git a/Pcie40Libraries/pcie40_ecs.h b/Pcie40Libraries/pcie40_ecs.h
new file mode 100644
index 0000000..d386b72
--- /dev/null
+++ b/Pcie40Libraries/pcie40_ecs.h
@@ -0,0 +1,55 @@
+#ifndef ECS_H
+#define ECS_H
+
+#include <linux/ioctl.h>
+
+typedef struct {
+	int size;
+} ecs_arg_t;
+
+#define    ECS_IOCTL_SET_SIZE   _IOW('e',0, ecs_arg_t *) 
+#define    ECS_IOCTL_GET_SIZE   _IOR('e',1, ecs_arg_t *)
+
+void ecs_printSetup();
+
+int  ecs_open(int dev, int bar);
+void ecs_close(int dev, int bar);
+
+int      ecs_write(int dev, int bar, unsigned add, int val);
+unsigned ecs_read(int dev, int bar, unsigned add);
+int 	 ecs_writeBloc(int dev, int bar, unsigned add, int size, unsigned *val);
+int 	 ecs_readBloc(int dev, int bar, int unsigned, int size, unsigned *val);
+
+
+//Adaptation with old library
+int ecs_iowrBar(int dev, int bar, unsigned add, unsigned *val);
+int ecs_iordBar(int dev, int bar, unsigned add, unsigned *val);
+int ecs_iowrBarBloc(int dev, int bar, unsigned add, int size, unsigned *val);
+int ecs_iordBarBloc(int dev, int bar, unsigned add, int size, unsigned *val);
+
+// functions to use for user space registers R/W
+int  ecs_openUser(int dev);
+void ecs_closeUser(int dev);
+int  ecs_iordUser(int dev, unsigned add, unsigned *val);
+int  ecs_iowrUser(int dev, unsigned add, unsigned *val);
+int  ecs_iordBlocUser(int dev, unsigned add, int size, unsigned *val);
+int  ecs_iowrBlocUser(int dev, unsigned add, int size, unsigned *val);
+
+// functions to use to access the LLI ressources
+int ecs_openLli(int dev);
+void ecs_closeLli(int dev);
+int  ecs_iordLli(int dev, unsigned add, unsigned *val);
+int  ecs_iowrLli(int dev, unsigned add, unsigned *val);
+int  ecs_iordBlocLli(int dev, unsigned add, int size, unsigned *val);
+int  ecs_iowrBlocLli(int dev, unsigned add, int size, unsigned *val);
+
+// functions to use to access the I2C core registers
+int  ecs_iordI2c(int dev, unsigned add, unsigned *val);
+int  ecs_iowrI2c(int dev, unsigned add, unsigned *val);
+int  ecs_iordI2c_slow(int dev, unsigned add, unsigned *val);
+int  ecs_iowrI2c_slow(int dev, unsigned add, unsigned *val);
+
+// function to access the PHY registers space
+int ecs_iordPhy(int dev, unsigned add, unsigned *val);
+int ecs_iowrPhy(int dev, unsigned add, unsigned *val);
+#endif
diff --git a/Pcie40Libraries/systemConfig.h b/Pcie40Libraries/systemConfig.h
new file mode 100644
index 0000000..06c351e
--- /dev/null
+++ b/Pcie40Libraries/systemConfig.h
@@ -0,0 +1,61 @@
+#ifndef SYSTEM_CONFIG_H
+#define SYSTEM_CONFIG_H
+
+// max number of used borad in a PC
+#define MAX_DEV 16
+
+//================= BAR DEFINE =================
+#define BAR_USER   0
+#define BAR_LLI    2
+
+#define BAR_I2C    2
+
+//================= I2C ========================
+// Makes the association between the BUS number and the BUS BASE
+
+#define I2C_BUS_BASE_TEMPERATURES                   0x10000
+#define I2C_BUS_TEMPERATURES                        0
+
+#define I2C_BUS_BASE_PLL_CLEANER1                   0x10020
+#define I2C_BUS_PLL_CLEANER1                        1
+
+#define I2C_BUS_BASE_PLL_CLEANER2                   0x10040
+#define I2C_BUS_PLL_CLEANER2                        2
+
+#define I2C_BUS_BASE_PLL_TFC                        0x10060
+#define I2C_BUS_PLL_TFC                             3
+
+#define I2C_BUS_BASE_FANOUT			    0x10080
+#define I2C_BUS_FANOUT                              4
+
+#define I2C_BUS_BASE_SFP1                           0x100A0
+#define I2C_BUS_SFP1                                5
+
+#define I2C_BUS_BASE_SFP2                           0x100C0
+#define I2C_BUS_SFP2                                6
+
+#define I2C_BUS_BASE_MINIPODS                       0x100E0
+#define I2C_BUS_MINIPODS                            7
+
+#define I2C_BUS_BASE_TEMP_MEZZANINE                 0x10100
+#define I2C_BUS_TEMP_MEZZANINE                      8
+
+#define I2C_BUS_BASE_FPGA_EEPROM                    0x10120
+#define I2C_BUS_FPGA_EEPROM                         9
+
+#define I2C_BUS_BASE_CURRENT1                       0x20000
+#define I2C_BUS_CURRENT1                            10
+
+#define I2C_BUS_BASE_CURRENT2                       0x20020
+#define I2C_BUS_CURRENT2                            11
+
+//============== FPGA Transceivers =====================
+#define NB_RECONFIG							1	//Number of reconfig blocs (transceivers) (Max 6 link by reconfig)
+#define RECONFIG_BASE_ADDR_LIST				{0x0200} 		//{addr_reconf0, addr_reconf1, addr_reconf2, addr_reconf3, ...}
+#define RECONFIG_MGMT_BASE 					0x0200
+#define PHY_MGMT_BASE      					0x0800
+
+//================= USER_SPACE Master (BRIDGE) ==========
+#define USER_SPACE_MASTER					0x80000
+
+#endif
-- 
GitLab