$OPTIMIZE(2) LARGE DEBUG NOINTVECTOR NOOVERFLOW TYPE MOD186 $NOCODE NOXREF NOSYMBOLS PAGEWIDTH(80) /*============================================================*/ $TITLE ('DCAM.PLM DWG:636-620 REV: -') /*-------------------------------------------------------------- NAME: Tethered Camera Camera Control Firmware REVISIONS: --REV-- --DATE-- --AUTHOR-- --DESCRIPTION-- - 03/11/92 JEM PRODUCTION BASELINE ==============================================================*/ DCAM: DO; $INCLUDE (DLIT.INC) $INCLUDE (DMAS.INC) $INCLUDE (DSYS.INC) $INCLUDE (DPNL.INC) $INCLUDE (DVID.INC) DCL BOARD_ID LIT '4'; /* Register definitions */ DCL ID_ATN_REG LIT 'REG(1)'; DCL INTEG_REG LIT 'REG(2)'; DCL MODE_REG LIT 'REG(3)'; DCL CCD_REG LIT 'REG(4)'; DCL PIXSUM_REG LIT 'REG(5)'; DCL FIFO_FLAG_REG LIT 'REG(6)'; DCL CAM_PWR_REG LIT 'REG(7)'; DCL CAM_BUS LIT 'REG(8)'; DCL VER_POS_REG LIT 'REG(9)'; DCL SKIPA_REG LIT 'REG(10)'; DCL DARK_REG LIT 'REG(11)'; DCL SKIPB_REG LIT 'REG(12)'; DCL IMAGE_REG WORD AT(@REG(13)); /* ID Control Codes */ DCL ID_OFF LIT '0000B'; DCL ID_SND LIT '1100B'; DCL HOR_SIZE LIT '1280'; DCL VER_SIZE LIT '1024'; DCL MIN_FLUSH_TIME LIT '400000'; DCL MAX_TRANSFER_TIME LIT '1000000'; DCL MAX_BUS_WAIT_TIME LIT '10000000'; DCL MAX_INTEGRATE_TIME LIT '16000000'; DCL MAX_WIND_TIME LIT '2000000'; DCL LONG_SHUTTER_TIME LIT '250000'; DCL CAMERA_OFF_TIME LIT '5000000'; /* Horizontal modes */ DCL IDLE LIT '0'; DCL TRANS LIT '1'; DCL FLUSH LIT '4'; /* Vertical Positions */ DCL SKIPA LIT '1'; DCL DARK LIT '3'; DCL SKIPB LIT '6'; DCL IMAGE LIT '4'; DCL DONE LIT '5'; DCL CDARK LIT '7'; /* Winder modes */ DCL SINGLE LIT '1'; DCL SLOW LIT '2'; DCL FAST LIT '3'; /* Variables */ DCL ACQUIRE BYTE; DCL CAM_PRESENT BYTE; DCL CAM_BODY_ON BYTE; DCL CAM_BACK_ON BYTE; DCL DARK_DISABLE BYTE; DCL MY_SLOT BYTE; DCL MT BYTE; DCL I WORD; DCL TEST_STEP BYTE; DCL BLACK_LEVEL BYTE; DCL ROM_DATA_WRITE BYTE; DCL ROM_DATA_READ BYTE; DCL ROM_KEY LIT '0AA55H'; DCL ROM_DATA (256) WORD; DCL ROM STRUCTURE (CHECKSUM WORD, KEY WORD, SERIAL_NO DWORD, COLOR BYTE, RESERVE (5) BYTE, BAD_COLUMNS BYTE, BAD_POINTS BYTE, COLUMN (16) WORD, POINT (64) STRUCTURE (H WORD, V WORD), COLUMN_GAIN (16) BYTE, POINT_GAIN (64) BYTE) AT (@ROM_DATA); DCL ROM_R_DATA (256) WORD; DCL ROM_R STRUCTURE (CHECKSUM WORD, KEY WORD, SERIAL_NO DWORD, COLOR BYTE, RESERVE (5) BYTE, BAD_COLUMNS BYTE, BAD_POINTS BYTE, COLUMN (16) WORD, POINT (64) STRUCTURE (H WORD, V WORD), COLUMN_GAIN (16) BYTE, POINT_GAIN (64) BYTE) AT (@ROM_R_DATA); DCL ROM_W_DATA (256) WORD; DCL ROM_W STRUCTURE (CHECKSUM WORD, KEY WORD, SERIAL_NO DWORD, COLOR BYTE, RESERVE (5) BYTE, BAD_COLUMNS BYTE, BAD_POINTS BYTE, COLUMN (16) WORD, POINT (64) STRUCTURE (H WORD, V WORD), COLUMN_GAIN (16) BYTE, POINT_GAIN (64) BYTE) AT (@ROM_W_DATA); /*------------------------------------------------------------*/ CAMERA_SERIAL_NUMBER: PROCEDURE WORD PUBLIC; RETURN LOW (ROM.SERIAL_NO); END; /*------------------------------------------------------------*/ CAMERA_TASK: PROCEDURE PUBLIC; DCL N BYTE; CUR_SLOT,MY_SLOT = FIND_BOARD (BOARD_ID); SLOT = CUR_SLOT; IF MY_SLOT = 255 THEN CALL WAIT (NEVER); X = WAIT_FLAG (FLAG_RUN,TRUE,NEVER); IF WAIT_FLAG (FLAG_COLD_START,TRUE,0) THEN DO; CAM_PRESENT = FALSE; ROM.SERIAL_NO = 0; ROM.COLOR = TRUE; ROM.BAD_COLUMNS,ROM.BAD_POINTS = 0; END; CALL INITIALIZE; DO FOREVER; IF NOT CAM_PRESENT THEN DO; /* Cycle power to camera */ IF CAM_PWR_REG = 1 THEN DO; CAM_PWR_REG = 0; CALL WAIT (1500000); END; CAM_PWR_REG = 1; END; N = 0; DO WHILE (NOT CAMERA_OK) AND (N < 10); N = N + 1; CALL SLEEP (50000); END; CALL INITIALIZE_CAMERA; CALL IDENTIFY_CAMERA; DO WHILE CAMERA_OK; CAM_PRESENT = TRUE; IF ACQUIRE OR EXT_ACQUIRE OR BUTTON_SOFT THEN IF NOT CAMERA_WOUND THEN DO; IF C.CAMERA_WIND > OFF THEN DO; CALL CAMERA_MOTOR_MED; CALL WAIT (MAX_WIND_TIME); CALL CAMERA_MOTOR_OFF; END; END; ELSE DO; CALL CAMERA_BACK_ON; CALL CAMERA_BODY_ON; CALL CAMERA_SOFT_ON; DARK_DISABLE = FALSE; CALL START_FLUSH; CALL WAIT (MIN_FLUSH_TIME); CALL TIMER (MT,CAMERA_OFF_TIME); DO WHILE NOT TIMEOUT (MT); CALL WAIT (5000); CALL DISPLAYS_ON; IF BUTTON_SOFT THEN CALL TIMER (MT,CAMERA_OFF_TIME); IF (BUTTON_HARD OR EXT_ACQUIRE OR ACQUIRE) AND CAMERA_WOUND THEN DO; IF INHIBIT_CAPTURE OR NOT BATTERY_OK THEN DO; CALL DISP_TEXT (16,8,@('LowBatt ')); IF ASSIGN_BUS (1000000) THEN DO; CALL STOP_VIDEO; CALL RELEASE_BUS; END; CALL WAIT (3000000); INHIBIT_CAPTURE = TRUE; END; ELSE DO; I = NEW_IMAGE_ID (HOR_SIZE,VER_SIZE,ROM.COLOR); IF I = 0 THEN DO; CALL SET_FLAG (FLAG_FINISH,TRUE); CALL WAIT (500000); END; ELSE DO; /* Release shutter */ CALL START_INTEGRATION; CALL CAMERA_HARD_ON; CALL TIMER (MT,MAX_INTEGRATE_TIME); DO WHILE CAMERA_WOUND AND NOT TIMEOUT (MT); CALL WAIT (10000); END; CALL CAMERA_SOFT_ON; IF C.CAMERA_WIND = FAST THEN CALL CAMERA_MOTOR_FAST; IF ASSIGN_BUS (MAX_BUS_WAIT_TIME) THEN DO; CALL WAIT (10000); IF TIMER_TIME (MT) > LONG_SHUTTER_TIME THEN CALL WAIT (20000); CALL ENABLE_MEMORY_WRITE (ACQUIRE_ADDRESS (I)); CALL IMAGE_XFER; CALL DISABLE_MEMORY; CALL START_FLUSH; CALL RELEASE_BUS; CALL ACQUIRE_COMPLETE (I); ACQUIRE = FALSE; IF (NOT (BUTTON_HARD OR EXT_ACQUIRE)) OR (C.CAMERA_WIND = OFF) OR (C.CAMERA_WIND = SINGLE) THEN CALL SET_FLAG (FLAG_FINISH,TRUE); END; ELSE DO; CALL START_FLUSH; CALL ACQUIRE_ABORT (I); END; IF C.CAMERA_WIND = SINGLE THEN DO; DO WHILE BUTTON_HARD OR EXT_ACQUIRE; CALL WAIT (10000); END; CALL CAMERA_MOTOR_MED; END; IF C.CAMERA_WIND = SLOW THEN CALL CAMERA_MOTOR_MED; CALL TIMER (MT,MAX_WIND_TIME); DO WHILE NOT (CAMERA_WOUND OR TIMEOUT (MT)); CALL WAIT (10000); END; CALL CAMERA_MOTOR_OFF; CALL TIMER (MT,CAMERA_OFF_TIME); END; END; END; ELSE CALL SET_FLAG (FLAG_FINISH,TRUE); END; CALL CAMERA_BACK_OFF; CALL CAMERA_BODY_OFF; CALL CAMERA_SOFT_OFF; INHIBIT_CAPTURE = FALSE; END; IF ROM_DATA_WRITE THEN DO; CALL LOG_EVENT (@('Program ROM '),ROM_W.SERIAL_NO); CALL DISP_TEXT (16,8,@('PROGRAM ')); CALL CAMERA_BACK_ON; CALL WRITE_BACK_MEMORY; ROM_DATA_WRITE = FALSE; CALL CAMERA_BACK_OFF; CALL DISP_TEXT (16,8,@(' ')); END; IF ROM_DATA_READ THEN DO; CALL CAMERA_BACK_ON; CALL READ_BACK_MEMORY; ROM_DATA_READ = FALSE; CALL CAMERA_BACK_OFF; END; CALL CAMERA_SLEEP; CALL SLEEP (20000); CALL INITIALIZE_CAMERA; IF TEST_STEP THEN DO; TEST_STEP = FALSE; CALL CAMERA_BACK_ON; CALL CAMERA_BODY_ON; CALL CAMERA_SOFT_ON; DARK_DISABLE = TRUE; DO WHILE NOT BUTTON_SOFT; DARK_DISABLE = NOT DARK_DISABLE; CALL START_FLUSH; IF DARK_DISABLE THEN CALL DISP_TEXT (16,8,@('Flush ')); ELSE CALL DISP_TEXT (16,8,@('FlushDrk')); DO WHILE NOT (TEST_STEP OR BUTTON_SOFT); CALL WAIT (30000); END; TEST_STEP = FALSE; END; DARK_DISABLE = FALSE; CALL CAMERA_BACK_OFF; CALL CAMERA_BODY_OFF; CALL CAMERA_SOFT_OFF; CALL DISP_TEXT (16,8,@('Ready! ')); END; END; CAM_PRESENT = FALSE; END; END; /*------------------------------------------------------------*/ ACQUIRE_ONCE: PROCEDURE PUBLIC; ACQUIRE = TRUE; END; /*------------------------------------------------------------*/ INITIALIZE: PROCEDURE; MT = ASSIGN_TIMER; ACQUIRE = FALSE; CAM_BODY_ON = FALSE; DARK_DISABLE = FALSE; ID_ATN_REG = ID_SND; ID_ATN_REG = ID_OFF; INTEG_REG = 01B; MODE_REG = IDLE; TEST_STEP = FALSE; BLACK_LEVEL = 0; ROM_DATA_WRITE = FALSE; END; /*------------------------------------------------------------*/ INITIALIZE_CAMERA: PROCEDURE; CAM_BUS = 00000000B; CAM_BUS = 00000000B; CAM_BUS = 00000000B; CAM_BUS = 01010000B; CAM_BUS = 01010000B; CAM_BACK_ON = FALSE; END; /*------------------------------------------------------------*/ IDENTIFY_CAMERA: PROCEDURE; CAM_BUS = 00110001B; CAM_BUS = 00110001B; CAM_BUS = 00110001B; CAM_BUS = 00110001B; CAM_BUS = 00110001B; IF CAM_BUS = 00110001B THEN DO; CALL WAIT (150000); CAM_BUS = 10000000B; CALL READ_BACK_MEMORY; END; CAM_BUS = 00000000B; CAM_BACK_ON = FALSE; END; /*------------------------------------------------------------*/ CAMERA_TEST: PROCEDURE PUBLIC; TEST_STEP = TRUE; END; /*------------------------------------------------------------*/ CAMERA_COLOR: PROCEDURE BYTE PUBLIC; RETURN ROM.COLOR; END; /*------------------------------------------------------------*/ CAMERA_PRESENT: PROCEDURE BYTE PUBLIC; RETURN CAM_PRESENT; END; /*------------------------------------------------------------*/ CAMERA_ON: PROCEDURE BYTE PUBLIC; RETURN CAM_PRESENT AND CAM_BACK_ON; END; /*------------------------------------------------------------*/ CAMERA_BLACK_LEVEL: PROCEDURE BYTE PUBLIC; RETURN BLACK_LEVEL; END; /*------------------------------------------------------------*/ CAMERA_OFF: PROCEDURE PUBLIC; CUR_SLOT = MY_SLOT; SLOT = CUR_SLOT; INTEG_REG = 01B; CAM_BUS = 01010000B; CAM_BUS = 00000001B; CAM_PWR_REG = 0; CAM_BACK_ON = FALSE; END; /*------------------------------------------------------------*/ CAMERA_SLEEP: PROCEDURE; CAM_BUS = 00000001B; CAM_BACK_ON = FALSE; END; /*------------------------------------------------------------*/ CAMERA_BODY_ON: PROCEDURE; CAM_BODY_ON = TRUE; X = CAMERA_BUS (01010001B); END; /*------------------------------------------------------------*/ CAMERA_BODY_OFF: PROCEDURE; CAM_BODY_ON = FALSE; X = CAMERA_BUS (01010000B); END; /*------------------------------------------------------------*/ CAMERA_HARD_ON: PROCEDURE; X = CAMERA_BUS (01110011B); X = CAMERA_BUS (01010000B OR (00000001B AND CAM_BODY_ON)); END; /*------------------------------------------------------------*/ CAMERA_SOFT_ON: PROCEDURE; X = CAMERA_BUS (01110010B); X = CAMERA_BUS (01010000B OR (00000001B AND CAM_BODY_ON)); END; /*------------------------------------------------------------*/ CAMERA_SOFT_OFF: PROCEDURE; X = CAMERA_BUS (01110000B); X = CAMERA_BUS (01010000B OR (00000001B AND CAM_BODY_ON)); END; /*------------------------------------------------------------*/ BUTTON_HARD: PROCEDURE BYTE; RETURN (CAMERA_BUS (11100000B) AND 00000001B) = 00000001B; END; /*------------------------------------------------------------*/ BUTTON_SOFT: PROCEDURE BYTE; RETURN (CAMERA_BUS (11100000B) AND 00000010B) = 00000010B; END; /*------------------------------------------------------------*/ CAMERA_OK: PROCEDURE BYTE; DCL N BYTE, OK BYTE; DO N = 1 TO 5; OK = TRUE; CAM_BUS = 11000000B; CAM_BUS = 11000000B; IF (CAM_BUS AND 11111000B) <> 01000000B THEN OK = FALSE; CAM_BUS = 10110000B; CAM_BUS = 10110000B; IF (CAM_BUS AND 11111110B) <> 00110000B THEN OK = FALSE; IF OK THEN RETURN TRUE; CALL WAIT (20000); END; RETURN FALSE; END; /*------------------------------------------------------------*/ CAMERA_WOUND: PROCEDURE BYTE; RETURN (CAMERA_BUS (11100000B) AND 00000100B) = 00000100B; END; /*------------------------------------------------------------*/ CAMERA_MOTOR_OFF: PROCEDURE; X = CAMERA_BUS (01000000B); END; /*------------------------------------------------------------*/ CAMERA_MOTOR_MED: PROCEDURE; X = CAMERA_BUS (01000010B); END; /*------------------------------------------------------------*/ CAMERA_MOTOR_FAST: PROCEDURE; X = CAMERA_BUS (01000011B); END; /*------------------------------------------------------------*/ CAMERA_BACK_ON: PROCEDURE; INTEG_REG = 01B; MODE_REG = IDLE; X = CAMERA_BUS (00110001B); CALL WAIT (30000); CAM_BACK_ON = TRUE; END; /*------------------------------------------------------------*/ CAMERA_BACK_OFF: PROCEDURE; INTEG_REG = 01B; MODE_REG = IDLE; CAM_BUS = 00000000B; CAM_BACK_ON = FALSE; END; /*------------------------------------------------------------*/ ENABLE_AD: PROCEDURE; X = CAMERA_BUS (BACK_CONTROLS OR 00100001B); END; /*------------------------------------------------------------*/ DISABLE_AD: PROCEDURE; X = CAMERA_BUS (BACK_CONTROLS OR 00100000B); END; /*------------------------------------------------------------*/ BACK_CONTROLS: PROCEDURE BYTE; IF C.CAMERA_GAIN > 3 THEN C.CAMERA_GAIN = 3; DO CASE C.CAMERA_GAIN; RETURN 0000B; RETURN 0010B; RETURN 0100B; RETURN 0110B; END; RETURN 0000B; END; /*------------------------------------------------------------*/ DEFECT_DATA_AVAILABLE: PROCEDURE PUBLIC; CALL PARSE_DEFECT_DATA; ROM_DATA_WRITE = TRUE; END; /*------------------------------------------------------------*/ DEFECT_DATA_ADDRESS: PROCEDURE DWORD PUBLIC; ROM_DATA_READ = TRUE; DO WHILE ROM_DATA_READ; CALL WAIT (20000); END; CALL DEPARSE_DEFECT_DATA; RETURN 512; END; /*------------------------------------------------------------*/ WRITE_DEFECT_ROM_DEBUG: PROCEDURE PUBLIC; ROM_DATA_WRITE = TRUE; END; /*------------------------------------------------------------*/ CAMERA_BUS: PROCEDURE (CMD) BYTE; DCL CMD BYTE, STATUS BYTE, ACTIVE BYTE; ACTIVE = ((INTEG_REG AND 01B) = 00B); INTEG_REG = 01B; IF ACTIVE THEN CALL DELAY (300); CAM_BUS = CMD; CAM_BUS = CMD; CAM_BUS = CMD; CAM_BUS = CMD; STATUS = CAM_BUS; IF ACTIVE THEN INTEG_REG = 00B; RETURN STATUS; END; /*------------------------------------------------------------*/ START_FLUSH: PROCEDURE; CALL DISABLE_AD; INTEG_REG = 01B; CALL WAIT (1000); MODE_REG = FLUSH; INTEG_REG = 00B; IF DARK_DISABLE THEN VER_POS_REG = OFF; ELSE VER_POS_REG = CDARK; END; /*------------------------------------------------------------*/ START_INTEGRATION: PROCEDURE; CALL DISABLE_AD; IF (INTEG_REG AND 01B) = 01B THEN RETURN; INTEG_REG = 01B; CALL WAIT (1000); IF DARK_DISABLE THEN VER_POS_REG = OFF; ELSE VER_POS_REG = CDARK; END; /*------------------------------------------------------------*/ IMAGE_XFER: PROCEDURE; DCL N BYTE, SUM WORD; CALL ENABLE_AD; VER_POS_REG = OFF; SUM = 0; DO N = 1 TO 50; SUM = SUM + CAM_BUS; END; CALL DISABLE_AD; BLACK_LEVEL = LOW (SUM / 50); INTEG_REG = 01B; ID_ATN_REG = ID_SND; CALL SET_XFER_COUNT (10000000); CALL ENABLE_XFER; CCD_REG = 2; SKIPA_REG = 0; DARK_REG = 1; SKIPB_REG = 1; IMAGE_REG = VER_SIZE; CALL ENABLE_AD; MODE_REG = TRANS; PIXSUM_REG = FALSE; INTEG_REG = 00B; CALL TIMER (MT,MAX_TRANSFER_TIME); DO WHILE ((INTEG_REG AND 10B) = 0) AND NOT TIMEOUT (MT); CALL WAIT (10000); END; INTEG_REG = 01B; CALL WAIT (1000); VER_POS_REG = OFF; CALL DISABLE_AD; CALL DISABLE_XFER; ID_ATN_REG = ID_OFF; END; /*-- Back serial PROM procedures -----------------------------*/ DCL ROM_READ LIT '1000000000B'; DCL ROM_WEN LIT '0011000000B'; DCL ROM_WRITE LIT '0100000000B'; DCL ROM_WRALL LIT '0001000000B'; DCL ROM_WDS LIT '0000000000B'; DCL ROM_PRREAD LIT '1000000000B'; DCL ROM_PREN LIT '0011000000B'; DCL ROM_PRCLEAR LIT '1111111111B'; DCL ROM_PRWRITE LIT '0100000000B'; DCL ROM_PRDS LIT '0000000000B'; /*------------------------------------------------------------*/ PARSE_DEFECT_DATA: PROCEDURE; DCL POINTS WORD, COLUMNS WORD, N BYTE; IF NOT ASSIGN_BUS (20000000) THEN RETURN; CALL SETB (0,@ROM_W,SIZE (ROM_W)); /* Read CCD serial number */ CALL ENABLE_MEMORY_READ (0); ROM_W.SERIAL_NO = 0; CALL READ_BLOCK (@ROM_W.SERIAL_NO,3); /* Read monochrome/color */ CALL READ_BLOCK (@ROM_W.COLOR,1); ROM_W.COLOR = (ROM_W.COLOR <> 'M'); /* Read number of point defects */ CALL READ_BLOCK (@POINTS,2); IF POINTS < LENGTH (ROM_W.POINT) THEN ROM_W.BAD_POINTS = POINTS; ELSE ROM_W.BAD_POINTS = LENGTH (ROM_W.POINT) - 1; /* Read point defect coordinates and gains */ DO N = 1 TO ROM_W.BAD_POINTS; CALL READ_BLOCK (@ROM_W.POINT(N),4); CALL READ_BLOCK (@ROM_W.POINT_GAIN(N),1); END; /* Read number of column defects */ CALL ENABLE_MEMORY_READ (6 + (POINTS * 5)); CALL READ_BLOCK (@COLUMNS,2); IF COLUMNS < LENGTH (ROM_W.COLUMN) THEN ROM_W.BAD_COLUMNS = COLUMNS; ELSE ROM_W.BAD_COLUMNS = LENGTH (ROM_W.COLUMN) - 1; /* Read column defect coordinates and gains */ DO N = 1 TO ROM_W.BAD_COLUMNS; CALL READ_BLOCK (@ROM_W.COLUMN(N),2); CALL READ_BLOCK (@ROM_W.COLUMN_GAIN(N),1); END; CALL DISABLE_MEMORY; CALL RELEASE_BUS; /* Correct coordinate origins */ DO N = 1 TO ROM_W.BAD_POINTS; ROM_W.POINT(N).H = ROM_W.POINT(N).H - 1; ROM_W.POINT(N).V = ROM_W.POINT(N).V - 1; END; DO N = 1 TO ROM_W.BAD_COLUMNS; ROM_W.COLUMN(N) = ROM_W.COLUMN(N) - 1; END; END; /*------------------------------------------------------------*/ DEPARSE_DEFECT_DATA: PROCEDURE; /* Recreate defect file from ROM_R_DATA structure */ DCL N BYTE; IF NOT ASSIGN_BUS (20000000) THEN RETURN; /* Correct coordinate origins */ DO N = 1 TO ROM_R.BAD_POINTS; ROM_R.POINT(N).H = ROM_R.POINT(N).H + 1; ROM_R.POINT(N).V = ROM_R.POINT(N).V + 1; END; DO N = 1 TO ROM_R.BAD_COLUMNS; ROM_R.COLUMN(N) = ROM_R.COLUMN(N) + 1; END; /* Read CCD serial number */ CALL ENABLE_MEMORY_WRITE (512); CALL FILL_BLOCK (0,512); CALL ENABLE_MEMORY_WRITE (512); CALL WRITE_BLOCK (@ROM_R.SERIAL_NO,3); /* Read monochrome/color */ IF ROM_R.COLOR THEN CALL WRITE_BLOCK (@('C'),1); ELSE CALL WRITE_BLOCK (@('M'),1); /* Read number of point defects */ CALL WRITE_BLOCK (@ROM_R.BAD_POINTS,1); CALL WRITE_BLOCK (@(0),1); /* Read point defect coordinates and gains */ DO N = 1 TO ROM_R.BAD_POINTS; CALL WRITE_BLOCK (@ROM_R.POINT(N),4); CALL WRITE_BLOCK (@ROM_R.POINT_GAIN(N),1); END; /* Read number of column defects */ CALL WRITE_BLOCK (@ROM_R.BAD_COLUMNS,1); CALL WRITE_BLOCK (@(0),1); /* Read column defect coordinates and gains */ DO N = 1 TO ROM_R.BAD_COLUMNS; CALL WRITE_BLOCK (@ROM_R.COLUMN(N),2); CALL WRITE_BLOCK (@ROM_R.COLUMN_GAIN(N),1); END; CALL DISABLE_MEMORY; CALL RELEASE_BUS; END; /*------------------------------------------------------------*/ REPORT_DEFECTS: PROCEDURE PUBLIC; DCL N BYTE, E BYTE, TXT (80) BYTE, P BYTE; IF NOT ASSIGN_BUS (0) THEN RETURN; CALL SETB (' ',@TXT,80); CALL VIDEO_TEXT (@TXT,80); IF ROM_R.COLOR THEN CALL MOVB (@(' Serial number: -------- (Color) '),@TXT,40); ELSE CALL MOVB (@(' Serial number: -------- (Monochrome) '),@TXT,40); CALL TO_DECIMAL (@TXT(16),8,ROM_R.SERIAL_NO); CALL VIDEO_TEXT (@TXT,80); /* Blank line */ CALL SETB (' ',@TXT,80); CALL VIDEO_TEXT (@TXT,80); CALL MOVB (@(' Columns: -- (Hpos/Gain) '),@TXT,40); CALL TO_DECIMAL (@TXT(10),2,ROM_R.BAD_COLUMNS); CALL VIDEO_TEXT (@TXT,80); P = 0; CALL SETB (' ',@TXT,80); DO N = 1 TO ROM_R.BAD_COLUMNS; CALL TO_DECIMAL (@TXT(P + 2),4,ROM_R.COLUMN(N)); TXT(P + 6) = '/'; CALL TO_DECIMAL (@TXT(P + 7),2,ROM_R.COLUMN_GAIN(N)); IF (P < 60) AND (N < ROM_R.BAD_COLUMNS) THEN P = P + 20; ELSE DO; P = 0; CALL VIDEO_TEXT (@TXT,80); CALL SETB (' ',@TXT,80); END; END; /* Blank line */ CALL SETB (' ',@TXT,80); CALL VIDEO_TEXT (@TXT,80); CALL MOVB (@(' Points: -- (Hpos/Vpos/Gain) '),@TXT,40); CALL TO_DECIMAL (@TXT(9),2,ROM_R.BAD_POINTS); CALL VIDEO_TEXT (@TXT,80); P = 0; CALL SETB (' ',@TXT,80); DO N = 1 TO ROM_R.BAD_POINTS; CALL TO_DECIMAL (@TXT(P + 2),4,ROM_R.POINT(N).H); TXT(P + 6) = '/'; CALL TO_DECIMAL (@TXT(P + 7),4,ROM_R.POINT(N).V); TXT(P + 11) = '/'; CALL TO_DECIMAL (@TXT(P + 12),2,ROM_R.POINT_GAIN(N)); IF (P < 60) AND (N < ROM_R.BAD_POINTS) THEN P = P + 20; ELSE DO; P = 0; CALL VIDEO_TEXT (@TXT,80); CALL SETB (' ',@TXT,80); END; END; CALL RELEASE_BUS; END; /*------------------------------------------------------------*/ WRITE_BACK_MEMORY: PROCEDURE; DCL W BYTE, SUM WORD; ROM_W.KEY = ROM_KEY; SUM = 0; DO W = 1 TO 255; SUM = SUM + ROM_W_DATA(W); END; ROM_W.CHECKSUM = SUM; CALL WRITE_ROM (ROM_WEN,FALSE,FALSE,0); DO W = 0 TO 255; CALL WRITE_ROM (ROM_WRITE + W,FALSE,TRUE,ROM_W_DATA(W)); END; CALL WRITE_ROM (ROM_WDS,FALSE,FALSE,0); END; /*------------------------------------------------------------*/ WRITE_ROM: PROCEDURE (INS,PRE,DWR,DAT); DCL INS WORD, PRE BYTE, DWR BYTE, DAT WORD, B BYTE; /* SK low */ CAM_BUS = 00100110B; /* PE,PRE,CS low */ CAM_BUS = 00011110B; /* PE,CS high */ IF PRE THEN CAM_BUS = 00010000B; ELSE CAM_BUS = 00010100B; /* Start bit */ CAM_BUS = 00100010B; CAM_BUS = 00100000B; /* Send instruction */ DO B = 1 TO 10; IF (INS AND 1000000000B) = 0 THEN DO; CAM_BUS = 00100110B; CAM_BUS = 00100100B; END; ELSE DO; CAM_BUS = 00100010B; CAM_BUS = 00100000B; END; INS = ROL (INS,1); END; IF DWR THEN DO; /* Send word */ DO B = 1 TO 16; IF (DAT AND 1000000000000000B) = 0 THEN DO; CAM_BUS = 00100110B; CAM_BUS = 00100100B; END; ELSE DO; CAM_BUS = 00100010B; CAM_BUS = 00100000B; END; DAT = ROL (DAT,1); END; END; /* SK low */ CAM_BUS = 00100110B; /* PRE,CS low */ CAM_BUS = 00010110B; /* PE low */ CAM_BUS = 00011110B; IF DWR THEN CALL WAIT (10000); END; /*------------------------------------------------------------*/ READ_BACK_MEMORY: PROCEDURE; DCL W BYTE, DAT WORD, B BYTE, SUM WORD, TRY BYTE; DO TRY = 1 TO 5; /* SK low */ CAM_BUS = 00100110B; /* PE,PRE,CS low */ CAM_BUS = 00011110B; /* CS high */ CAM_BUS = 00011100B; /* First clock */ CAM_BUS = 00100110B; CAM_BUS = 00100100B; /* Start bit */ CAM_BUS = 00100010B; CAM_BUS = 00100000B; /* Instruction ONE bit */ CAM_BUS = 00100010B; CAM_BUS = 00100000B; /* Instruction ZERO bits */ DO B = 1 TO 9; CAM_BUS = 00100110B; CAM_BUS = 00100100B; END; /* SK low */ CAM_BUS = 00100110B; /* Read all data */ DO W = 0 TO 255; DAT = 0; /* Receive word */ DO B = 1 TO 16; DAT = ROL (DAT,1); CAM_BUS = 00100100B; CAM_BUS = 10000000B; IF CAM_BUS THEN DAT = DAT + 1; CAM_BUS = 00100110B; END; ROM_R_DATA(W) = DAT; END; /* PE,PRE,CS low */ CAM_BUS = 00011110B; IF ROM_R.KEY = ROM_KEY THEN DO; SUM = 0; DO W = 1 TO 255; SUM = SUM + ROM_R_DATA(W); END; IF SUM = ROM_R.CHECKSUM THEN DO; CALL MOVW (@ROM_R_DATA,@ROM_DATA,256); RETURN; END; END; END; X = WAIT_FLAG (FLAG_TEST_IMAGE,FALSE,10000000); CALL WAIT (100000); CALL DISP_TEXT (16,8,@('ROMerror')); ROM.KEY = 0; ROM.SERIAL_NO = 0; ROM.COLOR = TRUE; ROM.BAD_COLUMNS,ROM.BAD_POINTS = 0; END; /*------------------------------------------------------------*/ CORRECT_DEFECTS: PROCEDURE (ADR) PUBLIC; DCL ADR DWORD, D BYTE, G BYTE; DO CASE C.CAMERA_GAIN; G = 4; G = 8; G = 16; G = 32; END; IF ASSIGN_BUS (10000000) THEN DO; CALL CORRECT_FIRST_FIVE_COLUMNS (ADR); CALL RELEASE_BUS; END; DO D = 1 TO ROM.BAD_COLUMNS; IF G >= ROM.COLUMN_GAIN(D) THEN IF ASSIGN_BUS (10000000) THEN DO; IF (G >= ROM.COLUMN_GAIN(D + 1)) AND (ROM.COLUMN(D + 1) = ROM.COLUMN(D) + 1) THEN CALL CORRECT_COLUMN_DEFECT (ADR,ROM.COLUMN(D),TRUE); ELSE CALL CORRECT_COLUMN_DEFECT (ADR,ROM.COLUMN(D),FALSE); CALL RELEASE_BUS; END; END; IF ASSIGN_BUS (10000000) THEN DO; DO D = 1 TO ROM.BAD_POINTS; IF G >= ROM.POINT_GAIN(D) THEN CALL CORRECT_POINT_DEFECT (ADR,ROM.POINT(D).H,ROM.POINT(D).V); END; CALL RELEASE_BUS; END; END; /*------------------------------------------------------------*/ TEST_CAMERA: PROCEDURE PUBLIC; DCL N WORD, D BYTE, TEST_DATA (32) BYTE; DCL TEST_PATTERN (*) BYTE DATA (001H,0FEH,002H,0FDH,004H,0FBH,008H,0F7H, 010H,0EFH,020H,0DFH,040H,0BFH,080H,07FH, 001H,0FEH,002H,0FDH,004H,0FBH,008H,0F7H, 010H,0EFH,020H,0DFH,040H,0BFH,080H,07FH); CALL SEND_CHAR (13); CUR_SLOT,MY_SLOT = FIND_BOARD (BOARD_ID); SLOT = CUR_SLOT; IF MY_SLOT = 255 THEN DO; CALL SEND_STRING (@('FAILED, Interface board not found',13)); RETURN; END; CALL INITIALIZE; CALL SEND_STRING (@('-- Interface Board Test --',13)); CALL SEND_CHAR (13); N = TEST_REGISTERS; IF N <> 0 THEN DO; CALL SEND_STRING (@('Failure code = ',0)); CALL SEND_DECIMAL (N,2); CALL SEND_CHAR (13); CALL TEST_FAIL (@('Interface board - Registers',13)); RETURN; END; /* - Begin loopback FIFO test - - - - - - - - - - - - - - - - - - - */ CAM_PWR_REG = 1; CCD_REG = 7; ID_ATN_REG = ID_SND; INTEG_REG = 1; INTEG_REG = 0; /* First, see if test plug is present */ DO N = 0 TO 513; CAM_BUS = 0; END; IF FIFO_FLAG_REG <> 1000B THEN DO; CALL SEND_STRING (@('Attach Camera Board Test Adapter, Press SPACE BAR when done',7,13)); DO N = 1 TO 80; CALL WAIT (250000); IF DIAGNOSTIC_INT THEN N = 200; END; END; IF N < 200 THEN DO; CALL TEST_FAIL (@('Interface board - Test plug not attached',13)); RETURN; END; /* - FIFO test - - - - - - - - - - - - - - - - - - - - - - - */ INTEG_REG = 1; INTEG_REG = 0; DO N = 0 TO 513; CAM_BUS = 0; END; IF FIFO_FLAG_REG <> 1000B THEN DO; CALL SEND_STRING (@('FIFO flag register: ',0)); CALL SEND_HEX (FIFO_FLAG_REG,2); CALL SEND_CHAR (13); CALL TEST_FAIL (@('Interface board - FIFO half full flag',0)); END; DO N = 0 TO 511; CAM_BUS = 0; END; IF FIFO_FLAG_REG <> 1100B THEN DO; CALL SEND_STRING (@('FIFO flag register: ',0)); CALL SEND_HEX (FIFO_FLAG_REG,2); CALL SEND_CHAR (13); CALL TEST_FAIL (@('Interface board - FIFO full flag',0)); END; CALL READ_BLOCK (@TEST_DATA,2); IF FIFO_FLAG_REG <> 1000B THEN DO; CALL SEND_STRING (@('FIFO flag register: ',0)); CALL SEND_HEX (FIFO_FLAG_REG,2); CALL SEND_CHAR (13); CALL TEST_FAIL (@('Interface board - FIFO read',0)); END; INTEG_REG = 1; INTEG_REG = 0; IF FIFO_FLAG_REG <> 0000B THEN DO; CALL SEND_STRING (@('FIFO flag register: ',0)); CALL SEND_HEX (FIFO_FLAG_REG,2); CALL SEND_CHAR (13); CALL TEST_FAIL (@('Interface board - FIFO reset',0)); END; DO N = 0 TO 31; CAM_BUS = TEST_PATTERN(N); END; CALL SETB (0,@TEST_DATA,16); CALL READ_BLOCK (@TEST_DATA,1); CALL READ_BLOCK (@TEST_DATA,16); IF CMPB (@TEST_PATTERN,@TEST_DATA,16) < 16 THEN DO; DO N = 0 TO 15; IF TEST_PATTERN(N) <> TEST_DATA(N) THEN DO; CALL SEND_STRING (@('Expected data: ',0)); CALL SEND_HEX (TEST_PATTERN(N),2); CALL SEND_STRING (@(' Actual data: ',0)); CALL SEND_HEX (TEST_DATA(N),2); CALL SEND_CHAR (13); END; END; CALL TEST_FAIL (@('Interface board - FIFO data',0)); END; ID_ATN_REG = ID_OFF; INTEG_REG = 1; CAM_PWR_REG = 0; /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ END; /*------------------------------------------------------------*/ TEST_WINDER: PROCEDURE PUBLIC; DCL N WORD, NN BYTE, SUM WORD; CALL SEND_CHAR (13); CUR_SLOT,MY_SLOT = FIND_BOARD (BOARD_ID); SLOT = CUR_SLOT; IF MY_SLOT = 255 THEN DO; CALL SEND_STRING (@('FAILED, Interface board not found',13)); RETURN; END; CALL INITIALIZE; CALL SEND_STRING (@('-- Winder/Back Test --',13)); /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ CALL SEND_CHAR (13); CALL SEND_STRING (@('Attach Winder and Camera, Set camera body shutter speed to "2000"',13)); CALL SEND_STRING (@('Press SPACE BAR when done',7,13)); DO N = 1 TO 160; CALL WAIT (250000); IF DIAGNOSTIC_INT THEN N = 200; END; /* First, see if winder is present */ CAM_PWR_REG = 0; CALL WAIT (500000); CAM_PWR_REG = 1; CALL WAIT (500000); CALL INITIALIZE_CAMERA; CALL INITIALIZE_CAMERA; CALL IDENTIFY_CAMERA; IF NOT CAMERA_OK THEN DO; CAM_PWR_REG = 0; CALL TEST_FAIL (@('Winder - Not connected',13)); RETURN; END; /* - - - Check back ROM - - - - - - - - - - - - - - - - - - */ CALL SEND_CHAR (13); ROM.KEY = 0; CALL IDENTIFY_CAMERA; IF ROM.KEY <> ROM_KEY THEN CALL TEST_FAIL (@('Winder/Back - ROM not programmed',13)); ELSE DO; CALL SEND_STRING (@('Imager Serial Number: ',0)); CALL SEND_DECIMAL (ROM.SERIAL_NO,8); IF ROM.COLOR THEN CALL SEND_STRING (@(' (Color)',13)); ELSE CALL SEND_STRING (@(' (Monochrome)',13)); CALL SEND_STRING (@('Column defects: ',0)); CALL SEND_DECIMAL (ROM.BAD_COLUMNS,3); CALL SEND_STRING (@(' Point defects: ',0)); CALL SEND_DECIMAL (ROM.BAD_POINTS,3); CALL SEND_CHAR (13); END; /* - - Check body and winder - - - - - - - - - - - - - - - - */ CALL SEND_CHAR (13); CALL SEND_STRING (@('Winder test, press SPACE BAR to quit',13)); CALL SEND_STRING (@('--------------------',13)); CALL SEND_STRING (@(27,'[1A',0)); CALL CAMERA_BODY_ON; CALL CAMERA_SOFT_ON; CALL WAIT (50000); SUM = 0; DO NN = 1 TO 20; IF CAMERA_WOUND THEN CALL CAMERA_HARD_ON; CALL WAIT (50000); CALL CAMERA_SOFT_ON; DO N = 1 TO 100; IF NOT CAMERA_WOUND THEN N = 200; CALL WAIT (10000); END; IF DIAGNOSTIC_INT THEN NN = 200; CALL SEND_CHAR ('*'); IF DIAGNOSTIC_INT THEN NN = 200; IF N < 200 THEN DO; CALL SEND_CHAR (13); CALL TEST_FAIL (@('Winder / Body - Shutter release test',13)); NN = 200; END; ELSE DO; CALL CAMERA_MOTOR_MED; DO N = 1 TO 100; IF CAMERA_WOUND THEN DO; SUM = SUM + N; N = 200; END; CALL WAIT (10000); END; IF N < 200 THEN DO; CALL SEND_CHAR (13); CALL TEST_FAIL (@('Winder / Body - Winder test',13)); NN = 200; END; END; END; CALL SEND_CHAR (13); IF NN < 200 THEN DO; CALL SEND_STRING (@('Average wind time: 0.',0)); CALL SEND_DECIMAL (SUM / 2,3); CALL SEND_STRING (@(' seconds',13)); END; CALL CAMERA_MOTOR_OFF; CALL CAMERA_SOFT_OFF; CALL CAMERA_BODY_OFF; /* - - Check image data transfer - - - - - - - - - - - - - - */ DO; DCL BLACKS (4) BYTE; CALL CAMERA_BACK_ON; CALL WAIT (100000); DARK_DISABLE = FALSE; CALL START_FLUSH; CALL WAIT (500000); CALL START_INTEGRATION; /* Check black levels */ DO C.CAMERA_GAIN = 0 TO 3; CALL ENABLE_AD; VER_POS_REG = OFF; CALL WAIT (10000); SUM = 0; DO N = 1 TO 50; SUM = SUM + CAM_BUS; END; CALL DISABLE_AD; BLACKS(C.CAMERA_GAIN) = LOW (SUM / 50); END; CALL SEND_CHAR (13); IF ROM.COLOR THEN CALL SEND_STRING (@('Iso: 100 200 400 800',13)); ELSE CALL SEND_STRING (@('Iso: 200 400 800 1600',13)); CALL SEND_STRING (@('Black: ',0)); DO N = 0 TO 3; CALL SEND_DECIMAL (BLACKS(N),3); CALL SEND_STRING (@(' ',0)); END; CALL SEND_CHAR (13); IF (BLACKS(0) > 10) OR (BLACKS(1) > 15) OR (BLACKS(2) > 10) OR (BLACKS(3) > 30) THEN DO; CALL TEST_FAIL (@('Back - Black level test',13)); END; INTEG_REG = 01B; ID_ATN_REG = ID_SND; CALL SET_XFER_COUNT (10000000); CALL ENABLE_XFER; CCD_REG = 2; SKIPA_REG = 0; DARK_REG = 1; SKIPB_REG = 1; IMAGE_REG = VER_SIZE; CALL ENABLE_AD; MODE_REG = TRANS; PIXSUM_REG = FALSE; INTEG_REG = 00B; NN = 50; DO N = 1 TO 50; IF (INTEG_REG AND 10B) = 10B THEN DO; NN = N; N = 200; END; CALL WAIT (10000); END; IF (NN < 25) OR (NN > 27) OR (XFER_COUNT <> 1310720) THEN DO; CALL SEND_STRING (@('Transfer time: 0.',0)); CALL SEND_DECIMAL (N * 10,3); CALL SEND_STRING (@(' seconds, Pixels transferred: ',0)); CALL SEND_DECIMAL (XFER_COUNT,8); CALL SEND_CHAR (13); CALL TEST_FAIL (@('Winder / Body - Image data transfer test',13)); END; INTEG_REG = 01B; CALL WAIT (1000); VER_POS_REG = OFF; CALL DISABLE_AD; CALL DISABLE_XFER; ID_ATN_REG = ID_OFF; CALL CAMERA_BACK_OFF; END; /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ CAM_PWR_REG = 0; END; /*------------------------------------------------------------*/ TEST_REGISTERS: PROCEDURE BYTE; CALL RESET_BUS; CAM_PWR_REG = 0; IF (ID_ATN_REG AND 1110B) <> 1000B THEN RETURN 10; ID_ATN_REG = 1100B; IF (ID_ATN_REG AND 1110B) <> 1100B THEN RETURN 11; ID_ATN_REG = 1000B; IF (INTEG_REG AND 01B) <> 01B THEN RETURN 20; INTEG_REG = 00B; IF (INTEG_REG AND 01B) <> 00B THEN RETURN 21; INTEG_REG = 01B; IF (INTEG_REG AND 01B) <> 01B THEN RETURN 22; IF MODE_REG <> 000B THEN RETURN 30; MODE_REG = 001B; IF MODE_REG <> 001B THEN RETURN 31; MODE_REG = 010B; IF MODE_REG <> 010B THEN RETURN 32; MODE_REG = 100B; IF MODE_REG <> 100B THEN RETURN 33; MODE_REG = 000B; IF MODE_REG <> 000B THEN RETURN 34; IF CCD_REG <> 000B THEN RETURN 40; CCD_REG = 001B; IF CCD_REG <> 001B THEN RETURN 41; CCD_REG = 010B; IF CCD_REG <> 010B THEN RETURN 42; CCD_REG = 100B; IF CCD_REG <> 100B THEN RETURN 43; CCD_REG = 000B; IF CCD_REG <> 000B THEN RETURN 44; IF PIXSUM_REG <> 0B THEN RETURN 50; PIXSUM_REG = 1B; IF PIXSUM_REG <> 1B THEN RETURN 51; PIXSUM_REG = 0B; IF PIXSUM_REG <> 0B THEN RETURN 52; IF FIFO_FLAG_REG <> 0000B THEN RETURN 60; IF CAM_BUS <> 0 THEN RETURN 70; RETURN 0; END; /*------------------------------------------------------------*/ END;