#!/usr/bin/python
#===============================================================================
# CERN (BE-CO-HT)
# Pulse test script
#===============================================================================
# author: Denia Bouhired(t.stana@cern.ch)
#
# date of creation:
#
# version: 1.0
#
# description:
# This script is used during manual upgrade of conv-ttl boards.
# It is used to:
# - Scan barcode of board
# - Read hw version
# - Read gw version
# - Read unique temperature chip ID
# - Output information on log file
#
#===============================================================================
# GNU LESSER GENERAL PUBLIC LICENSE
#===============================================================================
# This source file is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by the
# Free Software Foundation; either version 2.1 of the License, or (at your
# option) any later version. This source is distributed in the hope that it
# will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
# of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU Lesser General Public License for more details. You should have
# received a copy of the GNU Lesser General Public License along with this
# source; if not, download it from http://www.gnu.org/licenses/lgpl-2.1.html
#===============================================================================

#===============================================================================
#  TODO: 
#===============================================================================


import sys
sys.path.append("../ei2c")	
sys.path.append("../multiboot/lib-multiboot")
import time
from ei2c import *
from ei2cexcept import *
import binascii
import re
import subprocess
import os
import traceback
from xil_multiboot import *

##-------------------------------------------------------------------------------------------------
## Method to turn on the VME crate.
##-------------------------------------------------------------------------------------------------
## It calls the men-on script which sends the necessary SMTP commands to the ELMA crate to turn on
## power to the VME backplane.
##-------------------------------------------------------------------------------------------------
def men_on():
    print("Switching on the ELMA crate")
    subprocess.call("./men-on", shell=True, stdout=None, stderr=None)
    time.sleep(1)

##-------------------------------------------------------------------------------------------------
## Method to turn off the VME crate.
##-------------------------------------------------------------------------------------------------
## It calls the men-off script which sends the necessary SMTP commands to the ELMA crate to turn off
## power to the VME backplane.
##-------------------------------------------------------------------------------------------------
def men_off():
    print("Switching off the ELMA crate")
    subprocess.call("./men-off", shell=True, stdout=None, stderr=None)
    time.sleep(1)

##-------------------------------------------------------------------------------------------------
# Define registers memory address
IDREG = 0x00		# Board ID register
SRREG = 0x04		# Status register
UIDREGLS = 0xac		# 1-wire chip Unique ID - LSB
UIDREGMS = 0xb0		# 1-wire chip Unique ID - MSB

# Status register offsets
CSR_GWVERS_OFS     = 0
CSR_HWVERS_OFS     = 22

# Target version
gwvers_target =  0.0      # Add release version here Eg: gwvers_target =  1.0
gwvers_gold_target = 0.0  # Add golden version here Eg: gwvers_gold_target =  0.2

#gateware to write
#gw_file="golden-v"+str(gwvers_gold_target)+".bin"
gw_file="golden-v"+str(gwvers_gold_target)+"_release-v"+str(gwvers_target)+".bin"

##-------------------------------------------------------------------------------------------------
## Method to check hardware and gateware version
##-------------------------------------------------------------------------------------------------
def gw_hw_version():
    hwvers = (elma.read(slot, SRREG) & 0x0fc00000) >> CSR_HWVERS_OFS
    gwvers = (elma.read(slot, SRREG) & 0xFF) >> CSR_GWVERS_OFS 
    
    #print ("maj is %d, min is %d" % int(hwvers >> 2), int(hwvers & 0x03))
    hwvers = int(hwvers >> 2)+float(hwvers & 0x03)/10
    gwvers = int(gwvers >> 4)+float(gwvers & 0xF)/10
    
    return hwvers, gwvers;

