Initial commit
r2845 | ffr | 2009-12-11 13:09:56 +1100 (Fri, 11 Dec 2009) | 2 lines
This commit is contained in:
committed by
Douglas Clowes
parent
3abd3effa2
commit
35d1930d1b
193
site_ansto/hardsup/sct_ansrfamp.c
Normal file
193
site_ansto/hardsup/sct_ansrfamp.c
Normal file
@@ -0,0 +1,193 @@
|
||||
/** @file Protocol handler for Aviatronic 35V 7A AC RF amplifier.
|
||||
* Ferdi Franceschini July 2009
|
||||
*
|
||||
* Create with
|
||||
* makesctcontroller sct_rfamp ansrfamp IP:PORT
|
||||
*
|
||||
* TODO Handle control commands
|
||||
*/
|
||||
#include <errno.h>
|
||||
#include <ascon.h>
|
||||
#include <ascon.i>
|
||||
#include <dynstring.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define STARTSIG 2
|
||||
#define ENDSIG 3
|
||||
#define ERRMSGLEN 127
|
||||
#define MAXRETRY 3
|
||||
|
||||
/** @brief Enclose command with start and send signals
|
||||
* before sending
|
||||
*/
|
||||
int AnsfrWriteStart(Ascon *a) {
|
||||
char startSignal[2] = {STARTSIG,'\0'}, endSignal = ENDSIG;
|
||||
|
||||
DynStringInsert(a->wrBuffer, startSignal, 0);
|
||||
DynStringConcatChar(a->wrBuffer, endSignal);
|
||||
a->state = AsconWriting;
|
||||
a->wrPos = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int AnsfrReading(Ascon *a) {
|
||||
int ret, i;
|
||||
static int retries = MAXRETRY;
|
||||
unsigned char reply[11];
|
||||
char chr, errmsg[ERRMSGLEN];
|
||||
char startSignal = STARTSIG, endSignal = ENDSIG;
|
||||
unsigned char OutputOn, C1on, C2on, C3on, OH, CV, CC;
|
||||
|
||||
OutputOn = 1 << 7;
|
||||
C1on = 1 << 6;
|
||||
C2on = 1 << 5;
|
||||
C3on = 1 << 4;
|
||||
|
||||
OH = 1 << 7;
|
||||
CV = 1 << 6;
|
||||
CC = 1 << 5;
|
||||
|
||||
|
||||
ret = AsconReadChar(a->fd, &chr);
|
||||
if (ret > 0 && chr != startSignal && retries > 0) {
|
||||
AsconReadGarbage(a->fd);
|
||||
a->state = AsconWriting;
|
||||
a->wrPos = 0;
|
||||
retries--;
|
||||
return 0;
|
||||
} else if (retries <= 0) {
|
||||
a->state = AsconReadDone;
|
||||
AsconError(a, "Failed to get start signal", 0);
|
||||
retries = MAXRETRY;
|
||||
return 0;
|
||||
}
|
||||
ret = AsconReadChar(a->fd, &chr);
|
||||
retries = MAXRETRY;
|
||||
for (i=0; ret > 0; i++) {
|
||||
a->start = DoubleTime();
|
||||
|
||||
if (chr == endSignal) {
|
||||
a->state = AsconReadDone;
|
||||
break;
|
||||
} else {
|
||||
if (i >= 11) {
|
||||
a->state = AsconReadDone;
|
||||
AsconError(a, "Corrupt reply", ENOMEM);
|
||||
return 1;
|
||||
}
|
||||
reply[i] = chr;
|
||||
ret = AsconReadChar(a->fd, &chr);
|
||||
}
|
||||
}
|
||||
|
||||
if (a->state != AsconReadDone) {
|
||||
if (a->timeout > 0) {
|
||||
if (DoubleTime() - a->start > a->timeout) {
|
||||
AsconError(a, "read timeout", 0);
|
||||
a->state = AsconTimeout;
|
||||
return 1;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
DynStringConcatChar(a->rdBuffer, reply[0]);
|
||||
DynStringConcatChar(a->rdBuffer, ' ');
|
||||
DynStringConcatChar(a->rdBuffer, reply[1]);
|
||||
DynStringConcatChar(a->rdBuffer, ' ');
|
||||
DynStringConcatChar(a->rdBuffer, reply[2]);
|
||||
DynStringConcatChar(a->rdBuffer, reply[3]);
|
||||
DynStringConcatChar(a->rdBuffer, ' ');
|
||||
DynStringConcatChar(a->rdBuffer, reply[4]);
|
||||
DynStringConcatChar(a->rdBuffer, reply[5]);
|
||||
DynStringConcatChar(a->rdBuffer, reply[6]);
|
||||
DynStringConcatChar(a->rdBuffer, ' ');
|
||||
DynStringConcatChar(a->rdBuffer, reply[7]);
|
||||
DynStringConcatChar(a->rdBuffer, reply[8]);
|
||||
DynStringConcatChar(a->rdBuffer, ' ');
|
||||
if (C3on & reply[9]) {
|
||||
DynStringConcatChar(a->rdBuffer, '1');
|
||||
DynStringConcatChar(a->rdBuffer, ' ');
|
||||
} else {
|
||||
DynStringConcatChar(a->rdBuffer, '0');
|
||||
DynStringConcatChar(a->rdBuffer, ' ');
|
||||
}
|
||||
if (C2on & reply[9]) {
|
||||
DynStringConcatChar(a->rdBuffer, '1');
|
||||
DynStringConcatChar(a->rdBuffer, ' ');
|
||||
} else {
|
||||
DynStringConcatChar(a->rdBuffer, '0');
|
||||
DynStringConcatChar(a->rdBuffer, ' ');
|
||||
}
|
||||
if (C1on & reply[9]) {
|
||||
DynStringConcatChar(a->rdBuffer, '1');
|
||||
DynStringConcatChar(a->rdBuffer, ' ');
|
||||
} else {
|
||||
DynStringConcatChar(a->rdBuffer, '0');
|
||||
DynStringConcatChar(a->rdBuffer, ' ');
|
||||
}
|
||||
if (OutputOn & reply[9]) {
|
||||
DynStringConcatChar(a->rdBuffer, '1');
|
||||
DynStringConcatChar(a->rdBuffer, ' ');
|
||||
} else {
|
||||
DynStringConcatChar(a->rdBuffer, '0');
|
||||
DynStringConcatChar(a->rdBuffer, ' ');
|
||||
}
|
||||
if (CC & reply[10]) {
|
||||
DynStringConcatChar(a->rdBuffer, '1');
|
||||
DynStringConcatChar(a->rdBuffer, ' ');
|
||||
} else {
|
||||
DynStringConcatChar(a->rdBuffer, '0');
|
||||
DynStringConcatChar(a->rdBuffer, ' ');
|
||||
}
|
||||
if (CV & reply[10]) {
|
||||
DynStringConcatChar(a->rdBuffer, '1');
|
||||
DynStringConcatChar(a->rdBuffer, ' ');
|
||||
} else {
|
||||
DynStringConcatChar(a->rdBuffer, '0');
|
||||
DynStringConcatChar(a->rdBuffer, ' ');
|
||||
}
|
||||
if (OH & reply[10]) {
|
||||
DynStringConcatChar(a->rdBuffer, '1');
|
||||
DynStringConcatChar(a->rdBuffer, ' ');
|
||||
} else {
|
||||
DynStringConcatChar(a->rdBuffer, '0');
|
||||
DynStringConcatChar(a->rdBuffer, ' ');
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** brief ANSFR RF amplifier protocol handler.
|
||||
* This handler formats commands (ie adds cr line terminator) and
|
||||
* sorts replies into standard responses of
|
||||
* <value>
|
||||
* OK
|
||||
* ASCERR:...
|
||||
*/
|
||||
int AnsfrProtHandler(Ascon *a) {
|
||||
int ret;
|
||||
|
||||
switch(a->state){
|
||||
case AsconWriteStart:
|
||||
ret = AnsfrWriteStart(a);
|
||||
return ret;
|
||||
break;
|
||||
case AsconReading:
|
||||
ret = AnsfrReading(a);
|
||||
return ret;
|
||||
break;
|
||||
default:
|
||||
return AsconStdHandler(a);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void AddAnsfrProtocol(){
|
||||
AsconProtocol *prot = NULL;
|
||||
|
||||
prot = calloc(sizeof(AsconProtocol), 1);
|
||||
prot->name = strdup("ansrfamp");
|
||||
prot->init = AsconStdInit;
|
||||
prot->handler = AnsfrProtHandler;
|
||||
AsconInsertProtocol(prot);
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
# $Revision: 1.2 $
|
||||
# $Date: 2009-12-11 02:08:43 $
|
||||
# Author: Ferdi Franceschini (ffr@ansto.gov.au)
|
||||
# Last revision by: $Author: ffr $
|
||||
|
||||
namespace eval ::environment::temperature { }
|
||||
|
||||
# @brief Make a simulated temperature controller object.
|
||||
#
|
||||
# @param temp_sobj, name for temperature controller object.
|
||||
proc ::environment::temperature::mkwest400sim {temp_sobj} {
|
||||
EvFactory new $temp_sobj sim
|
||||
sicslist setatt $temp_sobj numsensors 1
|
||||
sicslist setatt $temp_sobj controlsensor sensora
|
||||
sicslist setatt $temp_sobj sensorlist sensora
|
||||
sicslist setatt $temp_sobj units kelvin
|
||||
sicslist setatt $temp_sobj klass @none
|
||||
}
|
||||
|
||||
#WEST4100 tempcontroller creation
|
||||
proc ::environment::temperature::mkwest400 {temp_sobj IP } {
|
||||
MakeRS232Controller sertemp $IP 502
|
||||
sertemp timeout 300
|
||||
sertemp sendterminator 0x0
|
||||
sertemp replyterminator 0x0
|
||||
EvFactory new tc1 west4100 sertemp 1 2
|
||||
|
||||
sicslist setatt tc1 units kelvin
|
||||
sicslist setatt tc1 klass @none
|
||||
}
|
||||
|
||||
# @brief Adds a west400 temperature controller object.
|
||||
#
|
||||
# This must be called when the instrument configuration is loaded and before\n
|
||||
# the buildHDB function is called. Currently there is no way to add and remove\n
|
||||
# environment controllers and their hdb paths at runtime.
|
||||
proc ::environment::temperature::add_west400 {IP} {
|
||||
set sim_mode [SplitReply [environment_simulation]]
|
||||
if {$sim_mode == "true"} {
|
||||
::environment::temperature::mkwest400sim tc1
|
||||
} else {
|
||||
::environment::temperature::mkwest400 tc1 $IP
|
||||
tc1 Upperlimit 1500
|
||||
tc1 Lowerlimit 0
|
||||
tc1 tolerance 10
|
||||
}
|
||||
|
||||
sicslist setatt tc1 environment_name tempone
|
||||
sicslist setatt tc1 long_name control_sensor_reading
|
||||
::environment::mkenvinfo tc1 {ramprate {priv user} powerlimit {priv manager} }
|
||||
#::environment::mkenvinfo tc1 {heateron {priv user} range {priv manager} }
|
||||
|
||||
}
|
||||
@@ -0,0 +1,193 @@
|
||||
# $Revision: 1.2 $
|
||||
# $Date: 2009-12-11 02:09:56 $
|
||||
# Author: Ferdi Franceschini (ffr@ansto.gov.au)
|
||||
# Last revision by: $Author: ffr $
|
||||
|
||||
##
|
||||
# @file Platypus Beam Attenuator control and status.
|
||||
namespace eval ::scobj::galil {
|
||||
variable sim_mode
|
||||
variable bat_state
|
||||
array set bat_state [list OUT -1 IN 0 OSC 1]
|
||||
|
||||
set NS ::scobj::galil
|
||||
set batObjName scbat
|
||||
set batpath /sics/$batObjName
|
||||
|
||||
set sim_mode [SplitReply [motor_simulation]]
|
||||
# set sim_mode "false"
|
||||
|
||||
if {$sim_mode == "false"} {
|
||||
makesctcontroller sct_mc1 galil mc1-platypus:1034
|
||||
}
|
||||
MakeSICSObj $batObjName SCT_OBJECT
|
||||
|
||||
##
|
||||
# @brief Send a command which returns a value
|
||||
# @param nextState, State which handles the reply
|
||||
# @param cmd, Galil command
|
||||
# @return The next state
|
||||
proc getValue {nextState cmd} {
|
||||
sct send $cmd
|
||||
return $nextState
|
||||
}
|
||||
|
||||
##
|
||||
# @brief Check that a command has been acknowledged
|
||||
proc ackCmd {} {
|
||||
set reply [sct result]
|
||||
switch -glob -- $reply {
|
||||
"ASCERR:*" {
|
||||
sct geterror $reply
|
||||
}
|
||||
"OK" {
|
||||
return idle
|
||||
}
|
||||
default {
|
||||
sct geterror "Unhandled reply: $reply"
|
||||
}
|
||||
}
|
||||
return idle
|
||||
}
|
||||
|
||||
##
|
||||
# @brief Simply reports a reply to the user by setting the hipadaba node
|
||||
# which this proc is associated with.
|
||||
proc rdValue {} {
|
||||
set data [sct result]
|
||||
switch -glob -- $data {
|
||||
"ASCERR:*" {
|
||||
sct geterror $data
|
||||
}
|
||||
default {
|
||||
if {$data != [sct oldval]} {
|
||||
sct oldval $data
|
||||
sct update $data
|
||||
sct utime readtime
|
||||
}
|
||||
}
|
||||
}
|
||||
return idle
|
||||
}
|
||||
|
||||
##
|
||||
# @brief Translates BAT state to English and reports it via the hdb node.
|
||||
proc rdBatAction {} {
|
||||
variable bat_state
|
||||
set oscd [expr int([sct result])]
|
||||
switch -- $oscd [subst {
|
||||
$bat_state(OUT) {set msg "out"}
|
||||
$bat_state(IN) {set msg "in"}
|
||||
$bat_state(OSC) {set msg "osc"}
|
||||
default {
|
||||
sct geterror "Illegal value $oscd for beam attenuator state"
|
||||
return idle
|
||||
}
|
||||
} ]
|
||||
if {$msg != [sct oldval]} {
|
||||
sct oldval $msg
|
||||
sct update $msg
|
||||
sct utime readtime
|
||||
}
|
||||
return idle
|
||||
}
|
||||
|
||||
##
|
||||
# @brief Sets the BAT to the state set in the target property
|
||||
# of the hdb node.
|
||||
# @param nextState, The script context state which handles the galil reply.
|
||||
proc setBatAction {nextState} {
|
||||
variable bat_state
|
||||
set par [sct target]
|
||||
switch $par {
|
||||
"out" {sct send "OSCD=$bat_state(OUT)"}
|
||||
"in" {sct send "OSCD=$bat_state(IN)"}
|
||||
"osc" {sct send "OSCD=$bat_state(OSC)"}
|
||||
default {
|
||||
error "ERROR: illegal action $par for beam attenuator, try 'in', 'out' or 'osc'"
|
||||
}
|
||||
}
|
||||
return $nextState
|
||||
}
|
||||
|
||||
##
|
||||
# @brief Send a status request to the Galil
|
||||
#
|
||||
# NOTE: If you change the status command you must also
|
||||
# update the rdStatus procedure
|
||||
proc getStatus {} {
|
||||
sct send "MG OSCD,POS,_TPA,DBAND"
|
||||
return rdStatus
|
||||
}
|
||||
|
||||
##
|
||||
# @brief Parse the status reply from the Galil and set
|
||||
# the abstract status.
|
||||
proc rdStatus {} {
|
||||
variable bat_state
|
||||
|
||||
set data [sct result]
|
||||
switch -glob -- $data {
|
||||
"ASCERR:*" {
|
||||
sct geterror $data
|
||||
}
|
||||
default {
|
||||
if {$data != [sct oldval]} {
|
||||
sct oldval $data
|
||||
foreach {OSCD POS TPA DBAND} $data {}
|
||||
if [expr $OSCD == $bat_state(OSC)] {
|
||||
set newStatus "busy"
|
||||
} elseif [expr abs($TPA - $POS) < $DBAND] {
|
||||
set newStatus "idle"
|
||||
} else {
|
||||
set newStatus "busy"
|
||||
}
|
||||
if {[sct oldStatus] != $newStatus} {
|
||||
sct oldStatus $newStatus
|
||||
sct update $newStatus
|
||||
sct utime readtime
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return idle
|
||||
}
|
||||
|
||||
# Read and set the BAT state, ie in, out, oscillating
|
||||
hfactory $batpath/action plain user text
|
||||
hsetprop $batpath/action read ${NS}::getValue rdBatAction "MG OSCD"
|
||||
hsetprop $batpath/action rdBatAction ${NS}::rdBatAction
|
||||
hsetprop $batpath/action write ${NS}::setBatAction ${NS}::ackCmd
|
||||
hsetprop $batpath/action ackCmd ${NS}::ackCmd
|
||||
hsetprop $batpath/action oldval UNKNOWN
|
||||
|
||||
# Report the abstract status to GumTree
|
||||
hfactory $batpath/status plain user text
|
||||
hsetprop $batpath/status read ${NS}::getStatus
|
||||
hsetprop $batpath/status rdStatus ${NS}::rdStatus
|
||||
hsetprop $batpath/status values busy,idle
|
||||
hsetprop $batpath/status oldval UNKNOWN
|
||||
hsetprop $batpath/status oldStatus UNKNOWN
|
||||
hset $batpath/status idle
|
||||
|
||||
# Report the current position in encoder counts
|
||||
# Useful as an activity monitor and troubleshooting.
|
||||
hfactory $batpath/pos plain user int
|
||||
hsetprop $batpath/pos read ${NS}::getValue rdValue "TPA"
|
||||
hsetprop $batpath/pos rdValue ${NS}::rdValue
|
||||
hsetprop $batpath/pos oldval UNKNOWN
|
||||
|
||||
if {$sim_mode == "false"} {
|
||||
sct_mc1 poll $batpath/pos
|
||||
sct_mc1 poll $batpath/action
|
||||
sct_mc1 poll $batpath/status
|
||||
sct_mc1 write $batpath/action
|
||||
}
|
||||
|
||||
# Set hipadaba properties for GumTree interface
|
||||
# and NeXus data file.
|
||||
hsetprop $batpath klass NXaperture
|
||||
::scobj::hinitprops $batObjName
|
||||
hsetprop $batpath/action mutable "false"
|
||||
::scobj::hinitprops $batObjName action
|
||||
}
|
||||
Reference in New Issue
Block a user