Adding more servos
[inav.git] / src / main / config / parameter_group.c
blob997fddb8eff389dbf1d49f3e9ece6fce33f328ff
1 /*
2 * This file is part of Cleanflight.
4 * Cleanflight is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
9 * Cleanflight is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with Cleanflight. If not, see <http://www.gnu.org/licenses/>.
18 #include <stddef.h>
19 #include <string.h>
20 #include <stdint.h>
22 #include "platform.h"
24 #include "parameter_group.h"
25 #include "common/maths.h"
27 const pgRegistry_t* pgFind(pgn_t pgn)
29 PG_FOREACH(reg) {
30 if (pgN(reg) == pgn) {
31 return reg;
34 return NULL;
37 static uint8_t *pgOffset(const pgRegistry_t* reg, uint8_t profileIndex)
39 const uint16_t regSize = pgSize(reg);
41 uint8_t *base = reg->address;
42 if (!pgIsSystem(reg)) {
43 base += (regSize * profileIndex);
45 return base;
48 static void pgResetInstance(const pgRegistry_t *reg, uint8_t *base)
50 const uint16_t regSize = pgSize(reg);
52 memset(base, 0, regSize);
53 if (reg->reset.ptr >= (void*)__pg_resetdata_start && reg->reset.ptr < (void*)__pg_resetdata_end) {
54 // pointer points to resetdata section, to it is data template
55 memcpy(base, reg->reset.ptr, regSize);
56 } else if (reg->reset.fn) {
57 // reset function, call it
58 reg->reset.fn(base);
62 void pgReset(const pgRegistry_t* reg, int profileIndex)
64 pgResetInstance(reg, pgOffset(reg, profileIndex));
67 void pgResetCurrent(const pgRegistry_t *reg)
69 if (pgIsSystem(reg)) {
70 pgResetInstance(reg, reg->address);
71 } else {
72 pgResetInstance(reg, *reg->ptr);
76 bool pgResetCopy(void *copy, pgn_t pgn)
78 const pgRegistry_t *reg = pgFind(pgn);
79 if (reg) {
80 pgResetInstance(reg, copy);
81 return true;
83 return false;
86 void pgLoad(const pgRegistry_t* reg, int profileIndex, const void *from, int size, int version)
88 pgReset(reg, profileIndex);
89 // restore only matching version, keep defaults otherwise
90 if (version == pgVersion(reg)) {
91 const int take = MIN(size, pgSize(reg));
92 memcpy(pgOffset(reg, profileIndex), from, take);
96 int pgStore(const pgRegistry_t* reg, void *to, int size, uint8_t profileIndex)
98 const int take = MIN(size, pgSize(reg));
99 memcpy(to, pgOffset(reg, profileIndex), take);
100 return take;
104 void pgResetAll(int profileCount)
106 PG_FOREACH(reg) {
107 if (pgIsSystem(reg)) {
108 pgReset(reg, 0);
109 } else {
110 // reset one instance for each profile
111 for (int profileIndex = 0; profileIndex < profileCount; profileIndex++) {
112 pgReset(reg, profileIndex);
118 void pgActivateProfile(int profileIndex)
120 PG_FOREACH(reg) {
121 if (!pgIsSystem(reg)) {
122 uint8_t *ptr = pgOffset(reg, profileIndex);
123 *(reg->ptr) = ptr;