import logging
import argparse
from opcuaserv import opcuaserv
from opcuaserv import i2client
from opcuaserv import yamlreader
#from opcuaserv import pypcc2
from i2cserv import i2cthread
import threading
import time
import sys
import signal
from yamlconfig import Find;
import yamlconfig as yc

logging.basicConfig(level="WARNING",format='%(asctime)s [%(levelname)-8s,%(filename)-20s:%(lineno)-3d] %(message)s')
RCU=5
#Gain=0; #15dB
#Gain=0x0a; #5dB
#Gain=0xf; #0dB
#Gain=0x15; #-6dB
#Gain=[0x00,0xf,0x00]
Gain=[0x15,0x15,0x15]
print("Power on RCU=",RCU);
RunTimer=True;
#def signal_handler(sig, frame):
#    logging.warn('Stop signal received!')
#    global RunTimer; 
#    RunTimer=False
#signal.signal(signal.SIGINT, signal_handler)

#logging.info("Start I2C processes")   
#threads=[]
#I2Cclients=[]
name='RCUL'
#RCU_I2C=i2client.i2client(name=name)

conf=yc.yamlconfig(name)
conf.linkdevices()
conf.loaddrivers()
conf.linkdrivers()

def GetVal(name,N=1):
 varid=conf.getvarid(name);
 var1=conf.getvars()[varid]
 drv=var1.get('drivercls');
 mask=[False]*((32)*N);
 mask[RCU]=True;
 data=drv.OPCUAReadVariable(varid,var1,mask)
 return data[0].data,var1

data,var1=GetVal('RCU_ID');
#print(data);
i=RCU*4;
print("ID=",[hex(d) for d in data[i:i+4]]);

if True:
 data,var1=GetVal('RCU_temperature');
# print(data);
 i=RCU*3;
 D=((data[i]*256+data[i+1])*256+data[i+2])*var1.get('scale',1.)
 print("Temp=",D,"K")
 if (D<290) or (D>350): exit()

 data,var1=GetVal('RCU_3V3');
 D=((data[i]*256+data[i+1])*256+data[i+2])*var1.get('scale',1.)
 print("3V3=",D,"V")
 if (D<3.2) or (D>3.4): exit()
#print("data=",[hex(d) for d in data[:3]]);


def SetRegister(regname,value):
  methodid=conf.getmethodid("RCU_on");
  var1=conf.getmethod(methodid)
  drv=var1.get('drivercls');
  v1=conf.getdevreg(regname)
  drv2=v1.get('drivercls')
  mask=[False]*32;
  mask[RCU]=True;
  if drv:  drv.Setdevreg(v1,value,mask)
  elif drv2: drv2.Setdevreg(v1,value,mask)
  else: logging.warn("Driver not specified for instruction"+key)

if True:
# AntPower=0xC0
 SetRegister("IO1.GPIO1",[Gain[0]])
 SetRegister("IO1.GPIO2",[0x80+Gain[1]]) #Analog power on
# SetRegister("IO1.GPIO1",[0xC0+Gain])
# SetRegister("IO1.GPIO2",[0xC0+Gain]) #Analog power on
 SetRegister("IO2.GPIO1",[0x40+Gain[2]]) #Digital power on
# SetRegister("IO1.GPIO2",[0x00]) #Analog power off
# SetRegister("IO2.GPIO1",[0x00]) #Digital power off
 SetRegister("IO2.GPIO2",[0x15]) #Band select all band0, leds on (low) 10MHz
# SetRegister("IO2.GPIO2",[0x2a]) #Band select all band1, leds on (low) 30MHz
# SetRegister("IO2.GPIO2",[0x00]) #

 SetRegister("IO1.CONF1",[0])
 SetRegister("IO1.CONF2",[0])
 SetRegister("IO2.CONF1",[0x80]) #Pgood on P07
 SetRegister("IO2.CONF2",[0])

 print("IO expander status:");
 data,var=GetVal('RCU_IO1_GPIO1');print("IO1_1",hex(data[RCU]))
 data,var=GetVal('RCU_IO1_GPIO2');print("IO1_2",hex(data[RCU]))
 data,var=GetVal('RCU_IO2_GPIO1');print("IO2_1",hex(data[RCU]))
 data,var=GetVal('RCU_IO2_GPIO2');print("IO2_2",hex(data[RCU]))

if True:
 i=RCU*3;
 data,var1=GetVal('RCU_1V8');
 D=((data[i]*256+data[i+1])*256+data[i+2])*var1.get('scale',1.)
 print("1V8=",D,"")
 if (D<1.6) or (D>2.0): exit()

 data,var1=GetVal('RCU_2V5');
 D=((data[i]*256+data[i+1])*256+data[i+2])*var1.get('scale',1.)
 print("2V5=",D,"")
