Integrated low level IP Port driver from DLS

Integrated the low level asyn IP Port driver from the Diamond Light
Source so that StreamDevices can use it as well.
This commit is contained in:
2025-04-10 15:37:45 +02:00
parent 295cd34993
commit 4b70676eb0
5 changed files with 919 additions and 46 deletions

View File

@@ -174,56 +174,59 @@ asynStatus turboPmacController::writeRead(int axisNo, const char *command,
return asynError;
}
/*
The message protocol of the turboPmac used at PSI looks as follows (all
characters immediately following each other without a newline):
0x40 (ASCII value of @) -> Request for download
0xBF (ASCII value of ¿) -> Select mode "get_response"
0x00 (ASCII value of 0)
0x00 (ASCII value of 0)
0x00 (ASCII value of 0)
0x00 (ASCII value of 0)
0x00 (ASCII value of 0)
[message length in network byte order] -> Use the htons function for this
value [Actual message] It is not necessary to append a terminator, since
this protocol encodes the message length at the beginning. See Turbo PMAC
User Manual, page 418 in VR_PMAC_GETRESPONSE
x0D (ASCII value of carriage return) -> The controller needs a carriage
return at the end of a "send" command (a command were we transmit data via
=). For "request" commands (e.g. read status or position), this is not
necessary, but it doesn't hurt either, therefore we always add a carriage
return.
// NOT NEEDED ANYMORE DUE TO THE LOW LEVEL DRIVER
// /*
// The message protocol of the turboPmac used at PSI looks as follows (all
// characters immediately following each other without a newline):
// 0x40 (ASCII value of @) -> Request for download
// 0xBF (ASCII value of ¿) -> Select mode "get_response"
// 0x00 (ASCII value of 0)
// 0x00 (ASCII value of 0)
// 0x00 (ASCII value of 0)
// 0x00 (ASCII value of 0)
// 0x00 (ASCII value of 0)
// [message length in network byte order] -> Use the htons function for this
// value [Actual message] It is not necessary to append a terminator, since
// this protocol encodes the message length at the beginning. See Turbo PMAC
// User Manual, page 418 in VR_PMAC_GETRESPONSE
// x0D (ASCII value of carriage return) -> The controller needs a carriage
// return at the end of a "send" command (a command were we transmit data
// via
// =). For "request" commands (e.g. read status or position), this is not
// necessary, but it doesn't hurt either, therefore we always add a carriage
// return.
The message has to be build manually into the buffer fullCommand, since it
contains NULL terminators in its middle, therefore the string manipulation
methods of C don't work.
*/
// The message has to be build manually into the buffer fullCommand, since
// it contains NULL terminators in its middle, therefore the string
// manipulation methods of C don't work.
// */
const size_t commandLength = strlen(command);
const int offset = 9;
// const size_t commandLength = strlen(command);
// const int offset = 9;
// Positions 2 to 6 must have the value 0. Since fullCommand is initialized
// as an array of zeros, we don't need to set these bits manually.
fullCommand[0] = '\x40';
fullCommand[1] = '\xBF';
// // Positions 2 to 6 must have the value 0. Since fullCommand is
// initialized
// // as an array of zeros, we don't need to set these bits manually.
// fullCommand[0] = '\x40';
// fullCommand[1] = '\xBF';
// The size of size_t is platform dependant (pointers-sized), while htons
// needs an unsigned int. The byte order is then converted from host to
// network order. The offset "+1" is for the carriage return.
u_int16_t len = htons(static_cast<u_int16_t>(commandLength + 1));
// // The size of size_t is platform dependant (pointers-sized), while htons
// // needs an unsigned int. The byte order is then converted from host to
// // network order. The offset "+1" is for the carriage return.
// u_int16_t len = htons(static_cast<u_int16_t>(commandLength + 1));
// Split up into the upper and the lower byte
fullCommand[7] = (char)(len >> 8); // Shift the 8 higher bits to the right
fullCommand[8] = (char)(len & 0xFF); // Mask the higher bits
// // Split up into the upper and the lower byte
// fullCommand[7] = (char)(len >> 8); // Shift the 8 higher bits to the
// right fullCommand[8] = (char)(len & 0xFF); // Mask the higher bits
// Write the actual command behind the protocol
for (size_t i = 0; i < commandLength; i++) {
fullCommand[i + offset] = command[i];
}
fullCommand[offset + commandLength] = '\x0D';
// // Write the actual command behind the protocol
// for (size_t i = 0; i < commandLength; i++) {
// fullCommand[i + offset] = command[i];
// }
// fullCommand[offset + commandLength] = '\x0D';
// +1 for the carriage return.
const size_t fullComandLength = offset + commandLength + 1;
// // +1 for the carriage return.
// const size_t fullComandLength = offset + commandLength + 1;
/*
We use separated write and read commands here, not the combined writeRead
@@ -239,7 +242,7 @@ asynStatus turboPmacController::writeRead(int axisNo, const char *command,
trying to reconnect. If the problem persists, ask them to call the support
*/
status = pasynOctetSyncIO->write(ipPortUser_, fullCommand, fullComandLength,
status = pasynOctetSyncIO->write(ipPortUser_, command, commandLength,
comTimeout_, &nbytesOut);
msgPrintControlKey writeKey =