#!   /usr/bin/env   python
#    coding: utf8

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

import sys
import rr
import time
import os
from numpy import *
from pylab import *

from ptsexcept import *

import spec_fmc_adc
import fmc_adc
import calibr_box
import find_usb_tty
from PAGE.Agilent33250A import *
from PAGE.SineWaveform import *


"""
test18: Test calibration box

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


# Calibration box vendor and device IDs
BOX_USB_VENDOR_ID = 0x10c4 # Cygnal Integrated Products, Inc.
BOX_USB_DEVICE_ID = 0xea60 # CP210x Composite Device
# Agilent AWG serial access vendor and device IDs
AWG_USB_VENDOR_ID = 0x0403 # Future Technology Devices International, Ltd
AWG_USB_DEVICE_ID = 0x6001 # FT232 USB-Serial (UART) IC
RS232_BAUD = 57600
NB_CHANNELS = 4

AWG_SET_SLEEP = 1
SSR_SET_SLEEP = 0.05

ACQ_TIMEOUT = 10

MAX_FIRMWARE_RELOAD = 10

PRE_TRIG_SAMPLES = 10
POST_TRIG_SAMPLES = 1000
NB_SHOTS = 1

ACQ_LENGTH = 1 # in samples
DMA_LENGTH = 4096 # in bytes


def load_firmware(default_directory):
    print('Load firmware to FPGA')
    path_fpga_loader = '../../../gnurabbit/user/fpga_loader';
    path_firmware = '../firmwares/spec_fmcadc100m14b4cha_test.bin';

    firmware_loader = os.path.join(default_directory, path_fpga_loader)
    bitstream = os.path.join(default_directory, path_firmware)
    print firmware_loader + ' ' + bitstream
    os.system( firmware_loader + ' ' + bitstream )

    time.sleep(2);


def disconnect_channels(fmc):
    for i in range(1,NB_CHANNELS+1):
        fmc.set_input_range(i, 'OPEN')
        time.sleep(SSR_SET_SLEEP)


def fmc_adc_init(spec, fmc):
    print('Initialise FMC board.')
    fmc.__init__(spec)
    # Reset offset DACs
    fmc.dc_offset_reset()
    # Make sure all switches are OFF
    disconnect_channels(fmc)
    # Set trigger
    fmc.set_soft_trig()
    # Set acquisition
    fmc.set_pre_trig_samples(PRE_TRIG_SAMPLES)
    fmc.set_post_trig_samples(POST_TRIG_SAMPLES)
    fmc.set_shots(NB_SHOTS)
    # Print configuration
    #fmc.print_adc_core_config()


def set_awg_freq(gen, sine, freq):
    sine.frequency = freq
    gen.play(sine)
    print('Sine frequency:%3.3fMHz')%(sine.frequency/1E6)
    time.sleep(AWG_SET_SLEEP)


def main (default_directory = '.'):

    # Load firmware to FPGA
    load_firmware(default_directory)

    # Objects declaration
    spec = rr.Gennum() # bind to the SPEC board
    spec_fmc = spec_fmc_adc.CSpecFmcAdc100Ms(spec)
    fmc = fmc_adc.CFmcAdc100Ms(spec)
    usb_tty = find_usb_tty.CttyUSB()
    awg_tty = usb_tty.find_usb_tty(AWG_USB_VENDOR_ID, AWG_USB_DEVICE_ID)
    box_tty = usb_tty.find_usb_tty(BOX_USB_VENDOR_ID, BOX_USB_DEVICE_ID)
    gen = Agilent33250A(device=awg_tty[0], bauds=RS232_BAUD)
    sine = SineWaveform()
    box = calibr_box.CCalibr_box(box_tty[0])

    # Enable "DMA finished" IRQ
    spec_fmc.set_irq_en_mask(0x1)

    # Initialise fmc adc
    fmc_adc_init(spec, fmc)

    # Disconnect all inputs
    disconnect_channels(fmc)

    # Test calibration box ranges
    print('\n=== 10V range ===')
    box.select_output('10V')
    print('Box gpio: %X')%box.get_config()
    raw_input('Press ENTER to continue...')
    print('\n=== 1V range ===')
    box.select_output('1V')
    print('Box gpio: %X')%box.get_config()
    raw_input('Press ENTER to continue...')
    print('\n=== 100mV range ===')
    box.select_output('100mV')
    print('Box gpio: %X')%box.get_config()
    raw_input('Press ENTER to continue...')
    print('\n=== AWG ===')
    box.select_output('AWG')
    print('Box gpio: %X')%box.get_config()


if __name__ == '__main__' :
    main()
