; $Id$: ; full raw data readout with up to 30 samples, multiple of 3 ; possible options: ; - RAW_SCSN is one of: ; - RAW_SCSN_ALL (all channels stored in DMEM for SCSN readout) ; - RAW_SCSN_DIS (don't store in DMEM) ; - FULL_WITH_FIT2DM is 1 (on) or 0 (off): store the fit registers in DMEM for debugging ; - FULL_WITH_STAT: accumulate sum and sum**2 of the ADC data in DMEM, in order to calculate ; later the RMS ; prepare the pointer to DMEM, lower 16 bits - ADC data, upper 16 bits - ADC statistics data #REP Compiling Full Readout Raw Data Mode #ifneq RAW_SCSN, RAW_SCSN_DIS mov AddrDMdata, r15 #ifeq FULL_WITH_STAT, 1 mov AddrDMstat, r2 swp r2, r2 ; for SCSN readout only, both start addresses are CPU specific! or r15, r2, r15 ; bits 27..16 - statistics, bits 11..0 - ADC data #endif #endif #ifdef cpu0 spio r11, NODP ; NI transfer chip header, prepared before #ifneq RAW_SCSN, RAW_SCSN_DIS sra+ r11 ; and to DMEM if not disabled #endif #endif ; cpu0 ; refresh EBPP - when wrong, the ADC data contain a parity bit #ifdef cpu1 mov EBPP_VAL, r7 iext EBPP sgio r7, EBPP #endif ; once for all 5 or 6 transmitted channels mov RAW_END_BITS, r7 ; RAW_SCSN is one of: RAW_SCSN_ALL, RAW_SCSN_DIS ;############################################## ;# NI&SCSN transfer of 5/6 channels ;############################################## mov EBR0, rio mvpcr +2, rstack jmp cc_uncond, raw_ChTML ; with/without DMEM store mov EBR1, rio mvpcr +2, rstack jmp cc_uncond, raw_ChTML ; with/without DMEM store mov EBR2, rio mvpcr +2, rstack jmp cc_uncond, raw_ChTML ; with/without DMEM store mov EBR3, rio mvpcr +2, rstack jmp cc_uncond, raw_ChTML ; with/without DMEM store mov EBR4, rio mvpcr +2, rstack jmp cc_uncond, raw_ChTML ; with/without DMEM store #ifdef cpu3 mov EBR5, rio mvpcr +2, rstack jmp cc_uncond, raw_ChTML ; with/without DMEM store #endif ; save the fit register pairs in DMEM #ifeq FULL_WITH_FIT2DM, 1 mov r15, r2 ; save temporary the DMEM address pointers mov FIT2DM_DM, r15; DMEM pointer sll 6, c5, r1 ; 16 * 4 * CPUid add r1, r15, r15 mov f0, r1 sra+ r1 mov f1, r1 sra+ r1 mov f2, r1 sra+ r1 mov f3, r1 sra+ r1 mov f4, r1 sra+ r1 mov f5, r1 sra+ r1 mov f6, r1 sra+ r1 mov f7, r1 sra+ r1 mov f8, r1 sra+ r1 mov f9, r1 sra+ r1 mov f10, r1 sra+ r1 mov f11, r1 sra+ r1 mov f12, r1 sra+ r1 mov f13, r1 sra+ r1 mov f14, r1 sra+ r1 mov f15, r1 sra+ r1 mov r2, r15 ; restore the DMEM address pointers #endif jmp cc_uncond, raw_end_ni_tmsn ;############################################################################## ;# ;# NI transmission of one channel ;# ;############################################################################## ;# ;# Interface: ;# ;# Input: r14 (rio) start address of event buffer in LIO ;# r1 number of time bins to read (>0, multiple of three) ;# r7 OR mask for the 32 bit word (the two LSBits) ;# r8 rstack, return address ;# ;# Output: sends data to the NI output port, writes data to DMEM ;# Modifies: r1, r3, r4, r5, r14, r13 ;# ;############################################################################## ;############################################## ;# BEGIN data transfer loop raw_ChTML: mov NSAMPLES, r1 ; init the loop counter #ifeq FULL_WITH_STAT, 1 mov 0, r11 ; clear r11 and r13 ONLY in case of ADC statistics! mov 0, r13 #endif raw_ChTML_loop: ; now only one jump entry point for all kinds of readout & test patterns! ; now read 3 ADC values in a burst, the readout is pipelined, the first value must be read twice! lpio+ r3 ; initial read has to be done twice due to lpio+ r3 ; memory delay (synchronous read), get the first values and request the second lpio+ r4 ; get the second value and request the third lpio rio, r5 ; get the third, but don't request next values, as the pointer will be incremented again! #ifeq FULL_WITH_STAT, 1 ; the special case of statistics mode mul32 r3, r3, r0 ; calculate ADC**2 add r11, r3, r11 ; accumulate sum(ADC), r11 was initialized with 0 before the loop for one channel add r13, r0, r13 ; accumulate sum(ADC**2), r13 was initialized with 0 before the loop for one channel mul32 r4, r4, r0 ; calculate ADC**2 add r11, r4, r11 ; accumulate sum(ADC) add r13, r0, r13 ; accumulate sum(ADC**2) mul32 r5, r5, r0 ; calculate ADC**2 add r11, r5, r11 ; accumulate sum(ADC) add r13, r0, r13 ; accumulate sum(ADC**2) #endif ; here the 3 samples are in r3 (earlier), r4, r5 (latest) ; the format is, from bit 31 to 0: r5 - r4 - r3 - r7 (2 LSBits) sll 10, r5, r5 ; combine three 10 bit data words or r5, r4, r5 ; to one (32=10+10+10+2) bit data word slr 4, r5 ; shift by 4 so we are looking at the upper 16 bit only jmp cc_zero, raw_ADCzero ; correct data if the upper 16 bit of the two ADC samples are 0 ; => OR r5 with 0x400, effectively set the LSBit if the last ADC sample raw_ADCcor: ; returns here after the optional correction (s. above) sll 10, r5, r5 ; r5 already contains two samples, (latest << 10 | middle) << 10 or r5, r3, r5 ; append the first (earliest) ADC sample sll 2, r5, r5 ; prepare space for two additional bits on the right side or r5, r7, r5 ; set the two LSBs, r7 is preloaded and toggled properly after each channel spio r5, NODP ; write to NI #ifneq RAW_SCSN, RAW_SCSN_DIS sra+ r5 ; store the ADC data to DMEM, note that the pointer is initialized before! #endif sub r1, 3, r1 ; decrease the remaining number of samples to read by 3, as we send 3 samples at once jmp cc_gtu, raw_ChTML_loop ; close the loop ; no more data in this ADC channel xor r7, 1, r7 ; toggle the LSB, prepare for the next channel #ifeq FULL_WITH_STAT, 1 ; store the ADC statistics to DMEM swp r15, r15 ; swap the two DMEM pointers - now for statistics nop lra4 r4 ; read the old sum(ADC) lra4 r4 add r11, r4, r11 ; add the current sum(ADC) sra+ r11 ; and write back nop ; the reg r15 should be NOT modified befire MCM-read! lra4 r4 ; read the old sum(ADC**2) lra4 r4 add r13, r4, r13 ; add the current sum(ADC**2) sra+ r13 ; and store back nop lra4 r4 ; load the upper 32 bits of sum(ADC**2) lra4 r4 adc r4, c0, r4 ; add the carry, sra+ and lra don't modify the carry! sra+ r4 ; and write back swp r15, r15 ; swap the two DMEM pointers again, now for ADC data #endif jmp cc_uncond, rstack ; return from subroutine raw_ADCzero: mov 0x400, r4 ; set the LSB of the latest ADC sample or r5, r4, r5 ; to prevent sending the end-marker 0x0000 in the upper 16 bits jmp cc_uncond, raw_ADCcor