Compare commits

...

24 Commits
6.1.1 ... 6.1.2

Author SHA1 Message Date
ae0a54a774 Merge branch 'main' into 6.1.2.rc 2022-11-25 16:12:02 +01:00
ae33622da2 updated pybind and catch (#588)
* updated pybind and catch
* added to release notes
Co-authored-by: Erik Frojdh <erik.frojdh@psi.ch>
2022-11-25 16:08:36 +01:00
c4a453fdbd updated release version 2022-11-25 10:31:10 +01:00
672c0f4a07 updated client date 2022-11-25 10:26:23 +01:00
05af370883 update server bin 2022-11-25 10:23:49 +01:00
a6022b7cec updated release notes and eiger server 2022-11-25 10:18:37 +01:00
72316fa2ce release notes 2022-11-25 10:09:15 +01:00
65523dcc94 release notes 2022-11-25 10:08:17 +01:00
df40665c5e Using a loop to stop (#585)
* loop for stop, 10 retries
  For example, if module A got a "stop" during an acquisition, it stops to an 'Idle' state. If module B gets a "stop" before an acquisition, it will return it is in 'Idle' state and continue to start the next acquisition, but module B then waits for "ready  for trigger" synchronization from module A, which it will never get. Since module B missed the asynchronous stop command, the workaround in the client is to send another "stop" command (upto 10 retries) till it returns Idle.
2022-11-25 09:55:51 +01:00
8472cca81f naming 2022-11-17 17:15:05 +01:00
110e57ff6c Eiger stop lock (#576)
* added a lock when stopping or starting state machine in eiger server

* added 5ms right after acq started to make sure it really started

* added 100ms right after acq started to make sure it really started
2022-11-17 15:23:41 +01:00
fdd6031add renaming for version 2022-11-15 08:50:39 +01:00
e7c65f44cb returning empty fail message for eiger 2022-11-11 16:56:58 +01:00
0063cc8eb2 update release notes 2022-11-11 16:51:20 +01:00
27e6fc3c73 serverbin shortcuts 2022-11-11 16:02:57 +01:00
83e0eb8b01 removed the test for allow update for kernel and server as it is eligible if the kernel is booting up anyway 2022-11-11 16:02:17 +01:00
7f8b5ac6c0 blackfin nCE pin fix for new kernel 2022-11-11 15:31:30 +01:00
340abec016 updated release txt 2022-11-07 12:47:52 +01:00
a8b37e3932 ensure eiger hot fix server version stays the same 2022-10-24 10:54:48 +02:00
0883c73e88 not updating the client versions for 'server only hot fix' 2022-10-24 10:51:50 +02:00
ef7e9d73a5 eiger server fixes:
- removed feb reset in stop acquisition as it caused processing bit to randomly not go high (leads to infinite loop waiting for it to go high). This is anyway done at prepare acquisition and set trimbits.
- left AND right registers monitored for processing bit done
- febProcessinginprogress returns STATUS_IDLE and not IDLE
- In feb stop acquisition, if processing bit is running forever, checks for 1 s, then if acq done bit is high, returns ok, else throws
- feb stop acquisition returns 1 if success and fucntion in list calling it compares properly instead of STATUS_IDLE (no effect, but incorrect logic)
- chipsignals to trimquad should only monitor right fpga (not both as it will throw)
- fixed error messages of readregister inconsistent values
- setmodule and read frame was returning fail without setting error messages (leading to broken tcp connection due to no error message)
-
2022-10-21 16:31:17 +02:00
a8bdc1495c Update issue templates 2022-03-01 10:19:57 +01:00
1c54dea9c7 Update issue templates 2022-03-01 10:18:52 +01:00
cee286b6ad Update issue templates 2022-03-01 10:16:41 +01:00
35 changed files with 4791 additions and 1638 deletions

View File

@ -2,7 +2,7 @@
# Copyright (C) 2021 Contributors to the SLS Detector Package
cmake_minimum_required(VERSION 3.12)
project(slsDetectorPackage)
set(PROJECT_VERSION 6.1.1)
set(PROJECT_VERSION 6.1.2)
set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG")

View File

@ -1,13 +1,13 @@
SLS Detector Package Minor Release 6.1.1 released on 04.01.2022
SLS Detector Package Patch Release 6.1.2 released on 25.11.2022
===============================================================
This document describes the differences between v6.1.1 and v6.1.0.
This document describes the differences between v6.1.2 and v6.1.1.
CONTENTS
--------
1. Resolved Issues
2. On-board Detector Server Compatibility
2. Firmware Requirements
3. Kernel Requirements
4. Download, Documentation & Support
@ -20,74 +20,137 @@ This document describes the differences between v6.1.1 and v6.1.0.
Detector Server
---------------
1. [Jungfrau] Cannot start
Under some circumstances and not always reproducible, the detector
cannot start once it has stopped. Fixed by adding a delay between the
stop pulse and the resetting core to give sufficient time to readout and
stream out the ongoing frame.
1. [Jungfrau, Moench, Ctb]
Programming Firmware
Updating kernel was not enough to ensure seamless programming of FPGA.
nCe signal now made high before programming blackfin.
Updating the on-board detector server to this version is recommended
before updating firmware for future releases.
Also removed the unnecessary test to check if it is allowed to update
kernel or on-board detector server, depending on the current kernel
version.
2. [Eiger] locking for start and stop
Since the start and stop has a few commands within the server itself,
they are locked to ensure they dont disturb the other to have undefined
behavior.
3. [Eiger] Quad Trimbits or threshold
Loading trimbits or setting threshold will throw an incorrect exception
for a quad as the left and right register values will not match. The fix
only sets and monitors right fpga for chip trim signals in quad.
4. [Eiger] Minor refactoring
Inconsistent reads between left and right register for read/write
register commands now give clear error messages.
Fixed some minor functions returned empty error messages when failing.
Client
------
1. [Eiger] Stop command freezes server
It is apparent in large detectors.
For example, if module A got a "stop" during an acquisition,
it stops to an 'Idle' state. If module B gets a "stop" before an
acquisition, it will return it is in 'Idle' state and continue
to start the next acquisition, but module B then waits for "ready
for trigger" synchronization from module A, which it will never get.
Since module B missed the asynchronous stop command, the workaround
in the client is to send another "stop" command (upto 10 retries)
till it returns Idle.
2. [Eiger][Jungfrau][Moench][Ctb]
Stop results in different frame numbers
A "stop" command will also now check for inconsistent 'nextframenumber'
between the modules and set it to the max + 1 to ensure that they
all start with the same frame number for the next acquisition.
2. Firmware Requirements
Python
------
1. Conda package
Removed conda pkgs for python 3.6 and 3.7
Added conda pkgs for python 3.11
2. Pybind11
Updated pybind11 from 2.6.2 to 2.10.11
Test
----
1. Updated catch to latest 2.x version due do build failure on fedora
2. On-board Detector Server Compatibility
==========================================
Eiger 6.1.2
Jungfrau 6.1.2
Gotthard 6.1.0
Mythen3 6.1.0
Gotthard2 6.1.0
Moench 6.1.2
Ctb 6.1.2
On-board Detector Server Upgrade
================================
From v6.1.0 (without tftp):
Using command 'updatedetectorserver'
From 5.0.0 (with tftp):
Using command 'copydetectorserver'
Instructions available at
https://slsdetectorgroup.github.io/devdoc/serverupgrade.html
3. Firmware Requirements
========================
Note: No change to 6.1.0.
Note: No change to 6.1.1.
Eiger 08.10.2021 (v29)
Jungfrau 31.08.2021 (v1.2, PCB v1.0)
08.10.2021 (v2.2, PCB v2.0)
Gotthard 08.02.2018 (50um and 25um Master)
09.02.2018 (25 um Slave)
Mythen3 10.09.2021 (v1.1)
Gotthard2 27.05.2021 (v0.1)
Moench 05.10.2020 (v1.0)
Ctb 05.10.2020 (v1.0)
Eiger
=====
Compatible version : 08.10.2021 (v29)
Jungfrau
========
Compatible version : 31.08.2021 (v1.2, PCB v1.0)
: 08.10.2021 (v2.2, PCB v2.0)
Gotthard
========
Compatible version : 08.02.2018 (50um and 25um Master)
: 09.02.2018 (25 um Slave)
Mythen3
=======
Compatible version : 10.09.2021 (v1.1)
Gotthard2
=========
Compatible version : 27.05.2021 (v0.1)
Moench
======
Compatible version : 05.10.2020 (v1.0)
Ctb
===
Compatible version : 05.10.2020 (v1.0)
Detector Upgrade
================
Detector Firmware Upgrade
=========================
The following can be upgraded remotely:
Eiger via bit files
Jungfrau via command <.pof>
Mythen3 via command <.rbf>
Gotthard2 via command <.rbf>
Moench via command <.pof>
Ctb via command <.pof>
Jungfrau via 'programfpga' command <.pof>
Mythen3 via 'programfpga' command <.rbf>
Gotthard2 via 'programfpga' command <.rbf>
Moench via 'programfpga' command <.pof>
Ctb via 'programfpga' command <.pof>
The following cannot be upgraded remotely:
Gotthard
Instructions available at
https://slsdetectorgroup.github.io/devdoc/firmware.html
and
https://slsdetectorgroup.github.io/devdoc/serverupgrade.html
3. Kernel Requirements
4. Kernel Requirements
======================
Note: No change to 6.1.0.
Note: No change to 6.1.1.
Blackfin
@ -114,7 +177,7 @@ This document describes the differences between v6.1.1 and v6.1.0.
4. Download, Documentation & Support
5. Download, Documentation & Support
====================================
Download

View File

@ -21,4 +21,4 @@ echo "Building using: ${NCORES} cores"
cmake --build . -- -j${NCORES}
cmake --build . --target install
CTEST_OUTPUT_ON_FAILURE=1 ctest -j 2
CTEST_OUTPUT_ON_FAILURE=1 ctest -j 1

View File

@ -1,9 +1,8 @@
python:
- 3.6
- 3.7
- 3.8
- 3.9
- 3.10
- 3.11
numpy:
- 1.17

File diff suppressed because it is too large Load Diff

View File

@ -1 +0,0 @@
../slsDetectorServers/ctbDetectorServer/bin/ctbDetectorServerv6.1.0

View File

@ -0,0 +1 @@
../slsDetectorServers/ctbDetectorServer/bin/ctbDetectorServerv6.1.2

View File

@ -1 +0,0 @@
../slsDetectorServers/eigerDetectorServer/bin/eigerDetectorServerv6.1.0

View File

@ -0,0 +1 @@
../slsDetectorServers/eigerDetectorServer/bin/eigerDetectorServerv6.1.2

View File

@ -1 +0,0 @@
../slsDetectorServers/jungfrauDetectorServer/bin/jungfrauDetectorServerv6.1.1

View File

@ -0,0 +1 @@
../slsDetectorServers/jungfrauDetectorServer/bin/jungfrauDetectorServerv6.1.2

View File

@ -1 +0,0 @@
../slsDetectorServers/moenchDetectorServer/bin/moenchDetectorServerv6.1.0

View File

@ -0,0 +1 @@
../slsDetectorServers/moenchDetectorServer/bin/moenchDetectorServerv6.1.2

View File

@ -715,7 +715,7 @@ int Feb_Control_ProcessingInProgress() {
unsigned int regr = 0, regl = 0;
// deactivated should return end of processing
if (!Feb_Control_activated)
return IDLE;
return STATUS_IDLE;
if (!Feb_Interface_ReadRegister(Feb_Control_rightAddress, FEB_REG_STATUS,
&regr)) {
@ -729,8 +729,9 @@ int Feb_Control_ProcessingInProgress() {
"processing status\n"));
return STATUS_ERROR;
}
LOG(logDEBUG1, ("regl:0x%x regr:0x%x\n", regl, regr));
// processing done
if ((regr | regl) & FEB_REG_STATUS_ACQ_DONE_MSK) {
if (regr & regl & FEB_REG_STATUS_ACQ_DONE_MSK) {
return STATUS_IDLE;
}
// processing running
@ -1046,6 +1047,7 @@ int Feb_Control_StopAcquisition() {
// wait for feb processing to be done
int is_processing = Feb_Control_ProcessingInProgress();
int check_error = 0;
int check_stuck = 0;
while (is_processing != STATUS_IDLE) {
usleep(500);
is_processing = Feb_Control_ProcessingInProgress();
@ -1057,13 +1059,29 @@ int Feb_Control_StopAcquisition() {
break;
check_error++;
} // reset check_error for next time
else
else {
check_error = 0;
}
LOG(logINFO, ("Feb: Processing done (to stop acq)\n"));
// check stuck only 2000 times (1s)
if (is_processing == STATUS_RUNNING) {
if (check_stuck == 2000) {
LOG(logERROR, ("Unable to get feb processing done signal\n"));
// at least it is idle
if (Feb_Control_AcquisitionInProgress() == STATUS_IDLE) {
return 1;
}
LOG(logERROR, ("Unable to get acquisition done signal\n"));
return 0;
}
check_stuck++;
} // reset check_stuck for next time
else {
check_stuck = 0;
}
}
LOG(logINFO, ("Feb: Processing done (to stop acq)\n"));
}
return 1;
}
@ -1544,7 +1562,9 @@ int Feb_Control_SetChipSignalsToTrimQuad(int enable) {
LOG(logINFO, ("%s chip signals to trim quad\n",
enable ? "Enabling" : "Disabling"));
unsigned int regval = 0;
if (!Feb_Control_ReadRegister(DAQ_REG_HRDWRE, &regval)) {
// right fpga only
uint32_t righOffset = DAQ_REG_HRDWRE + Feb_Control_rightAddress;
if (!Feb_Control_ReadRegister(righOffset, &regval)) {
LOG(logERROR, ("Could not set chip signals to trim quad\n"));
return 0;
}
@ -1554,7 +1574,7 @@ int Feb_Control_SetChipSignalsToTrimQuad(int enable) {
regval &= ~(DAQ_REG_HRDWRE_PROGRAM_MSK | DAQ_REG_HRDWRE_M8_MSK);
}
return Feb_Control_WriteRegister(DAQ_REG_HRDWRE, regval);
return Feb_Control_WriteRegister(righOffset, regval);
}
return 1;
}
@ -1587,19 +1607,19 @@ int Feb_Control_WriteRegister(uint32_t offset, uint32_t data) {
int run[2] = {0, 0};
// both registers
if (offset < 0x100) {
if (offset < Feb_Control_leftAddress) {
run[0] = 1;
run[1] = 1;
}
// right registers only
else if (offset >= 0x200) {
else if (offset >= Feb_Control_rightAddress) {
run[0] = 1;
actualOffset = offset - 0x200;
actualOffset = offset - Feb_Control_rightAddress;
}
// left registers only
else {
run[1] = 1;
actualOffset = offset - 0x100;
actualOffset = offset - Feb_Control_leftAddress;
}
for (int iloop = 0; iloop < 2; ++iloop) {
@ -1625,19 +1645,19 @@ int Feb_Control_ReadRegister(uint32_t offset, uint32_t *retval) {
uint32_t value[2] = {0, 0};
int run[2] = {0, 0};
// both registers
if (offset < 0x100) {
if (offset < Feb_Control_leftAddress) {
run[0] = 1;
run[1] = 1;
}
// right registers only
else if (offset >= 0x200) {
else if (offset >= Feb_Control_rightAddress) {
run[0] = 1;
actualOffset = offset - 0x200;
actualOffset = offset - Feb_Control_rightAddress;
}
// left registers only
else {
run[1] = 1;
actualOffset = offset - 0x100;
actualOffset = offset - Feb_Control_leftAddress;
}
for (int iloop = 0; iloop < 2; ++iloop) {
@ -1658,11 +1678,11 @@ int Feb_Control_ReadRegister(uint32_t offset, uint32_t *retval) {
}
}
}
// Inconsistent values
if (value[0] != value[1]) {
// Inconsistent values when reading both registers
if ((run[0] & run[1]) & (value[0] != value[1])) {
LOG(logERROR,
("Inconsistent values read from left 0x%x and right 0x%x\n",
value[0], value[1]));
("Inconsistent values read from %s 0x%x and %s 0x%x\n",
side[0], value[0], side[1], value[1]));
return 0;
}
return 1;

View File

@ -1158,6 +1158,8 @@ int setModule(sls_detector_module myMod, char *mess) {
// if quad, set M8 and PROGRAM manually
if (!Feb_Control_SetChipSignalsToTrimQuad(1)) {
sprintf(mess, "Could not set module. Could not enable chip signals to set trimbits\n");
LOG(logERROR, (mess));
return FAIL;
}
@ -1170,6 +1172,8 @@ int setModule(sls_detector_module myMod, char *mess) {
// if quad, reset M8 and PROGRAM manually
if (!Feb_Control_SetChipSignalsToTrimQuad(0)) {
sprintf(mess, "Could not set module. Could not disable chip signals to set trimbits\n");
LOG(logERROR, (mess));
return FAIL;
}
@ -1179,6 +1183,8 @@ int setModule(sls_detector_module myMod, char *mess) {
// if quad, reset M8 and PROGRAM manually
if (!Feb_Control_SetChipSignalsToTrimQuad(0)) {
sprintf(mess, "Could not set module. Could not disable chip signals to set trimbits\n");
LOG(logERROR, (mess));
return FAIL;
}
@ -2211,43 +2217,44 @@ int setTransmissionDelayRight(int value) {
/* aquisition */
int prepareAcquisition() {
#ifndef VIRTUAL
sharedMemory_lockLocalLink();
LOG(logINFO, ("Going to prepare for acquisition with counter_bit:%d\n",
Feb_Control_Get_Counter_Bit()));
Feb_Control_PrepareForAcquisition();
sharedMemory_unlockLocalLink();
#endif
return OK;
}
int startStateMachine() {
sharedMemory_lockAcqFlag();
#ifdef VIRTUAL
// create udp socket
if (createUDPSocket(0) != OK) {
sharedMemory_unlockAcqFlag();
return FAIL;
}
if (createUDPSocket(1) != OK) {
sharedMemory_unlockAcqFlag();
return FAIL;
}
LOG(logINFOBLUE, ("Starting State Machine\n"));
if (sharedMemory_getStop() != 0) {
LOG(logERROR, ("Cant start acquisition. "
"Stop server has not updated stop status to 0\n"));
sharedMemory_unlockAcqFlag();
return FAIL;
}
sharedMemory_setStatus(RUNNING);
if (pthread_create(&virtual_tid, NULL, &start_timer, NULL)) {
LOG(logERROR, ("Could not start Virtual acquisition thread\n"));
sharedMemory_setStatus(IDLE);
sharedMemory_unlockAcqFlag();
return FAIL;
}
LOG(logINFO, ("Virtual Acquisition started\n"));
sharedMemory_unlockAcqFlag();
return OK;
#else
sharedMemory_lockLocalLink();
LOG(logINFO, ("Acquisition started bit toggled\n"));
LOG(logINFO, ("Going to prepare for acquisition with counter_bit:%d\n",
Feb_Control_Get_Counter_Bit()));
Feb_Control_PrepareForAcquisition();
int ret = OK, prev_flag;
// get the DAQ toggle bit
prev_flag = Feb_Control_AcquisitionStartedBit();
@ -2264,12 +2271,14 @@ int startStateMachine() {
LOG(logERROR,
("Acquisition did not LOG(logERROR ouble reading register\n"));
sharedMemory_unlockLocalLink();
sharedMemory_unlockAcqFlag();
return FAIL;
}
usleep(100 * 1000);
LOG(logINFOGREEN, ("Acquisition started\n"));
}
sharedMemory_unlockLocalLink();
sharedMemory_unlockAcqFlag();
return ret;
#endif
}
@ -2502,6 +2511,10 @@ void *start_timer(void *arg) {
#endif
int stopStateMachine() {
// acq lock for seamless stop
sharedMemory_lockAcqFlag();
LOG(logINFORED, ("Stopping state machine\n"));
// if scan active, stop scan
if (sharedMemory_getScanStatus() == RUNNING) {
@ -2514,13 +2527,15 @@ int stopStateMachine() {
usleep(500);
sharedMemory_setStop(0);
LOG(logINFO, ("Stopped State Machine\n"));
sharedMemory_unlockAcqFlag();
return OK;
#else
sharedMemory_lockLocalLink();
// sends last frames from fifo and wait for feb processing done
if ((Feb_Control_StopAcquisition() != STATUS_IDLE)) {
if (!Feb_Control_StopAcquisition()) {
LOG(logERROR, ("failed to stop acquisition\n"));
sharedMemory_unlockLocalLink();
sharedMemory_unlockAcqFlag();
return FAIL;
}
sharedMemory_unlockLocalLink();
@ -2531,6 +2546,7 @@ int stopStateMachine() {
// wait for beb to send out all packets
if (Beb_IsTransmitting(&isTransmitting, send_to_ten_gig, 1) == FAIL) {
LOG(logERROR, ("failed to stop beb acquisition\n"));
sharedMemory_unlockAcqFlag();
return FAIL;
}
if (isTransmitting) {
@ -2545,6 +2561,7 @@ int stopStateMachine() {
sharedMemory_unlockLocalLink();
if (!Beb_StopAcquisition()) {
LOG(logERROR, ("failed to stop acquisition\n"));
sharedMemory_unlockAcqFlag();
return FAIL;
}
@ -2554,6 +2571,7 @@ int stopStateMachine() {
Beb_SetNextFrameNumber(retval + 1);
}
LOG(logINFOBLUE, ("Stopping state machine complete\n\n"));
sharedMemory_unlockAcqFlag();
return OK;
#endif
}
@ -2637,7 +2655,8 @@ void readFrame(int *ret, char *mess) {
sharedMemory_lockLocalLink();
if (Feb_Control_WaitForFinishedFlag(5000, 1) == STATUS_ERROR) {
sharedMemory_unlockLocalLink();
LOG(logERROR, ("Waiting for finished flag\n"));
strcpy(mess, "Could not wait for finished flag\n");
LOG(logERROR, (mess));
*ret = FAIL;
return;
}
@ -2653,6 +2672,7 @@ void readFrame(int *ret, char *mess) {
sharedMemory_unlockLocalLink();
if (i == STATUS_ERROR) {
strcpy(mess, "Could not read feb processing done register\n");
LOG(logERROR, (mess));
*ret = (int)FAIL;
return;
}
@ -2664,6 +2684,7 @@ void readFrame(int *ret, char *mess) {
// wait for beb to send out all packets
if (Beb_IsTransmitting(&isTransmitting, send_to_ten_gig, 1) == FAIL) {
strcpy(mess, "Could not read delay counters\n");
LOG(logERROR, (mess));
*ret = (int)FAIL;
return;
}

View File

@ -11,12 +11,11 @@
#define BLACKFIN_DEFINED
int defineGPIOpins(char *mess);
int FPGAdontTouchFlash(char *mess);
int FPGATouchFlash(char *mess);
int FPGAdontTouchFlash(char *mess, int programming);
int FPGATouchFlash(char *mess, int programming);
int resetFPGA(char *mess);
int emptyTempFolder(char *mess);
int allowUpdate(char *mess, char *functionType);
/**
* deletes old file
* verify memory available to copy

View File

@ -25,4 +25,6 @@ int sharedMemory_getScanStop();
#ifdef EIGERD
void sharedMemory_lockLocalLink();
void sharedMemory_unlockLocalLink();
void sharedMemory_lockAcqFlag();
void sharedMemory_unlockAcqFlag();
#endif

View File

@ -600,9 +600,6 @@ int setTransmissionDelayRight(int value);
#endif
// aquisition
#ifdef EIGERD
int prepareAcquisition();
#endif
int startStateMachine();
#ifdef VIRTUAL
void *start_timer(void *arg);

View File

@ -18,8 +18,11 @@
#define CMD_GPIO9_DEFINE "echo 9 > /sys/class/gpio/export"
#define CMD_GPIO3_DEFINE "echo 3 > /sys/class/gpio/export"
// N config done
#define CMD_GPIO7_EXIST "/sys/class/gpio/gpio7"
// N Config
#define CMD_GPIO9_EXIST "/sys/class/gpio/gpio9"
// N CE (access to AS interface)
#define CMD_GPIO3_EXIST "/sys/class/gpio/gpio3"
#define CMD_GPIO9_DEFINE_OUT "echo out > /sys/class/gpio/gpio9/direction"
@ -28,8 +31,11 @@
#define CMD_GPIO9_DEFINE_IN "echo in > /sys/class/gpio/gpio9/direction"
#define CMD_GPIO3_DEFINE_IN "echo in > /sys/class/gpio/gpio3/direction"
// nConfig
#define CMD_GPIO9_DONT_TOUCH_FLASH "echo 0 > /sys/class/gpio/gpio9/value"
#define CMD_GPIO3_DONT_TOUCH_FLASH "echo 0 > /sys/class/gpio/gpio3/value"
// nCE
#define CMD_GPIO3_DONT_TOUCH_FLASH "echo 1 > /sys/class/gpio/gpio3/value"
// CD
#define CMD_FPGA_PICKED_STATUS "cat /sys/class/gpio/gpio7/value"
#define CMD_GET_FPGA_FLASH_DRIVE "awk \'$4== \"\\\"bitfile(spi)\\\"\" {print $1}\' /proc/mtd"
@ -65,7 +71,7 @@ int defineGPIOpins(char *mess) {
if (FAIL == validateKernelVersion(KERNEL_DATE_VRSN_3GPIO)) {
latestKernelVerified = 0;
LOG(logWARNING,
("Kernel too old to use gpio 3 pins. Update kernel to "
("Kernel too old to use gpio3 (nCE). Update kernel to "
"guarantee error-free fpga programming. \n\tNot the end "
"of the world. Continuing with current kernel...\n"));
} else {
@ -78,35 +84,35 @@ int defineGPIOpins(char *mess) {
if (access(CMD_GPIO7_EXIST, F_OK) != 0) {
if (executeCommand(CMD_GPIO7_DEFINE, retvals, logDEBUG1) == FAIL) {
snprintf(mess, MAX_STR_LENGTH,
"Could not define gpio7 pins for fpga (%s)\n", retvals);
"Could not define gpio7 (CD) for fpga (%s)\n", retvals);
LOG(logERROR, (mess));
return FAIL;
}
LOG(logINFO, ("\tgpio7: defined\n"));
LOG(logINFO, ("\tgpio7 (CD): defined\n"));
} else {
LOG(logINFO, ("\tgpio7: already defined\n"));
LOG(logINFO, ("\tgpio7 (CD): already defined\n"));
}
// define gpio7 direction
if (executeCommand(CMD_GPIO7_DEFINE_IN, retvals, logDEBUG1) == FAIL) {
snprintf(mess, MAX_STR_LENGTH,
"Could not set gpio7 as input for fpga (%s)\n", retvals);
"Could not set gpio7 (CD) as input for fpga (%s)\n", retvals);
LOG(logERROR, (mess));
return FAIL;
}
LOG(logINFO, ("\tgpio7: setting intput\n"));
LOG(logINFO, ("\tgpio7 (CD): setting intput\n"));
// define gpio9
if (access(CMD_GPIO9_EXIST, F_OK) != 0) {
if (executeCommand(CMD_GPIO9_DEFINE, retvals, logDEBUG1) == FAIL) {
snprintf(mess, MAX_STR_LENGTH,
"Could not define gpio9 pins for fpga (%s)\n", retvals);
"Could not define gpio9 (nConfig) for fpga (%s)\n", retvals);
LOG(logERROR, (mess));
return FAIL;
}
LOG(logINFO, ("\tgpio9: defined\n"));
LOG(logINFO, ("\tgpio9 (nConfig): defined\n"));
} else {
LOG(logINFO, ("\tgpio9: already defined\n"));
LOG(logINFO, ("\tgpio9 (nConfig): already defined\n"));
}
// define gpio3 (not chip enable)
@ -114,21 +120,21 @@ int defineGPIOpins(char *mess) {
if (access(CMD_GPIO3_EXIST, F_OK) != 0) {
if (executeCommand(CMD_GPIO3_DEFINE, retvals, logDEBUG1) == FAIL) {
snprintf(mess, MAX_STR_LENGTH,
"Could not define gpio3 pins for fpga (%s)\n",
"Could not define gpio3 (nCE) for fpga (%s)\n",
retvals);
LOG(logERROR, (mess));
return FAIL;
}
LOG(logINFO, ("\tgpio3: defined\n"));
LOG(logINFO, ("\tgpio3 (nCE): defined\n"));
} else {
LOG(logINFO, ("\tgpio3: already defined\n"));
LOG(logINFO, ("\tgpio3 (nCE): already defined\n"));
}
}
return OK;
}
int FPGAdontTouchFlash(char *mess) {
int FPGAdontTouchFlash(char *mess, int programming) {
#ifdef VIRTUAL
return OK;
#endif
@ -136,51 +142,51 @@ int FPGAdontTouchFlash(char *mess) {
// define gpio9 as output
if (executeCommand(CMD_GPIO9_DEFINE_OUT, retvals, logDEBUG1) == FAIL) {
snprintf(mess, MAX_STR_LENGTH,
"Could not set gpio9 as output for fpga (%s)\n", retvals);
"Could not set gpio9 (nConfig) as output for fpga (%s)\n", retvals);
LOG(logERROR, (mess));
return FAIL;
}
LOG(logINFO, ("\tgpio9: setting output\n"));
LOG(logINFO, ("\tgpio9 (nConfig): setting output\n"));
// define gpio3 as output
if (latestKernelVerified == 1) {
if (programming && latestKernelVerified == 1) {
if (executeCommand(CMD_GPIO3_DEFINE_OUT, retvals, logDEBUG1) == FAIL) {
snprintf(mess, MAX_STR_LENGTH,
"Could not set gpio3 as output for fpga (%s)\n", retvals);
"Could not set gpio3 (nCE) as output for fpga (%s)\n", retvals);
LOG(logERROR, (mess));
return FAIL;
}
LOG(logINFO, ("\tgpio3: setting output\n"));
LOG(logINFO, ("\tgpio3 (nCE): setting output\n"));
}
// tell FPGA to not: gpio9
if (executeCommand(CMD_GPIO9_DONT_TOUCH_FLASH, retvals, logDEBUG1) ==
FAIL) {
snprintf(mess, MAX_STR_LENGTH,
"Could not set gpio9 to not touch flash for fpga (%s)\n",
"Could not set gpio9 (nConfig) to not touch flash for fpga (%s)\n",
retvals);
LOG(logERROR, (mess));
return FAIL;
}
LOG(logINFO, ("\tgpio9: fpga dont touch flash\n"));
LOG(logINFO, ("\tgpio9 (nConfig): fpga dont touch flash (Low)\n"));
// tell FPGA to not: gpio3
if (latestKernelVerified == 1) {
if (programming && latestKernelVerified == 1) {
if (executeCommand(CMD_GPIO3_DONT_TOUCH_FLASH, retvals, logDEBUG1) ==
FAIL) {
snprintf(mess, MAX_STR_LENGTH,
"Could not set gpio3 to not touch flash for fpga (%s)\n",
"Could not set gpio3 (nCE) to not touch flash for fpga (%s)\n",
retvals);
LOG(logERROR, (mess));
return FAIL;
}
LOG(logINFO, ("\tgpio3: fpga dont touch flash\n"));
LOG(logINFO, ("\tgpio3 (nCE): fpga dont touch flash (High)\n"));
}
// usleep(100*1000);
return OK;
}
int FPGATouchFlash(char *mess) {
int FPGATouchFlash(char *mess, int programming) {
#ifdef VIRTUAL
return OK;
#endif
@ -188,20 +194,20 @@ int FPGATouchFlash(char *mess) {
// tell FPGA to touch flash to program itself
if (executeCommand(CMD_GPIO9_DEFINE_IN, retvals, logDEBUG1) == FAIL) {
snprintf(mess, MAX_STR_LENGTH,
"Could not set gpio9 as input for fpga (%s)\n", retvals);
"Could not set gpio9 (nConfig) as input for fpga (%s)\n", retvals);
LOG(logERROR, (mess));
return FAIL;
}
LOG(logINFO, ("\tgpio9: setting input\n"));
LOG(logINFO, ("\tgpio9 (nConfig): setting input\n"));
if (latestKernelVerified == 1) {
if (programming && latestKernelVerified == 1) {
if (executeCommand(CMD_GPIO3_DEFINE_IN, retvals, logDEBUG1) == FAIL) {
snprintf(mess, MAX_STR_LENGTH,
"Could not set gpio3 as input for fpga (%s)\n", retvals);
"Could not set gpio3 (nCE) as input for fpga (%s)\n", retvals);
LOG(logERROR, (mess));
return FAIL;
}
LOG(logINFO, ("\tgpio3: setting input\n"));
LOG(logINFO, ("\tgpio3 (nCE): setting input\n"));
}
return OK;
}
@ -211,10 +217,10 @@ int resetFPGA(char *mess) {
#ifdef VIRTUAL
return OK;
#endif
if (FPGAdontTouchFlash(mess) == FAIL) {
if (FPGAdontTouchFlash(mess, 0) == FAIL) {
return FAIL;
}
if (FPGATouchFlash(mess) == FAIL) {
if (FPGATouchFlash(mess, 0) == FAIL) {
return FAIL;
}
usleep(CTRL_SRVR_INIT_TIME_US);
@ -248,41 +254,6 @@ int emptyTempFolder(char *mess) {
#endif
}
int allowUpdate(char *mess, char *functionType) {
LOG(logINFO, ("\tVerifying %s allowed...\n", functionType));
#ifdef VIRTUAL
return OK;
#endif
char retvals[MAX_STR_LENGTH] = {0};
if (executeCommand(CMD_GET_AMD_FLASH, retvals, logDEBUG1) == FAIL) {
// no amd found
if (strstr(retvals, "No result") != NULL) {
LOG(logINFO, ("\tNot Amd Flash\n"));
return OK;
}
// could not figure out if amd
snprintf(
mess, MAX_STR_LENGTH,
"Could not update %s. (Could not figure out if Amd flash: %s)\n",
functionType, retvals);
LOG(logERROR, (mess));
return FAIL;
}
// amd, only current kernel works with amd flash
if (validateKernelVersion(KERNEL_DATE_VRSN_3GPIO) == FAIL) {
getKernelVersion(retvals);
snprintf(mess, MAX_STR_LENGTH,
"Could not update %s. Kernel version %s is too old to "
"update the Amd flash/ root directory. Most likely, blackfin needs rescue or replacement. Please contact us.\n",
functionType, retvals);
LOG(logERROR, (mess));
return FAIL;
}
LOG(logINFO, ("\tAmd flash with compatible kernel version\n"));
return OK;
}
int preparetoCopyProgram(char *mess, char *functionType, FILE **fd,
uint64_t fsize) {
@ -335,7 +306,7 @@ int eraseAndWriteToFlash(char *mess, enum PROGRAM_INDEX index,
}
if (index == PROGRAM_FPGA) {
if (FPGAdontTouchFlash(mess) == FAIL) {
if (FPGAdontTouchFlash(mess, 1) == FAIL) {
return FAIL;
}
}
@ -564,14 +535,14 @@ int writeToFlash(char *mess, ssize_t fsize, FILE *flashfd, FILE *srcfd) {
int waitForFPGAtoTouchFlash(char *mess) {
// touch and program
if (FPGATouchFlash(mess) == FAIL) {
if (FPGATouchFlash(mess, 1) == FAIL) {
return FAIL;
}
#ifdef VIRTUAL
return OK;
#endif
LOG(logINFO, ("\tWaiting for FPGA to program from flash\n"));
LOG(logINFO, ("\tWaiting for FPGA to program from flash... \n\t[gpio7 (CD) should be High when done]\n"));
int timeSpent = 0;
int result = 0;
@ -609,8 +580,8 @@ int waitForFPGAtoTouchFlash(char *mess) {
LOG(logERROR, (mess));
return FAIL;
}
LOG(logDEBUG1, ("gpi07 returned %d\n", result));
LOG(logDEBUG1, ("gpi07 (CD)returned %d\n", result));
}
LOG(logINFO, ("\tFPGA has picked up the program from flash\n"));
LOG(logINFO, ("\tFPGA has picked up the program from flash. gpio7 (CD) is High\n"));
return OK;
}

View File

@ -20,6 +20,7 @@ typedef struct Memory {
pthread_mutex_t lockStatus;
#ifdef EIGERD
pthread_mutex_t lockLocalLink;
pthread_mutex_t lockAcqFlag;
#endif
enum runStatus scanStatus; // idle, running or error
int scanStop;
@ -120,6 +121,7 @@ int sharedMemory_initialize() {
#endif
#ifdef EIGERD
// local link mutex
pthread_mutexattr_t lockLocalLinkAttribute;
if (pthread_mutexattr_init(&lockLocalLinkAttribute) != 0) {
LOG(logERROR,
@ -141,6 +143,28 @@ int sharedMemory_initialize() {
"shared memory\n"));
return FAIL;
}
// acq flag mutex
pthread_mutexattr_t lockAcqFlagAttribute;
if (pthread_mutexattr_init(&lockAcqFlagAttribute) != 0) {
LOG(logERROR,
("Failed to initialize mutex attribute for lockAcqFlag for "
"shared memory\n"));
return FAIL;
}
if (pthread_mutexattr_setpshared(&lockAcqFlagAttribute,
PTHREAD_PROCESS_SHARED) != 0) {
LOG(logERROR, ("Failed to set attribute property to process shared for "
"lockAcqFlag for shared memory\n"));
return FAIL;
}
if (pthread_mutex_init(&(shm->lockAcqFlag), &lockAcqFlagAttribute) !=
0) {
LOG(logERROR, ("Failed to initialize pthread_mutex_t lockAcqFlag for "
"shared memory\n"));
return FAIL;
}
#endif
shm->scanStatus = IDLE;
shm->scanStop = 0;
@ -266,4 +290,10 @@ void sharedMemory_lockLocalLink() { pthread_mutex_lock(&(shm->lockLocalLink)); }
void sharedMemory_unlockLocalLink() {
pthread_mutex_unlock(&(shm->lockLocalLink));
}
void sharedMemory_lockAcqFlag() { pthread_mutex_lock(&(shm->lockAcqFlag)); }
void sharedMemory_unlockAcqFlag() {
pthread_mutex_unlock(&(shm->lockAcqFlag));
}
#endif

View File

@ -1499,7 +1499,7 @@ int write_register(int file_des) {
} else {
if (readRegister(addr, &retval) == FAIL) {
ret = FAIL;
sprintf(mess, "Could not read register 0x%x.\n", addr);
sprintf(mess, "Could not read register 0x%x or inconsistent values. Try to read +0x100 for only left and +0x200 for only right.\n", addr);
LOG(logERROR, (mess));
}
}
@ -1537,7 +1537,7 @@ int read_register(int file_des) {
#elif EIGERD
if (readRegister(addr, &retval) == FAIL) {
ret = FAIL;
sprintf(mess, "Could not read register 0x%x.\n", addr);
sprintf(mess, "Could not read register 0x%x or inconsistent values. Try +0x100 for only left and +0x200 for only right..\n", addr);
LOG(logERROR, (mess));
}
#else
@ -1909,9 +1909,6 @@ void *start_state_machine(void *arg) {
}
usleep(scanSettleTime_ns / 1000);
}
#ifdef EIGERD
prepareAcquisition();
#endif
ret = startStateMachine();
LOG(logDEBUG2, ("Starting Acquisition ret: %d\n", ret));
if (ret == FAIL) {
@ -2984,6 +2981,10 @@ int validateAndSetAllTrimbits(int arg) {
LOG(logERROR, (mess));
} else {
ret = setAllTrimbits(arg);
if (ret == FAIL) {
strcpy(mess, "Could not set all trimbits\n");
LOG(logERROR, (mess));
}
#ifdef EIGERD
// changes settings to undefined
if (getSettings() != UNDEFINED) {
@ -4143,13 +4144,7 @@ int copy_detector_server(int file_des) {
LOG(logINFOBLUE, ("Copying server %s from host %s\n", sname, hostname));
char cmd[MAX_STR_LENGTH] = {0};
#ifdef BLACKFIN_DEFINED
// check update is allowed (Non Amd OR AMD + current kernel)
ret = allowUpdate(mess, "copy detector server");
#endif
// tftp server
if (ret == OK) {
if (snprintf(cmd, MAX_STR_LENGTH, "tftp %s -r %s -g", hostname,
sname) >= MAX_STR_LENGTH) {
ret = FAIL;
@ -4165,7 +4160,6 @@ int copy_detector_server(int file_des) {
} else {
LOG(logINFO, ("\tServer copied\n"));
}
}
if (ret == OK) {
ret = setupDetectorServer(mess, sname);
@ -9403,16 +9397,6 @@ void receive_program_via_blackfin(int file_des, enum PROGRAM_INDEX index,
functionType);
LOG(logERROR, (mess));
#else
// only when writing to kernel flash or root directory
if (index != PROGRAM_FPGA) {
// check update is allowed (Non Amd OR AMD + current kernel)
ret = allowUpdate(mess, functionType);
if (ret == FAIL) {
Server_SendResult(file_des, INT32, NULL, 0);
return;
}
}
// open file and allocate memory for part program
FILE *fd = NULL;
ret = preparetoCopyProgram(mess, functionType, &fd, filesize);
@ -9632,12 +9616,6 @@ int set_update_mode(int file_des) {
return printSocketReadError();
LOG(logDEBUG1, ("Setting update mode to \n", arg));
#ifdef BLACKFIN_DEFINED
// check update is allowed (Non Amd OR AMD + current kernel)
ret = allowUpdate(mess, "set/unset update mode");
#endif
if (ret == OK) {
switch (arg) {
case 0:
ret = deleteFile(mess, UPDATE_FILE, "unset update mode");
@ -9651,7 +9629,6 @@ int set_update_mode(int file_des) {
LOG(logERROR, (mess));
break;
}
}
return Server_SendResult(file_des, INT32, NULL, 0);
}

View File

@ -780,7 +780,39 @@ void Detector::startDetectorReadout() {
}
void Detector::stopDetector(Positions pos) {
// stop and check status X times
int retries{0};
//avoid default construction of runStatus::IDLE on squash
auto status = getDetectorStatus().squash(defs::runStatus::RUNNING);
while(status != defs::runStatus::IDLE){
pimpl->Parallel(&Module::stopAcquisition, pos);
status = getDetectorStatus().squash(defs::runStatus::RUNNING);
++retries;
if(retries == 10)
throw RuntimeError("Could not stop detector");
}
// validate consistent frame numbers
switch (getDetectorType().squash()) {
case defs::EIGER:
case defs::JUNGFRAU:
case defs::MOENCH:
case defs::CHIPTESTBOARD: {
auto res = getNextFrameNumber(pos);
if (!res.equal()) {
uint64_t maxVal = 0;
for (auto it : res) {
maxVal = std::max(maxVal, it);
}
setNextFrameNumber(maxVal + 1);
}
} break;
default:
break;
}
}
Result<defs::runStatus> Detector::getDetectorStatus(Positions pos) const {

View File

@ -1,15 +1,15 @@
// SPDX-License-Identifier: LGPL-3.0-or-other
// Copyright (C) 2021 Contributors to the SLS Detector Package
/** API versions */
#define GITBRANCH "6.1.1"
#define GITBRANCH "6.1.2"
#define APILIB 0x211125
#define APIRECEIVER 0x211125
#define APIGUI 0x211125
#define APICTB 0x211125
#define APIGOTTHARD 0x211125
#define APIGOTTHARD2 0x211125
#define APIMYTHEN3 0x211125
#define APIMOENCH 0x211124
#define APIEIGER 0x211125
#define APIJUNGFRAU 0x220104
#define APILIB 0x221125
#define APIRECEIVER 0x211125
#define APIGUI 0x211125
#define APIEIGER 0x211125