#!python

from pycpsw import *
import numpy as np
import time
from math import *
import matplotlib.pyplot as plt


# save files to 
#f_dir = '/afs/slac/g/lcls/package/cpsw/controlGUI/MAIN_TRUNK/config/cryo/data/dataTest001'

# setup CPSW heirarchy
#h = Hub.loadYamlFile( '/afs/slac/u/re/ulegat/ProjDocs/LLRF/firmware/targets/mr/AmcCarrierMrRtmEth/images/AmcCarrierMrRtmEth_project.yaml/000TopLevel.yaml', 'NetIODev' )

p = Path.loadYamlFile( '/afs/slac/u/re/ulegat/ProjDocs/LLRF/firmware/targets/mr/AmcCarrierMrRtmEth/images/AmcCarrierMrRtmEth_project.yaml/000TopLevel.yaml', 'NetIODev' )

# setup PATHs 
#p = Path.create( p )
p_mmio = p.findByName('mmio')
#p_mr = p_mmio.findByName( 'AmcCarrierMrRtmEth' )
#p_AmcCore = p_mr.findByName( 'AmcCarrierCore' )

# Load YAML config
#p_mmio.loadConfigFromYamlFile( '/afs/slac/g/lcls/package/cpsw/controlGUI/MAIN_TRUNK/config/cryo/defaults.yaml' )


# create stream interfaces
# strm0 = Stream.create( p.findByName('Stream0') )
# strm1 = Stream.create( p.findByName('Stream1') )
# strm2 = Stream.create( p.findByName('Stream2') )
# strm3 = Stream.create( p.findByName('Stream3') )
# strm4 = Stream.create( p.findByName('Stream4') )
# strm5 = Stream.create( p.findByName('Stream5') )
# strm6 = Stream.create( p.findByName('Stream6') )
# strm7 = Stream.create( p.findByName('Stream7') )

# Thresholds
KlyWiperRegA = ScalVal.create( p_mmio.findByName('AmcCarrierMrRtmEth/AmcCarrierMrLlrfApp/RtmLlrfCore/KlyWiperRegA') )
KlyWiperRegB = ScalVal.create( p_mmio.findByName('AmcCarrierMrRtmEth/AmcCarrierMrLlrfApp/RtmLlrfCore/KlyWiperRegB') )
KlyNVRegA = ScalVal.create( p_mmio.findByName('AmcCarrierMrRtmEth/AmcCarrierMrLlrfApp/RtmLlrfCore/KlyNVRegA') )
KlyNVRegB = ScalVal.create( p_mmio.findByName('AmcCarrierMrRtmEth/AmcCarrierMrLlrfApp/RtmLlrfCore/KlyNVRegB') )
ModWiperRegA = ScalVal.create( p_mmio.findByName('AmcCarrierMrRtmEth/AmcCarrierMrLlrfApp/RtmLlrfCore/ModWiperRegA') )
ModWiperRegB = ScalVal.create( p_mmio.findByName('AmcCarrierMrRtmEth/AmcCarrierMrLlrfApp/RtmLlrfCore/ModWiperRegB') )
ModNVRegA = ScalVal.create( p_mmio.findByName('AmcCarrierMrRtmEth/AmcCarrierMrLlrfApp/RtmLlrfCore/ModNVRegA') )
ModNVRegB = ScalVal.create( p_mmio.findByName('AmcCarrierMrRtmEth/AmcCarrierMrLlrfApp/RtmLlrfCore/ModNVRegB') )


AdcFrameDelay = ScalVal.create( p_mmio.findByName('AmcCarrierMrRtmEth/AmcCarrierMrLlrfApp/RtmLlrfCore/AdcFrameSetDelay') )
AdcSetDelay = ScalVal.create( p_mmio.findByName('AmcCarrierMrRtmEth/AmcCarrierMrLlrfApp/RtmLlrfCore/AdcSetDelay') )
AdcIDelayLoad = ScalVal.create( p_mmio.findByName('AmcCarrierMrRtmEth/AmcCarrierMrLlrfApp/RtmLlrfCore/AdcIDelayLoad') )	

