#!   /usr/bin/env   python

# Copyright Creotech SA, 2015
# Author: Marek Guminski <marek.guminski@creotech.pl>
# Licence: GPL v2 or later.
# Website: http://www.ohwr.org


import sys
import shutil
import time
import os

from spec import *
from fmcmasterfip import *

import numpy 
import matplotlib.pyplot as plt
import scipy.signal


# FIRMWARE_PATH='/../gateware/ip_cores/masterfip-gw/syn/spec/spec_masterfip.bin'
# FIRMWARE_PATH='/../gateware/syn/spec/spec_top_fmc_masterfip.bin'
FIRMWARE_PATH='/project/gateware/syn/spec/spec_top_fmc_masterfip.bin'
ACQ_SCRIPT_PATH='/project/scripts/'
TOPDIRNAME="fmcmasterfip"

DEBUG = True

def generate_traffic( masterFIP, count = 1 ):
    
    i = 1;
    while True:
        print ("---- Presence variable")
        # Send ID_DAT for presence variable
        masterFIP.send_id_dat(0x7F14) # nanoFIPdiag address: 7F
        time.sleep(0.00020) #..approximately
        # Read RP_DAT reply fron nanoFIPdiag
        presence_var_reply = masterFIP.read_rp_dat()
        if (presence_var_reply == 0xA0300000002038005509A00F000249A00F0):
            print ("Presence variable OK!")
        elif (presence_var_reply == 0x0):
            msg = ("ERROR: no WorldFIP traffic on presence variable")
            print (msg)
        else:
            msg = ("ERROR: data errors on presence variable")
            print (msg)
        
        if count > 0:
            i = i + 1;
            if i > count:
                return
        
        
        
            
            
def read_adc_samples( filename, nsamples, savename="" ):
    with open( filename,"rb") as fin:
    
        # Discard header
        header=fin.read(512) 
    
        # read data from file
        d=numpy.fromfile(file=fin,dtype=numpy.int16).reshape(nsamples,4)
        
        # helper vector
        samples_range=range(0,nsamples-1)
    
        # positive line is connected to ADC channel 0
        positive_samples = numpy.int32( d[samples_range, 0] )
        
        # negative line is connected to ADC channel 1
        negative_samples = numpy.int32( d[samples_range, 1] )
        
        transmission = numpy.int32( positive_samples - negative_samples );
        filtered_transmission = scipy.signal.medfilt( transmission, 51 );
        plt.plot( samples_range, positive_samples, 'g', samples_range, negative_samples, 'b', samples_range, transmission, 'r' );
        plt.show()
        
        plt.plot( samples_range, transmission, 'r' );
        plt.show()
        
    if savename != "":
        shutil.copyfile(filename, savename )
#         plt.plot( samples_range, filtered_transmission, 'r' );
#         plt.show()
        
# find absolute path of directory of name stored in topdirname
def find_prj_topdir(topdirname):
    [ tmppath, dirname ] = os.path.split( os.getcwd() );
    while( tmppath != '/' ):
        if dirname == topdirname:
            return os.path.join( tmppath, dirname)
        [ tmppath, dirname ] = os.path.split(tmppath);
    return "";



def setup_acquisition( carrier, topdirpath, nsamples, deglith ):
    
    tmp = carrier.read(0x21308 );
#     clear deglith field
    tmp = tmp & ~0xff00;
#     set up correct value
    tmp = tmp | ( deglith << 8 );
#     write back
    carrier.write(0x21308, tmp );
    os.system( topdirpath + "/project/scripts/acq.sh " +str(nsamples)+" "+ "10" + " " + str( 1 ) +"")




def main (card=None, default_directory='.',suite=None):
  
  
    carrier=spec();
