#!   ./python
#    coding: utf8

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

# Import system modules
import sys
import time
import os

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

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


"""
svec_test42: Tests sampling frequency counter
"""

def main (default_directory='.'):

    # Constants declaration
    LUN = 0
    TEST_NB = 42
    FMC_ADC_BITSTREAM = '../../gatewares/svec_fmcadc100m14b4cha.bin'
    FMC_ADC_BITSTREAM = os.path.join(default_directory, FMC_ADC_BITSTREAM)
    EXPECTED_BITSTREAM_TYPE = 0x0
    NB_CHANNELS = 4
    EEPROM_ADDR = 0x50
    SI570_ADDR = 0x55
    TEST_PATTERN = 0x6A1


    start_test_time = time.time()
    print "\n================================================================================"
    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)
    print "Initialising device.\n"

    # Load FMC ADC gateware
    ask = ''
    while ((ask != "Y") and (ask != "N")) :
        ask = raw_input("Do you want to load the gateware: %s? [y,n]"%(FMC_ADC_BITSTREAM))
        ask = ask.upper()
        print " "

    if (ask == "Y"):
        print "Loading FMC ADC gateware: %s\n" % FMC_ADC_BITSTREAM
        bus.vv_init()
        ret = bus.vv_load(FMC_ADC_BITSTREAM, 1)
        print('')
        time.sleep(2)
    else:
        bus.vv_open()

    # Carrier object declaration (SPEC board specific part)
    try:
        carrier = CFmcAdc100mSvec(bus, EXPECTED_BITSTREAM_TYPE)
    except FmcAdc100mSvecOperationError as e:
        raise PtsCritical("Carrier init failed, test stopped: %s" % e)

    # Test carrier periherals
    print('\n-------------------------------------------------------------')
    print('[Carrier]')
    carrier.print_unique_id()
    carrier.print_temp()

    # Mezzanines object declaration (FmcAdc100m14b4cha board specific part)
    fmc = []
    for i in range(2):
        try:
            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))

    # Test mezzanines peripherals
    error = ['','']
    for i in range(2):
        try:
            print('\n-------------------------------------------------------------')
            print('[FMC slot %d]\n'%(i+1))

            #############################################################
            # Read sampling frequency register
            expect_samp_freq = 100E6

            samp_freqs = []
            for a in range(20):
                time.sleep(2)
                samp_freq = fmc[i].get_samp_freq()
                samp_freqs.append(samp_freq)
                diff = abs(samp_freq - expect_samp_freq)
                print("Sampling frequency: %6d Hz, diff: %6d Hz"%(samp_freq, diff))

            freq_mean = mean(samp_freqs)
            freq_dev  = std(samp_freqs)
            print("Measured sampling frequency, mean: %f std_dev:%f"%(freq_mean, freq_dev))
            #############################################################


        except FmcAdc100mOperationError as e:
            raise PtsError("Mezzanine %d onewire test failed: %s" % (i+1, e))

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

    err_s = ''
    if (error[0] != ''):
        err_s = '[FMC slot 1]' + error[0] + '\n'
    if (error[1] != ''):
        err_s += '[FMC slot 2]' + error[1]

    if (err_s != ''):
        raise PtsError(err_s)

    bus.vv_close()


if __name__ == '__main__' :
    main()
