-
Notifications
You must be signed in to change notification settings - Fork 9
Expand file tree
/
Copy pathconfig.cpp
More file actions
122 lines (100 loc) · 3.97 KB
/
config.cpp
File metadata and controls
122 lines (100 loc) · 3.97 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
/*
* Flybrix Flight Controller -- Copyright 2018 Flying Selfie Inc. d/b/a Flybrix
*
* http://www.flybrix.com
*/
#include "config.h"
#include "systems.h"
#include "eepromcursor.h"
// Default Config ID
ConfigID::ConfigID() : ConfigID{0} {
}
Config::Config() { // Default Settings
// This function will only initialize data variables
// data needs to be written manually to the EEPROM
}
template <std::size_t field>
inline decltype(std::get<field>(Config::Data())) & systemMapping(Systems& sys);
// Maps a subsystem configuration to a flag, whereby we state the subsystem we're mapping to
#define MAP_SYSTEM(name, type, variable) \
template <> \
inline type& systemMapping<Config::name>(Systems & sys) { \
return sys.variable; \
}
MAP_SYSTEM(VERSION, Version, version);
MAP_SYSTEM(ID, ConfigID, id);
MAP_SYSTEM(PCB, PcbTransform, imu.pcb_transform);
MAP_SYSTEM(MIX_TABLE, Airframe::MixTable, pilot.mix_table());
MAP_SYSTEM(MAG_BIAS, AK8963::MagBias, imu.magnetometer_bias());
MAP_SYSTEM(CHANNEL, Receiver::ChannelProperties, radioReceiver().channel);
MAP_SYSTEM(PID_PARAMETERS, Control::PIDParameters, control.pid_parameters);
MAP_SYSTEM(STATE_PARAMETERS, State::Parameters, state.parameters);
MAP_SYSTEM(LED_STATES, LED::States, led.states);
MAP_SYSTEM(DEVICE_NAME, DeviceName, name);
MAP_SYSTEM(VELOCITY_PID_PARAMETERS, Control::VelocityPIDParameters, control.velocity_pid_parameters);
MAP_SYSTEM(INERTIAL_BIAS, Imu::InertialBias, imu.bias);
#undef MAP_SYSTEM
bool isEmptyEEPROM() {
return EEPROM.read(0) == 255;
}
Config readEEPROM() {
Config CONFIG;
if (isEmptyEEPROM()) {
// No EEPROM values detected, re-initialize to default values
Config().writeTo(EEPROMCursor()); // store the default values
CONFIG = readEEPROM();
} else {
CONFIG.readFrom(EEPROMCursor());
// Verify version and general settings
if (!CONFIG.verify()) {
// If the stored configuration isn't legal in any way, report it
// via debug and reset it
Config().writeTo(EEPROMCursor()); // store the default values
CONFIG = readEEPROM();
}
}
return CONFIG;
}
// No need to modify anything below this line
template <std::size_t I = 0, typename... Tp>
inline typename std::enable_if<I == sizeof...(Tp), void>::type applyFieldsTo(const std::tuple<Tp...>& t, Systems& systems) {
}
template <std::size_t I = 0, typename... Tp>
inline typename std::enable_if < I<sizeof...(Tp), void>::type applyFieldsTo(const std::tuple<Tp...>& t, Systems& systems) {
systemMapping<I>(systems) = std::get<I>(t);
applyFieldsTo<I + 1, Tp...>(t, systems);
systems.parseConfig();
}
template <std::size_t I = 0, typename... Tp>
inline typename std::enable_if<I == sizeof...(Tp), void>::type setFieldsFrom(std::tuple<Tp...>& t, Systems& systems) {
}
template <std::size_t I = 0, typename... Tp>
inline typename std::enable_if < I<sizeof...(Tp), void>::type setFieldsFrom(std::tuple<Tp...>& t, Systems& systems) {
std::get<I>(t) = systemMapping<I>(systems);
setFieldsFrom<I + 1, Tp...>(t, systems);
}
Config::Config(Systems& sys) {
setFieldsFrom(data, sys);
}
void Config::resetPartial(uint16_t submask, uint16_t led_mask) {
resetFields(data, submask, led_mask);
}
void Config::applyTo(Systems& systems) const {
applyFieldsTo(data, systems);
}
template <class T>
inline bool verifyArg(T& var) {
return var.verify();
}
template <std::size_t I = 0, typename... Tp>
inline typename std::enable_if<I == sizeof...(Tp), bool>::type verifyArgs(const std::tuple<Tp...>& t) {
return true;
}
template <std::size_t I = 0, typename... Tp>
inline typename std::enable_if < I<sizeof...(Tp), bool>::type verifyArgs(const std::tuple<Tp...>& t) {
bool ok{verifyArg(std::get<I>(t))};
return verifyArgs<I + 1, Tp...>(t) && ok;
}
bool Config::verify() const {
return verifyArgs(data);
}