SatNOGS-COMMS  4.1.0
A COMMS subsystem for CubeSats
Loading...
Searching...
No Matches
settings.hpp
Go to the documentation of this file.
1/*
2 * SatNOGS-COMMS MCU software
3 *
4 * Copyright (C) 2024-2025, Libre Space Foundation <http://libre.space>
5 *
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 *
19 * SPDX-License-Identifier: GNU General Public License v3.0 or later
20 */
21
22#pragma once
23#include "scoped_lock.hpp"
24#include "utils/hash_map.hpp"
25#include <etl/flat_map.h>
28#include <type_traits>
29#include <utility>
30#include <variant>
31#include <zephyr/fs/fs.h>
32#include <zephyr/fs/littlefs.h>
33#include <zephyr/kernel.h>
34#include <zephyr/storage/flash_map.h>
35
36namespace satnogs::comms
37{
38
58
60{
61public:
62 static constexpr uint32_t TRUE_MAGIC = 0xA17E3C5D;
63 static constexpr uint32_t FALSE_MAGIC = 0x0CF18BE2;
70 enum class param : uint16_t
71 {
149 };
150
151 static constexpr std::size_t TABLE_SIZE =
152 static_cast<std::size_t>(param::_COUNT);
153
154 /*AGC1 settings */
155 struct agc1
156 {
157 at86rf215_agc_tgt_t tgt;
158 at86rf215_agc_avgs_t avg;
159 bool input;
160 };
161
162 struct fsk
163 {
164 at86rf215_fsk_srate_t baudrate;
165 float mod_idx;
166 float shaping;
167 };
168
178 template <typename... ExtraTypes> struct basic_param_info
179 {
180 const char *path;
181 std::variant<float, uint32_t, bool, agc1, fsk, lib::rf_frontend::gain_mode,
183 lib::fpga::boot_mode, ExtraTypes...>
186 };
187
189 template <typename T> struct is_param_info : std::false_type
190 {
191 };
192
193 template <typename... Types>
194 struct is_param_info<basic_param_info<Types...>> : std::true_type
195 {
196 };
197
198 template <typename T>
200
203
209 static settings &
211 {
212 static settings instance;
213 return instance;
214 }
215 /* Singleton */
216 settings(settings const &) = delete;
217 void
218 operator=(settings const &) = delete;
219
220 void
222
223 bool
224 deployed();
225
226 void
228
229 void
231
234
242 template <const auto Key, const auto &Map>
243 static constexpr auto
245 {
246 using MapType = std::remove_reference_t<decltype(Map)>;
247 static_assert(std::is_same_v<typename MapType::key_type, decltype(Key)>,
248 "Key type and map key type do not match");
250 "Map values must be a basic_param_info<...> specialization.");
251 return std::get<Map[Key].default_value.index()>(Map[Key].default_value);
252 }
253
260 template <param P>
261 static constexpr auto
263 {
264 return std::get<m_settings_map[P].default_value.index()>(
265 m_settings_map[P].default_value);
266 }
267
277 template <
278 const auto Key, const auto &Map, auto &RuntimeMap, typename T,
279 typename = std::enable_if_t<!std::is_same_v<decltype(Key), param>, void>>
280 void
281 set(T x)
282 {
283 using MapType = std::remove_reference_t<decltype(Map)>;
284 static_assert(std::is_same_v<typename MapType::key_type, decltype(Key)>,
285 "Key type and map key type do not match");
287 "Map values must be a basic_param_info<...> specialization.");
288 scoped_lock lock(&m_mtx);
289 // Set setting entry in RAM shadow table
290 RuntimeMap.at(Key) = x;
291 }
292
299 template <
300 const auto Key, typename T,
301 typename = std::enable_if_t<std::is_same_v<decltype(Key), param>, void>>
302 void
303 set(T x)
304 {
305 static_assert(std::holds_alternative<T>(m_settings_map[Key].default_value),
306 "Parameter value type and specified type do not match");
307 scoped_lock lock(&m_mtx);
308 // Set setting entry in RAM shadow table
309 m_runtime_settings_map.at(Key) = x;
310 }
311
319 template <const auto Key, const auto &Map, auto &RuntimeMap>
320 void
322 {
323 using MapType = std::remove_reference_t<decltype(Map)>;
324 static_assert(std::is_same_v<typename MapType::key_type, decltype(Key)>,
325 "Key type and map key type do not match");
327 "Map values must be a basic_param_info<...> specialization.");
329 }
330
335 template <param P>
336 void
338 {
340 }
341
346 template <param P>
347 auto
349 {
350 scoped_lock lock(&m_mtx);
351 constexpr const auto d = defaults<P>();
352 return std::get<std::decay_t<decltype(d)>>(m_runtime_settings_map.at(P));
353 }
354
364 template <const auto Key, const auto &Map, const auto &RuntimeMap>
365 auto
367 {
368 scoped_lock lock(&m_mtx);
369 constexpr const auto d = defaults<Key, Map>();
370 return std::get<std::decay_t<decltype(d)>>(RuntimeMap.at(Key));
371 }
372
385 template <const auto Key, const auto &Map, auto &RuntimeMap>
386 void
388 {
389 scoped_lock lock(&m_mtx);
390 constexpr auto d = defaults<Key, Map>();
391 using value_t = std::decay_t<decltype(d)>;
392
393 if constexpr (std::is_same_v<value_t, bool>) {
394 uint32_t raw;
395 if (read(Map[Key].path, raw) >= 0 &&
396 (raw == TRUE_MAGIC || raw == FALSE_MAGIC)) {
397 RuntimeMap.at(Key) = (raw == TRUE_MAGIC);
398 } else {
401 }
402 return;
403 }
404 value_t val;
405 if (read(Map[Key].path, val) >= 0)
406 RuntimeMap.at(Key) = val;
407 else {
410 }
411 return;
412 }
413
423 template <param P>
424 void
426 {
427 scoped_lock lock(&m_mtx);
428 constexpr auto d = defaults<P>();
429 using value_t = std::decay_t<decltype(d)>;
430 if constexpr (std::is_same_v<value_t, bool>) {
431 uint32_t raw;
432 if (read(m_settings_map[P].path, raw) >= 0 &&
433 (raw == TRUE_MAGIC || raw == FALSE_MAGIC)) {
434 m_runtime_settings_map.at(P) = (raw == TRUE_MAGIC);
435 } else {
436 reset<P>();
437 save_one<P>();
438 }
439 return;
440 }
441 value_t val;
442 if (read(m_settings_map[P].path, val) >= 0)
443 m_runtime_settings_map.at(P) = val;
444 else {
445 reset<P>();
446 save_one<P>();
447 }
448 return;
449 }
450
462 template <param P>
463 void
465 {
466 scoped_lock lock(&m_mtx);
467 constexpr const auto d = defaults<P>();
468 using value_t = std::decay_t<decltype(d)>;
469 auto val = std::get<value_t>(m_runtime_settings_map.at(P));
470
471 if constexpr (std::is_same_v<value_t, bool>) {
472 write(m_settings_map[P].path, val ? TRUE_MAGIC : FALSE_MAGIC);
473 } else {
474 write(m_settings_map[P].path, val);
475 }
476 return;
477 }
478
492 template <const auto Key, const auto &Map, auto &RuntimeMap>
493 void
495 {
496 using MapType = std::remove_reference_t<decltype(Map)>;
497 static_assert(std::is_same_v<typename MapType::key_type, decltype(Key)>,
498 "Key type and map key type do not match");
500 "Map values must be a basic_param_info<...> specialization.");
501
502 scoped_lock lock(&m_mtx);
503 constexpr const auto d = defaults<Key, Map>();
504 using value_t = std::decay_t<decltype(d)>;
505 auto val = std::get<value_t>(RuntimeMap.at(Key));
506 if constexpr (std::is_same_v<value_t, bool>) {
507 write(Map[Key].path, val ? TRUE_MAGIC : FALSE_MAGIC);
508 } else {
509 write(Map[Key].path, val);
510 }
511 return;
512 }
513
514 void
515 reset_all();
516
517 void
518 load();
519
520 void
521 save();
522
530 template <const auto &Map, auto &RuntimeMap>
531 constexpr void
533 {
534 load_sequence<Map, RuntimeMap>(std::make_index_sequence<Map.size()>{});
535 }
536
543 template <const auto &Map, auto &RuntimeMap>
544 constexpr void
546 {
547 reset_sequence<Map, RuntimeMap>(std::make_index_sequence<Map.size()>{});
548 }
549
557 template <const auto &Map, auto &RuntimeMap>
558 constexpr void
560 {
561 save_sequence<Map, RuntimeMap>(std::make_index_sequence<Map.size()>{});
562 }
563
564protected:
565 settings();
566
567private:
568 mutable struct k_mutex m_mtx;
592 m_settings_map{
593 std::make_pair(param::BOOT_COUNT, param_info{"/lfs1/boot-cnt", 0U}),
594 std::make_pair(
596 param_info{"/lfs1/uhf-tx-freq",
597 static_cast<uint32_t>(CONFIG_UHF_TX_FREQ_HZ)}),
598 std::make_pair(param::UHF_RX_FREQ,
600 "/lfs1/uhf-rx-freq",
601 static_cast<uint32_t>(CONFIG_UHF_RX_FREQ_HZ),
602 }),
603 std::make_pair(param::SBAND_TX_FREQ,
605 "/lfs1/sband-tx-freq",
606 static_cast<uint32_t>(CONFIG_SBAND_TX_FREQ_HZ),
607 }),
608 std::make_pair(param::SBAND_RX_FREQ,
610 "/lfs1/sband-rx-freq",
611 static_cast<uint32_t>(CONFIG_SBAND_RX_FREQ_HZ),
612 }),
613 std::make_pair(param::UHF_TX_EN,
614 param_info{"/lfs1/uhf-tx-en",
615 static_cast<bool>(CONFIG_UHF_TX_ENABLE)}),
616 std::make_pair(param::SBAND_TX_EN,
617 param_info{"/lfs1/sband-tx-en",
618 static_cast<bool>(CONFIG_SBAND_TX_ENABLE)}),
619 std::make_pair(
622 "/lfs1/uhf-tx-gain",
623 static_cast<float>(CONFIG_UHF_TX_GAIN_DB10) / 10.0f,
624 }),
625 std::make_pair(
628 "/lfs1/sband-tx-gain",
629 static_cast<float>(CONFIG_SBAND_TX_GAIN_DB10) / 10.0f,
630 }),
631 std::make_pair(param::IO_WDG_PERIOD_MINS,
633 "/lfs1/io-wdg-period-min",
634 static_cast<uint32_t>(CONFIG_IO_WDG_PERIOD_MINS),
635 }),
636 std::make_pair(
639 "/lfs1/sband-rx-range-min",
640 static_cast<uint32_t>(CONFIG_SBAND_RX_RANGE_MIN_HZ),
641 }),
642 std::make_pair(
645 "/lfs1/sband-rx-range-max",
646 static_cast<uint32_t>(CONFIG_SBAND_RX_RANGE_MAX_HZ),
647 }),
648 std::make_pair(
651 "/lfs1/sband-tx-range-min",
652 static_cast<uint32_t>(CONFIG_SBAND_TX_RANGE_MIN_HZ),
653 }),
654 std::make_pair(
657 "/lfs1/sband-tx-range-max",
658 static_cast<uint32_t>(CONFIG_SBAND_TX_RANGE_MAX_HZ),
659 }),
660 std::make_pair(
663 "/lfs1/sband-agc0-range-min",
664 static_cast<float>(CONFIG_SBAND_AGC0_RANGE_MIN_DB10) / 10.0f,
665 }),
666 std::make_pair(
669 "/lfs1/sband-agc0-range-max",
670 static_cast<float>(CONFIG_SBAND_AGC0_RANGE_MAX_DB10) / 10.0f,
671 }),
672 std::make_pair(
675 "/lfs1/sband-gain0-range-min",
676 static_cast<float>(CONFIG_SBAND_GAIN0_RANGE_MIN_DB10) / 10.0f,
677 }),
678 std::make_pair(
681 "/lfs1/sband-gain0-range-max",
682 static_cast<float>(CONFIG_SBAND_GAIN0_RANGE_MAX_DB10) / 10.0f,
683 }),
684
685 std::make_pair(
688 "/lfs1/sband-agc0-calib-slope",
689 static_cast<float>(CONFIG_SBAND_AGC0_CALIB_SLOPE_M100000) /
690 100000.0f,
691 }),
692 std::make_pair(
695 "/lfs1/sband-agc0-calib-intrcpt",
696 static_cast<float>(CONFIG_SBAND_AGC0_CALIB_INTRCPT_M100000) /
697 100000.0f,
698 }),
699 std::make_pair(
702 "/lfs1/sband-gain0-calib-slope",
703 static_cast<float>(CONFIG_SBAND_GAIN0_CALIB_SLOPE_M100000) /
704 100000.0f,
705 }),
706 std::make_pair(
709 "/lfs1/sband-gain0-calib-intrcpt",
710 static_cast<float>(CONFIG_SBAND_GAIN0_CALIB_INTRCPT_M100000) /
711 100000.0f,
712 }),
713
714 std::make_pair(param::UHF_RX_RANGE_MIN,
716 "/lfs1/uhf-rx-range-min",
717 static_cast<uint32_t>(CONFIG_UHF_RX_RANGE_MIN_HZ),
718 }),
719 std::make_pair(param::UHF_RX_RANGE_MAX,
721 "/lfs1/uhf-rx-range-max",
722 static_cast<uint32_t>(CONFIG_UHF_RX_RANGE_MAX_HZ),
723 }),
724 std::make_pair(param::UHF_TX_RANGE_MIN,
726 "/lfs1/uhf-tx-range-min",
727 static_cast<uint32_t>(CONFIG_UHF_TX_RANGE_MIN_HZ),
728 }),
729 std::make_pair(param::UHF_TX_RANGE_MAX,
731 "/lfs1/uhf-tx-range-max",
732 static_cast<uint32_t>(CONFIG_UHF_TX_RANGE_MAX_HZ),
733 }),
734 std::make_pair(
737 "/lfs1/uhf-agc0-range-min",
738 static_cast<float>(CONFIG_UHF_AGC0_RANGE_MIN_DB10) / 10.0f,
739 }),
740 std::make_pair(
743 "/lfs1/uhf-agc0-range-max",
744 static_cast<float>(CONFIG_UHF_AGC0_RANGE_MAX_DB10) / 10.0f,
745 }),
746 std::make_pair(
749 "/lfs1/uhf-gain0-range-min",
750 static_cast<float>(CONFIG_UHF_GAIN0_RANGE_MIN_DB10) / 10.0f,
751 }),
752 std::make_pair(
755 "/lfs1/uhf-gain0-range-max",
756 static_cast<float>(CONFIG_UHF_GAIN0_RANGE_MAX_DB10) / 10.0f,
757 }),
758 std::make_pair(
761 "/lfs1/uhf-agc0-calib-slope",
762 static_cast<float>(CONFIG_UHF_AGC0_CALIB_SLOPE_M100000) /
763 100000.0f,
764 }),
765 std::make_pair(
768 "/lfs1/uhf-agc0-calib-intrcpt",
769 static_cast<float>(CONFIG_UHF_AGC0_CALIB_INTRCPT_M100000) /
770 100000.0f,
771 }),
772 std::make_pair(
775 "/lfs1/uhf-gain0-calib-slope",
776 static_cast<float>(CONFIG_UHF_GAIN0_CALIB_SLOPE_M100000) /
777 100000.0f,
778 }),
779 std::make_pair(
782 "/lfs1/uhf-gain0-calib-intrcpt",
783 static_cast<float>(CONFIG_UHF_GAIN0_CALIB_INTRCPT_M100000) /
784 100000.0f,
785 }),
786 std::make_pair(param::PLL_REF_CLK_SRC,
787 param_info{"/lfs1/clk-src", 0U}),
788 std::make_pair(param::UHF_FILTER,
789 param_info{"/lfs1/uhf-filter",
790 static_cast<lib::rf_frontend::filter>(
791 CONFIG_UHF_FILTER)}),
792 std::make_pair(
795 "/lfs1/sband-filter",
796 static_cast<lib::rf_frontend::filter>(CONFIG_SBAND_FILTER),
797 }),
798
799 std::make_pair(param::UHF_ENABLE,
800 param_info{"/lfs1/uhf-enable",
801 static_cast<bool>(CONFIG_UHF_ENABLE)}),
802
803 std::make_pair(param::UHF_GAIN0_MODE,
804 param_info{"/lfs1/uhf-gain0-mode",
805 static_cast<lib::rf_frontend::gain_mode>(
806 CONFIG_UHF_GAIN0_MODE)}),
807 std::make_pair(param::UHF_GAIN1_MODE,
808 param_info{"/lfs1/uhf-gain1-mode",
809 static_cast<lib::rf_frontend::gain_mode>(
810 CONFIG_UHF_GAIN1_MODE)}),
811 std::make_pair(
813 param_info{"/lfs1/uhf-gain0-tgt",
814 static_cast<float>(CONFIG_UHF_GAIN0_TGT_DB10) /
815 10.0f}),
816 std::make_pair(
818 param_info{"/lfs1/uhf-gain0-gain",
819 static_cast<float>(CONFIG_UHF_GAIN0_GAIN_DB10) /
820 10.0f}),
821 std::make_pair(
823 param_info{"/lfs1/uhf-gain1-agc",
824 agc1{.tgt = static_cast<at86rf215_agc_tgt_t>(
825 CONFIG_UHF_GAIN1_TGT),
826 .avg = static_cast<at86rf215_agc_avgs_t>(
827 CONFIG_UHF_GAIN1_AVGS),
828 .input = CONFIG_UHF_GAIN1_INPUT}}),
829 std::make_pair(param::UHF_GAIN1_GAIN,
830 param_info{"/lfs1/uhf-gain1-gain",
831 static_cast<float>(CONFIG_UHF_GAIN1_GAIN)}),
832
833 std::make_pair(param::UHF_TX_MODULATION,
834 param_info{"/lfs1/uhf-tx-modulation",
835 static_cast<lib::radio::modulation>(
836 CONFIG_UHF_TX_MODULATION)}),
837 std::make_pair(
840 "/lfs1/uhf-fsk-tx",
841 fsk{.baudrate = static_cast<at86rf215_fsk_srate_t>(
842 CONFIG_UHF_FSK_TX_BAUDRATE),
843 .mod_idx = CONFIG_UHF_FSK_TX_MOD_IDX_M1000 / 1000.0f,
844 .shaping =
845 CONFIG_UHF_FSK_TX_SHAPING_BT_M1000 / 1000.0f}}),
846 std::make_pair(param::UHF_RX_MODULATION,
847 param_info{"/lfs1/uhf-rx-modulation",
848 static_cast<lib::radio::modulation>(
849 CONFIG_UHF_RX_MODULATION)}),
850 std::make_pair(
853 "/lfs1/uhf-fsk-rx",
854 fsk{.baudrate = static_cast<at86rf215_fsk_srate_t>(
855 CONFIG_UHF_FSK_RX_BAUDRATE),
856 .mod_idx = CONFIG_UHF_FSK_RX_MOD_IDX_M1000 / 1000.0f,
857 .shaping = 1.0f}}),
858
859 std::make_pair(param::SBAND_ENABLE,
860 param_info{"/lfs1/sband-enable",
861 static_cast<bool>(CONFIG_SBAND_ENABLE)}),
862 std::make_pair(param::SBAND_GAIN0_MODE,
863 param_info{"/lfs1/sband-gain0-mode",
864 static_cast<lib::rf_frontend::gain_mode>(
865 CONFIG_SBAND_GAIN0_MODE)}),
866 std::make_pair(param::SBAND_GAIN1_MODE,
867 param_info{"/lfs1/sband-gain1-mode",
868 static_cast<lib::rf_frontend::gain_mode>(
869 CONFIG_SBAND_GAIN1_MODE)}),
870 std::make_pair(
872 param_info{"/lfs1/sband-gain0-tgt",
873 static_cast<float>(CONFIG_SBAND_GAIN0_TGT_DB10) /
874 10.0f}),
875 std::make_pair(
877 param_info{"/lfs1/sband-gain0-gain",
878 static_cast<float>(CONFIG_SBAND_GAIN0_GAIN_DB10) /
879 10.0f}),
880 std::make_pair(
882 param_info{"/lfs1/sband-gain1-agc",
883 agc1{.tgt = static_cast<at86rf215_agc_tgt_t>(
884 CONFIG_SBAND_GAIN1_TGT),
885 .avg = static_cast<at86rf215_agc_avgs_t>(
886 CONFIG_SBAND_GAIN1_AVGS),
887 .input = CONFIG_SBAND_GAIN1_INPUT}}),
888 std::make_pair(
890 param_info{"/lfs1/sband-gain1-gain",
891 static_cast<float>(CONFIG_SBAND_GAIN1_GAIN)}),
892 std::make_pair(param::SBAND_TX_MODULATION,
893 param_info{"/lfs1/sband-tx-modulation",
894 static_cast<lib::radio::modulation>(
895 CONFIG_SBAND_TX_MODULATION)}),
896 std::make_pair(
899 "/lfs1/sband-fsk-tx",
900 fsk{.baudrate = static_cast<at86rf215_fsk_srate_t>(
901 CONFIG_SBAND_FSK_TX_BAUDRATE),
902 .mod_idx = CONFIG_SBAND_FSK_TX_MOD_IDX_M1000 / 1000.0f,
903 .shaping =
904 CONFIG_SBAND_FSK_TX_SHAPING_BT_M1000 / 1000.0f}}),
905 std::make_pair(param::SBAND_RX_MODULATION,
906 param_info{"/lfs1/sband-rx-modulation",
907 static_cast<lib::radio::modulation>(
908 CONFIG_SBAND_RX_MODULATION)}),
909 std::make_pair(
912 "/lfs1/sband-fsk-rx",
913 fsk{.baudrate = static_cast<at86rf215_fsk_srate_t>(
914 CONFIG_SBAND_FSK_RX_BAUDRATE),
915 .mod_idx = CONFIG_SBAND_FSK_RX_MOD_IDX_M1000 / 1000.0f,
916 .shaping = 1.0f}}),
917 std::make_pair(
919 param_info{"/lfs1/thermal-uhf-shutdown-temp",
920 static_cast<float>(CONFIG_THERMAL_UHF_SHUTDOWN_TEMP)}),
921 std::make_pair(
923 param_info{"/lfs1/thermal-uhf-enable-temp",
924 static_cast<float>(CONFIG_THERMAL_UHF_ENABLE_TEMP)}),
926 param_info{"/lfs1/thermal-sband-shutdown-temp",
927 static_cast<float>(
928 CONFIG_THERMAL_SBAND_SHUTDOWN_TEMP)}),
929 std::make_pair(
931 param_info{"/lfs1/thermal-sband-enable-temp",
932 static_cast<float>(CONFIG_THERMAL_SBAND_ENABLE_TEMP)}),
933 std::make_pair(
935 param_info{"/lfs1/thermal-pcb-shutdown-temp",
936 static_cast<float>(CONFIG_THERMAL_PCB_SHUTDOWN_TEMP)}),
937 std::make_pair(
939 param_info{"/lfs1/thermal-pcb-enable-temp",
940 static_cast<float>(CONFIG_THERMAL_PCB_ENABLE_TEMP)}),
941 std::make_pair(
943 param_info{"/lfs1/thermal-min-valid-temp",
944 static_cast<float>(CONFIG_THERMAL_MIN_VALID_TEMP)}),
945 std::make_pair(
947 param_info{"/lfs1/thermal-max-valid-temp",
948 static_cast<float>(CONFIG_THERMAL_MAX_VALID_TEMP)}),
949 std::make_pair(
951 param_info{"/lfs1/uhf-trx-turnaround-ms",
952 static_cast<uint32_t>(CONFIG_UHF_TRX_TURNAROUND_MS)}),
953 std::make_pair(param::SBAND_TRX_TURNAROUND_MS,
954 param_info{"/lfs1/sband-trx-turnaround-ms",
955 static_cast<uint32_t>(
956 CONFIG_SBAND_TRX_TURNAROUND_MS)}),
957 std::make_pair(
959 param_info{"/lfs1/uhf-rx-on-secs",
960 static_cast<uint32_t>(CONFIG_UHF_RX_ON_SECS)}),
961 std::make_pair(
963 param_info{"/lfs1/uhf-rx-off-secs",
964 static_cast<uint32_t>(CONFIG_UHF_RX_OFF_SECS)}),
965 std::make_pair(
967 param_info{"/lfs1/sband-rx-on-secs",
968 static_cast<uint32_t>(CONFIG_SBAND_RX_ON_SECS)}),
969 std::make_pair(
971 param_info{"/lfs1/sband-rx-off-secs",
972 static_cast<uint32_t>(CONFIG_SBAND_RX_OFF_SECS)}),
973
974 std::make_pair(
976 param_info{"/lfs1/uhf-tx-wait-ms",
977 static_cast<uint32_t>(CONFIG_UHF_TX_WAIT_MS)}),
978
979 std::make_pair(
981 param_info{"/lfs1/sband-tx-wait-ms",
982 static_cast<uint32_t>(CONFIG_SBAND_TX_WAIT_MS)}),
983
984 std::make_pair(param::FPGA_BOOT_MODE,
985 param_info{"/lfs1/fpga-boot-mode",
986 static_cast<lib::fpga::boot_mode>(
987 CONFIG_FPGA_BOOT_MODE)})};
988
989 etl::flat_map<param, decltype(param_info::default_value), TABLE_SIZE>
990 m_runtime_settings_map;
991
992 template <typename T>
993 int
994 read(const char *fname, T &x)
995 {
996 T val;
997 struct fs_file_t file;
998 int ret;
999
1000 fs_file_t_init(&file);
1001 ret = fs_open(&file, fname, FS_O_READ);
1002 if (ret) {
1003 return ret;
1004 }
1005
1006 ret = fs_read(&file, &val, sizeof(val));
1007 if (ret < 0) {
1008 fs_close(&file);
1009 return ret;
1010 }
1011
1012 ret = fs_close(&file);
1013 if (ret) {
1014 return ret;
1015 }
1016 x = val;
1017 return 0;
1018 }
1019
1020 template <typename T>
1021 int
1022 write(const char *fname, const T &x)
1023 {
1024 struct fs_file_t file;
1025 int ret;
1026
1027 fs_file_t_init(&file);
1028 ret = fs_open(&file, fname, FS_O_CREATE | FS_O_RDWR);
1029 if (ret && ret != -ENOENT) {
1030 return ret;
1031 }
1032
1033 ret = fs_write(&file, &x, sizeof(x));
1034 if (ret < 0) {
1035 fs_close(&file);
1036 return ret;
1037 }
1038 return fs_close(&file);
1039 }
1040
1049 template <const auto &Map, auto &RuntimeMap, const auto... KeySeq>
1050 void
1051 reset_sequence(std::index_sequence<KeySeq...>)
1052 {
1053 constexpr auto keys = Map.keys();
1055 }
1056
1062 template <const auto... KeySeq>
1063 void
1064 reset_sequence(std::index_sequence<KeySeq...>)
1065 {
1066 constexpr auto keys = m_settings_map.keys();
1067 (reset<keys[KeySeq]>(), ...);
1068 }
1069
1075 template <const auto... KeySeq>
1076 void
1077 load_sequence(std::index_sequence<KeySeq...>)
1078 {
1079 constexpr auto keys = m_settings_map.keys();
1080 (load_one<keys[KeySeq]>(), ...);
1081 }
1082
1091 template <const auto &Map, auto &RuntimeMap, const auto... KeySeq>
1092 void
1093 load_sequence(std::index_sequence<KeySeq...>)
1094 {
1095 constexpr auto keys = Map.keys();
1097 }
1098
1104 template <const auto... KeySeq>
1105 void
1106 save_sequence(std::index_sequence<KeySeq...>)
1107 {
1108 constexpr auto keys = m_settings_map.keys();
1109 (save_one<keys[KeySeq]>(), ...);
1110 }
1111
1119 template <const auto &Map, auto &RuntimeMap, const auto... KeySeq>
1120 void
1121 save_sequence(std::index_sequence<KeySeq...>)
1122 {
1123 constexpr auto keys = Map.keys();
1125 }
1126};
1127
1128} // namespace satnogs::comms
RX configuration parameters.
Definition radio.hpp:299
modulation
Supported modulation schemes.
Definition radio.hpp:196
interface
Radio interface identifier.
Definition radio.hpp:177
clk_src
PLL Reference Clock identifier.
Definition radio.hpp:167
Implements a scoped lock utilizing the Zephyr mutex.
constexpr void reset_all()
Reset ALL mission-defined settings.
Definition settings.hpp:545
void save()
Save all the core settings from the RAM shadow table to FLASH.
Definition settings.cpp:253
auto get()
Get a mission-defined setting in RAM shadow table.
Definition settings.hpp:366
static constexpr std::size_t TABLE_SIZE
Definition settings.hpp:151
void save_one()
Save a mission specific setting from RAM shadow table to FLASH.
Definition settings.hpp:494
static constexpr uint32_t FALSE_MAGIC
Definition settings.hpp:63
static settings & get_instance()
Get a singleton access to the settings subsystem.
Definition settings.hpp:210
void save_one()
Save a core setting from RAM shadow table to FLASH.
Definition settings.hpp:464
void reset()
Reset a mission specific setting in RAM shadow table.
Definition settings.hpp:321
settings()
Construct a new settings::settings object and mounts the LittleFS partition.
Definition settings.cpp:46
void set(T x)
Sets a mission-defined setting in RAM shadow table.
Definition settings.hpp:281
void reset()
Reset a specific core setting in RAM shadow table.
Definition settings.hpp:337
void operator=(settings const &)=delete
void get_tx_conf(lib::radio::interface iface, lib::radio::tx_conf &cnf)
Retrieve the TX configuration parameters for a specific interface.
Definition settings.cpp:105
static constexpr auto defaults()
Returns the default value of a mission-defined setting.
Definition settings.hpp:244
static constexpr bool is_param_info_v
Definition settings.hpp:199
void get_rx_conf(lib::radio::interface iface, lib::radio::rx_conf &cnf)
Retrieve the TX configuration parameters for a specific interface.
Definition settings.cpp:139
constexpr void save()
Save ALL mission-defined settings from the RAM shadow table to FLASH.
Definition settings.hpp:559
auto get()
Get a specific core setting from RAM shadow table.
Definition settings.hpp:348
void set(T x)
Sets a specific core setting in RAM shadow table.
Definition settings.hpp:303
void load_one()
Load a core setting from FLASH to the RAM shadow table.
Definition settings.hpp:425
bool deployed()
Retrieves the information regarding if this is the first time that the system deploys.
Definition settings.cpp:93
void reset_all()
Resets all the settings to their default values.
Definition settings.cpp:225
settings(settings const &)=delete
param
Specific setting identifier.
Definition settings.hpp:71
constexpr void load()
Load ALL mission-defined settings from FLASH to the RAM shadow table.
Definition settings.hpp:532
void load_one()
Load a mission-defined setting from FLASH to the RAM shadow table.
Definition settings.hpp:387
basic_param_info<> param_info
Definition settings.hpp:202
lib::radio::clk_src radio_clk_src()
Returns the current radio clock source.
Definition settings.cpp:205
void incr_boot_cnt()
Increments the current boot count and stores it at the persistent storage.
Definition settings.cpp:76
static constexpr auto defaults()
Returns the default value of a specific setting.
Definition settings.hpp:262
static constexpr uint32_t TRUE_MAGIC
Definition settings.hpp:62
void load()
Loads all the core settings from FLASH to the RAM shadow table.
Definition settings.cpp:239
Compile-time hash-map (associative key-value container) that performs all operations in constexpr con...
Definition hash_map.hpp:66
at86rf215_agc_avgs_t avg
Definition settings.hpp:158
at86rf215_agc_tgt_t tgt
Definition settings.hpp:157
Extensible parameter descriptor.
Definition settings.hpp:179
std::variant< float, uint32_t, bool, agc1, fsk, lib::rf_frontend::gain_mode, lib::rf_frontend::filter, lib::radio::modulation, lib::fpga::boot_mode, ExtraTypes... > default_value
Definition settings.hpp:184
at86rf215_fsk_srate_t baudrate
Definition settings.hpp:164