From a54a055106bc36cc32a4ad6d977a56ced9e0fb6e Mon Sep 17 00:00:00 2001
From: ROBBE Patrick <robbe@lal.in2p3.fr>
Date: Wed, 24 Jul 2019 17:15:01 +0200
Subject: [PATCH] Functions for slow control

---
 Pcie40Applications/main_pcie40_b2slc.c |   6 +-
 Pcie40Libraries/pcie40_b2slc.c         | 175 +++++++++++++++----------
 Pcie40Libraries/pcie40_b2slc.h         |   4 +-
 3 files changed, 112 insertions(+), 73 deletions(-)

diff --git a/Pcie40Applications/main_pcie40_b2slc.c b/Pcie40Applications/main_pcie40_b2slc.c
index 47d17c3..31f2724 100644
--- a/Pcie40Applications/main_pcie40_b2slc.c
+++ b/Pcie40Applications/main_pcie40_b2slc.c
@@ -1,14 +1,16 @@
 #include "pcie40_ecs.h"
 #include "pcie40_b2slc.h"
+#include <stdio.h>
 
 int main(int argc, char *argv[]) { 
-  int result[5];
   ecs_open( 0 , 2 ) ;
 
-  pcie40_readfee8( 0 , 0x12 ) ;
+  int data ; 
+  int result = pcie40_readfee32( 0 , 0x12 , &data ) ;
   
   ecs_close( 0 , 2 ) ;
 
+  printf( "Value = %X\n" , result ) ;
 
   return 0 ;
 }
