Compare commits

...

27 Commits

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
da8e0060d3 updated release notes and project version 2022-01-04 10:44:07 +01:00
85da65ca15 update versioning (prev commit) 2022-01-04 10:38:45 +01:00
4fe067363a This commit fixes the issue #336
A delay of 100ms has been added between the generation of the stop pulse and the resetCore function call. This should give enough time to the detector to readout and streamout the ongoing frame before the internal logic is reset (even after the transmission is delayed with txndelay_frame).

Conflicts:
	slsDetectorServers/jungfrauDetectorServer/bin/jungfrauDetectorServerv6.1.0
2022-01-04 10:37:57 +01:00
36 changed files with 4782 additions and 1703 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.0)
set(PROJECT_VERSION 6.1.2)
set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG")

View File

@ -1,170 +1,158 @@
SLS Detector Package Minor Release 6.1.0 released on 25.11.2021
SLS Detector Package Patch Release 6.1.2 released on 25.11.2022
===============================================================
This document describes the differences between v6.1.0 and v6.0.0.
This document describes the differences between v6.1.2 and v6.1.1.
CONTENTS
--------
1. New or Changed Features
2. Resolved Issues
3. Firmware Requirements
4. Kernel Requirements
5. Download, Documentation & Support
1. Resolved Issues
2. On-board Detector Server Compatibility
2. Firmware Requirements
3. Kernel Requirements
4. Download, Documentation & Support
1. New or Changed Features
==========================
Client
------
1. Kernel version
Commandline: kernelversion, API: getKernelVersion
2. [Jungfrau][Mythen3][Gotthard2][Gotthard][Moench][Ctb]
Update Kernel
Commandline: updatekernel, API: updatekernel
You could damage the detector. Please use with caution.
3. Update Detector Server (no tftp)
Commandline: updatedetectorserver, API: updateDetectorServer
Updates the detector server without using tftp. It also creates a
symbolic link to a shorter name and reboots. The API using tftp
(copydetectorserver) is deprecated.
4. Update Firmware and Server (no tftp)
Commandline: update (fewer arguments), API: updateFirmwareAndServer
(overloaded) Same as before, except the server is transferred to the
detector without tftp. The previous API and command (fewer arguments)
using tftp is deprecated.
5. Update mode in Detector server
Commandline: udpatemode, API set/getUpdateMode
One can set detector server to update mode (especially if server and
firmware are incompatible that the server cannot start up without errors).
This mode will limit access to a few operations only needed to update the
detector. Setting it will create an empty file (udpate.txt) and resetting
it will delete the empty file. Ofcourse, command line "--update" will
overwrite any file detection and start server in update mode.
Detector Server
---------------
1. [Gotthard2] speed
Ensuring dbitpipeline is default when changing speed. This has an effect
only if dbitpipeline was changed in between.
2. Resolved Issues
1. Resolved Issues
==================
Detector Server
---------------
1. [Jungfrau][Moench][Ctb] Programming Firmware Failures
Firmware programming via software failures are fixed using a new kernel
and corresponding changes in server software. Software works with both
old and new kernels.
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.
2. [Gotthard2][Mythen3]
Verifies kernel version at server start up.
Updating the on-board detector server to this version is recommended
before updating firmware for future releases.
3. [Jungfrau]
Verifies HW2.0 before trying to set read n rows or flip rows.
Has no effect when not using slsReceiver.
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.
4. [Eiger]
Thresholdnotb command loads threshold energy without trimbits, but had
a bug in the server that was setting nchip to 0 and further trimval or
trim commands would no work reliably. This is fixed now.
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. Receiver Id in the commands in config files were ignored. Fixed.
1. [Eiger] Stop command freezes server
It is apparent in large detectors.
2. Execute command now also mentions which module failed.
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.
3. [Jungfrau][Moench][Ctb]
Programming firmware procedure did not delete temporary file created in
6.0.0. Fixed.
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.
Receiver
--------
1. Setting receiver hostname to "none" threw an exception. Fixed.
Python
------
2. [Jungfrau]
Since the server verifies HW2.0 for number of rows before trying to set it,
the receiver now does not show incorrect missing packets stemming from this
issue.
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
========================
Eiger
=====
Compatible version : 08.10.2021 (v29)
Note: No change to 6.1.1.
Jungfrau
========
Compatible version : 31.08.2021 (v1.2, PCB v1.0)
: 08.10.2021 (v2.2, PCB v2.0)
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)
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
4. Kernel Requirements
======================
Note: No change to 6.1.1.
Blackfin
========
Latest version: Fri Oct 29 00:00:00 2021

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.0

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,12 +1059,28 @@ int Feb_Control_StopAcquisition() {
break;
check_error++;
} // reset check_error for next time
else
else {
check_error = 0;
}
// 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 0;
}
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

@ -2646,6 +2646,7 @@ int stopStateMachine() {
LOG(logINFO, ("Status Register: %08x\n", bus_r(STATUS_REG)));
usleep(100 * 1000);
resetCore();
return OK;
}

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,28 +4144,21 @@ 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;
strcpy(mess, "Could not copy detector server. Command to copy "
"server too long\n");
LOG(logERROR, (mess));
} else if (executeCommand(cmd, retvals, logDEBUG1) == FAIL) {
ret = FAIL;
snprintf(mess, MAX_STR_LENGTH,
"Could not copy detector server (tftp). %s\n",
retvals);
// LOG(logERROR, (mess)); already printed in executecommand
} else {
LOG(logINFO, ("\tServer copied\n"));
}
if (snprintf(cmd, MAX_STR_LENGTH, "tftp %s -r %s -g", hostname,
sname) >= MAX_STR_LENGTH) {
ret = FAIL;
strcpy(mess, "Could not copy detector server. Command to copy "
"server too long\n");
LOG(logERROR, (mess));
} else if (executeCommand(cmd, retvals, logDEBUG1) == FAIL) {
ret = FAIL;
snprintf(mess, MAX_STR_LENGTH,
"Could not copy detector server (tftp). %s\n",
retvals);
// LOG(logERROR, (mess)); already printed in executecommand
} else {
LOG(logINFO, ("\tServer copied\n"));
}
if (ret == OK) {
@ -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,25 +9616,18 @@ 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");
break;
case 1:
ret = createEmptyFile(mess, UPDATE_FILE, "set update mode");
break;
default:
ret = FAIL;
sprintf(mess, "Could not set updatemode. Options: 0 or 1\n");
LOG(logERROR, (mess));
break;
}
switch (arg) {
case 0:
ret = deleteFile(mess, UPDATE_FILE, "unset update mode");
break;
case 1:
ret = createEmptyFile(mess, UPDATE_FILE, "set update mode");
break;
default:
ret = FAIL;
sprintf(mess, "Could not set updatemode. Options: 0 or 1\n");
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) {
pimpl->Parallel(&Module::stopAcquisition, 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.0"
#define GITBRANCH "6.1.2"
#define APILIB 0x211125
#define APIRECEIVER 0x211125
#define APIGUI 0x211125
#define APICTB 0x211125
#define APIGOTTHARD 0x211125
#define APIGOTTHARD2 0x211125
#define APIJUNGFRAU 0x211125
#define APIMYTHEN3 0x211125
#define APIMOENCH 0x211124
#define APIJUNGFRAU 0x220104
#define APILIB 0x221125
#define APIRECEIVER 0x211125
#define APIGUI 0x211125
#define APIEIGER 0x211125