'<ADbasic Header, Headerversion 001.001>
' Process_Number                 = 1
' Initial_Processdelay           = 2000
' Eventsource                    = Timer
' Control_long_Delays_for_Stop   = No
' Priority                       = High
' Version                        = 1
' ADbasic_Version                = 6.3.1
' Optimize                       = Yes
' Optimize_Level                 = 4
' Stacksize                      = 1000
' Info_Last_Save                 = ATI098-60  ATI098-60\labuser
'<Header End>
#include adwinpro_all.inc
#include ADwin_utils.inc

' Array Size Settings
' TODO: check these values in labscript_devices files
#define ZERO          32768       ' Zero Volts in Adwin 16bit representation
#define MAXEVENTS     100000      ' Max number of events that can be stored
#define AOUTFIFO      100000      ' Max number of changing the AOUT set value
#define PIDFIFO       20          ' Max number of changing the AIN channel for PID feedback to AOUT
#define PIDNO         28          ' Number of implemented PIDs
#define MAXTICOEVENTS 2000        ' Max number of Digital Output events
#define AINFIFO       100000      ' Size of Array to transmit AIN values to the runner PC

' Set Module Adresses
' TODO get or set these values from labscript ?
#define DIO1  1                       'DIO  Card 32
#define DIO2  2                       'DIO  Card 32
#define AIN1  3                       'AIN  Card 8/16
#define AIN2  4                       'AIN  Card 8/16
#define AOUT1 5                       'AOUT Card 8/16
#define AOUT2 6                       'AOUT Card 8/16

' Declare Arrays for Analog Data from experiment control software
DIM DATA_1[MAXEVENTS] AS Long           'analog time
DIM DATA_2[MAXEVENTS] AS Long           'Analog Out change monitor
DIM DATA_3[MAXEVENTS] AS Long           'Analog Out PID change monitor
' Format: DATA_{module}{channel} + 100 for PID channels
DIM DATA_50[AOUTFIFO] AS Long AS Fifo    'AOUT1 Channel 00
DIM DATA_51[AOUTFIFO] AS Long AS Fifo    'AOUT1 Channel 01
DIM DATA_52[AOUTFIFO] AS Long AS Fifo    'AOUT1 Channel 02
DIM DATA_53[AOUTFIFO] AS Long AS Fifo    'AOUT1 Channel 03
DIM DATA_54[AOUTFIFO] AS Long AS Fifo    'AOUT1 Channel 04
DIM DATA_55[AOUTFIFO] AS Long AS Fifo    'AOUT1 Channel 05
DIM DATA_56[AOUTFIFO] AS Long AS Fifo    'AOUT1 Channel 06
DIM DATA_57[AOUTFIFO] AS Long AS Fifo    'AOUT1 Channel 07
DIM DATA_60[AOUTFIFO] AS Long AS Fifo    'AOUT2 Channel 00
DIM DATA_61[AOUTFIFO] AS Long AS Fifo    'AOUT2 Channel 01
DIM DATA_62[AOUTFIFO] AS Long AS Fifo    'AOUT2 Channel 02
DIM DATA_63[AOUTFIFO] AS Long AS Fifo    'AOUT2 Channel 03
DIM DATA_64[AOUTFIFO] AS Long AS Fifo    'AOUT2 Channel 04
DIM DATA_65[AOUTFIFO] AS Long AS Fifo    'AOUT2 Channel 05
DIM DATA_66[AOUTFIFO] AS Long AS Fifo    'AOUT2 Channel 06
DIM DATA_67[AOUTFIFO] AS Long AS Fifo    'AOUT2 Channel 07
' Declare Arrays for PID channels for each AOUT channel
DIM DATA_150[PIDFIFO] AS Long AS Fifo    'PID for AOUT1 Channel 00
DIM DATA_151[PIDFIFO] AS Long AS Fifo    'PID for AOUT1 Channel 01
DIM DATA_152[PIDFIFO] AS Long AS Fifo    'PID for AOUT1 Channel 02
DIM DATA_153[PIDFIFO] AS Long AS Fifo    'PID for AOUT1 Channel 03
DIM DATA_154[PIDFIFO] AS Long AS Fifo    'PID for AOUT1 Channel 04
DIM DATA_155[PIDFIFO] AS Long AS Fifo    'PID for AOUT1 Channel 05
DIM DATA_156[PIDFIFO] AS Long AS Fifo    'PID for AOUT1 Channel 06
DIM DATA_157[PIDFIFO] AS Long AS Fifo    'PID for AOUT1 Channel 07
DIM DATA_160[PIDFIFO] AS Long AS Fifo    'PID for AOUT2 Channel 00
DIM DATA_161[PIDFIFO] AS Long AS Fifo    'PID for AOUT2 Channel 01
DIM DATA_162[PIDFIFO] AS Long AS Fifo    'PID for AOUT2 Channel 02
DIM DATA_163[PIDFIFO] AS Long AS Fifo    'PID for AOUT2 Channel 03
DIM DATA_164[PIDFIFO] AS Long AS Fifo    'PID for AOUT2 Channel 04
DIM DATA_165[PIDFIFO] AS Long AS Fifo    'PID for AOUT2 Channel 05
DIM DATA_166[PIDFIFO] AS Long AS Fifo    'PID for AOUT2 Channel 06
DIM DATA_167[PIDFIFO] AS Long AS Fifo    'PID for AOUT2 Channel 07

