From 1ac9be7925ee9b38a30ab87ce53a09ada8363e52 Mon Sep 17 00:00:00 2001
From: Gijs Schoonderbeek <schoonderbeek@astron.nl>
Date: Thu, 27 May 2021 18:07:17 +0200
Subject: [PATCH] 1000Mb/s to the FPGAs is working

---
 spi_switch_Unb2c.py | 175 +++++++++++++++++++++++++-------------------
 1 file changed, 100 insertions(+), 75 deletions(-)

diff --git a/spi_switch_Unb2c.py b/spi_switch_Unb2c.py
index bdb48a7..9ddd737 100644
--- a/spi_switch_Unb2c.py
+++ b/spi_switch_Unb2c.py
@@ -15,6 +15,15 @@ limitations under the License.
 Created: 2021-05-19 by Leon Hiemstra, edited by Gijs
 file used to read and write to switch registers
 
+This script is made to run on a Raspberry pi where SPI port 0 is connected
+to the EEPROM socket.
+
+use for setting the switch
+Python spi_switch_Unb2c.py set
+
+use for information
+Python spi_switch_Unb2c.py stat
+
 """
 
 import time
@@ -35,7 +44,7 @@ spi = spidev.SpiDev()
 spi.open(bus, device)
 
 # Set SPI speed and mode
-spi.max_speed_hz = 1000000
+spi.max_speed_hz = 2000000
 #spi.max_speed_hz = 50000
 spi.mode = 1
 
@@ -45,6 +54,9 @@ cmd_normal_write = 0x61
 
 
 def read_register(addr):
+    #
+    # Function to read from a SPI register
+    #
     cmd =  cmd_normal_read
     if 0:
         spi.writebytes([cmd,addr])
@@ -57,6 +69,9 @@ def read_register(addr):
     return ret[2:]
 
 def write_register(addr, data):
+    #
+    # Function to write to a SPI register
+    #
     cmd =  cmd_normal_write
     if 0:
         spi.writebytes([cmd, addr, data])
@@ -68,6 +83,9 @@ def write_register(addr, data):
         print(stri)
 
 def read_switch(page, addr, pr_stri = True):
+    #
+    # Function to read from a register on the Switch
+    #
     stri = '<< read switch from page: 0x{0:0>2x}, address: 0x{1:0>2x}'.format(page, addr)
     ret = spi.xfer2([cmd_normal_write, 0xff, page])
     ret = spi.xfer2([cmd_normal_read, addr, 0, 0, 0, 0])
@@ -85,6 +103,9 @@ def read_switch(page, addr, pr_stri = True):
     return ret
 
 def write_switch_bytes(page, addr, data, pr_stri = True):
+    #
+    # Function to write to a register on the Switch
+    #
     stri = '> write switch from page: 0x{0:0>2x}, address: 0x{1:0>2x} data 0x'.format(page, addr)
     for byte_cnt in range(len(data)):
         add_stri = "{0:0>2x}".format(data[-1-byte_cnt])
@@ -104,7 +125,10 @@ def write_switch_bytes(page, addr, data, pr_stri = True):
         read_register(0xfe)
         read_register(addr)
 
-def read_link_status(ports=16):
+def read_link_status():
+    #
+    # Function to read the port information on the switch
+    #
     print("links status register")
     ret = read_switch(0x01,0x00, pr_stri=False)
     stri = "|15 |14 |13 |12 |11 |10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |"
@@ -116,34 +140,34 @@ def read_link_status(ports=16):
         else:
             stri += "  | "
     print(stri)
-    for cnt in range(ports):
+    for cnt in [0,1,2,3]:
         stri = "Port status phy nr {} ".format(cnt)
         ret = read_switch(0x01,0x20+cnt, pr_stri = False)
         if ret[1] & 0x01:
             stri += "link up "
+            if ret[1] & 0x02:
+                stri += "dupplex "
+            else:
+                stri += "simplex "
+            if ret[1] & 0x4:
+                stri += " 100M "
+            elif ret[1] & 0x8:
+                stri += "1000M "
+            else:
+                stri += "  10M "
+            ret = read_switch(0x10+cnt,0x28, pr_stri = False)
+            if ret[1] & 0x01:
+                stri += "SGMII  "
+            else:
+                stri += "SERDES "
+            if ret[2] & 0x08:
+                stri += "Tx: Er "
+            if ret[2] & 0x04:
+                stri += "Rx: Er "
+            if ret[2] & 0x40:
+                stri += "Rx FIFO Er "
         else:
             stri += "link down "
-        if ret[1] & 0x02:
-            stri += "dupplex "
-        else:
-            stri += "simplex "
-        if ret[1] & 0x4:
-            stri += " 100M "
-        elif ret[1] & 0x8:
-            stri += "1000M "
-        else:
-            stri += "  10M "
-        ret = read_switch(0x10+cnt,0x28, pr_stri = False)
-        if ret[1] & 0x01:
-            stri += "SGMII  "
-        else:
-            stri += "SERDES "
-        if ret[2] & 0x08:
-            stri += "Tx: Er "
-        if ret[2] & 0x04:
-            stri += "Rx: Er "
-        if ret[2] & 0x40:
-            stri += "Rx FIFO Er "
         print(stri)
 # Read phy registister status
     for cnt in range(4):
@@ -177,67 +201,68 @@ def read_link_status(ports=16):
             write_switch_bytes(0x80+cnt, 0x3c, [0x35, 0x08], pr_stri = False)
             ret = read_switch(0x80+cnt,0x3e)
     if 0:
-        print("Drop packet count register")
-        for cnt in range(16):
-#        read_switch(0x41,0x80+2*cnt)
-            read_switch(0x0,0x0 + cnt)
-        print("Port State Override")
-        for cnt in range(16):
-    #        read_switch(0x41,0x80+2*cnt)
-            read_switch(0x0,0x60 + cnt)
-        read_switch(0x0,0x10)
-        read_switch(0x0,0x20)
-    if 1:
-        print("Receive count register")
-        for cnt in range(16):
-            # Set to receive packet count
-            write_switch_bytes(0x10+cnt, 0x20, [0xD0, 0x09], pr_stri = False) 
-        time.sleep(0.5)
+        # Lines to read the received packets
+        # Only works in combination with register on page 0x10+ch cont, addr: 0x20
+        print("Receive count register") 
         for cnt in range(16):
             read_switch(0x10+cnt,0x2e)
-        
+    if 1:
+        # alternative status read out, works better for SerDes lines.
+        for prt_cnt in [9, 10, 11,12, 13,14, 15]:
+            ret = read_switch(0x10+prt_cnt,0x28, pr_stri = False)
+            stri = "Port status of " + str(prt_cnt) + " "
+            if ret[1] & 0x02:
+                stri += "UP "
+                if ret[1] & 0x01:
+                    stri += "SGMII "
+                else:
+                    stri += "SerDes "
+                if ret[1] & 0x10:
+                    stri += "1000M "
+                elif ret[1] & 0x08:
+                    stri += "100M "
+                else:
+                    stri += "10M "
+                if ret[1] & 0x80:
+                    stri += "Link Changed "
+                if ret[2] & 0x04:
+                    stri += "Rx Err "
+                if ret[2] & 0x08:
+                    stri += "Tx Err "
+                if ret[2] & 0x10:
+                    stri += "CRC Err "
+                if ret[2] & 0x40:
+                    stri += "Rx Fifo Err "
+                if ret[2] & 0x80:
+                    stri += "Tx Fifo Err "
+            else:
+                stri += "Down "
+            print(stri)
+    print("strap resistors")
+    read_switch(0x01,0x70)
+
 
 
 
 if len(sys.argv) < 2:
-    print(sys.argv)
-    print("write and read led register")
-    write_switch_bytes(0x00, 0x24, [0x20, 0x02]) #LSB first
-    read_switch(0x00,0x24)
-    print("write and read jumbo register")
-    write_switch_bytes(0x40, 0x01, [0xff, 0xff, 0x00, 0x00])
-    read_switch(0x40,0x01)
-    print("strap resistors")
-    read_switch(0x01,0x70)
-    read_link_status(4)
+    print("spi_switch_Unb2c stat for status")
+    print("spi_switch_Unb2c set  to set registers")
 elif sys.argv[1] == "stat":
-    read_link_status(16)
+    read_link_status()
 elif sys.argv[1] == "set":
-    # Extra setting for the switch, not needed, bonus settings
-    if 0:
-        print("write and read led register")
-        write_switch_bytes(0x00, 0x24, [0x20, 0x02]) #LSB first
-        read_switch(0x00,0x24)
-        print("write and read jumbo register")
-        write_switch_bytes(0x40, 0x01, [0xff, 0xff, 0x00, 0x00])
+    # Setting for the switch
+    print("Write and read jumbo register")
+    write_switch_bytes(0x40, 0x01, [0xff, 0xff, 0x00, 0x00])
+    if DEBUG:
         read_switch(0x40,0x01)
-        print("strap resistors")
-        read_switch(0x01,0x70)
-    # required setting for the switch
-    if 1:
-#        for ch_cnt in range(16):
-#           print("write and read SGMII register CH0, fifo size max")
-#           write_switch_bytes(0x10+ch_cnt, 0x24, [0x44, 0x00])
-#           read_switch(0x10+ch_cnt,0x24)
-        speed_100Mbit = False
-        speed_1000Mbit = False
-        for ch_cnt in range(4):
-            print("Set PHY ch 0 and read back to 10 Mbit 0x01 100Mbit 0x21")
-            write_switch_bytes(0x80 + ch_cnt, 0x00, [(0x00 | (speed_1000Mbit << 6)), (0x01 | (speed_100Mbit << 5))])
-            write_switch_bytes(0x00, 0x60 + ch_cnt, [(0x83 | (speed_100Mbit << 2) | (speed_1000Mbit << 3))]) # fix PHY ports to 10 Mbit
-# Set the FPGA links to disable Auto negatiation
-    for cnt in [15, 13, 11, 9]: # only ETH0 interface
+    print("Set PHY port to SGMII Master")
+    for ch_cnt in range(4):
+        write_switch_bytes(0x10 + ch_cnt, 0x20, [0xe0, 0x09])            
+    print("Fix ports to 1000Mb/s")
+    for cnt in [15, 14, 13, 12, 11, 10, 9, 8]: #, 0, 1, 2, 3]: # only ETH0 interface
         write_switch_bytes(0x00, 0x60+cnt, [0x8B]) #Fix FPGA links
+    for cnt in [0, 1, 2, 3]: # only ETH0 interface
+        write_switch_bytes(0x00, 0x60+cnt, [0x8B])
 else:
     print("spi_switch_Unb2c stat for status")
     print("spi_switch_Unb2c set  to set registers")
-- 
GitLab