;############################################################################## ;# ;# Rudimentary Readout Program for TRAP3 chip ;# ;# Marcus Gutfleisch ;# Universität Heidelberg, Kirchhoff-Institut für Physik ;# ;# Heidelberg, 15.10.2004 ;# ;############################################################################## #inc ;############################################################################## ;# ;# defines ;# ;############################################################################## #def endsig_tr = c14 ; end signature for tracklet readout #def endsig_rr = c15 ; end signature for raw data readout #def nsamples = c13 ; number of ADC samples per pad #def ChipPOS = c8 ; Chip Position for Header #def EventHeader = c9 ; Readout Board Header #def EHchip = 28 ; Evenh Header sending chip #def EventCounter = c12 ; event counter #def NI_tmsn_delay = c11 ; programmable network interface readout delay #def ReadoutFlag = c10 ; bit1: NI readout enable ; bit0: SCSN readout enable #def EvtCtrGIOAdr = 0xC0C ; Address of Event Counter in GIO #def rstack = r8 ; program counter stack (depth=1) #def rio = r14 ; local I/O auto incrementer register #ifdef cpu0 #def clk_onoff = CPU0SS ; own clock #def clk_onoff_next = CPU2SS ; for delayed start of partner CPU #def LSBdata = 0x03 ; LSBs for data transfer words #def ni_counters = 0xF0E0 ; ni parity error and word counters #def IRQHW = IRQHW0 ; #def IRQHL = IRQHL0 ; #endif #ifdef cpu1 #def clk_onoff = CPU1SS; ; own clock #def clk_onoff_next = CPU3SS; ; for delayed start of partner CPU #def LSBdata = 0x02 ; LSBs for data transfer words #def ni_counters = 0xF0E1 ; ni parity error and word counters #def IRQHW = IRQHW1 ; #def IRQHL = IRQHL1 ; #endif #ifdef cpu2 #def clk_onoff = CPU2SS; ; own clock #def LSBdata = 0x03 ; LSBs for data transfer words #def ni_counters = 0xF0E2 ; ni parity error and word counters #def IRQHW = IRQHW2 ; #def IRQHL = IRQHL2 ; #endif #ifdef cpu3 #def clk_onoff = CPU3SS; ; own clock #def LSBdata = 0x02 ; LSBs for data transfer words #def ni_counters = 0xF0E3 ; ni parity error and word counters #def IRQHW = IRQHW3 ; #def IRQHL = IRQHL3 ; #endif ;############################################################################## ;# ;# 0x000: Infinite Loop at Instruction Memory Reset Address ;# ;############################################################################## ORG 0x0; jmpr cc_uncond, 0 nop ;############################################################################## ;# ;# 0x100: Interrupt Clear Jump Address ;# ;############################################################################## ORG 0x100; clr: #ifdef cpu0 iext b1111_0101_0000_0000_0010_0000; mov b1111_0101_0000_0000_0010_0000, r1 jmpr cc_busy, 0 sgio r1, SMOFFON ; switch off all NI LVDS cells, clk_prepr, clk_ni (VA), clk_fil ON #endif #ifdef cpu1 mov cmd_ext_clr, r0 jmpr cc_busy, 0 sgio r0, SMCMD ; clear ready (VA) nop #endif #ifdef cpu2 nop nop nop nop #endif #ifdef cpu3 nop nop nop nop #endif jmpr cc_uncond, 0 nop ;############################################################################## ;# ;# 0x200: Interrupt Tracklet Processing Jump Address ;# ;############################################################################## ORG 0x200; acq: #ifdef cpu0 mov b0000_0010_0000, r1 jmpr cc_busy, 0 sgio r1, SMOFF ; switch off clk_fil #else nop nop nop #endif mov 32, r0 delay: ; wait a while to make sure that GSM and sub r0, c1, r0 ; NI are ready for transmission and state jmp cc_nzero, delay ; transition. ;#ifdef cpu0 ; mov 0xEAD, r0 ; #else mov endsig_tr r0 ; load Tracklet End Signature ;#endif spio r0 NODP ; Send Tracklet End Signature via NI jmpr cc_uncond 0 nop ;############################################################################## ;# ;# 0x400: Interrupt Raw Data Transmission Jump Address ;# ;############################################################################## ORG 0x400 raw: #ifdef cpu0 mov cmd_CPU_done r0 ; CPU0 indicates upcoming data transmission jmpr cc_busy, 0 sgio r0 SMCMD; jmp cc_uncond, continue ; CPU0 fills FIFO immediately #endif #ifdef cpu1 nop nop nop jmp cc_uncond, continue ; CPU1 fills FIFO immediately as well #endif #ifdef cpu2 nop nop nop nop #endif #ifdef cpu3 nop nop nop nop #endif mov 0, r0 ; switch off own clock because jmpr cc_busy, 0 sgio r0, clk_onoff; ; CPU2 and CPU3 are filling their FIFOs delayed. jmpr cc_busy, 0 ; They will be started by CPU0 and CPU 1 later. nop nop nop nop continue: ;############################################## ;# Store Start addresses for SCSN transfer via Databank ;############################################## #ifdef cpu0 ; CPU0 starts at address 0xF000 iext 0xF000 mov 0xF000, rio #endif #ifdef cpu1 ; CPU1 starts at address 0xF040 iext 0xF033 mov 0xF033, rio #endif #ifdef cpu2 ; CPU2 starts at address 0xF080 iext 0xF065 mov 0xF065, rio #endif #ifdef cpu3 ; CPU3 starts at address 0xF0C0 iext 0xF097 mov 0xF097, rio ; end C8 #endif ;############################################## ;# NI transfer event header (CPU0 only) ;############################################## #ifdef cpu0 mov EHchip, r0 ; chip EHchip starts readout tree sequence cmp r0, ChipPOS ; and sends event header jmp cc_nzero, no_event_header shl 2, EventHeader, r0 ; combine event header or r0, c1, r0 ; SOE+"01"+SOE+"01" shl 15, r0, r1 ; where SOE is the 14 bit Start of Event Marker shl 1, r1, r1 or r0, r1, r0 spio r0 NODP ; NI transfer event header jmpr cc_busy, 0 ; SCSN transfer chip header sgio+ r0 #else nop nop nop nop nop nop nop nop nop nop nop #endif no_event_header: swp rio, rio ; swap DBANK address to high word of rio mov ReadoutFlag, r2 ; load NI&SCSN readout flag cmp r2, 0 jmp cc_eq, del_end ; check for transmission flags #ifdef cpu0 shl 15, ChipPOS, r0 ; combine chip header shl 5, r0, r0 ; ChipPOS(8)+EventCounter(20)+"1100" or r0, EventCounter, r0 shl 2, r0, r0 or r0, c3, r0 shl 2, r0, r0 spio r0 NODP ; NI transfer chip header swp rio, rio jmpr cc_busy, 0 ; SCSN transfer chip header sgio+ r0 ; no busy flag check due to large delay swp rio, rio ; till next access #else nop nop nop nop nop nop nop nop nop nop nop #endif mov LSBdata, r7 ; pass the two LSBs for data transmission iext 0xFFFF0000 ; high word mask for Channel switching mov 0xFFFF0000, r15 mov nsamples, r1 ; initially load number of samples cmp r1, 0 jmp cc_nzero, run_tmsn ; check for transmission flags del_end: mov 0x020, r2 ; wait a while to make sure that GSM and no_tmsn_del: ; NI are ready for transmission and state sub r2, c1, r2 ; transition. jmp cc_nzero, no_tmsn_del nop jmp cc_uncond, complete_ni_tmsn nop run_tmsn: ;############################################## ;# NI&SCSN transfer 1st channel ;############################################## mov EBR0, r0 ; address in LIO of the event buffer or r0, rio, rio ; to low word of rio ; mov nsamples,r1 ; number of samples to read (done above) mvpcr +2, rstack jmp cc_uncond, ChTML; ;############################################## ;# NI&SCSN transfer 2nd channel ;############################################## and r15, rio, rio mov EBR1, r0 ; address in LIO of the event buffer or r0, rio, rio ; to low word of rio mov nsamples,r1 ; number of samples to read mvpcr +2, rstack jmp cc_uncond, ChTML; ;############################################## ;# NI&SCSN transfer 3rd channel ;############################################## and r15, rio, rio mov EBR2, r0 ; address in LIO of the event buffer or r0, rio, rio ; to low word of rio mov nsamples,r1 ; number of samples to read mvpcr +2, rstack jmp cc_uncond, ChTML; ;############################################## ;# NI&SCSN transfer 4th channel ;############################################## and r15, rio, rio mov EBR3, r0 ; address in LIO of the event buffer or r0, rio, rio ; to low word of rio mov nsamples,r1 ; number of samples to read mvpcr +2, rstack jmp cc_uncond, ChTML; ;############################################## ;# NI&SCSN transfer 5th channel ;############################################## and r15, rio, rio mov EBR4, r0 ; address in LIO of the event buffer or r0, rio, rio ; to low word of rio mov nsamples,r1 ; number of samples to read mvpcr +2, rstack jmp cc_uncond, ChTML; ;############################################## ;# NI&SCSN transfer 6th channel (CPU3 only) ;############################################## #ifdef cpu3 and r15, rio, rio mov EBR5, r0 ; address in LIO of the event buffer or r0, rio, rio ; to low word of rio mov nsamples,r1 ; number of samples to read mvpcr +2, rstack jmp cc_uncond, ChTML; #else nop nop nop nop nop #endif; ;############################################## ;# Slow down NI transmission if NI_tmsn_delay != 0 ;############################################## complete_ni_tmsn: nop #ifdef cpu3 mov NI_tmsn_delay, r1 ; mov doesn't set the flags! andt r1, r1 jmp cc_zero, end_ni_tmsn cli mov 0x015, r1 mov 0x415, r0 sgio r0, IRQHW jmpr cc_busy, 0 sgio r0, IRQHL jmpr cc_busy, 0 jmp cc_uncond, coff #else nop nop nop nop nop nop nop nop nop nop nop #endif ;############################################## ;# CPU0, CPU1: start CPU2 and CPU3 for delayed transfer ;############################################## end_ni_tmsn: mov 1, r1 #ifdef cpu0 jmpr cc_busy, 0 sgio r1 clk_onoff_next #endif #ifdef cpu1 jmpr cc_busy, 0 sgio r1 clk_onoff_next #endif #ifdef cpu2 nop nop #endif #ifdef cpu3 nop nop #endif ;############################################## ;# CPU3: Increment Event Counter ;############################################## #ifdef cpu3 mov EventCounter, r0 add r0, c1, r0 iext 0x1FFFFF mov 0x1FFFFF, r1 and r1, r0, r0 jmp cc_nzero, EvtCtrOK mov 10, r0 EvtCtrOK: jmpr cc_busy, 0 sgio r0 EvtCtrGIOAdr #else nop nop nop nop nop nop nop nop nop #endif ;############################################## ;# NI&SCSN transfer end marker ;############################################## mov endsig_rr r0 spio r0 NODP swp rio, rio jmpr cc_busy, 0 ; sgio+ r0 swp rio, rio ;############################################## ;# automatically go to clear state if ReadoutFlag=0 ;############################################## ; mov ReadoutFlag, r2 ; load NI&SCSN readout flag ; cmp r2, 0 ; jmp cc_nzero, coff ; check for transmission flags ; ; #ifdef cpu3 ; mov CMD_CLEAR, r0 ; CPU0 indicates upcoming data transmission ; jmpr cc_busy, 0 ; sgio r0 SMCMD; ; #else ; nop ; nop ; nop ; #endif ;############################################## ;# switch off own clock after transfer ;############################################## coff: mov 0, r0 jmpr cc_busy, 0 sgio r0 clk_onoff jmpr cc_busy, 0 nop nop nop nop nop nop nop jmp cc_uncond, coff nop ;############################################################################## ;# ;# NI transmission of one channel ;# ;############################################################################## ;# ;# Interface: ;# ;# Input: r14 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 ;# r2 Readout Flags ;# ;# Output: sends data to the NI output port ;# Modifies: r3, r4, r5, r14, r1 (0) ;# ;############################################################################## ;############################################## ;# BEGIN data transfer loop ChTML: ;############################################## lpio+ r3 ; initial read has to be done twice due to lpio+ r3 ; memory delay (synchronous read) lpio+ r4 lpio rio, r5 shl 10, r5, r5 ; combine three 10 bit data words or r5, r4, r5 ; to one (32=10+10+10+2) bit data word shl 10, r5, r5 or r5, r3, r5 shl 2, r5, r5 or r5, r7, r5 ; set the two LSBs and r2, c2, r2 ; check NI readout flag jmp cc_zero, scsn_readout spio r5, NODP ; write to NI scsn_readout: swp rio, rio ; switch to SCSN storage address sgio+ r5 ; write to DBANK for SCSN reading swp rio, rio ; switch back to event buffer read address sub r1, c3, r1 ; decrease number of words to read jmp cc_gtu, ChTML ; loop xor r7, c1, r7 jmp cc_uncond, rstack ; return from subroutine ;############################################## ;# END data transfer loop ;############################################## nop ;############################################################################## ;# ;# 0x500: Interrupt NI FIFO empty ;# ;############################################################################## ; ORG 0x500 sgio r1, IRQHL jmpr cc_busy, 0 sgio r1, IRQHW jmpr cc_busy, 0 ; program the delay mov NI_tmsn_delay, r1 spio r1, 0x200 mov b1010_0101_1111, r1 ; counter, down, irq spio r1, 0x201 mov b0101_0101, r1 sgio r1, IRQHL jmpr cc_busy, 0 sgio r1, IRQHW jmpr cc_busy, 0 jmp cc_uncond, coff ;############################################################################## ;# ;# 0x600: Interrupt NI FIFO empty ;# ;############################################################################## ; ORG 0x600 ; restore the interrupt mask mov 0x015, r1 sgio r1, IRQHL jmpr cc_busy, 0 sgio r1, IRQHW jmpr cc_busy, 0 ; send end signature jmp cc_uncond, end_ni_tmsn nop