'Declare Arrays for Digital Data from experiment control software
DIM DATA_10[MAXTICOEVENTS] AS Long         'DIO1 TiCo times
DIM DATA_11[MAXTICOEVENTS] AS Long         'DIO1 Digital Outputs
DIM DATA_20[MAXTICOEVENTS] AS Long         'DIO2 TiCo times
DIM DATA_21[MAXTICOEVENTS] AS Long         'DIO2 Digital Outputs


'Declare Arrays that are used for AIN transmission
DIM DATA_4[AINFIFO] AS LONG AS FIFO
DIM DATA_5[AINFIFO] AS LONG AS FIFO
DIM DATA_6[AINFIFO] AS LONG AS FIFO

' TODO what are these used for ?
DIM remainder AS LONG
DIM oldReglerIPG AS LONG

'Declare Tico Data Transfer Arrays
DIM TICO_MEMORY1[150] AS LONG
DIM TICO_MEMORY2[150] AS LONG

'Declare PID SETTINGS Arrays
DIM p_pid[PIDNO] AS FLOAT
DIM i_pid[PIDNO] AS FLOAT
DIM d_pid[PIDNO] AS FLOAT

DIM sum[PIDNO], ra_alt_diff[PIDNO]  AS FLOAT
DIM ra_diff, diff, lin AS FLOAT
DIM ra, regler AS LONG

'Declare Other Variables
DIM processIdx AS LONG
DIM aEventIdx AS LONG
DIM dEventIdx AS LONG
DIM timer AS LONG
DIM i AS LONG   'number in for loops

'Declare Array for reading/writing AIN and AOUT Channels
DIM act_values[28] AS LONG ' Analog values measured from AINs
DIM set_values[16] AS LONG ' Set values to be written to AOUTs

'declare ADC FIFO variables
DIM ADC_Channel_FIFO1 AS LONG
DIM ADC_Channel_FIFO2 AS LONG
DIM ADC_Channel_FIFO3 AS LONG
DIM ADC_stepsize AS LONG
DIM ADC_start AS LONG
DIM ADC_enable AS LONG
DIM ADC_fifo_update AS LONG
DIM ADC_average_update  AS LONG
DIM ADC_average1 AS LONG
DIM ADC_average2 AS LONG
DIM ADC_average3 AS LONG
DIM ADC_fifo_frequ  AS FLOAT
  

