#
# Script to exercise AIDA mini-TLU
#
# David Cussans, December 2012
# 
# Modified by Alvaro Dosil, January 2013

from PyChipsUser import *
from FmcTluI2c import *
from ROOT import *

import sys
import time


def mean(TS):
    val=0
    for i in range(1,len(TS)):
        val+=TS[i]-TS[i-1]
    return val/(len(TS)-1)



bAddrTab = AddressTable("./aida_mini_tlu_addr_map.txt")

# Assume DIP-switch controlled address. Switches at 1 
board = ChipsBusUdp(bAddrTab,"192.168.200.16",50001)

# Check the bus for I2C devices
boardi2c = FmcTluI2c(board)

firmwareID=board.read("FirmwareId")
firmwareID=board.read("FirmwareId")

print "Firmware = " , hex(firmwareID)

print "Scanning I2C bus:"
scanResults = boardi2c.i2c_scan()
print scanResults

boardId = boardi2c.get_serial_number()
print "FMC-TLU serial number = " , boardId

resetClocks = 0
resetSerdes = 1 

# set DACs to -200mV
print "Setting all threshold DAC to -200mV "
boardi2c.set_threshold_voltage(7, 1.0)

clockStatus = board.read("LogicClocksCSR")
print "Clock status = " , hex(clockStatus)

if resetClocks:
    print "Resetting clocks"
    board.write("LogicRst", 1 )

    clockStatus = board.read("LogicClocksCSR")
    print "Clock status after reset = " , hex(clockStatus)

inputStatus = board.read("SerdesRstR")
print "Input status = " , hex(inputStatus)

if resetSerdes:
    board.write("SerdesRstW", 0x00000003 )
    inputStatus = board.read("SerdesRstR")
    print "Input status during reset = " , hex(inputStatus)

    board.write("SerdesRstW", 0x00000000 )
    inputStatus = board.read("SerdesRstR")
    print "Input status after reset = " , hex(inputStatus)

    board.write("SerdesRstW", 0x00000004 )
    inputStatus = board.read("SerdesRstR")
    print "Input status during calibration = " , hex(inputStatus)

    board.write("SerdesRstW", 0x00000000 )
    inputStatus = board.read("SerdesRstR")
    print "Input status after calibration = " , hex(inputStatus)

# Look at status of input IODELAYs
numLoops = 5

for iLoop in range(0,numLoops):

    inputStatus = board.read("SerdesRstR")
    print "Input status = " , hex(inputStatus)

    count0 = board.read("ThrCount0R")
    print " Count 0 = " , count0

    count1 = board.read("ThrCount1R")
    print " Count 1 = " , count1

    count2 = board.read("ThrCount2R")
    print " Count 2 = " , count2

    count3 = board.read("ThrCount3R")
    print " Count 3 = " , count3

    time.sleep(1.0)

board.write("InternalTriggerIntervalW",0)

print "Enabling DUT 1"
board.write("DUTMaskW",0)
board.write("TriggerMaskW",0x0)
board.write("TriggerVetoW",0)
print "Trigger inputs enabled: ", board.read("TriggerMaskR")

print "Reseting FIFO"
board.write("EventFifoCSR",0x2)

print "Enabling to record data"
board.write("Enable_Record_Data",1)

print "Enabling handshake: No-handshake"
board.write("HandshakeTypeW",1)

TriggerInterval = 160
board.write("InternalTriggerIntervalW",TriggerInterval)  #0->Internal pulse generator disabled. Any other value will generate pulses with a frequency of n*6.25ns

#sys.exit(0)

f=open("data/data.dat",'w')

