formatted

This commit is contained in:
2026-02-10 16:10:51 +01:00
parent 1c18803dc9
commit 1c44a66964
5 changed files with 104 additions and 99 deletions

View File

@@ -7,9 +7,9 @@
#include "sls/sls_detector_funcs.h" #include "sls/sls_detector_funcs.h"
#include "slsDetectorFunctionList.h" #include "slsDetectorFunctionList.h"
#include <errno.h>
#include <fcntl.h> #include <fcntl.h>
#include <sys/ioctl.h> #include <sys/ioctl.h>
#include <errno.h>
#if defined(CHIPTESTBOARDD) || defined(XILINX_CHIPTESTBOARDD) || \ #if defined(CHIPTESTBOARDD) || defined(XILINX_CHIPTESTBOARDD) || \
defined(MYTHEN3D) defined(MYTHEN3D)
@@ -11111,59 +11111,61 @@ int set_pattern_wait_interval(int file_des) {
* in to restore the register. * in to restore the register.
*/ */
int spi_read(int file_des){ int spi_read(int file_des) {
#if !defined(XILINX_CHIPTESTBOARDD) #if !defined(XILINX_CHIPTESTBOARDD)
functionNotImplemented(); functionNotImplemented();
return sendError(file_des); return sendError(file_des);
#endif #endif
int chip_id = 0; int chip_id = 0;
if (receiveData(file_des, &chip_id, sizeof(chip_id), INT32) < 0){ if (receiveData(file_des, &chip_id, sizeof(chip_id), INT32) < 0) {
return printSocketReadError(); return printSocketReadError();
} }
if(chip_id < 0 || chip_id > 15){ if (chip_id < 0 || chip_id > 15) {
sprintf(mess, "Invalid chip_id %d. Must be 0-15\n", chip_id); sprintf(mess, "Invalid chip_id %d. Must be 0-15\n", chip_id);
return sendError(file_des); return sendError(file_des);
} }
int register_id = 0; int register_id = 0;
if (receiveData(file_des, &register_id, sizeof(register_id), INT32) < 0){ if (receiveData(file_des, &register_id, sizeof(register_id), INT32) < 0) {
return printSocketReadError(); return printSocketReadError();
} }
if(register_id < 0 || register_id > 15){ if (register_id < 0 || register_id > 15) {
sprintf(mess, "Invalid register_id %d. Must be 0-15\n", register_id); sprintf(mess, "Invalid register_id %d. Must be 0-15\n", register_id);
return sendError(file_des); return sendError(file_des);
} }
int n_bytes = 0; int n_bytes = 0;
if (receiveData(file_des, &n_bytes, sizeof(n_bytes), INT32) < 0){ if (receiveData(file_des, &n_bytes, sizeof(n_bytes), INT32) < 0) {
return printSocketReadError(); return printSocketReadError();
} }
if(n_bytes < 1 ){ if (n_bytes < 1) {
sprintf(mess, "Invalid n_bytes %d. Must ask for a read of at least 1 byte\n", n_bytes); sprintf(mess,
"Invalid n_bytes %d. Must ask for a read of at least 1 byte\n",
n_bytes);
return sendError(file_des); return sendError(file_des);
} }
LOG(logINFO, ("SPI Read Requested: chip_id=%d, register_id=%d, n_bytes=%d\n", LOG(logINFO,
chip_id, register_id, n_bytes)); ("SPI Read Requested: chip_id=%d, register_id=%d, n_bytes=%d\n",
chip_id, register_id, n_bytes));
#ifdef VIRTUAL #ifdef VIRTUAL
// For the virtual detector we create a fake register to read from // For the virtual detector we create a fake register to read from
// and fill it with 0,2,4,6,... This way we can check that copying // and fill it with 0,2,4,6,... This way we can check that copying
// of the data works as expected // of the data works as expected
uint8_t *fake_register = malloc(n_bytes); uint8_t *fake_register = malloc(n_bytes);
if(fake_register == NULL){ if (fake_register == NULL) {
LOG(logERROR, ("Could not allocate memory for fake register\n")); LOG(logERROR, ("Could not allocate memory for fake register\n"));
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
for (int i = 0; i < n_bytes; i++) { for (int i = 0; i < n_bytes; i++) {
fake_register[i] = (uint8_t)( (i*2) % 256 ); fake_register[i] = (uint8_t)((i * 2) % 256);
} }
#else #else
int spifd = open("/dev/spidev2.0", O_RDWR); int spifd = open("/dev/spidev2.0", O_RDWR);
LOG(logINFO, ("SPI Read: opened spidev2.0 with fd=%d\n", spifd)); LOG(logINFO, ("SPI Read: opened spidev2.0 with fd=%d\n", spifd));
if(spifd < 0){ if (spifd < 0) {
sprintf(mess, "Could not open /dev/spidev2.0\n"); sprintf(mess, "Could not open /dev/spidev2.0\n");
return sendError(file_des); return sendError(file_des);
} }
@@ -11172,55 +11174,55 @@ int spi_read(int file_des){
// Allocate dummy data to shif in, we keep a copy of this // Allocate dummy data to shif in, we keep a copy of this
// to double check that we access a register of the correct size // to double check that we access a register of the correct size
uint8_t *dummy_data = malloc(n_bytes); uint8_t *dummy_data = malloc(n_bytes);
if(dummy_data == NULL){ if (dummy_data == NULL) {
LOG(logERROR, ("Could not allocate memory for dummy data\n")); LOG(logERROR, ("Could not allocate memory for dummy data\n"));
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
for(int i=0; i<n_bytes; i++){ for (int i = 0; i < n_bytes; i++) {
dummy_data[i] = (uint8_t)(i % 256); dummy_data[i] = (uint8_t)(i % 256);
} }
// Allocate actual data buffer this holds the data we read out // Allocate actual data buffer this holds the data we read out
// and that we need to write back to restore the register // and that we need to write back to restore the register
uint8_t *actual_data = malloc(n_bytes); uint8_t *actual_data = malloc(n_bytes);
if(actual_data == NULL){ if (actual_data == NULL) {
LOG(logERROR, ("Could not allocate memory for actual data\n")); LOG(logERROR, ("Could not allocate memory for actual data\n"));
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
memset(actual_data, 0, n_bytes); memset(actual_data, 0, n_bytes);
// Setup sending and receiving buffers and the spi_ioc_transfer struct. // Setup sending and receiving buffers and the spi_ioc_transfer struct.
// We need one more byte before the actual data to send chip_id and register_id // We need one more byte before the actual data to send chip_id and
uint8_t* local_tx = malloc(n_bytes+1); // register_id
if(local_tx == NULL){ uint8_t *local_tx = malloc(n_bytes + 1);
if (local_tx == NULL) {
LOG(logERROR, ("Could not allocate memory for local_tx\n")); LOG(logERROR, ("Could not allocate memory for local_tx\n"));
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
uint8_t* local_rx = malloc(n_bytes+1); uint8_t *local_rx = malloc(n_bytes + 1);
if(local_rx == NULL){ if (local_rx == NULL) {
LOG(logERROR, ("Could not allocate memory for local_rx\n")); LOG(logERROR, ("Could not allocate memory for local_rx\n"));
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
struct spi_ioc_transfer send_cmd[1]; struct spi_ioc_transfer send_cmd[1];
memset(send_cmd, 0, sizeof(send_cmd)); memset(send_cmd, 0, sizeof(send_cmd));
send_cmd[0].len = n_bytes+1; send_cmd[0].len = n_bytes + 1;
send_cmd[0].tx_buf = (unsigned long) local_tx; send_cmd[0].tx_buf = (unsigned long)local_tx;
send_cmd[0].rx_buf = (unsigned long) local_rx; send_cmd[0].rx_buf = (unsigned long)local_rx;
// 0 - Normal operation, 1 - CSN remains zero after operation // 0 - Normal operation, 1 - CSN remains zero after operation
// We use cs_change = 1 to not close the SPI transaction and // We use cs_change = 1 to not close the SPI transaction and
// allow for shifting the read out data back in to restore the // allow for shifting the read out data back in to restore the
// regitster // regitster
send_cmd[0].cs_change = 1; send_cmd[0].cs_change = 1;
// First byte of the message is 4 bits chip_id then 4 bits register_id // First byte of the message is 4 bits chip_id then 4 bits register_id
local_tx[0] = ((chip_id & 0xF) << 4) | (register_id & 0xF); local_tx[0] = ((chip_id & 0xF) << 4) | (register_id & 0xF);
// Then the data follows // Then the data follows
for (int i=0; i < n_bytes; i++) for (int i = 0; i < n_bytes; i++)
local_tx[i+1] = dummy_data[i]; local_tx[i + 1] = dummy_data[i];
#ifdef VIRTUAL #ifdef VIRTUAL
// For the virtual detector we have to copy the data // For the virtual detector we have to copy the data
@@ -11229,54 +11231,57 @@ int spi_read(int file_des){
local_rx[0] = 0; local_rx[0] = 0;
// Then we copy the data from the fake register to the local_rx buffer // Then we copy the data from the fake register to the local_rx buffer
// and the local_tx data to the fake register to emulate the shifting in and out of the data // and the local_tx data to the fake register to emulate the shifting in and
for (int i=0; i < n_bytes; i++){ // out of the data
local_rx[i+1] = fake_register[i]; for (int i = 0; i < n_bytes; i++) {
fake_register[i] = local_tx[i+1]; local_rx[i + 1] = fake_register[i];
fake_register[i] = local_tx[i + 1];
} }
#else #else
// For the real detector we do the transfer here // For the real detector we do the transfer here
if(ioctl(spifd, SPI_IOC_MESSAGE(1), &send_cmd)<0){ if (ioctl(spifd, SPI_IOC_MESSAGE(1), &send_cmd) < 0) {
//cleanup since we return early // cleanup since we return early
close(spifd); close(spifd);
free(local_tx); free(local_tx);
free(local_rx); free(local_rx);
free(dummy_data); free(dummy_data);
free(actual_data); free(actual_data);
//Send error message // Send error message
sprintf(mess, "SPI write failed with %d:%s\n", errno, strerror(errno)); sprintf(mess, "SPI write failed with %d:%s\n", errno, strerror(errno));
return sendError(file_des); return sendError(file_des);
} }
#endif #endif
// Copy everything but the first received byte to the user. First byte should be 0x00 anyway // Copy everything but the first received byte to the user. First byte
for (int i=0; i < n_bytes; i++) // should be 0x00 anyway
actual_data[i] = local_rx[i+1]; for (int i = 0; i < n_bytes; i++)
actual_data[i] = local_rx[i + 1];
// Set up for the second transfer to restore the register // Set up for the second transfer to restore the register
send_cmd[0].cs_change = 0; // we want to end the transaction after this transfer send_cmd[0].cs_change =
0; // we want to end the transaction after this transfer
local_tx[0] = ((chip_id & 0xF) << 4) | (register_id & 0xF); local_tx[0] = ((chip_id & 0xF) << 4) | (register_id & 0xF);
for (int i=0; i < n_bytes; i++) for (int i = 0; i < n_bytes; i++)
local_tx[i+1] = actual_data[i]; local_tx[i + 1] = actual_data[i];
#ifdef VIRTUAL #ifdef VIRTUAL
// Copy the data from the fake register to the local_rx buffer // Copy the data from the fake register to the local_rx buffer
for (int i=0; i < n_bytes; i++){ for (int i = 0; i < n_bytes; i++) {
local_rx[i+1] = fake_register[i]; local_rx[i + 1] = fake_register[i];
} }
free(fake_register); // we are done with the fake register free(fake_register); // we are done with the fake register
#else #else
if(ioctl(spifd, SPI_IOC_MESSAGE(1), &send_cmd)<0){ if (ioctl(spifd, SPI_IOC_MESSAGE(1), &send_cmd) < 0) {
//cleanup since we return early // cleanup since we return early
close(spifd); close(spifd);
free(local_tx); free(local_tx);
free(local_rx); free(local_rx);
free(dummy_data); free(dummy_data);
free(actual_data); free(actual_data);
//Send error message // Send error message
sprintf(mess, "SPI write failed with %d:%s\n", errno, strerror(errno)); sprintf(mess, "SPI write failed with %d:%s\n", errno, strerror(errno));
return sendError(file_des); return sendError(file_des);
} }
@@ -11288,29 +11293,26 @@ int spi_read(int file_des){
sendData(file_des, actual_data, n_bytes, OTHER); sendData(file_des, actual_data, n_bytes, OTHER);
free(local_tx); free(local_tx);
free(local_rx); free(local_rx);
free(dummy_data); free(dummy_data);
free(actual_data); free(actual_data);
return ret; return ret;
} }
/** /**
* Write to SPI register. * Write to SPI register.
*/ */
int spi_write(int file_des){ int spi_write(int file_des) {
#if !defined(XILINX_CHIPTESTBOARDD) #if !defined(XILINX_CHIPTESTBOARDD)
functionNotImplemented(); functionNotImplemented();
return Server_SendResult(file_des, INT32, NULL, 0); return Server_SendResult(file_des, INT32, NULL, 0);
#endif #endif
int chip_id = 0; int chip_id = 0;
if (receiveData(file_des, &chip_id, sizeof(chip_id), INT32) < 0){ if (receiveData(file_des, &chip_id, sizeof(chip_id), INT32) < 0) {
return printSocketReadError(); return printSocketReadError();
} }
if(chip_id < 0 || chip_id > 15){ if (chip_id < 0 || chip_id > 15) {
ret = FAIL; ret = FAIL;
sprintf(mess, "Invalid chip_id %d. Must be 0-15\n", chip_id); sprintf(mess, "Invalid chip_id %d. Must be 0-15\n", chip_id);
LOG(logERROR, (mess)); LOG(logERROR, (mess));
@@ -11318,10 +11320,10 @@ int spi_write(int file_des){
} }
int register_id = 0; int register_id = 0;
if (receiveData(file_des, &register_id, sizeof(register_id), INT32) < 0){ if (receiveData(file_des, &register_id, sizeof(register_id), INT32) < 0) {
return printSocketReadError(); return printSocketReadError();
} }
if(register_id < 0 || register_id > 15){ if (register_id < 0 || register_id > 15) {
ret = FAIL; ret = FAIL;
sprintf(mess, "Invalid register_id %d. Must be 0-15\n", register_id); sprintf(mess, "Invalid register_id %d. Must be 0-15\n", register_id);
LOG(logERROR, (mess)); LOG(logERROR, (mess));
@@ -11329,67 +11331,70 @@ int spi_write(int file_des){
} }
int n_bytes = 0; int n_bytes = 0;
if (receiveData(file_des, &n_bytes, sizeof(n_bytes), INT32) < 0){ if (receiveData(file_des, &n_bytes, sizeof(n_bytes), INT32) < 0) {
return printSocketReadError(); return printSocketReadError();
} }
if(n_bytes < 1 ){ if (n_bytes < 1) {
sprintf(mess, "Invalid n_bytes %d. Must ask for a write of at least 1 byte\n", n_bytes); sprintf(mess,
"Invalid n_bytes %d. Must ask for a write of at least 1 byte\n",
n_bytes);
return sendError(file_des); return sendError(file_des);
} }
LOG(logINFO, ("SPI Write Requested: chip_id=%d, register_id=%d, n_bytes=%d\n", LOG(logINFO,
chip_id, register_id, n_bytes)); ("SPI Write Requested: chip_id=%d, register_id=%d, n_bytes=%d\n",
chip_id, register_id, n_bytes));
uint8_t *data = malloc(n_bytes); uint8_t *data = malloc(n_bytes);
if(data == NULL){ if (data == NULL) {
LOG(logERROR, ("Could not allocate memory for SPI write data\n")); LOG(logERROR, ("Could not allocate memory for SPI write data\n"));
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
memset(data, 0, n_bytes); memset(data, 0, n_bytes);
if (receiveData(file_des, data, n_bytes, OTHER) < 0){ if (receiveData(file_des, data, n_bytes, OTHER) < 0) {
free(data); free(data);
return printSocketReadError(); return printSocketReadError();
} }
uint8_t* local_tx = malloc(n_bytes+1); uint8_t *local_tx = malloc(n_bytes + 1);
if(local_tx == NULL){ if (local_tx == NULL) {
LOG(logERROR, ("Could not allocate memory for local_tx\n")); LOG(logERROR, ("Could not allocate memory for local_tx\n"));
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
uint8_t* local_rx = malloc(n_bytes+1); uint8_t *local_rx = malloc(n_bytes + 1);
if(local_rx == NULL){ if (local_rx == NULL) {
LOG(logERROR, ("Could not allocate memory for local_rx\n")); LOG(logERROR, ("Could not allocate memory for local_rx\n"));
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
struct spi_ioc_transfer send_cmd[1]; struct spi_ioc_transfer send_cmd[1];
memset(send_cmd, 0, sizeof(send_cmd)); memset(send_cmd, 0, sizeof(send_cmd));
send_cmd[0].len = n_bytes+1; send_cmd[0].len = n_bytes + 1;
send_cmd[0].tx_buf = (unsigned long) local_tx; send_cmd[0].tx_buf = (unsigned long)local_tx;
send_cmd[0].rx_buf = (unsigned long) local_rx; send_cmd[0].rx_buf = (unsigned long)local_rx;
// 0 - Normal operation, 1 - CSn remains zero after operation // 0 - Normal operation, 1 - CSn remains zero after operation
send_cmd[0].cs_change = 0; send_cmd[0].cs_change = 0;
local_tx[0] = ((chip_id & 0xF) << 4) | (register_id & 0xF); local_tx[0] = ((chip_id & 0xF) << 4) | (register_id & 0xF);
for (int i=0; i < n_bytes; i++) for (int i = 0; i < n_bytes; i++)
local_tx[i+1] = data[i]; local_tx[i + 1] = data[i];
#ifdef VIRTUAL #ifdef VIRTUAL
// For the virtual detector copy the data from local_tx to local_rx // For the virtual detector copy the data from local_tx to local_rx
for (int i=0; i < n_bytes+1; i++){ for (int i = 0; i < n_bytes + 1; i++) {
local_rx[i] = local_tx[i]; local_rx[i] = local_tx[i];
} }
#else #else
int spifd = open("/dev/spidev2.0", O_RDWR); int spifd = open("/dev/spidev2.0", O_RDWR);
LOG(logINFO, ("SPI Read: opened spidev2.0 with fd=%d\n", spifd)); LOG(logINFO, ("SPI Read: opened spidev2.0 with fd=%d\n", spifd));
if(spifd < 0){ if (spifd < 0) {
free(data); free(data);
free(local_tx); free(local_tx);
free(local_rx); free(local_rx);
sprintf(mess, "Could not open /dev/spidev2.0\n"); sprintf(mess, "Could not open /dev/spidev2.0\n");
return sendError(file_des); return sendError(file_des);
} }
if(ioctl(spifd, SPI_IOC_MESSAGE(1), &send_cmd)<0){ if (ioctl(spifd, SPI_IOC_MESSAGE(1), &send_cmd) < 0) {
close(spifd); close(spifd);
free(data); free(data);
free(local_tx); free(local_tx);
@@ -11403,7 +11408,7 @@ int spi_write(int file_des){
ret = OK; ret = OK;
LOG(logDEBUG1, ("SPI Write Complete\n")); LOG(logDEBUG1, ("SPI Write Complete\n"));
Server_SendResult(file_des, INT32, NULL, 0); Server_SendResult(file_des, INT32, NULL, 0);
sendData(file_des, local_rx+1, n_bytes, OTHER); sendData(file_des, local_rx + 1, n_bytes, OTHER);
free(data); free(data);
free(local_tx); free(local_tx);

View File

@@ -2248,10 +2248,11 @@ class Detector {
///@} ///@}
Result<std::vector<uint8_t>> readSpi(int chip_id, int register_id, Result<std::vector<uint8_t>> readSpi(int chip_id, int register_id,
int n_bytes, Positions pos = {}) const; int n_bytes, Positions pos = {}) const;
Result<std::vector<uint8_t>> writeSpi(int chip_id, int register_id, Result<std::vector<uint8_t>> writeSpi(int chip_id, int register_id,
const std::vector<uint8_t> &data, Positions pos = {}); const std::vector<uint8_t> &data,
Positions pos = {});
private: private:
std::vector<uint16_t> getValidPortNumbers(uint16_t start_port); std::vector<uint16_t> getValidPortNumbers(uint16_t start_port);

View File

@@ -2961,12 +2961,10 @@ Result<std::vector<uint8_t>> Detector::readSpi(int chip_id, int register_id,
n_bytes); n_bytes);
} }
Result<std::vector<uint8_t>> Detector::writeSpi(int chip_id, int register_id, Result<std::vector<uint8_t>>
const std::vector<uint8_t> &data, Positions pos){ Detector::writeSpi(int chip_id, int register_id,
const std::vector<uint8_t> &data, Positions pos) {
return pimpl->Parallel(&Module::writeSpi, pos, chip_id, register_id, data); return pimpl->Parallel(&Module::writeSpi, pos, chip_id, register_id, data);
} }
} // namespace sls } // namespace sls

View File

@@ -4076,7 +4076,7 @@ void Module::simulatingActivityinDetector(const std::string &functionType,
} }
std::vector<uint8_t> Module::readSpi(int chip_id, int register_id, std::vector<uint8_t> Module::readSpi(int chip_id, int register_id,
int n_bytes) const{ int n_bytes) const {
auto client = DetectorSocket(shm()->hostname, shm()->controlPort); auto client = DetectorSocket(shm()->hostname, shm()->controlPort);
client.Send(F_SPI_READ); client.Send(F_SPI_READ);
client.setFnum(F_SPI_READ); client.setFnum(F_SPI_READ);
@@ -4094,11 +4094,10 @@ std::vector<uint8_t> Module::readSpi(int chip_id, int register_id,
std::vector<uint8_t> data(n_bytes); std::vector<uint8_t> data(n_bytes);
client.Receive(data); client.Receive(data);
return data; return data;
} }
std::vector<uint8_t> Module::writeSpi(int chip_id, int register_id, std::vector<uint8_t> Module::writeSpi(int chip_id, int register_id,
const std::vector<uint8_t> &data){ const std::vector<uint8_t> &data) {
auto client = DetectorSocket(shm()->hostname, shm()->controlPort); auto client = DetectorSocket(shm()->hostname, shm()->controlPort);
client.Send(F_SPI_WRITE); client.Send(F_SPI_WRITE);
client.setFnum(F_SPI_WRITE); client.setFnum(F_SPI_WRITE);
@@ -4114,7 +4113,8 @@ std::vector<uint8_t> Module::writeSpi(int chip_id, int register_id,
throw DetectorError(os.str()); throw DetectorError(os.str());
} }
// Read the output from the SPI write. This contains the data before the write. // Read the output from the SPI write. This contains the data before the
// write.
std::vector<uint8_t> ret(data.size()); std::vector<uint8_t> ret(data.size());
client.Receive(ret); client.Receive(ret);
return ret; return ret;

View File

@@ -608,9 +608,10 @@ class Module : public virtual slsDetectorDefs {
int64_t getActualTime() const; int64_t getActualTime() const;
int64_t getMeasurementTime() const; int64_t getMeasurementTime() const;
std::vector<uint8_t> readSpi(int chip_id, int register_id, std::vector<uint8_t> readSpi(int chip_id, int register_id,
int n_bytes) const; int n_bytes) const;
std::vector<uint8_t> writeSpi(int chip_id, int register_id, const std::vector<uint8_t> &data); std::vector<uint8_t> writeSpi(int chip_id, int register_id,
const std::vector<uint8_t> &data);
private: private:
std::string getReceiverLongVersion() const; std::string getReceiverLongVersion() const;