'========================================================================================================================================
'= LOWINIT             =
'========================================================================================================================================

init:
  'Set Processdelay to 2us and return it to the experiment control software
  
  PROCESSDELAY = 2000 ' TODO wirte it from labscript ?
  par_1 = PROCESSDELAY
  par_2 = 0
  
  'Initialize Variables
  processIdx = 0
  aEventIdx = 1
  dEventIdx  =1
  par_14 = 0 'timer variable 

  'Set DIO Channels As Outputs
  ' TODO do we want to set this dynamically from labscript ?
  P2_DIGPROG(DIO1, 1111b)                'Channel 0-31
  P2_DIGPROG(DIO2, 1111b)                'Channel 32-63 
  
  CPU_Dig_IO_Config(000010b)   'SET Adwin T12 DIO as digital input for falling edge (DIG I 0-1) and rising Edge DIG I 0-0
  
  'Reset Tico and initialize data transfer Arrays
  P2_tico_reset(2^(DIO1-1) + 2^(DIO2-1))  '(0000000000010001b)    'Resets DIO Modules
  P2_tdrv_init(DIO1, 1, TICO_MEMORY1)    'Data Transfer to Module DIO1
  P2_tdrv_init(DIO2, 1, TICO_MEMORY2)    'Data Transfer to Module DIO2

  'Load the digital event data into the memory two DIO modules
  P2_setdata_long(TICO_MEMORY1, 1, 1, MAXTICOEVENTS, DATA_10, 1, 1) 'Time for digital channels
  P2_setdata_long(TICO_MEMORY1, 2, 1, MAXTICOEVENTS, DATA_11, 1, 1) 'Output values of the digital channels 0-31

  P2_setdata_long(TICO_MEMORY2, 1, 1, MAXTICOEVENTS, DATA_20, 1, 1) 'Time for digital channels
  P2_setdata_long(TICO_MEMORY2, 2, 1, MAXTICOEVENTS, DATA_21, 1, 1) 'Output values of the digital channels 32-63

  'Turn Module LEDs on
  P2_SET_LED(DIO1, 1)
  P2_SET_LED(DIO2, 1)
  P2_SET_LED(AIN1, 1)
  P2_SET_LED(AIN2, 1)
  P2_SET_LED(AOUT1, 1)
  P2_SET_LED(AOUT2, 1)

  '========================================================================================================================================
  '=                                                        PID PARAMETERS             =
  '========================================================================================================================================

    