n=600000   #number of measurements
data={"EvtType":[],"InputTrig":[],"CoarseTS":[],"FineTS0":[],"FineTS1":[],"FineTS2":[],"FineTS3":[],"EvtNumber":[], "TS":[]}
read=range(4)
trigger_old=0
i=0
while i<n:
	PostVetoTrig = board.read("PostVetoTriggersR")
	if PostVetoTrig!=trigger_old:
            f.write("word "+str(hex(i))+"\n")
            for j in range(4):
                read[j] = board.read("EventFifoData")
                f.write(str(hex(read[j]))+"\n")
            trigger_old = PostVetoTrig
	else: continue
	data["EvtType"].append(read[0] >> 28)
	data["InputTrig"].append((read[0]&0xfff0000)>>16)
	data["CoarseTS"].append(((read[0]&0xffff)<<32) | read[1])
	data["FineTS0"].append(read[2]>>24)
	data["FineTS1"].append(read[2]>>16 & 0xff)
	data["FineTS2"].append(read[2]>>8 & 0xff)
	data["FineTS3"].append(read[2] & 0xff)
	data["EvtNumber"].append(read[3])
        #if read[3]&0x84000000!=0: sys.exit(0)
        
        if data["InputTrig"][i]==0x800:
            data["TS"].append(data["CoarseTS"][i]*25+(data["FineTS0"][i]>>3)*6.25+(data["FineTS0"][i]&0x7)*0.781)
        elif data["InputTrig"][i]==0x400:
            data["TS"].append(data["CoarseTS"][i]*25+(data["FineTS1"][i]>>3)*6.25+(data["FineTS1"][i]&0x7)*0.781)
        elif data["InputTrig"][i]==0x200:
            data["TS"].append(data["CoarseTS"][i]*25+(data["FineTS2"][i]>>3)*6.25+(data["FineTS2"][i]&0x7)*0.781)
        elif data["InputTrig"][i]==0x100:
            data["TS"].append(data["CoarseTS"][i]*25+(data["FineTS3"][i]>>3)*6.25+(data["FineTS3"][i]&0x7)*0.781)
        else:
            data["TS"].append(data["CoarseTS"][i]*25+(data["FineTS0"][i]>>3)*6.25+(data["FineTS0"][i]&0x7)*0.781)
        #print data["CoarseTS"][i], (data["FineTS0"][i]&0x18)>>3
        #hFineTS.Fill(data["FineTS0"][i]&0x7)
        #if i!=0:
        #    print i, data["TS"][i]-data["TS"][i-1], data["EvtNumber"][i]
            #hTS.Fill(data["TS"][i]-data["TS"][i-1])
        if TriggerInterval==0 and data["EvtType"][i]==0:
            print "Error!!! internal trigger detected!"
        if TriggerInterval!=0 and data["EvtType"][i]!=0:
            print "Error!!! external trigger detected!", 
            print hex(data["InputTrig"][i]), "EvtNumber:",data["EvtNumber"][i]
	#time.sleep(.05)
        #if i%100000==0: board.write("EventFifoCSR",0x2)
        i+=1
        
f.close()

meanVal=0
if len(data["TS"])<500:
    meanVal=mean(data["TS"])
else:
    meanVal=mean(data["TS"][0:500])
print meanVal
plotWidth=100

hTS = TH1D("hTS", "hTS", int(plotWidth/0.78), meanVal-plotWidth/2., meanVal+plotWidth/2.)
hFineTS0 = TH1D("hFineTS0", "hFineTS0", 8, 0, 8)
hFineTS1 = TH1D("hFineTS1", "hFineTS1", 8, 0, 8)
hFineTS2 = TH1D("hFineTS2", "hFineTS2", 8, 0, 8)
hFineTS3 = TH1D("hFineTS3", "hFineTS3", 8, 0, 8)
h6TS0 = TH1D("h6TS3","h6TS0",4,0,4)
h6TS1 = TH1D("h6TS3","h6TS1",4,0,4)
h6TS2 = TH1D("h6TS3","h6TS2",4,0,4)
h6TS3 = TH1D("h6TS3","h6TS3",4,0,4)
hEvtNumber = TH1D("hEvtNumber", "hEvtNumber", 11, -1, 10)

hTS.GetXaxis().SetTitle("#Delta Time stamp [ns]")
hTS.GetYaxis().SetTitle("#events")
hEvtNumber.GetYaxis().SetTitle("#events")

for i in range(len(data["TS"])):
    if i!=0:
        interval=data["TS"][i]-data["TS"][i-1]
        hTS.Fill(interval)
        hEvtNumber.Fill(data["EvtNumber"][i]-data["EvtNumber"][i-1])
        
        hFineTS0.Fill(data["FineTS0"][i]&0x7)
        hFineTS1.Fill(data["FineTS1"][i]&0x7)
        hFineTS2.Fill(data["FineTS2"][i]&0x7)
        hFineTS3.Fill(data["FineTS3"][i]&0x7)
        h6TS0.Fill(data["FineTS0"][i]>>3)
        h6TS1.Fill(data["FineTS1"][i]>>3)
        h6TS2.Fill(data["FineTS2"][i]>>3)
        h6TS3.Fill(data["FineTS3"][i]>>3)

cPlots = TCanvas("cPlots","cPlots",900,600)
cPlots.Divide(2)
cPlots.cd(1)
hTS.Draw()
cPlots.cd(2)
hEvtNumber.Draw()

c6TS = TCanvas("c6TS", "c6TS", 1000,900)
c6TS.Divide(2,2)
c6TS.cd(1)
h6TS0.Draw()
c6TS.cd(2)
h6TS1.Draw()
c6TS.cd(3)
h6TS2.Draw()
c6TS.cd(4)
h6TS3.Draw()

cFineTS = TCanvas("cFineTS","cFineTS",1000,900)
cFineTS.Divide(2,2)
cFineTS.cd(1)
hFineTS0.Draw()
cFineTS.cd(2)
hFineTS1.Draw()
cFineTS.cd(3)
hFineTS2.Draw()
cFineTS.cd(4)
hFineTS3.Draw()
