ChimeraTK-DeviceAccess 03.29.00
Loading...
Searching...
No Matches
GenericMuxedInterruptDistributor.h
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Deutsches Elektronen-Synchrotron DESY, MSK, ChimeraTK Project <chimeratk-support@desy.de>
2// SPDX-License-Identifier: LGPL-3.0-or-later
3#pragma once
4#include "../NDRegisterAccessor.h"
5#include "../RegisterPath.h"
7
8#include <atomic>
9#include <bitset>
10#include <chrono>
11#include <map>
12#include <memory>
13#include <thread>
14
15namespace ChimeraTK::async {
16
18 ISR = 0, // Interrupt Status Register
19 IER, // Interrupt Enable Register
20 MER, // Master Enable Register,
21 MIE, // Master Interrupt Enable Functionally equivalent to MER
22 GIE, // Global Interrupt Enable, Functionally equivalent to MER
23 ICR, // Interrupt Clear Register
24 IAR, // Interrupt Acknowledge Register
25 IPR, // Interrupt Pending Register =ISR & IER, a convenience feature for software.
26 SIE, // Set Interrupt Enable
27 CIE, // Clear Interrupt Enable
28 IMaskR, // Interrupt Mask Register. IMR Acronym Collision. Temporarily not allowed. See
29 IModeR, // Interrupt Mode Register. IMR Acronym Collision, defined in the standard but not allowed; REMOVE?
30 IVR, // defined in the standard but not allowed; REMOVE?
31 ILR, // defined in the standard but not allowed; REMOVE?
32 IVAR, // defined in the standard but not allowed; REMOVE?
33 IVEAR, // defined in the standard but not allowed; REMOVE?
34 OPTION_CODE_COUNT, // used for counting how many valid enums there are here & setting list lengths
36 };
37
38 /********************************************************************************************************************/
39
41 public:
42 explicit GenericMuxedInterruptDistributor(const boost::shared_ptr<SubDomain<std::nullptr_t>>& parent,
43 const std::string& registerPath, std::bitset<(ulong)GmidOptionCode::OPTION_CODE_COUNT> optionRegisterSettings);
45
49 void handle(VersionNumber version) override;
50
51 void activate(VersionNumber version) override;
52
58 static std::unique_ptr<GenericMuxedInterruptDistributor> create(std::string const& description, // THE JSON SNIPPET
59 const boost::shared_ptr<SubDomain<std::nullptr_t>>& parent);
60
61 protected:
64 bool _hasMer;
65 uint32_t _activeInterrupts{0}; // like a local copy of IER
66
67 boost::shared_ptr<NDRegisterAccessor<uint32_t>> _isr;
68 boost::shared_ptr<NDRegisterAccessor<uint32_t>> _ier; // May point to IER or Imaskr
69 boost::shared_ptr<NDRegisterAccessor<uint32_t>> _icr; // May point to ICR, IAR, or ISR, which act identically
70 boost::shared_ptr<NDRegisterAccessor<uint32_t>> _mer; // May point to MER, MIE, or GIE, all act identically.
71 // We can have at most 1 of {MIE, GIE, MER}
72 boost::shared_ptr<NDRegisterAccessor<uint32_t>> _sie; // We either have both SIE or CIE or neither.
73 boost::shared_ptr<NDRegisterAccessor<uint32_t>> _cie;
74
75 RegisterPath _path; // just a string path, with the added overwritten / operator etc.
76
79 std::atomic<bool> _handlerRan{false};
80
82 std::atomic<bool> _watchdogAlerted{false};
83
85 std::thread _watchdogThread;
86 std::atomic<bool> _stopWatchdog{false};
88 static constexpr std::chrono::milliseconds _watchdogInterval{1000};
89
91 void watchdogLoop();
92
98 void clearInterruptsFromMask(uint32_t mask);
99
100 inline void clearOneInterrupt(uint32_t ithInterrupt);
101
102 inline void clearAllInterrupts();
103
104 inline void clearAllEnabledInterrupts();
105
110 void disableInterruptsFromMask(uint32_t mask);
111
112 inline void disableOneInterrupt(uint32_t ithInterrupt);
113
118 void enableInterruptsFromMask(uint32_t mask);
119
120 inline void enableOneInterrupt(uint32_t ithInterrupt);
121
122 void activateSubDomain(SubDomain<std::nullptr_t>& subDomain, VersionNumber const& version) override;
123 };
124
125} // namespace ChimeraTK::async
Class to store a register path name.
Class for generating and holding version numbers without exposing a numeric representation.
std::atomic< bool > _handlerRan
Set true by handle() after each completed run.
void clearInterruptsFromMask(uint32_t mask)
In mask, 1 bits clear the corresponding registers, 0 bits do nothing.
void enableInterruptsFromMask(uint32_t mask)
For each bit in mask that is a 1, the corresponding interrupt gets enabled, and the internal copy of ...
static constexpr std::chrono::milliseconds _watchdogInterval
Watchdog polling/decision interval (experimental)
void disableInterruptsFromMask(uint32_t mask)
Disables each interrupt corresponding to the 1 bits in mask, and updates _activeInterrupts.
boost::shared_ptr< NDRegisterAccessor< uint32_t > > _ier
boost::shared_ptr< NDRegisterAccessor< uint32_t > > _cie
std::atomic< bool > _watchdogAlerted
Set true once the watchdog has raised a device exception.
boost::shared_ptr< NDRegisterAccessor< uint32_t > > _isr
boost::shared_ptr< NDRegisterAccessor< uint32_t > > _sie
void handle(VersionNumber version) override
Handle gets called when a trigger comes in.
void activateSubDomain(SubDomain< std::nullptr_t > &subDomain, VersionNumber const &version) override
Function to activate a (new) single SubDomain if the MuxedInterruptDistributor is already active.
boost::shared_ptr< NDRegisterAccessor< uint32_t > > _icr
boost::shared_ptr< NDRegisterAccessor< uint32_t > > _mer
std::thread _watchdogThread
Watchdog thread and its stop flag.
static std::unique_ptr< GenericMuxedInterruptDistributor > create(std::string const &description, const boost::shared_ptr< SubDomain< std::nullptr_t > > &parent)
Create parses the json configuration snippet 'description', and calls the constructor.
Interface base class for interrupt controller handlers.
Send backend-specific asynchronous data to different distributors:
Definition SubDomain.h:33