DataTrigDelay = ScalVal.create( p_mmio.findByName('AmcCarrierMrRtmEth/AmcCarrierMrLlrfApp/TrigRtmData/PulseDelay') )
DataTrigMask = ScalVal.create( p_mmio.findByName('AmcCarrierMrRtmEth/AmcCarrierMrLlrfApp/TrigRtmData/OpCodeMask[0-7]') )

AccelTrigDelay = ScalVal.create( p_mmio.findByName('AmcCarrierMrRtmEth/AmcCarrierMrLlrfApp/TrigRtmAccel/PulseDelay') )
AccelTrigWidth = ScalVal.create( p_mmio.findByName('AmcCarrierMrRtmEth/AmcCarrierMrLlrfApp/TrigRtmAccel/PulseWidth') )
AccelTrigMask = ScalVal.create( p_mmio.findByName('AmcCarrierMrRtmEth/AmcCarrierMrLlrfApp/TrigRtmAccel/OpCodeMask[0-7]') )

StandbyTrigDelay = ScalVal.create( p_mmio.findByName('AmcCarrierMrRtmEth/AmcCarrierMrLlrfApp/TrigRtmStandby/PulseDelay') )
StandbyTrigWidth = ScalVal.create( p_mmio.findByName('AmcCarrierMrRtmEth/AmcCarrierMrLlrfApp/TrigRtmStandby/PulseWidth') )
StandbyTrigMask = ScalVal.create( p_mmio.findByName('AmcCarrierMrRtmEth/AmcCarrierMrLlrfApp/TrigRtmStandby/OpCodeMask[0-7]') )


SoftBufferClear = ScalVal.create( p_mmio.findByName('AmcCarrierMrRtmEth/AmcCarrierMrLlrfApp/RtmLlrfCore/SoftBufferClear') )
SoftBufferTrigger = ScalVal.create( p_mmio.findByName('AmcCarrierMrRtmEth/AmcCarrierMrLlrfApp/RtmLlrfCore/SoftBufferTrigger') )

BeamVIData = ScalVal_RO.create( p_mmio.findByName('AmcCarrierMrRtmEth/AmcCarrierMrLlrfApp/RtmLlrfCore/RtmAdcBuffer[0]/MemoryArray[0-511]') )
BeamPwrData = ScalVal_RO.create( p_mmio.findByName('AmcCarrierMrRtmEth/AmcCarrierMrLlrfApp/RtmLlrfCore/RtmAdcBuffer[1]/MemoryArray[0-511]') )

Mode = ScalVal.create( p_mmio.findByName('AmcCarrierMrRtmEth/AmcCarrierMrLlrfApp/RtmLlrfCore/Mode') )

ClkConfig = ScalVal.create( p_mmio.findByName('AmcCarrierMrRtmEth/AmcCarrierCore/AxiSy56040/OutputConfig[0-3]') )
ClkSel = ScalVal.create( p_mmio.findByName('AmcCarrierMrRtmEth/AmcCarrierCore/AmcCarrierTiming/TimingFrameRx/ClkSel') )

# CPLD
Status = ScalVal_RO.create( p_mmio.findByName('AmcCarrierMrRtmEth/AmcCarrierMrLlrfApp/RtmLlrfCore/Status') )

# 
CfgRegister = ScalVal.create( p_mmio.findByName('AmcCarrierMrRtmEth/AmcCarrierMrLlrfApp/RtmLlrfCore/CfgRegister') )

AdcIn0 = ScalVal_RO.create( p_mmio.findByName('AmcCarrierMrRtmEth/AmcCarrierMrLlrfApp/RtmLlrfCore/AdcIn[0]') )
AdcIn1 = ScalVal_RO.create( p_mmio.findByName('AmcCarrierMrRtmEth/AmcCarrierMrLlrfApp/RtmLlrfCore/AdcIn[1]') )
AdcIn2 = ScalVal_RO.create( p_mmio.findByName('AmcCarrierMrRtmEth/AmcCarrierMrLlrfApp/RtmLlrfCore/AdcIn[2]') )
AdcIn3 = ScalVal_RO.create( p_mmio.findByName('AmcCarrierMrRtmEth/AmcCarrierMrLlrfApp/RtmLlrfCore/AdcIn[3]') )

