; $Id$: ; this program part will be executed only after the first trigger ; instead of the tracklet fit! ; ; it replaces the acq interrupt start address with the proper one, so the ; next trigger will start the real tracklet routine ; the total program length of the IRQ ACQ, should be increased later! ; some changes in the new version: ; - some constants, corresponding to configuration registers are not more read ; via the global bus, but directly set as constants in the ASM file. ; TO DO: ; clear the pedestal filter by writing 0 and then 1 to the FPCL, may be at a distance of 1-2 slow clocks. ; => done ; DO WE HAVE some more similar actions? ; all MCMs init: #ifdef cpu0 sem 1 ; cpu0..2 wait until cpu3 writes the readout flags to g0 mov 0, r1 iext FPCL sgio r1, FPCL ; clear the pedestal filter jmpr cc_busy, 0 iext FGCL ; clear the gain counters sgio r1, FGCL #endif #ifdef cpu1 sem 1 ; cpu0..2 wait until cpu3 writes the readout flags to g0 mov 1, r1 iext EvtCtr_DB sgio r1, EvtCtr_DB ; init the software event counter in DBANK ; init the global counter, can be done in the main.tcs #ifeq DYN_L1A, 1 jmpr cc_busy, 0 lgio 1, CTGDOUT ; request reading of the global counter - special pulse for full readout mova SML2_VALnoA, r5 ; prepare to write the SML2, load it without L1A/R bit jmpr cc_busy, 0 ; wait for the global bus lpio GBUSR1, r0 ; get the global counter, requested before - was a special pulse for full readout? and r0, c1, r0 ; we expect 0 or 1 sll 14, r0, r0 ; shift to position 14 -> ignore_L1R or r0, r5, r5 ; merge with the SML2 value sgio r5, SML2 ; write the complete SML2 with ignore_L1R set (when the counter=1 was) or cleared (when counter=0 was) #endif mova CTGCTRL_VAL, r1 ; refresh the counter config jmpr cc_busy, 0 sgio r1, CTGCTRL mov 0, r0 ; prepare to clear the counter jmpr cc_busy, 0 sgio r0, CTGDINI ; clear the counter anyway! #endif #ifdef cpu2 sem 1 ; cpu0..2 wait until cpu3 writes the readout flags to g0 lgio 0, h_0_DB ; read the HCM header 0 from DBANK jmpr cc_busy, 0 lpio GBUSR0, r1 sgio r1, h_0_ConIO ; and store it to a constant and to g2 mov r1, g2 #endif #ifdef cpu3 lgio 0, ChipPOS_DB jmpr cc_busy, 0 ; wait for the global bus lpio GBUSR0, r1 sgio r1, ChipPOS_ConIO mov r1, g1 jmpr cc_busy, 0 slr 16, r1, g0 ; the flags are in the upper 16 bits, now in the lower 16 bits #else syn ; this means automatically that cpu2 has finished, as it has higher priority #endif sem b1000_0000_0000_0000 ; wait for write to g15 mov g0, r2 ; copy in order to check bits 1..0 andt r2, c3 ; here bits 0 and 1 are set for normal MCMs, bits 2..3 are set for HCM, all 0 => BM jmp cc_zero, init_bm_hcm ; here are only MCMs without HCM and BM! #ifdef cpu0 mvpcr +2, rstack jmp cc_uncond, load_direct_first_m #endif ; initialise the IRQ tables mvpcr +2, rstack jmp cc_uncond, init_irq_vec #ifdef cpu0 ; #ifdef EvnCntL0 ; shl 0, c11, r3 ; check if c11 is 1 ; jmpr cc_nzero, +5 ; mov 0x700, r2 ; external input, L0A, up, counter ; spio r2, CTPCTRL ; init the privat counter of CPU0 ; ; here r3 is 0 ; sgio r3, C11CPU0 ; spio r3, CTPDINI ; #endif ; ; #ifdef CpLocCnt ; mov c10, r1 ; spio r1, CTPCTRL ; mov 0, r1 ; spio r1, CTPDINI ; #endif lgio 0, ADCMSK_DB jmpr cc_busy, 0 lpio GBUSR0, r1 iext ADCMSK ; and write to the register sgio r1, ADCMSK ; so it doesn't need to be extra initialised mvpcr +2, rstack jmp cc_uncond, load_dm_par #endif ; fill the table with min/max values for the slope with -127, 127, -128 is reserved! #ifdef cpu3 mov 0, r1 sra r1, WDOG_DM ; watch dog for too many events WITH tracklets mov 127, r1 ; + 127, upper limit neg r1, r2 ; - 127 mov DEFL_RNG_TBL_DM, r15 mov 19, r3 ; channel counter sra+ r2 nop sra+ r1 sub r3, c1, r3 jmpr cc_nzero, -4 #endif ; 20+3 #ifdef cpu1 ; g1 contains the ChipPos, as well as c14 ; new: calculate the pad_row_col ; pad_row_col = ((ROB# >> 1) << 4) | (MCM# & 0xF) ; MCM# = ChipPOS & 0xF ; ROB# = ChipPOS >> 4) & 0x07 slr 5, ChipPOS, r1 ; ROB# >> 1 and r1, c3, r1 ; take only two bits shl 4, r1, r1 ; (ROB# >> 1) << 4 mov 0xF, r2 and r2, ChipPOS, r2 ; MCM# & 0xF or r1, r2, r6 ; ((ROB# >> 1) << 4) | (MCM# & 0xF) ; now prepare exactly for the MCM header in tracklet mode ; MCM header: from MSBit left (bit 31) to the LSBit ; < 1 | padrow (4 bits) | column (2 bits) | HPID2 (8 bit) | HPID1 (8 bit) | HPID0 (8 bit) | 1 > mov b1_0000_00, r7 or r6, r7, r6 shl 12, r6, r6 shl 13, r6, r6 or r6, c1, r6 ; < 1 | padrow (4 bits) | column (2 bits) | 00..0 (8 bit) | 00..0 (8 bit) | 00..0 (8 bit) | 1 > ; so it is ready to be ORed with the 3x8 bits additional tracklet information iext H_PAD_ROW_COL_DB sgio r6, H_PAD_ROW_COL_DB sra r6, H_PAD_ROW_COL_DM mvpcr +2, rstack jmp cc_uncond, load_direct_adc mvpcr +2, rstack jmp cc_uncond, load_direct_bm_m #ifeq TRACKLETS_MODE, TRACKLETS_TPT_MODE ; init the local counter as PSRG 32-bit mov b111111, r6 ; inc after read, 32 bit, psrg spio r6, CTPCTRL ; the seed (0x80 | ChipPos ) ^ h_0 ^ rot, where ; rot = SCRM_WORD_H << mcm_pos | SCRM_WORD_L >> (16-mcm_pos) mov b1000_0000, r6 ; 1000 0000b or r6, ChipPOS, r6 ; 1rrr mmmmb rrr ROB#, mmmm MCM# xor r6, h_0, r6 iext SCRM_WORD_H mov SCRM_WORD_H, r7 swp r7, r5 iext SCRM_WORD_L mov SCRM_WORD_L, r4 or r4, r5, r5 shl r2, r5, r4 ; SCRM_WORD << MCMpos xor r6, r4, r6 mov 16, r3 sub r2, r3, r2 ; MCMpos - 16 shl r2, r7, r5 ; SCRM_WORD_H << (MCMpos - 16) is the same as SCRM_WORD_H >> (16 - MCMpos) xor r6, r5, r6 ; the final seed word spio r6, CTPDINI #endif ; do we need yoffs ??? #endif #ifdef cpu2 mov TPFE_VAL, r3 iext TPFE sgio r3, TPFE ; restore TPFE mvpcr +2, rstack jmp cc_uncond, load_direct_all mvpcr +2, rstack jmp cc_uncond, load_direct_bm_m mov 0, g15 ; release the other CPUs #else syn #endif ; this part is executed by all MCMs! init_fin: #ifdef cpu3 mov 1, r1 jmpr cc_busy, 0 iext FPCL sgio r1, FPCL ; remove the clear of the pedestal filter jmpr cc_busy, 0 iext FGCL sgio r1, FGCL ; remove the clear of the gain counters #endif ; write the end marker ; put later some special MCM header??? iext NSIG_TR_VAL mov NSIG_TR_VAL, r6 spio r6, NODP jmp cc_uncond, clr_endloop ; only for HCM and BM init_bm_hcm: #ifdef cpu0 mvpcr +2, rstack jmp cc_uncond, load_direct_first_hcm_bm ; uses only r1! #endif mvpcr +2, rstack jmp cc_uncond, init_irq_vec_hcm_bm sem 1 ; wait until cpu0 writes to g0 #ifdef cpu1 ; init the privat counter/timer as counter/up/int/cont - 120MHz mov 0x640, r0 spio r0, CTPCTRL mov 0, r0 spio r0, CTPDINI jmpr cc_busy, 0 iext ADCMSK_DB sgio r0, ADCMSK_DB jmpr cc_busy, 0 iext ADCMSK sgio r0, ADCMSK ; some refresh mvpcr +2, rstack jmp cc_uncond, load_patchm_par #endif #ifdef cpu2 ; init the privat counter/timer as counter/down/int/cont - 120MHz mov 0xA40, r0 spio r0, CTPCTRL mov 11, r0 ; counts 11, 10, ... 0, 11, 10 ..., we have 12 fast clocks in 1 ADC clock spio r0, CTPDINI #endif #ifdef cpu3 ; init the privat counter/timer as counter/up/pre mov 0x700, r0 spio r0, CTPCTRL mov 0, r0 spio r0, CTPDINI #endif #ifdef cpu0 slr 2, r2, r2 ; now the HCM flags are in bits 1..0 mvpcr +4, rstack ; load the return address to the NOP andt r2, c3 ; check bits 1..0 jmp cc_zero, load_direct_bm_m ; when 00 => BM, use the part for normal MCMs and BMs jmp cc_uncond, load_direct_hcm ; when 11 => HCM, use the part for HCM mvpcr +2, rstack jmp cc_uncond, load_direct_all ; init the privat counter/timer as counter/up/L0A mov 0x700, r0 spio r0, CTPCTRL mov 0, r0 spio r0, CTPDINI mov 0, g0 #else syn #endif jmp cc_uncond, init_fin nop