diff --git a/Pcie40Libraries/pcie40_b2slc.c b/Pcie40Libraries/pcie40_b2slc.c
index 50215f9..45a0069 100644
--- a/Pcie40Libraries/pcie40_b2slc.c
+++ b/Pcie40Libraries/pcie40_b2slc.c
@@ -10,7 +10,7 @@
 int pcie40_readfee8( int dev , int adr) {
   // PCIe40
   if ( ( adr <=0 ) || ( adr > 0x7F ) ) return -1 ;
-  // Reset the FIFO
+  // Reset the FIFO (Emit and reception)
   unsigned ret = 0 ;
   ret = ecs_write( dev , SLC_BAR , SLC_WFIFO_RESET_ADD , 
 		   1 << SLC_WFIFO_RESET_BIT ) ;
@@ -48,46 +48,69 @@ int pcie40_readfee8( int dev , int adr) {
   ret = ecs_write( dev , SLC_BAR , SLC_WFIFO_RESET_ADD , 0 ) ;
   if ( ret != 0 ) return -1 ;
 
-  return 0 ;
-
-  // Wait for the result to come back
+  // Wait for the result to come back (1 word in the fifo)
   int i ;
   for ( i=0 ; i<10 ; i++ ) {
     usleep( 10 ) ; //10 ms
     ret = ecs_read( dev , SLC_BAR , SLC_RFIFO_STATUS ) ;
-    if ( ret == 0x11 ) break;
+    if ( ret == 1 ) break;
   }
 
   if (i == 10) return -1;
 
   // Read the value 
   ret = ecs_read( dev , SLC_BAR , SLC_RFIFO_ADD );
+  
+  // check address consistency
+  if ( ( ( ret & 0x7F00 ) >> 8 ) != adr ) return -1 ;
 
-  return ret;
+  return ( ret & 0xFF ) ;
 }
 
 //==============================================================================
 // Write 8b
 //==============================================================================
 int pcie40_writefee8( int dev , int adr , int val ) {
-  if ( ( adr <= 0 ) || ( adr > 0x7F ) ) return -1 ;
-  int ret ;
+  // PCIe40
+  if ( ( adr <=0 ) || ( adr > 0x7F ) ) return -1 ;
+  // Reset the FIFO
+  unsigned ret = 0 ;
   ret = ecs_write( dev , SLC_BAR , SLC_WFIFO_RESET_ADD , 
 		   1 << SLC_WFIFO_RESET_BIT ) ;
   if ( ret != 0 ) return -1 ;
-  
-  int data_word_1 = 
-    ( 0x73 ) | ( 0x0a << 8 ) | ( adr << 16 ) | ( ( val & 0xFF ) << 24 ) ;
-  int data_word_2 = ( 0x08 << 0 ) ;
+  ret = ecs_write( dev , SLC_BAR , SLC_WFIFO_RESET_ADD , 0 ) ;
+  if ( ret != 0 ) return -1 ;
+
+  // Fill the FIFO with the requested information: write MSB first
+  int data_word_1 = 0xFFFE ;
+  int data_word_2 = 0x0001 ;
+  int data_word_3 = 0x8000 | ( adr & 0x7F ) ;
+  int data_word_4 = 0x0000 | ( val & 0xFF ) ;
+  int data_word_5 = 0xEEEE ;
 
   ret = ecs_write( dev , SLC_BAR , SLC_WFIFO_ADD , 
 		   (int) ( data_word_1 & 0xFFFFFFFF ) ) ;
   if ( ret != 0 ) return -1 ;
-
   ret = ecs_write( dev , SLC_BAR , SLC_WFIFO_ADD , 
 		   (int) ( data_word_2 & 0xFFFFFFFF ) ) ;
   if ( ret != 0 ) return -1 ;
-  
+  ret = ecs_write( dev , SLC_BAR , SLC_WFIFO_ADD , 
+		   (int) ( data_word_3 & 0xFFFFFFFF ) ) ;
+  if ( ret != 0 ) return -1 ;
+  ret = ecs_write( dev , SLC_BAR , SLC_WFIFO_ADD , 
+		   (int) ( data_word_4 & 0xFFFFFFFF ) ) ;
+  if ( ret != 0 ) return -1 ;
+  ret = ecs_write( dev , SLC_BAR , SLC_WFIFO_ADD , 
+		   (int) ( data_word_5 & 0xFFFFFFFF ) ) ;
+  if ( ret != 0 ) return -1 ;
+
+  // start emit
+  ret = ecs_write( dev , SLC_BAR , SLC_WFIFO_RESET_ADD , 
+  		   1 << SLC_WFIFO_EMIT_BIT ) ;
+  if ( ret != 0 ) return -1 ;
+  ret = ecs_write( dev , SLC_BAR , SLC_WFIFO_RESET_ADD , 0 ) ;
+  if ( ret != 0 ) return -1 ;
+
   return 0 ;
 }
 
@@ -96,7 +119,7 @@ int pcie40_writefee8( int dev , int adr , int val ) {
 //==============================================================================
 int pcie40_readfee32( int dev , int adr , int *valp ) {
   // PCIe40
-  if ( ( adr <=0 ) || ( adr > 0x7F ) ) return -1 ;
+  if ( ( adr <0 ) || ( adr > 0xFFFF ) ) return -1 ;
   // Reset the FIFO
   unsigned ret = 0 ;
   ret = ecs_write( dev , SLC_BAR , SLC_WFIFO_RESET_ADD , 
@@ -105,55 +128,60 @@ int pcie40_readfee32( int dev , int adr , int *valp ) {
   ret = ecs_write( dev , SLC_BAR , SLC_WFIFO_RESET_ADD , 0 ) ;
   if ( ret != 0 ) return -1 ;
 
-  // Fill the FIFO with the requested information
-  int data_word_1 = 
-    ( 0x73 ) | ( 0x0c << 8 ) | ( ( adr & 0xFF ) << 16 ) | 
-    ( ( ( adr & 0xFF00 ) >> 8 ) << 24 ) ;
-  int data_word_2 = ( 0x04 << 24 ) | ( 0x04 << 16 ) | ( 0x0c0c ) ;
+  // Fill the FIFO with the requested information: write MSB first
+  int data_word_1 = 0xFFFB ;
+  int data_word_2 = 0x7000 | ( ( adr & 0xFF00 ) >> 8 ) ;
+  int data_word_3 = 0x7000 | ( adr & 0xFF ) ;
+  int data_word_5 = 0xEEEE ;
 
-  //
   ret = ecs_write( dev , SLC_BAR , SLC_WFIFO_ADD , 
-		   ( data_word_1 & 0xFFFFFFFF ) ) ; 
+		   (int) ( data_word_1 & 0xFFFFFFFF ) ) ;
   if ( ret != 0 ) return -1 ;
   ret = ecs_write( dev , SLC_BAR , SLC_WFIFO_ADD , 
-		   ( data_word_2 & 0xFFFFFFFF ) ) ; 
+		   (int) ( data_word_2 & 0xFFFFFFFF ) ) ;
   if ( ret != 0 ) return -1 ;
-
-  int data_word_3 = 
-    ( 0x73 ) | ( 0x0c << 8 ) | ( 0x0c  << 16 ) | ( 0x0c << 24 ) ;
-  int data_word_4 = ( 0x08 << 24 ) | ( 0x02 << 16 ) | ( 0x0c0c ) ;
-
-  //
   ret = ecs_write( dev , SLC_BAR , SLC_WFIFO_ADD , 
-		   ( data_word_3 & 0xFFFFFFFF ) ) ; 
+		   (int) ( data_word_3 & 0xFFFFFFFF ) ) ;
   if ( ret != 0 ) return -1 ;
   ret = ecs_write( dev , SLC_BAR , SLC_WFIFO_ADD , 
-		   ( data_word_4 & 0xFFFFFFFF ) ) ; 
+		   (int) ( data_word_5 & 0xFFFFFFFF ) ) ;
   if ( ret != 0 ) return -1 ;
 
   // start emit
   ret = ecs_write( dev , SLC_BAR , SLC_WFIFO_RESET_ADD , 
-		   1 << SLC_WFIFO_EMIT_BIT ) ;
+  		   1 << SLC_WFIFO_EMIT_BIT ) ;
   if ( ret != 0 ) return -1 ;
   ret = ecs_write( dev , SLC_BAR , SLC_WFIFO_RESET_ADD , 0 ) ;
   if ( ret != 0 ) return -1 ;
