int hook_led_cmd(struct katcp_dispatch *d, int argc, int value) { struct tbs_raw *tr; #if 0 log_message_katcp(d, KATCP_LEVEL_DEBUG, NULL, "running tbs hook function with value %d", value); #endif tr = get_mode_katcp(d, TBS_MODE_RAW); if(tr == NULL){ return -1; } if(tr->r_chassis == NULL){ return -1; } if(write_event_tbs(d, tr->r_chassis, EV_LED, LED_MISC, value) < 0){ return -1; } if(write_event_tbs(d, tr->r_chassis, EV_SYN, 0, 0) < 0){ return -1; } return 0; }
int parser_save(struct katcp_dispatch *d, char *filename, int force){ struct kcs_basic *kb; struct p_parser *p; kb = get_mode_katcp(d,KCS_MODE_BASIC); if (kb == NULL) return KATCP_RESULT_FAIL; p = kb->b_parser; if (p != NULL) { int rtn; if (filename == NULL && !force){ rtn = save_tree(p,p->filename,force); if (rtn == KATCP_RESULT_FAIL){ log_message_katcp(d,KATCP_LEVEL_WARN,NULL,"File has been edited behind your back!!! use ?parser save newfilename or force save ?parser forcesave"); return KATCP_RESULT_FAIL; } } else if (force) rtn = save_tree(p,p->filename,force); else rtn = save_tree(p,filename,force); if (rtn == KATCP_RESULT_OK){ log_message_katcp(d,KATCP_LEVEL_INFO,NULL,"Saved configuration file as %s",(filename == NULL)?p->filename:filename); return rtn; } } log_message_katcp(d,KATCP_LEVEL_ERROR,NULL,"No configuration file loaded yet, use ?parser load [filename]"); return KATCP_RESULT_FAIL; }
int start_chassis_cmd(struct katcp_dispatch *d, int argc) { char *match; struct tbs_raw *tr; tr = get_mode_katcp(d, TBS_MODE_RAW); if(tr == NULL){ log_message_katcp(d, KATCP_LEVEL_FATAL, NULL, "unable to get raw state"); return KATCP_RESULT_FAIL; } if(tr->r_chassis){ log_message_katcp(d, KATCP_LEVEL_WARN, NULL, "chassis logic already registered"); return KATCP_RESULT_FAIL; } if(argc <= 1){ match = TBS_ROACH_CHASSIS; } else { match = arg_string_katcp(d, 1); if(match == NULL){ log_message_katcp(d, KATCP_LEVEL_ERROR, NULL, "unable to acquire valid match"); return KATCP_RESULT_FAIL; } } tr->r_chassis = chassis_init_tbs(d, match); if(tr->r_chassis == NULL){ return KATCP_RESULT_FAIL; } return KATCP_RESULT_OK; }
int load_pattern_walsh_cmd(struct katcp_dispatch *d, int argc){ int i, j, s, input; time_t timeStamp; char walshBytes[2][64]; uint32_t *ind, value, patval; struct tbs_raw *tr; struct tbs_entry *te; /* Grab the mode pointer */ tr = get_mode_katcp(d, TBS_MODE_RAW); if(tr == NULL){ log_message_katcp(d, KATCP_LEVEL_ERROR, NULL, "unable to acquire raw mode state"); return KATCP_RESULT_FAIL; } /* Make sure we're programmed */ if(tr->r_fpga != TBS_FPGA_MAPPED){ log_message_katcp(d, KATCP_LEVEL_ERROR, NULL, "fpga not programmed"); return KATCP_RESULT_FAIL; } /* Get the pointer to the Walsh table block memory */ te = find_data_avltree(tr->r_registers, WALSH_TABLE_BRAM); if(te == NULL){ log_message_katcp(d, KATCP_LEVEL_ERROR, NULL, "register %s not defined", WALSH_TABLE_BRAM); return KATCP_RESULT_FAIL; } /* Grab the Walsh pattern using DSM */ s = dsm_read(DDS_HOST, DSM_WALSH_VAR, &walshBytes, &timeStamp); if (s != DSM_SUCCESS) { dsm_error_message(s, "dsm_read()"); log_message_katcp(d, KATCP_LEVEL_ERROR, NULL, "dsm_read('%s', '%s'): failed with %d", DDS_HOST, DSM_WALSH_VAR, s); return KATCP_RESULT_FAIL; } /* For each input ... */ for (input=0; input<DSM_WALSH_INP; input++) { /* Repeat the pattern to fill the block */ for (i=0; i<WALSH_LEN/(DSM_WALSH_LEN/DSM_WALSH_SKIP); i++) { for (j=0; j<(DSM_WALSH_LEN/DSM_WALSH_SKIP); j++) { /* Get current value of WALSH_TABLE_BRAM[i*DSM_WALSH_LEN + j] */ ind = tr->r_map + te->e_pos_base + 4*(i*(DSM_WALSH_LEN/DSM_WALSH_SKIP) + j); value = *((uint32_t *)ind); /* Mask in the requested values */ patval = ((uint32_t)walshBytes[input][j*2] & 0xf) << (input*4); *((uint32_t *)ind) = (value & ~(0xf << (input*4))) | patval; /* mysnc to update the memory map */ msync(tr->r_map, tr->r_map_size, MS_SYNC); } } } return KATCP_RESULT_OK; }
int parser_destroy(struct katcp_dispatch *d){ struct kcs_basic *kb; struct p_parser *p; kb = get_mode_katcp(d,KCS_MODE_BASIC); if (kb == NULL) return KATCP_RESULT_FAIL; p = kb->b_parser; #ifdef DEBUG fprintf(stderr,"PARSER Destroy called\n"); #endif if (p != NULL){ clean_up_parser(p); return KATCP_RESULT_OK; } return KATCP_RESULT_FAIL; }
int parser_set(struct katcp_dispatch *d, char *srcl, char *srcs, unsigned long vidx, char *nv){ struct kcs_basic *kb; struct p_parser *p; kb = get_mode_katcp(d,KCS_MODE_BASIC); if (kb == NULL) return KATCP_RESULT_FAIL; p = kb->b_parser; if (p != NULL) { return set_label_setting_value(d,p,srcl,srcs,vidx,nv); } log_message_katcp(d,KATCP_LEVEL_ERROR,NULL,"No configuration file loaded yet, use ?parser load [filename]"); return KATCP_RESULT_FAIL; }
int register_dram_poco(struct katcp_dispatch *d, char *name, unsigned int count) { struct capture_poco *cp; struct state_poco *sp; sp = get_mode_katcp(d, POCO_POCO_MODE); if(sp == NULL){ #ifdef DEBUG fprintf(stderr, "dram: unable to access mode %d\n", POCO_POCO_MODE); #endif return -1; } if(register_capture_poco(d, name, &run_generic_capture)){ #ifdef DEBUG fprintf(stderr, "dram: unable to register capture\n"); #endif return -1; } cp = find_capture_poco(sp, name); #ifdef DEBUG if(cp == NULL){ fprintf(stderr, "dram: major logic failure: unable to find freshly created instance %s\n", name); abort(); } #endif sane_capture(cp); #if 0 /* TODO: make this a parameter */ cp->c_period.tv_sec = 1; cp->c_period.tv_usec = 0; #endif if(create_dram_poco(d, cp, count)){ #ifdef DEBUG fprintf(stderr, "dram: unable to create dram\n"); #endif return -1; } return 0; }
int parser_list(struct katcp_dispatch *d){ struct kcs_basic *kb; struct p_parser *p; kb = get_mode_katcp(d,KCS_MODE_BASIC); if (kb == NULL) return KATCP_RESULT_FAIL; p = kb->b_parser; if (p != NULL) { show_tree(d,p); } else { log_message_katcp(d,KATCP_LEVEL_ERROR,NULL,"No configuration file loaded yet, use ?parser load [filename]"); return KATCP_RESULT_FAIL; } return KATCP_RESULT_OK; }
int parser_load(struct katcp_dispatch *d, char *filename){ int rtn; struct kcs_basic *kb; struct p_parser *p; kb = get_mode_katcp(d,KCS_MODE_BASIC); if (kb == NULL) return KATCP_RESULT_FAIL; p = kb->b_parser; if (p != NULL){ clean_up_parser(p); } p = malloc(sizeof(struct p_parser)); p->lcount = 0; p->labels = NULL; p->comments = NULL; p->comcount = 0; p->fsize = 0; rtn = start_parser(p,filename); if (rtn != 0){ log_message_katcp(d,KATCP_LEVEL_ERROR,NULL,"%s",strerror(rtn)); clean_up_parser(p); return KATCP_RESULT_FAIL; } p->filename = strdup(filename); kb->b_parser = p; log_message_katcp(d,KATCP_LEVEL_INFO,NULL,"Configuration file loaded"); return KATCP_RESULT_OK; }
int led_chassis_cmd(struct katcp_dispatch *d, int argc) { struct tbs_raw *tr; int code, value; char *name, *parm; if(argc <= 1){ log_message_katcp(d, KATCP_LEVEL_ERROR, NULL, "insufficient parameters"); return KATCP_RESULT_FAIL; } tr = get_mode_katcp(d, TBS_MODE_RAW); if(tr == NULL){ log_message_katcp(d, KATCP_LEVEL_FATAL, NULL, "unable to get raw state"); return KATCP_RESULT_FAIL; } if(tr->r_chassis == NULL){ log_message_katcp(d, KATCP_LEVEL_WARN, NULL, "no chassis logic registered"); return KATCP_RESULT_FAIL; } name = arg_string_katcp(d, 1); if(name == NULL){ log_message_katcp(d, KATCP_LEVEL_WARN, NULL, "unable to acquire led name"); return KATCP_RESULT_FAIL; } /* this should be an array lookup, but it is only two leds */ if(!strcmp(name, "red")){ code = LED_SUSPEND; } else if(!strcmp(name, "green")){ code = LED_MISC; } else { log_message_katcp(d, KATCP_LEVEL_WARN, NULL, "unsupported led colour %s", name); return KATCP_RESULT_FAIL; } value = 0; parm = arg_string_katcp(d, 2); if(parm){ if(strcmp(parm, "off") && strcmp(parm, "false") && strcmp(parm, "0") ){ value = 1; } } log_message_katcp(d, KATCP_LEVEL_TRACE, NULL, "%s led code %d", value ? "setting" : "clearing", code); if(write_event_tbs(d, tr->r_chassis, EV_LED, code, value) < 0){ return KATCP_RESULT_FAIL; } if(write_event_tbs(d, tr->r_chassis, EV_SYN, 0, 0) < 0){ return KATCP_RESULT_FAIL; } return KATCP_RESULT_OK; }
int test_walsh_cmd(struct katcp_dispatch *d, int argc){ int iter = 0; char *regname; uint32_t value; double sec, msec, period; long long tv_sec, tv_nsec; struct tbs_raw *tr; struct tbs_entry *te; struct timespec start, next, last; /* Grab the mode pointer */ tr = get_mode_katcp(d, TBS_MODE_RAW); if(tr == NULL){ log_message_katcp(d, KATCP_LEVEL_ERROR, NULL, "unable to acquire raw mode state"); return KATCP_RESULT_FAIL; } /* Make sure we're programmed */ if(tr->r_fpga != TBS_FPGA_MAPPED){ log_message_katcp(d, KATCP_LEVEL_ERROR, NULL, "fpga not programmed"); return KATCP_RESULT_FAIL; } /* Grab the first argument, name of reg to twiddle */ regname = arg_string_katcp(d, 1); if (regname == NULL){ log_message_katcp(d, KATCP_LEVEL_ERROR, NULL, "unable to parse first command line argument"); return KATCP_RESULT_FAIL; } /* Grab the second argument, period in microseconds */ period = (double)arg_unsigned_long_katcp(d, 2) * 1e-3; if (period == 0.0){ log_message_katcp(d, KATCP_LEVEL_ERROR, NULL, "unable to parse second command line argument"); return KATCP_RESULT_FAIL; } log_message_katcp(d, KATCP_LEVEL_INFO, NULL, "period=%.6f ms", period); /* Get the register pointer */ te = find_data_avltree(tr->r_registers, regname); if(te == NULL){ log_message_katcp(d, KATCP_LEVEL_ERROR, NULL, "register %s not defined", regname); return KATCP_RESULT_FAIL; } /* Get current value of WALSH_ARM_REG */ value = *((uint32_t *)(tr->r_map + te->e_pos_base)); log_message_katcp(d, KATCP_LEVEL_INFO, NULL, "arm ctrl value = %d", (int)value); /* Loop for a minute */ clock_gettime(CLOCK_REALTIME, &start); start.tv_sec++; start.tv_nsec = 0; while (iter < (int)(60000.0/period)) { iter++; msec = iter * period; sec = msec * 1e-3; tv_sec = (long long)sec; tv_nsec = ((long long)(msec * 1e6) % 1000000000); next.tv_sec = start.tv_sec + tv_sec; next.tv_nsec = start.tv_nsec + tv_nsec; last = wait_for(next); //log_message_katcp(d, KATCP_LEVEL_INFO, NULL, "iter==%lld.%09lld", tv_sec, tv_nsec); /* Twiddle the LSB value */ *((uint32_t *)(tr->r_map + te->e_pos_base)) = value | (iter%2); msync(tr->r_map, tr->r_map_size, MS_SYNC); } log_message_katcp(d, KATCP_LEVEL_INFO, NULL, "start=%d.%09d", start.tv_sec, start.tv_nsec); log_message_katcp(d, KATCP_LEVEL_INFO, NULL, "stop==%d.%09d", last.tv_sec, last.tv_nsec); return KATCP_RESULT_OK; }
int arm_walsh_cmd(struct katcp_dispatch *d, int argc){ int s, hb_offset; time_t timeStamp; uint32_t value, mask; struct tbs_raw *tr; struct tbs_entry *te; double start_db, now_db, arm_at_db; struct timespec start, now; /* Grab the mode pointer */ tr = get_mode_katcp(d, TBS_MODE_RAW); if(tr == NULL){ log_message_katcp(d, KATCP_LEVEL_ERROR, NULL, "unable to acquire raw mode state"); return KATCP_RESULT_FAIL; } /* Make sure we're programmed */ if(tr->r_fpga != TBS_FPGA_MAPPED){ log_message_katcp(d, KATCP_LEVEL_ERROR, NULL, "fpga not programmed"); return KATCP_RESULT_FAIL; } /* Get the register pointer */ te = find_data_avltree(tr->r_registers, WALSH_ARM_REG); if(te == NULL){ log_message_katcp(d, KATCP_LEVEL_ERROR, NULL, "register %s not defined", WALSH_ARM_REG); return KATCP_RESULT_FAIL; } /* Get current value of WALSH_ARM_REG */ value = *((uint32_t *)(tr->r_map + te->e_pos_base)); log_message_katcp(d, KATCP_LEVEL_INFO, NULL, "arm ctrl value = %d", (int)value); /* Set MSB=0 to prepare to arm */ *((uint32_t *)(tr->r_map + te->e_pos_base)) = value & 0x7fffffff; msync(tr->r_map, tr->r_map_size, MS_SYNC); /* Grab the first argument, offset in heartbeats */ hb_offset = arg_signed_long_katcp(d, 1); log_message_katcp(d, KATCP_LEVEL_INFO, NULL, "hb_offset=%d", hb_offset); /* Grab the sync time over DSM */ s = dsm_read(DDS_HOST, DSM_ARMAT_VAR, &arm_at_db, &timeStamp); if (s != DSM_SUCCESS) { dsm_error_message(s, "dsm_read()"); log_message_katcp(d, KATCP_LEVEL_ERROR, NULL, "dsm_read('%s', '%s'): failed with %d", DDS_HOST, DSM_ARMAT_VAR, s); return KATCP_RESULT_FAIL; } /* Make sure arm_at is not in the past */ clock_gettime(CLOCK_REALTIME, &now); if ((int)arm_at_db <= now.tv_sec){ log_message_katcp(d, KATCP_LEVEL_ERROR, NULL, "%0.6f is in the past! It's %d.%06d now", arm_at_db, now.tv_sec, now.tv_nsec); return KATCP_RESULT_FAIL; } /* Print out requested arm time */ log_message_katcp(d, KATCP_LEVEL_INFO, NULL, "arm reqst=%.9f", arm_at_db); /* Add in the HB offset and print */ arm_at_db += ((double)hb_offset) * HB_PERIOD; log_message_katcp(d, KATCP_LEVEL_INFO, NULL, "arming at=%.9f", arm_at_db); /* ... and now we wait, timeout=60 seconds */ clock_gettime(CLOCK_REALTIME, &start); start_db = timespec_to_double(start); now_db = timespec_to_double(now); while (now_db < arm_at_db) { clock_gettime(CLOCK_REALTIME, &now); now_db = timespec_to_double(now); if (now.tv_sec > start.tv_sec+60) { log_message_katcp(d, KATCP_LEVEL_ERROR, NULL, "arm timed out after 60 seconds"); return KATCP_RESULT_FAIL; } } /* Twiddle bits 31 and 29 finally to arm swof and mcnt */ mask = 0xa0000000; *((uint32_t *)(tr->r_map + te->e_pos_base)) = value & ~mask; msync(tr->r_map, tr->r_map_size, MS_SYNC); *((uint32_t *)(tr->r_map + te->e_pos_base)) = value | mask; msync(tr->r_map, tr->r_map_size, MS_SYNC); *((uint32_t *)(tr->r_map + te->e_pos_base)) = value & ~mask; msync(tr->r_map, tr->r_map_size, MS_SYNC); log_message_katcp(d, KATCP_LEVEL_INFO, NULL, "armed at==%.9f", now_db); return KATCP_RESULT_OK; }
int register_capture_poco(struct katcp_dispatch *d, char *name, int (*call)(struct katcp_dispatch *d, struct capture_poco *cp, int poke)) { struct state_poco *sp; struct capture_poco *cp, **tmp; sp = get_mode_katcp(d, POCO_POCO_MODE); if(sp == NULL){ return -1; } tmp = realloc(sp->p_captures, sizeof(struct capture_poco *) * (sp->p_size + 1)); if(tmp == NULL){ return -1; } sp->p_captures = tmp; cp = malloc(sizeof(struct capture_poco)); if(cp == NULL){ return -1; } cp->c_magic = CAPTURE_MAGIC; cp->c_name = NULL; cp->c_fd = (-1); cp->c_port = htons(0); cp->c_ip = htonl(0); /* c_prep - unset */ cp->c_start.tv_sec = 0; cp->c_start.tv_usec = 0; cp->c_stop.tv_sec = 0; cp->c_stop.tv_usec = 0; #if 0 cp->c_period.tv_sec = 0; cp->c_period.tv_usec = 0; #endif cp->c_state = 0; #if 0 cp->c_ping = 0; #endif cp->c_schedule = call; cp->c_ts_msw = 0; cp->c_ts_lsw = 0; cp->c_options = 0; cp->c_buffer = NULL; cp->c_size = 0; cp->c_sealed = 0; cp->c_limit = MTU_POCO - PACKET_OVERHEAD_POCO; cp->c_used = 8; /* always have a header */ cp->c_failures = 0; cp->c_dump = NULL; cp->c_toggle = NULL; cp->c_destroy = NULL; cp->c_name = strdup(name); if(cp->c_name == NULL){ destroy_capture_poco(d, cp); return -1; } cp->c_buffer = malloc(cp->c_limit); if(cp->c_buffer == NULL){ destroy_capture_poco(d, cp); return -1; } cp->c_size = cp->c_limit; sp->p_captures[sp->p_size] = cp; sp->p_size++; return 0; }