Merge branch 'dingo' into merge-replace
This commit is contained in:
8
site_ansto/TESTS/dingo_camera/Makefile
Normal file
8
site_ansto/TESTS/dingo_camera/Makefile
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
# vim: ft=make: ts=8: sw=8: noet: cindent:
|
||||||
|
|
||||||
|
all: camera_test.c ../../hardsup/camera.c ../../hardsup/camera.h
|
||||||
|
gcc -g -Wall -Wextra -std=c99 -pedantic -I../../hardsup -o camera_test camera_test.c ../../hardsup/camera.c
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm camera_test
|
||||||
|
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
input: ECD_TK_SHOT :SCM_IDLE,SCL_RDY,SDR_IDLEcamdriv_out: symbol=EDR_BUSY, output=HWBUSY
|
||||||
|
input: ECM_IDLE :SCM_IDLE,SCL_TK_SHOT,SDR_BUSYcamdriv_out: symbol=ECA_TK_SHOT, output=take shot
|
||||||
194
site_ansto/TESTS/dingo_camera/camera_test.c
Normal file
194
site_ansto/TESTS/dingo_camera/camera_test.c
Normal file
@@ -0,0 +1,194 @@
|
|||||||
|
/**
|
||||||
|
* \file camera_test.c
|
||||||
|
* \brief Test camera.[ch] state machine.
|
||||||
|
*
|
||||||
|
* \Author Ferdi Franceschini February 2013
|
||||||
|
*/
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "camera.h"
|
||||||
|
|
||||||
|
|
||||||
|
void print_state(state_t s) {
|
||||||
|
char *cl, *cm, *dr;
|
||||||
|
cm = SCM_NAMES[s.cm];
|
||||||
|
cl = SCL_NAMES[s.cl];
|
||||||
|
dr = SDR_NAMES[s.dr];
|
||||||
|
printf("%s,%s,%s", cm, cl, dr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_event(event_t E) {
|
||||||
|
char *ca, *cm, *cd, *dr;
|
||||||
|
ca = event_names[E.ca];
|
||||||
|
cm = event_names[E.cm];
|
||||||
|
cd = event_names[E.cd];
|
||||||
|
dr = event_names[E.dr];
|
||||||
|
printf("%s,%s,%s,%s", ca, cm, cd, dr);
|
||||||
|
}
|
||||||
|
|
||||||
|
event_t output(state_t Sc, enum event_codes Ei) {
|
||||||
|
int i;
|
||||||
|
trans_t tr;
|
||||||
|
event_t Eo;
|
||||||
|
|
||||||
|
for (i=0; tr=TRANS_TABLE[i], tr.Sc.dr!= END_TABLE; i++) {
|
||||||
|
if (Ei==tr.Ei && INSYS(Sc,tr.Sc)) {
|
||||||
|
EVset(&Eo,tr.Eo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Eo;
|
||||||
|
}
|
||||||
|
|
||||||
|
int test_camrep2sym(void) {
|
||||||
|
int i, cm_sym, time_rem, time_tot;
|
||||||
|
enum event_codes ca_sym;
|
||||||
|
char *camrep[] = {
|
||||||
|
"StartTime Remaining= 3907 ms, Total Time=3686 ms,",
|
||||||
|
"Open ShutrTime Remaining= 539454 ms, Total Time=3686 ms,",
|
||||||
|
"Acq ImageTime Remaining= 109 ms, Total Time=3686 ms,",
|
||||||
|
"Close ShutrTime Remaining= 218 ms, Total Time=3686 ms,",
|
||||||
|
"Read ImageTime Remaining= 328 ms, Total Time=3686 ms,",
|
||||||
|
"Read ImageTime Remaining= 328 ms, Total Time=3686 ms,",
|
||||||
|
"Read ImageTime Remaining= 328 ms, Total Time=3686 ms,",
|
||||||
|
"Idle",
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
fprintf(stderr, "TEST_CAMREP2SYM:DESCRIPTION: Parse camera status messages and convert them to camera events and camera model events\n");
|
||||||
|
fprintf(stderr, "TEST_CAMREP2SYM:DESCRIPTION: Output format = 'status message' => camera_symbol => camera_model_symbol\n");
|
||||||
|
fprintf(stderr, "TEST_CAMREP2SYM:OUTPUT:START\n");
|
||||||
|
for (i=0; camrep[i] != NULL; i++) {
|
||||||
|
if ( cam_parse_status(camrep[i], &ca_sym, &time_rem, &time_tot) == -1)
|
||||||
|
exit(1);
|
||||||
|
else {
|
||||||
|
cm_sym = camera_model(ca_sym);
|
||||||
|
if (ECA_IDLE==ca_sym)
|
||||||
|
printf("'%s' => %s => %s\n",
|
||||||
|
camrep[i], event_names[ca_sym], event_names[cm_sym]);
|
||||||
|
else
|
||||||
|
printf("'%s' => %s => %s: time remaining = %d, total time = %d\n",
|
||||||
|
camrep[i], event_names[ca_sym], event_names[cm_sym],
|
||||||
|
time_rem, time_tot);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fprintf(stderr, "TEST_CAMREP2SYM:OUTPUT:END\n\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int test_trans_fn(void) {
|
||||||
|
int i;
|
||||||
|
event_t Eo={0,0,0,0};
|
||||||
|
|
||||||
|
|
||||||
|
state_t Sc = {.cl=SCL_RDY, .cm=SCM_IDLE, .dr=SDR_IDLE};
|
||||||
|
int input[] = {
|
||||||
|
ECM_IDLE, ECD_TK_SHOT, ECM_IDLE, ECM_IDLE, ECM_ACQ, ECD_TK_SHOT,
|
||||||
|
ECM_PROC, ECD_TK_SHOT, ECM_PROC, ECM_IDLE, ECM_ACQ,
|
||||||
|
ECM_PROC, ECM_IDLE, 0
|
||||||
|
};
|
||||||
|
|
||||||
|
fprintf(stderr, "TEST_TRANS_FN:DESCRIPTION: Test the state transitions. Each line of ouput has three fields.\n");
|
||||||
|
fprintf(stderr, "TEST_TRANS_FN:DESCRIPTION: Output pattern ~= Ein Scurr Eout\n");
|
||||||
|
fprintf(stderr, "TEST_TRANS_FN:DESCRIPTION: You can follow the transitions by reading down the Scurr column\n");
|
||||||
|
fprintf(stderr, "TEST_TRANS_FN:OUTPUT:START\n");
|
||||||
|
printf("INPUT,\tCURR SCM,CURR SCL,CURR SDR,\tCA OUT,CM OUT,CD OUT,DR OUT\n");
|
||||||
|
for (i=0; input[i]; i++) {
|
||||||
|
EVclr(&Eo);
|
||||||
|
printf("%s,\t",event_names[input[i]]);
|
||||||
|
print_state(Sc);
|
||||||
|
cam_trans_fn(Sc, input[i], &Sc, &Eo);
|
||||||
|
printf(",\t");
|
||||||
|
print_event(Eo);
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
fprintf(stderr, "TEST_TRANS_FN:OUTPUT:END\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int camdriv_out(void *me, event_t Eo) {
|
||||||
|
int *self = me; *self=0; /* shudduppa your warnings */
|
||||||
|
if (Eo.ca) {
|
||||||
|
printf("camdriv_out: symbol=%s, output=%s\n", event_names[Eo.ca], event_signatures[Eo.ca]);
|
||||||
|
}
|
||||||
|
if (Eo.cm) {
|
||||||
|
printf("camdriv_out: symbol=%s, output=%s\n", event_names[Eo.cm], event_signatures[Eo.cm]);
|
||||||
|
}
|
||||||
|
if (Eo.cd) {
|
||||||
|
printf("camdriv_out: symbol=%s, output=%s\n", event_names[Eo.cd], event_signatures[Eo.cd]);
|
||||||
|
}
|
||||||
|
if (Eo.dr) {
|
||||||
|
printf("camdriv_out: symbol=%s, output=%s\n", event_names[Eo.dr], event_signatures[Eo.dr]);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int test_camdriv_event_io(void) {
|
||||||
|
int Ein=ECD_TK_SHOT;
|
||||||
|
int self;
|
||||||
|
camsm_t cdinfo = {
|
||||||
|
.Sc = {.cl=SCL_RDY, .cm=SCM_IDLE, .dr=SDR_IDLE},
|
||||||
|
.Eo = {.ca=0},
|
||||||
|
.multi = 0,
|
||||||
|
.output_fn = camdriv_out,
|
||||||
|
};
|
||||||
|
|
||||||
|
fprintf(stderr, "TEST_CAMDRIVER_EVENT_IO:DESCRIPTION: Test State machine output_fn callback\n");
|
||||||
|
fprintf(stderr, "TEST_CAMDRIVER_EVENT_IO:DESCRIPTION: Output pattern ~= Ein:Scurr:Eo:output message\n");
|
||||||
|
fprintf(stderr, "TEST_CAMDRIVER_EVENT_IO:OUPUT:START\n");
|
||||||
|
|
||||||
|
printf("input: %s :", event_names[Ein]);
|
||||||
|
print_state(cdinfo.Sc);
|
||||||
|
camdriv_input(&self, &cdinfo, Ein);
|
||||||
|
|
||||||
|
Ein = ECM_IDLE;
|
||||||
|
printf("input: %s :", event_names[Ein]);
|
||||||
|
cdinfo.Sc.cl=SCL_TK_SHOT;
|
||||||
|
print_state(cdinfo.Sc);
|
||||||
|
camdriv_input(&self, &cdinfo, Ein);
|
||||||
|
|
||||||
|
fprintf(stderr, "TEST_CAMDRIVER_EVENT_IO:OUPUT:END\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *tests[] = {"camrep2sym", "trans_fn", "camdriv_input"};
|
||||||
|
void usage(char *name) {
|
||||||
|
int i;
|
||||||
|
printf("Usage: %s [n]\n",name);
|
||||||
|
printf("default: run all tests\n");
|
||||||
|
printf("n is an int whose bits indicate which tests will be executed as follows\n");
|
||||||
|
for (i=0; i<3; i++)
|
||||||
|
printf("n=%d; %s\n",1 << i, tests[i]);
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
int ret, test=0, tflag=7;
|
||||||
|
|
||||||
|
if (argc == 1)
|
||||||
|
test = tflag;
|
||||||
|
else if (strstr(argv[1], "help")) {
|
||||||
|
usage(argv[0]);
|
||||||
|
return 0;
|
||||||
|
} else
|
||||||
|
test = atoi(argv[1]);
|
||||||
|
|
||||||
|
if ((test < 1) || (test > tflag)) {
|
||||||
|
printf("ERROR: Argument must be a positive integer between 1 and %d inclusive\n", tflag);
|
||||||
|
usage(argv[0]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (test & 1)
|
||||||
|
ret = test_camrep2sym();
|
||||||
|
if (test & 2)
|
||||||
|
ret = test_trans_fn();
|
||||||
|
if (test & 4)
|
||||||
|
ret = test_camdriv_event_io();
|
||||||
|
|
||||||
|
if (ret)
|
||||||
|
return 0;
|
||||||
|
else
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
8
site_ansto/TESTS/dingo_camera/camrep2sym_expect.txt
Normal file
8
site_ansto/TESTS/dingo_camera/camrep2sym_expect.txt
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
'StartTime Remaining= 3907 ms, Total Time=3686 ms,' => ECA_START => ECM_ACQ: time remaining = 3907, total time = 3686
|
||||||
|
'Open ShutrTime Remaining= 539454 ms, Total Time=3686 ms,' => ECA_OPEN_SHUTR => ECM_ACQ: time remaining = 539454, total time = 3686
|
||||||
|
'Acq ImageTime Remaining= 109 ms, Total Time=3686 ms,' => ECA_ACQ_IMAGE => ECM_ACQ: time remaining = 109, total time = 3686
|
||||||
|
'Close ShutrTime Remaining= 218 ms, Total Time=3686 ms,' => ECA_CLOSE_SHUTR => ECM_PROC: time remaining = 218, total time = 3686
|
||||||
|
'Read ImageTime Remaining= 328 ms, Total Time=3686 ms,' => ECA_READ_IMAGE => ECM_PROC: time remaining = 328, total time = 3686
|
||||||
|
'Read ImageTime Remaining= 328 ms, Total Time=3686 ms,' => ECA_READ_IMAGE => ECM_PROC: time remaining = 328, total time = 3686
|
||||||
|
'Read ImageTime Remaining= 328 ms, Total Time=3686 ms,' => ECA_READ_IMAGE => ECM_PROC: time remaining = 328, total time = 3686
|
||||||
|
'Idle' => ECA_IDLE => ECM_IDLE
|
||||||
14
site_ansto/TESTS/dingo_camera/trans_fn_expect.txt
Normal file
14
site_ansto/TESTS/dingo_camera/trans_fn_expect.txt
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
INPUT, CURR SCM,CURR SCL,CURR SDR, CA OUT,CM OUT,CD OUT,DR OUT
|
||||||
|
ECM_IDLE, SCM_IDLE,SCL_RDY,SDR_IDLE, 0,0,0,0
|
||||||
|
ECD_TK_SHOT, SCM_IDLE,SCL_RDY,SDR_IDLE, 0,0,0,EDR_BUSY
|
||||||
|
ECM_IDLE, SCM_IDLE,SCL_TK_SHOT,SDR_BUSY, ECA_TK_SHOT,0,0,0
|
||||||
|
ECM_IDLE, SCM_IDLE,SCL_WT,SDR_BUSY, 0,0,0,0
|
||||||
|
ECM_ACQ, SCM_IDLE,SCL_RDY,SDR_BUSY, 0,0,0,0
|
||||||
|
ECD_TK_SHOT, SCM_ACQ,SCL_RDY,SDR_BUSY, 0,0,0,0
|
||||||
|
ECM_PROC, SCM_ACQ,SCL_RDY,SDR_BUSY, 0,0,0,EDR_IDLE
|
||||||
|
ECD_TK_SHOT, SCM_PROC,SCL_RDY,SDR_IDLE, 0,0,0,EDR_BUSY
|
||||||
|
ECM_PROC, SCM_PROC,SCL_TK_SHOT,SDR_BUSY, 0,0,0,0
|
||||||
|
ECM_IDLE, SCM_PROC,SCL_TK_SHOT,SDR_BUSY, ECA_TK_SHOT,0,0,0
|
||||||
|
ECM_ACQ, SCM_IDLE,SCL_WT,SDR_BUSY, 0,0,0,0
|
||||||
|
ECM_PROC, SCM_ACQ,SCL_RDY,SDR_BUSY, 0,0,0,EDR_IDLE
|
||||||
|
ECM_IDLE, SCM_PROC,SCL_RDY,SDR_IDLE, 0,0,0,0
|
||||||
4
site_ansto/cameradriver.h
Normal file
4
site_ansto/cameradriver.h
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
#ifndef CAMERADRIVER_H
|
||||||
|
#define CAMERADRIVER_H
|
||||||
|
void CameraInitProtocol(SicsInterp *pSics);
|
||||||
|
#endif
|
||||||
218
site_ansto/hardsup/camera.c
Normal file
218
site_ansto/hardsup/camera.c
Normal file
@@ -0,0 +1,218 @@
|
|||||||
|
/**
|
||||||
|
* \file camera.c
|
||||||
|
* \brief Defines the state transition table and implements the state transition function
|
||||||
|
*
|
||||||
|
* \Author Ferdi Franceschini February 2013
|
||||||
|
*
|
||||||
|
* Copyright: see file Copyright.txt
|
||||||
|
*/
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "camera.h"
|
||||||
|
|
||||||
|
#define TR(a,b) #a,
|
||||||
|
#define TE(a,b) #a
|
||||||
|
char *event_names[] = { "0", CAMERA_CMDS_TABLE, CAMERA_MSGS_TABLE, CAM_MOD_EVENT_TABLE, DRIVER_EVENT_TABLE, CMD_EVENT_TABLE };
|
||||||
|
#undef TR
|
||||||
|
#undef TE
|
||||||
|
|
||||||
|
/* The signature array defines the identifying characters at the start of a reply. */
|
||||||
|
#define TR(a,b) b,
|
||||||
|
#define TE(a,b) b
|
||||||
|
char *event_signatures[] = { "0", CAMERA_CMDS_TABLE, CAMERA_MSGS_TABLE, CAM_MOD_EVENT_TABLE, DRIVER_EVENT_TABLE, CMD_EVENT_TABLE };
|
||||||
|
#undef TR
|
||||||
|
#undef TE
|
||||||
|
|
||||||
|
#define TR(a,b) #a,
|
||||||
|
#define TE(a,b) #a
|
||||||
|
char *SCL_NAMES[] = {"0", COMMAND_LATCH_STATE_TABLE};
|
||||||
|
char *SCM_NAMES[] = {"0", CAMERA_MODEL_STATE_TABLE};
|
||||||
|
char *SDR_NAMES[] = {"0", DRIVER_STATE_TABLE};
|
||||||
|
#undef TR
|
||||||
|
#undef TE
|
||||||
|
|
||||||
|
#define TR(a,b) b,
|
||||||
|
#define TE(a,b) b
|
||||||
|
char *COMMAND_LATCH_STATE_DESCRIPTION[] = {"0", COMMAND_LATCH_STATE_TABLE};
|
||||||
|
char *CAMERA_MODEL_STATE_DESCRIPTION[] = {"0", CAMERA_MODEL_STATE_TABLE};
|
||||||
|
char *DRIVER_STATE_DESCRIPTION[] = {"0", DRIVER_STATE_TABLE};
|
||||||
|
#undef TR
|
||||||
|
#undef TE
|
||||||
|
|
||||||
|
char state_str[SSLEN+1];
|
||||||
|
char event_str[ESLEN+1];
|
||||||
|
/* Clear event channel */
|
||||||
|
void EVclr(event_t *E) {
|
||||||
|
E->ca=0;
|
||||||
|
E->cm=0;
|
||||||
|
E->cd=0;
|
||||||
|
E->dr=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set event channel */
|
||||||
|
void EVset(event_t *E, event_t Ev) {
|
||||||
|
if (Ev.ca) E->ca = Ev.ca;
|
||||||
|
if (Ev.cm) E->cm = Ev.cm;
|
||||||
|
if (Ev.cd) E->cd = Ev.cd;
|
||||||
|
if (Ev.dr) E->dr = Ev.dr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set system state */
|
||||||
|
void STset(state_t *Sc, state_t St) {
|
||||||
|
if (St.cl) Sc->cl = St.cl;
|
||||||
|
if (St.cm) Sc->cm = St.cm;
|
||||||
|
if (St.dr) Sc->dr = St.dr;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum event_codes camera_model(enum event_codes event) {
|
||||||
|
switch (event) {
|
||||||
|
case ECA_START:
|
||||||
|
case ECA_OPEN_SHUTR:
|
||||||
|
case ECA_ACQ_IMAGE:
|
||||||
|
return ECM_ACQ;
|
||||||
|
|
||||||
|
case ECA_CLOSE_SHUTR:
|
||||||
|
case ECA_READ_IMAGE:
|
||||||
|
case ECA_SEND_IMAGE:
|
||||||
|
return ECM_PROC;
|
||||||
|
|
||||||
|
case ECA_STOP:
|
||||||
|
return ECM_STOP;
|
||||||
|
case ECA_IDLE:
|
||||||
|
return ECM_IDLE;
|
||||||
|
case ECA_FAIL:
|
||||||
|
return ECM_FAIL;
|
||||||
|
default:
|
||||||
|
return ECM_UNKNOWN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int cam_parse_status(char *msg, enum event_codes *ca_sym, int *time_rem, int *time_tot) {
|
||||||
|
char *delim=" ,";
|
||||||
|
char str[100], *tok;
|
||||||
|
int ret = 1;
|
||||||
|
|
||||||
|
strcpy(str,msg);
|
||||||
|
tok=strtok(str,delim);
|
||||||
|
ret = cam_rep2sym(tok);
|
||||||
|
if (ret != -1) {
|
||||||
|
*ca_sym = ret;
|
||||||
|
if (ECA_IDLE == *ca_sym) {
|
||||||
|
*time_rem = *time_tot = -1;
|
||||||
|
} else {
|
||||||
|
tok=strstr(msg, "Remaining");
|
||||||
|
sscanf(tok, " Remaining= %d ms, Total Time= %d ms, ", time_rem, time_tot);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* return -1 if message is unknown
|
||||||
|
* NOTE: 0 has meaning in the transition table
|
||||||
|
*/
|
||||||
|
enum event_codes cam_rep2sym(char *msg) {
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = ECA_START; i <= ECA_STOP; i++) {
|
||||||
|
if (0 == strcmp(msg, event_signatures[i])) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* return 0 = no transition,
|
||||||
|
* return 1 = transition
|
||||||
|
*/
|
||||||
|
int cam_trans_fn(state_t Sc, enum event_codes Ein, state_t *Sn, event_t *Eo) {
|
||||||
|
trans_t tt;
|
||||||
|
int i, ret=0;
|
||||||
|
|
||||||
|
STset(Sn, Sc);
|
||||||
|
EVclr(Eo);
|
||||||
|
for (i=0; tt=TRANS_TABLE[i], tt.Sc.dr != END_TABLE; i++) {
|
||||||
|
if ( Ein == tt.Ei && INSYS(Sc,tt.Sc)) {
|
||||||
|
STset(Sn, tt.Sn);
|
||||||
|
EVset(Eo, tt.Eo);
|
||||||
|
ret = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO Do we need Eo in self, should camsm_t be refactored to remove it? */
|
||||||
|
void camdriv_input(void *caller, camsm_t *self, enum event_codes event_sym) {
|
||||||
|
state_t Sn;
|
||||||
|
cam_trans_fn(self->Sc, event_sym, &Sn, &self->Eo);
|
||||||
|
self->output_fn(caller, self->Eo);
|
||||||
|
self->Sc = Sn;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *strstate(state_t s) {
|
||||||
|
char *cl, *cm, *dr;
|
||||||
|
cm = SCM_NAMES[s.cm];
|
||||||
|
cl = SCL_NAMES[s.cl];
|
||||||
|
dr = SDR_NAMES[s.dr];
|
||||||
|
snprintf(state_str, SSLEN, "%s,%s,%s", cm, cl, dr);
|
||||||
|
return state_str;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *strevent(event_t E) {
|
||||||
|
char *ca, *cm, *cd, *dr;
|
||||||
|
ca = event_names[E.ca];
|
||||||
|
cm = event_names[E.cm];
|
||||||
|
cd = event_names[E.cd];
|
||||||
|
dr = event_names[E.dr];
|
||||||
|
snprintf(event_str, ESLEN, "%s,%s,%s,%s", ca, cm, cd, dr);
|
||||||
|
return event_str;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The transition table has four columns,
|
||||||
|
* {current state}, input_event, {output events}, {next state}
|
||||||
|
*
|
||||||
|
* Each state is actually a 3-tuple (cl,cm,dr) where
|
||||||
|
* cl = command latch state
|
||||||
|
* cm = camera model state
|
||||||
|
* dr = driver state
|
||||||
|
*
|
||||||
|
* There is only one stream in the input event channel.
|
||||||
|
*
|
||||||
|
* The output event channel is a 4-tuple (ca,cm,cd,dr) where
|
||||||
|
* ca = camera event stream
|
||||||
|
* cm = cameram model event stream
|
||||||
|
* cd = command event stream
|
||||||
|
* dr = driver event stream
|
||||||
|
*
|
||||||
|
* The next state is a 3-tuple as above.
|
||||||
|
*
|
||||||
|
* 0 = wildcard for components of current state.
|
||||||
|
* 0 = no output for the output events.
|
||||||
|
* 0 = no change for components of next state.
|
||||||
|
*/
|
||||||
|
trans_t TRANS_TABLE[] = {
|
||||||
|
{{.cl=SCL_RDY, .dr=SDR_IDLE}, ECD_TK_SHOT, {.dr=0}, {.cl=SCL_TK_SHOT}},
|
||||||
|
{{.cl=SCL_RDY, .dr=SDR_IDLE}, ECD_MLTI_ON, {.dr=0}, {.cl=SCL_TK_MLTI}},
|
||||||
|
{{.cl=SCL_TK_SHOT}, ECM_IDLE, {.ca=ECA_TK_SHOT}, {.cl=SCL_WT}},
|
||||||
|
{{.cl=SCL_TK_MLTI}, ECD_MLTI_OFF,{.dr=0}, {.cl=SCL_RDY}},
|
||||||
|
{{.cl=SCL_TK_MLTI}, ECM_IDLE, {.ca=ECA_MLTI_ON}, {.cl=SCL_MLTI_ON}},
|
||||||
|
{{.cl=SCL_MLTI_ON}, ECD_MLTI_OFF,{.ca=ECA_MLTI_OFF},{.cl=SCL_WT}},
|
||||||
|
{{.cl=SCL_WT}, ECM_ACQ, {.dr=0}, {.cl=SCL_RDY}},
|
||||||
|
{{.cl=SCL_WT}, ECM_PROC, {.dr=0}, {.cl=SCL_RDY}},
|
||||||
|
{{.cl=SCL_WT}, ECM_STOP, {.dr=0}, {.cl=SCL_RDY}},
|
||||||
|
{{.cl=SCL_WT}, ECM_IDLE, {.dr=0}, {.cl=SCL_RDY}},
|
||||||
|
|
||||||
|
{{.cm=SCM_IDLE}, ECM_ACQ, {.dr=0}, {.cm=SCM_ACQ}},
|
||||||
|
{{.cm=SCM_IDLE}, ECM_PROC, {.dr=0}, {.cm=SCM_PROC}},
|
||||||
|
{{.cm=SCM_ACQ}, ECM_PROC, {.dr=0}, {.cm=SCM_PROC}},
|
||||||
|
{{.cm=SCM_ACQ}, ECM_STOP, {.dr=0}, {.cm=SCM_IDLE}},
|
||||||
|
{{.cm=SCM_PROC}, ECM_STOP, {.dr=0}, {.cm=SCM_IDLE}},
|
||||||
|
{{.cm=SCM_ACQ}, ECM_IDLE, {.dr=0}, {.cm=SCM_IDLE}},
|
||||||
|
{{.cm=SCM_PROC}, ECM_IDLE, {.dr=0}, {.cm=SCM_IDLE}},
|
||||||
|
|
||||||
|
{{.dr=SDR_IDLE}, ECD_TK_SHOT, {.dr=EDR_BUSY}, {.dr=SDR_BUSY}},
|
||||||
|
{{.dr=SDR_IDLE}, ECD_MLTI_ON, {.dr=EDR_BUSY}, {.dr=SDR_BUSY}},
|
||||||
|
{{.dr=SDR_BUSY, .cl=SCL_RDY}, ECM_PROC, {.dr=EDR_IDLE}, {.dr=SDR_IDLE}},
|
||||||
|
{{.dr=SDR_BUSY, .cl=SCL_RDY}, ECM_STOP, {.dr=EDR_IDLE}, {.dr=SDR_IDLE}},
|
||||||
|
{{.dr=SDR_BUSY, .cl=SCL_RDY}, ECM_IDLE, {.dr=EDR_IDLE}, {.dr=SDR_IDLE}},
|
||||||
|
{{.dr=END_TABLE}, END_TABLE, {.dr=END_TABLE}, {.dr=END_TABLE}}
|
||||||
|
};
|
||||||
247
site_ansto/hardsup/camera.h
Normal file
247
site_ansto/hardsup/camera.h
Normal file
@@ -0,0 +1,247 @@
|
|||||||
|
/**
|
||||||
|
* \file camera.h
|
||||||
|
* \brief Enumerates event codes and states, and defines the abstract
|
||||||
|
* types used in the state machine.
|
||||||
|
*
|
||||||
|
* \Author Ferdi Franceschini February 2013
|
||||||
|
*
|
||||||
|
* Copyright: see file Copyright.txt
|
||||||
|
*
|
||||||
|
* Deterministic Finite State machine transducer (Mealy)
|
||||||
|
* The idea is to synthesize a state machine which handles the union of input
|
||||||
|
* events for a given set state machines in a system.
|
||||||
|
*
|
||||||
|
* The system is made up of three components, a command latch (CL), a camera
|
||||||
|
* model (CM) and the driver (DR). The system state machine is considered to be
|
||||||
|
* made up of the component state machines running in parallel and with some of
|
||||||
|
* the component state machine transitions being restricted by system state
|
||||||
|
* transition rules.
|
||||||
|
* The sets of states are,
|
||||||
|
* SCL:Command Latch states, SCM:Camera Model states, SCDR:Driver states.
|
||||||
|
* Q is the set of system states.
|
||||||
|
* The sets of event symbols are defined as,
|
||||||
|
* ECA:Camera events, ECM:Camera model events, ECD:User command events,
|
||||||
|
* EDR:Driver events.
|
||||||
|
*
|
||||||
|
* The system state machine for the camera driver is defined as follows.
|
||||||
|
* In the following, '<' means subset
|
||||||
|
* Q < SCL X SCM X SCDR
|
||||||
|
* Ein = ECA U ECM U ECD U EDR
|
||||||
|
* Eo < ECA X ECM X ECD X EDR
|
||||||
|
* trans fn: QXEin -> Q
|
||||||
|
* out fn : QXEin -> Eo
|
||||||
|
*
|
||||||
|
* In the implementation the transition and output functions are combined in
|
||||||
|
* TRANS_TABLE.
|
||||||
|
*/
|
||||||
|
#ifndef CAMERA_H
|
||||||
|
#define CAMERA_H
|
||||||
|
|
||||||
|
/* END_TABLE marks the last row in the transition table */
|
||||||
|
#define END_TABLE -1
|
||||||
|
/* EVENT CODES */
|
||||||
|
/* All event enum constants start with 'EXX_', XX identifies the source
|
||||||
|
* ECA_ : Camera event stream. Messages destined for or received from the camera.
|
||||||
|
* ECM_ : Events from the camera model.
|
||||||
|
* ECD_ : Command input, either directly from a user or via the scan command
|
||||||
|
* EDR_ : Driver events
|
||||||
|
*/
|
||||||
|
#define CAMERA_CMDS_TABLE \
|
||||||
|
TR(ECA_SET_CAM, "set camera") \
|
||||||
|
TR(ECA_TK_SHOT, "take shot") \
|
||||||
|
TR(ECA_MLTI_ON, "take multi on") \
|
||||||
|
TR(ECA_MLTI_OFF, "take multi off") \
|
||||||
|
TR(ECA_GET_STATUS, "get status") \
|
||||||
|
TE(ECA_GET_STATE, "get state")
|
||||||
|
|
||||||
|
#define CAMERA_MSGS_TABLE \
|
||||||
|
TR(ECA_START, "StartTime") \
|
||||||
|
TR(ECA_OK, "OK") \
|
||||||
|
TR(ECA_FAIL, "Fail") \
|
||||||
|
TR(ECA_IDLE, "Idle") \
|
||||||
|
TR(ECA_OPEN_SHUTR, "Open") \
|
||||||
|
TR(ECA_CLOSE_SHUTR, "Close") \
|
||||||
|
TR(ECA_ACQ_IMAGE, "Acq") \
|
||||||
|
TR(ECA_READ_IMAGE, "Read") \
|
||||||
|
TR(ECA_SEND_IMAGE, "Send") \
|
||||||
|
TE(ECA_STOP, "Stop")
|
||||||
|
|
||||||
|
#define CAM_MOD_EVENT_TABLE \
|
||||||
|
TR(ECM_UNKNOWN, "Stop message received from camera") \
|
||||||
|
TR(ECM_STOP, "Stop message received from camera") \
|
||||||
|
TR(ECM_IDLE, "Camera in idle state") \
|
||||||
|
TR(ECM_FAIL, "Command rejected") \
|
||||||
|
TR(ECM_ACQ, "catch-all for start of acq phase") \
|
||||||
|
TE(ECM_PROC, "catch-all for end of acq phase")
|
||||||
|
|
||||||
|
/* COMMAND EVENTS
|
||||||
|
* These are events triggered by user input.
|
||||||
|
* The events can be direct via the 'send' subcommand or
|
||||||
|
* indirect via the scan command through the counter interface.
|
||||||
|
*/
|
||||||
|
#define CMD_EVENT_TABLE \
|
||||||
|
TR(ECD_CLEAR, "Clear latched command") \
|
||||||
|
TR(ECD_TK_SHOT, "take shot") \
|
||||||
|
TR(ECD_MLTI_ON, "take multi on") \
|
||||||
|
TR(ECD_MLTI_OFF, "take multi off") \
|
||||||
|
TR(ECD_GET_STATE, "get state") \
|
||||||
|
TE(ECD_GET_STATUS, "get status")
|
||||||
|
|
||||||
|
/* DRIVER EVENT TABLE
|
||||||
|
* These events are of interest to SICS.
|
||||||
|
*/
|
||||||
|
#define DRIVER_EVENT_TABLE \
|
||||||
|
TR(EDR_IDLE, "HWIDLE") \
|
||||||
|
TR(EDR_BUSY, "HWBUSY") \
|
||||||
|
TE(EDR_FAULT, "HWFAULT")
|
||||||
|
|
||||||
|
#define ESLEN 32
|
||||||
|
|
||||||
|
/* STATE CODES
|
||||||
|
* SXX_ State code enum constants, XX identifies a component of the system.
|
||||||
|
* SCL_ Command latch states
|
||||||
|
* SCM_ Camera model states
|
||||||
|
* SDR_ Driver states
|
||||||
|
*/
|
||||||
|
#define COMMAND_LATCH_STATE_TABLE \
|
||||||
|
TR(SCL_RDY, "command latch ready to accept") \
|
||||||
|
TR(SCL_TK_SHOT, "latched a take shot command") \
|
||||||
|
TR(SCL_TK_MLTI, "latched a multi-shot command") \
|
||||||
|
TR(SCL_MLTI_ON, "multi-shot is running") \
|
||||||
|
TE(SCL_WT, "waiting for camera to start acquisition")
|
||||||
|
|
||||||
|
#define CAMERA_MODEL_STATE_TABLE \
|
||||||
|
TR(SCM_IDLE, "Camera is idle") \
|
||||||
|
TR(SCM_ACQ, "Camera is acquiring an image") \
|
||||||
|
TE(SCM_PROC, "Camera is processing an image")
|
||||||
|
|
||||||
|
#define DRIVER_STATE_TABLE \
|
||||||
|
TR(SDR_IDLE, "HWIdle") \
|
||||||
|
TR(SDR_BUSY, "HWBusy") \
|
||||||
|
TE(SDR_FAULT, "HWFault")
|
||||||
|
|
||||||
|
#define SSLEN 32
|
||||||
|
|
||||||
|
/* Enumerate event and state symbols */
|
||||||
|
#define TR(a,b) a,
|
||||||
|
#define TE(a,b) a
|
||||||
|
enum event_codes {ECA_UNKNOWN, CAMERA_CMDS_TABLE, CAMERA_MSGS_TABLE, CAM_MOD_EVENT_TABLE, DRIVER_EVENT_TABLE, CMD_EVENT_TABLE};
|
||||||
|
#undef TR
|
||||||
|
#undef TE
|
||||||
|
|
||||||
|
#define TR(n,d) n,
|
||||||
|
#define TE(n,d) n
|
||||||
|
enum command_latch_states {CL_Z,COMMAND_LATCH_STATE_TABLE};
|
||||||
|
enum camera_model_states {CM_Z,CAMERA_MODEL_STATE_TABLE};
|
||||||
|
enum driver_states {DR_Z,DRIVER_STATE_TABLE};
|
||||||
|
#undef TR
|
||||||
|
#undef TE
|
||||||
|
|
||||||
|
extern char *SCL_NAMES[];
|
||||||
|
extern char *SCM_NAMES[];
|
||||||
|
extern char *SDR_NAMES[];
|
||||||
|
/* List of names generated from the event_codes. */
|
||||||
|
extern char *event_names[];
|
||||||
|
|
||||||
|
/* The signature array includes the identifying characters at the start of a reply.
|
||||||
|
* as well as camera commands or just describes the corresponding symbols.
|
||||||
|
*/
|
||||||
|
extern char *event_signatures[];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Output event channel
|
||||||
|
* A tuple (Eca,Ecm,Ecd,Edr) in ECA X ECM X ECD X EDR
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
enum event_codes ca;
|
||||||
|
enum event_codes cm;
|
||||||
|
enum event_codes cd;
|
||||||
|
enum event_codes dr;
|
||||||
|
} event_t;
|
||||||
|
|
||||||
|
/* A tuple (Scl,Scm,Sdr) in SCL X SCM X SDR */
|
||||||
|
typedef struct {
|
||||||
|
int cl;
|
||||||
|
int cm;
|
||||||
|
int dr;
|
||||||
|
} state_t;
|
||||||
|
|
||||||
|
/* Defines a row in the transition table */
|
||||||
|
typedef struct {
|
||||||
|
state_t Sc;
|
||||||
|
enum event_codes Ei;
|
||||||
|
event_t Eo;
|
||||||
|
state_t Sn;
|
||||||
|
} trans_t;
|
||||||
|
|
||||||
|
/* Transfer object for state machine IO and transitions
|
||||||
|
* output_fn: This is the output function callback. It must be defined by the
|
||||||
|
* IO layer (ie cameradriver.c).
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
state_t Sc;
|
||||||
|
event_t Eo;
|
||||||
|
int multi;
|
||||||
|
int debug;
|
||||||
|
int (*output_fn)(void *caller, event_t Eo);
|
||||||
|
} camsm_t;
|
||||||
|
|
||||||
|
/* Are we in the SCL_XX, SCM_ or SDR_ state?
|
||||||
|
* NOTE: 0 is a wildcard so any Sc.cl value matches St.cl==0
|
||||||
|
*/
|
||||||
|
#define INCL(Sc,St) (!St.cl || Sc.cl==St.cl)
|
||||||
|
#define INCM(Sc,St) (!St.cm || Sc.cm==St.cm)
|
||||||
|
#define INDR(Sc,St) (!St.dr || Sc.dr==St.dr)
|
||||||
|
/* INSYS is True if system state Sc is in St.
|
||||||
|
* St is normally the current state in the transition table
|
||||||
|
* and describes a range of possible states.
|
||||||
|
*/
|
||||||
|
#define INSYS(Sc,St) ( INCL(Sc,St) && INCM(Sc,St) && INDR(Sc,St) )
|
||||||
|
|
||||||
|
|
||||||
|
/* Clear the given event */
|
||||||
|
void EVclr(event_t *E);
|
||||||
|
/* Set E to Ev */
|
||||||
|
void EVset(event_t *E, event_t Ev);
|
||||||
|
/* Set Sc to St */
|
||||||
|
void STset(state_t *Sc, state_t St);
|
||||||
|
|
||||||
|
/* \brief Translates a camera status message to a camera (ECA_) event */
|
||||||
|
enum event_codes cam_rep2sym(char *msg);
|
||||||
|
|
||||||
|
/* \brief Converts a camera (ECA_) event to a camera modle (ECM_) event */
|
||||||
|
enum event_codes camera_model(enum event_codes event);
|
||||||
|
|
||||||
|
/* \brief Determines camera state from camera status message and reads acquisition
|
||||||
|
* time if camera is running.
|
||||||
|
* \param msg camera status message from the "get status" command.
|
||||||
|
* \param ca_sym symbol for the camera state in the status message, one of ECA_ enums.
|
||||||
|
* \param time_rem time remaining during while the camera is running.
|
||||||
|
* \param time_tot total time while the camera is running.
|
||||||
|
*/
|
||||||
|
int cam_parse_status(char *msg, enum event_codes *ca_sym, int *time_rem, int *time_tot);
|
||||||
|
|
||||||
|
/* \brief Transition function for the camera system state machine.
|
||||||
|
* \param Sc the current system state.
|
||||||
|
* \param Ein input event.
|
||||||
|
* \param Sn the next system state.
|
||||||
|
* \param Eo the output events.
|
||||||
|
*/
|
||||||
|
int cam_trans_fn(state_t Sc, enum event_codes Ein, state_t *Sn, event_t *Eo);
|
||||||
|
|
||||||
|
/* \brief This is the state machine input function called by the IO layer (ie cameradriver.c)
|
||||||
|
*
|
||||||
|
* \param caller, Provides context info for the ouput function callback.
|
||||||
|
* \param self, Provides current state on input and next state and output event on return.
|
||||||
|
*/
|
||||||
|
void camdriv_input(void *caller, camsm_t *self, enum event_codes event_sym);
|
||||||
|
|
||||||
|
/* Convenience functions to convert a state or event to a descriptive string */
|
||||||
|
char *strstate(state_t s);
|
||||||
|
char *strevent(event_t E);
|
||||||
|
|
||||||
|
/* The transition table */
|
||||||
|
extern trans_t TRANS_TABLE[];
|
||||||
|
#endif
|
||||||
798
site_ansto/hardsup/cameradriver.c
Normal file
798
site_ansto/hardsup/cameradriver.c
Normal file
@@ -0,0 +1,798 @@
|
|||||||
|
/**
|
||||||
|
* \file cameradriver.c
|
||||||
|
* \brief This provides the IO layer which feeds inputs from a user or
|
||||||
|
* the camera server to the state machine, and then sends any state machine
|
||||||
|
* output back to SICS or the camera.
|
||||||
|
*
|
||||||
|
* \Author Ferdi Franceschini February 2013
|
||||||
|
*
|
||||||
|
* Copyright: see file Copyright.txt
|
||||||
|
*/
|
||||||
|
#include <string.h>
|
||||||
|
#include <sics.h>
|
||||||
|
#include <obdes.h>
|
||||||
|
#include <countdriv.h>
|
||||||
|
#include <nwatch.h>
|
||||||
|
#include <asyncqueue.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include "camera.h"
|
||||||
|
|
||||||
|
#define ERRLEN 256
|
||||||
|
#define MSGLEN 512
|
||||||
|
|
||||||
|
enum camstates {idle, acquiring, processing, saving};
|
||||||
|
#define CAMDRIV_ERRTABLE \
|
||||||
|
TR(ENONE, "OK") \
|
||||||
|
TR(EFAIL, "command failed") \
|
||||||
|
TR(EBUSYACQ, "camera busy acquiring image") \
|
||||||
|
TR(EBUSYSAVE, "camera busy saving image") \
|
||||||
|
TE(EBUSYPROC, "camera busy processing image")
|
||||||
|
|
||||||
|
#define TR(a,b) a,
|
||||||
|
#define TE(a,b) a
|
||||||
|
enum errcodes {CAMDRIV_ERRTABLE};
|
||||||
|
#undef TR
|
||||||
|
#undef TE
|
||||||
|
|
||||||
|
#define TR(a,b) b,
|
||||||
|
#define TE(a,b) b
|
||||||
|
static char *errmsg[] = {CAMDRIV_ERRTABLE};
|
||||||
|
#undef TR
|
||||||
|
#undef TE
|
||||||
|
|
||||||
|
#define CAMDRIV_PARTABLE \
|
||||||
|
TR(CLOCK, "clock") \
|
||||||
|
TR(BIN, "bin") \
|
||||||
|
TR(SIZE, "size") \
|
||||||
|
TR(GAIN, "gain") \
|
||||||
|
TR(FLIP, "flip") \
|
||||||
|
TR(XSTART, "xstart") \
|
||||||
|
TR(YSTART, "ystart") \
|
||||||
|
TR(XEND, "xend") \
|
||||||
|
TR(YEND, "yend") \
|
||||||
|
TR(EXPOSURE, "exposure") \
|
||||||
|
TR(TEMP, "temperature") \
|
||||||
|
TR(THRESH, "threshold") \
|
||||||
|
TR(SHOPT, "shutteropentime") \
|
||||||
|
TE(SHCLT, "shutterclosetime")
|
||||||
|
#define TR(a,b) 1+
|
||||||
|
#define TE(a,b) 1
|
||||||
|
static int NUMCAMPAR = CAMDRIV_PARTABLE;
|
||||||
|
#undef TR
|
||||||
|
#undef TE
|
||||||
|
|
||||||
|
#define FLIP_TABLE \
|
||||||
|
TR(NORMAL, "normal") \
|
||||||
|
TR(INVINT, "invintensity") \
|
||||||
|
TR(NORMFH, "normfh") \
|
||||||
|
TR(NORMFV, "normfv") \
|
||||||
|
TR(NORMFHV, "normfhv") \
|
||||||
|
TR(INVFH, "invfh") \
|
||||||
|
TR(INVFV, "invfv") \
|
||||||
|
TE(INVFHV, "invfhv")
|
||||||
|
|
||||||
|
#define TR(a,b) a,
|
||||||
|
#define TE(a,b) a
|
||||||
|
enum campar {CAMDRIV_PARTABLE, MULTI};
|
||||||
|
enum flipval {FLIP_TABLE};
|
||||||
|
#undef TR
|
||||||
|
#undef TE
|
||||||
|
|
||||||
|
#define TR(a,b) b,
|
||||||
|
#define TE(a,b) b
|
||||||
|
static char *cacmdstr[] = {CAMDRIV_PARTABLE, "multi", NULL};
|
||||||
|
static char *flipcmdstr[] = {FLIP_TABLE, NULL};
|
||||||
|
#undef TR
|
||||||
|
#undef TE
|
||||||
|
|
||||||
|
// Camera get/set commands: ['status', 'info', 'state', 'camera', 'meta', 'file']
|
||||||
|
#define ECMDSTART 0
|
||||||
|
#define EGETSTART 100
|
||||||
|
#define ESETSTART 200
|
||||||
|
typedef struct {
|
||||||
|
float clockMHz;
|
||||||
|
float bin;
|
||||||
|
float size;
|
||||||
|
float gain;
|
||||||
|
enum flipval flip;
|
||||||
|
float xstart;
|
||||||
|
float ystart;
|
||||||
|
float xend;
|
||||||
|
float yend;
|
||||||
|
float exposure;
|
||||||
|
float temp;
|
||||||
|
float thresh;
|
||||||
|
float shopt;
|
||||||
|
float shclt;
|
||||||
|
int updatecfg;
|
||||||
|
} camcfg_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char path[MSGLEN];
|
||||||
|
char basename[MSGLEN];
|
||||||
|
int startnumber;
|
||||||
|
char imageformat[MSGLEN];
|
||||||
|
char experimentdetail[MSGLEN];
|
||||||
|
int updatecfg;
|
||||||
|
} filecfg_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int debug;
|
||||||
|
char *asynq;
|
||||||
|
camsm_t state_machine;
|
||||||
|
pNWTimer state_timer;
|
||||||
|
int status;
|
||||||
|
enum errcodes camError;
|
||||||
|
camcfg_t camera;
|
||||||
|
/* filecfg_t file;*/
|
||||||
|
pAsyncUnit asyncUnit;
|
||||||
|
} CamObj;
|
||||||
|
|
||||||
|
/* Camera communications and protocol handlers */
|
||||||
|
static pAsyncProtocol CAM_Protocol = NULL;
|
||||||
|
static int cb_state_timer(void *ctx, int mode);
|
||||||
|
static int cb_getstate(pAsyncTxn txn);
|
||||||
|
|
||||||
|
static void CAM_Notify(void* context, int event) {
|
||||||
|
CamObj *self = (CamObj *) context;
|
||||||
|
|
||||||
|
switch (event) {
|
||||||
|
case AQU_DISCONNECT:
|
||||||
|
SICSLogWrite("CAM:(AQU_DISCONNECT)", eLogError);
|
||||||
|
break;
|
||||||
|
case AQU_RECONNECT:
|
||||||
|
SICSLogWrite("CAM:(AQU_RECONNECT)", eLogError);
|
||||||
|
if (self->state_timer) {
|
||||||
|
NetWatchRemoveTimer(self->state_timer);
|
||||||
|
self->state_timer=0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int CAM_Tx(pAsyncProtocol p, pAsyncTxn txn) {
|
||||||
|
|
||||||
|
if (txn == NULL) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
txn->txn_status = ATX_ACTIVE;
|
||||||
|
if (AsyncUnitWrite(txn->unit, txn->out_buf, txn->out_len) < 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int defaultHandleInput(pAsyncProtocol p, pAsyncTxn txn, int ch);
|
||||||
|
static int CAM_Rx(pAsyncProtocol p, pAsyncTxn txn, int ch) {
|
||||||
|
int ret = 1;
|
||||||
|
|
||||||
|
if (ch == '\r')
|
||||||
|
ret = 1;
|
||||||
|
else if (ch == '\n')
|
||||||
|
ret = AQU_POP_CMD;
|
||||||
|
else if (txn->inp_idx < txn->inp_len)
|
||||||
|
txn->inp_buf[txn->inp_idx++] = ch;
|
||||||
|
else
|
||||||
|
ret = AQU_POP_CMD;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
static int CAM_Ev(pAsyncProtocol p, pAsyncTxn pTxn, int event) {
|
||||||
|
if (event == AQU_TIMEOUT) {
|
||||||
|
pTxn->txn_status = ATX_TIMEOUT;
|
||||||
|
return AQU_POP_CMD;
|
||||||
|
}
|
||||||
|
return AQU_POP_CMD;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CameraInitProtocol(SicsInterp *pSics) {
|
||||||
|
if (CAM_Protocol == NULL) {
|
||||||
|
CAM_Protocol = AsyncProtocolCreate(pSics, "CAMERA", NULL, NULL);
|
||||||
|
CAM_Protocol->sendCommand = CAM_Tx;
|
||||||
|
CAM_Protocol->handleInput = CAM_Rx;
|
||||||
|
CAM_Protocol->prepareTxn = NULL;
|
||||||
|
CAM_Protocol->killPrivate = NULL;
|
||||||
|
CAM_Protocol->handleEvent = CAM_Ev;
|
||||||
|
#if 0
|
||||||
|
CAM_Protocol->sendTerminator = strdup("\r\n");
|
||||||
|
CAM_Protocol->replyTerminator[0] = strdup("\r\n");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* CounterDriver interface functions */
|
||||||
|
static int CamGetStatus(CounterDriver *cntrData, float *fControl) {
|
||||||
|
CamObj *camdrv= (CamObj *)cntrData->pData;
|
||||||
|
|
||||||
|
return camdrv->status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* \brief run_sm, call the state machine with the given input.
|
||||||
|
* \param self, driver context including current state
|
||||||
|
* \param ev_sym, input event
|
||||||
|
*/
|
||||||
|
static void run_sm(CamObj *self, enum event_codes ev_sym) {
|
||||||
|
char sscur[SSLEN+1], ssnext[SSLEN+1], esout[ESLEN+1], message[MSGLEN+1];
|
||||||
|
|
||||||
|
if (self->debug)
|
||||||
|
strncpy(sscur, strstate(self->state_machine.Sc), SSLEN);
|
||||||
|
|
||||||
|
camdriv_input(self, &self->state_machine, ev_sym);
|
||||||
|
|
||||||
|
if (self->debug) {
|
||||||
|
strncpy(ssnext, strstate(self->state_machine.Sc), SSLEN);
|
||||||
|
strncpy(esout, strevent(self->state_machine.Eo), ESLEN);
|
||||||
|
snprintf(message, MSGLEN, "DEBUG:(run_sm) Scurr:%s Ei:%s",
|
||||||
|
sscur,event_names[ev_sym]);
|
||||||
|
SICSLogWrite(message, eLog);
|
||||||
|
snprintf(message, MSGLEN, "DEBUG:(run_sm) Snext:%s Eo:%s", ssnext,esout);
|
||||||
|
SICSLogWrite(message, eLog);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* \brief sendcfg, Send the camera configuration to the camera server
|
||||||
|
*/
|
||||||
|
int sendcfg(CamObj *self) {
|
||||||
|
int status, replen=MSGLEN;
|
||||||
|
char reply[MSGLEN+1], logmsg[MSGLEN+1];
|
||||||
|
char cfgCmd[MSGLEN+1];
|
||||||
|
float clock = self->camera.clockMHz;
|
||||||
|
|
||||||
|
if(self->camera.updatecfg) {
|
||||||
|
sprintf(cfgCmd,
|
||||||
|
"set camera,clock=%.*fmhz,bin=%dx,size=%d,gain=%dxhs,flip=%s,xstart=%d,ystart=%d,xend=%d,yend=%d,exposure=%f,temperature=%f,threshold=%d,shutteropentime=%d,shutterclosetime=%d",
|
||||||
|
clock>=1 ? 0 : 1, clock, (int)self->camera.bin, (int)self->camera.size,
|
||||||
|
(int)self->camera.gain, flipcmdstr[self->camera.flip],
|
||||||
|
(int)self->camera.xstart, (int)self->camera.ystart,
|
||||||
|
(int)self->camera.xend, (int)self->camera.yend, self->camera.exposure,
|
||||||
|
self->camera.temp, (int)self->camera.thresh, (int)self->camera.shopt,
|
||||||
|
(int)self->camera.shclt
|
||||||
|
);
|
||||||
|
|
||||||
|
status = AsyncUnitTransact(self->asyncUnit, cfgCmd, strlen(cfgCmd), reply, &replen);
|
||||||
|
if (status <= 0)
|
||||||
|
return 0;
|
||||||
|
else
|
||||||
|
if (strncmp("OK", reply, 2) == 0)
|
||||||
|
return 1;
|
||||||
|
else {
|
||||||
|
snprintf(logmsg, MSGLEN, "CAM:(sendcfg) set camera reply=%s", reply);
|
||||||
|
SICSLogWrite(logmsg, eLogError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TBD, other fields to be set
|
||||||
|
if(self->file.updatecfg) {
|
||||||
|
sprintf(cfgCmd, "set camera, path=%s,basename=%s,startnumber=%d,imageformat=%s,experimentdetail=%s",
|
||||||
|
self->file.path,
|
||||||
|
self->file.basename,
|
||||||
|
self->file.startnumber,
|
||||||
|
self->file.imageformat, self->file.experimentdetail);
|
||||||
|
status = AsyncUnitTransact(self->asyncUnit, cfgCmd, strlen(cfgCmd), reply, &replen);
|
||||||
|
if (status <= 0)
|
||||||
|
return 0;
|
||||||
|
else
|
||||||
|
if (strncmp("OK", reply, 2) == 0)
|
||||||
|
return 1;
|
||||||
|
else {
|
||||||
|
snprintf(logmsg, MSGLEN, "CAM:(sendcfg) set file reply=%s", reply);
|
||||||
|
SICSLogWrite(logmsg, eLogError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
} */
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Called by the scan command and via the count and countnb subcommands of a
|
||||||
|
* counter object. Will update the configuration if necessary.
|
||||||
|
*/
|
||||||
|
static int CamStart(CounterDriver *cntrData) {
|
||||||
|
CamObj *self = NULL;
|
||||||
|
enum event_codes cd_sym;
|
||||||
|
char logmsg[MSGLEN+1];
|
||||||
|
|
||||||
|
self = cntrData->pData;
|
||||||
|
|
||||||
|
/* Send the updated configuration to the camera server if it has been changed
|
||||||
|
* on SICS since the last shot was taken. */
|
||||||
|
if (self->camera.updatecfg) {
|
||||||
|
if (sendcfg(self) == 0) {
|
||||||
|
snprintf(logmsg, MSGLEN, "CAM:(CamStart) Failed to upload configuration");
|
||||||
|
SICSLogWrite(logmsg, eLogError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
self->camera.updatecfg = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (self->state_machine.multi) {
|
||||||
|
cd_sym = ECD_MLTI_ON;
|
||||||
|
} else {
|
||||||
|
cd_sym = ECD_TK_SHOT;
|
||||||
|
}
|
||||||
|
run_sm(self, cd_sym);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int CamPause(CounterDriver *cntrData) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
static int CamContinue(CounterDriver *cntrData) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
static int CamHalt(CounterDriver *cntrData) {
|
||||||
|
CamObj *self = cntrData->pData;
|
||||||
|
|
||||||
|
if (self->state_machine.multi) {
|
||||||
|
run_sm(self, ECD_MLTI_OFF);
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
/* TODO what should the counter data be set to? Total intensity? */
|
||||||
|
static int CamReadValues(CounterDriver *cntrData) {
|
||||||
|
int status, iReplyLen=MSGLEN;
|
||||||
|
char *cmd="TODO ", pReply[MSGLEN];
|
||||||
|
CamObj *self = NULL;
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
self = cntrData->pData;
|
||||||
|
status = AsyncUnitTransact(self->asyncUnit, cmd, strlen(cmd), pReply, &iReplyLen);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int CamGetError(CounterDriver *cntrData, int *iCode, char *error, int iErrLen) {
|
||||||
|
CamObj *camdrv=NULL;
|
||||||
|
camdrv = (CamObj *) cntrData->pData;
|
||||||
|
*iCode = camdrv->camError;
|
||||||
|
|
||||||
|
camdrv->camError = ENONE;
|
||||||
|
switch (*iCode) {
|
||||||
|
case EBUSYACQ:
|
||||||
|
snprintf(error, (size_t) iErrLen,
|
||||||
|
"CAM: Can't complete operation, %s", errmsg[EBUSYACQ]);
|
||||||
|
break;
|
||||||
|
case EBUSYSAVE:
|
||||||
|
snprintf(error, (size_t) iErrLen,
|
||||||
|
"CAM: Can't complete operation, %s", errmsg[EBUSYSAVE]);
|
||||||
|
break;
|
||||||
|
case EBUSYPROC:
|
||||||
|
snprintf(error, (size_t) iErrLen,
|
||||||
|
"CAM: Can't complete operation, %s", errmsg[EBUSYPROC]);
|
||||||
|
break;
|
||||||
|
case ENONE:
|
||||||
|
snprintf(error, (size_t) iErrLen,
|
||||||
|
"CAM: Can't complete operation, %s", errmsg[ENONE]);
|
||||||
|
break;
|
||||||
|
case EFAIL:
|
||||||
|
snprintf(error, (size_t) iErrLen, "CAM: %s", errmsg[EFAIL]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int CamTryAndFixIt(CounterDriver *cntrData, int iCode) {
|
||||||
|
return COTERM;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int CamSet(CounterDriver *cntrData, char *name, int iCter, float fVal) {
|
||||||
|
CamObj *camdriv= (CamObj *)cntrData->pData;
|
||||||
|
|
||||||
|
int found=0;
|
||||||
|
char *cmd;
|
||||||
|
enum campar id;
|
||||||
|
enum flipval flip;
|
||||||
|
|
||||||
|
for (id=0; (cmd = cacmdstr[id]) != NULL; id++) {
|
||||||
|
if (strcmp(cmd,name) == 0) {
|
||||||
|
found=1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!found) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
switch (id) {
|
||||||
|
case MULTI:
|
||||||
|
if (fVal != 0 && fVal != 1) {
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
camdriv->state_machine.multi = fVal;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case CLOCK:
|
||||||
|
if (fVal > 0) {
|
||||||
|
camdriv->camera.clockMHz = fVal;
|
||||||
|
camdriv->camera.updatecfg = 1;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case BIN:
|
||||||
|
if (fVal > 0) {
|
||||||
|
camdriv->camera.bin = fVal;
|
||||||
|
camdriv->camera.updatecfg = 1;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SIZE:
|
||||||
|
if (fVal > 0) {
|
||||||
|
camdriv->camera.size = fVal;
|
||||||
|
camdriv->camera.updatecfg = 1;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case GAIN:
|
||||||
|
if (fVal > 0) {
|
||||||
|
camdriv->camera.gain = fVal;
|
||||||
|
camdriv->camera.updatecfg = 1;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case FLIP:
|
||||||
|
flip = fVal;
|
||||||
|
switch (flip) {
|
||||||
|
case NORMAL:
|
||||||
|
case INVINT:
|
||||||
|
case NORMFH:
|
||||||
|
case NORMFV:
|
||||||
|
case NORMFHV:
|
||||||
|
case INVFH:
|
||||||
|
case INVFV:
|
||||||
|
case INVFHV:
|
||||||
|
camdriv->camera.flip = flip;
|
||||||
|
camdriv->camera.updatecfg = 1;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case XSTART:
|
||||||
|
if (fVal > 0) {
|
||||||
|
camdriv->camera.xstart = fVal;
|
||||||
|
camdriv->camera.updatecfg = 1;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case YSTART:
|
||||||
|
if (fVal > 0) {
|
||||||
|
camdriv->camera.ystart = fVal;
|
||||||
|
camdriv->camera.updatecfg = 1;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case XEND:
|
||||||
|
if (fVal > 0) {
|
||||||
|
camdriv->camera.xend = fVal;
|
||||||
|
camdriv->camera.updatecfg = 1;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case YEND:
|
||||||
|
if (fVal > 0) {
|
||||||
|
camdriv->camera.yend = fVal;
|
||||||
|
camdriv->camera.updatecfg = 1;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case EXPOSURE:
|
||||||
|
if (fVal > 0) {
|
||||||
|
camdriv->camera.exposure = fVal;
|
||||||
|
camdriv->camera.updatecfg = 1;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TEMP:
|
||||||
|
camdriv->camera.temp = fVal;
|
||||||
|
camdriv->camera.updatecfg = 1;
|
||||||
|
break;
|
||||||
|
case THRESH:
|
||||||
|
if (fVal > 0) {
|
||||||
|
camdriv->camera.thresh = fVal;
|
||||||
|
camdriv->camera.updatecfg = 1;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SHOPT:
|
||||||
|
if (fVal > 0) {
|
||||||
|
camdriv->camera.shopt = fVal;
|
||||||
|
camdriv->camera.updatecfg = 1;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SHCLT:
|
||||||
|
if (fVal > 0) {
|
||||||
|
camdriv->camera.shclt = fVal;
|
||||||
|
camdriv->camera.updatecfg = 1;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int CamGet(CounterDriver *cntrData, char *name, int iCter, float *fVal) {
|
||||||
|
CamObj *camdriv= (CamObj *)cntrData->pData;
|
||||||
|
|
||||||
|
int found=0;
|
||||||
|
char *cmd;
|
||||||
|
enum campar id;
|
||||||
|
|
||||||
|
for (id=0; (cmd = cacmdstr[id]) != NULL; id++) {
|
||||||
|
if (strcmp(cmd,name) == 0) {
|
||||||
|
found=1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!found) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
switch (id) {
|
||||||
|
case MULTI:
|
||||||
|
*fVal = (float) camdriv->state_machine.multi;
|
||||||
|
break;
|
||||||
|
case CLOCK:
|
||||||
|
*fVal = camdriv->camera.clockMHz;
|
||||||
|
break;
|
||||||
|
case BIN:
|
||||||
|
*fVal = camdriv->camera.bin;
|
||||||
|
break;
|
||||||
|
case SIZE:
|
||||||
|
*fVal = camdriv->camera.size;
|
||||||
|
break;
|
||||||
|
case GAIN:
|
||||||
|
*fVal = camdriv->camera.gain;
|
||||||
|
break;
|
||||||
|
case FLIP:
|
||||||
|
*fVal = camdriv->camera.flip;
|
||||||
|
break;
|
||||||
|
case XSTART:
|
||||||
|
*fVal = camdriv->camera.xstart;
|
||||||
|
break;
|
||||||
|
case YSTART:
|
||||||
|
*fVal = camdriv->camera.ystart;
|
||||||
|
break;
|
||||||
|
case XEND:
|
||||||
|
*fVal = camdriv->camera.xend;
|
||||||
|
break;
|
||||||
|
case YEND:
|
||||||
|
*fVal = camdriv->camera.yend;
|
||||||
|
break;
|
||||||
|
case EXPOSURE:
|
||||||
|
*fVal = camdriv->camera.exposure;
|
||||||
|
break;
|
||||||
|
case TEMP:
|
||||||
|
*fVal = camdriv->camera.temp;
|
||||||
|
break;
|
||||||
|
case THRESH:
|
||||||
|
*fVal = camdriv->camera.thresh;
|
||||||
|
break;
|
||||||
|
case SHOPT:
|
||||||
|
*fVal = camdriv->camera.shopt;
|
||||||
|
break;
|
||||||
|
case SHCLT:
|
||||||
|
*fVal = camdriv->camera.shclt;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int CamSend(CounterDriver *cntrData, char *pText, char *pReply, int iReplyLen) {
|
||||||
|
int status;
|
||||||
|
CamObj *self = NULL;
|
||||||
|
|
||||||
|
self = cntrData->pData;
|
||||||
|
|
||||||
|
//char *pBuf = (char *)calloc(strlen(pText)+10, sizeof(char));
|
||||||
|
//sprintf(pBuf, "set meta, %s", pText);
|
||||||
|
//status = AsyncUnitTransact(self->asyncUnit, pBuf, strlen(pBuf), pReply, &iReplyLen);
|
||||||
|
status = AsyncUnitTransact(self->asyncUnit, pText, strlen(pText), pReply, &iReplyLen);
|
||||||
|
//free(pBuf);
|
||||||
|
if (status <= 0)
|
||||||
|
return 0;
|
||||||
|
else
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cb_shotcmd(pAsyncTxn txn) {
|
||||||
|
CamObj *self = (CamObj *) txn->cntx;
|
||||||
|
char *resp = txn->inp_buf, message[MSGLEN+1];
|
||||||
|
enum event_codes cd_sym;
|
||||||
|
|
||||||
|
if (strncmp(resp, "OK", 2) != 0) {
|
||||||
|
self->camError = EFAIL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int camdriv_out(void *me, event_t Eo) {
|
||||||
|
int len;
|
||||||
|
char cmd[MSGLEN]="", logmsg[MSGLEN+1]="";
|
||||||
|
CamObj *self = (CamObj *)me;
|
||||||
|
|
||||||
|
if (Eo.ca) {
|
||||||
|
/* send command to camera */
|
||||||
|
switch (Eo.ca) {
|
||||||
|
case ECA_TK_SHOT:
|
||||||
|
len = strlen(event_signatures[ECA_TK_SHOT]);
|
||||||
|
strncpy(cmd, event_signatures[ECA_TK_SHOT], len);
|
||||||
|
break;
|
||||||
|
case ECA_MLTI_ON:
|
||||||
|
len = strlen(event_signatures[ECA_MLTI_ON]);
|
||||||
|
strncpy(cmd, event_signatures[ECA_MLTI_ON], len);
|
||||||
|
break;
|
||||||
|
case ECA_MLTI_OFF:
|
||||||
|
len = strlen(event_signatures[ECA_MLTI_OFF]);
|
||||||
|
strncpy(cmd, event_signatures[ECA_MLTI_OFF], len);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
snprintf(logmsg, MSGLEN, "CAM:(camdriv_out) Unhandled event %s", event_names[Eo.ca]);
|
||||||
|
SICSLogWrite(logmsg, eLogError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
AsyncUnitSendTxn(self->asyncUnit, cmd, len, cb_shotcmd, self, MSGLEN);
|
||||||
|
if (self->debug) {
|
||||||
|
snprintf(logmsg, MSGLEN, "DEBUG:(camdriv_out:Eo.ca): ev=%s, output=%s\n",
|
||||||
|
event_names[Eo.ca], event_signatures[Eo.ca]);
|
||||||
|
SICSLogWrite(logmsg, eLog);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (Eo.cm) {
|
||||||
|
snprintf(logmsg, MSGLEN, "TODO:(camdriv_out:Eo.cm): ev=%s, output=%s\n",
|
||||||
|
event_names[Eo.cm], event_signatures[Eo.cm]);
|
||||||
|
SICSLogWrite(logmsg, eLogError);
|
||||||
|
}
|
||||||
|
if (Eo.cd) {
|
||||||
|
snprintf(logmsg, MSGLEN, "TODO:(camdriv_out:Eo.cm): ev=%s, output=%s\n",
|
||||||
|
event_names[Eo.cd], event_signatures[Eo.cd]);
|
||||||
|
SICSLogWrite(logmsg, eLogError);
|
||||||
|
}
|
||||||
|
if (Eo.dr) {
|
||||||
|
/* send msg to SICS */
|
||||||
|
switch (Eo.dr) {
|
||||||
|
case EDR_IDLE:
|
||||||
|
self->status = HWIdle;
|
||||||
|
break;
|
||||||
|
case EDR_BUSY:
|
||||||
|
self->status = HWBusy;
|
||||||
|
break;
|
||||||
|
case EDR_FAULT:
|
||||||
|
self->status = HWFault;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
snprintf(logmsg, MSGLEN, "CAM:(camdriv_out) Unhandled event %s", event_names[Eo.dr]);
|
||||||
|
SICSLogWrite(logmsg, eLogError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (self->debug) {
|
||||||
|
snprintf(logmsg, MSGLEN, "DEBUG:(camdriv_out): ev=%s, output=%s\n",
|
||||||
|
event_names[Eo.dr], event_signatures[Eo.dr]);
|
||||||
|
SICSLogWrite(logmsg, eLog);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
static int cb_state_timer(void *ctx, int mode) {
|
||||||
|
CamObj *self = (CamObj *) ctx;
|
||||||
|
char errmsg[32]="";
|
||||||
|
char cmd[MSGLEN];
|
||||||
|
int len, status;
|
||||||
|
|
||||||
|
len = strlen(event_signatures[ECA_GET_STATE]);
|
||||||
|
strncpy(cmd, event_signatures[ECA_GET_STATE], len);
|
||||||
|
status = AsyncUnitSendTxn(self->asyncUnit, cmd, len, cb_getstate, self, MSGLEN);
|
||||||
|
|
||||||
|
if (status==1) {
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
snprintf(errmsg, 31, "CAM:(cb_getstate) AsyncUnitSendTxn failed");
|
||||||
|
SICSLogWrite(errmsg, eLogError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Input from camera state feedback */
|
||||||
|
static int cb_getstate(pAsyncTxn txn) {
|
||||||
|
CamObj *self = (CamObj *) txn->cntx;
|
||||||
|
char *resp = txn->inp_buf, message[MSGLEN+1];
|
||||||
|
int len = txn->inp_idx, ret=1, time_rem, time_tot;
|
||||||
|
enum event_codes ca_sym, cm_sym;
|
||||||
|
|
||||||
|
|
||||||
|
if (txn->txn_status == ATX_TIMEOUT) {
|
||||||
|
ret = 0;
|
||||||
|
} else if ( cam_parse_status(resp, &ca_sym, &time_rem, &time_tot) == -1) {
|
||||||
|
snprintf(message, MSGLEN,
|
||||||
|
"CAM:(cb_getstate) cam_parse_status failed to parse '%s'",resp);
|
||||||
|
SICSLogWrite(message, eLogError);
|
||||||
|
ret = 0;
|
||||||
|
} else {
|
||||||
|
cm_sym = camera_model(ca_sym);
|
||||||
|
run_sm(self, cm_sym);
|
||||||
|
}
|
||||||
|
if (self->state_timer) {
|
||||||
|
NetWatchRemoveTimer(self->state_timer);
|
||||||
|
self->state_timer=0;
|
||||||
|
}
|
||||||
|
char logmsg[MSGLEN+1]="";
|
||||||
|
snprintf(logmsg, MSGLEN,"CAM:(cb_getstate) Entering NetWatchRegisterTimer");
|
||||||
|
SICSLogWrite(logmsg, eLog);
|
||||||
|
NetWatchRegisterTimer(&self->state_timer, 500, cb_state_timer, self);
|
||||||
|
snprintf(logmsg, MSGLEN,"CAM:(cb_getstate) Leaving NetWatchRegisterTimer");
|
||||||
|
SICSLogWrite(logmsg, eLog);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
pCounterDriver CreateCam(SConnection *pCon, char *name, char *asynq) {
|
||||||
|
char msg[ERRLEN], cmd[MSGLEN], reply[MSGLEN];
|
||||||
|
int len, reply_len;
|
||||||
|
state_t start_state = {.cl=SCL_RDY, .cm=SCM_IDLE, .dr=SDR_IDLE};
|
||||||
|
|
||||||
|
pCounterDriver pCntDriv = NULL;
|
||||||
|
CamObj *pNewCam = NULL;
|
||||||
|
|
||||||
|
pNewCam = (CamObj *) malloc(sizeof(CamObj));
|
||||||
|
memset(pNewCam, 0, sizeof(CamObj));
|
||||||
|
STset(&pNewCam->state_machine.Sc, start_state);
|
||||||
|
EVclr(&pNewCam->state_machine.Eo);
|
||||||
|
pNewCam->state_machine.output_fn = camdriv_out;
|
||||||
|
pNewCam->state_machine.multi = 0;
|
||||||
|
pNewCam->state_timer = 0;
|
||||||
|
pNewCam->status = HWIdle;
|
||||||
|
pNewCam->camError = ENONE;
|
||||||
|
pNewCam->debug = 1;
|
||||||
|
pNewCam->camera.updatecfg = 1;
|
||||||
|
pNewCam->asynq = strdup(asynq);
|
||||||
|
|
||||||
|
if (!AsyncUnitCreate(asynq, &pNewCam->asyncUnit)) {
|
||||||
|
snprintf(msg, ERRLEN, "CAM:AsyncQueue %s has not been defined", asynq);
|
||||||
|
SCWrite(pCon, msg, eError);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
AsyncUnitSetTimeout(pNewCam->asyncUnit, 1000);
|
||||||
|
AsyncUnitSetNotify(pNewCam->asyncUnit, pNewCam, CAM_Notify);
|
||||||
|
|
||||||
|
pCntDriv = CreateCounterDriver(name, "anstocamera");
|
||||||
|
if (pCntDriv == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
|
||||||
|
pCntDriv->GetStatus = CamGetStatus;
|
||||||
|
pCntDriv->Start = CamStart;
|
||||||
|
pCntDriv->Pause = CamPause;
|
||||||
|
pCntDriv->Continue = CamContinue;
|
||||||
|
pCntDriv->Halt = CamHalt;
|
||||||
|
pCntDriv->ReadValues = CamReadValues;
|
||||||
|
pCntDriv->GetError = CamGetError;
|
||||||
|
pCntDriv->TryAndFixIt = CamTryAndFixIt;
|
||||||
|
pCntDriv->Set = CamSet;
|
||||||
|
pCntDriv->Get = CamGet;
|
||||||
|
pCntDriv->Send = CamSend;
|
||||||
|
|
||||||
|
pCntDriv->iNoOfMonitors = 1;
|
||||||
|
pCntDriv->pData = pNewCam;
|
||||||
|
|
||||||
|
len = strlen(event_signatures[ECA_GET_STATE]);
|
||||||
|
strncpy(cmd, event_signatures[ECA_GET_STATE], len);
|
||||||
|
AsyncUnitSendTxn(pNewCam->asyncUnit, cmd, len, cb_getstate, pNewCam, MSGLEN);
|
||||||
|
return pCntDriv;
|
||||||
|
}
|
||||||
4
site_ansto/hardsup/cameradriver.h
Normal file
4
site_ansto/hardsup/cameradriver.h
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
#ifndef CAMERADRIVER_H
|
||||||
|
#define CAMERADRIVER_H
|
||||||
|
void CameraInitProtocol(SicsInterp *pSics);
|
||||||
|
#endif
|
||||||
@@ -32,6 +32,8 @@ HOBJ += sct_rfamp.o
|
|||||||
HOBJ += sinqhttpprot.o
|
HOBJ += sinqhttpprot.o
|
||||||
HOBJ += sct_protek608.o
|
HOBJ += sct_protek608.o
|
||||||
HOBJ += sct_lfprot.o
|
HOBJ += sct_lfprot.o
|
||||||
|
HOBJ += camera.o
|
||||||
|
HOBJ += cameradriver.o
|
||||||
|
|
||||||
libhlib.a: $(HOBJ)
|
libhlib.a: $(HOBJ)
|
||||||
rm -f libhlib.a
|
rm -f libhlib.a
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
# Required by server_config.tcl
|
# Required by server_config.tcl
|
||||||
VarMake Instrument Text Internal
|
VarMake Instrument Text Internal
|
||||||
Instrument echidna
|
Instrument bear
|
||||||
Instrument lock
|
Instrument lock
|
||||||
|
|
||||||
#START SERVER CONFIGURATION SECTION
|
#START SERVER CONFIGURATION SECTION
|
||||||
|
|||||||
@@ -76,6 +76,25 @@ proc ::scan::hmm_scan_collect {sobj uobj point} {
|
|||||||
clientput "Monitor $bmn [SplitReply [$bmon getcounts]]"
|
clientput "Monitor $bmn [SplitReply [$bmon getcounts]]"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
proc ::scan::cm_scan_collect {sobj uobj point} {
|
||||||
|
set vlist [split [$sobj getvarpar 0] = ];
|
||||||
|
|
||||||
|
set w(NP) $point
|
||||||
|
set sv [string trim [lindex [split [lindex $vlist 0] . ] 1]]
|
||||||
|
set header [format "%-4.4s %-9.9s %-14s %-7.7s" NP $sv Counts Time]
|
||||||
|
set varval [SplitReply [$sv]]
|
||||||
|
set counts [SplitReply [::histogram_memory::total_counts]]
|
||||||
|
set time [SplitReply [::histogram_memory::time]]
|
||||||
|
set data [format "%-4d %-9.3f %-14d %-7.2f" $point $varval $counts $time]
|
||||||
|
clientput $header
|
||||||
|
clientput $data
|
||||||
|
for {set bmn 1} {$bmn <= $::counter::isc_numchannels} {incr bmn} {
|
||||||
|
set bmon bm$bmn
|
||||||
|
clientput "Monitor $bmn [SplitReply [$bmon getcounts]]"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
proc ::scan::hmscanend_event {} {
|
proc ::scan::hmscanend_event {} {
|
||||||
::scan::runscan_cmd -set feedback status IDLE
|
::scan::runscan_cmd -set feedback status IDLE
|
||||||
}
|
}
|
||||||
@@ -86,6 +105,11 @@ proc ::scan::bmonscanend_event {} {
|
|||||||
}
|
}
|
||||||
publish ::scan::bmonscanend_event user
|
publish ::scan::bmonscanend_event user
|
||||||
|
|
||||||
|
proc ::scan::cmscanend_event {} {
|
||||||
|
#::scan::iscan_cmd -set feedback status IDLE
|
||||||
|
}
|
||||||
|
publish ::scan::cmscanend_event user
|
||||||
|
|
||||||
proc ::scan::ic_initialize {} {
|
proc ::scan::ic_initialize {} {
|
||||||
if [ catch {
|
if [ catch {
|
||||||
variable ic_runscanpar
|
variable ic_runscanpar
|
||||||
@@ -93,8 +117,9 @@ proc ::scan::ic_initialize {} {
|
|||||||
|
|
||||||
set ic_hmm_datatype HISTOGRAM_XYT
|
set ic_hmm_datatype HISTOGRAM_XYT
|
||||||
|
|
||||||
MakeScanCommand hmscan bm $::cfPath(scan)/scan_common_1.hdd recover.bin
|
#MakeScanCommand hmscan bm $::cfPath(scan)/scan_common_1.hdd recover.bin
|
||||||
MakeScanCommand bmonscan bm $::cfPath(scan)/scan_common_1.hdd recover.bin
|
#MakeScanCommand bmonscan bm $::cfPath(scan)/scan_common_1.hdd recover.bin
|
||||||
|
#MakeScanCommand iscan cm1 $::cfPath(scan)/scan_common_1.hdd recover.bin
|
||||||
|
|
||||||
bmonscan configure script
|
bmonscan configure script
|
||||||
bmonscan function writeheader ::scan::donothing
|
bmonscan function writeheader ::scan::donothing
|
||||||
@@ -104,7 +129,6 @@ proc ::scan::ic_initialize {} {
|
|||||||
bmonscan function prepare ::scan::bm_scan_prepare
|
bmonscan function prepare ::scan::bm_scan_prepare
|
||||||
bmonscan function finish ::scan::bm_scan_finish
|
bmonscan function finish ::scan::bm_scan_finish
|
||||||
|
|
||||||
|
|
||||||
hmscan configure script
|
hmscan configure script
|
||||||
hmscan function writeheader ::scan::donothing
|
hmscan function writeheader ::scan::donothing
|
||||||
hmscan function writepoint ::scan::hmm_writepoint
|
hmscan function writepoint ::scan::hmm_writepoint
|
||||||
@@ -113,6 +137,14 @@ proc ::scan::ic_initialize {} {
|
|||||||
hmscan function prepare ::scan::hmm_scan_prepare
|
hmscan function prepare ::scan::hmm_scan_prepare
|
||||||
hmscan function finish ::scan::hmm_scan_finish
|
hmscan function finish ::scan::hmm_scan_finish
|
||||||
|
|
||||||
|
#iscan configure script
|
||||||
|
#iscan function writeheader ::scan::donothing
|
||||||
|
#iscan function writepoint ::scan:cm_writepoint
|
||||||
|
#iscan function count ::scan::cm_count
|
||||||
|
#iscan function collect ::scan::cm_scan_collect
|
||||||
|
#iscan function prepare ::scan::cm_scan_prepare
|
||||||
|
#iscan function finish ::scan::cm_scan_finish
|
||||||
|
|
||||||
# TODO Use ic_runscanpar to create the ::scan::runscan command and
|
# TODO Use ic_runscanpar to create the ::scan::runscan command and
|
||||||
# to validate the "runscan" proc parameters.
|
# to validate the "runscan" proc parameters.
|
||||||
array set ic_runscanpar [subst {
|
array set ic_runscanpar [subst {
|
||||||
@@ -126,8 +158,9 @@ proc ::scan::ic_initialize {} {
|
|||||||
savetype text=save,nosave
|
savetype text=save,nosave
|
||||||
force boolean
|
force boolean
|
||||||
}]
|
}]
|
||||||
scriptcallback connect hmscan SCANEND ::scan::hmscanend_event
|
#scriptcallback connect hmscan SCANEND ::scan::hmscanend_event
|
||||||
scriptcallback connect bmonscan SCANEND ::scan::bmonscanend_event
|
#scriptcallback connect bmonscan SCANEND ::scan::bmonscanend_event
|
||||||
|
scriptcallback connect iscan SCANEND ::scan::cmscanend_event
|
||||||
} message ] {
|
} message ] {
|
||||||
if {$::errorCode=="NONE"} {return $message}
|
if {$::errorCode=="NONE"} {return $message}
|
||||||
return -code error $message
|
return -code error $message
|
||||||
@@ -327,7 +360,7 @@ proc ::scan::bm_scan_prepare {sobj uobj} {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if [catch {
|
if [catch {
|
||||||
#TODO Parameterise varindex in some way
|
#TODO Parameterise varindex in some way
|
||||||
set varindex 0;
|
set varindex 0;
|
||||||
|
|
||||||
set numpoints [SplitReply [$sobj np]]
|
set numpoints [SplitReply [$sobj np]]
|
||||||
@@ -356,9 +389,87 @@ proc ::scan::bm_scan_prepare {sobj uobj} {
|
|||||||
} else {
|
} else {
|
||||||
return -code error "BMONSCAN ABORTED: Instrument not ready"
|
return -code error "BMONSCAN ABORTED: Instrument not ready"
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
proc ::scan::cm_count {sobj uobj point mode preset} {
|
||||||
|
# send "clear meta" command to the camera server
|
||||||
|
clientput "sending clear meta"
|
||||||
|
set cmd "clear meta\r\n"
|
||||||
|
cm1 send $cmd
|
||||||
|
# send motor position
|
||||||
|
set cmd "set meta"
|
||||||
|
foreach m [sicslist type motor] {
|
||||||
|
append cmd "," "[$m]"
|
||||||
|
}
|
||||||
|
append cmd "\r\n"
|
||||||
|
clientput $cmd
|
||||||
|
cm1 send $cmd
|
||||||
|
}
|
||||||
|
|
||||||
|
proc ::scan::cm_scan_prepare {sobj uobj} {
|
||||||
|
|
||||||
|
variable save_filetype
|
||||||
|
variable check_instrument_ready
|
||||||
|
variable force_scan
|
||||||
|
|
||||||
|
if {$force_scan || $check_instrument_ready && [::plc::inst_ready]} {
|
||||||
|
set force_scan false
|
||||||
|
if [catch {
|
||||||
|
::scan::check_scanvar $sobj $uobj
|
||||||
|
::scan::pre_hmm_scan_prepare
|
||||||
|
}] {
|
||||||
|
return -code error "ISCAN ABORTED: $::errorInfo"
|
||||||
|
}
|
||||||
|
|
||||||
|
# send "shutter auto" command over
|
||||||
|
clientput "shutter auto"
|
||||||
|
shutter auto
|
||||||
|
# send "focusflight off" command over
|
||||||
|
clientput "focuslight off"
|
||||||
|
focuslight off
|
||||||
|
# send "clear meta" command to the camera server
|
||||||
|
clientput "sending clear meta"
|
||||||
|
set cmd "clear meta\r\n"
|
||||||
|
cm1 send $cmd
|
||||||
|
# send motor position
|
||||||
|
set cmd "set meta"
|
||||||
|
foreach m [sicslist type motor] {
|
||||||
|
append cmd "," "[$m]"
|
||||||
|
}
|
||||||
|
append cmd "\r\n"
|
||||||
|
clientput $cmd
|
||||||
|
cm1 send $cmd
|
||||||
|
|
||||||
|
if [catch {
|
||||||
|
#TODO Parameterise varindex in some way
|
||||||
|
set varindex 0;
|
||||||
|
|
||||||
|
set numpoints [SplitReply [$sobj np]]
|
||||||
|
set vlist [split [$sobj getvarpar $varindex] = ]
|
||||||
|
set scanstart [lindex $vlist 1]
|
||||||
|
set scanstep [lindex $vlist 2]
|
||||||
|
#::scan::iscan_cmd -set NP $numpoints
|
||||||
|
#::scan::iscan_cmd -set scan_variable [string trim [lindex [split [lindex $vlist 0] . ] 1]];
|
||||||
|
#::scan::iscan_cmd -set scan_start $scanstart
|
||||||
|
#::scan::iscan_cmd -set scan_increment $scanstep
|
||||||
|
set scanvar_pts [SplitReply [$sobj getvardata $varindex]]
|
||||||
|
|
||||||
|
#::scan::iscan_cmd -set feedback status BUSY
|
||||||
|
clientput "run_mode iscan"
|
||||||
|
run_mode "iscan"
|
||||||
|
|
||||||
|
#::nexus::newfile BEAM_MONITOR $save_filetype
|
||||||
|
stdscan prepare $sobj $uobj;
|
||||||
|
clientput "Scan start: $scanstart, Scan step: $scanstep, Number of points: $numpoints"
|
||||||
|
}] {
|
||||||
|
run_mode "normal"
|
||||||
|
return -code error $::errorInfo
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return -code error "ISCAN ABORTED: Instrument not ready"
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Publish ::scan::hmm_count user
|
Publish ::scan::hmm_count user
|
||||||
Publish ::scan::hmm_scan_prepare user
|
Publish ::scan::hmm_scan_prepare user
|
||||||
@@ -373,6 +484,9 @@ Publish ::scan::bm_scan_collect user
|
|||||||
Publish ::scan::bm_writepoint user
|
Publish ::scan::bm_writepoint user
|
||||||
Publish ::scan::bm_count user
|
Publish ::scan::bm_count user
|
||||||
|
|
||||||
|
publish ::scan::cm_count user
|
||||||
|
publish ::scan::cm_scan_prepare user
|
||||||
|
|
||||||
namespace eval scan {
|
namespace eval scan {
|
||||||
namespace export runscan
|
namespace export runscan
|
||||||
VarMake ::scan::runscan_reset_position Text internal
|
VarMake ::scan::runscan_reset_position Text internal
|
||||||
|
|||||||
@@ -6,10 +6,62 @@ namespace eval counter {
|
|||||||
variable isc_monitor_address
|
variable isc_monitor_address
|
||||||
variable isc_portlist
|
variable isc_portlist
|
||||||
variable isc_beam_monitor_list
|
variable isc_beam_monitor_list
|
||||||
|
|
||||||
|
variable isc_cm_address
|
||||||
|
variable isc_cm_port
|
||||||
|
|
||||||
proc set_sobj_attributes {} {
|
proc set_sobj_attributes {} {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
proc ::counter::cm_initialize {} {
|
||||||
|
if [ catch {
|
||||||
|
variable isc_cm_address
|
||||||
|
variable isc_cm_port
|
||||||
|
|
||||||
|
set isc_cm_address 137.157.204.193
|
||||||
|
#set isc_cm_address localhost
|
||||||
|
set isc_cm_port 33000
|
||||||
|
|
||||||
|
MakeAsyncQueue cmserver CAMERA $isc_cm_address $isc_cm_port
|
||||||
|
MakeCounter cm1 anstocamera cmserver
|
||||||
|
|
||||||
|
sicslist setatt cm1 privilege internal
|
||||||
|
::utility::macro::getset text cm1_mode {} {
|
||||||
|
return [cm1 getmode]
|
||||||
|
}
|
||||||
|
sicslist setatt cm1_mode klass monitor
|
||||||
|
sicslist setatt cm1_mode long_name mode
|
||||||
|
sicslist setatt cm1_mode mutable false
|
||||||
|
|
||||||
|
::utility::macro::getset float cm1_preset {} {
|
||||||
|
return [cm1 getpreset]
|
||||||
|
}
|
||||||
|
sicslist setatt cm1_preset klass monitor
|
||||||
|
sicslist setatt cm1_preset long_name preset
|
||||||
|
sicslist setatt cm1_preset mutable false
|
||||||
|
|
||||||
|
::utility::macro::getset int cm1_counts {} [subst -nocommands {
|
||||||
|
return "[cm1 getcounts]"
|
||||||
|
}]
|
||||||
|
sicslist setatt cm1_counts klass monitor
|
||||||
|
sicslist setatt cm1_counts long_name cm1_counts
|
||||||
|
sicslist setatt cm1_counts mutable true
|
||||||
|
|
||||||
|
::utility::macro::getset float cm1_time {} [subst -nocommands {
|
||||||
|
return "[cm1 gettime]"
|
||||||
|
}]
|
||||||
|
sicslist setatt cm1_time klass monitor
|
||||||
|
sicslist setatt cm1_time long_name cm1_time
|
||||||
|
sicslist setatt cm1_time mutable true
|
||||||
|
} message ] {
|
||||||
|
if {$::errorCode=="NONE"} {return $message}
|
||||||
|
return -code error $message
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
publish ::counter::cm_initialize user
|
||||||
|
|
||||||
proc ::counter::isc_initialize {} {
|
proc ::counter::isc_initialize {} {
|
||||||
if [catch {
|
if [catch {
|
||||||
variable isc_numchannels
|
variable isc_numchannels
|
||||||
@@ -17,10 +69,14 @@ proc ::counter::isc_initialize {} {
|
|||||||
variable isc_portlist
|
variable isc_portlist
|
||||||
variable isc_beam_monitor_list {MONITOR_1 MONITOR_2 MONITOR_3}
|
variable isc_beam_monitor_list {MONITOR_1 MONITOR_2 MONITOR_3}
|
||||||
|
|
||||||
set isc_monitor_address "das1-[SplitReply [instrument]]"
|
#set isc_monitor_address "das1-[SplitReply [instrument]]"
|
||||||
set isc_portlist [list 33000 33001 33002 33003 33004 33005 33006 33007]
|
#set isc_portlist [list 33000 33001 33002 33003 33004 33005 33006 33007]
|
||||||
set isc_numchannels [llength $isc_beam_monitor_list]
|
#set isc_numchannels [llength $isc_beam_monitor_list]
|
||||||
::counter::ic_initialize
|
#::counter::ic_initialize
|
||||||
|
|
||||||
|
set isc_cm_address 137.157.204.193
|
||||||
|
set isc_cm_port 33000
|
||||||
|
::counter::cm_initialize
|
||||||
} message ] {
|
} message ] {
|
||||||
if {$::errorCode=="NONE"} {return $message}
|
if {$::errorCode=="NONE"} {return $message}
|
||||||
return -code error "$message"
|
return -code error "$message"
|
||||||
|
|||||||
@@ -17,78 +17,24 @@ set dmc2280_controller2(port) pmc2-$animal
|
|||||||
set dmc2280_controller3(host) mc3-$animal
|
set dmc2280_controller3(host) mc3-$animal
|
||||||
set dmc2280_controller3(port) pmc3-$animal
|
set dmc2280_controller3(port) pmc3-$animal
|
||||||
|
|
||||||
set dmc2280_controller4(host) mc4-$animal
|
#set dmc2280_controller4(host) mc4-$animal
|
||||||
set dmc2280_controller4(port) pmc4-$animal
|
#set dmc2280_controller4(port) pmc4-$animal
|
||||||
|
|
||||||
if {$sim_mode == "true"} {
|
if {$sim_mode == "true"} {
|
||||||
set motor_driver_type asim
|
set motor_driver_type asim
|
||||||
} else {
|
} else {
|
||||||
set motor_driver_type DMC2280
|
set motor_driver_type DMC2280
|
||||||
# MakeAsyncQueue mc1 DMC2280 $dmc2280_controller1(host) $dmc2280_controller1(port)
|
MakeAsyncQueue mc1 DMC2280 $dmc2280_controller1(host) $dmc2280_controller1(port)
|
||||||
# MakeAsyncQueue mc2 DMC2280 $dmc2280_controller2(host) $dmc2280_controller2(port)
|
MakeAsyncQueue mc2 DMC2280 $dmc2280_controller2(host) $dmc2280_controller2(port)
|
||||||
MakeAsyncQueue mc3 DMC2280 $dmc2280_controller3(host) $dmc2280_controller3(port)
|
MakeAsyncQueue mc3 DMC2280 $dmc2280_controller3(host) $dmc2280_controller3(port)
|
||||||
MakeAsyncQueue mc4 DMC2280 $dmc2280_controller4(host) $dmc2280_controller4(port)
|
# MakeAsyncQueue mc4 DMC2280 $dmc2280_controller4(host) $dmc2280_controller4(port)
|
||||||
# MakeAsyncQueue mc6 DMC2280 $dmc2280_controller6(host) $dmc2280_controller6(port)
|
# MakeAsyncQueue mc6 DMC2280 $dmc2280_controller6(host) $dmc2280_controller6(port)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#Measured absolute encoder reading at home position
|
|
||||||
set dummy_Home 0
|
|
||||||
|
|
||||||
set ftz_Home 0
|
|
||||||
set ptz_Home 0
|
|
||||||
set pom_Home 0
|
|
||||||
set stth_Home 0
|
|
||||||
set mtth_Home 0
|
|
||||||
|
|
||||||
set sv1_Home 0
|
|
||||||
set sh1_Home 0
|
|
||||||
set sv2_Home 0
|
|
||||||
set sh2_Home 0
|
|
||||||
set gom_Home 0
|
|
||||||
set scor_Home 0
|
|
||||||
|
|
||||||
# AND abs Encoder Reading with FFF to get the lowest 12 bits only
|
|
||||||
#set mra_Home 4286
|
|
||||||
set mra_Home 191
|
|
||||||
#set moma_Home 8386659
|
|
||||||
set moma_Home 2147
|
|
||||||
#set mrb_Home 294
|
|
||||||
set mrb_Home 294
|
|
||||||
#set momb_Home 8386694
|
|
||||||
set momb_Home 2182
|
|
||||||
#set mrc_Home 4558982
|
|
||||||
set mrc_Home 86
|
|
||||||
#set momc_Home 12499198
|
|
||||||
set momc_Home 2302
|
|
||||||
|
|
||||||
set mphi_Home 0
|
|
||||||
set mchi_Home 8383096
|
|
||||||
set mx_Home 8390604
|
|
||||||
set my_Home 8391084
|
|
||||||
set mom_Home 8389414
|
|
||||||
|
|
||||||
set rco_Home 0
|
|
||||||
set rcz_Home 0
|
|
||||||
set bsr_Home 0
|
|
||||||
set gv1_Home 0
|
|
||||||
set gv2_Home 0
|
|
||||||
|
|
||||||
|
|
||||||
# set movecount high to reduce the frequency of
|
|
||||||
# hnotify messages to a reasonable level
|
|
||||||
set move_count 100
|
|
||||||
|
|
||||||
############################
|
|
||||||
# Motor Controller 1
|
|
||||||
# Motor Controller 1
|
|
||||||
# Motor Controller 1
|
|
||||||
############################
|
|
||||||
#
|
|
||||||
|
|
||||||
# Dummy translation motor, useful for testing scans
|
# Dummy translation motor, useful for testing scans
|
||||||
|
set dummy_Home 0
|
||||||
#Motor dummy_motor asim [params \
|
Motor dummy_motor asim [params \
|
||||||
asyncqueue mc1\
|
asyncqueue mc1\
|
||||||
host mc1-dingo\
|
host mc1-dingo\
|
||||||
port pmc1-dingo\
|
port pmc1-dingo\
|
||||||
@@ -103,17 +49,53 @@ set move_count 100
|
|||||||
absEnc 1\
|
absEnc 1\
|
||||||
absEncHome $dummy_Home\
|
absEncHome $dummy_Home\
|
||||||
cntsPerX [expr 8192.0/5.0]]
|
cntsPerX [expr 8192.0/5.0]]
|
||||||
#dummy_motor part instrument
|
dummy_motor part instrument
|
||||||
#dummy_motor long_name dummy_motor
|
dummy_motor long_name dummy_motor
|
||||||
#dummy_motor softlowerlim -500
|
dummy_motor softlowerlim -500
|
||||||
#dummy_motor softupperlim 500
|
dummy_motor softupperlim 500
|
||||||
#dummy_motor home 0
|
dummy_motor home 0
|
||||||
|
|
||||||
# mc1: Polariser & Spin Flipper - Z translation slide
|
############################
|
||||||
# Moto: 100:1 gear, 2mm pitch
|
# Motor Controller 1
|
||||||
set ptzStepRate [expr (300000.0/100.0)/2.0]
|
# Motor Controller 1
|
||||||
|
# Motor Controller 1
|
||||||
|
############################
|
||||||
|
#
|
||||||
|
|
||||||
Motor ptz $motor_driver_type [params \
|
# All motors are at 25000steps/turn if no other specify
|
||||||
|
set motorrate 25000.0
|
||||||
|
|
||||||
|
# mc1: Sample rotation axis
|
||||||
|
# Gearbox 100:1, Gear ratio 356:1
|
||||||
|
set stth_Home 0
|
||||||
|
set stthStepRate [expr $motorrate*100.0*356.0/360.0]
|
||||||
|
Motor stth $motor_driver_type [params \
|
||||||
|
asyncqueue mc1\
|
||||||
|
host mc1-dingo\
|
||||||
|
port pmc1-dingo\
|
||||||
|
axis A\
|
||||||
|
units degree\
|
||||||
|
hardlowerlim 0\
|
||||||
|
hardupperlim 360\
|
||||||
|
maxSpeed [expr 400000.0/300000.0]\
|
||||||
|
maxAccel [expr 150000.0/300000.0]\
|
||||||
|
maxDecel [expr 150000.0/300000.0]\
|
||||||
|
stepsPerX $stthStepRate\
|
||||||
|
absEnc 1\
|
||||||
|
absEncHome $stth_Home\
|
||||||
|
cntsPerX 4096]
|
||||||
|
stth part sample
|
||||||
|
stth long_name stth
|
||||||
|
stth softlowerlim 0
|
||||||
|
stth softupperlim 360
|
||||||
|
stth home 0
|
||||||
|
|
||||||
|
|
||||||
|
# mc1: Sample X-translation sample stage
|
||||||
|
# Gearbox 20:1, pitch 5mm
|
||||||
|
set sx_Home 0
|
||||||
|
set sxStepRate [expr $motorrate*20.0/5.0]
|
||||||
|
Motor sx $motor_driver_type [params \
|
||||||
asyncqueue mc1\
|
asyncqueue mc1\
|
||||||
host mc1-dingo\
|
host mc1-dingo\
|
||||||
port pmc1-dingo\
|
port pmc1-dingo\
|
||||||
@@ -124,22 +106,21 @@ Motor ptz $motor_driver_type [params \
|
|||||||
maxSpeed [expr 400000.0/300000.0]\
|
maxSpeed [expr 400000.0/300000.0]\
|
||||||
maxAccel [expr 150000.0/300000.0]\
|
maxAccel [expr 150000.0/300000.0]\
|
||||||
maxDecel [expr 150000.0/300000.0]\
|
maxDecel [expr 150000.0/300000.0]\
|
||||||
stepsPerX $ptzStepRate\
|
stepsPerX $sxStepRate\
|
||||||
absEnc 1\
|
absEnc 1\
|
||||||
absEncHome $ptz_Home\
|
absEncHome $sx_Home\
|
||||||
cntsPerX 4096]
|
cntsPerX 4096]
|
||||||
ptz part crystal
|
sx part sample
|
||||||
ptz long_name ptz
|
sx long_name sx
|
||||||
ptz softlowerlim 0
|
sx softlowerlim -250
|
||||||
ptz softupperlim 500
|
sx softupperlim 250
|
||||||
ptz home 0
|
sx home 0
|
||||||
|
|
||||||
#if $use_tiltstage {
|
# mc1: Sample Y-translation sample stage
|
||||||
# mc1: Beryllium / Graphite filter shared - Z translation slide
|
# Gearbox 20:1, pitch 5mm
|
||||||
# Moto: 100:1 gear, 2mm pitch
|
set sy_Home 0
|
||||||
set ftzStepRate [expr (300000.0/100.0)/2.0]
|
set syStepRate [expr $motorrate*20.0/5.0]
|
||||||
|
Motor sy $motor_driver_type [params \
|
||||||
Motor ftz $motor_driver_type [params \
|
|
||||||
asyncqueue mc1\
|
asyncqueue mc1\
|
||||||
host mc1-dingo\
|
host mc1-dingo\
|
||||||
port pmc1-dingo\
|
port pmc1-dingo\
|
||||||
@@ -150,87 +131,65 @@ Motor ftz $motor_driver_type [params \
|
|||||||
maxSpeed [expr 400000.0/300000.0]\
|
maxSpeed [expr 400000.0/300000.0]\
|
||||||
maxAccel [expr 150000.0/300000.0]\
|
maxAccel [expr 150000.0/300000.0]\
|
||||||
maxDecel [expr 150000.0/300000.0]\
|
maxDecel [expr 150000.0/300000.0]\
|
||||||
stepsPerX $ftzStepRate\
|
stepsPerX $syStepRate\
|
||||||
absEnc 1\
|
absEnc 1\
|
||||||
absEncHome $ftz_Home\
|
absEncHome $sy_Home\
|
||||||
cntsPerX 4096]
|
cntsPerX 4096]
|
||||||
ftz part crystal
|
sy part sample
|
||||||
ftz long_name ftz
|
sy long_name sy
|
||||||
ftz softlowerlim 0
|
sy softlowerlim -250
|
||||||
ftz softupperlim 500
|
sy softupperlim 250
|
||||||
ftz home 0
|
sy home 0
|
||||||
|
|
||||||
# mc1: Polariser (& Spin Flipper) - Rotation + - 2 deg about polariser (i.e, The Elbow)
|
# mc1: Sample Z-translation sample stage
|
||||||
set pomSetRate 25000
|
# Gearbox 20:1, pitch ?
|
||||||
|
set sz_Home 0
|
||||||
Motor pom $motor_driver_type [params \
|
set szStepRate ?
|
||||||
|
Motor sz $motor_driver_type [params \
|
||||||
asyncqueue mc1\
|
asyncqueue mc1\
|
||||||
host mc1-dingo\
|
host mc1-dingo\
|
||||||
port pmc1-dingo\
|
port pmc1-dingo\
|
||||||
axis E\
|
axis D\
|
||||||
units degrees\
|
units mm\
|
||||||
hardlowerlim 0\
|
hardlowerlim 0\
|
||||||
hardupperlim 2\
|
hardupperlim 500\
|
||||||
maxSpeed [expr 250000.0/$pomSetRate]\
|
maxSpeed [expr 400000.0/300000.0]\
|
||||||
maxAccel [expr 25000.0/$pomSetRate]\
|
maxAccel [expr 150000.0/300000.0]\
|
||||||
maxDecel [expr 25000.0/$pomSetRate]\
|
maxDecel [expr 150000.0/300000.0]\
|
||||||
stepsPerX $pomSetRate\
|
stepsPerX $szStepRate\
|
||||||
absEnc 1\
|
absEnc 1\
|
||||||
absEncHome $pom_Home\
|
absEncHome $sz_Home\
|
||||||
cntsPerX 4096]
|
cntsPerX 4096]
|
||||||
pom part crystal
|
sz part sample
|
||||||
pom long_name pom
|
sz long_name sz
|
||||||
pom softlowerlim 0
|
sz softlowerlim -250
|
||||||
pom softupperlim 2
|
sz softupperlim 250
|
||||||
pom home 0
|
sz home 0
|
||||||
|
|
||||||
# mc1: Sample/Detector Chamber Rotation (Detector)
|
# mc1: End station Z-translation
|
||||||
set stthSetRate 25000
|
# Gearbox 5:1, Gear ratio 16:1, pitch 4mm
|
||||||
|
set dz_Home 0
|
||||||
Motor stth $motor_driver_type [params \
|
set dzStepRate [expr $motorrate*5.0*16.0/4.0]
|
||||||
asyncqueue mc1\
|
Motor dz $motor_driver_type [params \
|
||||||
host mc1-dingo\
|
|
||||||
port pmc1-dingo\
|
|
||||||
axis F\
|
|
||||||
units degrees\
|
|
||||||
hardlowerlim -125\
|
|
||||||
hardupperlim 8\
|
|
||||||
maxSpeed [expr 150000.0/$stthSetRate]\
|
|
||||||
maxAccel [expr 5000.0/$stthSetRate]\
|
|
||||||
maxDecel [expr 5000.0/$stthSetRate]\
|
|
||||||
stepsPerX $stthSetRate\
|
|
||||||
absEnc 1\
|
|
||||||
absEncHome $stth_Home\
|
|
||||||
cntsPerX 4096]
|
|
||||||
stth part detector
|
|
||||||
stth long_name stth
|
|
||||||
stth softlowerlim -125
|
|
||||||
stth softupperlim 8
|
|
||||||
stth home 0
|
|
||||||
|
|
||||||
# mc1: Instrument Drive System (Main Drive)
|
|
||||||
set mtthSetRate 25000
|
|
||||||
|
|
||||||
Motor mtth $motor_driver_type [params \
|
|
||||||
asyncqueue mc1\
|
asyncqueue mc1\
|
||||||
host mc1-dingo\
|
host mc1-dingo\
|
||||||
port pmc1-dingo\
|
port pmc1-dingo\
|
||||||
axis G\
|
axis G\
|
||||||
units mm\
|
units mm\
|
||||||
hardlowerlim 40\
|
hardlowerlim 0\
|
||||||
hardupperlim 140\
|
hardupperlim 500\
|
||||||
maxSpeed [expr 150000.0/$mtthSetRate]\
|
maxSpeed [expr 400000.0/300000.0]\
|
||||||
maxAccel [expr 25000.0/$mtthSetRate]\
|
maxAccel [expr 150000.0/300000.0]\
|
||||||
maxDecel [expr 25000.0/$mtthSetRate]\
|
maxDecel [expr 150000.0/300000.0]\
|
||||||
stepsPerX $mtthSetRate\
|
stepsPerX $dzStepRate\
|
||||||
absEnc 1\
|
absEnc 1\
|
||||||
absEncHome $mtth_Home\
|
absEncHome $dz_Home\
|
||||||
cntsPerX 4096]
|
cntsPerX 4096]
|
||||||
mtth part detector
|
dz part sample
|
||||||
mtth long_name mtth
|
dz long_name dz
|
||||||
mtth softlowerlim 40
|
dz softlowerlim -125
|
||||||
mtth softupperlim 140
|
dz softupperlim 125
|
||||||
mtth home 0
|
sz home 0
|
||||||
|
|
||||||
|
|
||||||
############################
|
############################
|
||||||
@@ -238,478 +197,66 @@ mtth home 0
|
|||||||
# Motor Controller 2
|
# Motor Controller 2
|
||||||
# Motor Controller 2
|
# Motor Controller 2
|
||||||
############################
|
############################
|
||||||
#
|
#
|
||||||
|
|
||||||
# mc2: Slits Set AB1- (After Beryllium Filter) (2 blades and 1 Motor & Encoder set)
|
# mc2: Camera translation axis along beam
|
||||||
set sv1SetRate 25000
|
# Gearbox ?, Gear ratio ?,
|
||||||
|
set dy_Home 0
|
||||||
Motor sv1 $motor_driver_type [params \
|
set dyStepRate ?
|
||||||
|
Motor dy $motor_driver_type [params \
|
||||||
asyncqueue mc2\
|
asyncqueue mc2\
|
||||||
host mc2-dingo\
|
host mc2-dingo\
|
||||||
port pmc2-dingo\
|
port pmc2-dingo\
|
||||||
axis A\
|
axis A\
|
||||||
units mm\
|
units mm\
|
||||||
hardlowerlim -2\
|
|
||||||
hardupperlim 60\
|
|
||||||
maxSpeed [expr 25000.0/$sv1SetRate]\
|
|
||||||
maxAccel [expr 25000.0/$sv1SetRate]\
|
|
||||||
maxDecel [expr 25000.0/$sv1SetRate]\
|
|
||||||
stepsPerX $sv1SetRate\
|
|
||||||
absEnc 1\
|
|
||||||
absEncHome $sv1_Home\
|
|
||||||
cntsPerX 4096]
|
|
||||||
sv1 part aperture
|
|
||||||
sv1 long_name sv1
|
|
||||||
sv1 softlowerlim -2
|
|
||||||
sv1 softupperlim 60
|
|
||||||
sv1 home 0
|
|
||||||
|
|
||||||
# mc2: Slits Set AB2- (After Beryllium Filter) (2 blades and 1 Motor & Encoder set)
|
|
||||||
set sh1SetRate 25000
|
|
||||||
|
|
||||||
Motor sh1 $motor_driver_type [params \
|
|
||||||
asyncqueue mc2\
|
|
||||||
host mc2-dingo\
|
|
||||||
port pmc2-dingo\
|
|
||||||
axis B\
|
|
||||||
units mm\
|
|
||||||
hardlowerlim -2\
|
|
||||||
hardupperlim 50\
|
|
||||||
maxSpeed [expr 25000.0/$sh1SetRate]\
|
|
||||||
maxAccel [expr 25000.0/$sh1SetRate]\
|
|
||||||
maxDecel [expr 25000.0/$sh1SetRate]\
|
|
||||||
stepsPerX $sh1SetRate\
|
|
||||||
absEnc 1\
|
|
||||||
absEncHome $sh1_Home\
|
|
||||||
cntsPerX 4096]
|
|
||||||
sh1 part aperture
|
|
||||||
sh1 long_name sh1
|
|
||||||
sh1 softlowerlim -2
|
|
||||||
sh1 softupperlim 50
|
|
||||||
sh1 home 0
|
|
||||||
|
|
||||||
# mc2: Slits Set AF1- (After Fermi Chopper) (2 blades and 1 Motor & Encoder set)
|
|
||||||
set sv2SetRate 25000
|
|
||||||
|
|
||||||
Motor sv2 $motor_driver_type [params \
|
|
||||||
asyncqueue mc2\
|
|
||||||
host mc2-dingo\
|
|
||||||
port pmc2-dingo\
|
|
||||||
axis C\
|
|
||||||
units mm\
|
|
||||||
hardlowerlim -2\
|
|
||||||
hardupperlim 40\
|
|
||||||
maxSpeed [expr 25000.0/$sv2SetRate]\
|
|
||||||
maxAccel [expr 25000.0/$sv2SetRate]\
|
|
||||||
maxDecel [expr 25000.0/$sv2SetRate]\
|
|
||||||
stepsPerX $sv2SetRate\
|
|
||||||
absEnc 1\
|
|
||||||
absEncHome $sv2_Home\
|
|
||||||
cntsPerX 4096]
|
|
||||||
sv2 part aperture
|
|
||||||
sv2 long_name sv2
|
|
||||||
sv2 softlowerlim -2
|
|
||||||
sv2 softupperlim 40
|
|
||||||
sv2 home 0
|
|
||||||
|
|
||||||
# mc2: Slits Set AF2- (After Fermi Chopper) (2 blades and 1 Motor & Encoder set)
|
|
||||||
set sh2SetRate 25000
|
|
||||||
|
|
||||||
Motor sh2 $motor_driver_type [params \
|
|
||||||
asyncqueue mc2\
|
|
||||||
host mc2-dingo\
|
|
||||||
port pmc2-dingo\
|
|
||||||
axis D\
|
|
||||||
units mm\
|
|
||||||
hardlowerlim -2\
|
|
||||||
hardupperlim 30\
|
|
||||||
maxSpeed [expr 25000.0/$sh2SetRate]\
|
|
||||||
maxAccel [expr 25000.0/$sh2SetRate]\
|
|
||||||
maxDecel [expr 25000.0/$sh2SetRate]\
|
|
||||||
stepsPerX $sh2SetRate\
|
|
||||||
absEnc 1\
|
|
||||||
absEncHome $sh2_Home\
|
|
||||||
cntsPerX 4096]
|
|
||||||
sh2 part aperture
|
|
||||||
sh2 long_name sh2
|
|
||||||
sh2 softlowerlim -2
|
|
||||||
sh2 softupperlim 30
|
|
||||||
sh2 home 0
|
|
||||||
|
|
||||||
# mc2: Graphite filter rotation stage (post 1st slit and post 1st Fermi chopper)
|
|
||||||
set gomSetRate 25000
|
|
||||||
|
|
||||||
Motor gom $motor_driver_type [params \
|
|
||||||
asyncqueue mc2\
|
|
||||||
host mc2-dingo\
|
|
||||||
port pmc2-dingo\
|
|
||||||
axis E\
|
|
||||||
units degrees\
|
|
||||||
hardlowerlim 0\
|
hardlowerlim 0\
|
||||||
hardupperlim 15\
|
hardupperlim 500\
|
||||||
maxSpeed [expr 50000.0/$gomSetRate]\
|
maxSpeed [expr 400000.0/300000.0]\
|
||||||
maxAccel [expr 25000.0/$gomSetRate]\
|
maxAccel [expr 150000.0/300000.0]\
|
||||||
maxDecel [expr 25000.0/$gomSetRate]\
|
maxDecel [expr 150000.0/300000.0]\
|
||||||
stepsPerX $gomSetRate\
|
stepsPerX $dyStepRate\
|
||||||
absEnc 1\
|
absEnc 1\
|
||||||
absEncHome $gom_Home\
|
absEncHome $dy_Home\
|
||||||
cntsPerX 4096]
|
cntsPerX 4096]
|
||||||
gom part sample
|
dy part instrument
|
||||||
gom long_name gom
|
dy long_name dy
|
||||||
gom softlowerlim 0
|
dy softlowerlim 0
|
||||||
gom softupperlim 15
|
dy softupperlim 20
|
||||||
gom home 0
|
dy home 0
|
||||||
|
|
||||||
# mc2: Sample rotation correction - 10 deg rotation
|
|
||||||
set scorSetRate 25000
|
|
||||||
|
|
||||||
Motor scor $motor_driver_type [params \
|
|
||||||
asyncqueue mc2\
|
|
||||||
host mc2-dingo\
|
|
||||||
port pmc2-dingo\
|
|
||||||
axis F\
|
|
||||||
units degrees\
|
|
||||||
hardlowerlim 0\
|
|
||||||
hardupperlim 360\
|
|
||||||
maxSpeed [expr 50000.0/$scorSetRate]\
|
|
||||||
maxAccel [expr 25000.0/$scorSetRate]\
|
|
||||||
maxDecel [expr 25000.0/$scorSetRate]\
|
|
||||||
stepsPerX $scorSetRate\
|
|
||||||
absEnc 1\
|
|
||||||
absEncHome $scor_Home\
|
|
||||||
cntsPerX 4096]
|
|
||||||
scor part sample
|
|
||||||
scor long_name scor
|
|
||||||
scor softlowerlim 0
|
|
||||||
scor softupperlim 360
|
|
||||||
scor home 0
|
|
||||||
|
|
||||||
############################
|
############################
|
||||||
# Motor Controller 3
|
# Motor Controller 3
|
||||||
# Motor Controller 3
|
# Motor Controller 3
|
||||||
# Motor Controller 3
|
# Motor Controller 3
|
||||||
############################
|
############################
|
||||||
#
|
#
|
||||||
|
|
||||||
# ROTATION STAGES 120:1 PLUS GEARBOX 8:1
|
# mc3: Selector Wheel Rotation Axis (attenuator)
|
||||||
# ROTATION STAGE RESOLVER 360:55
|
# Gearbox 50:1, Gear ratio 119:14
|
||||||
|
set at_Home 0
|
||||||
# FOCUS STAGE GEARBOX 6:1
|
set atStepRate [expr $motorrate*50.0*119.0/14.0/360.0]
|
||||||
# FOCUS STAGE RESOLVER DIRECT 310 DEG, 3527 COUNTS USABLE RANGE
|
Motor at $motor_driver_type [params \
|
||||||
|
|
||||||
# Computes Monochromator step rates (steps per degree) of focusing and Rotation
|
|
||||||
# 1 unit here is 1 degree
|
|
||||||
set monoRotateStepsPerUnit [expr 25000.0*8.0*120.0/360.0]
|
|
||||||
|
|
||||||
# Encode reading at the roation, 1 unit here is 1 degree
|
|
||||||
set MonoRotateCntsPerUnit [expr 4096.0*360.0/55.0/360.0]
|
|
||||||
|
|
||||||
# Setup Focus range as min = 0 and max = 1, working range = 0 to 1 (310 degrees)
|
|
||||||
# or, 0 for full focus and 1 for non focus
|
|
||||||
# Focusing rate 25000 steps * 6:1 gears = 150000, 1 unit here is 310 degrees
|
|
||||||
set monoFocusStepsPerUnit [expr -25000.0*6.0*310.0/360.0]
|
|
||||||
|
|
||||||
# Encode reading at Focusing stage, 1 unit here is 310 degrees
|
|
||||||
set monoFocusCntsPerUnit [expr 4096.0*310.0/360.0]
|
|
||||||
|
|
||||||
# Max speed for Focusing , -- currently set as 0.083
|
|
||||||
# speed unit here is 310 degrees
|
|
||||||
set monoFocusSpeed 0.05
|
|
||||||
set monoFocusMaxSpeed 0.083
|
|
||||||
|
|
||||||
# Precision setting turn/move, or 310*turn/move (degrees)
|
|
||||||
set monoFocusprecision 0.001
|
|
||||||
|
|
||||||
# mc3: Monochromator Focusing 1 - Focus
|
|
||||||
Motor mra $motor_driver_type [params \
|
|
||||||
asyncqueue mc3\
|
asyncqueue mc3\
|
||||||
host mc3-dingo\
|
host mc3-dingo\
|
||||||
port pmc3-dingo\
|
port pmc3-dingo\
|
||||||
axis A\
|
axis A\
|
||||||
units degrees\
|
|
||||||
hardlowerlim 0\
|
|
||||||
hardupperlim 1\
|
|
||||||
precision $monoFocusprecision\
|
|
||||||
maxSpeed $monoFocusMaxSpeed\
|
|
||||||
maxAccel [expr 25000.0/25000.0]\
|
|
||||||
maxDecel [expr 25000.0/25000.0]\
|
|
||||||
stepsPerX $monoFocusStepsPerUnit\
|
|
||||||
absEnc 1\
|
|
||||||
absEncHome $mra_Home\
|
|
||||||
bias_bits 12\
|
|
||||||
cntsPerX $monoFocusCntsPerUnit]
|
|
||||||
mra speed $monoFocusSpeed
|
|
||||||
mra accel $monoFocusSpeed
|
|
||||||
mra decel $monoFocusSpeed
|
|
||||||
mra part crystal
|
|
||||||
mra long_name mra
|
|
||||||
mra softlowerlim 0
|
|
||||||
mra softupperlim 1
|
|
||||||
mra home 0
|
|
||||||
# fix the motor
|
|
||||||
mra fixed -1
|
|
||||||
|
|
||||||
# mc3: Monochromator Focusing 1 - Rotation
|
|
||||||
Motor moma $motor_driver_type [params \
|
|
||||||
asyncqueue mc3\
|
|
||||||
host mc3-dingo\
|
|
||||||
port pmc3-dingo\
|
|
||||||
axis B\
|
|
||||||
units degrees\
|
|
||||||
hardlowerlim -72.003174\
|
|
||||||
hardupperlim -20.0379\
|
|
||||||
maxSpeed 0.5\
|
|
||||||
maxAccel 0.5\
|
|
||||||
maxDecel 0.5\
|
|
||||||
stepsPerX $monoRotateStepsPerUnit\
|
|
||||||
absEnc 1\
|
|
||||||
absEncHome $moma_Home\
|
|
||||||
bias_bits 12\
|
|
||||||
cntsPerX $MonoRotateCntsPerUnit]
|
|
||||||
moma part crystal
|
|
||||||
moma long_name moma
|
|
||||||
moma softlowerlim -70
|
|
||||||
moma softupperlim -20.537842
|
|
||||||
moma home -45
|
|
||||||
|
|
||||||
# mc3: Monochromator Focusing 2 - Focus
|
|
||||||
Motor mrb $motor_driver_type [params \
|
|
||||||
asyncqueue mc3\
|
|
||||||
host mc3-dingo\
|
|
||||||
port pmc3-dingo\
|
|
||||||
axis C\
|
|
||||||
units degrees\
|
|
||||||
hardlowerlim 0\
|
|
||||||
hardupperlim 1\
|
|
||||||
precision $monoFocusprecision\
|
|
||||||
maxSpeed $monoFocusMaxSpeed\
|
|
||||||
maxAccel [expr 25000.0/25000.0]\
|
|
||||||
maxDecel [expr 25000.0/25000.0]\
|
|
||||||
stepsPerX $monoFocusStepsPerUnit\
|
|
||||||
absEnc 1\
|
|
||||||
absEncHome $mrb_Home\
|
|
||||||
bias_bits 12\
|
|
||||||
cntsPerX $monoFocusCntsPerUnit]
|
|
||||||
mrb speed $monoFocusSpeed
|
|
||||||
mrb accel $monoFocusSpeed
|
|
||||||
mrb decel $monoFocusSpeed
|
|
||||||
mrb part crystal
|
|
||||||
mrb long_name mrb
|
|
||||||
mrb softlowerlim 0
|
|
||||||
mrb softupperlim 1
|
|
||||||
mrb home 0
|
|
||||||
# fix the motor
|
|
||||||
mrb fixed -1
|
|
||||||
|
|
||||||
# mc3: Monochromator Focusing 2 - Rotation
|
|
||||||
Motor momb $motor_driver_type [params \
|
|
||||||
asyncqueue mc3\
|
|
||||||
host mc3-dingo\
|
|
||||||
port pmc3-dingo\
|
|
||||||
axis D\
|
|
||||||
units degree\
|
units degree\
|
||||||
hardlowerlim -72.003174\
|
|
||||||
hardupperlim -20.198975\
|
|
||||||
maxSpeed 0.5\
|
|
||||||
maxAccel 0.5\
|
|
||||||
maxDecel 0.5\
|
|
||||||
stepsPerX $monoRotateStepsPerUnit\
|
|
||||||
absEnc 1\
|
|
||||||
absEncHome $momb_Home\
|
|
||||||
bias_bits 12\
|
|
||||||
cntsPerX $MonoRotateCntsPerUnit]
|
|
||||||
momb part crystal
|
|
||||||
momb long_name momb
|
|
||||||
momb softlowerlim -70
|
|
||||||
momb softupperlim -20.698975
|
|
||||||
momb home -45
|
|
||||||
|
|
||||||
# mc3: Monochromator Focusing 3 - Focus
|
|
||||||
Motor mrc $motor_driver_type [params \
|
|
||||||
asyncqueue mc3\
|
|
||||||
host mc3-dingo\
|
|
||||||
port pmc3-dingo\
|
|
||||||
axis E\
|
|
||||||
units degrees\
|
|
||||||
hardlowerlim 0\
|
hardlowerlim 0\
|
||||||
hardupperlim 1\
|
hardupperlim 500\
|
||||||
precision $monoFocusprecision\
|
maxSpeed [expr 400000.0/300000.0]\
|
||||||
maxSpeed $monoFocusMaxSpeed\
|
maxAccel [expr 150000.0/300000.0]\
|
||||||
maxAccel [expr 25000.0/25000.0]\
|
maxDecel [expr 150000.0/300000.0]\
|
||||||
maxDecel [expr 25000.0/25000.0]\
|
stepsPerX $atStepRate\
|
||||||
stepsPerX $monoFocusStepsPerUnit\
|
|
||||||
absEnc 1\
|
absEnc 1\
|
||||||
absEncHome $mrc_Home\
|
absEncHome $at_Home\
|
||||||
bias_bits 12\
|
|
||||||
cntsPerX $monoFocusCntsPerUnit]
|
|
||||||
mrc speed $monoFocusSpeed
|
|
||||||
mrc accel $monoFocusSpeed
|
|
||||||
mrc decel $monoFocusSpeed
|
|
||||||
mrc part crystal
|
|
||||||
mrc long_name mrc
|
|
||||||
mrc softlowerlim 0
|
|
||||||
mrc softupperlim 1
|
|
||||||
mrc home 0
|
|
||||||
# fix the motor
|
|
||||||
mrc fixed -1
|
|
||||||
|
|
||||||
# mc3: Monochromator Focusing 3 - Rotation
|
|
||||||
Motor momc $motor_driver_type [params \
|
|
||||||
asyncqueue mc3\
|
|
||||||
host mc3-dingo\
|
|
||||||
port pmc3-dingo\
|
|
||||||
axis F\
|
|
||||||
units degree\
|
|
||||||
hardlowerlim -72.003174\
|
|
||||||
hardupperlim -21.246338\
|
|
||||||
maxSpeed 0.5\
|
|
||||||
maxAccel 0.5\
|
|
||||||
maxDecel 0.5\
|
|
||||||
stepsPerX $monoRotateStepsPerUnit\
|
|
||||||
absEnc 1\
|
|
||||||
absEncHome $momc_Home\
|
|
||||||
bias_bits 12\
|
|
||||||
cntsPerX $MonoRotateCntsPerUnit]
|
|
||||||
momc part crystal
|
|
||||||
momc long_name momc
|
|
||||||
momc softlowerlim -70
|
|
||||||
momc softupperlim -21.746338
|
|
||||||
momc home -45
|
|
||||||
|
|
||||||
|
|
||||||
############################
|
|
||||||
# Motor Controller 4
|
|
||||||
# Motor Controller 4
|
|
||||||
# Motor Controller 4
|
|
||||||
############################
|
|
||||||
#
|
|
||||||
|
|
||||||
# mc4: Monochromator crystal stages tilt stage - G270
|
|
||||||
set mphiSetRate 25000
|
|
||||||
|
|
||||||
Motor mphi $motor_driver_type [params \
|
|
||||||
asyncqueue mc4\
|
|
||||||
host mc4-dingo\
|
|
||||||
port pmc4-dingo\
|
|
||||||
axis A\
|
|
||||||
units degrees\
|
|
||||||
hardlowerlim -5\
|
|
||||||
hardupperlim 5\
|
|
||||||
maxSpeed [expr 50000.0/25000.0]\
|
|
||||||
maxAccel [expr 12500.0/25000.0]\
|
|
||||||
maxDecel [expr 12500.0/25000.0]\
|
|
||||||
stepsPerX $mphiSetRate\
|
|
||||||
absEnc 1\
|
|
||||||
absEncHome $mphi_Home\
|
|
||||||
cntsPerX 4096]
|
cntsPerX 4096]
|
||||||
mphi part crystal
|
at part sample
|
||||||
mphi long_name mphi
|
at long_name at
|
||||||
mphi softlowerlim -5
|
at softlowerlim 0
|
||||||
mphi softupperlim 5
|
at softupperlim 20
|
||||||
mphi home 0
|
|
||||||
|
|
||||||
# mc4: Monochromator crystal stages tilt stage - G350
|
|
||||||
set mchiSetRate 25000
|
|
||||||
|
|
||||||
Motor mchi $motor_driver_type [params \
|
|
||||||
asyncqueue mc4\
|
|
||||||
host mc4-dingo\
|
|
||||||
port pmc4-dingo\
|
|
||||||
axis B\
|
|
||||||
units degrees\
|
|
||||||
hardlowerlim -5\
|
|
||||||
hardupperlim 5\
|
|
||||||
maxSpeed [expr 50000.0/25000.0]\
|
|
||||||
maxAccel [expr 12500.0/25000.0]\
|
|
||||||
maxDecel [expr 12500.0/25000.0]\
|
|
||||||
stepsPerX $mchiSetRate\
|
|
||||||
absEnc 1\
|
|
||||||
absEncHome $mchi_Home\
|
|
||||||
cntsPerX 4096]
|
|
||||||
mchi part crystal
|
|
||||||
mchi long_name mchi
|
|
||||||
mchi softlowerlim -5
|
|
||||||
mchi softupperlim 5
|
|
||||||
mchi home 0
|
|
||||||
mchi speed 0.2
|
|
||||||
mchi accel 0.1
|
|
||||||
mchi decel 0.1
|
|
||||||
|
|
||||||
# mc4: Monochromator crystal stages Linear stage X - T250
|
|
||||||
set mxSetRate 25000
|
|
||||||
|
|
||||||
Motor mx $motor_driver_type [params \
|
|
||||||
asyncqueue mc4\
|
|
||||||
host mc4-dingo\
|
|
||||||
port pmc4-dingo\
|
|
||||||
axis C\
|
|
||||||
units mm\
|
|
||||||
hardlowerlim -20\
|
|
||||||
hardupperlim 20\
|
|
||||||
maxSpeed [expr 50000.0/25000.0]\
|
|
||||||
maxAccel [expr 12500.0/25000.0]\
|
|
||||||
maxDecel [expr 12500.0/25000.0]\
|
|
||||||
stepsPerX $mxSetRate\
|
|
||||||
absEnc 1\
|
|
||||||
absEncHome $mx_Home\
|
|
||||||
cntsPerX 4096]
|
|
||||||
mx part crystal
|
|
||||||
mx long_name mx
|
|
||||||
mx softlowerlim -20
|
|
||||||
mx softupperlim 20
|
|
||||||
mx home 0
|
|
||||||
mx speed 1.0
|
|
||||||
|
|
||||||
# mc4: Monochromator crystal stages Linear stage Y - T250
|
|
||||||
set mySetRate 25000
|
|
||||||
|
|
||||||
Motor my $motor_driver_type [params \
|
|
||||||
asyncqueue mc4\
|
|
||||||
host mc4-dingo\
|
|
||||||
port pmc4-dingo\
|
|
||||||
axis D\
|
|
||||||
units mm\
|
|
||||||
hardlowerlim -20\
|
|
||||||
hardupperlim 20\
|
|
||||||
maxSpeed [expr 50000.0/25000.0]\
|
|
||||||
maxAccel [expr 12500.0/25000.0]\
|
|
||||||
maxDecel [expr 12500.0/25000.0]\
|
|
||||||
stepsPerX $mySetRate\
|
|
||||||
absEnc 1\
|
|
||||||
absEncHome $my_Home\
|
|
||||||
cntsPerX 4096]
|
|
||||||
my part crystal
|
|
||||||
my long_name my
|
|
||||||
my softlowerlim -10
|
|
||||||
my softupperlim 10
|
|
||||||
my home 0
|
|
||||||
my speed 1.0
|
|
||||||
|
|
||||||
# mc4: Monochromator crystal stages Rotation stage - R275
|
|
||||||
set momSetRate 25000
|
|
||||||
|
|
||||||
Motor mom $motor_driver_type [params \
|
|
||||||
asyncqueue mc4\
|
|
||||||
host mc4-dingo\
|
|
||||||
port pmc4-dingo\
|
|
||||||
axis E\
|
|
||||||
units degrees\
|
|
||||||
hardlowerlim -15\
|
|
||||||
hardupperlim 15\
|
|
||||||
maxSpeed [expr 50000.0/25000.0]\
|
|
||||||
maxAccel [expr 12500.0/25000.0]\
|
|
||||||
maxDecel [expr 12500.0/25000.0]\
|
|
||||||
stepsPerX $momSetRate\
|
|
||||||
absEnc 1\
|
|
||||||
absEncHome $mom_Home\
|
|
||||||
cntsPerX 4096]
|
|
||||||
mom speed 0.5
|
|
||||||
mom part crystal
|
|
||||||
mom long_name mom
|
|
||||||
mom softlowerlim -15
|
|
||||||
mom softupperlim 15
|
|
||||||
mom home 0
|
|
||||||
|
|
||||||
proc motor_set_sobj_attributes {} {
|
proc motor_set_sobj_attributes {} {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# End of configuration file
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,21 @@
|
|||||||
set sim_mode [SplitReply [plc_simulation]]
|
set sim_mode [SplitReply [plc_simulation]]
|
||||||
if {$sim_mode == "false"} {
|
#if {$sim_mode == "false"} {
|
||||||
# MakeAsyncQueue plc_chan SafetyPLC 137.157.204.79 31001
|
MakeAsyncQueue plc_chan SafetyPLC 137.157.204.213 30000
|
||||||
# MakeSafetyPLC plc plc_chan 0
|
MakeSafetyPLC plc plc_chan 0
|
||||||
|
#}
|
||||||
|
|
||||||
|
proc shutter {args} {
|
||||||
|
set cmd "set shutter=$args\r\n"
|
||||||
|
plc_chan send $cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
|
proc focuslight {args} {
|
||||||
|
set cmd "set focuslight=$args\r\n"
|
||||||
|
plc_chan send $cmd
|
||||||
|
}
|
||||||
|
|
||||||
|
publish shutter user
|
||||||
|
publish focuslight user
|
||||||
|
|
||||||
source $cfPath(plc)/plc_common_1.tcl
|
source $cfPath(plc)/plc_common_1.tcl
|
||||||
|
|
||||||
|
|||||||
@@ -3,4 +3,23 @@ proc ::scan::pre_hmm_scan_prepare {} {}
|
|||||||
|
|
||||||
proc ::scan::isc_initialize {} {
|
proc ::scan::isc_initialize {} {
|
||||||
::scan::ic_initialize
|
::scan::ic_initialize
|
||||||
|
|
||||||
|
foreach {n v} {
|
||||||
|
clock 1
|
||||||
|
bin 1
|
||||||
|
size 2048
|
||||||
|
gain 1
|
||||||
|
flip 0
|
||||||
|
xstart 1
|
||||||
|
ystart 1
|
||||||
|
xend 2048
|
||||||
|
yend 2048
|
||||||
|
exposure 0.777
|
||||||
|
temperature -50
|
||||||
|
threshold 800
|
||||||
|
shutteropentime 100
|
||||||
|
shutterclosetime 200
|
||||||
|
} {
|
||||||
|
cm1 setpar $n 0 $v
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,15 +15,36 @@ MakeDrive
|
|||||||
########################################
|
########################################
|
||||||
# INSTRUMENT SPECIFIC CONFIGURATION
|
# INSTRUMENT SPECIFIC CONFIGURATION
|
||||||
|
|
||||||
|
Motor dummy_motor asim [params \
|
||||||
|
asyncqueue mc1\
|
||||||
|
host mc1-dingo\
|
||||||
|
port pmc1-dingo\
|
||||||
|
axis A\
|
||||||
|
units mm\
|
||||||
|
hardlowerlim -500\
|
||||||
|
hardupperlim 500\
|
||||||
|
maxSpeed 1\
|
||||||
|
maxAccel 5\
|
||||||
|
maxDecel 5\
|
||||||
|
stepsPerX [expr 25000.0/5.0]\
|
||||||
|
absEnc 1\
|
||||||
|
absEncHome 0\
|
||||||
|
cntsPerX [expr 8192.0/5.0]]
|
||||||
|
dummy_motor part instrument
|
||||||
|
dummy_motor long_name dummy_motor
|
||||||
|
dummy_motor softlowerlim -500
|
||||||
|
dummy_motor softupperlim 500
|
||||||
|
dummy_motor home 0
|
||||||
|
|
||||||
source $cfPath(hipadaba)/hipadaba_configuration.tcl
|
source $cfPath(hipadaba)/hipadaba_configuration.tcl
|
||||||
|
|
||||||
fileeval $cfPath(source)/source.tcl
|
fileeval $cfPath(source)/source.tcl
|
||||||
fileeval $cfPath(motors)/motor_configuration.tcl
|
#fileeval $cfPath(motors)/motor_configuration.tcl
|
||||||
fileeval $cfPath(motors)/positmotor_configuration.tcl
|
#fileeval $cfPath(motors)/positmotor_configuration.tcl
|
||||||
#fileeval $cfPath(motors)/extraconfig.tcl
|
#fileeval $cfPath(motors)/extraconfig.tcl
|
||||||
fileeval $cfPath(plc)/plc.tcl
|
fileeval $cfPath(plc)/plc.tcl
|
||||||
fileeval $cfPath(counter)/counter.tcl
|
fileeval $cfPath(counter)/counter.tcl
|
||||||
fileeval $cfPath(hmm)/hmm_configuration.tcl
|
#fileeval $cfPath(hmm)/hmm_configuration.tcl
|
||||||
fileeval $cfPath(nexus)/nxscripts.tcl
|
fileeval $cfPath(nexus)/nxscripts.tcl
|
||||||
fileeval $cfPath(scan)/scan.tcl
|
fileeval $cfPath(scan)/scan.tcl
|
||||||
fileeval $cfPath(commands)/commands.tcl
|
fileeval $cfPath(commands)/commands.tcl
|
||||||
@@ -31,8 +52,8 @@ fileeval $cfPath(anticollider)/anticollider.tcl
|
|||||||
|
|
||||||
source gumxml.tcl
|
source gumxml.tcl
|
||||||
|
|
||||||
::utility::mkVar ::anticollider::protect_detector text manager protect_detector false detector true false
|
#::utility::mkVar ::anticollider::protect_detector text manager protect_detector false detector true false
|
||||||
::anticollider::protect_detector "true"
|
#::anticollider::protect_detector "true"
|
||||||
|
|
||||||
# fix all motors
|
# fix all motors
|
||||||
foreach m [sicslist type motor] {
|
foreach m [sicslist type motor] {
|
||||||
@@ -45,6 +66,9 @@ foreach m [sicslist type motor] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
server_init
|
server_init
|
||||||
|
|
||||||
|
clientput "serverport [get_portnum $::serverport]"
|
||||||
|
|
||||||
###########################################
|
###########################################
|
||||||
# WARNING: Do not add any code below server_init, if you do SICS may fail to initialise properly.
|
# WARNING: Do not add any code below server_init, if you do SICS may fail to initialise properly.
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +0,0 @@
|
|||||||
fileeval $cfPath(beamline)/sct_hv.tcl
|
|
||||||
|
|
||||||
::scobj::hv::mkHV {
|
|
||||||
name "hv"
|
|
||||||
IP localhost
|
|
||||||
PORT 55010
|
|
||||||
tuning 1
|
|
||||||
interval 3
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,193 +0,0 @@
|
|||||||
###########################################################################################################################
|
|
||||||
# @file Proptocols between SICS and High Voltage Controller
|
|
||||||
#
|
|
||||||
# This is a driver for SICS to make following communication with the High Voltage Controller
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# 1. SICS uses TCP/IP protocol to interact with the HV component who shall provide an IP address
|
|
||||||
# together with an port number.
|
|
||||||
#
|
|
||||||
# 2. Commands From SICS to HV component,
|
|
||||||
# 1. HV_START hv1=xxx, i1=xxx, hv2=xxx, i2=xxx
|
|
||||||
# :: Responses from HV component back to SICS are either
|
|
||||||
# OK (if the system start correctly), or
|
|
||||||
# Error Message (if the system does not start normally, the error message shall indicate
|
|
||||||
# type of the errors)
|
|
||||||
#
|
|
||||||
# 2. HV_STOP (This will stop/shutdown the HV component totally)
|
|
||||||
#
|
|
||||||
# 3. HV_RESET (This will reset the HV component using the hv/i values specified in the Gumtree client GUI)
|
|
||||||
# :: Responses from HV component back to SICS are either
|
|
||||||
# OK (if the system start correctly), or
|
|
||||||
# Error Message (if the system does not start normally, the error message will indicate type of the errors)
|
|
||||||
#
|
|
||||||
# 4. HV_STATUS (This command will send to HV component automatically and regularly, i.e. every 1 sec)
|
|
||||||
# :: Responses from HV component back to SICS is "hv1=xxx, i1=xxx, hv2=xxx, i2=xxx, system=rampingup;\n",
|
|
||||||
# SICS uses this information to update their values in the SICS system and on the Gumtree client as well.
|
|
||||||
#
|
|
||||||
# 3. HV parameters to be dsiaplyed on the Gumtree GUI are, hv1, i1, hv2, i2, system
|
|
||||||
#
|
|
||||||
# Author: Jing Chen (jgn@ansto.gov.au) July 2011
|
|
||||||
#
|
|
||||||
# The HV Controller can be installed with the following command,
|
|
||||||
# ::scobj::hv::mkHV {
|
|
||||||
# name "hv"
|
|
||||||
# IP localhost
|
|
||||||
# PORT 55010
|
|
||||||
# tuning 1
|
|
||||||
# interval 1
|
|
||||||
#
|
|
||||||
##############################################################################################################################
|
|
||||||
|
|
||||||
|
|
||||||
namespace eval ::scobj::hv {
|
|
||||||
}
|
|
||||||
|
|
||||||
proc ::scobj::hv:setting {par} {
|
|
||||||
|
|
||||||
set newPara [sct target]
|
|
||||||
|
|
||||||
if{[sct oldStatus] != $newPara} {
|
|
||||||
set oldStatus $newPara
|
|
||||||
switch $par {
|
|
||||||
"hv1" {set comm "hv_set hv1 $newPara"}
|
|
||||||
"hv2" {set comm "hv_set hv2 $newPara"}
|
|
||||||
"i1" {set comm "hv_set i1 $newPara"}
|
|
||||||
"i2" {set comm "hv_set i2 $newPara"}
|
|
||||||
default {error "ERROR: illegal parameters, try "hv1","hv2","i1" or "i2""
|
|
||||||
return idle}
|
|
||||||
}
|
|
||||||
|
|
||||||
sct send $comm
|
|
||||||
return checkReply
|
|
||||||
} else {
|
|
||||||
return idle
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
proc ::scobj::hv::checkReplyFunc {basePath} {
|
|
||||||
set replyStr [sct result]
|
|
||||||
#analysis the reply from the HV Device
|
|
||||||
if {[string first "Error" $replyStr] != -1} {
|
|
||||||
broadcast "ERROR command, check again!!"
|
|
||||||
}
|
|
||||||
hset $basePath/msg $replyStr
|
|
||||||
return idle
|
|
||||||
}
|
|
||||||
|
|
||||||
##
|
|
||||||
|
|
||||||
# @brief send "hv_get" command to the HV device and obtain the latest values of those parameters
|
|
||||||
proc ::scobj::hv::getParaFunc {} {
|
|
||||||
set comm "hv_get"
|
|
||||||
sct send $comm
|
|
||||||
return rdParaState
|
|
||||||
}
|
|
||||||
|
|
||||||
##
|
|
||||||
# @brief Read and record the parameters' values from the HV device
|
|
||||||
proc ::scobj::hv::rdParaStateFunc {basePath} {
|
|
||||||
set replyStr [sct result]
|
|
||||||
#broadcast "Reply from hv_get: $replyStr"
|
|
||||||
|
|
||||||
if {[string first "Error" $replyStr] != -1} {
|
|
||||||
broadcast "ERROR: cannot get the current parameters setting from the HV device, check again!"
|
|
||||||
} elseif {$replyStr != [sct oldval]} {
|
|
||||||
sct oldval $replyStr
|
|
||||||
broadcast "oldval = [sct oldval]"
|
|
||||||
set s1 [string trimright $replyStr "\n"]
|
|
||||||
set s2 [split $s1 "=;"]
|
|
||||||
|
|
||||||
array set paraArr $s2
|
|
||||||
|
|
||||||
hset $basePath/hv1 $paraArr(hv1)
|
|
||||||
hset $basePath/i1 $paraArr(i1)
|
|
||||||
hset $basePath/hv2 $paraArr(hv2)
|
|
||||||
hset $basePath/i2 $paraArr(i2)
|
|
||||||
|
|
||||||
#broadcast "HV1:$paraArr(hv1); I1:$paraArr(i1); HV2:$paraArr(hv2); I2:$paraArr(i2)\n"
|
|
||||||
|
|
||||||
sct utime readtime
|
|
||||||
}
|
|
||||||
|
|
||||||
return idle
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
##
|
|
||||||
# @brief Make a HV Controller
|
|
||||||
#
|
|
||||||
# @param argList, {name "hv" IP localhost PORT 65123 tuning 1 interval 1}
|
|
||||||
#
|
|
||||||
# name: name of hv controller object
|
|
||||||
# IP: IP address of RF generator moxa box
|
|
||||||
# PORT: Port number assigned to the generator on the moxa-box
|
|
||||||
# tuning: boolean, set tuning=1 to allow instrument scientists to set the axe positions
|
|
||||||
# interval: polling and ramping interval in seconds.
|
|
||||||
|
|
||||||
proc ::scobj::hv::mkHV {argList} {
|
|
||||||
# Generate parameter array from the argument list
|
|
||||||
foreach {k v} $argList {
|
|
||||||
set KEY [string toupper $k]
|
|
||||||
set pa($KEY) $v
|
|
||||||
}
|
|
||||||
|
|
||||||
MakeSICSObj $pa(NAME) SCT_OBJECT
|
|
||||||
sicslist setatt $pa(NAME) klass instrument
|
|
||||||
sicslist setatt $pa(NAME) long_name $pa(NAME)
|
|
||||||
hsetprop /sics/$pa(NAME) status "IDLE"
|
|
||||||
|
|
||||||
hfactory /sics/$pa(NAME)/hv1 plain user int
|
|
||||||
hfactory /sics/$pa(NAME)/hv2 plain user int
|
|
||||||
hfactory /sics/$pa(NAME)/i1 plain user int
|
|
||||||
hfactory /sics/$pa(NAME)/i2 plain user int
|
|
||||||
hfactory /sics/$pa(NAME)/msg plain user text
|
|
||||||
|
|
||||||
#makesctcontroller sct_hv rfamp $pa(IP):$pa(PORT)
|
|
||||||
makesctcontroller sct_hv std $pa(IP):$pa(PORT)
|
|
||||||
|
|
||||||
hfactory /sics/$pa(NAME)/status plain user text
|
|
||||||
hsetprop /sics/$pa(NAME)/status read ::scobj::hv::getParaFunc
|
|
||||||
hsetprop /sics/$pa(NAME)/status rdParaState ::scobj::hv::rdParaStateFunc /sics/$pa(NAME)
|
|
||||||
hsetprop /sics/$pa(NAME)/status oldval UNKNOWN
|
|
||||||
hset /sics/$pa(NAME)/status idle
|
|
||||||
|
|
||||||
hsetprop /sics/$pa(NAME)/status tuning $pa(TUNING)
|
|
||||||
|
|
||||||
# Initialise properties required for generating the API for GumTree and to save data
|
|
||||||
::scobj::hinitprops $pa(NAME) hv1 i1 hv2 i2 msg
|
|
||||||
|
|
||||||
sct_hv poll /sics/$pa(NAME)/status $pa(INTERVAL)
|
|
||||||
|
|
||||||
if {$pa(TUNING)} {
|
|
||||||
hfactory /sics/$pa(NAME)/set_hv1 plain user int
|
|
||||||
hfactory /sics/$pa(NAME)/set_hv2 plain user int
|
|
||||||
hfactory /sics/$pa(NAME)/set_i1 plain user int
|
|
||||||
hfactory /sics/$pa(NAME)/set_i2 plain user int
|
|
||||||
|
|
||||||
::scobj::hinitprops $pa(NAME) status set_hv1 set_hv2 set_i1 set_i2
|
|
||||||
|
|
||||||
hsetprop /sics/$pa(NAME)/set_hv1 write ::scobj::hv:setting "hv1"
|
|
||||||
hsetprop /sics/$pa(NAME)/set_hv1 checkReply ::scobj::hv::checkReplyFunc /sics/$pa(NAME)
|
|
||||||
hsetprop /sics/$pa(NAME)/set_hv1 oldStatus UNKNOWN
|
|
||||||
|
|
||||||
hsetprop /sics/$pa(NAME)/set_hv2 write ::scobj::hv:setting "hv2"
|
|
||||||
hsetprop /sics/$pa(NAME)/set_hv2 checkReply ::scobj::hv::checkReplyFunc /sics/$pa(NAME)
|
|
||||||
hsetprop /sics/$pa(NAME)/set_hv2 oldStatus UNKNOWN
|
|
||||||
|
|
||||||
hsetprop /sics/$pa(NAME)/set_i1 write ::scobj::hv:setting "i1"
|
|
||||||
hsetprop /sics/$pa(NAME)/set_i1 checkReply ::scobj::hv::checkReplyFunc /sics/$pa(NAME)
|
|
||||||
hsetprop /sics/$pa(NAME)/set_i1 oldStatus UNKNOWN
|
|
||||||
|
|
||||||
hsetprop /sics/$pa(NAME)/set_i2 write ::scobj::hv:setting "i2"
|
|
||||||
hsetprop /sics/$pa(NAME)/set_i2 checkReply ::scobj::hv::checkReplyFunc /sics/$pa(NAME)
|
|
||||||
hsetprop /sics/$pa(NAME)/set_i2 oldStatus UNKNOWN
|
|
||||||
|
|
||||||
sct_hv write /sics/$pa(NAME)/set_hv1 $pa(INTERVAL)
|
|
||||||
sct_hv write /sics/$pa(NAME)/set_hv2 $pa(INTERVAL)
|
|
||||||
sct_hv write /sics/$pa(NAME)/set_i1 $pa(INTERVAL)
|
|
||||||
sct_hv write /sics/$pa(NAME)/set_i2 $pa(INTERVAL)
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -29,7 +29,6 @@ fileeval $cfPath(scan)/scan.tcl
|
|||||||
fileeval $cfPath(commands)/commands.tcl
|
fileeval $cfPath(commands)/commands.tcl
|
||||||
fileeval $cfPath(commands)/monodrive.tcl
|
fileeval $cfPath(commands)/monodrive.tcl
|
||||||
fileeval $cfPath(anticollider)/anticollider.tcl
|
fileeval $cfPath(anticollider)/anticollider.tcl
|
||||||
fileeval $cfPath(beamline)/hv_control.tcl
|
|
||||||
|
|
||||||
source gumxml.tcl
|
source gumxml.tcl
|
||||||
|
|
||||||
|
|||||||
@@ -386,28 +386,48 @@ static int PLC_Action(SConnection *pCon, SicsInterp *pSics,
|
|||||||
if (strcasecmp(argv[1], "hattach") == 0) {
|
if (strcasecmp(argv[1], "hattach") == 0) {
|
||||||
}
|
}
|
||||||
else if (strcasecmp(argv[1], "shutter") == 0) {
|
else if (strcasecmp(argv[1], "shutter") == 0) {
|
||||||
if (strcasecmp(argv[2], "open") == 0) {
|
//if (strcasecmp(argv[2], "open") == 0) {
|
||||||
|
if (strcasecmp(argv[2], "on") == 0) {
|
||||||
/* open shutter */
|
/* open shutter */
|
||||||
AsyncUnitSendTxn(self->unit, "WRITE 1", 4, PutCallback, self, 132);
|
//AsyncUnitSendTxn(self->unit, "set shutter=on", 14, PutCallback, self, 132);
|
||||||
|
AsyncUnitSendTxn(self->unit, "READ", 4, PutCallback, self, 132);
|
||||||
return OKOK;
|
return OKOK;
|
||||||
}
|
}
|
||||||
else if (strcasecmp(argv[2], "close") == 0 ||
|
//else if (strcasecmp(argv[2], "close") == 0 ||
|
||||||
strcasecmp(argv[2], "shut") == 0) {
|
else if (strcasecmp(argv[2], "off") == 0) {
|
||||||
|
// strcasecmp(argv[2], "shut") == 0) {
|
||||||
/* close shutter */
|
/* close shutter */
|
||||||
AsyncUnitSendTxn(self->unit, "WRITE 2", 4, PutCallback, self, 132);
|
AsyncUnitSendTxn(self->unit, "set shutter=off", 15, PutCallback, self, 132);
|
||||||
|
return OKOK;
|
||||||
|
}
|
||||||
|
else if (strcasecmp(argv[2], "auto") == 0) {
|
||||||
|
AsyncUnitSendTxn(self->unit, "set shutter=auto", 16, PutCallback, self, 132);
|
||||||
return OKOK;
|
return OKOK;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
snprintf(line, 132, "%s %s does not understand %s",
|
snprintf(line, 132, "%s %s does not understand %s", argv[0], argv[1], argv[2]);
|
||||||
argv[0], argv[1], argv[2]);
|
|
||||||
SCWrite(pCon, line, eError);
|
SCWrite(pCon, line, eError);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (strcasecmp(argv[1], "focuslight") == 0) {
|
||||||
|
if (strcasecmp(argv[2], "on") == 0) {
|
||||||
|
AsyncUnitSendTxn(self->unit, "set focuslight=on", 17, PutCallback, self, 132);
|
||||||
|
return OKOK;
|
||||||
|
} else if (strcasecmp(argv[2], "off") == 0) {
|
||||||
|
AsyncUnitSendTxn(self->unit, "set focuslight=off", 18, PutCallback, self, 132);
|
||||||
|
return OKOK;
|
||||||
|
} else {
|
||||||
|
snprintf(line, 132, "%s %s does not understand %s", argv[0], argv[1], argv[2]);
|
||||||
|
SCWrite(pCon, line, eError);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
snprintf(line, 132, "%s does not understand %s", argv[0], argv[1]);
|
||||||
|
SCWrite(pCon, line, eError);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
snprintf(line, 132, "%s does not understand %s", argv[0], argv[1]);
|
|
||||||
SCWrite(pCon, line, eError);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static pSafetyPLCController PLC_Create(const char* pName)
|
static pSafetyPLCController PLC_Create(const char* pName)
|
||||||
|
|||||||
@@ -51,6 +51,7 @@
|
|||||||
#include "safetyplc.h"
|
#include "safetyplc.h"
|
||||||
#include "lssmonitor.h"
|
#include "lssmonitor.h"
|
||||||
#include "beamstopaction.h"
|
#include "beamstopaction.h"
|
||||||
|
#include "cameradriver.h"
|
||||||
|
|
||||||
/*@observer@*//*@null@*/ pCounterDriver CreateMonCounter(/*@observer@*/SConnection *pCon, /*@observer@*/char *name, char *params);
|
/*@observer@*//*@null@*/ pCounterDriver CreateMonCounter(/*@observer@*/SConnection *pCon, /*@observer@*/char *name, char *params);
|
||||||
|
|
||||||
@@ -68,6 +69,7 @@ extern void AddTCPMBProtocol ();
|
|||||||
extern void AddLFGenProtocol();
|
extern void AddLFGenProtocol();
|
||||||
extern int ANSTO_MakeHistMemory(SConnection *pCon, SicsInterp *pSics, void *pData, int argc, char *argv[]);
|
extern int ANSTO_MakeHistMemory(SConnection *pCon, SicsInterp *pSics, void *pData, int argc, char *argv[]);
|
||||||
extern int testLogCmd(SConnection *pCon, SicsInterp *pSics, void *pData, int argc, char *argv[]);
|
extern int testLogCmd(SConnection *pCon, SicsInterp *pSics, void *pData, int argc, char *argv[]);
|
||||||
|
extern pCounterDriver CreateCam(SConnection *pCon, char *name, char *asynq);
|
||||||
|
|
||||||
int SICS_Site(SConnection *pCon, SicsInterp *pSics, void *pData, int argc, char *argv[])
|
int SICS_Site(SConnection *pCon, SicsInterp *pSics, void *pData, int argc, char *argv[])
|
||||||
{
|
{
|
||||||
@@ -203,6 +205,7 @@ static void AddCommands(SicsInterp *pInter)
|
|||||||
NHQ200InitProtocol(pInter);
|
NHQ200InitProtocol(pInter);
|
||||||
ORHVPSInitProtocol(pInter);
|
ORHVPSInitProtocol(pInter);
|
||||||
LS340InitProtocol(pInter);
|
LS340InitProtocol(pInter);
|
||||||
|
CameraInitProtocol(pInter);
|
||||||
AddCommand(pInter,"InstallProtocolHandler", InstallProtocol,NULL,NULL);
|
AddCommand(pInter,"InstallProtocolHandler", InstallProtocol,NULL,NULL);
|
||||||
AddCommand(pInter,"hostnam",hostNamCmd,NULL,NULL);
|
AddCommand(pInter,"hostnam",hostNamCmd,NULL,NULL);
|
||||||
AddCommand(pInter,"portnum",portNumCmd,NULL,NULL);
|
AddCommand(pInter,"portnum",portNumCmd,NULL,NULL);
|
||||||
@@ -294,6 +297,8 @@ static pCounterDriver CreateCounterDriverAnsto(SConnection *pCon,
|
|||||||
strtolower(argv[2]);
|
strtolower(argv[2]);
|
||||||
if(strcmp(argv[2],"anstomonitor") == 0) {
|
if(strcmp(argv[2],"anstomonitor") == 0) {
|
||||||
pDriver = CreateMonCounter(pCon, argv[1], argv[3]);
|
pDriver = CreateMonCounter(pCon, argv[1], argv[3]);
|
||||||
|
} else if (strcmp(argv[2], "anstocamera") == 0) {
|
||||||
|
pDriver = CreateCam(pCon, argv[1], argv[3]);
|
||||||
}
|
}
|
||||||
if(!pDriver){
|
if(!pDriver){
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|||||||
Reference in New Issue
Block a user