FirmwareVersion = ScalVal_RO.create( p_mmio.findByName('AmcCarrierMrRtmEth/AmcCarrierMrLlrfApp/RtmLlrfCore/FirmwareVersion') )
SystemId0 = ScalVal_RO.create( p_mmio.findByName('AmcCarrierMrRtmEth/AmcCarrierMrLlrfApp/RtmLlrfCore/SystemId[0]') )
SystemId1 = ScalVal_RO.create( p_mmio.findByName('AmcCarrierMrRtmEth/AmcCarrierMrLlrfApp/RtmLlrfCore/SystemId[1]') )
SystemId2 = ScalVal_RO.create( p_mmio.findByName('AmcCarrierMrRtmEth/AmcCarrierMrLlrfApp/RtmLlrfCore/SystemId[2]') )
SystemId3 = ScalVal_RO.create( p_mmio.findByName('AmcCarrierMrRtmEth/AmcCarrierMrLlrfApp/RtmLlrfCore/SystemId[3]') )

FirmwareDate0 = ScalVal_RO.create( p_mmio.findByName('AmcCarrierMrRtmEth/AmcCarrierMrLlrfApp/RtmLlrfCore/FirmwareDate[0]') )
FirmwareDate1 = ScalVal_RO.create( p_mmio.findByName('AmcCarrierMrRtmEth/AmcCarrierMrLlrfApp/RtmLlrfCore/FirmwareDate[1]') )
FirmwareDate2 = ScalVal_RO.create( p_mmio.findByName('AmcCarrierMrRtmEth/AmcCarrierMrLlrfApp/RtmLlrfCore/FirmwareDate[2]') )
FirmwareDate3 = ScalVal_RO.create( p_mmio.findByName('AmcCarrierMrRtmEth/AmcCarrierMrLlrfApp/RtmLlrfCore/FirmwareDate[3]') )

SubType0 = ScalVal_RO.create( p_mmio.findByName('AmcCarrierMrRtmEth/AmcCarrierMrLlrfApp/RtmLlrfCore/SubType[0]') )
SubType1 = ScalVal_RO.create( p_mmio.findByName('AmcCarrierMrRtmEth/AmcCarrierMrLlrfApp/RtmLlrfCore/SubType[1]') )
SubType2 = ScalVal_RO.create( p_mmio.findByName('AmcCarrierMrRtmEth/AmcCarrierMrLlrfApp/RtmLlrfCore/SubType[2]') )
SubType3 = ScalVal_RO.create( p_mmio.findByName('AmcCarrierMrRtmEth/AmcCarrierMrLlrfApp/RtmLlrfCore/SubType[3]') )

StatusBits1 = ['Normal Mode', 'Motor Time out', 'Detuning', 'Tuning', 'Lower Tuned', 'Upper Tuned', 'Motor Not Tuned',
              'Lower Detuned', 'Upper Detuned', 'Motor Not Detuned', 'Modulator Fault', 'Beam Under Current', 'Beam Over Current',
              'Beam Over Voltage', 'Forward Power Over', 'Reflected Power Over']

StatusBits0 = ['Standby Mode', 'Motor Not Timed out', 'Not Detuning', 'Not Tuning', 'Lower Not Tuned', 'Upper Not Tuned', 'Motor Tuned',
              'Lower Not Detuned', 'Upper not Detuned', 'Motor  Detuned', 'Modulator Ok', 'Beam Under Current OK', 'Beam Over Current Ok',
              'Beam Over Voltage Ok', 'Forward Power Over Ok', 'Reflected Power Over Ok']


def PotVolts2Counts(Threshold):

	RTop = 1
	RChip = 10
	RBottom = 1
	VSource = 3.3

	I = VSource/(RTop + RChip + RBottom)
	Counts = int((Threshold-I*RBottom)*255/I/RChip)
	return Counts
  
def ADCCounts2Volts(Counts):
	Volts = float(Counts)*2.5/65535
	return Volts

def DecodeStatus(Stat):
	for i in range(15,-1,-1):
#		print(i)
		if ((int(Stat) & int(pow(2,i))) > 0):
			print StatusBits1[(15-i)]
		else:
			print StatusBits0[(15-i)]
	return

