SatCat5
cfgbus_led.cc
1 // Copyright 2021-2023 The Aerospace Corporation.
3 // This file is a part of SatCat5, licensed under CERN-OHL-W v2 or later.
5 
6 #include <satcat5/cfgbus_led.h>
7 #include <satcat5/cfgbus_stats.h>
8 
14 
15 // Sinusoidal "breathing" pattern (32 points)
16 static const u8 SINE_ARRAY[] = {
17  0x00, 0x02, 0x09, 0x15, 0x25, 0x38, 0x4E, 0x66,
18  0x7F, 0x98, 0xB0, 0xC6, 0xD9, 0xE9, 0xF5, 0xFC,
19  0xFF, 0xFC, 0xF5, 0xE9, 0xD9, 0xC6, 0xB0, 0x98,
20  0x7F, 0x66, 0x4E, 0x38, 0x25, 0x15, 0x09, 0x02};
21 
22 LedArray::LedArray(satcat5::cfg::ConfigBus* cfg,
23  unsigned devaddr, unsigned count)
24  : m_reg(cfg->get_register(devaddr, 0))
25  , m_count(count)
26 {
27  // Turn all LEDs off on startup.
28  for (unsigned a = 0 ; a < m_count ; ++a)
29  m_reg[a] = 0;
30 }
31 
32 u8 LedArray::get(unsigned idx)
33 {
34  if (idx < m_count)
35  return (u8)m_reg[idx];
36  else
37  return 0;
38 }
39 
40 void LedArray::set(unsigned idx, u8 brt)
41 {
42  if (idx < m_count)
43  m_reg[idx] = (u32)brt;
44 }
45 
47  unsigned devaddr, unsigned regaddr, unsigned stats_idx, u8 brt)
48  : m_reg(cfg->get_register(devaddr, regaddr))
49  , m_stats_idx(stats_idx)
50  , m_brt(brt)
51  , m_state(0)
52  , m_next(0)
53 {
54  // No other initialization required.
55 }
56 
58 {
59  // Minimum activity-LED "blink" time (in 1/30th second increments)
60  static const unsigned ACTIVITY_SUSTAIN = 3;
61 
62  // New activity since last update?
63  const satcat5::cfg::TrafficStats port = stats->get_port(m_stats_idx);
64  u32 active = port.rcvd_frames + port.sent_frames;
65 
66  // Update LED based on new and recent activity:
67  if (m_state > ACTIVITY_SUSTAIN) {
68  // Turn LED back on after "winking".
69  m_state = ACTIVITY_SUSTAIN; *m_reg = m_brt;
70  } else if (active && m_state > 0) {
71  // New activity with LED on -> Wink off.
72  m_state = ACTIVITY_SUSTAIN + 1; *m_reg = 0;
73  } else if (active) {
74  // New activity with LED off -> LED on.
75  m_state = ACTIVITY_SUSTAIN; *m_reg = m_brt;
76  } else if (m_state > 0) {
77  // Hold LED on until countdown reaches zero.
78  --m_state; *m_reg = m_brt;
79  } else {
80  // No recent activity.
81  *m_reg = 0;
82  }
83 }
84 
87  unsigned delay_msec)
88  : m_stats(stats)
89 {
90  timer_every(delay_msec);
91 }
92 
94 {
95  // Refresh the NetworkStats object.
96  m_stats->refresh_now();
97 
98  // Ask each registered LED to update.
99  LedActivity* item = m_list.head();
100  while (item) {
101  item->update(m_stats);
102  item = m_list.next(item);
103  }
104 }
105 
107  unsigned devaddr, unsigned regaddr, u8 brt)
108  : m_reg(cfg->get_register(devaddr, regaddr))
109  , m_brt(brt)
110  , m_phase(0)
111  , m_next(0)
112 {
113  // No other initialization required.
114 }
115 
116 void LedWave::update(u32 incr)
117 {
118  // Increment phase, then index into lookup table [0..31]
119  m_phase += incr;
120  u8 tbl = SINE_ARRAY[m_phase >> 27];
121  // Scale based on user brightness parameter.
122  *m_reg = (((u32)tbl * (u32)m_brt) >> 8);
123 }
124 
125 LedWaveCtrl::LedWaveCtrl()
126  : m_incr(0)
127 {
128  // No other initialization required.
129 }
130 
131 void LedWaveCtrl::start(unsigned delay)
132 {
133  // Set initial phase for each LED so they are equally spaced.
134  unsigned count = m_list.len();
135  u32 phase = 0, delta = UINT32_MAX / count;
136 
137  LedWave* item = m_list.head();
138  while (item) {
139  item->update(phase);
140  phase += delta;
141  item = m_list.next(item);
142  }
143 
144  // Timer parameters give a full cycle every 2.0 seconds.
145  m_incr = UINT32_MAX / 100; // Phase increment per update
146  timer_every(delay); // Updates at specified interval
147 }
148 
150 {
151  timer_stop();
152 }
153 
155 {
156  // Forward timer event to each LED.
157  LedWave* item = m_list.head();
158  while (item) {
159  item->update(m_incr);
160  item = m_list.next(item);
161  }
162 }
ConfigBus-controlled PWM LEDs and animation functions.
Generic ConfigBus API.
Definition: cfgbus_core.h:124
Coordinate multiple LedActivity objects.
Definition: cfgbus_led.h:68
LedActivityCtrl(satcat5::cfg::NetworkStats *stats, unsigned delay_msec=33)
Link this controller to an activity source.
Definition: cfgbus_led.cc:85
void timer_event() override
Child class MUST override this method.
Definition: cfgbus_led.cc:93
Single-LED controller for a network-activity light.
Definition: cfgbus_led.h:46
LedActivity(satcat5::cfg::ConfigBus *cfg, unsigned devaddr, unsigned regaddr, unsigned stats_idx, u8 brt=128)
Link to a specific LED.
Definition: cfgbus_led.cc:46
void update(satcat5::cfg::NetworkStats *stats)
Callback object for LedActivityCtrl.
Definition: cfgbus_led.cc:57
Basic LED array with direct user control of each intensity value.
Definition: cfgbus_led.h:24
const unsigned m_count
Number of LEDs.
Definition: cfgbus_led.h:40
u8 get(unsigned idx)
Get brightness of the Nth LED.
Definition: cfgbus_led.cc:32
satcat5::cfg::Register m_reg
Base control register.
Definition: cfgbus_led.h:39
void set(unsigned idx, u8 brt)
Set brightness of the Nth LED.
Definition: cfgbus_led.cc:40
Coordinate multiple LedWave objects.
Definition: cfgbus_led.h:106
void timer_event() override
Child class MUST override this method.
Definition: cfgbus_led.cc:154
void stop()
Stop wave animation.
Definition: cfgbus_led.cc:149
void start(unsigned delay=20)
Animation controls.
Definition: cfgbus_led.cc:131
Single-LED controller for a "Breathing" or "Wave" pattern.
Definition: cfgbus_led.h:88
LedWave(satcat5::cfg::ConfigBus *cfg, unsigned devaddr, unsigned regaddr, u8 m_brt=128)
Link to a specific LED.
Definition: cfgbus_led.cc:106
void update(u32 incr)
Callback object for LedWaveCtrl.
Definition: cfgbus_led.cc:116
Traffic statistics polling.
Definition: cfgbus_stats.h:49
satcat5::cfg::TrafficStats get_port(unsigned idx)
Read most recent statistics for the Nth port.
Definition: cfgbus_stats.cc:36
void refresh_now()
Immediately refresh statistics for every port.
Definition: cfgbus_stats.cc:31
void timer_stop()
Stop all future notifications.
Definition: polling.cc:326
void timer_every(unsigned msec)
Configure a repeating notification every X milliseconds.
Definition: polling.cc:321
Data structure for reading per-port traffic statistics.
Definition: cfgbus_stats.h:19