From 03dd3536842aa4ce072e982f7d9a7991aa04df3f Mon Sep 17 00:00:00 2001
From: Grzegorz Daniluk <grzegorz.daniluk@cern.ch>
Date: Fri, 3 Aug 2012 11:39:19 +0200
Subject: [PATCH] shell: t2/t4 phase transition can be read from EEPROM or
 obtained from calibration procedure

---
 dev/eeprom.c      | 29 +++++++++++++++++++++++++++--
 include/eeprom.h  |  6 +++++-
 shell/cmd_calib.c | 30 +++++++++++++++++++++++++++++-
 3 files changed, 61 insertions(+), 4 deletions(-)

diff --git a/dev/eeprom.c b/dev/eeprom.c
index 559b919..0014165 100644
--- a/dev/eeprom.c
+++ b/dev/eeprom.c
@@ -10,8 +10,8 @@
  * placed also outside the FMC standardized EEPROM structure. The only requirement
  * is that it starts with 0xdeadbeef pattern. The structure of SFP section is:
  *
- * --------------
- * | count (1B) |
+ * ----------------------------------------------
+ * | cal_ph_trans (4B) | SFP count (1B) |
  * --------------------------------------------------------------------------------------------
  * |   SFP(1) part number (16B)       | alpha (4B) | deltaTx (4B) | deltaRx (4B) | chksum(1B) |
  * --------------------------------------------------------------------------------------------
@@ -23,6 +23,8 @@
  * --------------------------------------------------------------------------------------------
  *
  * Fields description:
+ * cal_ph_trans       - t2/t4 phase transition value (got from measure_t24p() ), contains 
+ *                      _valid_ bit (MSB) and 31 bits of cal_phase_transition value
  * count              - how many SFPs are described in the list (binary)
  * SFP(n) part number - SFP PN as read from SFP's EEPROM (e.g. AXGE-1254-0531) 
  *                      (16 ascii chars)
@@ -187,6 +189,29 @@ int8_t eeprom_match_sfp(uint8_t i2cif, uint8_t i2c_addr, struct s_sfpinfo* sfp)
   return 0;
 }
 
+int8_t eeprom_phtrans(uint8_t i2cif, uint8_t i2c_addr, uint32_t *val, uint8_t write)
+{
+  if(write)
+  {
+    *val |= (1<<31);
+    if( eeprom_write(i2cif, i2c_addr, EE_BASE_CAL, val, sizeof(val) ) != sizeof(val) )
+      return EE_RET_I2CERR;
+    else
+      return 1;
+  }
+  else
+  {
+    if( eeprom_read(i2cif, i2c_addr, EE_BASE_CAL, val, sizeof(val) ) != sizeof(val) )
+      return EE_RET_I2CERR;
+
+    if( !(*val&(1<<31)) )
+      return 0;
+
+    *val &= 0x7fffffff;  //return ph_trans value without validity bit
+    return 1;
+  }
+}
+
 int8_t eeprom_init_erase(uint8_t i2cif, uint8_t i2c_addr)
 {
   uint16_t used = 0;
diff --git a/include/eeprom.h b/include/eeprom.h
index e1a2dd6..978add3 100644
--- a/include/eeprom.h
+++ b/include/eeprom.h
@@ -4,7 +4,8 @@
 #define SFP_SECTION_PATTERN 0xdeadbeef
 #define SFPS_MAX 4
 #define SFP_PN_LEN 16
-#define EE_BASE_SFP 4*1024
+#define EE_BASE_CAL 4*1024
+#define EE_BASE_SFP 4*1024+4
 #define EE_BASE_INIT 4*1024+SFPS_MAX*29
 
 #define EE_RET_I2CERR -1
@@ -15,6 +16,7 @@
 extern int32_t sfp_alpha;
 extern int32_t sfp_deltaTx;
 extern int32_t sfp_deltaRx;
+extern uint32_t cal_phase_transition;
 
 struct s_sfpinfo
 {
@@ -32,6 +34,8 @@ int32_t eeprom_sfpdb_erase(uint8_t i2cif, uint8_t i2c_addr);
 int32_t eeprom_sfp_section(uint8_t i2cif, uint8_t i2c_addr, size_t size, uint16_t *section_sz);
 int8_t eeprom_match_sfp(uint8_t i2cif, uint8_t i2c_addr, struct s_sfpinfo* sfp);
 
+int8_t eeprom_phtrans(uint8_t i2cif, uint8_t i2c_addr, uint32_t *val, uint8_t write);
+
 int8_t eeprom_init_erase(uint8_t i2cif, uint8_t i2c_addr);
 int8_t eeprom_init_add(uint8_t i2cif, uint8_t i2c_addr, const char *args[]);
 int32_t eeprom_init_show(uint8_t i2cif, uint8_t i2c_addr);
diff --git a/shell/cmd_calib.c b/shell/cmd_calib.c
index 29dd83a..743eae4 100644
--- a/shell/cmd_calib.c
+++ b/shell/cmd_calib.c
@@ -4,11 +4,39 @@
 		Description: launches the WR Core monitor GUI */
 		
 #include "shell.h"
+#include "eeprom.h"
+#include "syscon.h"
 
 
 extern int measure_t24p(int *value);
 
 int cmd_calib(const char *args[])
 {
-	return measure_t24p(NULL);
+	uint32_t trans;
+
+	if(args[0] && !strcasecmp(args[0], "force"))
+	{
+		if( measure_t24p(&trans)<0 )
+			return -1;
+		return eeprom_phtrans(WRPC_FMC_I2C, FMC_EEPROM_ADR, &trans, 1);
+	}
+	else if( !args[0] )
+	{
+		if( eeprom_phtrans(WRPC_FMC_I2C, FMC_EEPROM_ADR, &trans, 0) )
+		{
+			mprintf("Found phase transition in EEPROM: %dps\n", trans);
+			cal_phase_transition = trans;
+			return 0;
+		}
+		else
+		{
+			mprintf("Measuring t2/t4 phase transition...\n");
+			if( measure_t24p(&trans)<0 )
+				return -1;
+			cal_phase_transition = trans;
+			return eeprom_phtrans(WRPC_FMC_I2C, FMC_EEPROM_ADR, &trans, 1);
+		}
+	}
+
+	return 0;
 }
-- 
GitLab