-  
-  return 0 ;
 
   // Wait for the result to come back
   int i ;
   for ( i=0 ; i<10 ; i++ ) {
     usleep( 10 ) ; //10 ms
     ret = ecs_read( dev , SLC_BAR , SLC_RFIFO_STATUS ) ;
-    if ( ret == 0x11 ) break;
+    if ( ret == 4 ) break;
   }
 
   if (i == 10) return -1;
 
   // Read the value 
-  ret = ecs_read( dev , SLC_BAR , SLC_RFIFO_ADD );
-
-  return ret;
+  int ret1 = ecs_read( dev , SLC_BAR , SLC_RFIFO_ADD );
+  int ret2 = ecs_read( dev , SLC_BAR , SLC_RFIFO_ADD );
+
+  int add1 = ( ret1 & 0x7F000000 ) >> 24 ;
+  int add2 = ( ret1 & 0x7F00 ) >> 8 ;
+  int add3 = ( ret2 & 0x7F000000 ) >> 24 ;
+  int add4 = ( ret2 & 0x7F00 ) >> 8 ;
+
+  if ( ( add1 != 0x6C ) || ( add2 != 0x6D ) || ( add3 != 0x6A ) || ( add4 != 0x6B ) )
+    return -1 ;
+
+  int res1 = ( ret1 & 0xFF0000 ) >> 16 ;
+  int res2 = ( ret1 & 0xFF ) ;
+  int res3 = ( ret2 & 0xFF0000 ) >> 16 ;
+  int res4 = ( ret2 & 0xFF ) ;
+ 
+  return ( res2 << 24 ) | ( res1 << 16 ) | ( res4 << 8 ) | ( res3 ) ;
 }
 
 //==============================================================================
@@ -161,53 +189,62 @@ int pcie40_readfee32( int dev , int adr , int *valp ) {
 //==============================================================================
 int pcie40_writefee32( int dev , int adr , int val ) { 
   // PCIe40
-  if ( ( adr <=0 ) || ( adr > 0x7F ) ) return -1 ;
+  if ( ( adr <0 ) || ( adr > 0xFFFF ) ) return -1 ;
   // Reset the FIFO
   unsigned ret = 0 ;
   ret = ecs_write( dev , SLC_BAR , SLC_WFIFO_RESET_ADD , 
 		   1 << SLC_WFIFO_RESET_BIT ) ;
   if ( ret != 0 ) return -1 ;
+  ret = ecs_write( dev , SLC_BAR , SLC_WFIFO_RESET_ADD , 0 ) ;
+  if ( ret != 0 ) return -1 ;
+
+  int val1 = ( val & 0xFF ) ;
+  int val2 = ( val & 0xFF00 ) >> 8 ;
+  int val3 = ( val & 0xFF0000 ) >> 16 ;
+  int val4 = ( val & 0xFF000000 ) >> 24 ;
+
+  // Fill the FIFO with the requested information: write MSB first
+  int data_word_1 = 0xFFFB ;
+  int data_word_2 = 0x7000 | ( ( adr & 0xFF00 ) >> 8 ) ;
+  int data_word_3 = 0x7000 | ( adr & 0xFF ) ;
+  int data_word_4 = 0x7000 | val1 ;
+  int data_word_5 = 0x7000 | val2 ;
+  int data_word_6 = 0x7000 | val3 ;
+  int data_word_7 = 0x7000 | val4 ;
+  int data_word_8 = 0xEEEE ;
 
-  // Fill the FIFO with the requested information
-  int data_word_1 = 
-    ( 0x73 ) | ( 0x0b << 8 ) | ( ( adr & 0xFF ) << 16 ) | 
-    ( ( ( adr & 0xFF00 ) >> 8 ) << 24 ) ;
-  int data_word_2 = ( 0x04 << 24 ) | ( 0x04 << 16 ) 
-    | ( val & 0xFF ) | ( ( ( val & 0xFF00 ) >> 8 ) << 8 );
 
-  //
   ret = ecs_write( dev , SLC_BAR , SLC_WFIFO_ADD , 
-		   ( data_word_1 & 0xFFFFFFFF ) ) ; 
+		   (int) ( data_word_1 & 0xFFFFFFFF ) ) ;
   if ( ret != 0 ) return -1 ;
   ret = ecs_write( dev , SLC_BAR , SLC_WFIFO_ADD , 
-		   ( data_word_2 & 0xFFFFFFFF ) ) ; 
+		   (int) ( data_word_2 & 0xFFFFFFFF ) ) ;
   if ( ret != 0 ) return -1 ;
