SatCat5
cfgbus_interrupt.cc
1 // Copyright 2021-2024 The Aerospace Corporation.
3 // This file is a part of SatCat5, licensed under CERN-OHL-W v2 or later.
5 // ConfigBus core definitions
6 //
7 // Define a memory-mapped "ConfigBus" interface, based on a base address.
8 // All registers in this interface correspond to volatile pointers.
9 //
10 
11 #include <satcat5/cfgbus_interrupt.h>
12 
14 
15 // Status and command codes for interrupt-control register
16 static constexpr u32 IRQ_DISABLE = 0;
17 static constexpr u32 IRQ_ENABLE = (1u << 0);
18 static constexpr u32 IRQ_REQUEST = (1u << 1);
19 
20 Interrupt::Interrupt(cfg::ConfigBus* cfg)
21  : m_cfg(cfg)
22  , m_ctrl(SATCAT5_NULL_REGISTER)
23  , m_next(0)
24 {
25  cfg->register_irq(this);
26 }
27 
29  cfg::ConfigBus* cfg, unsigned devaddr, unsigned regaddr)
30  : m_cfg(cfg)
31  , m_ctrl(cfg->get_register(devaddr, regaddr))
32  , m_next(0)
33 {
34  cfg->register_irq(this);
35  *m_ctrl = IRQ_ENABLE;
36 }
37 
38 #if SATCAT5_ALLOW_DELETION
39 Interrupt::~Interrupt()
40 {
41  if (!!m_ctrl) *m_ctrl = 0;
42  m_cfg->unregister_irq(this);
43 }
44 #endif
45 
47 {
48  // For nonstandard interfaces, always call irq_event().
49  // Otherwise, prescreen based on the individual request flag.
50  if (!m_ctrl) {
51  irq_event(); // Call designated handler
52  } else if (*m_ctrl & IRQ_REQUEST) {
53  irq_event(); // Call designated handler
54  *m_ctrl = IRQ_ENABLE; // Acknowledge interrupt event
55  }
56 }
57 
59 {
60  if (!!m_ctrl) *m_ctrl = IRQ_ENABLE;
61 }
62 
64 {
65  if (!!m_ctrl) *m_ctrl = IRQ_DISABLE;
66 }
Generic ConfigBus API.
Definition: cfgbus_core.h:124
void unregister_irq(satcat5::cfg::Interrupt *obj)
Remove an interrupt handler.
Definition: cfgbus_core.cc:91
void register_irq(satcat5::cfg::Interrupt *obj)
Add an interrupt handler.
Definition: cfgbus_core.cc:80
Event-handler for individual ConfigBus interrupts.
void irq_disable()
Temporarily disable this interrupt.
Interrupt(satcat5::cfg::ConfigBus *cfg)
Nonstandard constructor.
virtual void irq_event()=0
Interrupt service routine.
void irq_check()
Check if this interrupt may need service.
void irq_enable()
Enable this interrupt.