From 59f38b729e4f933d823cefafc0c4a8ede54625f8 Mon Sep 17 00:00:00 2001
From: qzhou <qidong.zhou@desy.de>
Date: Wed, 15 Jul 2020 23:45:21 +0900
Subject: [PATCH] add pll configuration and tx reset

---
 Pcie40Applications/regconfig.cpp | 174 ++++++++++++++++---------------
 Pcie40Applications/statlink.cpp  |  31 +++++-
 2 files changed, 118 insertions(+), 87 deletions(-)

diff --git a/Pcie40Applications/regconfig.cpp b/Pcie40Applications/regconfig.cpp
index f849eff..a4844e4 100644
--- a/Pcie40Applications/regconfig.cpp
+++ b/Pcie40Applications/regconfig.cpp
@@ -12,6 +12,7 @@
 
 #include "pcie40_b2slc.h"
 #include "pcie40_reg.h"
+#include "pcie40_b2config.h"
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -51,6 +52,8 @@ bool OP_FLAG         = false;
 #define PCIE40_CHECKFEE 0x102
 #define PCIE40_TRGOFF   0x104
 #define PCIE40_TRGON    0x105
+#define PCIE40_RESETB2L 0x110
+#define PCIE40_CONFPLL  0x111
 
 /* 0 parameter (obsolete, unused) */
 #define PCIE40_TTTRG    0x106
@@ -155,8 +158,6 @@ void argument(int argc, char **argv){
     if(ss=="--op"){
       OP_FLAG = true;
       operation = argv[++i];
-      addr = strtoul(argv[++i], 0, 16);
-      data = strtoul(argv[++i], 0, 16);
     }
     if(ss=="-h" || ss=="-help"){
       fprintf(stderr, "%s version %d.%02d date %d\n"
@@ -168,9 +169,11 @@ void argument(int argc, char **argv){
                        "       --ch    xx              #link channel number\n" 
                        "       --fee8 or --fee32       #use A7D8 or A16D32 for access register\n"
                        "       -r xx or -w xx xx       #read or write register with address xx[hex] or data xx[hex]\n\n"
+	               "       %s --ch 0 --op checkfee\n"
+                       "       --op operation name writen in check hsreg()\n\n"
 	               "       %s --ch 0 --stream /path/firmware.bit\n"
                        "       --stream /path/filename #streaming a file by using stream file method\n\n"
-	      , ARGV0, ARGV0);
+	      , ARGV0, ARGV0, ARGV0);
       return;
     }
   }
@@ -185,6 +188,8 @@ hsreg(const char *name)
   static struct { char *name; int adrs; } regs[] = {
     { "link",     PCIE40_LINK } ,
     { "checkfee", PCIE40_CHECKFEE },
+    { "resetb2l", PCIE40_RESETB2L },
+    { "confpll",  PCIE40_CONFPLL },
     
     { "trghold",  PCIE40_TRGOFF },
     { "trigger",  PCIE40_TRGON },
@@ -221,17 +226,42 @@ hsreg(const char *name)
   return (i > 0 && i < 0x100) ? i : -1;
 }
 
+//---------------------------------------------------------------------- 
+//    getfee
+// ---------------------------------------------------------------------- 
+int
+getfee(pcie40reg_t *pcie40)
+{
+  int hwtype;
+  int serial;
+  int fwtype;
+  int fwver;
+
+  hwtype = pcie40_readfee8(dev_slot, ch, PCIE40REG_FEEHWTYPE);
+  serial = pcie40_readfee8(dev_slot, ch, PCIE40REG_FEESERIAL);
+  fwtype = pcie40_readfee8(dev_slot, ch, PCIE40REG_FEEFWTYPE);
+  fwver  = pcie40_readfee8(dev_slot, ch, PCIE40REG_FEEFWVER);
+
+  pcie40->feeser = (serial | (hwtype << 8)) & 0xfff;
+  pcie40->feever = (fwver  | (fwtype << 8)) & 0xfff;
+  pcie40->feehw  = (hwtype >> 4) & 0x0f;
+  pcie40->feefw  = (fwtype >> 4) & 0x0f;
+  
+  pcie40->feecrce = pcie40_readfee8(dev_slot, ch, PCIE40REG_CRCERR);
+
+  return 0;
+}
+
 /* ---------------------------------------------------------------------- *\
    pcie40_op
 \* ---------------------------------------------------------------------- */
 int
