#include #include #include #include #include #include #define SBUS_DEV "/dev/astro0" #define SBUS_ID 1 #define TIM_ID 2 #define UTIL_ID 3 #define P 'P' #define X 'X' #define Y 'Y' #define P_MASK 0x00100000 #define X_MASK 0x00200000 #define Y_MASK 0x00400000 #define RDM 0x52444d #define WRM 0x57524d #define SRA 0x535241 #define SEX 0x534558 #define LDA 0x4c4441 #define PON 0x504f4e #define TDL 0x54444c #define DON 0x444f4e #define ERR 0x455252 #define COK 0x434f4b #define CSR 0x435352 #define Reset 0x526573 #define TRUE 1 #define FALSE 0 #define H_MASK 0xffff0000 #define L_MASK 0x0000ffff #define REPLY_MASK 0x00ffffff #define ROWS 2000 #define COLS 2000 #define EXP_TIME 1000 #define SBUS_REPLY_SIZE 8 #define SBUS_BUFFER_SIZE 64 #define MAX_EXPOSURE_BYTES 10240000 #define SBUS_REQUEST_WRITE_CSR 0x80040000 #define SBUS_REQUEST_READ_CSR 0x40040000 #define SBUS_REQUEST_WRITE_UNUSED 0x80000003 #define SBUS_REQUEST_WORD_WIDTH 0x80040004 #define SBUS_RESET 0x80000009 #define FITS_HEADER_SIZE 2880 union reply_buffer { char ch[256]; u_int uin[64]; }; union exp_data { char ch[MAX_EXPOSURE_BYTES]; u_int uin[MAX_EXPOSURE_BYTES/4]; short sh[MAX_EXPOSURE_BYTES/2]; }; union reply_buffer dat; int *reply_arg = (int *)&dat.uin[0]; char *reply_byte = (char *)&dat.ch[0]; union exp_data expdata; char *exp_byte; int image_fd; void write_card(); void opendiff(); void closediff(); void diff_image(); void initialize(); void quit(); int get_reply(); void dsp_command(); void clear_reply_mem(); void clear_image_buf(); void image_transfer(); void putFitsHead(); int reply_id; int sbus_fd, image_fd, sbus_request; int no_alarm; char filename[12] = "TEST0001\0"; char filediff[32]; int exp; int diff_fd; int interval, logone = 2, loopmax = 1, num_exp = 2, exp_count = 1; char expmode, loop, write_image, logexp; int rows, cols, maxval, nccds; int error_found, imagesave = 0; void main () { char c; int i; int data, left, right; int shutter, exp_time; initialize(); printf("\n\n\n\n\n\n"); printf("\n *** SBUS Board Exposure Readout Software ***\n"); printf("\n\nEnter 'T' for Test Exposure mode or 'M' for Multiple Readout mode (T/M): "); scanf("%c", &expmode); if ((expmode == 'm') || (expmode == 'M')) { printf("\nInvalid response..."); quit(); printf("\nEnter number of exposures (decimal): "); scanf("%d", &i); if (i < 1) i = 1; num_exp = i+1; imagesave = 1; goto CONT1; } else if ((expmode == 't') || (expmode == 'T')) { printf("\n* WARNING: Be sure to use the correct timing board ROM test software *\n"); printf("\nEnter 'L' to test multiple exposures or 'S' to test a single exposure (L/S): "); scanf("%c", &loop); scanf("%c", &loop); if ((loop == 'l') || (loop == 'L')) { printf("\nDo you want to enter a maximum number of exposures? (y/n): "); scanf("%c", &c); scanf("%c", &c); if ((c == 'y') || (c == 'Y')) { printf("\nEnter maximum number of exposures (decimal): "); scanf("%d", &i); if (i < 1) i = 1; num_exp = i+1; } else if ((c == 'n') || (c == 'N')) { loopmax = 0; } else { printf("\nInvalid response..."); quit(); } } else if ((loop == 's') || (loop == 'S')) { num_exp = 2; } else { printf("\nInvalid response..."); quit(); } printf("\nDo you want to log exposure errors? (y/n): "); scanf("%c", &logexp); scanf("%c", &logexp); if ((logexp == 'y') || (logexp == 'Y')) { printf("\nEnter '0' to log all errors or '1' to log only one error\nfor each exposure (0/1): "); scanf("%d", &i); if ((i != 0) && (i != 1)) { printf("\nInvalid response..."); quit(); } logone = i; } printf("\nEnter 'V' to write only valid images to disk or\n 'E' to write only images with exposure errors or\n 'A' to write all images to disk or\n 'N' to not write any images to disk (V/E/A/N): "); scanf("%c", &write_image); scanf("%c", &write_image); if ((write_image == 'v') || (write_image == 'V') || (write_image == 'e') || (write_image == 'E') || (write_image == 'a') || (write_image == 'A')) { printf("\nImages will be written to disk"); if ((write_image == 'a') || (write_image == 'A')) { imagesave = 1; } } else if ((write_image == 'n') || (write_image == 'N')) { printf("\nImages will NOT be written to disk"); } else { printf("\nInvalid response..."); quit(); } } else { printf("\nInvalid response..."); quit(); } printf("\n\n"); printf("\n ***** Press Ctrl-C to abort *****\n\n"); CONT1: nccds = 1; rows = ROWS; cols = COLS; interval = 1; dsp_command(SBUS_ID, Reset); for (exp=1; exp < num_exp ; exp++) { if (loopmax == 0) exp = 0; printf("\n\nStarting exposure# %d for %s with interval %d: ", exp_count, filename, interval); dsp_command(SBUS_ID, CSR); dsp_command(TIM_ID, WRM, Y, 1, cols); dsp_command(TIM_ID, WRM, Y, 2, rows); dsp_command(TIM_ID, WRM, Y, 8, interval); shutter = 1; exp_time = EXP_TIME; dsp_command(UTIL_ID, WRM, X, 1, shutter); dsp_command(UTIL_ID, WRM, Y, 24, exp_time); image_transfer(rows*cols*2); exp_count++; if (exp_count < 10) sprintf(filename, "TEST000%d", exp_count); else if ((exp_count > 9) && (exp_count < 100)) sprintf(filename, "TEST00%d", exp_count); else if ((exp_count > 99) && (exp_count < 1000)) sprintf(filename, "TEST0%d", exp_count); else if ((exp_count > 999) && (exp_count < 10000)) sprintf(filename, "TEST%d", exp_count); else { printf("\nImage file rolling over to TEST0001"); sprintf(filename, "TEST0001"); exp_count = 0; } if ((expmode == 't') || (expmode == 'T')) { /* Vary rows and columns to change readout size */ rows = rows - 2; cols = cols - 4; interval = interval + 1; if (rows < 1000) rows = 2000; if (cols < 1000) cols = 2000; /* Vary the interval at which the count is incremented */ if (interval > 20) interval = 1; } dsp_command(SBUS_ID, Reset); } printf("\n"); } void putFitsHead( cols, rows, maxval) int cols, rows, maxval; { int i = 0; char card[81]; sprintf( card, "SIMPLE = T " ); write_card( card ); ++i; sprintf( card, "BITPIX = 16 " ); write_card( card ); ++i; sprintf( card, "NAXIS = 2 " ); write_card( card ); ++i; sprintf( card, "NAXIS1 = %10d ", cols ); write_card( card ); ++i; sprintf( card, "NAXIS2 = %10d ", rows ); write_card( card ); ++i; sprintf( card, "END " ); write_card( card ); ++i; sprintf( card, " " ); while ( i < 36 ) { write_card( card ); ++i; } } void write_card(str) char *str; { write(image_fd, str, 80); } void initialize() { if ((sbus_fd = open(SBUS_DEV, O_RDWR)) == -1) { perror("Cannot open fd for SBUS device"); exit(1); } /* else printf("\nSBUS device opened...");*/ } void quit() { fprintf(stderr, "\nExiting...\n\n"); if ((close(sbus_fd)) == -1) { perror("cannot close SBUS device"); } exit(1); } int get_reply(reply, reply_id, timeout) int reply; int reply_id; int timeout; { int value=0; value = read(sbus_fd, reply_arg, SBUS_REPLY_SIZE); /* printf("\ndat.uin[0] = 0x%x", dat.uin[0]); printf("\ndat.uin[1] = 0x%x", dat.uin[1]);*/ if (value == -1) { perror("Bad value returned."); return(1); } if ((dat.uin[1] & REPLY_MASK) == ERR) { perror("ERROR returned."); return(1); } else if ((dat.uin[1] & REPLY_MASK) == reply) { if ((dat.uin[0] & REPLY_MASK) != reply_id) { perror("Bad reply code."); printf("\nexp: %08x", reply_id); printf("\ngot: %08x", dat.uin[0]); return(1); } } else printf("\nWEIRD!"); return(0); } void dsp_command(va_alist) va_dcl { va_list ap; int destination, command, addr, data, mask, reply, reply2; int byteshft, value; char type; va_start(ap); destination = va_arg(ap, int); command = va_arg(ap, int); clear_reply_mem(SBUS_BUFFER_SIZE); switch (command) { case WRM: reply = (destination << 16) + 2; destination = (destination << 8) + 4; type = va_arg(ap, char); addr = va_arg(ap, int); data = va_arg(ap, int); switch (type) { case 'P': mask = P_MASK; break; case 'X': mask = X_MASK; break; case 'Y': mask = Y_MASK; break; } /* printf("\n%s:%08x %08x %08x %08x", "WRM",destination, WRM, addr | mask, data);*/ dat.uin[0] = destination; dat.uin[1] = WRM; dat.uin[2] = addr | mask; dat.uin[3] = data; byteshft = (4 * 4); byteshft <<= 16; sbus_request = (byteshft | SBUS_REQUEST_WRITE_UNUSED); value = ioctl(sbus_fd, sbus_request, reply_arg); if (value == -1) { printf("\nIOCTL() returned error: WRM"); break; } clear_reply_mem(SBUS_REPLY_SIZE); if (get_reply(DON, reply, 1)) { printf("\nWRM type: %c", type); printf("\nWRM reply: %08x", reply); quit(); } break; case TDL: reply = (destination << 16) + 2; destination = (destination << 8) + 4; data = va_arg(ap, int); printf("\n%s:%08x %08x %08x\n", "TDL",destination, TDL, data); dat.uin[0] = destination; dat.uin[1] = TDL; dat.uin[2] = data; byteshft = (3 * 4); byteshft <<= 16; sbus_request = (byteshft | SBUS_REQUEST_WRITE_UNUSED); value = ioctl(sbus_fd, sbus_request, reply_arg); if (value == -1) { printf("\nIOCTL() returned error: WRM"); break; } clear_reply_mem(SBUS_REPLY_SIZE); if (get_reply(DON, data, 1)) { printf("\nTDL data: %08x", data); quit(); } break; case SEX: reply = (destination << 16) + 2; destination = (destination << 8) + 2; printf("\n%s:%08x %08x", "SEX",destination, SEX); dat.uin[0] = destination; dat.uin[1] = SEX; byteshft = (2 * 4); byteshft <<= 16; sbus_request = (byteshft | SBUS_REQUEST_WRITE_UNUSED); value = ioctl(sbus_fd, sbus_request, reply_arg); if (value == -1) { printf("\nIOCTL() returned error: SEX"); break; } clear_reply_mem(SBUS_REPLY_SIZE); if (get_reply(DON, reply, 1)) { printf("\nSEX: no DON"); quit(); } printf("\nSEX: got DON..."); break; case PON: reply = (destination << 16) + 2; destination = (destination << 8) + 2; printf("\n%s:%08x %08x", "PON",destination, PON); dat.uin[0] = destination; dat.uin[0] = PON; byteshft = (2 * 4); byteshft <<= 16; sbus_request = (byteshft | SBUS_REQUEST_WRITE_UNUSED); value = ioctl(sbus_fd, sbus_request, reply_arg); if (value == -1) { printf("\nIOCTL() returned error: PON"); break; } clear_reply_mem(SBUS_REPLY_SIZE); if (get_reply(DON, reply, 60)) { printf("\nPON: no DON"); quit(); } printf("\nPON: got DON..."); break; case CSR: /* printf("\n%s", "Reading CSR...");*/ clear_reply_mem(SBUS_REPLY_SIZE); sbus_request = SBUS_REQUEST_READ_CSR; value = ioctl(sbus_fd, sbus_request, reply_arg); if (value == -1) { printf("\nIOCTL() returned error: CSR"); break; } /* printf("\ndat.uin[0] = %x", dat.uin[0]);*/ break; case Reset: printf("\n%s", "Resetting SBUS..."); byteshft = (0 * 4); byteshft <<= 16; sbus_request = (byteshft | SBUS_RESET); value = ioctl(sbus_fd, sbus_request, reply_arg); if (value == -1) { printf("\nIOCTL() returned error: Reset"); break; } send_ww(0); break; } } void clear_reply_mem(size) int size; { int i; for (i=0; ivme RDC reply */ numbytes = (va_arg(ap, int) + 4); exp_byte = (char *)&expdata.ch[0]; clear_image_buf(MAX_EXPOSURE_BYTES); dsp_command(UTIL_ID, SEX); send_ww(1); printf("\nreadout started, bytes = %d", (numbytes-4)); ivalue = read(sbus_fd, exp_byte, numbytes); send_ww(0); if (ivalue == -1) { printf("\nBad ivalue returned from readout of image"); } if ((expmode == 't') || (expmode == 'T')) { printf("\nRunning diff on image data..."); diff_image(numbytes/2); if (((write_image == 'e') || (write_image == 'E')) && error_found) errorsave = 1; if (((write_image == 'v') || (write_image == 'V')) && (!(error_found))) errorsave = 1; } if ((imagesave) || (errorsave)) { if ((image_fd = open(filename, O_RDWR | O_CREAT, 0666)) == -1) { perror("Cannot open fd for image file"); exit(1); } printf("\nwriting image data to file..."); lseek (image_fd, FITS_HEADER_SIZE+cols*rows*nccds*2, SEEK_SET); write(image_fd, "", 1); lseek (image_fd, 0, SEEK_SET); maxval = 65535; putFitsHead(cols, rows*nccds, maxval); lseek(image_fd, FITS_HEADER_SIZE, 0); write(image_fd, &expdata.ch[4], (numbytes-4)); printf("\nfinished writing image data!\n"); if ((close(image_fd)) == -1) { perror("cannot close image file descriptor"); } } errorsave = 0; return; } static void clear_image_buf(size) int size; { int i; /* printf("\nClearing image buffer..."); for (i=0; i 32767) k = -32768; } if (expdata.sh[j] != k) { error_found = 1; if (logone != 2) { sprintf(card, "Exposure#:%d short#:%d transmitted: %6d received: %6d \n", exp_count, j+1, k, expdata.sh[j]) ; write(diff_fd, card, strlen(card)) ; if (logone == 1) goto EXITCMP; } } } EXITCMP: if (error_found) printf("\nDIFFS FOUND IN EXP# %d", exp_count); else printf("\nNo differences in Exp# %d", exp_count); closediff() ; }