COMMENT * This file is used to generate DSP code for the PCI interface board using a DSP56301 as its main processor. Version 1.7 - Replies to commands with polling only, no interrupts Number of 16-bit pixels returned to host during image readout 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. Version 1.7 as follows: - Slaved READ IMAGE to the controller for the number of pixels to be read, not just the starting time. - Introduced the 'IIA' = Initialize Image Address command sent by the timing board as a reply to the 'SEX' command to set PCI_ADDR = BASE_ADDR at the start of an image instead of having the host computer issue it. - Took out the WRITE_NUMBER_OF_BYTES_IN_IMAGE and INITIALIZE_NUMBER_OF_PIXELS command because the timing board now does this. - Introduced the local variable X:$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 8-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 no reason 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 ; Establish interrupt priority levels IPL MOVEP #$0001C0,X:IPRC ; IRQC priority IPL = 2 (reset switch, edge) ; IRQB priority IPL = 2 or 0 ; (FIFO half full - HF*, level) MOVEP #>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 MOVE X0,X:7,B AND Y0,B ; Extract NWORDS, must be >= 2 CMP #1,B JLE just ignore it ; Check if the command or reply is for the host. If not just ignore it. HOSTCMD MOVE X: Reply with a value MOVE Y0,X: Normal execution MOVE Y0,X: controller error MOVE Y0,X: controller reset MOVE Y0,X: controller busy MOVE Y0,X: 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 ; Pipeline delay 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 ; Pipeline delay 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 2,B ; Increment PCI address MOVE A0,A1 OR #$C70000,A ; Write 16 LS bits only NOP JCLR #EF,X:PDRD,* MOVEP Y:RDFIFO,X:DTXM ; Least significant word to transmit AGAIN3 MOVEP A1,X:DPAR ; Write to PCI bus NOP ; Pipeline delay NOP ; Pipeline delay JCLR #MARQ,X:DPSR,* ; Bit is clear if PCI still in progress JSET #14,X:DPSR,END_WR ; 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 convert byte address to pixel NOP MOVE A0,X: Normal execution MOVE X0,X: Reply with a value MOVE X0,X: Error value MOVE X0,X: System reset MOVE X0,X: Controller is busy MOVE X0,X: error NOP RTS GT_RPLY MOVE Y0,B LSL #16,B ; Shift byte in D7-D0 to D23-D16 NOP MOVE B1,Y1 MOVE Y:RDFIFO,Y0 ; Read the FIFO word MOVE #$00FFFF,B AND Y0,B ; Select out D15-D0 OR Y1,B ; Add D23-D16 to D15-D0 NOP NOP BCLR #0,SR ; Clear carry bit => no error NOP RTS ; This might work with some effort ;GT_RPLY MOVE Y:RDFIFO,B ; Read the FIFO word ; EXTRACTU #$010018,B,B ; INSERT #$008000,Y0,B ; Add MSB to D23-D16 ; NOP ; MOVE B0,B1 ; NOP ; 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 MOVE #$10000,X0 ; Y:$000000 to Y:$FEFFFF MOVE A,R0 DO #$FF,L_WRITE_RAM1 DO X0,L_WRITE_RAM0 MOVE A1,Y:(R0)+ ADD #1,A NOP L_WRITE_RAM0 JSR controller busy MOVE Y1,X: command executing FLAG_DONE DC $000008 ; Flag = 1 => DONE FLAG_REPLY DC $000010 ; Flag = 2 => reply value available FLAG_ERR DC $000018 ; Flag = 3 => error FLAG_SYR DC $000020 ; Flag = 4 => controller reset FLAG_RDI DC $000028 ; Flag = 5 => reading out image FLAG_BUSY DC $000030 ; Flag = 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 NPXLS_1 DC 0 ; # of pxls in current READ_IMAGE call, MS byte NPXLS_0 DC 0 ; # of pxls in current READ_IMAGE, LS 24-bits IPXLS_1 DC 0 ; Down pixel counter in READ_IMAGE, MS byte IPXLS_0 DC 0 ; Down pixel counter in READ_IMAGE, 24-bits R_PXLS_1 DC 0 ; Up Counter of # of pixels read, MS 16-bits R_PXLS_0 DC 0 ; Up Counter of # of pixels read, LS 16-bits BASE_ADDR_1 DC 0 ; Starting PCI address of image, MS byte BASE_ADDR_0 DC 0 ; Starting PCI address of image, LS 24-bits PCI_ADDR_1 DC 0 ; Current PCI address of image, MS byte PCI_ADDR_0 DC 0 ; Current PCI address of image, LS 24-bits REPLY DC 0 ; Reply value HOST_FLAG DC 0 ; Value of host flags written to X:DCTR FO_DEST DC 0 ; Whether host or PCI board receives command FO_CMD DC 0 ; Fiber optic command or reply ; 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 DESTINATION DC 0 ; Derived from header NUM_ARG DC 0 ; Derived from header ; End of program END