#exit()
if False:
 data,var1=GetVal('ANT_Vin');
 D0=((data[0]*256+data[1])*256+data[2])*var1.get('scale',1.)
 D1=((data[3]*256+data[4])*256+data[5])*var1.get('scale',1.)
 D2=((data[6]*256+data[7])*256+data[8])*var1.get('scale',1.)
 print("Vant_in=",D0,D1,D2)


# SetRegister("IO1.GPIO1",[0xC0]) #Antenna power on
# SetRegister("IO1.GPIO2",[0xC0]) #Analog power on

 data,var1=GetVal('ANT_Vout');
 D0=((data[0]*256+data[1])*256+data[2])*var1.get('scale',1.)
 D1=((data[3]*256+data[4])*256+data[5])*var1.get('scale',1.)
 D2=((data[6]*256+data[7])*256+data[8])*var1.get('scale',1.)
 print("Vant_out=",D0,D1,D2)

 data,var1=GetVal('ANT_I');
 D0=((data[0]*256+data[1])*256+data[2])*var1.get('scale',1.)
 D1=((data[3]*256+data[4])*256+data[5])*var1.get('scale',1.)
 D2=((data[6]*256+data[7])*256+data[8])*var1.get('scale',1.)
 print("Iant=",D0,D1,D2)

print("Setup ADC")
if True:
 SetRegister("IO3.GPIO1",[0x15]) #ADC_SDIO=high, clk=low,  DTH_EN=low
 SetRegister("IO3.GPIO2",[0x47]) #ADC SC=high, DTH_SDA=high
 SetRegister("IO3.CONF1",[0]) #All output
 SetRegister("IO3.CONF2",[0])
 data,var=GetVal('RCU_IO3_GPIO1');print("IO3_1",hex(data[RCU]))
 data,var=GetVal('RCU_IO3_GPIO2');print("IO3_2",hex(data[RCU]))
# data,var=GetVal('RCU_ADC_sync');print("ADC sync",[hex(d) for d in data[RCU*3:RCU*3+3]])
 if True:
 #Test writing ADC register

  SetRegister("ADC1.SYNC_control",[1])
  SetRegister("ADC1.JESD_control1",[0x14])
  SetRegister("ADC1.CML_level",[0x7])
#  SetRegister("ADC1.Offset",[0x0])
  SetRegister("ADC1.Update",[1])

  SetRegister("ADC2.SYNC_control",[1])
  SetRegister("ADC2.JESD_control1",[0x14])
  SetRegister("ADC2.CML_level",[0x7])
#  SetRegister("ADC2.Offset",[0x0])
  SetRegister("ADC2.Update",[1])

  SetRegister("ADC3.SYNC_control",[1])
  SetRegister("ADC3.JESD_control1",[0x14])
  SetRegister("ADC3.CML_level",[0x7])
#  SetRegister("ADC3.Offset",[0x0])
  SetRegister("ADC3.Update",[1])

if True:
 data,var=GetVal('RCU_ADC_sync'); print("ADC sync",[hex(d) for d in data[RCU*3:RCU*3+3]])
 data,var1=GetVal("RCU_ADC_lock");print("ADC lock",[hex(d) for d in data[RCU*3:RCU*3+3]])
 data,var1=GetVal("RCU_ADC_CML_level");print("CML level",[hex(d) for d in data[RCU*3:RCU*3+3]])


if True:
 print("Switch antenna voltages on")
# SetRegister("IO1.GPIO1",[0xC0]) #Antenna power on
# SetRegister("IO1.GPIO2",[0xC0]) #Analog power on
 SetRegister("IO1.GPIO1",[0xC0+Gain[0]])
 SetRegister("IO1.GPIO2",[0xC0+Gain[1]]) #Analog power on

 data,var1=GetVal('ANT_Vin');
 i=RCU*9;
 D0=((data[i+0]*256+data[i+1])*256+data[i+2])*var1.get('scale',1.)
 D1=((data[i+3]*256+data[i+4])*256+data[i+5])*var1.get('scale',1.)
 D2=((data[i+6]*256+data[i+7])*256+data[i+8])*var1.get('scale',1.)
 print("Vant_in=",D0,D1,D2)


 data,var1=GetVal('ANT_Vout');
 D0=((data[i+0]*256+data[i+1])*256+data[i+2])*var1.get('scale',1.)
 D1=((data[i+3]*256+data[i+4])*256+data[i+5])*var1.get('scale',1.)
 D2=((data[i+6]*256+data[i+7])*256+data[i+8])*var1.get('scale',1.)
 print("Vant_out=",D0,D1,D2)

 data,var1=GetVal('ANT_I');
 D0=((data[i+0]*256+data[i+1])*256+data[i+2])*var1.get('scale',1.)
 D1=((data[i+3]*256+data[i+4])*256+data[i+5])*var1.get('scale',1.)
 D2=((data[i+6]*256+data[i+7])*256+data[i+8])*var1.get('scale',1.)
 print("Iant=",D0,D1,D2)