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

import sys
import rr
import random
import time
import spi
import ltc217x
import csr
#import max5442
import i2c
#import onewire
#import ds18b20
#import mcp9801
import gn4124
import si57x
import eeprom_24aa64
#import dac_AD5622
import ad5662_spi
import math



class CFmcAdc100ks:

    """
    Contans all functions required for the full test suite production of the 200ksps 16bit ADC FMC
     
    """
    
    # ADDRESSES - See firmware top level
    # Test CSR
    

    # EEPROM ADDRESS - see datasheet for device    
    EEPROM_ADDR = 0x50
    DAC_ADDR    = 0x0F

    #MCP9801_ADDR = 0x48

    FMC_CSR = {
               0x00:'Control register',
               0x04:'Status register',
               0x08:'Trigger configuration register',
               0x0C:'Trigger delay register',
               0x10:'Software trigger register',
               0x14:'Number of shots register',
               0x18:'Trigger UTC (LSB) register',
               0x1C:'Trigger UTC (MSB) register',
               0x20:'Start UTC (LSB) register',
               0x24:'Start UTC (MSB) register',
               0x28:'Stop UTC (LSB) register',
               0x2C:'Stop UTC (MSB) register',
               0x30:'Decimation factor register',
               0x34:'Pre-trigger samples register',
               0x38:'Post-trigger samples register',
               0x3C:'Samples counter register',
               0x40:'CH1 current value register',
               0x44:'CH2 current value register',
               0x48:'CH3 current value register',
               0x4C:'CH4 current value register',
               0x50:'CH5 current value register',
               0x54:'CH6 current value register',
               0x58:'CH7 current value register',
               0x5C:'CH8 current value register',
               0x60:'CH9 current value register',
               0x64:'CH10 current value register',
               0x68:'CH11 current value register',
               0x6C:'CH12 current value register',
               0x70:'CH13 current value register',
               0x74:'CH14 current value register',
               0x78:'CH15 current value register',
               0x7C:'CH16 current value register',
               0x80:'Trigger Position',
               0x84:'Test Register',
               0x88:'Shot Counters Register',
               0x8C:'Post Trig Counter',
               0x90:'Pre Trig Counter',
               0x94:'Spare',}


    ##########################################################################
    # ADC CORE REGISTER ADDRESSES
    ##########################################################################
    
    R_CTL = 0x00    
    R_STA = 0x04
    R_TRIG_CFG = 0x08
    R_TRIG_DLY = 0x0C
    R_SW_TRIG = 0x10
    R_SHOTS = 0x14
    R_TRIG_UTC_L = 0x18
    R_TRIG_UTC_H = 0x1C
    R_START_UTC_L = 0x20
    R_START_UTC_H = 0x24
    R_STOP_UTC_L = 0x28
    R_STOP_UTC_H = 0x2C
    R_SRATE = 0x30
    R_PRE_SAMPLES = 0x34
    R_POST_SAMPLES = 0x38
    R_SAMP_CNT = 0x3C
    R_CH1_VALUE = 0x40
    R_CH2_VALUE = 0x44
    R_CH3_VALUE = 0x48
    R_CH4_VALUE = 0x4C
    R_CH5_VALUE = 0x50
    R_CH6_VALUE = 0x54
    R_CH7_VALUE = 0x58
    R_CH8_VALUE = 0x5C
    R_CH9_VALUE = 0x60
    R_CH10_VALUE = 0x64
    R_CH11_VALUE = 0x68
    R_CH12_VALUE = 0x6C
    R_CH13_VALUE = 0x70
    R_CH14_VALUE = 0x74
    R_CH15_VALUE = 0x78
    R_CH16_VALUE = 0x7C
    R_TRIGGER_POSITION = 0x80
    R_TEST = 0x84
    R_SHOT_COUNTER_VAL = 0x88
    R_POST_TRIG_COUNTER_VAL = 0x8C
    R_PRE_TRIG_COUNTER_VAL = 0x90
    R_SPARE = 0x94


    # CTL Register Addresses
    CTL_FSM_CMD = 0x0           
    CTL_TEST_DATA_EN = 0x2
    CTL_ADC_CONT_CMD = 0x3
    CTL_RANGE =	0x4
    CTL_MASK  = 0xFC   
    
    # I dont know...
    RANGE_CMD_MASK = 0x10

    # TRIG REGGISTER ADDRESSES
    #TRIG_CFG_HW_EN = 0
    #TRIG_CFG_SW_EN = 1
    #TRIG_CFG_INT_SEL = 2
    #TRIG_CFG_SLOPE   = 7
    #TRIG_CFG_DUMMY   = 8
    #TRIG_CFG_INT_THRES = 16
    
    # TRIG REGGISTER ADDRESSES
    TRIG_CFG_HW_EN = 0
    TRIG_CFG_SW_EN = 1
    TRIG_CFG_INT_SEL = 2
    TRIG_CFG_SLOPE   = 7
    #TRIG_CFG_DUMMY   = 8
    TRIG_CFG_EDGE_EN = 8
    TRIG_CFG_DUMMY   = 9
    TRIG_CFG_INT_THRES = 16
    
    
    

    # TRIG REG MASKS
    INT_SEL_MASK    = 0x0000007C   
    INT_THRES_MASK  = 0xFFFF0000
    INT_DUMMY_MASK  = 0x0000FF00

    # CTL REGISTER MASKS and Commands
    FSM_CMD_MASK = 0x00000003
    ADC_CONT_CMD_MASK = 0x00000008
    FSM_CMD_START = 0x1
    FSM_CMD_STOP = 0x2
    FSM_MASK = 0x00000007

    
    # ADC CORE STATES
    FSM_STATES = ['N/A','IDLE','PRE_TRIG','WAIT_TRIG','WAIT_TRIG_WR',
                  'POST_TRIG','DECR_SHOT','N/A','others']  
    


    ##########################################################################   
    # Carrier CSR REGISTER ADDRESSES
    ##########################################################################    
    R_CARRIER_INFO = 0x0
    R_BITSTREAM_TYPE = 0x4
    R_BITSTREAM_DATE = 0x8
    R_CARRIER_STATUS = 0xC
    R_CARRIER_CTL = 0x10	
    
    # Carrier CSR MASKS
    R_WHOLE_REG_MASK = 0xFFFFFFFF
    R_16_BITS_MASK = 0xFFFF
    
    ##########################################################################   	
    # Test register addresses
    ##########################################################################
    R_CTL_TEST =0x0
    R_STA_TEST= 0x4
    R_STA_2_TEST=0x8
    R_SYS_CNT_VAL_TEST = 0xC
    R_SYS_CNT_EN = 0x10
    R_SYS_BUSY_CHECK = 0x14
    R_LEDS_TEST = 0x18
    
    

    ##########################################################################
    # Wishbone Object Addresses
    ##########################################################################

    FMC_CARRIER_CSR  	= 0x20000
    FMC_SPI_ADDR 	= 0x40000
    #FMC_CARRIER_CSR  	= 0x40000
    #FMC_SPI_ADDR 	= 0x20000
    
    FMC_CSR_ADDR 	= 0x60000
    FMC_SYS_I2C_ADDR 	= 0x80000
    FMC_TEST_CSR_ADDR 	= 0xE0000
        
    GN4124_CSR = 0x0 

    def __init__(self, bus):
        self.bus = bus

    ##########################################################################
    # Object Declerations
    ##########################################################################        

        # SPI controller for mez   # bus  ,  address of spi master , divider
 	self.spi_master = spi.COpenCoresSPI(self.bus,self.FMC_SPI_ADDR ,10)

        self.pll_dac = ad5662_spi.CAD5662(self.spi_master, 0)
        
        # CSR for ADC CORE 
        self.fmc_adc_csr = csr.CCSR(self.bus, self.FMC_CSR_ADDR)    	
    	
    	# System I2C for EEPROM
        self.fmc_sys_i2c = i2c.COpenCoresI2C(self.bus, self.FMC_SYS_I2C_ADDR, 249)      

        # EEPROM Device
        self.eeprom_24aa64 = eeprom_24aa64.C24AA64(self.fmc_sys_i2c, self.EEPROM_ADDR)
    	
    	# CSR for Test Suite
    	self.fmc_test_csr = csr.CCSR(self.bus, self.FMC_TEST_CSR_ADDR)
    	
    	#self.spec = rr.Gennum() # bind to the SPEC board
    	self.gn4124 = gn4124.CGN4124(self.bus , 0x0 )	
    
    	#ADC carrier CSR
    	self.fmc_carrier_csr = csr.CCSR(self.bus, self.FMC_CARRIER_CSR)
    	



    def fmc_eeprom_gen_wr(self,filename):
    	self.eeprom_24aa64.dump_file_to_eeprom(filename)



    ##########################################################################
    # Functions using the Carrier CSR
    ##########################################################################

    def pcb_version(self):
    	pcb_ver = self.fmc_carrier_csr.rd_reg(self.R_CARRIER_INFO) & 0xF
    	return pcb_ver
    	
    def carrier_type(self):
    	carrier_type = (self.fmc_carrier_csr.rd_reg(self.R_CARRIER_INFO) >>16) & self.R_16_BITS_MASK
  	return carrier_type
     
  
    def bitstream_type(self):
    	bitstream_type = self.fmc_carrier_csr.rd_reg(self.R_BITSTREAM_TYPE) & 0x1
  	return bitstream_type & self.R_WHOLE_REG_MASK
  	
    def bitstream_date(self):
    	mez_present = self.fmc_carrier_csr.rd_reg(self.R_BITSTREAM_DATE) & self.R_16_BITS_MASK
     	return mez_present
     	
    def carrier_csr_sta(self):
    	return self.fmc_carrier_csr.rd_reg(self.R_CARRIER_STATUS) & 0xF
    
    def carrier_csr_ctl(self):
   	carrier_ctl = self.fmc_carrier_csr.rd_reg(self.R_CARRIER_CTL) & 0x3
   	return carrier_ctl
  
    def check_mez_present(self):
    	mez_present = self.fmc_carrier_csr.rd_reg(self.R_CARRIER_STATUS) & 0x1
    	return mez_present



    ##########################################################################
    # Functions using ADC Core CSR
    ##########################################################################


    def test_data_en(self):
        reg = self.fmc_adc_csr.rd_reg(self.R_CTL)
        print("R_CTL:%.8X")%reg
        reg |= ((1<<self.CTL_TEST_DATA_EN) & self.CTL_MASK)
        print("R_CTL:%.8X")%reg
        self.fmc_adc_csr.wr_reg(self.R_CTL, reg)

    def test_data_dis(self):
        reg = self.fmc_adc_csr.rd_reg(self.R_CTL)
        print("R_CTL:%.8X")%reg
        reg &= (~(1<<self.CTL_TEST_DATA_EN) & self.CTL_MASK)
        print("R_CTL:%.8X")%reg
        self.fmc_adc_csr.wr_reg(self.R_CTL, reg)

    def set_decimation(self, factor):
        self.fmc_adc_csr.wr_reg(self.R_SRATE, factor)

    def get_decimation(self):
        return self.fmc_adc_csr.rd_reg(self.R_SRATE)


        
        # Set trigger configuration                                                             
    def set_trig_config(self, hw_en, sw_en, int_sel, int_thres, slope, delay, edge):
        # Hardware trigger enable
        self.fmc_adc_csr.wr_bit(self.R_TRIG_CFG, self.TRIG_CFG_HW_EN, hw_en)
        # Software trigger enable
        self.fmc_adc_csr.wr_bit(self.R_TRIG_CFG, self.TRIG_CFG_SW_EN, sw_en)
        
        #Edge trigger enable
        self.fmc_adc_csr.wr_bit(self.R_TRIG_CFG, self.TRIG_CFG_EDGE_EN,edge)
        
        # Slope for threshold triger
        self.fmc_adc_csr.wr_bit(self.R_TRIG_CFG, self.TRIG_CFG_SLOPE, slope)
        
        # Internal trigger channel select (2 to 6)
        reg = self.fmc_adc_csr.rd_reg(self.R_TRIG_CFG)

        reg &= ~self.INT_SEL_MASK
        reg |= (int_sel<< self.TRIG_CFG_INT_SEL) & self.INT_SEL_MASK
        #reg |= ((int_sel <<self.TRIG_CFG_INT_SEL) & self.INT_SEL_MASK)
        self.fmc_adc_csr.wr_reg(self.R_TRIG_CFG, reg)

        # Internal trigger threshold
        reg = self.fmc_adc_csr.rd_reg(self.R_TRIG_CFG)
        reg &= ~self.INT_THRES_MASK
        reg |= ((int_thres<<self.TRIG_CFG_INT_THRES) & self.INT_THRES_MASK)
        self.fmc_adc_csr.wr_reg(self.R_TRIG_CFG, reg)

        # Write zeros to dummy					###############CHANGED
        reg = self.fmc_adc_csr.rd_reg(self.R_TRIG_CFG)
        reg &= ~self.INT_DUMMY_MASK
        reg |= ((0<<self.TRIG_CFG_DUMMY) & self.INT_DUMMY_MASK)
        self.fmc_adc_csr.wr_reg(self.R_TRIG_CFG, reg)
        # Trigger delay (in sampling clock ticks)
        self.fmc_adc_csr.wr_reg(self.R_TRIG_DLY, delay)



    # Start acquisition                             
    def start_acq(self):
        # Reads from the control register
        reg = self.fmc_adc_csr.rd_reg(self.R_CTL)
        reg &= ~self.FSM_CMD_MASK
        reg |= ((self.FSM_CMD_START<<self.CTL_FSM_CMD) & self.FSM_CMD_MASK)
        reg &= (self.CTL_MASK | self.FSM_CMD_MASK)
        self.fmc_adc_csr.wr_reg(self.R_CTL, reg)

   # Start ADC controller
    def start_adc_cont(self):
    	reg = self.fmc_adc_csr.rd_reg(self.R_CTL)
    	reg &= ~self.ADC_CONT_CMD_MASK
        reg |= ((self.FSM_CMD_START<<self.CTL_ADC_CONT_CMD) & self.ADC_CONT_CMD_MASK)
        reg &= (self.CTL_MASK | self.ADC_CONT_CMD_MASK)
        self.fmc_adc_csr.wr_reg(self.R_CTL, reg)

    # Stop acquisition                 
    def stop_acq(self):
        reg = self.fmc_adc_csr.rd_reg(self.R_CTL)
        reg &= ~self.FSM_CMD_MASK
        reg |= ((self.FSM_CMD_STOP<<self.CTL_FSM_CMD) & self.FSM_CMD_MASK)
        #print("R_CTL:%.8X")%reg
        self.fmc_adc_csr.wr_reg(self.R_CTL, reg)

    # Software trigger                 
    def sw_trig(self):
        while(3 != self.get_acq_fsm_state()):
            print self.get_acq_fsm_state()
            time.sleep(.1)
        self.fmc_adc_csr.wr_reg(self.R_SW_TRIG, 0xFFFFFFFF)

    # Set pre-trigger samples                          
    def set_pre_trig_samples(self, samples):
        self.fmc_adc_csr.wr_reg(self.R_PRE_SAMPLES, samples)
        
    def get_pre_trig(self):
    	return self.fmc_adc_csr.rd_reg(self.R_PRE_TRIG_COUNTER_VAL)  

    # Set post-trigger samples                          
    def set_post_trig_samples(self, samples):
        self.fmc_adc_csr.wr_reg(self.R_POST_SAMPLES, samples)
    
    # Get post-trigger value    
    def get_post_trig(self):
    	return self.fmc_adc_csr.rd_reg(self.R_POST_TRIG_COUNTER_VAL)
	
    # Set number of shots                               
    def set_shots(self, shots):
        self.fmc_adc_csr.wr_reg(self.R_SHOTS, shots)
    
    
    # Set range pin	YET TO BE DEFINED 
    def set_range(self,range_val):
    	reg = self.fmc_adc_csr.rd_reg(self.R_CTL)
    	reg &= ~self.RANGE_CMD_MASK
        reg |= (( (range_val & 0x1) <<self.CTL_RANGE) & self.RANGE_CMD_MASK)
        reg &= (self.CTL_MASK | self.ADC_CONT_CMD_MASK)
        self.fmc_adc_csr.wr_reg(self.R_CTL, reg)
    	
    # Get ADC core status                           
    def get_status(self):                           
        return self.fmc_adc_csr.rd_reg(self.R_STA)   


    # Get number of shots    
    def get_shots(self):
    	return self.fmc_adc_csr.rd_reg(self.R_SHOT_COUNTER_VAL)

    # Get acquisition state machine status             
    def get_acq_fsm_state(self):
        state = (self.fmc_adc_csr.rd_reg(self.R_STA) & self.FSM_MASK)
        #print("FSM state: %d")%state
        return state 
        #self.FSM_STATES[state]  # this should be used by the other status not this

    # Read spare register        
    def get_spare_reg(self):
    	return self.fmc_adc_csr.rd_reg(self.R_SPARE)
    
    # Return position of trigger in memory... aligned to first channel
    def get_trig_pos(self):
    	return self.fmc_adc_csr.rd_reg(self.R_TRIGGER_POSITION)




    ##########################################################################
    # Functions for the test suite csr and general test suite use
    ##########################################################################

    def read_test_suite_csr(self):
    	return self.fmc_test_csr.rd_reg(self.R_STA_2_TEST)
    	
    	
    def start_leds_blinking(self):
    	self.fmc_test_csr.wr_reg(self.R_LEDS_TEST, 1 & 0xFFFF)

    def stop_leds_blinking(self):	
    	self.fmc_test_csr.wr_reg(self.R_LEDS_TEST, 0 & 0xFFFF)

    def clock_comparison(self):
    	self.fmc_test_csr.wr_reg(self.R_CTL_TEST ,1)
    	while self.fmc_test_csr.rd_reg(self.R_STA_TEST) & 0xFFFF == 0: # This register remains 0 until the count has finished
    		time.sleep(.1)					       # At which point it is 
    	final_val = self.fmc_test_csr.rd_reg(self.R_STA_TEST)
    	self.fmc_test_csr.wr_reg(self.R_CTL_TEST,0)					# should be R_CTL_TEST also?
    	if self.fmc_test_csr.rd_reg(self.R_STA_TEST) & 0xFFFF != 0:
    		print "Counter not reset properly"
    	print "value after reset", self.fmc_test_csr.rd_reg(self.R_STA_TEST)
    	return final_val

    def check_busy_lines(self):
        busy_lines = self.fmc_test_csr.rd_reg(self.R_SYS_BUSY_CHECK)
	return busy_lines 
                                                                    # Need to check these are still used... or still can be used	
    def check_sta_2(self):
    	return self.fmc_test_csr.rd_reg(self.R_STA_2_TEST)
    
    def check_sta_3(self):
    	return self.fmc_test_csr.rd_reg(self.R_SYS_CNT_EN)
	

    def mean(self,numberList):
	if len(numberList)==0:
		return int('nan')
	
	intnums = [int(x) for x in numberList]
	return sum(intnums)/len(numberList)	
    
    	
    def check_range_pin(self,ADC):
    	if ADC & 0x3 == 2:
    		chan = 1
    	else:
    		chan = 8
    	self.set_range(0) # check if its 0 or one
    	result_1 = self.do_small_acq(chan)
    	self.set_range(1)
    	result_2 = self.do_small_acq(chan)
    	if self.mean(result_1)> self.mean(result_2)*1.5:
    		return 1
    	else:
    		return 0

    def do_test_acq(self):
    	pre_trig_val = 0
    	post_trig_val = 9
    	pages = self.gn4124.get_physical_addr()
    	self.stop_acq()
   	self.set_shots(1)
   	time.sleep(.1)
    	self.set_pre_trig_samples(pre_trig_val)
    	time.sleep(.1)
    	self.set_post_trig_samples(post_trig_val)
    	time.sleep(.1)
    	self.set_decimation(1)
    	time.sleep(.1)
    	self.set_trig_config(0,1,0x1,0xFFFF,0,0,0)   
    	time.sleep(.1)
    	self.start_acq()
	self.start_adc_cont()
    	while self.get_status() !=3: 	
		time.sleep(.1)
		#self.start_acq()
	 	#self.start_adc_cont()
    	self.sw_trig()
    	time.sleep(1)
    	if self.get_status()!=0x1:
    		Error_state = self.get_acq_fsm_state()
		time.sleep(0.1)
	else:
		Error_state = 0  	
    	return  Error_state
    



    ##########################################################################
    # Functions for SPI and i2c
    ##########################################################################
    
    def spi_dac_write(self, data):
        return self.pll_dac.set_offset(data & 0xFFFF)
    	
    def i2c_scan(self):
        print '\nScan I2C bus'
        return self.fmc_i2c.scan()

    def sys_i2c_scan(self):
        print '\nScan system I2C bus'
        return self.fmc_sys_i2c.scan()

    def sys_i2c_eeprom_write(self, addr, data):
        return self.eeprom_24aa64.wr_data(addr, data)

    def sys_i2c_eeprom_read(self, addr, size):
        return self.eeprom_24aa64.rd_data(addr, size)


    # Enable test data                           

    

    ##########################################################################
    # Currently unused    
    ##########################################################################
    # Front panel LED manual control
    def acq_led(self, state):                           
        reg = self.fmc_adc_csr.rd_reg(self.R_CTL)
        #print("R_CTL:%.8X")%reg
        if(state == 0):
            reg &= (~(1<<self.CTL_ACQ_LED) & self.CTL_MASK)
        else:
            reg |= ((1<<self.CTL_ACQ_LED) & self.CTL_MASK)  
        #print("R_CTL:%.8X")%reg
        self.fmc_adc_csr.wr_reg(self.R_CTL, reg)
    
    
    def trig_led(self, state):                         
        reg = self.fmc_adc_csr.rd_reg(self.R_CTL)
        #print("R_CTL:%.8X")%reg
        if(state == 0):
            reg &= (~(1<<self.CTL_TRIG_LED) & self.CTL_MASK)
        else:
            reg |= ((1<<self.CTL_TRIG_LED) & self.CTL_MASK)
        #print("R_CTL:%.8X")%reg
        self.fmc_adc_csr.wr_reg(self.R_CTL, reg)




    ##########################################################################
    # Acquisition Functions
    ##########################################################################

    def dma_access(self, start_addr,end_addr):
    	
	dma_length=0x1000
	pages_required = int(math.ceil(((dma_end-dma_start)/float(dma_length))))
	for num in range(pages_required):   
    		if  pages_required==num+1: 				
        		end_character=0                                 
        		length=(dma_end-(num*dma_length))               
    		else:
        		end_character=1                                 
        		length=dma_length                               
    		if num==0:                                          
        		start_address=dma_start                           
    		else:
        		start_address=dma_start + num*dma_length    
    		print "gn4124.add_dma_item( %s, pages[%d], %d, 0,%d)"%(start_address,num+1,length,end_character)	
    		self.gn4124.add_dma_item(start_address, num+1,length,0, end_character)
    
    
    def do_small_acq(self, chan):
    	pre_trig_val = 10
    	post_trig_val = 9
    	
    	pages = self.gn4124.get_physical_addr()
    	self.stop_acq()
   	self.set_shots(1)
   	time.sleep(.1)
    	self.set_pre_trig_samples(pre_trig_val)
    	time.sleep(.1)
    	self.set_post_trig_samples(post_trig_val)
    	time.sleep(.1)
    	self.set_decimation(1)
    	time.sleep(.1)
    	self.set_trig_config(0,1,0x1,0xFFFF,0,0,0)   
    	time.sleep(.1)
    	self.start_acq()
	self.start_adc_cont()
    	while self.get_status() !=3: 	
		time.sleep(.1)
    	self.sw_trig()
    	while self.get_status()!=0x1:
		time.sleep(1)
    	trigger_position=self.get_trig_pos() & 0xFFFFFFFF
    	dma_start= trigger_position-(pre_trig_val*8)
    	self.gn4124.add_dma_item((dma_start<<2),pages[1],0x1000,0,0)   # will need to add the gennum class to this file
    	# load array from pages
    	self.gn4124.start_dma()
	while('Done' != self.gn4124.get_dma_status()):
		time.sleep(.5)
		self.gn4124.wait_irq()
	    
	page1_data = self.gn4124.get_memory_page(1)    
    	# sort into chanels
    	channels = []
    	for i in range(2**10):
	    	channels.append(page1_data[i] >>16 )
		channels.append(page1_data[i] & 0xFFFF)
    	for i in range(len(channels)):
		if(channels[i] & 0x8000):
			channels[i] = -0x10000 + channels[i]
    	
    	
    	channel_requested = channels[(chan-1)::16]
    	return channel_requested[0: pre_trig_val + post_trig_val + 1]
    
    
    
    
    
    
    def do_acq(self, chan, mode ,average,post_trig_val,pre_trig_val,thresh):
    	dma_length = 0x1000
    	self.start_adc_cont()
    	pages = self.gn4124.get_physical_addr()
    	self.stop_acq()
   	self.set_shots(1)
   	time.sleep(.1)
    	self.set_pre_trig_samples(pre_trig_val)
    	time.sleep(.1)
    	self.set_post_trig_samples(post_trig_val)
    	time.sleep(.1)
    	self.set_decimation(1)
    	time.sleep(.1)
    	
    	if thresh!=1:
    		sw_trig_en =1
    	else:
    		sw_trig_en =0
    		
    	self.set_trig_config(thresh,sw_trig_en,0x1,0x1000,1,0,0)   
    	time.sleep(.1)
    	self.start_acq()
	
    	while self.get_status() !=3: 	
		time.sleep(.5)
		#self.start_acq()
	 	#self.start_adc_cont()
	 	print "waiting for state machine to be in trigger state"
    	if thresh !=1:
    		self.sw_trig()
    		print "software trig applied"
    	while self.get_status()!=0x1:
		time.sleep(1)
		#print "waiting for thresh trig"
    	trigger_position=self.get_trig_pos() & 0xFFFFFFFF
    	#if trigger_position%8!=0:
    	#	print "\n\n\n ERROR \n\n\n"
    	
    	dma_start= trigger_position-(pre_trig_val*8)
    	#print "DMA START", dma_start
    	#print "Trigger position",trigger_position
    	
    	
    	self.gn4124.add_dma_item((dma_start<<2)+(0*dma_length),pages[1], dma_length, 0,1)
	self.gn4124.add_dma_item((dma_start<<2)+(1*dma_length),pages[2], dma_length, 0,1)
	self.gn4124.add_dma_item((dma_start<<2)+(2*dma_length),pages[3], dma_length, 0,0)   	
 
    	# load array from pages
    	self.gn4124.start_dma()
	while('Done' != self.gn4124.get_dma_status()):
		time.sleep(.5)
		self.gn4124.wait_irq()

    	page1_data = self.gn4124.get_memory_page(1)
    	page2_data = self.gn4124.get_memory_page(2)
    	page3_data = self.gn4124.get_memory_page(3)


    	# sort into chanels
    	channels = []
	for i in range(2**10):
	    	channels.append(page1_data[i] >>16 )
		channels.append(page1_data[i] & 0xFFFF)

	for i in range(2**10):
	    	channels.append(page2_data[i]>>16) 
		channels.append(page2_data[i] & 0xFFFF)
	
    	for i in range(len(channels)):
		if(channels[i] & 0x8000):
			channels[i] = -0x10000 + channels[i]
			
    	if mode   == "chan_select":
    		channel_requested = channels[(chan-1)::16]
    		if average.upper() =="Y":
    			return self.mean(channel_requested[0: pre_trig_val + post_trig_val + 1])
    		else:
    			return channel_requested[0: pre_trig_val + post_trig_val + 1]
    	elif mode == "camera_link":
    		split_channels=[]
    		#print "HERE"
    		for j in range(11):	
		#	print channels[j::16]
			split_chan = channels[j::16]
			split_channels.append(split_chan[0:pre_trig_val +post_trig_val +1])
    			
    		if average.upper() == "Y":
    			averaged =[]
    			for i in range(len(split_channels)):
    				averaged.append(self.mean(split_channels[i]))
    			return averaged
    			
    		else:
    			return split_channels
    			#return split_channels[0: pre_trig_val + post_trig_val + 1]
    	elif mode == "all_chans":
    		split_channels=[]
		for j in range(16):	
			#print channels[j::16]
			split_chan = channels[j::16]
			split_channels.append(split_chan[0:pre_trig_val +post_trig_val +1])
    		if average.upper() == "Y":
    		    	averaged =[]
    			for i in range(len(split_channels)):
    				averaged.append(self.mean(split_channels[i]))
    			return averaged
    		else:
    			return split_channels






#    		for i in range(16):
#    			split_channels=[]
#			split_channels.append(force_inputs[i::16])
#			if average.upper() == "Y":
#    				averaged =[]
#    				for i in range(len(split_channels)):
#    					averaged.append(mean(split_channels[i]))
#    				return averaged
#    			else:
#    				return split_channels[0: pre_trig_val + post_trig_val + 1]
    		
