Initial commit

r2845 | ffr | 2009-12-11 13:09:56 +1100 (Fri, 11 Dec 2009) | 2 lines
This commit is contained in:
Ferdi Franceschini
2009-12-11 13:09:56 +11:00
committed by Douglas Clowes
parent 3abd3effa2
commit 35d1930d1b
3 changed files with 439 additions and 0 deletions

View 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);
}

View File

@@ -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} }
}

View File

@@ -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
}