#     carrier.program(FIRMWARE_PATH);
    
    absolute_project_path = find_prj_topdir(TOPDIRNAME);
    
    masterFIP = fmcmasterfip(carrier, absolute_project_path+FIRMWARE_PATH)
    bitstream_type = masterFIP.read_bitstream_type()
    if(bitstream_type == 0xFFFFFFFF):
        msg = ("FATAL ERROR: No access to masterFIP core")
        print (msg)
        raise Exception(msg)
    elif(bitstream_type != 0x10003):
        msg = ("FATAL ERROR: Wrong bitstream type loaded 0x%8X")%bitstream_type
        print (msg)
        raise Exception(msg)
    else:
        print("Access to masterFIP core OK 0x%8X")%bitstream_type
  
        
    print ("\n________________________masterFIP config_________________________\n")

    # Configure masterFIP core registers
    masterFIP.rst_core()
    time.sleep(0.5)
    
    carrier.write( 0x1404,1 )
    carrier.write( 0x21504,1 )


    masterFIP.read_speed()
    masterFIP.read_masterfip_id()
    masterFIP.disable_ext_sync_tst()
#     masterFIP.bus_term_dis()

    print ("\n________________________WorldFIP traffic_________________________\n")

    print ("---- Presence variable")
    # Send ID_DAT for presence variable
    masterFIP.send_id_dat(0x7F14) # nanoFIPdiag address: 7F
    time.sleep(0.00020) #..approximately
    # Read RP_DAT reply fron nanoFIPdiag
    presence_var_reply = masterFIP.read_rp_dat()
    if (presence_var_reply == 0xA0300000002038005509A00F000249A00F0):
        print ("Presence variable OK!")
    elif (presence_var_reply == 0x0):
        msg = ("ERROR: no WorldFIP traffic on presence variable")
        print (msg)
    else:
        msg = ("ERROR: data errors on presence variable")
        print (msg)

    time.sleep(0.05)

    # Send ID_DAT for identification variable
    print ("\n---- Identification variable")
    masterFIP.send_id_dat(0x7F10)
    time.sleep(0.00020) #..approximately
    # Read RP_DAT reply from nanoFIPdiag
    identif_var_reply = masterFIP.read_rp_dat()
    if (identif_var_reply == 0xD030000000200010852003000004DBA0000):
        print ("Identification variable OK!")
    elif (identif_var_reply == 0x0):
        msg = ("ERROR: no WorldFIP traffic on identification variable")
        print (msg)
    else:
        msg = ("ERROR: data errors on identification variable")
        print (msg)

    print "\n\n-----------------------------------------------------------------"

    masterFIP.adc_power(0);

    
    masterFIP.close_relay(1);
    setup_acquisition( carrier, absolute_project_path, 1024*20, 0 );
    generate_traffic( masterFIP, 1 );
    time.sleep( 2 )
    read_adc_samples( "/tmp/data.bin", 1024*20 + 256, "output/primary.bin" )
     

    
    
    masterFIP.close_relay(2);
    time.sleep(1)
    setup_acquisition( carrier, absolute_project_path, 1024*20, 64 );
    generate_traffic( masterFIP, 1 );
    time.sleep( 2 )
    read_adc_samples( "/tmp/data.bin", 1024*20 + 256, "output/secondary.bin" )
    
    setup_acquisition( carrier, absolute_project_path, 1024*20, 0 );
    generate_traffic( masterFIP, 1 );
    time.sleep( 2 )
    read_adc_samples( "/tmp/data.bin", 1024*20 + 256 )
    
    setup_acquisition( carrier, absolute_project_path, 1024*20, 0 );
#     generate_traffic( masterFIP, 1 );
    time.sleep( 2 )
    read_adc_samples( "/tmp/data.bin", 1024*20 + 256 )
    
#     masterFIP.close_relay(0);
#     setup_acquisition( absolute_project_path, 1024*40 );
#     time.sleep( 2 )
#     generate_traffic( masterFIP, 1 );
#     time.sleep( 2 )
#     read_adc_samples( "/tmp/data.bin", 1024*40 + 256 )
    
    
    

    generate_traffic(masterFIP, 0)

       
    return 0
        
if __name__ == '__main__' :
    main()