''' # Setting for the ADC 
  'Parameter for ADC
  ADC_stepsize=par_4
  ADC_start=par_9
  ADC_enable=par_5
  ADC_fifo_update=ADC_stepsize-1
  ADC_average_update=100-1
  
  'FIFOs leeren
  FOR i=0 TO 7
    FIFO_CLEAR(10*AOUT1 + i)
    FIFO_CLEAR(10*AOUT2 + i)
    FIFO_CLEAR(10*AOUT1 + i + 100)
    FIFO_CLEAR(10*AOUT2 + i + 100)
  NEXT i
  FIFO_CLEAR(4)
  FIFO_CLEAR(5)
  FIFO_CLEAR(6)
  'Mittelwerte zur�cksetzen
  ADC_average1=0
  ADC_average2=0
  ADC_average3=0
  ADC_fifo_frequ=1.0/ADC_stepsize ''number of values that are averaged depending on the timestep of the fifo
  
  'den FIFOs die ADC Channels zuweisen
  ADC_Channel_FIFO1=1
  ADC_Channel_FIFO2=2
  ADC_Channel_FIFO3=3
    
  'Shift Data in each Array to desynchronize chaching of the arrays in the event loop. this prevents single events from taking
  'a lot of time when all arrays are recached at the same event.
  ' TODO deleted chaching fix
  
  ' Set analog outputs for the first time in the sequence.
  set_values[1]  = DATA_50
  set_values[2]  = DATA_51
  set_values[3]  = DATA_52
  set_values[4]  = DATA_53
  set_values[5]  = DATA_54
  set_values[6]  = DATA_55
  set_values[7]  = DATA_56
  set_values[8]  = DATA_57
  set_values[9]  = DATA_60
  set_values[10] = DATA_61
  set_values[11] = DATA_62
  set_values[12] = DATA_63
  set_values[13] = DATA_64
  set_values[14] = DATA_65
  set_values[15] = DATA_66
  set_values[16] = DATA_67
  
  
  ''### Setzen der Stellwerte an die Analogausg�nge 
  P2_Write_DAC8(AOUT1,set_values,1)    ' sende neue stellwerte an die Analog out Karten
  P2_Write_DAC8(AOUT2,set_values,9)
  P2_Start_DAC(AOUT1)                 ' starte das rausschreiben der  analog output werte
  P2_Start_DAC(AOUT2)
  
  'initalize tico digital outputs
  
  P2_set_par(DIO1,1,1,DATA_11[dEventIdx])   'Initilisiere digitalausg�nge f�r tico  
  P2_set_par(DIO2,1,1,DATA_21[dEventIdx])   'Initilisiere digitalausg�nge f�r tico
  
  ''increase event index by 1
  inc dEventIdx
  
  P2_set_par(DIO2,1,2,81)      'initialisiere Zählvariable für tico         
  P2_set_par(DIO1,1,2,81)      'initialisiere Zählvariable für tico
  
  P2_set_par(DIO2,1,3,dEventIdx)  'Setze index nächstes event für tico  
  P2_set_par(DIO1,1,3,dEventIdx)  'Setze index nächstes event für tico

  
  '### P2_ADCF_MODE im Timer Modus. Anweisung sollte m�glichst am Ende der init stehen  
  P2_ADCF_MODE(2^(AIN1-1),0)    '2=module No.2, 1=timer mode(always measure)start timer mode (immediate before the EVENT Part)    
  P2_Set_Average_Filter(AIN1,2)
  'P2_Set_Gain(AIN1,1,1)
  
  'P2_Set_ADF(010b,5010h,1) 'check this  'change sampling frequency  for card 2 module No2 5010h is the adress and the measurement time is (value-1)*10ns+250ns and value ranges from 31 (default setting) to 1 check again 
  P2_ADCF_MODE(2^(AIN2-1),0)    'module No.6 set as 2^6=0100000 in binary, 1=timer mode(always measure)start timer mode (immediate before the EVENT Part)    
  P2_Set_Average_Filter(AIN2,2)
  '  P2_Set_Gain(AIN2,1,2)
  '  P2_Set_Gain(AIN2,2,1)
  '  P2_Set_Gain(AIN2,3,0)
  '  P2_Set_Gain(AIN2,5,3)
  '  P2_Set_Gain(AIN2,6,2)
  '  P2_Set_Gain(AIN1,7,2)
  '  P2_Set_Gain(AIN1,6,0)
  
  'Check_Card(6)
  'Par_20 = Peek((68050100h OR shift_left(6,20)))
  '### Set the Sampling Rate of the AIN cards. The Period is given by T = 250ns + (value-1)* 10ns. The value is set by writing to the correct register using POKE(register,value)
  ' TODO what's going on here ???
  CHECK_CARD(AIN1)                             
  POKE((68050100h OR  shift_left(AIN1,20)),1)

  CHECK_CARD(AIN2)
  POKE((68050100h OR  shift_left(AIN2,20)),1)
  
  
  
  'Start Conversion for first Event
  P2_Sync_All(2^(AIN1-1)+2^(AIN2-1))
  'P2_Sync_All(100010b)
  'Wait for 200 * 10ns to make sure that first ADC values are ready
  CPU_Sleep(200)
  
  '========================================================================================================================================
  '=                                                        EVENT LOOP             =
  '========================================================================================================================================

EVENT:
  timer = READ_TIMER_SYNC()
  
  'Read istwerte at all ADC Channels
  P2_READ_ADCF8(AIN1, act_values, 1)        'READ CHANNEL 1-8 OF AIN MODULE 1
  P2_READ_ADCF8(AIN2, act_values, 21)        'READ CHANNEL 1-8 OF AIN MODULE 2
  
  'Start conversion at all ADC Channels Synced for next Event
  'P2_Sync_All(100010b)
  P2_Sync_All(2^(AIN1-1)+2^(AIN2-1))
  

  'COMPUTE NEW SET VALUES
  ' DELETED PID etc. for OUTPUT CHANNELS !

    
  
  '### Werte ausgeben  
 
  if(processIdx = 20) then ' TODO why wait for 20 process cycles, is this a measued value ??
    P2_set_par(DIO1,1,20,1)    'starte tico event Modul 1
    P2_set_par(DIO2,1,20,1)    'starte tico event Modul 5
    
  endif
    
  ''### Setzen der Stellwerte an die Analogausgänge (t= 27)
  P2_Write_DAC8(AOUT1,set_values,1)  ''sende neue stellwerte an die Analog out Karten
  P2_Write_DAC8(AOUT2,set_values,9)
  
  'Write all DAC Channels Synced
  P2_Sync_All(2^(AOUT1-1)+2^(AOUT2-1))
 
  '### Rausschreiben ADC Arrays
  DATA_4 = act_values[ADC_Channel_FIFO1]
  DATA_5 = act_values[ADC_Channel_FIFO2]
  DATA_6 = act_values[ADC_Channel_FIFO3]
  'DATA_3[processIdx]=stellwert[12]
  
  inc processIdx
  
  If (DATA_1[aEventIdx+1] = processIdx)THEN 'check wether next event reached
    inc aEventIdx         'set index to next event
  ENDIF
  
  
  '### Programmterminierung
  IF (processIdx  > Par_3 ) THEN   ' TODO get parameter from labscript 
    END                                                  'end loop when last last timing event completed
  ENDIF
  
  '### Debug Timer  
  par_13=READ_TIMER_SYNC() -timer
  par_15=processIdx
  'if ( par_13 > par_14 ) then
  '  par_14=par_13    'Laufzeit (ca. t=1700)
  '  par_15=processIdx
  'endif
  'if(processIdx < FIFOLENGTH) then
  'DATA_2[processIdx-1] = stellwert[5]
  'DATA_2[processIdx-1]=stellwert[12]
  'DATA_3[processIdx-1] = stellwert[12]
  'endif
  
    
FINISH:
 
  P2_DAC(AOUT1,5,ZERO)       'Analogausgang 3 (feshbachcurrent lower) auf sicheren wert setzen
  P2_DAC(AOUT2,5,ZERO)       'Analogausgang 13 (feshbachcurrent upper) auf sicheren wert setzen
  P2_DAC(AOUT1,6,36700)   'Analogausgang 6 (ipg power) auf sicheren wert (1.2) setzen entspricht 20W
  
  '  P2_SET_LED(DIO1,0)            'LED am Modul 1 ausschalten = DIO32
  '  P2_SET_LED(DIO2,0)            'LED am Modul 5 ausschalten = DIO32
  '  P2_SET_LED(AIN1,0)            'LED am Modul 2 ausschalten = Ain 16bit
  '  P2_SET_LED(AIN2,0)
  '  P2_SET_LED(AOUT1,0)           'LED am Modul 3 ausschalten = AOUT 8/18
  '  P2_SET_LED(AOUT2,0)           'LED am Modul 4 ausschalten = AOUT 8/18

  P2_tico_stop_process(TICO_MEMORY1,1)
  P2_tico_stop_process(TICO_MEMORY2,1)
  
  PAR_2 = 0