#!   ./python
#    coding: utf8

# Copyright CERN, 2013
# Author: Matthieu Cattin <matthieu.cattin@cern.ch>
# Licence: GPL v2 or later.
# Website: http://www.ohwr.org
# Last modifications: 30/5/2012

# Import system modules
import sys
import time
import os

# Add common modules and libraries location to path
sys.path.append('../../../')
sys.path.append('../../../common/')
sys.path.append('../../../../svec_pts/ubuntu/pts/pyts/')

# Import common modules
from ptsexcept import *
from rr2vv import *

# Import specific modules
from fmc_adc_svec import *
from fmc_adc import *
from numpy import *


"""
svec_test12: Takes an aqcuisition of all channels and print it to a file
             Set UTC and read UTC time-tags

Note: Requires svec_test00.py to run first to load the firmware!
"""


NB_CHANNELS = 4

AWG_SET_SLEEP = 0.3
SSR_SET_SLEEP = 0.05
BOX_SET_SLEEP = 0.01

ACQ_TIMEOUT = 10

PRE_TRIG_SAMPLES = 10
POST_TRIG_SAMPLES = 10000
NB_SHOTS = 1

ACQ_LENGTH = 10000 # in samples


def main (default_directory='.'):

    # Constants declaration
    LUN = 0
    TEST_NB = 12
    FMC_ADC_BITSTREAM = '../../../../../firmwares/svec_fmcadc100m14b4cha.bin'
    FMC_ADC_BITSTREAM = os.path.join(default_directory, FMC_ADC_BITSTREAM)
    EXPECTED_BITSTREAM_TYPE = 0x0

    start_test_time = time.time()
    print "================================================================================"
    print "[SVEC] Test%02d start\n" % TEST_NB

    # SVEC object declaration
    print "Loading hardware access library and opening device.\n"
    bus = VME_rr_compatible(LUN)
    bus.vv_open()

    # Carrier object declaration (SVEC board specific part)
    # Used to check that the firmware is loaded.
    try:
        carrier = CFmcAdc100mSvec(bus, EXPECTED_BITSTREAM_TYPE)
    except FmcAdc100mSvecOperationError as e:
        raise PtsCritical("Carrier init failed, test stopped: %s" % e)

    """
    # Mezzanine object declaration (FmcAdc100m14b4cha board specific part)
    try:
        fmc = CFmcAdc100m(bus, 0x2000)
    except FmcAdc100mOperationError as e:
        raise PtsCritical("Mezzanine init failed, test stopped: %s" % e)
    """
    # Mezzanines object declaration (FmcAdc100m14b4cha board specific part)
    fmc = []
    for i in range(2):
        try:
            print('\n--------------------------------------------------------------------------------')
            print('\n--------------------------------------------------------------------------------')
            print('[FMC slot %d]'%(i+1))
            mezz_offset = 0x2000+i*0x4000
            print('Mezzanine offset: 0x%08X'%(mezz_offset))
            fmc.append(CFmcAdc100m(bus, mezz_offset))
        except FmcAdc100mOperationError as e:
            raise PtsCritical("Mezzanine %d init failed, test stopped: %s" % (i+1, e))

    try:

        fmc_channels = [[],[]]
        for i in range(2):
            print('\n--------------------------------------------------------------------------------')
            print('\n--------------------------------------------------------------------------------')
            print('[FMC slot %d]'%(i+1))

            # Initialise fmc adc
            #fmc_adc_init(bus, fmc[i])
            fmc[i].acq_init(PRE_TRIG_SAMPLES, POST_TRIG_SAMPLES, NB_SHOTS)

            # Use test data instead of data from ADC
            # fmc.test_data_en()

            # Use data pattern instead of ADC data
            # fmc.testpat_en(0x2000)

            # Print configuration
            fmc[i].print_adc_core_config()

            # Print ADC config
            fmc[i].print_adc_config()

            # Set UTC
            current_time = time.time()
            utc_seconds = int(current_time)
            fmc[i].set_utc_second_cnt(utc_seconds)
            print "UTC core seconds counter initialised to : %d" % fmc[i].get_utc_second_cnt()

            utc_coarse = int((current_time - utc_seconds)/8E-9)
            fmc[i].set_utc_coarse_cnt(utc_coarse)
            print "UTC core coarse  counter initialised to : %d" % fmc[i].get_utc_coarse_cnt()

            # Acquisition parameters
            ACQ_PAUSE = 1 # pause between acq. stop and start, start and trigger
            IN_RANGE  = '10V'
            IN_TERM   = 'ON'
            ADC_FS = {'10V':10.0, '1V':1.0, '100mV':0.1}

            channels_data = [[],[],[],[]]
            for ch in range(NB_CHANNELS):
                # Configure analogue input
                fmc[i].set_input_range(ch+1, IN_RANGE)
                fmc[i].set_input_term(ch+1, IN_TERM)
                time.sleep(SSR_SET_SLEEP)

            # Perform an acquisition
            print "\nAcquiring channels"

            acq_data = fmc[i].acq_channels('svec', carrier, ADC_FS[IN_RANGE], ACQ_LENGTH, ACQ_PAUSE)
            for ch in range(NB_CHANNELS):
                channels_data[ch] = acq_data[ch::4]
            # Get time-tags
            trig_tag = fmc[i].get_utc_trig_tag()
            start_tag = fmc[i].get_utc_start_tag()
            stop_tag = fmc[i].get_utc_stop_tag()
            end_tag = fmc[i].get_utc_end_tag()
            print('Acq stop time-tag  : %10.10f [s]')%(stop_tag[1]+(stop_tag[2]*8E-9))
            print('Acq start time-tag : %10.10f [s]')%(start_tag[1]+(start_tag[2]*8E-9))
            print('Trigger time-tag   : %10.10f [s]')%(trig_tag[1]+(trig_tag[2]*8E-9))
            print('Acq end time-tag   : %10.10f [s]')%(end_tag[1]+(end_tag[2]*8E-9))

            fmc[i].print_utc_core_regs()

            # Calculate mean for each channel data
            ch_mean = []
            for ch in range(NB_CHANNELS):
                ch_mean.append(mean(channels_data[ch]))

            # Make sure all switches are OFF
            fmc[i].open_all_channels()

            fmc_channels[i] = channels_data


        # print aqcuisition to file
        file_name = "svec_test12_data.txt"
        f = open(file_name, 'w')
        f.write("#Sample, FMC1 ch1 value [V], FMC1 ch2 value [V], FMC1 ch3 value [V], FMC1 ch4 value [V], FMC2 ch1 value [V], FMC2 ch2 value [V], FMC2 ch3 value [V], FMC2 ch4 value [V]\n")
        for i in range(len(fmc_channels[0][0])):
            f.write("%d, %2.9f, %2.9f, %2.9f, %2.9f, %2.9f, %2.9f, %2.9f, %2.9f\n"%(i, fmc_channels[0][0][i], fmc_channels[0][1][i], fmc_channels[0][2][i], fmc_channels[0][3][i], fmc_channels[1][0][i], fmc_channels[1][1][i], fmc_channels[1][2][i], fmc_channels[1][3][i]))
        f.close()

    except(FmcAdc100mSvecOperationError, FmcAdc100mOperationError) as e:
        raise PtsError("Test failed: %s" % e)


    print ""
    print "==> End of test%02d" % TEST_NB
    print "================================================================================"
    end_test_time = time.time()
    print "Test%02d elapsed time: %.2f seconds\n" % (TEST_NB, end_test_time-start_test_time)


if __name__ == '__main__' :
    main()