-pcie40_op(int dev, int ch, int op_addr, int addr, int data)
+pcie40_op(int dev, int ch, int op_addr, int addr, int data, pcie40reg_t pcie40)
 {
   int i;
   const char *feetype;
   int cmd = 0;
   int cmd_cdc = 0;
-  
   switch (op_addr) {
   case PCIE40_LINK:    cmd = 0x01; break;
   case PCIE40_TRGOFF:  cmd = 0x03; break;
@@ -241,55 +271,27 @@ pcie40_op(int dev, int ch, int op_addr, int addr, int data)
   }
 
   if (op_addr == PCIE40_CHECKFEE) {
-    int ret;
-    int hwtype;
-    int serial;
-    int fwtype;
-    int fwver;
-    static const char *feetype[] = {
-      "UNDEF", "SVD", "CDC", "BPID", "EPID", "ECL", "EECL", "KLM", "EKLM",
-      "TRG", "UNKNOWN-10", "UNKNOWN-11",
-      "UNKNOWN-12", "UNKNOWN-13", "DEMO", "TEST" };
-    static const char *demotype[] = {
-      "UNDEF", "HSLB-B2L", "SP605-B2L", "ML605-B2L", "AC701-B2L" };
-    static const char *trgtype[] = {
-      "TRGMERGER", /* = 0 */
-      "TRGTSF",    /* = 1 */
-      "TRG2D",     /* = 2 */
-      "TRG3D",     /* = 3 */
-      "TRGNN",     /* = 4 */
-      "TRGEVTT",   /* = 5 */
-      "TRGGRL",    /* = 6 */
-      "TRGGDL",    /* = 7 */
-      "TRGETM",    /* = 8 */
-      "TRGTOP",    /* = 9 */
-      "TRGKLM",    /* = 10 */
-    };
-
     if (!pcie40_b2l_status(dev_slot, ch)) {
       printf("Failed: b2l is down\n");
       return -1;
     }
-    hwtype = pcie40_readfee8(dev, ch, REG_FEEHWTYPE);
-    serial = pcie40_readfee8(dev, ch, REG_FEESERIAL);
-    fwtype = pcie40_readfee8(dev, ch, REG_FEEFWTYPE);
-    fwver  = pcie40_readfee8(dev, ch, REG_FEEFWVER);
-
-    serial |= (hwtype & 0xf) << 8;
-    fwver  |= (fwtype & 0xf) << 8;
-    hwtype = (hwtype >> 4) & 0xf;
-    fwtype = (fwtype >> 4) & 0xf;
-
-    if (hwtype == 14 && fwtype > 0 && fwtype <= 4) {
-      printf("FEE type %s serial %d version %d at PCIE40_LINK-%d\n",
-	     demotype[fwtype], serial, fwver, ch);
-    } else if (hwtype == 9 && fwtype >= 0 && fwtype <= 10) {
-      printf("FEE type %s serial %d version %d at PCIE40_LINK-%d\n",
-	     trgtype[fwtype], serial, fwver, ch);
+    pcie40reg_t *pcie = &pcie40;
+    memset(pcie, 0, sizeof(*pcie));
+    pcie->feeser = 0xffff;
+    pcie->feever = 0xffff;
+    getfee(pcie);
+    if (pcie->feeser & 0x8000) {
+      printf("fee info is not available\n");
     } else {
-      printf("FEE type %s serial %d firmware %d version %d at PCIE40_LINK-%d\n",
-	     feetype[hwtype], serial, fwtype, fwver, ch);
+      printf("%s serial %d version %d\n",
+    	     feename(pcie->feehw, pcie->feefw), pcie->feeser, pcie->feever);
     }
+  } else if (op_addr == PCIE40_RESETB2L) {
+    pcie40_resetMinipodLink(dev, ch);
+    printf("B2LINK-%02d is %s\n",ch, 
+	   (pcie40_b2l_status(dev_slot, ch)&& pcie40_b2l_rxready(dev_slot, ch) && pcie40_b2l_txready(dev_slot, ch))?"UP":"DOWN or NOT READY");    
+  } else if (op_addr == PCIE40_CONFPLL) {
+    pcie40_configurePLLs(dev);
   } else if (cmd) {
     pcie40_writefee8(dev, ch, PCIE40REG_FEECONT, cmd);
     
@@ -353,46 +355,48 @@ int main(int argc, char** argv){
     result = ecs_read( dev_slot , SLC_BAR , addr);
     printf("reg%08x = %08x\n", addr, result);    
   }
-
-  if(pcie40_b2l_status(dev_slot, ch) && pcie40_b2l_rxready(dev_slot, ch) && pcie40_b2l_txready(dev_slot, ch)){
-    if(USE_FEE8 && READ_ONLY){
-      result = pcie40_readfee8( dev_slot , ch , addr );
-      printf("reg%04x = %08x\n", addr, result);
-    }else if(USE_FEE8 && WRITE){
-      result = pcie40_writefee8( dev_slot , ch , addr, data );
-      if(result == 0)
-	printf("Write 0x%04x to register 0x%04x\n", data, addr);
-      else
-	printf("ERROR: Failed to write 0x%04x to register 0x%04x\n", data, addr);
-    }else if(USE_FEE32 && READ_ONLY){
-      result = pcie40_readfee32( dev_slot , ch , addr );
-      printf("reg%04x = %08x\n", addr, result);
-    }else if(USE_FEE32 && WRITE){
-      result = pcie40_writefee32( dev_slot , ch , addr, data );
-      if(result == 0)
-	printf("Write 0x%08x to register 0x%04x\n", data, addr);
-      else
-	printf("ERROR: Failed to write 0x%08x to register %04x\n", data, addr);
-    }else if(STREAM){
-      if(STREAM_ARICH)
-	result = pcie40_writestream_arich( dev_slot , ch , filename ) ;
-      else
-	result = pcie40_writestream_klm( dev_slot , ch , filename ) ;
-      if(result == 0)
-	std::cerr<<"Succeed streaming file: " << filename << std::endl;
-      else
-	std::cerr<<"ERROR: Failed streaming file: " << filename << std::endl;
-    } 
-
-    //This is only frame for register operation in the furture
-    if(OP_FLAG){
-      unsigned int op_addr = hsreg( operation );
-      pcie40_op(dev_slot, ch, op_addr, addr, data);
+  //register access via b2l
+  if(USE_FEE8 || USE_FEE32 || STREAM){
+    if(pcie40_b2l_status(dev_slot, ch) && pcie40_b2l_rxready(dev_slot, ch) && pcie40_b2l_txready(dev_slot, ch)){
+      if(USE_FEE8 && READ_ONLY){
+	result = pcie40_readfee8( dev_slot , ch , addr );
+	printf("reg%04x = %08x\n", addr, result);
+      }else if(USE_FEE8 && WRITE){
+	result = pcie40_writefee8( dev_slot , ch , addr, data );
+	if(result == 0)
+	  printf("Write 0x%04x to register 0x%04x\n", data, addr);
+	else
+	  printf("ERROR: Failed to write 0x%04x to register 0x%04x\n", data, addr);
+      }else if(USE_FEE32 && READ_ONLY){
+	result = pcie40_readfee32( dev_slot , ch , addr );
+	printf("reg%04x = %08x\n", addr, result);
+      }else if(USE_FEE32 && WRITE){
+	result = pcie40_writefee32( dev_slot , ch , addr, data );
+	if(result == 0)
+	  printf("Write 0x%08x to register 0x%04x\n", data, addr);
+	else
+	  printf("ERROR: Failed to write 0x%08x to register %04x\n", data, addr);
+      }else if(STREAM){
+	if(STREAM_ARICH)
+	  result = pcie40_writestream_arich( dev_slot , ch , filename ) ;
+	else
+	  result = pcie40_writestream_klm( dev_slot , ch , filename ) ;
+	if(result == 0)
+	  std::cerr<<"Succeed streaming file: " << filename << std::endl;
+	else
+	  std::cerr<<"ERROR: Failed streaming file: " << filename << std::endl;
+      } 
+    }else{
+      printf("ERROR: b2link-%02d is down or not ready\n", ch);
     }
-  }else{
-    printf("ERROR: b2link-%02d is down or not ready\n", ch);
   }
 
+  //This is frame for register operation
+  //Expert usage: specify the addr and data with "-r" or "-w" if needed
+  if(OP_FLAG){
+    unsigned int op_addr = hsreg( operation );
+    pcie40_op(dev_slot, ch, op_addr, addr, data, pcie40);
+  }
   // close pcie40 device driver for current process
   ecs_close( dev_slot , SLC_BAR) ;
 
diff --git a/Pcie40Applications/statlink.cpp b/Pcie40Applications/statlink.cpp
index 71dda49..8e2179a 100644
--- a/Pcie40Applications/statlink.cpp
+++ b/Pcie40Applications/statlink.cpp
@@ -12,6 +12,7 @@
 
 #include "pcie40_b2slc.h"
 #include "pcie40_reg.h"
+#include "pcie40_b2config.h"
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -30,6 +31,8 @@ extern "C" void  ecs_closeLli(int dev);
 #define SLC_BAR      2
 #define SIZE_MEMO_FPGA 1024 // maximum size of memory in FPGA
 
+bool INFO = false;
+
 #ifndef D
 #define D(a,b,c) (((a)>>(c))&((1<<((b)+1-(c)))-1))
 #define B(a,b)   D(a,b,b)
@@ -59,6 +62,9 @@ void argument(int argc, char **argv){
 	fprintf(stderr, "Invalid device slot %d, Valid slot [0, %d]\n", dev_slot, MAX_SLOT);
       }
     }
+    if(ss=="--info"){
+      INFO = true;
+    }
     if(ss=="--ch"){
       for(int j = i+1; j<argc; j++){
 	ch = atoi(argv[j]);
@@ -103,13 +109,34 @@ statpice40(pcie40reg_t pcie40reg)
 	 pcie40_run_number(dev_slot),
 	 D(pcie40_sta, 28, 17),
 	 pcie40_trg_type(dev_slot));	 
-  printf("rxlink: %s | txlink: %s | txlink: %s | rxdisp: %s | rxdata: %s\n", 
+  printf("PLLs:%s | rxlink: %s | txlink: %s | txlink: %s | rxdisp: %s | rxdata: %s\n", 	  
+	 pcie40_inputPLLFrequency(dev_slot)?"LOCKED":"NOT LOCKED",
 	 B(pcie40_sta, 0)?"READY":"NOT READY",
 	 B(pcie40_sta, 1)?"READY":"NOT READY",
 	 B(pcie40_sta, 2)?"SYNCED":"NOT SYNCED",
 	 B(pcie40_sta, 3)?"ERROR":"OK",
 	 B(pcie40_sta, 4)?"ERROR":"OK");
-
+  if(INFO){
+    printf("PLL[0-23]: %s | %s | %s | %s | %s | %s\nPLL[24-47]: %s | %s | %s | %s | %s | %s\nPLL[FTSW]: %s | %s | %s | %s | %s | %s\n",
+	   pcie40_pllLockStatus(dev_slot, 1)?"LOCKED":"LOL",
+	   pcie40_pllInputStatus(dev_slot, 1)?"OK":"BAD",
+	   pcie40_pllFrequencyStatus(dev_slot, 1)?"OK":"BAD",
+	   pcie40_pllLockCounter(dev_slot, 1)?"OK":"LOL",
+	   pcie40_pllInputCounter(dev_slot, 1)?"OK":"LOS",
+	   pcie40_pllFrequencyCounter(dev_slot, 1)?"OK":"OOF",
+	   pcie40_pllLockStatus(dev_slot, 2)?"LOCKED":"LOL",
+	   pcie40_pllInputStatus(dev_slot, 2)?"OK":"BAD",
+	   pcie40_pllFrequencyStatus(dev_slot, 2)?"OK":"BAD",
+	   pcie40_pllLockCounter(dev_slot, 2)?"OK":"LOL",
+	   pcie40_pllInputCounter(dev_slot, 2)?"OK":"LOS",
+	   pcie40_pllFrequencyCounter(dev_slot, 2)?"OK":"OOF",
+	   pcie40_pllLockStatus(dev_slot, 3)?"LOCKED":"LOL",
+	   pcie40_pllInputStatus(dev_slot, 3)?"OK":"BAD",
+	   pcie40_pllFrequencyStatus(dev_slot, 3)?"OK":"BAD",
+	   pcie40_pllLockCounter(dev_slot, 3)?"OK":"LOL",
+	   pcie40_pllInputCounter(dev_slot, 3)?"OK":"LOS",
+	   pcie40_pllFrequencyCounter(dev_slot, 3)?"OK":"OOF");
+  }
   return 0;
 }
 
-- 
GitLab