Merge pull request #1269 from pkendall64/crsf-max-output
[ExpressLRS.git] / src / lib / LQCALC / LQCALC.h
blob7e701928ca0adadcdc76f5f2015b46e13a83ebde
1 #pragma once
3 #include <stdint.h>
5 template <uint8_t N>
6 class LQCALC
8 public:
9 LQCALC(void)
11 reset();
12 // count is reset here only once on construction to start LQ counting
13 // at 100% on first connect, but 0 out of N after a failsafe
14 count = 1;
17 /* Set the bit for the current period to true and update the running LQ */
18 void add()
20 if (currentIsSet())
21 return;
22 LQArray[index] |= LQmask;
23 LQ += 1;
26 /* Start a new period */
27 void inc()
29 // Increment the counter by shifting one bit higher
30 // If we've shifted out all the bits, move to next idx
31 LQmask = LQmask << 1;
32 if (LQmask == 0)
34 LQmask = (1 << 0);
35 index += 1;
38 // At idx N / 32 and bit N % 32, wrap back to idx=0, bit=0
39 if ((index == (N / 32)) && (LQmask & (1 << (N % 32))))
41 index = 0;
42 LQmask = (1 << 0);
45 if ((LQArray[index] & LQmask) != 0)
47 LQArray[index] &= ~LQmask;
48 LQ -= 1;
51 if (count < N)
52 ++count;
55 /* Return the current running total of bits set, in percent */
56 uint8_t getLQ() const
58 return (uint32_t)LQ * 100U / count;
61 /* Return the current running total of bits set, up to N */
62 uint8_t getLQRaw() const
64 return LQ;
67 /* Return the number of periods recorded so far, up to N */
68 uint8_t getCount() const
70 return count;
73 /* Return N, the size of the LQ history */
74 uint8_t getSize() const
76 return N;
79 /* Initialize and zero the history */
80 void reset()
82 // count is intentonally not zeroed here to start LQ counting up from 0
83 // after a failsafe, instead of down from 100
84 LQ = 0;
85 index = 0;
86 LQmask = (1 << 0);
87 for (uint8_t i = 0; i < (sizeof(LQArray)/sizeof(LQArray[0])); i++)
88 LQArray[i] = 0;
91 /* Return true if the current period was add()ed */
92 bool currentIsSet() const
94 return LQArray[index] & LQmask;
97 private:
98 uint8_t LQ;
99 uint8_t index; // current position in LQArray
100 uint8_t count;
101 uint32_t LQmask;
102 uint32_t LQArray[(N + 31)/32];