def SledStatus(Stat):
	SLEDBITs = (Stat >> 6) & 0x3F
	if (SLEDBITs == 0x31):
		print("SLED Tuned")
	elif (SLEDBITs == 0x0E):
		print('SLED Detuned')
	else:
		print('SLED Fault')
			
def FastADCCounts2Volts(Counts):
	Volts = (float(Counts) - 2048)/2048
	return Volts
	
def PulseWidth(Time):
	Counts = int(Time*119)
	return Counts

def ADCDataDelay(Taps):
	AdcSetDelay.setVal([(Taps)])
	AdcIDelayLoad.setVal([1])
	AdCIDelayLoad.setVal([0])
	
	
#KlyWiperRegAB.setVal( [0x55] )
#print("AB=0x%x" % (KlyWiperRegAB.getVal()))
#Mode.setVal( [0x1] )
#print("Mode=0x%x" % (Mode.getVal()))


print("FIrmware=0x%x" % (FirmwareVersion.getVal()))
  
#Mode.setVal( [0x1] )
#Mode.setVal( [0x0] )

#Registers
print("SystemId0=0x%4x" % (SystemId0.getVal()))
print("SystemId1=0x%4x" % (SystemId1.getVal()))
print("SystemId2=0x%4x" % (SystemId2.getVal()))
print("SystemId3=0x%4x" % (SystemId3.getVal()))
print("Status=0x%4x" % (Status.getVal()))


DateString =''

DateString = chr((FirmwareDate0.getVal()) >> 8)
DateString = DateString + chr((FirmwareDate0.getVal()) & 255)
DateString = DateString + chr((FirmwareDate1.getVal()) >> 8)
DateString = DateString + chr((FirmwareDate1.getVal()) & 255)
DateString = DateString + chr((FirmwareDate2.getVal()) >> 8)
DateString = DateString + chr((FirmwareDate2.getVal()) & 255)
DateString = DateString + chr((FirmwareDate3.getVal()) >> 8)
DateString = DateString + chr((FirmwareDate3.getVal()) & 255)



IdString =''

IdString = chr((SystemId0.getVal()) >> 8)
IdString = IdString + chr((SystemId0.getVal()) & 255)
IdString = IdString + chr((SystemId1.getVal()) >> 8)
IdString = IdString + chr((SystemId1.getVal()) & 255)
IdString = IdString + chr((SystemId2.getVal()) >> 8)
IdString = IdString + chr((SystemId2.getVal()) & 255)
IdString = IdString + chr((SystemId3.getVal()) >> 8)
IdString = IdString + chr((SystemId3.getVal()) & 255)

SubTypeString =''

SubTypeString = chr((SubType0.getVal()) >> 8)
SubTypeString = SubTypeString + chr((SubType0.getVal()) & 255)
SubTypeString = SubTypeString + chr((SubType1.getVal()) >> 8)
SubTypeString = SubTypeString + chr((SubType1.getVal()) & 255)
SubTypeString = SubTypeString + chr((SubType2.getVal()) >> 8)
SubTypeString = SubTypeString + chr((SubType2.getVal()) & 255)
SubTypeString = SubTypeString + chr((SubType3.getVal()) >> 8)
SubTypeString = SubTypeString + chr((SubType3.getVal()) & 255)

print
print ("FirmwareVersion = 0x%4x" % (FirmwareVersion.getVal()))
print ("   Compile Date = " + DateString)
print ("      ID String = " + IdString)
print ("       Sub Type = " + SubTypeString)

print ("Timing Setup")
ClockConfig = [0,1,0,0]
ClkConfig.setVal(ClockConfig)
ClockConfig = ClkConfig.getVal()
print ClockConfig

print "Clock Select"
ClkSel.setVal([0])
print ClkSel.getVal()

print
print ("Test Threshold Pot and ADC")
Thres = 0x00

#while (True) :
KlyWiperRegA.setVal( [PotVolts2Counts(0.5)] )
KlyWiperRegB.setVal( [PotVolts2Counts(1.0)] )
ModWiperRegA.setVal( [PotVolts2Counts(1.5)] )
ModWiperRegB.setVal( [PotVolts2Counts(2.0)] )

# write CFG to scan
CfgRegister.setVal([0xFF1C])
time.sleep(0.1)

