# Define procs in ::scobj::xxx namespace # MakeSICSObj $obj SCT_ # The MakeSICSObj cmd adds a /sics/$obj node. NOTE the /sics node is not browsable. ## # /*-------------------------------------------------------------------------- # LF Amplifier/Generator Model AG 1010 Driver # # @file: This file contains the implementation of a driver for the AG 1010 # LF Amplifier/Generator # # @author: Jing Chen, ANSTO, 2012-06-26 # @brief: SICS driver for LF AG 1010 LF Amplifier/Generator # # ----------------------------------------------------------------------------*/ # Default AG1010 LF Amplifier/Generator Controller parameters namespace eval ::scobj::ag1010 { variable CtrlSetLIMITS [format %02x 2] variable CtrlSetPAGC [format %02x 3] variable CtrlSetPMGC [format %02x 4] variable CtrlSetFREQ [format %02x 5] variable CtrlSetSKEY [format %02x 7] variable CtrlSetBurstPar [format %02x 8] variable CtrlSetSweepPar [format %02x 9] variable CtrlGetLIMITS [format %02x 17] variable CtrlGetPAGC [format %02x 19] variable CtrlGetPMGC [format %02x 20] variable CtrlGetFREQ [format %02x 21] variable CtrlGetSKEY [format %02x 23] variable CtrlGetBurstPar [format %02x 24] variable CtrlGetSweepPar [format %02x 25] variable CtrlGetSVER [format %02x 29] variable CtrlGetMEAS [format %02x 30] variable CtrlGetSTA [format %02x 31] variable ForPowerLimit 10040 variable RefPowerLimit 1630 variable FreqUpLimit 2000000 variable FreqDownLimit 0.02 namespace export par } ############# Reading polled nodes ####################################################### ## # @brief Sends a query command to the device via a read node formalism # @param tc_root The path to the root of the node # @param nextState The next function to call after this one (typically 'rdValue' # to read the response from the device) # @param rdPara data to be sent to the device # @return nextState The next function to call after this one (typically 'rdValue') proc ::scobj::ag1010::getValue {tc_root nextState rdPara} { if {[ catch { set HEAD 0x96 set LEN [lindex $rdPara 0] set CTRL [lindex $rdPara 1] set DATA 0 set CRC 0 if {$LEN < 2} { return -code error "Error in LF AG1010 Setting: wrong data length provided." } elseif {$LEN > 2} { set cmd [format %02x%02x%02x%02x%02x $HEAD $LEN $CTRL $DATA $CRC] } else { set cmd [format %02x%02x%02x%02x $HEAD $LEN $CTRL $CRC] } sct send "$cmd" } message ]} { return -code error "Error in LF AG1010 Setting: $message." } return $nextState } ################## Writing to nodes ######################################################## ## # @brief Writes a new value to a node and sends the corresponding command to the device. # @param tc_root string variable holding the path to the object's base node in sics # @param nextState the next function to call after this one # @param wrPara indicates which control loop or which input channel the command belongs to # @return nextState Is typically noResponse as the device does not acknowledge the write request proc ::scobj::ag1010::setValue {tc_root nextState rdPara wrPara} { # tc_root and idx are not being used - however, don't remove so we can use the # same calling mask as for setPoint() or other $wrFunc variable ForPowerLimit variable RefPowerLimit variable FreqUpLimit variable FreqDownLimit set ns /sics/ag1010 #set ns [sct] if {[ catch { set HEAD 96 set LEN [lindex $rdPara 0] set CTRL [lindex $rdPara 1] set CRC 0 set newPara [string trim [sct target] " "] switch -exact $wrPara { "FPL" { if {$newPara > $ForPowerLimit || $newPara < 0} { broadcast "Error: The Limit for the Forward Power is 0~$ForPowerLimit dW" return idle } else { set RPL [hval $ns/limits/ReversePower] set data [format %04x%04x%04x%04x $newPara $RPL 0 0] } } "RPL" { if {$newPara > $RefPowerLimit || $newPara < 0} { broadcast "Error: The Limit for the Reverse Power is 0~$RefPowerLimit dW" return idle } else { set FPL [hval $ns/limits/ForwardPower] set data [format %04x%04x%04x%04x $FPL $newPara 0 0] } } "PAGC" { set data [format %04x $newPara] } "PMGC" { set data [format %04x $newPara] } "FREQ" { if {$newPara<$FreqDownLimit || $newPara>$FreqUpLimit} { broadcast "Error: Freqence shall be set between $FreqDownLimit Hz and $FreqUpLimit Hz" return idle } else { set Freq [expr $newPara / 1000] set FreqHz [expr $newPara % 1000] set data [format %04x%04x $Freq $FreqHz] } } "SoftOn" { if {$newPara > 1 || $newPara < 0} { return -code error "Error in setValue: only allowed input values for SoftKey are {0,1}." } else { if {$newPara == 1} { set data 0x80 } else { set data 0 } } if {[string match -nocase "on" [hval $ns/SKEY/Key1]]} { set data [expr $data | 0x08] } if {[string match -nocase "on" [hval $ns/SKEY/Key0]]} { set data [expr $data | 0x04] } if {[string match -nocase "on" [hval $ns/SKEY/Key2]]} { set data [expr $data | 0x02] } if {[string match -nocase "on" [hval $ns/SKEY/Key3]]} { set data [expr $data | 0x01] } set data [format %02x $data] } "Key1" { if {$newPara > 1 || $newPara < 0} { return -code error "Error in setValue: only allowed input values for Key1 are {0,1}." } else { if {$newPara == 1} { set data 0x08 } else { set data 0 } } if {[string match -nocase "Host takes" [hval $ns/SKEY/SoftOn]]} { set data [expr $data | 0x80] } if {[string match -nocase "on" [hval $ns/SKEY/Key0]]} { set data [expr $data | 0x04] } if {[string match -nocase "on" [hval $ns/SKEY/Key2]]} { set data [expr $data | 0x02] } if {[string match -nocase "on" [hval $ns/SKEY/Key3]]} { set data [expr $data | 0x01] } set data [format %02x $data] } "Key0" { if {$newPara > 1 || $newPara < 0} { return -code error "Error in setValue: only allowed input values for Key0 are {0,1}." } else { if {$newPara == 1} { set data 0x04 } else { set data 0 } } if {[string match -nocase "Host takes" [hval $ns/SKEY/SoftOn]]} { set data [expr $data | 0x80] } if {[string match -nocase "on" [hval $ns/SKEY/Key1]]} { set data [expr $data | 0x08] } if {[string match -nocase "on" [hval $ns/SKEY/Key2]]} { set data [expr $data | 0x02] } if {[string match -nocase "on" [hval $ns/SKEY/Key3]]} { set data [expr $data | 0x01] } set data [format %02x $data] } "Key2" { if {$newPara > 1 || $newPara < 0} { return -code error "Error in setValue: only allowed input values for Key2 are {0,1}." } else { if {$newPara == 1} { set data 0x02 } else { set data 0 } } if {[string match -nocase "Host takes" [hval $ns/SKEY/SoftOn]]} { set data [expr $data | 0x80] } if {[string match -nocase "on" [hval $ns/SKEY/Key1]]} { set data [expr $data | 0x08] } if {[string match -nocase "on" [hval $ns/SKEY/Key0]]} { set data [expr $data | 0x04] } if {[string match -nocase "on" [hval $ns/SKEY/Key3]]} { set data [expr $data | 0x01] } set data [format %02x $data] } "Key3" { if {$newPara > 1 || $newPara < 0} { return -code error "Error in setValue: only allowed input values for Key3 are {0,1}." } else { if {$newPara == 1} { set data 0x01 } else { set data 0 } } if {[string match -nocase "Host takes" [hval $ns/SKEY/SoftOn]]} { set data [expr $data | 0x80] } if {[string match -nocase "on" [hval $ns/SKEY/Key1]]} { set data [expr $data | 0x08] } if {[string match -nocase "on" [hval $ns/SKEY/Key0]]} { set data [expr $data | 0x04] } if {[string match -nocase "on" [hval $ns/SKEY/Key2]]} { set data [expr $data | 0x02] } set data [format %02x $data] } "BurstMode" { if {$newPara<0 || $newPara>3} { return -code error "Error in setValue: only allowed input values for BurstMode are {0,1,2,3}" } else { set BurstMode $newPara } set BRepTime [hval $ns/BurstPar/BRepTime] set TimeOfPower [hval $ns/BurstPar/TimeOfPower] set data [format %02x%04x%04x $BurstMode $BRepTime $TimeOfPower] } "BRepTime" { #set BurstMode [hval $ns/BurstPar/BurstMode] #if {[string match -nocase $BurstMode "Mode OFF"]} { # set BurstMode 0 #} elseif {[string match -nocase $BurstMode "Internal Burst"} { # set BurstMode 1 #} elseif {[string match -nocase "Without Changing" $BurstMode]} { # set BurstMode 2 #} elseif {[string match "External Burst" $BurstMode]} { # set BurstMode 3 #} else { # return -code error "Error in setValue: reading invaild BurstMode value." #} # set mode to Changing Burst Parameters without Chanigng Burst Mode -- 2 set BurstMode 2 set TimeOfPower [hval $ns/BurstPar/TimeOfPower] set data [format %02x%04x%04x $BurstMode $newPara $TimeOfPower] } "BTofP" { set BurstMode 2 set BRepTime [hval $ns/BurstPar/BRepTime] set data [format %02x%04x%04x $BurstMode $BRepTime $newPara] } "SweepMode" { if {$newPara<0 || $newPara>2} { return -code error "Error in setValue: only allowed input values for SweepMode are {0,1,2}" } else { set SweepMode $newPara } set SStr [expr [hval $ns/SweepPar/StartFreq] / 1000] set SStrHz [expr [hval $ns/SweepPar/StartFreq] % 1000] set SStp [expr [hval $ns/SweepPar/StepFreq] / 1000] set SStpHz [expr [hval $ns/SweepPar/StepFreq] % 1000] set SCyc [hval $ns/SweepPar/SCyc] set data [format %02x%02x%02x%02x%02x%02x $SweepMode $SStr $SStp $SCyc $SStrHz $SStpHz] } "SStrF" { #set SweepMode [hval $ns/SweepPar/SweepMode] #if {[string equal $SweepMode "OFF"]} { # set SweepMode 0 #} elseif {[string equal $SweepMode "ON"} { # set SweepMode 1 #} elseif {[string match "Without Changing" $SweepMode]} { # set SweepMode 2 #} else { # return -code error "Error in setValue: reading invaild SweepMode value." #} # set mode to "Changing parameters without changing mode - 2 set SweepMode 2 set SStr [expr $newPara / 1000] set SStrHz [expr $newPara % 1000] set SStp [expr [hval $ns/SweepPar/StepFreq] / 1000] set SStpHz [expr [hval $ns/SweepPar/StepFreq] % 1000] set SCyc [hval $ns/SweepPar/SCyc] set data [format %02x%02x%02x%02x%02x%02x $SweepMode $SStr $SStp $SCyc $SStrHz $SStpHz] } "SSteF" { set SweepMode 2 set SStr [expr [hval $ns/SweepPar/StartFreq] / 1000] set SStrHz [expr [hval $ns/SweepPar/StartFreq] % 1000] set SStp [expr $newPara / 1000] set SStpHz [expr $newPara % 1000] set SCyc [hval $ns/SweepPar/SCyc] set data [format %02x%02x%02x%02x%02x%02x $SweepMode $SStr $SStp $SCyc $SStrHz $SStpHz] } "SSCyc" { set SweepMode 2 set SStr [expr [hval $ns/SweepPar/StartFreq] / 1000] set SStrHz [expr [hval $ns/SweepPar/StartFreq] % 1000] set SStp [expr [hval $ns/SweepPar/StepFreq] / 1000] set SStpHz [expr [hval $ns/SweepPar/StepFreq] % 1000] set SCyc $newPara set data [format %02x%02x%02x%02x%02x%02x $SweepMode $SStr $SStp $SCyc $SStrHz $SStpHz] } default { return -code error "in setValue: Wrong setting field." } } set cmd [format %02s%02x%02x%s%02x $HEAD $LEN $CTRL $data $CRC] sct send "$cmd" } message ]} { return -code error "Error in setValue: $message. While sending command" } return $nextState } ## # @brief Reads the value of a read-node typically following a query command sent to the device # rdValue is the default nextState for getValue() and setValue() # @param idx indicates which control loop or which input channel the command belongs to # @return idle Always returns system state idle - command sequence completed. proc ::scobj::ag1010::rdValue {} { ##################################### # CTRL Codes # CtrlShowLIMITS 2 # CtrlShowPAGC 3 # CtrlShowPMGC 4 # CtrlShowFREQ 5 # CtrlShowSKEY 7 # CtrlShowBurstPar 8 # CtrlShowSweepPar 9 # CtrlShowSVER 13 # CtrlShowMEAS 14 # CtrlShowSTA 15 # # CtrlREJ 42 ##################################### set ns /sics/ag1010 #set ns [sct] if {[ catch { set data [string trim [sct result] " "] hset $ns/responseMsg "$data" #broadcast "rdValue : $data" if {[string first "failed" $data] != -1} { broadcast "Error in LF AG1010 Response: $data" return -code error "$data" } elseif {[string first "read timeout" $data] != -1} { broadcast "Error in LF AG1010 Response: $data" return -code error "$data" } elseif {[string length $data] < 1} { broadcast "Error in LF AG1010 Response: no message returned from device" return -code error "Error in LF AG1010 Response: no message returned from device" } set ctrlCode [format %d 0x[string range $data 4 5]] switch -glob $ctrlCode { 42 { return -code error "Error in rdValue()" } 2 { set FPLH [string range $data 6 7] set FPLL [string range $data 8 9] set RPLH [string range $data 10 11] set RPLL [string range $data 12 13] hset $ns/limits/ForwardPower [format %d [expr 0x$FPLH$FPLL]] hset $ns/limits/ReversePower [format %d [expr 0x$RPLH$RPLL]] } 3 { set AGCPoH [string range $data 6 7] set AGCPoL [string range $data 8 9] hset $ns/AGC/PAGC [format %d [expr 0x$AGCPoH$AGCPoL]] } 4 { set MGCPoH [string range $data 6 7] set MGCPoL [string range $data 8 9] hset $ns/MGC/PMGC [format %d [expr 0x$MGCPoH$MGCPoL]] } 5 { set FreqH [string range $data 6 7] set FreqL [string range $data 8 9] set FreqHzH [string range $data 10 11] set FreqHzL [string range $data 12 13] set Freq [format %d [expr 0x$FreqH$FreqL]] set FreqHz [format %d [expr 0x$FreqHzH$FreqHzL]] hset $ns/FRE/FREQ [expr $Freq * 1000 + $FreqHz] } 7 { set softKey 0x[string range $data 6 7] if {[expr $softKey & 0x80] == 0} { hset $ns/SKEY/SoftOn "Controller takes over the keyboard of controller" } else { hset $ns/SKEY/SoftOn "Host takes over the keyboard of controller" } if {[expr $softKey & 0x08] == 0} { hset $ns/SKEY/Key1 "Off" } else { hset $ns/SKEY/Key1 "On" } if {[expr $softKey & 0x04] == 0} { hset $ns/SKEY/Key0 "Off" } else { hset $ns/SKEY/Key0 "On" } if {[expr $softKey & 0x02] == 0} { hset $ns/SKEY/Key2 "Off" } else { hset $ns/SKEY/Key2 "On" } if {[expr $softKey & 0x01] == 0} { hset $ns/SKEY/Key3 "Off" } else { hset $ns/SKEY/Key3 "On" } } 8 { set SCode [format %02x 0x[string range $data 6 7]] if {$SCode == 0} { hset $ns/BurstPar/BurstMode "Burst Mode OFF" } elseif {$SCode == 1} { hset $ns/BurstPar/BurstMode "Internal Burst Mode ON" } elseif {$SCode == 2} { hset $ns/BurstPar/BurstMode "Change Burst Parameters Without Changing Burst On/Off" } elseif {$SCode == 3} { hset $ns/BurstPar/BurstMode "External Burst Mode ON" } set BRepTH [string range $data 8 9] set BRepTL [string range $data 10 11] hset $ns/BurstPar/BRepTime [format %d [expr 0x$BRepTH$BRepTL]] set BOnTH [string range $data 12 13] set BOnTL [string range $data 14 15] hset $ns/BurstPar/TimeOfPower [format %d [expr 0x$BOnTH$BOnTL]] } 9 { set SCode [format %02x 0x[string range $data 6 7]] if {$SCode == 0} { hset $ns/SweepPar/SweepMode "OFF" } elseif {$SCode == 1} { hset $ns/SweepPar/SweepMode "ON" } elseif {$SCode == 2} { hset $ns/SweepPar/SweepMode "Change Sweep Parameters Without Changing Sweep On/Off" } set SStr [format %d 0x[string range $data 8 9]] set SStrHz [format %d 0x[string range $data 14 15]] hset $ns/SweepPar/StartFreq [expr $SStr * 1000 + $SStrHz] set SStp [format %d 0x[string range $data 10 11]] set SStpHz [format %d 0x[string range $data 16 17]] hset $ns/SweepPar/StepFreq [expr $SStp * 1000 + $SStpHz] set SCyc [format %d 0x[string range $data 12 13]] hset $ns/SweepPar/SCyc $SCyc } 13 { set SNH [string range $data 6 7] set SNL [string range $data 8 9] hset $ns/SVER/SN "$SNH$SNL" set SVerH [string range $data 10 11] set SVerL [string range $data 12 13] hset $ns/SVER/SWVersion "$SVerH$SVerL" set DVerH [string range $data 14 15] set DVerL [string range $data 16 17] hset $ns/SVER/DeviceVersion "$DVerH$DVerL" } 14 { set FPH [string range $data 6 7] set FPL [string range $data 8 9] hset $ns/MEAS/ForwardPower [format %d [expr 0x$FPH$FPL]] set RPH [string range $data 10 11] set RPL [string range $data 12 13] hset $ns/MEAS/ReversePower [format %d [expr 0x$RPH$RPL]] set TPH [string range $data 18 19] set TPL [string range $data 20 21] hset $ns/MEAS/Temperature [format %d [expr 0x$TPH$TPL / 26.4]] } 15 { set MainState [format %d 0x[string range $data 6 7]] switch $MainState { "0" {hset $ns/STA/MainState "Initialization"} "1" {hset $ns/STA/MainState "Controller is in safe loop"} "2" {hset $ns/STA/MainState "Controller is waiting for RFPowerOn Request in LocalMode"} "3" {hset $ns/STA/MainState "Controller is waiting for confirm of RFPowerOn in LocalMode"} "4" {hset $ns/STA/MainState "Controller is in main loop of the LocalMode"} "5" {hset $ns/STA/MainState "Controller is waiting for RFPowerOn Request in RemoteMode"} "6" {hset $ns/STA/MainState "Controller is waiting for confirm of RFPowerOn in RemoteMode"} "7" {hset $ns/STA/MainState "Controller is in main loop of the RemoteMode"} } set state 0x[string range $data 8 9] if {[expr $state & 0x80] != 0} { hset $ns/STA/State/FstRemote "RemoteMode" } else { hset $ns/STA/State/FstRemote "LocalMode" } if {[expr $state & 0x40] != 0} { hset $ns/STA/State/FStExtBurst "External Burst mode ON" } else { hset $ns/STA/State/FStExtBurst "External Burst mode OFF" } if {[expr $state & 0x20] != 0} { hset $ns/STA/State/FStRFError "RFError Detected" } else { hset $ns/STA/State/FStRFError "RFError Not Detected" } if {[expr $state & 0x10] != 0} { hset $ns/STA/State/FStSafetyLP "Error of the Safety Loop Detected" } else { hset $ns/STA/State/FStSafetyLP "Error of the Safety Loop Not Detected" } if {[expr $state & 0x04] != 0} { hset $ns/STA/State/FStExceedRP "Limited of the ReversePower Detected" } else { hset $ns/STA/State/FStExceedRP "Limited of the ReversePower Not Detected" } if {[expr $state & 0x02] != 0} { hset $ns/STA/State/FStExceedFP "Limited of the ForwardPower Detected" } else { hset $ns/STA/State/FStExceedFP "Limited of the ForwardPower Not Detected" } if {[expr $state & 0x01] != 0} { hset $ns/STA/State/FStExceedTmp "Temperature Error Detected" } else { hset $ns/STA/State/FStExceedTmp "Temperature Error Not Detected" } set KeyState 0x[string range $data 10 11] if {[expr $KeyState & 0x80] != 0} { hset $ns/STA/keyState/SoftOn "Host takes over the keyboard of controller" } else { hset $ns/STA/keyState/SoftOn "Controller takes over the keyboard of controller" } if {[expr $KeyState & 0x08] != 0} { hset $ns/STA/keyState/Key1 "On" } else { hset $ns/STA/keyState/Key1 "Off" } if {[expr $KeyState & 0x04] != 0} { hset $ns/STA/keyState/Key0 "On" } else { hset $ns/STA/keyState/Key0 "Off" } if {[expr $KeyState & 0x02] != 0} { hset $ns/STA/keyState/Key2 "On" } else { hset $ns/STA/keyState/Key2 "Off" } if {[expr $KeyState & 0x01] != 0} { hset $ns/STA/keyState/Key3 "On" } else { hset $ns/STA/keyState/Key3 "Off" } } default { return -code error "Unexpected returned values from the device in rdValue()" } } } message ]} { return -code error "Error in rdValue: $message." } return idle } # function names provided # @param scobj_hpath string variabie holding the path to the object's base node in sics (/sample/tc1) # @param sct_controller name of the ag1010 scriptcontext object (typically sct_ag1010) # @param cmdGroup subdirectory (below /sample/tc*/) in which the node is to be created # @param varName name of the actual node typically representing one device command # @param readable set to 1 if the node represents a query command, 0 if it is not # @param writable set to 1 if the node represents a request for a change in settings sent to the device # @param pollEnabled set to 1 if the node property pollable is to be enabled (node gets read every 5 secs) # @param dataType data type of the node, must be one of none, int, float, text # @param unit data units, e.g. m, cm, mm, degree, Hz, W, dW and etc # @param permission defines what user group may read/write to this node (is one of spy, user, manager) # @param rdPara actual device query command to be sent to the device # @param rdFunc nextState Function to be called after the getValue function, typically rdValue() # Praparam wrPara actual device write command to be sent to the device # @param wrFunc Function to be called to send the wrPara to the device, typically setValue() # @param allowedValues allowed values for the node data - does not permit other # @return OK proc createNode {scobj_hpath sct_controller cmdGroup varName readable writable pollEnabled displayable \ dataType unit permission rdPara rdFunc wrPara allowedValues} { # It is a command that is supported by the device if { [catch { set parentnode "ag1010" set ns ::scobj::$parentnode set basepath $scobj_hpath/$parentnode if {2 < [string length $cmdGroup]} { set nodeName "$basepath/$cmdGroup/$varName" } else { set nodeName "$basepath/$varName" } hfactory $nodeName plain $permission $dataType switch $dataType { "none" {hset $nodeName none} "text" {hset $nodeName UNKNOWN} "int" {hset $nodeName 0} "float" {hset $nodeName 0.0} default {hset $nodeName UNKNOWN} } if {$readable == 1} { hsetprop $nodeName read ${ns}::getValue $scobj_hpath $rdFunc $rdPara hsetprop $nodeName $rdFunc ${ns}::$rdFunc if {$pollEnabled == 1} { if {[SplitReply [environment_simulation]]=="false"} { $sct_controller poll $nodeName } } } if {$writable == 1} { hsetprop $nodeName write ${ns}::setValue $scobj_hpath $rdFunc $rdPara $wrPara hsetprop $nodeName $rdFunc ${ns}::$rdFunc if {$pollEnabled == 1} { if {[SplitReply [environment_simulation]]=="false"} { $sct_controller write $nodeName } } } if {1 < [string length $unit]} { hsetprop $nodeName units $unit } if {1 < [string length $allowedValues]} { hsetprop $nodeName values $allowedValues } if {$displayable == 1} { if {2 < [string length $cmdGroup]} { ::scobj::hinitprops $parentnode $cmdGroup/$varName } else { ::scobj::hinitprops $parentnode $varName } } } message ]} { return -code error "Error in createNode $message" } return OK } ## # @brief mkAG creates a scriptcontext object for T&C AG1010 Amplifier/generator # #para argList configurable parameters from function call # @return nothing (well, the sct object) proc ::scobj::ag1010::mkAG {argList} { if {[catch { # 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) # Create a base node for all the state machines of this sics object #set scobj_hpath /sics/$pa(NAME) set scobj_hpath /sics #makesctcontroller sct_ag1010 rfamp $pa(IP):$pa(PORT) #makesctcontroller sct_$pa(NAME) std $pa(IP):$pa(PORT) makesctcontroller sct_$pa(NAME) lfgen $pa(IP):$pa(PORT) ######################################################################################################### # # Create state machines for the following device commands # Note that drivable nodes require the index of the control loop in their call to halt() # Nodes appear in gumtree in the order in which they are created here. # # Initialise the model-dependent list of supported device commands # # cmdGroup subdirectory in which the node is to be created, "P" means under top-parent node # varName name of the actual node typically representing one device command # readable set to 1 if the node represents a query command, 0 if it is not # writable set to 1 if the node represents a request for a change in settings sent to the device # pollEnabled set to 1 if the node property pollable is to be enabled (node gets read every 5 secs) # displayable set to 1 if the node to be displayed on Gumtree GUI, 0 if it is not # dataType data type of the node, must be one of none, int, float, text # unit data units, e.g. m, cm, mm, degree, Hz, W, dW and etc # permission defines what user group may read/write to this node (is one of spy, user, manager) # rdPara parameters LEN and CTRL to be sent to the device # rdFunc nextState Function to be called after the getValue function, typically rdValue() # wrPara actual device field in write command to be sent to the device # allowedValues allowed values for the node data - does not permit other # ########################################################################################################### set deviceCommandToplevel { P limits 1 0 1 1 none {} spy {2 18} {rdValue} {} {} limits ForwardPower 0 0 0 1 int {dW} user {} {} {} {} limits ReversePower 0 0 0 1 int {dW} user {} {} {} {} P AGC 1 0 1 1 none {} user {2 19} {rdValue} {} {} AGC PAGC 0 0 0 1 int {dW} user {} {} {} {} P MGC 1 0 1 1 none {} user {2 20} {rdValue} {} {} MGC PMGC 0 0 0 1 int {dW} user {} {} {} {} P FRE 1 0 1 1 none {} user {2 21} {rdValue} {} {} FRE FREQ 0 0 0 1 int {Hz} user {} {} {} {} P SKEY 1 0 1 1 none {} spy {3 23} {rdValue} {} {} SKEY SoftOn 0 0 0 1 text {} user {} {} {} {} SKEY Key1 0 0 0 1 text {} user {} {} {} {} SKEY Key0 0 0 0 1 text {} user {} {} {} {} SKEY Key2 0 0 0 1 text {} user {} {} {} {} SKEY Key3 0 0 0 1 text {} user {} {} {} {} P BurstPar 1 0 1 1 none {} spy {2 24} {rdValue} {} {} BurstPar BurstMode 0 0 0 1 text {} user {} {} {} {} BurstPar BRepTime 0 0 0 1 int {ms} user {} {} {} {} BurstPar TimeOfPower 0 0 0 1 int {us} user {} {} {} {} P SweepPar 1 0 1 1 none {} spy {2 25} {rdValue} {} {} SweepPar SweepMode 0 0 0 1 text {} user {} {} {} {} SweepPar StartFreq 0 0 0 1 int {Hz} user {} {} {} {} SweepPar StepFreq 0 0 0 1 int {Hz} user {} {} {} {} SweepPar SCyc 0 0 0 1 int {} user {} {} {} {} P SVER 1 0 1 1 none {} spy {2 29} {rdValue} {} {} SVER SN 0 0 0 1 text {} user {} {} {} {} SVER SWVersion 0 0 0 1 text {} user {} {} {} {} SVER DeviceVersion 0 0 0 1 text {} user {} {} {} {} P MEAS 1 0 1 1 none {} spy {2 30} {rdValue} {} {} MEAS ForwardPower 0 0 0 1 int {dW} user {} {} {} {} MEAS ReversePower 0 0 0 1 int {dW} user {} {} {} {} MEAS Temperature 0 0 0 1 int {0C} user {} {} {} {} P STA 1 0 1 1 none {} spy {2 31} {rdValue} {} {} STA MainState 0 0 0 1 text {} user {} {} {} {} STA State 0 0 0 1 int {} user {} {} {} {} STA/State FstRemote 0 0 0 1 text {} user {} {} {} {} STA/State FStExtBurst 0 0 0 1 text {} user {} {} {} {} STA/State FStRFError 0 0 0 1 text {} user {} {} {} {} STA/State FStSafetyLP 0 0 0 1 text {} user {} {} {} {} STA/State FStExceedRP 0 0 0 1 text {} user {} {} {} {} STA/State FStExceedFP 0 0 0 1 text {} user {} {} {} {} STA/State FStExceedTmp 0 0 0 1 text {} user {} {} {} {} STA keyState 0 0 0 1 int {} user {} {} {} {} STA/keyState SoftOn 0 0 0 1 text {} user {} {} {} {} STA/keyState Key1 0 0 0 1 text {} user {} {} {} {} STA/keyState Key0 0 0 0 1 text {} user {} {} {} {} STA/keyState Key2 0 0 0 1 text {} user {} {} {} {} STA/keyState Key3 0 0 0 1 text {} user {} {} {} {} P responseMsg 0 0 0 1 text {} spy {2 42} {} {} {} P SetLimitsFPL 0 1 1 1 int {dW} user {10 2} {rdValue} {FPL} {} P SetLimitsRPL 0 1 1 1 int {dW} user {10 2} {rdValue} {RPL} {} P SetPAGC 0 1 1 1 int {dW} user {4 3} {rdValue} {PAGC} {} P SetPMGC 0 1 1 1 int {dW} user {4 4} {rdValue} {PMGC} {} P SetFREQ 0 1 1 1 int {Hz} user {6 5} {rdValue} {FREQ} {} P SetSoftOn 0 1 1 1 int {} user {3 7} {rdValue} {SoftOn} {1,0} P SetKey1 0 1 1 1 int {} user {3 7} {rdValue} {Key1} {1,0} P SetKey0 0 1 1 1 int {} user {3 7} {rdValue} {Key0} {1,0} P SetKey2 0 1 1 1 int {} user {3 7} {rdValue} {Key2} {1,0} P SetKey3 0 1 1 1 int {} user {3 7} {rdValue} {Key3} {1,0} P SetBurstMode 0 1 1 1 int {} user {7 8} {rdValue} {BurstMode} {0,1,2,3} P SetBRepTime 0 1 1 1 int {ms} user {7 8} {rdValue} {BRepTime} {} P SetBTimeOfPower 0 1 1 1 int {us} user {7 8} {rdValue} {BTofP} {} P SetSweepMode 0 1 1 1 int {} user {13 9} {rdValue} {SweepMode} {0,1,2} P SetSStartFreq 0 1 1 1 int {Hz} user {13 9} {rdValue} {SStrF} {} P SetSStepFreq 0 1 1 1 int {Hz} user {13 9} {rdValue} {SSteF} {} P SetSSCyc 0 1 1 1 int {} user {13 9} {rdValue} {SSCyc} {} } foreach {cmdGroup varName readable writable pollEnabled displayable dataType unit permission rdPara rdFunc wrPara allowedValues} \ $deviceCommandToplevel { createNode $scobj_hpath sct_$pa(NAME) $cmdGroup $varName $readable $writable $pollEnabled $displayable $dataType $unit $permission $rdPara $rdFunc $wrPara $allowedValues } } message ]} { return -code error "Error in ::scobj::ag1010::mkAG $message" } } # end of namespace ::scobj::ag1010::mkAG # SICS commands namespace import ::scobj::ag1010::par proc LFSetLimitsFPL {para} { set HEAD 0x96 set LEN 10 set CTRL 2 set CRC 0 set ns /sics/ag1010 set newPara [string trim $para " "] if {$para > 10040 || $para < 0} { broadcast "Error: The Limit for the Forward Power is 0~10040 dW" } else { set RPL [hval $ns/limits/ReversePower] set data [format %04x%04x%04x%04x $newPara $RPL 0 0] set cmd [format %02x%02x%02x%s%02x $HEAD $LEN $CTRL $data $CRC] broadcast "Set Forward Power Limits to $newPara dW" sct_ag1010 send "$cmd" } } proc LFSetLimitsRPL {para} { set HEAD 0x96 set LEN 10 set CTRL 2 set CRC 0 set ns /sics/ag1010 set newPara [string trim $para " "] if {$para > 1630 || $para < 0} { broadcast "Error: The Limit for the Reflected Power is 0~1630 dW" } else { set FPL [hval $ns/limits/ForwardPower] set data [format %04x%04x%04x%04x $FPL $newPara 0 0] set cmd [format %02x%02x%02x%s%02x $HEAD $LEN $CTRL $data $CRC] broadcast "Set Reverse Power Limits to $newPara dW" sct_ag1010 send "$cmd" } } proc LFSetPAGC {para} { set HEAD 0x96 set LEN 4 set CTRL 3 set CRC 0 set ns /sics/ag1010 set newPara [string trim $para " "] set data [format %04x $newPara] set cmd [format %02x%02x%02x%s%02x $HEAD $LEN $CTRL $data $CRC] broadcast "Set Power Level for AGC mode to $newPara dW" sct_ag1010 send "$cmd" } proc LFSetPMGC {para} { set HEAD 0x96 set LEN 4 set CTRL 4 set CRC 0 set ns /sics/ag1010 set newPara [string trim $para " "] set data [format %04x $newPara] set cmd [format %02x%02x%02x%s%02x $HEAD $LEN $CTRL $data $CRC] broadcast "Set Power Level for MGC mode to $newPara dW" sct_ag1010 send "$cmd" } proc LFSetFREQ {para} { set HEAD 0x96 set LEN 6 set CTRL 5 set CRC 0 set ns /sics/ag1010 set newPara [string trim $para " "] if {$para < 0.02 || $para > 2000000} { broadcast "Error: Freqence shall be set between 0.02 Hz and 2 MHz" } else { set Freq [expr $newPara / 1000] set FreqHz [expr $newPara % 1000] set data [format %04x%04x $Freq $FreqHz] set cmd [format %02x%02x%02x%s%02x $HEAD $LEN $CTRL $data $CRC] broadcast "Set Frequency to $newPara Hz" sct_ag1010 send "$cmd" } } proc LFSetBurstMode {para} { set HEAD 0x96 set LEN 7 set CTRL 8 set CRC 0 set ns /sics/ag1010 set newPara [string trim $para " "] if {$newPara<0 || $newPara>3} { return -code error "Error in setValue: only allowed input values for BurstMode are {0,1,2,3}" } else { set BurstMode $newPara } set BRepTime [hval $ns/BurstPar/BRepTime] set TimeOfPower [hval $ns/BurstPar/TimeOfPower] set data [format %02x%04x%04x $BurstMode $BRepTime $TimeOfPower] set cmd [format %02x%02x%02x%s%02x $HEAD $LEN $CTRL $data $CRC] if {$BurstMode == 0} { set mode "Set Burst Mode to OFF" } elseif {$BurstMode == 1} { set mode "Set Burtst Mode to Internal Mode" } elseif {$BurstMode == 2} { set mode "Set Burst Mode to Change Burst Parameters without Changing Burst On/Off" } else { set mode "Set Burst Mode to External Mode" } broadcast "$mode" sct_ag1010 send "$cmd" } proc LFSetBRepTime {para} { set HEAD 0x96 set LEN 7 set CTRL 8 set CRC 0 set ns /sics/ag1010 set newPara [string trim $para " "] set BurstMode 2 set TimeOfPower [hval $ns/BurstPar/TimeOfPower] set data [format %02x%04x%04x $BurstMode $newPara $TimeOfPower] set cmd [format %02x%02x%02x%s%02x $HEAD $LEN $CTRL $data $CRC] broadcast "Set Repetition Period Burst Cycle to $newPara ms" sct_ag1010 send "$cmd" } proc LFSetBTimeOfPower {para} { set HEAD 0x96 set LEN 7 set CTRL 8 set CRC 0 set ns /sics/ag1010 set newPara [string trim $para " "] set BurstMode 2 set BRepTime [hval $ns/BurstPar/BRepTime] set data [format %02x%04x%04x $BurstMode $BRepTime $newPara] set cmd [format %02x%02x%02x%s%02x $HEAD $LEN $CTRL $data $CRC] broadcast "Set Time of Power in Burst Cycle to $newPara us" sct_ag1010 send "$cmd" } proc LFSetSweep {startF stepF scyc {mode 2} args} { if {$mode<0 || $mode>2} { return -code error "Error in setValue: only allowed input values for SweepMode are {0,1,2}" } else { set SweepMode $mode } set HEAD 0x96 set LEN 13 set CTRL 9 set CRC 0 set SStr [expr $startF / 1000] set SStrHz [expr $startF % 1000] set SStp [expr $stepF / 1000] set SStpHz [expr $stepF % 1000] set SCyc $scyc set data [format %02x%02x%02x%02x%02x%02x $SweepMode $SStr $SStp $SCyc $SStrHz $SStpHz] set cmd [format %02x%02x%02x%s%02x $HEAD $LEN $CTRL $data $CRC] broadcast "Set Starting Frequency at $startF Hz, step at $stepF Hz and $SCyc steps in full sweep cycle under Sweep mode $SweepMode" sct_ag1010 send "$cmd" } proc LFSetSweepMode {para} { set HEAD 0x96 set LEN 13 set CTRL 9 set CRC 0 set ns /sics/ag1010 set newPara [string trim $para " "] if {$newPara<0 || $newPara>2} { return -code error "Error in setValue: only allowed input values for SweepMode are {0,1,2}" } else { set SweepMode $newPara } set SStr [expr [hval $ns/SweepPar/StartFreq] / 1000] set SStrHz [expr [hval $ns/SweepPar/StartFreq] % 1000] set SStp [expr [hval $ns/SweepPar/StepFreq] / 1000] set SStpHz [expr [hval $ns/SweepPar/StepFreq] % 1000] set SCyc [hval $ns/SweepPar/SCyc] set data [format %02x%02x%02x%02x%02x%02x $SweepMode $SStr $SStp $SCyc $SStrHz $SStpHz] set cmd [format %02x%02x%02x%s%02x $HEAD $LEN $CTRL $data $CRC] if {$SweepMode == 0} { set mode "Turn Off Sweep Mode" } elseif {$SweepMode == 1} { set mode "Turn On Sweep Mode" } else { set mode "Set Sweep Mode to Change Sweep Mode Parameters Without Changing Sweep Mode On/Off" } broadcast "$mode" sct_ag1010 send "$cmd" } proc LFSetSStartFreq {para} { set HEAD 0x96 set LEN 13 set CTRL 9 set CRC 0 set ns /sics/ag1010 set newPara [string trim $para " "] set SweepMode 2 set SStr [expr $newPara / 1000] set SStrHz [expr $newPara % 1000] set SStp [expr [hval $ns/SweepPar/StepFreq] / 1000] set SStpHz [expr [hval $ns/SweepPar/StepFreq] % 1000] set SCyc [hval $ns/SweepPar/SCyc] set data [format %02x%02x%02x%02x%02x%02x $SweepMode $SStr $SStp $SCyc $SStrHz $SStpHz] set cmd [format %02x%02x%02x%s%02x $HEAD $LEN $CTRL $data $CRC] broadcast "Set Start Frequency in Sweep Mode to $newPara Hz" sct_ag1010 send "$cmd" } proc LFSetSStepFreq {para} { set HEAD 0x96 set LEN 13 set CTRL 9 set CRC 0 set ns /sics/ag1010 set newPara [string trim $para " "] set SweepMode 2 set SStr [expr [hval $ns/SweepPar/StartFreq] / 1000] set SStrHz [expr [hval $ns/SweepPar/StartFreq] % 1000] set SStp [expr $newPara / 1000] set SStpHz [expr $newPara % 1000] set SCyc [hval $ns/SweepPar/SCyc] set data [format %02x%02x%02x%02x%02x%02x $SweepMode $SStr $SStp $SCyc $SStrHz $SStpHz] set cmd [format %02x%02x%02x%s%02x $HEAD $LEN $CTRL $data $CRC] broadcast "Set Step Frequency in Sweep Mode to $newPara Hz" sct_ag1010 send "$cmd" } proc LFSetSSCyc {para} { set HEAD 0x96 set LEN 13 set CTRL 9 set CRC 0 set ns /sics/ag1010 set newPara [string trim $para " "] set SweepMode 2 set SStr [expr [hval $ns/SweepPar/StartFreq] / 1000] set SStrHz [expr [hval $ns/SweepPar/StartFreq] % 1000] set SStp [expr [hval $ns/SweepPar/StepFreq] / 1000] set SStpHz [expr [hval $ns/SweepPar/StepFreq] % 1000] set SCyc $newPara set data [format %02x%02x%02x%02x%02x%02x $SweepMode $SStr $SStp $SCyc $SStrHz $SStpHz] set cmd [format %02x%02x%02x%s%02x $HEAD $LEN $CTRL $data $CRC] broadcast "Set Number of Steps in Full Sweep Cycle to $newPara" sct_ag1010 send "$cmd" } proc LFGetLimits {} { broadcast "[hget /sics/ag1010/limits/ForwardPower] dW" broadcast "[hget /sics/ag1010/limits/ReversePower] dW" } proc LFGetPAGC {} { broadcast "[hget /sics/ag1010/AGC/PAGC] dW" } proc LFGetPMGC {} { broadcast "[hget /sics/ag1010/MGC/PMGC] dW" } proc LFGetFREQ {} { broadcast "[hget /sics/ag1010/FRE/FREQ] Hz" } proc LFGetBurstPar {} { broadcast "[hget /sics/ag1010/BurstPar/BurstMode]" broadcast "[hget /sics/ag1010/BurstPar/BRepTime] ms" broadcast "[hget /sics/ag1010/BurstPar/TimeOfPower] us" } proc LFGetSweepPar {} { broadcast "[hget /sics/ag1010/SweepPar/SweepMode]" broadcast "[hget /sics/ag1010/SweepPar/StartFreq] Hz" broadcast "[hget /sics/ag1010/SweepPar/StepFreq] Hz" broadcast "[hget /sics/ag1010/SweepPar/SCyc]" } proc LFGetMEAS {} { broadcast "[hget /sics/ag1010/MEAS/ForwardPower] dW" broadcast "[hget /sics/ag1010/MEAS/ReversePower] dW" broadcast "[hget /sics/ag1010/MEAS/Temperature] Degree" } publish LFSetLimitsFPL user publish LFSetLimitsRPL user publish LFSetPAGC user publish LFSetPMGC user publish LFSetFREQ user publish LFSetBurstMode user publish LFSetBRepTime user publish LFSetBTimeOfPower user publish LFSetSweep user publish LFSetSweepMode user publish LFSetSStartFreq user publish LFSetSStepFreq user publish LFSetSSCyc user publish LFGetLimits user publish LFGetPAGC user publish LFGetPMGC user publish LFGetFREQ user publish LFGetBurstPar user publish LFGetSweepPar user publish LFGetMEAS user # Main process call # @param name short name for the AG1010 Amplifier/Generator # @param IP IP address of the device (e.g. IP of moxabox that hooks up to the AG1010) # @param port port number on the moxabox (typ. 4001, 4002, 4003, or 4004) # @param turning if the parameter is turnable and can be set from the Gumtree # @internal time internal in polling the nodes # IP 137.157.202.219 ::scobj::ag1010::mkAG { name "ag1010" IP 137.157.202.219 PORT 4001 tuning 1 interval 5 }