-
-  int data_word_3 = 
-    ( 0x73 ) | ( 0x0c << 8 ) | ( ( ( val & 0xFF0000 ) >> 16 )  << 16 ) | 
-    ( ( (val & 0xFF000000 ) >> 24 ) << 24 ) ;
-  int data_word_4 = ( 0x08 << 24 ) | ( 0x02 << 16 ) | ( 0x0c0c ) ;
-
-  //
   ret = ecs_write( dev , SLC_BAR , SLC_WFIFO_ADD , 
-		   ( data_word_3 & 0xFFFFFFFF ) ) ; 
+		   (int) ( data_word_3 & 0xFFFFFFFF ) ) ;
   if ( ret != 0 ) return -1 ;
   ret = ecs_write( dev , SLC_BAR , SLC_WFIFO_ADD , 
-		   ( data_word_4 & 0xFFFFFFFF ) ) ; 
+		   (int) ( data_word_4 & 0xFFFFFFFF ) ) ;
+  if ( ret != 0 ) return -1 ;
+  ret = ecs_write( dev , SLC_BAR , SLC_WFIFO_ADD , 
+		   (int) ( data_word_5 & 0xFFFFFFFF ) ) ;
+  if ( ret != 0 ) return -1 ;
+  ret = ecs_write( dev , SLC_BAR , SLC_WFIFO_ADD , 
+		   (int) ( data_word_6 & 0xFFFFFFFF ) ) ;
+  if ( ret != 0 ) return -1 ;
+  ret = ecs_write( dev , SLC_BAR , SLC_WFIFO_ADD , 
+		   (int) ( data_word_7 & 0xFFFFFFFF ) ) ;
+  if ( ret != 0 ) return -1 ;
+  ret = ecs_write( dev , SLC_BAR , SLC_WFIFO_ADD , 
+		   (int) ( data_word_8 & 0xFFFFFFFF ) ) ;
   if ( ret != 0 ) return -1 ;
 
-  // Wait for the result to come back
-  int i ;
-  for ( i=0 ; i<10 ; i++ ) {
-    usleep( 10 ) ; //10 ms
-    ret = ecs_read( dev , SLC_BAR , SLC_RFIFO_STATUS ) ;
-    if ( ret == 0x11 ) break;
-  }
-
-  if (i == 10) return -1;
-
-  // Read the value 
-  ret = ecs_read( dev , SLC_BAR , SLC_RFIFO_ADD );
+  // start emit
+  ret = ecs_write( dev , SLC_BAR , SLC_WFIFO_RESET_ADD , 
+  		   1 << SLC_WFIFO_EMIT_BIT ) ;
+  if ( ret != 0 ) return -1 ;
+  ret = ecs_write( dev , SLC_BAR , SLC_WFIFO_RESET_ADD , 0 ) ;
+  if ( ret != 0 ) return -1 ;
 
   return ret;
 }
diff --git a/Pcie40Libraries/pcie40_b2slc.h b/Pcie40Libraries/pcie40_b2slc.h
index 108d383..5500998 100644
--- a/Pcie40Libraries/pcie40_b2slc.h
+++ b/Pcie40Libraries/pcie40_b2slc.h
@@ -10,8 +10,8 @@
 #define SLC_WFIFO_RESET_BIT 8
 #define SLC_WFIFO_EMIT_BIT 0
 #define SLC_WFIFO_ADD 0x00050000
-#define SLC_RFIFO_STATUS 0x00000
-#define SLC_RFIFO_ADD 0x0000
+#define SLC_RFIFO_STATUS 0x00050160
+#define SLC_RFIFO_ADD 0x00050140
 
 // Functions to read/write registers and stream files to Front End
 
-- 
GitLab