# Write CFG to no longer update
# clear msb, writing 0 does not work!
CfgRegister.setVal([0x7F1C])
time.sleep(0.1)
print
print

# Read adc's
print(ADCCounts2Volts(AdcIn0.getVal()))
print(ADCCounts2Volts(AdcIn1.getVal()))
print(ADCCounts2Volts(AdcIn2.getVal()))
print(ADCCounts2Volts(AdcIn3.getVal()))
print

DataTrigMask.setVal([0x00000000, 0x00000100, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000])
DataTrigDelay.setVal([50])

AccelTrigWidth.setVal([PulseWidth(5)])
AccelTrigDelay.setVal([0])
AccelTrigMask.setVal([0x00000000, 0x00000100, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000])

StandbyTrigWidth.setVal([PulseWidth(5)])
StandbyTrigDelay.setVal([0])
StandbyTrigMask.setVal([0x00000000, 0x00000100, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000])


#ADCDataDelay(128)

plt.figure()
plt.subplot(2,2,1)
plt.ylabel('Volts')
plt.title('Beam Volts')

plt.subplot(2,2,2)
plt.ylabel('Current')
plt.title('Beam Current')

plt.subplot(2,2,3)
plt.ylabel('Power')
plt.title('Reflected Power')

plt.subplot(2,2,4)
plt.ylabel('Power')
plt.title('Forward Power')

x= 0
AdcSetDelay.setVal([x, x, x, x])
AdcFrameDelay.setVal([x])
AdcIDelayLoad.setVal([1])
AdcIDelayLoad.setVal([0])
time.sleep(0.01)


while (True):


	SoftBufferClear.setVal([1])
	SoftBufferClear.setVal([0])
	time.sleep(0.01)

	BeamVIDataRaw = BeamVIData.getVal()
	BeamPwrDataRaw = BeamPwrData.getVal()

	BeamCurrentData =[]
	BeamVoltageData =[]
	BeamForwardData =[]
	BeamReflectedData =[]


	BeamCurrent  =[]
	BeamVoltage =[]
	BeamForward =[]
	BeamReflected =[]
  

	for i in range(0, 510):
		BeamVoltageData.append(BeamVIDataRaw[i+2] & 0xFFFF)
		BeamCurrentData.append((BeamVIDataRaw[i+2] >> 16 ) & 0xFFFF)
		BeamForwardData.append(BeamPwrDataRaw[i+2] & 0xFFFF)
		BeamReflectedData.append((BeamPwrDataRaw[i+2] >> 16) & 0xFFFF)

		BeamCurrent.append(FastADCCounts2Volts(BeamCurrentData[i]))
		BeamVoltage.append(FastADCCounts2Volts(BeamVoltageData[i]))
		BeamForward.append(FastADCCounts2Volts(BeamForwardData[i]))
		BeamReflected.append(FastADCCounts2Volts(BeamReflectedData[i]))

#	for j in range(0, 510):
#		print (' {:3d}   0x{:04x}   0x{:04x}   0x{:08x} '.format( j, BeamCurrentData[j], BeamCurrentData[j]-2048, BeamVIDataRaw[j+2]))
 
	plt.clf()
	plt.subplot(2,2,1)
	plt.plot(BeamVoltage)
	plt.subplot(2,2,2)
	plt.plot(BeamCurrent)
	plt.subplot(2,2,3)
	plt.plot(BeamReflected)
	plt.subplot(2,2,4)
	plt.plot(BeamForward)
 
	plt.show
	plt.pause(.1)

	print x
	x=x+1

x=input('Press Enter ')
  
plt.close()

#	print (" Status 0x%x" %(Status.getVal()))
#  	DecodeStatus(Status.getVal())
#	SledStatus(Status.getVal())
#	print
#	print 



#CfgRegister.setVal( [0x3fff] )
#print("CfgRegister=0x%x" % (CfgRegister.getVal()))

#print("AdcIn0=0x%x" % (AdcIn0.getVal()))
#print("AdcIn1=0x%x" % (AdcIn1.getVal()))
#print("AdcIn2=0x%x" % (AdcIn2.getVal()))
#print("AdcIn3=0x%x" % (AdcIn3.getVal()))
