COMMENT * This file is used to generate DSP code for the PCI interface board using a DSP56301 as its main processor. Version 1.6 - Replies to commands with polling only, no interrupts Some Rules - Commands executed only by the PCI board end with a jump to FINISH, FINISH1 or ERROR, since these will assert the reply flags and return from interrupt. Commands passed along to the timing board end only with RTI since the reply from the timing board will generate its own call to FINISH1 or ERROR. PCI -> commands are received as 24-bit words, with Communication of commands and replies over the PCI bus is all at 24 bits per word. PCI address that need to be passed are split into two 16-bit words. CHANGES, February to March 2001 - Get rid of Number of Bytes per pixel in images. Assume 2. - Get rid of $80A7 = read image command. - Process 'RDA' timing board command to start the readout - Jump to error if receiver FIFO is empty on vector commands - Replace GET_FO mess with calls to RD_FO - Implement a timeout on fiber optic words, called RD_FO_TIMEOUT - Number of bytes per image replaces NCOLS x NROWS - Interrupt levels set as folllows - New vector command locations for more order NMI for read PCI image address, reset PCI, abort readout IPL = 2 for reset button, FIFO HF, enabled during readout IPL = 1 for all host commands Host commands disabled during image readout - Host flags = 5 if reading out image - Commands from the PCI host follow the fiber optic protocol, header, command, arg1 - arg4 with command words written to $10020 and then vector $B1 - A BUSY host flag was introduced =6 for the case where a command takes longer than the voodoo TIMEOUT to execute - The non-maskable reboot from EEPROM command = $807B is implemented - RDM and WRM were changed to abide by the timing board convention of embedding the memory type in the address' most significant nibble. This limits memory accesses to 64k on this board. - Eliminate Scatter/Gather image processing in favor of direct FIFO to PCI bus transfers. April 25 - Change PCI write handshaking to MARQ and MDT, eliminating the special writing of 8 pixels at the beginning of each image. * PAGE 132 ; Printronix page width - 132 columns ; Equates to define the X: memory tables VAR_TBL EQU 0 ; Variables and constants table ARG_TBL EQU $30 ; Command arguments and addresses SC_TBL EQU $100 ; Scatter/Gather table TAINTED EQU 0 ; =1 if current block is being read or written N_TABLE EQU 255 ; Number of entries in scatter/gather table NRDFIFO EQU 128 ; Number of 512 pixel chunks in FIFO per ; image block ; Various addressing control registers BCR EQU $FFFFFB ; Bus Control Register DCR EQU $FFFFFA ; DRAM Control Register AAR0 EQU $FFFFF9 ; Address Attribute Register, channel 0 AAR1 EQU $FFFFF8 ; Address Attribute Register, channel 1 AAR2 EQU $FFFFF7 ; Address Attribute Register, channel 2 AAR3 EQU $FFFFF6 ; Address Attribute Register, channel 3 PCTL EQU $FFFFFD ; PLL control register IPRP EQU $FFFFFE ; Interrupt Priority register - Peripheral IPRC EQU $FFFFFF ; Interrupt Priority register - Core ; PCI control register DTXS EQU $FFFFCD ; DSP Slave transmit data FIFO DTXM EQU $FFFFCC ; DSP Master transmit data FIFO DRXR EQU $FFFFCB ; DSP Receive data FIFO DPSR EQU $FFFFCA ; DSP PCI Status Register DSR EQU $FFFFC9 ; DSP Status Register DPAR EQU $FFFFC8 ; DSP PCI Address Register DPMC EQU $FFFFC7 ; DSP PCI Master Control Register DPCR EQU $FFFFC6 ; DSP PCI Control Register DCTR EQU $FFFFC5 ; DSP Control Register ; Port E is the Synchronous Communications Interface (SCI) port PCRE EQU $FFFF9F ; Port Control Register PRRE EQU $FFFF9E ; Port Direction Register PDRE EQU $FFFF9D ; Port Data Register ; Various PCI register bit equates STRQ EQU 1 ; Slave transmit data request (DSR) SRRQ EQU 2 ; Slave receive data request (DSR) HACT EQU 23 ; Host active, low true (DSR) MTRQ EQU 1 ; Set whem master transmitter is not full (DPSR) MARQ EQU 4 ; Master address request (DPSR) TRTY EQU 10 ; PCI Target Retry (DPSR) HCIE EQU 0 ; Host command interrupt enable (DCTR) ; DPCR bit definitions CLRT EQU 14 ; Clear the master transmitter DTXM MACE EQU 18 ; Master access counter enable IAE EQU 21 ; Insert Address Enable ; Addresses of ESSI port TX00 EQU $FFFFBC ; Transmit Data Register 0 SSISR0 EQU $FFFFB7 ; Status Register CRB0 EQU $FFFFB6 ; Control Register B CRA0 EQU $FFFFB5 ; Control Register A ; SSI Control Register A Bit Flags TDE EQU 6 ; Set when transmitter data register is empty ; Miscellaneous addresses RDFIFO EQU $FFFFFF ; Read the FIFO for incoming fiber optic data TCSR0 EQU $FFFF8F ; Triple timer control and status register 0 TCSR1 EQU $FFFF8B ; Triple timer control and status register 1 TCSR2 EQU $FFFF87 ; Triple timer control and status register 2 ; Phase Locked Loop initialization PLL_INIT EQU $750012 ; PLL = 33 MHz x 19 / 8 = 78.4 MHz ; Port C is Enhanced Synchronous Serial Port 0 PCRC EQU $FFFFBF ; Port C Control Register PRRC EQU $FFFFBE ; Port C Data direction Register PDRC EQU $FFFFBD ; Port C GPIO Data Register ; Port D is Enhanced Synchronous Serial Port 1 PCRD EQU $FFFFAF ; Port D Control Register PRRD EQU $FFFFAE ; Port D Data direction Register PDRD EQU $FFFFAD ; Port D GPIO Data Register ; Bit number definitions of GPIO pins on Port D EF EQU 0 ; FIFO Empty flag, low true HF EQU 1 ; FIFO Half Full flag, low true MODE EQU 4 ; 1 for 32-bit reply data, 0 for 16-bit image ; STATUS bit definitions RDI EQU 0 ; Set to start reading an image ODD EQU 1 ; Set if odd number of pixels are in the image ; Special address for two words for the DSP to bootstrap code from the EEPROM IF @SCP("DOWNLOAD","ROM") ; Boot from ROM on power-on ORG P:0,P:0 DC END_ADR-INIT-2 ; Number of boot words DC INIT ; Starting address ORG P:0,P:2 INIT JMP $0000,X:DPMC ; Subsystem ID MOVEP #>$0000,X:DPAR ; Subsystem Vendor ID ; PCI Personal reset MOVEP X0,X:DCTR ; Personal software reset NOP NOP JSET #HACT,X:DSR,* ; Test for personal reset completion MOVE P:(*+3),X0 ; Trick to write "JMP $00001,X:DPMC ; 32-bit PCI <-> 24-bit DSP data BSET #20,X:DCTR ; HI32 mode = 1 => PCI BCLR #21,X:DCTR BCLR #22,X:DCTR NOP JSET #12,X:DPSR,* ; Host data transfer not in progress NOP BSET #MACE,X:DPCR ; Master access counter enable NOP ; End of PCI programming ; Set operation mode register OMR to normal expanded MOVEC #$0000,OMR ; Operating Mode Register = Normal Expanded MOVEC #0,SP ; Reset the Stack Pointer SP ; Move the table of constants from P: space to X: space MOVE #CONSTANTS_TBL_START,R1 ; Start of table of constants MOVE #2,R0 ; Leave X:0 for STATUS DO #CONSTANTS_TBL_LENGTH,L_WRITE MOVE P:(R1)+,X0 MOVE X0,X:(R0)+ ; Write the constants to X: L_WRITE ; Program the serial port ESSI0 = Port C for serial transmission to ; the timing board MOVEP #>0,X:PCRC ; Software reset of ESSI0 MOVEP #$000809,X:CRA0 ; Divide 78.4 MHz by 20 to get 3.92 MHz ; DC0-CD4 = 0 for non-network operation ; WL0-WL2 = ALC = 0 for 2-bit data words ; SSC1 = 0 for SC1 not used MOVEP #$010120,X:CRB0 ; SCKD = 1 for internally generated clock ; SHFD = 0 for MSB shifted first ; CKP = 0 for rising clock edge transitions ; TE0 = 1 to enable transmitter #0 ; MOD = 0 for normal, non-networked mode ; FSL1 = 1, FSL0 = 0 for on-demand transmit MOVEP #%101000,X:PCRC ; Control Register (0 for GPIO, 1 for ESSI) ; Set SCK0 = P3, STD0 = P5 to ESSI0 MOVEP #%010111,X:PRRC ; Data Direction Register (0 for In, 1 for Out) MOVEP #%000101,X:PDRC ; Data Register - ROM/FIFO* = 0, SC02 = 0, ; AUX1 = 0, AUX2 = AUX3 = 1 ; Conversion from software bits to schematic labels for Port C and D ; PC0 = SC00 = AUX3 PD0 = SC10 = EF* ; PC1 = SC01 = ROM/FIFO* PD1 = SC11 = HF* ; PC2 = SC02 = AUX2 PD2 = SC12 = RS* ; PC3 = SCK0 = Serial clock PD3 = SCK1 = FSYNC* ; PC4 = SRD0 = AUX1 PD4 = SRD1 = MODE ; PC5 = STD0 = Serial data PD5 = STD1 = WRFIFO* ; Program the serial port ESSI1 = Port D for general purpose I/O (GPIO) MOVEP #%000000,X:PCRD ; Control Register (0 for GPIO, 1 for ESSI) MOVEP #%010100,X:PRRD ; Data Direction Register (0 for In, 1 for Out) MOVEP #%010000,X:PDRD ; Data Register - Pulse RS* low, MODE = 1 REP #10 NOP MOVEP #%010100,X:PDRD ; Program the SCI port to benign values MOVEP #%000,X:PCRE ; Port Control Register = GPIO MOVEP #%110,X:PRRE ; Port Direction Register (0 = Input) MOVEP #%110,X:PDRE ; Port Data Register ; PE0 = RXD ; PE1 = TXD ; PE2 = SCLK ; Program the triple timer to assert TCI0 as a GPIO output = 1 MOVEP #$2800,X:TCSR0 MOVEP #$2800,X:TCSR1 MOVEP #$2800,X:TCSR2 ; Program the AA1 pin to read the FIFO memory for incoming timing board data MOVEP #$FFFC21,X:AAR1 ; Y = $FFF000 to $FFFFFF asserts AA1 low true ; Program the DRAM memory access and addressing MOVEP #$000020,X:BCR ; Bus Control Register MOVEP #$893A05,X:DCR ; DRAM Control Register MOVEP #$000122,X:AAR2 ; Y: $000000 to $7FFFFF asserts AA2 MOVEP #$800122,X:AAR0 ; Y: $800000 to $FFFFFF asserts AA0 MOVEP #$000112,X:AAR3 ; X: $000000 to $7FFFFF asserts AA3 ; Clear all PCI error conditions MOVEP X:DPSR,A OR #$1FE,A NOP MOVEP A,X:DPSR ; Only initialize STATUS and REPLY if booting from ROM after power-up IF @SCP("DOWNLOAD","ROM") MOVE A,X:2,X:IPRP ; Enable PCI Host interrupts, IPL = 1 BSET #HCIE,X:DCTR ; Enable host command interrupts MOVE #0,SR ; Don't mask any interrupts ; Initialize the fiber optic serial transmitter to zero JCLR #TDE,X:SSISR0,* MOVEP #$000000,X:TX00 ; Clear out the PCI receiver and transmitter FIFOs BSET #CLRT,X:DPCR ; Clear the master transmitter JSET #CLRT,X:DPCR,* ; Wait for the clearing to be complete CLR0 JCLR #SRRQ,X:DSR,CLR1 ; Wait for the receiver to be empty MOVEP X:DRXR,X0 ; Read receiver to empty it NOP JMP Normal execution JSR Normal execution JSR 7,A AND X0,A ; Extract NWORDS, must be >= 2 CMP #1,A JLE Reply with a value JSR Normal execution JSR controller error JSR controller reset JSR controller busy JSR clear the FIFO FO_ERR MOVEP #%010000,X:PDRD ; Clear FIFO RESET* for 2 milliseconds MOVE #200000,Y0 DO Y0,*+3 NOP MOVEP #%010100,X:PDRD ; Data Register - Set RS* high JMP 7,A AND X0,A ; Extract NUM_ARG, must be >= 0 NOP ; Pipeline restriction SUB #2,A JLT = 0 MOVE A1,X:3,A ; Extract just three bits of MOVE A1,X: PCI bus L_FIFO CLR A MOVE X: 32-bit PCI writes EXTRACTU #$010000,B,A NOP MOVE A0,A1 OR #$070000,A ; A1 gets written to DPAR register NOP MOVEP Y:RDFIFO,X:DTXM ; Least significant word to transmit MOVEP Y:RDFIFO,X:DTXM ; Most significant word to transmit AGAIN1 MOVEP A1,X:DPAR ; Write to PCI bus NOP ; Pipeline delay NOP JCLR #MARQ,X:DPSR,* ; Bit is clear if PCI still in progress JSET #14,X:DPSR,WR_OK1 ; MDT bit JCLR #TRTY,X:DPSR,END_WR ; Error if its not a retry MOVEP #$0400,X:DPSR ; Clear bit 10 = target retry bit JMP 32-bit PCI writes EXTRACTU #$010000,B,A NOP MOVE A0,A1 OR #$070000,A ; A1 gets written to DPAR register NOP JCLR #EF,X:PDRD,* MOVEP Y:RDFIFO,X:DTXM ; Least significant word to transmit JCLR #EF,X:PDRD,* MOVEP Y:RDFIFO,X:DTXM ; Most significant word to transmit AGAIN2 MOVEP A1,X:DPAR ; Write to PCI bus NOP ; Pipeline delay NOP JCLR #MARQ,X:DPSR,* ; Bit is clear if PCI still in progress JSET #14,X:DPSR,WR_OK2 ; MDT bit JCLR #TRTY,X:DPSR,END_WR ; Bit is set if its a retry MOVEP #$0400,X:DPSR ; Clear bit 10 = target retry bit JMP Normal execution JSR Reply with a value JSR Error value JSR System reset JSR Controller is busy JSR error NOP RTS GT_RPLY MOVE X0,A LSL #16,A ; Shift byte in D7-D0 to D23-D16 NOP MOVE A1,X1 MOVE Y:RDFIFO,X0 ; Read the FIFO word MOVE #$00FFFF,A AND X0,A ; Select out D15-D0 OR X1,A ; Add D23-D16 to D15-D0 NOP BCLR #0,SR ; Clear carry bit => no error NOP RTS ; ************************ Test on board DRAM *********************** ; Test Y: memory mapped to AA0 and AA2 from $000000 to $FFFFFF (16 megapixels) ; DRAM definitions TEST_DRAM ; Test Y: memory mapped to AA0 and AA2 from $000000 to $FFFFFF (16 megapixels) CLR A NOP MOVE A,R0 MOVE #$FF0000,Y0 ; Y:$000000 to Y:$FEFFFF DO Y0,L_WRITE_RAM0 MOVE A1,Y:(R0)+ ADD #1,A NOP L_WRITE_RAM0 CLR A NOP MOVE A,R0 MOVE #$FF0000,Y0 DO Y0,L_CHECK_RAM0 MOVE Y:(R0)+,X0 CMPU X0,A JEQ DONE FLAGS_REPLY DC $000010 ; Flags = 2 => reply value available FLAGS_ERR DC $000018 ; Flags = 3 => error FLAGS_SYR DC $000020 ; Flags = 4 => controller reset FLAGS_RDI DC $000028 ; Flags = 5 => reading out image FLAGS_BUSY DC $000030 ; Flags = 6 => controller is busy C512 DC 512 ; 1/2 the FIFO size C00FF00 DC $00FF00 C000202 DC $000202 ; Timing board header TRM_MEM DC 0 ; Test DRAM, memory type of failure TRM_ADR DC 0 ; Test DRAM, address of failure ; Tack the length of the variable table onto the length of code to be booted CONSTANTS_TBL_LENGTH EQU @CVS(P,*-ONE) ; Length of variable table ; Ending address of program so its length can be calculated for bootstrapping ; The constants defined after this are NOT initialized, so need not be ; downloaded. END_ADR EQU @LCV(L) ; End address of P: code written to ROM ; Miscellaneous variables SV_A DC 0 ; Place for saving accumulator A IPXLS_1 DC 0 ; Down Counter of number of pixels read, MSbyte IPXLS_0 DC 0 ; Down Counter of number of pixels read. LSW BASE_ADDR_1 DC 0 ; Starting PCI address of image, MSW BASE_ADDR_0 DC 0 ; Starting PCI address of image, LSW PCI_ADDR_1 DC 0 ; PCI image address being written to, MSByte PCI_ADDR_0 DC 0 ; PCI image address being written to, LSW NBYTES_1 DC 0 ; Number of bytes in image, MSbyte NBYTES_0 DC 0 ; Number of bytes in image, LSW REPLY DC 0 ; Reply value ; Check that the parameter table is not too big IF @CVS(N,*)>=ARG_TBL WARN 'The parameter table is too big!' ENDIF ORG X:ARG_TBL,P: ; Table that contains the header, command and its arguments HEADER DC 0 ; (Source, Destination, Number of words) COMMAND DC 0 ; Manual command ARG1 DC 0 ; First command argument ARG2 DC 0 ; Second command argument ARG3 DC 0 ; Third command argument ARG4 DC 0 ; Fourth command argument DESTINATION DC 0 ; Derived from header NUM_ARG DC 0 ; Derived from header ; Check that the parameter table is not too big IF @CVS(N,*)>=SC_TBL WARN 'The argument table is too big!' ENDIF ; End of program END