|
|
|
|
@@ -1,24 +1,24 @@
|
|
|
|
|
/**
|
|
|
|
|
* @brief Protocol handler for Mirrotron RF power supplies
|
|
|
|
|
Author: Ferdi Franceschini
|
|
|
|
|
|
|
|
|
|
TODO: Provide acknowledgement when setting a parameter
|
|
|
|
|
"OK", when successful
|
|
|
|
|
"ANSRFAMP: Set failed", on error
|
|
|
|
|
Author: Ferdi Franceschini
|
|
|
|
|
|
|
|
|
|
Current should be ramped up in steps of 0.5A but it doesn't
|
|
|
|
|
have to be ramped down.
|
|
|
|
|
|
|
|
|
|
Provides two commands (L)ist and (S)et
|
|
|
|
|
eg,
|
|
|
|
|
The following command lists status info from the RF Amp at address 3.
|
|
|
|
|
sct_rfamp send L:3
|
|
|
|
|
The reply string has the following form
|
|
|
|
|
address=1|type=L|curr=00|freq=170|voltage=50|K3=1|K2=1|K1=1|O=1|CC=1|CV=0|H=1
|
|
|
|
|
TODO: Provide acknowledgement when setting a parameter
|
|
|
|
|
"OK", when successful
|
|
|
|
|
"ANSRFAMP: Set failed", on error
|
|
|
|
|
|
|
|
|
|
The following command sets the current(I), frequency, switches(K1,K2,K3) and output(O).
|
|
|
|
|
sct_rfamp send S:3:I=5:F=170:K3=0:K2=1:k1=0:O=1
|
|
|
|
|
NOTE: The current is an integer which equals the desired current x10, ie 71 -> 7.1A
|
|
|
|
|
Current should be ramped up in steps of 0.5A but it doesn't
|
|
|
|
|
have to be ramped down.
|
|
|
|
|
|
|
|
|
|
Provides two commands (L)ist and (S)et
|
|
|
|
|
eg,
|
|
|
|
|
The following command lists status info from the RF Amp at address 3.
|
|
|
|
|
sct_rfamp send L:3
|
|
|
|
|
The reply string has the following form
|
|
|
|
|
address=1|type=L|curr=00|freq=170|voltage=50|K3=1|K2=1|K1=1|O=1|CC=1|CV=0|H=1
|
|
|
|
|
|
|
|
|
|
The following command sets the current(I), frequency, switches(K1,K2,K3) and output(O).
|
|
|
|
|
sct_rfamp send S:3:I=5:F=170:K3=0:K2=1:k1=0:O=1
|
|
|
|
|
NOTE: The current is an integer which equals the desired current x10, ie 71 -> 7.1A
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include <errno.h>
|
|
|
|
|
@@ -83,23 +83,24 @@ int RFAmpWriteStart (Ascon *a)
|
|
|
|
|
AsconError(a, errMsg, 0);
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
switch (ctype) {
|
|
|
|
|
case 'L':
|
|
|
|
|
sprintf(data->rfCmd,"%c%c%c%c", 2, address, ctype, 3);
|
|
|
|
|
DynStringReplaceWithLen(a->wrBuffer, data->rfCmd,0, LCMDLEN);
|
|
|
|
|
DynStringClear(a->wrBuffer);
|
|
|
|
|
DynStringConcatBytes(a->wrBuffer, data->rfCmd, LCMDLEN);
|
|
|
|
|
a->state = AsconWriting;
|
|
|
|
|
a->noResponse = 0;
|
|
|
|
|
a->wrPos = 0;
|
|
|
|
|
return 1;
|
|
|
|
|
break;
|
|
|
|
|
break;
|
|
|
|
|
case 'S':
|
|
|
|
|
if (ret < 8) {
|
|
|
|
|
snprintf(errMsg, ERRLEN, "ANSRFAMP: Invalid command string %s", dynStrBuffer);
|
|
|
|
|
a->state = AsconWriteDone;
|
|
|
|
|
a->noResponse = 1;
|
|
|
|
|
AsconError(a, errMsg, 0);
|
|
|
|
|
return 1;
|
|
|
|
|
snprintf(errMsg, ERRLEN, "ANSRFAMP: Invalid command string %s", dynStrBuffer);
|
|
|
|
|
a->state = AsconWriteDone;
|
|
|
|
|
a->noResponse = 1;
|
|
|
|
|
AsconError(a, errMsg, 0);
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
if (address < '1' || address > '9') {
|
|
|
|
|
snprintf(errMsg, ERRLEN, "ANSRFAMP: Invalid address %c, it should be between 1 and 9", address);
|
|
|
|
|
@@ -110,7 +111,7 @@ int RFAmpWriteStart (Ascon *a)
|
|
|
|
|
}
|
|
|
|
|
if (curr < MINCURRSPEC || curr > MAXCURRSPEC) {
|
|
|
|
|
snprintf(errMsg, ERRLEN, "ANSRFAMP: Invalid current specifier %d, it should be between %d and %d. NOTE:divide by 10 to convert to Amps", \
|
|
|
|
|
curr, MINCURRSPEC, MAXCURRSPEC);
|
|
|
|
|
curr, MINCURRSPEC, MAXCURRSPEC);
|
|
|
|
|
a->state = AsconWriteDone;
|
|
|
|
|
a->noResponse = 1;
|
|
|
|
|
AsconError(a, errMsg, 0);
|
|
|
|
|
@@ -139,21 +140,22 @@ int RFAmpWriteStart (Ascon *a)
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
sprintf(data->statusCmd,"%c%c%c%c", 2, address, 'L', 3);
|
|
|
|
|
DynStringReplaceWithLen(a->wrBuffer, data->statusCmd, 0, LCMDLEN);
|
|
|
|
|
DynStringClear(a->wrBuffer);
|
|
|
|
|
DynStringConcatBytes(a->wrBuffer, data->statusCmd, LCMDLEN);
|
|
|
|
|
data->transactInProg = txPreSet;
|
|
|
|
|
data->targetCurrent = curr;
|
|
|
|
|
a->state = AsconWriting;
|
|
|
|
|
a->noResponse = 0;
|
|
|
|
|
a->wrPos = 0;
|
|
|
|
|
return 1;
|
|
|
|
|
break;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
snprintf(errMsg, ERRLEN, "ANSRFAMP: Unknown command type %c, allowed types are 'L' or 'S'", ctype);
|
|
|
|
|
a->state = AsconWriteDone;
|
|
|
|
|
a->noResponse = 1;
|
|
|
|
|
AsconError(a, errMsg, 0);
|
|
|
|
|
return 1;
|
|
|
|
|
break;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -172,62 +174,64 @@ int RFAmpReading (Ascon *a)
|
|
|
|
|
|
|
|
|
|
if(data->transactInProg == txPostSet){
|
|
|
|
|
|
|
|
|
|
data->transactInProg = txCheckReply;
|
|
|
|
|
data->transactInProg = txCheckReply;
|
|
|
|
|
|
|
|
|
|
//Jing: add delay to wait for ramping complete
|
|
|
|
|
sleep(data->timeout);
|
|
|
|
|
//Jing: add delay to wait for ramping complete
|
|
|
|
|
sleep(data->timeout);
|
|
|
|
|
|
|
|
|
|
DynStringReplaceWithLen(a->wrBuffer, data->statusCmd, 0, LCMDLEN);
|
|
|
|
|
a->state = AsconWriting;
|
|
|
|
|
a->noResponse = 0;
|
|
|
|
|
a->wrPos = 0;
|
|
|
|
|
delay = 0;
|
|
|
|
|
}else{
|
|
|
|
|
// Start reading when byte = 2 and stop when 3
|
|
|
|
|
while ( ( rdChRet = AsconReadChar(a->fd, &chr) ) > 0) {
|
|
|
|
|
a->start = DoubleTime();
|
|
|
|
|
if (a->readState) {
|
|
|
|
|
if (a->readState >= LASTBYTENUM) {
|
|
|
|
|
a->readState = 0;
|
|
|
|
|
if (a->readState > LASTBYTENUM) {
|
|
|
|
|
snprintf(errMsg, ERRLEN, "ANSRFAMP: Packet larger than expected, size exceeds %d", LASTBYTENUM);
|
|
|
|
|
GetReplyFailed = 1;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if (chr != 3) {
|
|
|
|
|
snprintf(errMsg, ERRLEN, "ANSRFAMP: Unexpected value %X for packet end signal", chr);
|
|
|
|
|
GetReplyFailed = 1;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if (0 == DynStringConcatChar(a->rdBuffer, '\0')) {
|
|
|
|
|
strcpy(errMsg, "ANSRFAMP: DynStringConcatChar failed:");
|
|
|
|
|
errNum = ENOMEM;
|
|
|
|
|
GetReplyFailed = 1;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
address = GetCharArray(a->rdBuffer)[0];
|
|
|
|
|
ctype = GetCharArray(a->rdBuffer)[1];
|
|
|
|
|
DynStringClear(a->wrBuffer);
|
|
|
|
|
DynStringConcatBytes(a->wrBuffer, data->statusCmd, LCMDLEN);
|
|
|
|
|
a->state = AsconWriting;
|
|
|
|
|
a->noResponse = 0;
|
|
|
|
|
a->wrPos = 0;
|
|
|
|
|
delay = 0;
|
|
|
|
|
} else {
|
|
|
|
|
// Start reading when byte = 2 and stop when 3
|
|
|
|
|
while ( ( rdChRet = AsconReadChar(a->fd, &chr) ) > 0) {
|
|
|
|
|
a->start = DoubleTime();
|
|
|
|
|
if (a->readState) {
|
|
|
|
|
if (a->readState >= LASTBYTENUM) {
|
|
|
|
|
a->readState = 0;
|
|
|
|
|
if (a->readState > LASTBYTENUM) {
|
|
|
|
|
snprintf(errMsg, ERRLEN, "ANSRFAMP: Packet larger than expected, size exceeds %d", LASTBYTENUM);
|
|
|
|
|
GetReplyFailed = 1;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if (chr != 3) {
|
|
|
|
|
snprintf(errMsg, ERRLEN, "ANSRFAMP: Unexpected value %X for packet end signal", chr);
|
|
|
|
|
GetReplyFailed = 1;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if (0 == DynStringConcatChar(a->rdBuffer, '\0')) {
|
|
|
|
|
strcpy(errMsg, "ANSRFAMP: DynStringConcatChar failed:");
|
|
|
|
|
errNum = ENOMEM;
|
|
|
|
|
GetReplyFailed = 1;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
address = GetCharArray(a->rdBuffer)[0];
|
|
|
|
|
ctype = GetCharArray(a->rdBuffer)[1];
|
|
|
|
|
memset(curr, 0, sizeof(curr));
|
|
|
|
|
memset(freq, 0, sizeof(freq));
|
|
|
|
|
memset(voltage, 0, sizeof(voltage));
|
|
|
|
|
strncpy(curr, &GetCharArray(a->rdBuffer)[2], 2);
|
|
|
|
|
strncpy(freq, &GetCharArray(a->rdBuffer)[4], 3);
|
|
|
|
|
strncpy(voltage, &GetCharArray(a->rdBuffer)[7], 2);
|
|
|
|
|
switches = (unsigned char)GetCharArray(a->rdBuffer)[9];
|
|
|
|
|
opstate = GetCharArray(a->rdBuffer)[10];
|
|
|
|
|
strncpy(curr, &GetCharArray(a->rdBuffer)[2], 2);
|
|
|
|
|
strncpy(freq, &GetCharArray(a->rdBuffer)[4], 3);
|
|
|
|
|
strncpy(voltage, &GetCharArray(a->rdBuffer)[7], 2);
|
|
|
|
|
switches = (unsigned char)GetCharArray(a->rdBuffer)[9];
|
|
|
|
|
opstate = GetCharArray(a->rdBuffer)[10];
|
|
|
|
|
|
|
|
|
|
if (data->transactInProg == txPreSet) {
|
|
|
|
|
data->transactInProg = txPostSet;
|
|
|
|
|
if (abs(data->targetCurrent - atoi(curr)) <= (5 + data->currTol)) {
|
|
|
|
|
DynStringReplaceWithLen(a->wrBuffer, data->rfCmd,0, SCMDLEN);
|
|
|
|
|
delay = round(abs(data->targetCurrent - atoi(curr))/0.5 + 0.5);
|
|
|
|
|
a->state = AsconWriting;
|
|
|
|
|
a->noResponse = 0;
|
|
|
|
|
a->wrPos = 0;
|
|
|
|
|
} else {
|
|
|
|
|
strcpy(errMsg, "ANSRFAMP: Step size should be <= 5 for current");
|
|
|
|
|
GetReplyFailed = 1;
|
|
|
|
|
break;
|
|
|
|
|
if (data->transactInProg == txPreSet) {
|
|
|
|
|
data->transactInProg = txPostSet;
|
|
|
|
|
if (abs(data->targetCurrent - atoi(curr)) <= (5 + data->currTol)) {
|
|
|
|
|
DynStringClear(a->wrBuffer);
|
|
|
|
|
DynStringConcatBytes(a->wrBuffer, data->rfCmd, SCMDLEN);
|
|
|
|
|
delay = round(abs(data->targetCurrent - atoi(curr))/0.5 + 0.5);
|
|
|
|
|
a->state = AsconWriting;
|
|
|
|
|
a->noResponse = 0;
|
|
|
|
|
a->wrPos = 0;
|
|
|
|
|
} else {
|
|
|
|
|
strcpy(errMsg, "ANSRFAMP: Step size should be <= 5 for current");
|
|
|
|
|
GetReplyFailed = 1;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
} else if (data->transactInProg == txCheckReply) {
|
|
|
|
|
// TODO Compare rdBuffer to rfCmd if they match then set replyStr="OK" else set error message
|
|
|
|
|
@@ -240,54 +244,55 @@ int RFAmpReading (Ascon *a)
|
|
|
|
|
strncpy(tmpFreq, &data->rfCmd[5], 3);
|
|
|
|
|
tmpSwitchs = (unsigned char)data->rfCmd[8];
|
|
|
|
|
|
|
|
|
|
// TODO SICS-405 ffr Removed check because the read values don't immediately match the set values
|
|
|
|
|
// TODO SICS-405 ffr Removed check because the read values don't immediately match the set values
|
|
|
|
|
if( (abs(atoi(curr) - atoi(tmpCurr)) > data->currTol) ||
|
|
|
|
|
(atoi(freq) != atoi(tmpFreq)) ||
|
|
|
|
|
((switches & 0x0F) != (tmpSwitchs & 0x0F)) ) {
|
|
|
|
|
strcpy(errMsg, "ANSRFAMP: the (S)ET command failed");
|
|
|
|
|
GetReplyFailed = 1;
|
|
|
|
|
break;
|
|
|
|
|
strcpy(errMsg, "ANSRFAMP: the (S)ET command failed");
|
|
|
|
|
GetReplyFailed = 1;
|
|
|
|
|
break;
|
|
|
|
|
} else {
|
|
|
|
|
DynStringReplace(a->rdBuffer, "OK", 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* ffr Just report OK until we have a proper fix */
|
|
|
|
|
//DynStringReplace(a->rdBuffer, "OK", 0);
|
|
|
|
|
|
|
|
|
|
a->state = AsconReadDone;
|
|
|
|
|
data->transactInProg = txNormalRead;
|
|
|
|
|
} else if (data->transactInProg == txNormalRead) {
|
|
|
|
|
K3 = (switches & 0x08) >> 3;
|
|
|
|
|
K2 = (switches & 0x04) >> 2;
|
|
|
|
|
K1 = (switches & 0x02) >> 1;
|
|
|
|
|
outOn = switches & 0x01;
|
|
|
|
|
CC = (opstate & 0x04) >> 2;
|
|
|
|
|
CV = (opstate & 0x02) >> 1;
|
|
|
|
|
heat = opstate & 0x01;
|
|
|
|
|
snprintf(replyStr, 128, "address=%c|type=%c|curr=%s|freq=%s|voltage=%s|K3=%d|K2=%d|K1=%d|O=%d|CC=%d|CV=%d|H=%d", \
|
|
|
|
|
address, ctype, curr, freq, voltage, K3, K2, K1, outOn, CC, CV, heat);
|
|
|
|
|
if (0 == DynStringReplaceWithLen(a->rdBuffer, replyStr, 0, 128)) {
|
|
|
|
|
strcpy(errMsg, "ANSRFAMP: DynStringReplace failed:");
|
|
|
|
|
errNum = ENOMEM;
|
|
|
|
|
GetReplyFailed = 1;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
a->state = AsconReadDone;
|
|
|
|
|
}
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
if (0 == DynStringConcatChar(a->rdBuffer, chr)) {
|
|
|
|
|
strcpy(errMsg, "ANSRFAMP: DynStringConcatChar failed:");
|
|
|
|
|
errNum = ENOMEM;
|
|
|
|
|
GetReplyFailed = 1;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
a->readState++;
|
|
|
|
|
} else if (chr == 2) {
|
|
|
|
|
a->readState = 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
K3 = (switches & 0x08) >> 3;
|
|
|
|
|
K2 = (switches & 0x04) >> 2;
|
|
|
|
|
K1 = (switches & 0x02) >> 1;
|
|
|
|
|
outOn = switches & 0x01;
|
|
|
|
|
CC = (opstate & 0x04) >> 2;
|
|
|
|
|
CV = (opstate & 0x02) >> 1;
|
|
|
|
|
heat = opstate & 0x01;
|
|
|
|
|
snprintf(replyStr, 128, "address=%c|type=%c|curr=%s|freq=%s|voltage=%s|K3=%d|K2=%d|K1=%d|O=%d|CC=%d|CV=%d|H=%d", \
|
|
|
|
|
address, ctype, curr, freq, voltage, K3, K2, K1, outOn, CC, CV, heat);
|
|
|
|
|
DynStringClear(a->wrBuffer);
|
|
|
|
|
if (0 == DynStringConcatBytes(a->rdBuffer, replyStr, 128)) {
|
|
|
|
|
strcpy(errMsg, "ANSRFAMP: DynStringReplace failed:");
|
|
|
|
|
errNum = ENOMEM;
|
|
|
|
|
GetReplyFailed = 1;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
a->state = AsconReadDone;
|
|
|
|
|
}
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
if (0 == DynStringConcatChar(a->rdBuffer, chr)) {
|
|
|
|
|
strcpy(errMsg, "ANSRFAMP: DynStringConcatChar failed:");
|
|
|
|
|
errNum = ENOMEM;
|
|
|
|
|
GetReplyFailed = 1;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
a->readState++;
|
|
|
|
|
} else if (chr == 2) {
|
|
|
|
|
a->readState = 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (rdChRet < 0) {
|
|
|
|
|
AsconError(a, "ANSRFAMP: AsconReadChar failed:", errno);
|
|
|
|
|
return 1;
|
|
|
|
|
@@ -313,16 +318,16 @@ int RFAmpReading (Ascon *a)
|
|
|
|
|
int RFAmpProtHandler (Ascon *a)
|
|
|
|
|
{
|
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
switch (a->state) {
|
|
|
|
|
case AsconWriteStart:
|
|
|
|
|
ret = RFAmpWriteStart(a);
|
|
|
|
|
return ret;
|
|
|
|
|
break;
|
|
|
|
|
break;
|
|
|
|
|
case AsconReading:
|
|
|
|
|
ret = RFAmpReading(a);
|
|
|
|
|
return ret;
|
|
|
|
|
break;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
return AsconStdHandler(a);
|
|
|
|
|
}
|
|
|
|
|
@@ -345,11 +350,11 @@ int RFAmpInit(Ascon *a, SConnection *con, int argc, char *argv[])
|
|
|
|
|
|
|
|
|
|
void AddRFAmpProtocol()
|
|
|
|
|
{
|
|
|
|
|
AsconProtocol *prot = NULL;
|
|
|
|
|
|
|
|
|
|
prot = calloc(sizeof(AsconProtocol), 1);
|
|
|
|
|
prot->name = strdup("rfamp");
|
|
|
|
|
AsconProtocol *prot = NULL;
|
|
|
|
|
|
|
|
|
|
prot = calloc(sizeof(AsconProtocol), 1);
|
|
|
|
|
prot->name = strdup("rfamp");
|
|
|
|
|
prot->init = RFAmpInit;
|
|
|
|
|
prot->handler = RFAmpProtHandler;
|
|
|
|
|
AsconInsertProtocol(prot);
|
|
|
|
|
prot->handler = RFAmpProtHandler;
|
|
|
|
|
AsconInsertProtocol(prot);
|
|
|
|
|
}
|
|
|
|
|
|