##-------------------------------------------------------------------------------------------------
## Main "method" of upgrade module
##-------------------------------------------------------------------------------------------------
if __name__ == "__main__":

    	crate_list = "crate_list.txt"

	fin = open ('./crate_list.txt', 'r')
	
	for crate_line in fin:
		#Split each line into list of strings
		crate_info=crate_line.split()

		# Get the IP, user and password for the ELMA crate from ei2cdefine.py
		ip   = crate_info[0]
		user = crate_info[1]
		pwd  = crate_info[2]
		slot = int(crate_info[3])
		elma = EI2C(ip, user, pwd)
		try:
			elma.open()              
			print ("---------------------------------")
			print ("Connecting to crate %s ...  \n" % ip)
	    		# Get board ID and gateware version, fail if incorrect
			bid = elma.get_bid(slot)
			(hwvers, gwvers) = gw_hw_version()
		
			upgrade=True
			#Check whether upgrade is required
		    	if (gwvers == gwvers_target):
				upgrade=False
		
			baseaddr = 0x100
			if (bid == "TBLO"):
				gw_path="./gw-blo/"
			elif (bid == "T485"):
				gw_path="./gw-rs485/"
			if upgrade==True:
				print("Upgrade file is %s \n" % gw_path+gw_file)
				mb = XilMultiboot(ELMA_I2C_MULTIBOOT, elma, slot, baseaddr, "")
				mb.set_bitstream_file(gw_path+gw_file)
				multiboot_addr = "0x0"
				multiboot_addr = int(multiboot_addr, 16)
				mb.write(multiboot_addr)
				mb.iprog(multiboot_addr)

		
			time.sleep(10)

		    	(hwvers_new, gwvers_new) = gw_hw_version()	    
		    
			if (hwvers_new == 0.0):
		    		hwvers_new_str = "<4.0"
		    	else:
			
		    		hwvers_new_str = str(hwvers_new)       

		    	IDMS = elma.read(slot, UIDREGMS) 
		    	IDLS = elma.read(slot, UIDREGLS)   
	    	except BadHostnameError:
			print("... Bad crate name ... \n")
			(IDMS, IDLS, hwvers_new_str, gwvers, gwvers_new) = (0,0,"BadHostname",0,0)  
	    	except BadUsernameError:
			print("... Bad user name ... \n")
			(IDMS, IDLS, hwvers_new_str, gwvers, gwvers_new) = (0,0,"BadUsername",0,0)  
	    	except BadPasswordError:
			print("... Bad password ... \n")
			(IDMS, IDLS, hwvers_new_str, gwvers, gwvers_new) = (0,0,"BadPassword",0,0)  
	    	except NAckError:
			print("... Board not responding... \n")
			(IDMS, IDLS, hwvers_new_str, gwvers, gwvers_new) = (0,0,"NAckError",0,0)
		
	
		    #Generate log file
		    # Generate output file named according to current time

		fname = bid+"-"+time.strftime("remote-gwupgrade-%s-%Y-%m-%d", bid, time.localtime()) + ".txt"
		ret = subprocess.call(["ls ./log | grep " + fname], shell=True, stdout=None, stderr=None)
		print ("%d" % ret) 
		if (ret != 0):
		    	f     = open("./log/" + fname, "w")

			f.write("\n")
			f.write("CONV-TTL-XXX Upgrade log created on %s \n" % time.strftime("%Y-%m-%d-%Hh%Mm%Ss", time.localtime()))
		
			f.write("--------------------------------------------------------------------------------- \n")
			f.write("* Target version is (v%2.1f)\n" % gwvers_target)
			f.write("* Hardware (v0.0) means board is (v3.0) or earlier \n")
			f.write("\n")
			f.write("--------------------------------------------------------------------------------- \n")
			f.write("Crate name| Slot |Barcode | PCB ID | HW version | Old gw version | New gw version\n")
			f.write("--------------------------------------------------------------------------------- \n")
			f.close()

		print("Upgrade log can be found in ./log/%s \n" %  fname)
		    
		f     = open("./log/" + fname, "a")
		f.write("%s \t %d \t %x%x \t (%s) \t (%2.1f) \t (%2.1f) \n" % (ip, slot, IDMS, IDLS, hwvers_new_str, gwvers, gwvers_new) )
		   
		f.close()

	    		
          
	  

 
  
