COMMENT * This file is used to generate boot DSP code for the utility board. This is Rev. 3.00 software for use with the timII board. * PAGE 132 ; Printronix page width - 132 columns ; Define some useful DSP register locations RST_ISR EQU $00 ; Hardware reset interrupt ROM_ID EQU $06 ; Location of ROM Identification words = SWI interrupt IRQA_ISR EQU $08 ; Address of ISRA for 1 kHz timer interrupts SSI_ISR EQU $0C ; SSI serial receiver interrupt address SSI_ERR EQU $0E ; SSI interrupt with exception (error) START EQU $10 ; Address for beginning of code BUF_STR EQU $80 ; Starting address of buffers in X: BUF_LEN EQU $20 ; Length of each buffer SSI_BUF EQU BUF_STR ; Starting address of SSI buffer in X: COM_BUF EQU SSI_BUF+BUF_LEN ; Starting address of command buffer in X: COM_TBL EQU COM_BUF+BUF_LEN ; Starting address of command table in X: NUM_COM EQU 24 ; Number of entries in the command table TIMEOUT EQU 1666 ; Timeout for receiving complete command = 1 millisec APL_ADR EQU $90 ; Starting address of application program APL_XY EQU $1EE0 ; Start of application data tables RST_OFF EQU $6000 ; Reset code offset in EEPROM P_OFF EQU $6040 ; P: memory offset into EEPROM X_OFF EQU $6100 ; X: memory offset into EEPROM ROM_EXE EQU $6200 ; P: start address for routines that execute from EEPROM DLY_MUX EQU 70 ; Number of DSP cycles to delay for MUX settling DLY_AD EQU 100 ; Number of DSP cycles to delay for A/D settling ; Now assign a bunch of addresses to on-chip functions BCR EQU $FFFE ; Bus (=Port A) Control Register -> Wait States PBC EQU $FFE0 ; Port B Control Register PBDDR EQU $FFE2 ; Port B Data Direction Register PBD EQU $FFE4 ; Port B Data Register PCC EQU $FFE1 ; Port C Control Register PCDDR EQU $FFE5 ; PortC Data Direction Register IPR EQU $FFFF ; Interrupt Priority Register SSITX EQU $FFEF ; SSI Transmit and Receive data register SSIRX EQU $FFEF ; SSI Transmit and Receive data register SSISR EQU $FFEE ; SSI Status Register CRA EQU $FFEC ; SSI Control Register A CRB EQU $FFED ; SSI Control Register B SSI_TDE EQU 6 ; SSI Transmitter data register empty SSI_RDF EQU 7 ; SSI Receiver data register full ; Addresses of memory mapped components in Y: data memory space ; Write addresses first WR_DIG EQU $FFF0 ; Write Digital output values D00-D15 WR_MUX EQU $FFF1 ; Select MUX connected to A/D input - one of 16 EN_DIG EQU $FFF2 ; Enable digital outputs WR_DAC3 EQU $FFF7 ; Write to DAC#3 D00-D11 WR_DAC2 EQU $FFF6 ; Write to DAC#2 D00-D11 WR_DAC1 EQU $FFF5 ; Write to DAC#1 D00-D11 WR_DAC0 EQU $FFF4 ; Write to DAC#0 D00-D11 ; Read addresses next RD_DIG EQU $FFF0 ; Read Digital input values D00-D15 STR_ADC EQU $FFF1 ; Start ADC conversion, ignore data RD_ADC EQU $FFF2 ; Read A/D converter value D00-D11 WATCH EQU $FFF7 ; Watch dog timer - tell it that DSP is alive ; Bit definitions of STATUS word ST_SRVC EQU 0 ; Set if SERVICE routine needs executing ST_EX EQU 1 ; Set if timed exposure is in progress ST_SH EQU 2 ; Set if shutter is open ST_READ EQU 3 ; Set if a readout needs to be initiated ; Bit definitions of software OPTIONS word OPT_SH EQU 0 ; Set to open and close shutter ; Bit definitions of Port B = Host Processor Interface HVEN EQU 0 ; Enable high voltage PS (+32V nominal) - Output LVEN EQU 1 ; Enable low voltage PS (+/-15 volt nominal) - Output PWRST EQU 2 ; Reset power conditioner counter - Output SHUTTER EQU 3 ; Control shutter - Output IRQ_T EQU 4 ; Request interrupt service from timing board - Output SYS_RST EQU 5 ; Reset entire system - Output WATCH_T EQU 8 ; Processed watchdog signal from timing board - Input PWREN EQU 9 ; Enable power conditioner board - Output ;************************************************************************** ; * ; Register assignments * ; R1 - Address of SSI receiver contents * ; R2 - Address of processed SSI receiver contents * ; R3 - Pointer to current top of command buffer * ; R4 - Pointer to processed contents of command buffer * ; N4 - Address for internal jumps after receiving 'DON' replies * ; R0, R5, R6, A, X0, and X1 - Freely available for program use * ; B, Y0, and Y1 - For use by timer ISR only * ; * ;************************************************************************** ; Initialize the DSP. Because this is executed only on DSP boot from ROM ; it is not incorporated into any download code. ORG P:RST_OFF,P:RST_OFF MOVEC #$02,OMR ; Normal expanded mode NOP ; Allow time for the remapping to occur JMP INIT ; DSP resets to $E000, but we load program ; to EEPROM starting at RST_OFF = $6000 INIT MOVEP #$003F,X:PBD ; Power enables off, shutter high ; (closed), IRQA, SYSRST ; LVEN = HVEN = 1 => all power off MOVEP #$003F,X:PBDDR ; H0 - H5 Outputs, H6 - H9 Inputs ORI #$03,MR ; Temporarily mask interrupts MOVEP #$6000,X:CRA ; SSI programming - no prescaling; ; 24 bits/word; on-demand communications; ; no prescale; 5.0 MHz serial clock rate MOVEP #$BD20,X:CRB ; SSI programming - OF0, OF1 don't apply; ; SC0, SC1, SC2 are inputs; SCK is output; ; shift MSB first; rcv and xmt asynchronous ; wrt each other; gated clock; bit frame ; sync; network mode to get on-demand; ; RCV and its interrupts enabled; TX enabled, ; TX interrrupts disabled. MOVEP #$01C8,X:PCC ; Port C implemented as enabling the SSI ; function of STD, SRD, SCK, and SC0. MOVEP #$0000,X:PCDDR ; Data Direction register = all inputs. MOVEP #$0033,X:BCR ; Wait states for external memory accesses ; 2 for PROM = 150 nsec ; 2 for A/D, DAC, etc. = 150 nsec ; Load boot program into P: memory from EEPROM MOVE #P_OFF,R0 ; Starting P: address in EEPROM MOVE #0,R1 ; Put values starting at beginning of P: DO #APL_ADR+2,P_MOVE ; Boot program is APL_ADR words long ; +2 is for SERVICE and TIMER stubs MOVE P:(R0)+,A ; Get one word from EEPROM MOVE A,P:(R1)+ ; Write it to DSP P: memory P_MOVE ; Load X: data memory from EEPROM MOVE #X_OFF,R0 ; Starting X: address in EEPROM MOVE #0,R1 ; Put values starting at beginning of X: DO #$100,X_MOVE ; Assume 256 = $100 values exist MOVE P:(R0)+,A ; Get one word from EEPROM MOVE A,X:(R1)+ ; Write it to DSP X: memory X_MOVE ; Initialize various registers MOVE #SSI_BUF,R1 MOVE #COM_BUF,R3 MOVE R1,R2 MOVE R3,R4 MOVE #31,M1 ; Create circular buffers, modulo 32 MOVE M1,M2 MOVE M2,M3 MOVE M3,M4 MOVE # #DBRDID, so error ; Check the transmitter buffer for commands to send to the timing board XMT_CHK MOVE R3,A MOVE R4,X0 CMP X0,A ; R4 is incremented below JEQ 7,A1 ; Extract the 3 LS bits AND X0,A ; X0 = NWORDS in command DO A1,SSI_XMT SSI_WT2 JCLR #SSI_TDE,X:SSISR,SSI_WT2 ; SSI XMT register must be empty MOVEP X:(R4)+,X:SSITX ; Write to SSI buffer SSI_XMT JMP APL_ADR WARN 'Internal P: memory overflow!' ; Make sure application code ENDIF ; will not be overwritten ; Specify the memory location where the application program is to be loaded ORG P:APL_ADR,P:APL_ADR+P_OFF ; Define TIMER as a simple jump addresses so the "bootrom" program ; can work until the application program can be loaded SERVICE RTS ; Just return from subroutine call TIMER RTI ; Just return from interrupt ; The following boot routines execute directly from EEPROM, one 24-bit word ; at a time. Two reasons for this - to conserve DSP P: space, and to allow ; reading or writing to EEPROM space that overlaps with the P: internal ; DSP memory space. ORG P:ROM_EXE,P:ROM_EXE ; Test Data Link - simply return value received after 'TDL' TDL MOVE X:(R4)+,X0 ; Get data value JMP = $200 then its an EEPROM write CMP X0,A ; and a delay 10 milliseconds is needed MOVE X1,P:(R0) ; Write to Program memory JLE