From 989a4f5e537857076e0f4c1f56c905ed577b97f4 Mon Sep 17 00:00:00 2001 From: Collin Date: Sun, 19 Jul 2026 19:43:00 -0500 Subject: [PATCH 01/17] To_proc_time cmd added --- .../Components/Drv/RtcManager/RtcManager.cpp | 25 ++++++++++++++++++- .../Components/Drv/RtcManager/RtcManager.fpp | 7 ++++++ .../Components/Drv/RtcManager/RtcManager.hpp | 8 ++++++ 3 files changed, 39 insertions(+), 1 deletion(-) diff --git a/PROVESFlightControllerReference/Components/Drv/RtcManager/RtcManager.cpp b/PROVESFlightControllerReference/Components/Drv/RtcManager/RtcManager.cpp index 866b76d3..986df1cf 100644 --- a/PROVESFlightControllerReference/Components/Drv/RtcManager/RtcManager.cpp +++ b/PROVESFlightControllerReference/Components/Drv/RtcManager/RtcManager.cpp @@ -17,7 +17,8 @@ RtcManager ::RtcManager(const char* const compName) m_rtcHelper(), m_RtcNotReadyThrottle(false), m_RtcGetTimeFailedThrottle(false), - m_RtcInvalidTimeThrottle(false) { + m_RtcInvalidTimeThrottle(false), + m_ProcTimeSet(false) { // alarm time initialization memset(&this->m_alarm_time, 0, sizeof(struct rtc_time)); } @@ -51,6 +52,7 @@ void RtcManager ::timeGetPort_handler(FwIndexType portNum, Fw::Time& time) { // Check device readiness if (!device_is_ready(this->m_dev)) { this->log_CONSOLE_RtcNotReady(); + this->m_ProcTimeSet = true; // proc time flag // Use uptime as fallback time.set(TimeBase::TB_PROC_TIME, 0, seconds_since_boot, useconds_since_boot); @@ -63,6 +65,7 @@ void RtcManager ::timeGetPort_handler(FwIndexType portNum, Fw::Time& time) { const int rc = rtc_get_time(this->m_dev, &time_rtc); if (rc != 0) { this->log_CONSOLE_RtcGetTimeFailed(rc); + this->m_ProcTimeSet = true; // proc time flag // Use uptime as fallback time.set(TimeBase::TB_PROC_TIME, 0, seconds_since_boot, useconds_since_boot); @@ -78,6 +81,7 @@ void RtcManager ::timeGetPort_handler(FwIndexType portNum, Fw::Time& time) { U32 seconds_real_time = static_cast(timeutil_timegm(time_tm)); if (errno == ERANGE) { this->log_CONSOLE_RtcInvalidTime(); + this->m_ProcTimeSet = true; // proc time flag // Use uptime as fallback time.set(TimeBase::TB_PROC_TIME, 0, seconds_since_boot, useconds_since_boot); @@ -85,6 +89,8 @@ void RtcManager ::timeGetPort_handler(FwIndexType portNum, Fw::Time& time) { } this->log_CONSOLE_RtcInvalidTime_ThrottleClear(); + this->m_ProcTimeSet = false; // proc time flag + // Set FPrime time object time.set(TimeBase::TB_SC_TIME, 0, seconds_real_time, this->m_rtcHelper.rescaleUseconds(seconds_real_time, useconds_since_boot)); @@ -151,6 +157,8 @@ void RtcManager ::TIME_SET_cmdHandler(FwOpcodeType opCode, U32 cmdSeq, Drv::Time return; } + this->m_ProcTimeSet = false; // proc time flag + // Emit time set event, include previous time for reference this->log_ACTIVITY_HI_TimeSet(time_before_set.getSeconds(), time_before_set.getUSeconds()); @@ -158,6 +166,21 @@ void RtcManager ::TIME_SET_cmdHandler(FwOpcodeType opCode, U32 cmdSeq, Drv::Time this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK); } +void RtcManager ::TO_PROC_TIME_cmdHandler(FwOpcodeType opCode, U32 cmdSeq) { + // Switch the time source to proc time + Fw::Time proc_time; + int64_t t = k_uptime_get(); + U32 seconds_since_boot = static_cast(t / 1000); + U32 useconds_since_boot = static_cast((t % 1000) * 1000); + this->log_ACTIVITY_HI_procTimeSet(seconds_since_boot); // Log the current uptime in seconds + + this->m_ProcTimeSet = true; // proc time flag + proc_time.set(TimeBase::TB_PROC_TIME, 0, seconds_since_boot, useconds_since_boot); + + // Command response + this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK); +} + void RtcManager ::ALARM_SET_cmdHandler(FwOpcodeType opCode, U32 cmdSeq, Drv::TimeData t) { // retrieve info about current alarm diff --git a/PROVESFlightControllerReference/Components/Drv/RtcManager/RtcManager.fpp b/PROVESFlightControllerReference/Components/Drv/RtcManager/RtcManager.fpp index f912fbf5..3ac585cd 100644 --- a/PROVESFlightControllerReference/Components/Drv/RtcManager/RtcManager.fpp +++ b/PROVESFlightControllerReference/Components/Drv/RtcManager/RtcManager.fpp @@ -31,6 +31,9 @@ module Drv { t: Drv.TimeData @< Set the time ) + @ TO_PROC_TIME command to use proc time instead of RTC time + sync command TO_PROC_TIME() + @ ALARM_SET command to set an alarm on the RTC sync command ALARM_SET( t: Drv.TimeData @< Time to set the alarm for @@ -55,6 +58,10 @@ module Drv { useconds: U32 @< Microseconds ) severity activity high id 3 format "Time set on RTC, previous time: {}.{}" + event procTimeSet( + seconds: U32 @< Uptime in seconds + ) severity activity high id 17 format "Proc time set, current uptime: {}" + @ TimeNotSet event indicates that the time was not set successfully event TimeNotSet(rc: I32) severity warning high id 4 format "Time not set on RTC: {}" diff --git a/PROVESFlightControllerReference/Components/Drv/RtcManager/RtcManager.hpp b/PROVESFlightControllerReference/Components/Drv/RtcManager/RtcManager.hpp index 06fd7dbd..da5a7491 100644 --- a/PROVESFlightControllerReference/Components/Drv/RtcManager/RtcManager.hpp +++ b/PROVESFlightControllerReference/Components/Drv/RtcManager/RtcManager.hpp @@ -93,6 +93,13 @@ class RtcManager final : public RtcManagerComponentBase { U32 cmdSeq //!< The command sequence number ) override; + //! Handler implementation for command TO_PROC_TIME + //! + //! Switches the time source to use proc time + void TO_PROC_TIME_cmdHandler(FwOpcodeType opCode, //!< The opcode + U32 cmdSeq //!< The command sequence number + ) override; + private: // ---------------------------------------------------------------------- // Private helper methods @@ -135,6 +142,7 @@ class RtcManager final : public RtcManagerComponentBase { std::atomic m_RtcNotReadyThrottle; //!< Throttle for RtcNotReady std::atomic m_RtcGetTimeFailedThrottle; //!< Throttle for RtcGetTimeFailed std::atomic m_RtcInvalidTimeThrottle; //!< Throttle for RtcInvalidTime + std::atomic m_ProcTimeSet; //!< Proc time flag // rtc alarm members U16 m_curr_mask; //!< The mask of the alarm present on hardware From d92e6cfd4fddcc7aef167db09ddb43d96b49f6ce Mon Sep 17 00:00:00 2001 From: Collin Date: Sun, 19 Jul 2026 20:48:39 -0500 Subject: [PATCH 02/17] LoRa Mode beaconing added, bugs fixed --- .../Components/Drv/RtcManager/RtcManager.cpp | 7 +++++++ .../Top/ReferenceDeploymentPackets.fppi | 1 + 2 files changed, 8 insertions(+) diff --git a/PROVESFlightControllerReference/Components/Drv/RtcManager/RtcManager.cpp b/PROVESFlightControllerReference/Components/Drv/RtcManager/RtcManager.cpp index 986df1cf..d5c158a7 100644 --- a/PROVESFlightControllerReference/Components/Drv/RtcManager/RtcManager.cpp +++ b/PROVESFlightControllerReference/Components/Drv/RtcManager/RtcManager.cpp @@ -49,6 +49,13 @@ void RtcManager ::timeGetPort_handler(FwIndexType portNum, Fw::Time& time) { U32 seconds_since_boot = static_cast(t / 1000); U32 useconds_since_boot = static_cast((t % 1000) * 1000); + // check if proc time mode is set + if (this->m_ProcTimeSet) { + // use proc time + time.set(TimeBase::TB_PROC_TIME, 0, seconds_since_boot, useconds_since_boot); + return; + } + // Check device readiness if (!device_is_ready(this->m_dev)) { this->log_CONSOLE_RtcNotReady(); diff --git a/PROVESFlightControllerReference/ReferenceDeployment/Top/ReferenceDeploymentPackets.fppi b/PROVESFlightControllerReference/ReferenceDeployment/Top/ReferenceDeploymentPackets.fppi index 74ceb781..4237b135 100644 --- a/PROVESFlightControllerReference/ReferenceDeployment/Top/ReferenceDeploymentPackets.fppi +++ b/PROVESFlightControllerReference/ReferenceDeployment/Top/ReferenceDeploymentPackets.fppi @@ -11,6 +11,7 @@ telemetry packets ReferenceDeploymentPackets { packet Beacon id 1 group 1 { # Satellite Meta Data + ReferenceDeployment.lora.ModuleMode ReferenceDeployment.startupManager.BootCount ReferenceDeployment.modeManager.CurrentMode From 45aec08642a5191c4772df0d2de8d4463879c22c Mon Sep 17 00:00:00 2001 From: Collin Date: Fri, 24 Jul 2026 17:46:28 -0500 Subject: [PATCH 03/17] added LoRa cfg telemetry (again) --- .../Top/ReferenceDeploymentPackets.fppi | 7 ++++++- lib/fprime-zephyr | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/PROVESFlightControllerReference/ReferenceDeployment/Top/ReferenceDeploymentPackets.fppi b/PROVESFlightControllerReference/ReferenceDeployment/Top/ReferenceDeploymentPackets.fppi index 4237b135..c6be2647 100644 --- a/PROVESFlightControllerReference/ReferenceDeployment/Top/ReferenceDeploymentPackets.fppi +++ b/PROVESFlightControllerReference/ReferenceDeployment/Top/ReferenceDeploymentPackets.fppi @@ -11,10 +11,15 @@ telemetry packets ReferenceDeploymentPackets { packet Beacon id 1 group 1 { # Satellite Meta Data - ReferenceDeployment.lora.ModuleMode ReferenceDeployment.startupManager.BootCount ReferenceDeployment.modeManager.CurrentMode + #LoRa config data + ReferenceDeployment.lora.ModuleDataRate + ReferenceDeployment.lora.ModuleCodingRate + ReferenceDeployment.lora.ModuleBandwidth + ReferenceDeployment.lora.ModuleTransmitState + # Essential Sensor Data ReferenceDeployment.detumbleManager.AngularVelocityMagnitude diff --git a/lib/fprime-zephyr b/lib/fprime-zephyr index 31399714..eae2e79f 160000 --- a/lib/fprime-zephyr +++ b/lib/fprime-zephyr @@ -1 +1 @@ -Subproject commit 313997144363ea930af66e86b52d43537cf7f489 +Subproject commit eae2e79f0f3ac50143989a3fc5d9b1a3891281e2 From e5b955eb4d701079653da737ec4ee7aaf01d293b Mon Sep 17 00:00:00 2001 From: Collin Date: Fri, 24 Jul 2026 20:33:12 -0500 Subject: [PATCH 04/17] fixed submodule conflict --- lib/fprime-zephyr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/fprime-zephyr b/lib/fprime-zephyr index eae2e79f..60d395ed 160000 --- a/lib/fprime-zephyr +++ b/lib/fprime-zephyr @@ -1 +1 @@ -Subproject commit eae2e79f0f3ac50143989a3fc5d9b1a3891281e2 +Subproject commit 60d395edfcca61843045962d1c262674e815008b From 2240804a7526ea10dab63d2a114f30464351e5b2 Mon Sep 17 00:00:00 2001 From: Collin Date: Fri, 24 Jul 2026 20:42:45 -0500 Subject: [PATCH 05/17] fixed submodule conflict --- lib/fprime | 2 +- lib/fprime-extras | 2 +- lib/zephyr-workspace/zephyr | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/fprime b/lib/fprime index 8a62e455..f67b68fd 160000 --- a/lib/fprime +++ b/lib/fprime @@ -1 +1 @@ -Subproject commit 8a62e455a90b6d4f498c332d45d65a2a819988d8 +Subproject commit f67b68fdb611dd900922939b8a0404ab1008f957 diff --git a/lib/fprime-extras b/lib/fprime-extras index f4d4924f..982139f9 160000 --- a/lib/fprime-extras +++ b/lib/fprime-extras @@ -1 +1 @@ -Subproject commit f4d4924f0b9bd472b52f310041516dd309f9b26f +Subproject commit 982139f94ed833a5b3b97bab903b97e05f385b26 diff --git a/lib/zephyr-workspace/zephyr b/lib/zephyr-workspace/zephyr index 1f6485ec..3568e1b6 160000 --- a/lib/zephyr-workspace/zephyr +++ b/lib/zephyr-workspace/zephyr @@ -1 +1 @@ -Subproject commit 1f6485eca25431b5ff27ce9a754218c9e559bbbb +Subproject commit 3568e1b6d5cdd51a6b964a2a1d6d29200fea2056 From 8386485efd4dc4255cd1c58178855577368bf42d Mon Sep 17 00:00:00 2001 From: Collin Date: Fri, 24 Jul 2026 21:47:49 -0500 Subject: [PATCH 06/17] why --- .../Components/Drv/RtcManager/RtcManager.cpp | 2 +- lib/zephyr-workspace/zephyr | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/PROVESFlightControllerReference/Components/Drv/RtcManager/RtcManager.cpp b/PROVESFlightControllerReference/Components/Drv/RtcManager/RtcManager.cpp index d5c158a7..1352df3b 100644 --- a/PROVESFlightControllerReference/Components/Drv/RtcManager/RtcManager.cpp +++ b/PROVESFlightControllerReference/Components/Drv/RtcManager/RtcManager.cpp @@ -43,7 +43,7 @@ void RtcManager ::configure(const struct device* dev) { // Handler implementations for typed input ports // ---------------------------------------------------------------------- -void RtcManager ::timeGetPort_handler(FwIndexType portNum, Fw::Time& time) { +void RtcManager ::timeGetPort_handler(FgwIndexType portNum, Fw::Time& time) { // Get system uptime int64_t t = k_uptime_get(); U32 seconds_since_boot = static_cast(t / 1000); diff --git a/lib/zephyr-workspace/zephyr b/lib/zephyr-workspace/zephyr index 3568e1b6..1f6485ec 160000 --- a/lib/zephyr-workspace/zephyr +++ b/lib/zephyr-workspace/zephyr @@ -1 +1 @@ -Subproject commit 3568e1b6d5cdd51a6b964a2a1d6d29200fea2056 +Subproject commit 1f6485eca25431b5ff27ce9a754218c9e559bbbb From e4a68d79cec2523a22fec7707b6e862da8f19383 Mon Sep 17 00:00:00 2001 From: Collin Date: Fri, 24 Jul 2026 21:52:04 -0500 Subject: [PATCH 07/17] updated code --- .../Components/Drv/RtcManager/RtcManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PROVESFlightControllerReference/Components/Drv/RtcManager/RtcManager.cpp b/PROVESFlightControllerReference/Components/Drv/RtcManager/RtcManager.cpp index 1352df3b..52a88130 100644 --- a/PROVESFlightControllerReference/Components/Drv/RtcManager/RtcManager.cpp +++ b/PROVESFlightControllerReference/Components/Drv/RtcManager/RtcManager.cpp @@ -43,7 +43,7 @@ void RtcManager ::configure(const struct device* dev) { // Handler implementations for typed input ports // ---------------------------------------------------------------------- -void RtcManager ::timeGetPort_handler(FgwIndexType portNum, Fw::Time& time) { +void RtcManager ::timeGetPort_handler(FgsuwIndexType portNum, Fw::Time& time) { // Get system uptime int64_t t = k_uptime_get(); U32 seconds_since_boot = static_cast(t / 1000); From 69eaaf2e1f47b5aaf1dcf4abafd4bf29b40ad1f2 Mon Sep 17 00:00:00 2001 From: Collin Date: Fri, 24 Jul 2026 22:35:56 -0500 Subject: [PATCH 08/17] fix typo --- .../Components/Drv/RtcManager/RtcManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PROVESFlightControllerReference/Components/Drv/RtcManager/RtcManager.cpp b/PROVESFlightControllerReference/Components/Drv/RtcManager/RtcManager.cpp index 52a88130..d5c158a7 100644 --- a/PROVESFlightControllerReference/Components/Drv/RtcManager/RtcManager.cpp +++ b/PROVESFlightControllerReference/Components/Drv/RtcManager/RtcManager.cpp @@ -43,7 +43,7 @@ void RtcManager ::configure(const struct device* dev) { // Handler implementations for typed input ports // ---------------------------------------------------------------------- -void RtcManager ::timeGetPort_handler(FgsuwIndexType portNum, Fw::Time& time) { +void RtcManager ::timeGetPort_handler(FwIndexType portNum, Fw::Time& time) { // Get system uptime int64_t t = k_uptime_get(); U32 seconds_since_boot = static_cast(t / 1000); From 61edc637060f6373e7b2724cf522d8f02c856dc7 Mon Sep 17 00:00:00 2001 From: Collin Date: Fri, 24 Jul 2026 23:17:20 -0500 Subject: [PATCH 09/17] stable - no conflicts --- .../ReferenceDeployment/Top/ReferenceDeploymentPackets.fppi | 6 ------ lib/fprime | 2 +- lib/fprime-extras | 2 +- 3 files changed, 2 insertions(+), 8 deletions(-) diff --git a/PROVESFlightControllerReference/ReferenceDeployment/Top/ReferenceDeploymentPackets.fppi b/PROVESFlightControllerReference/ReferenceDeployment/Top/ReferenceDeploymentPackets.fppi index e69bac86..5ca221ec 100644 --- a/PROVESFlightControllerReference/ReferenceDeployment/Top/ReferenceDeploymentPackets.fppi +++ b/PROVESFlightControllerReference/ReferenceDeployment/Top/ReferenceDeploymentPackets.fppi @@ -14,12 +14,6 @@ telemetry packets ReferenceDeploymentPackets { startupManager.BootCount modeManager.CurrentMode - #LoRa config data - ReferenceDeployment.lora.ModuleDataRate - ReferenceDeployment.lora.ModuleCodingRate - ReferenceDeployment.lora.ModuleBandwidth - ReferenceDeployment.lora.ModuleTransmitState - # Essential Sensor Data detumbleManager.AngularVelocityMagnitude diff --git a/lib/fprime b/lib/fprime index f67b68fd..8a62e455 160000 --- a/lib/fprime +++ b/lib/fprime @@ -1 +1 @@ -Subproject commit f67b68fdb611dd900922939b8a0404ab1008f957 +Subproject commit 8a62e455a90b6d4f498c332d45d65a2a819988d8 diff --git a/lib/fprime-extras b/lib/fprime-extras index 982139f9..f4d4924f 160000 --- a/lib/fprime-extras +++ b/lib/fprime-extras @@ -1 +1 @@ -Subproject commit 982139f94ed833a5b3b97bab903b97e05f385b26 +Subproject commit f4d4924f0b9bd472b52f310041516dd309f9b26f From f7f6fa6057ef2177b739aa1d234654e3df2465d0 Mon Sep 17 00:00:00 2001 From: Collin Date: Fri, 24 Jul 2026 23:37:36 -0500 Subject: [PATCH 10/17] proctime --- .../Components/Drv/RtcManager/RtcManager.cpp | 4 +++- .../Components/Drv/RtcManager/RtcManager.fpp | 8 +++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/PROVESFlightControllerReference/Components/Drv/RtcManager/RtcManager.cpp b/PROVESFlightControllerReference/Components/Drv/RtcManager/RtcManager.cpp index d5c158a7..824f4327 100644 --- a/PROVESFlightControllerReference/Components/Drv/RtcManager/RtcManager.cpp +++ b/PROVESFlightControllerReference/Components/Drv/RtcManager/RtcManager.cpp @@ -168,6 +168,7 @@ void RtcManager ::TIME_SET_cmdHandler(FwOpcodeType opCode, U32 cmdSeq, Drv::Time // Emit time set event, include previous time for reference this->log_ACTIVITY_HI_TimeSet(time_before_set.getSeconds(), time_before_set.getUSeconds()); + this->log_ACTIVITY_HI_TimeBase(Fw::String("RTC")); // Send command response this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK); @@ -179,10 +180,11 @@ void RtcManager ::TO_PROC_TIME_cmdHandler(FwOpcodeType opCode, U32 cmdSeq) { int64_t t = k_uptime_get(); U32 seconds_since_boot = static_cast(t / 1000); U32 useconds_since_boot = static_cast((t % 1000) * 1000); - this->log_ACTIVITY_HI_procTimeSet(seconds_since_boot); // Log the current uptime in seconds + this->log_ACTIVITY_HI_ProcTimeSet(seconds_since_boot); // Log the current uptime in seconds this->m_ProcTimeSet = true; // proc time flag proc_time.set(TimeBase::TB_PROC_TIME, 0, seconds_since_boot, useconds_since_boot); + this->log_ACTIVITY_HI_TimeBase(Fw::String("PROC")); // Command response this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK); diff --git a/PROVESFlightControllerReference/Components/Drv/RtcManager/RtcManager.fpp b/PROVESFlightControllerReference/Components/Drv/RtcManager/RtcManager.fpp index 3ac585cd..f407bd50 100644 --- a/PROVESFlightControllerReference/Components/Drv/RtcManager/RtcManager.fpp +++ b/PROVESFlightControllerReference/Components/Drv/RtcManager/RtcManager.fpp @@ -58,10 +58,16 @@ module Drv { useconds: U32 @< Microseconds ) severity activity high id 3 format "Time set on RTC, previous time: {}.{}" - event procTimeSet( + @ ProcTimeSet event indicates that proc time was set + event ProcTimeSet( seconds: U32 @< Uptime in seconds ) severity activity high id 17 format "Proc time set, current uptime: {}" + @ Timebase even fires when the timebase changes and indicates the current timebase + event TimeBase( + timeBase: string size 4 + ) severity activity high id 18 format "Timebase is currently: {}" + @ TimeNotSet event indicates that the time was not set successfully event TimeNotSet(rc: I32) severity warning high id 4 format "Time not set on RTC: {}" From 55aedcfffb181d3a71d8cfa6c9b34154848cf4b5 Mon Sep 17 00:00:00 2001 From: Collin Date: Sat, 25 Jul 2026 02:00:39 -0500 Subject: [PATCH 11/17] updated code --- .../test/int/rtc_test.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/PROVESFlightControllerReference/test/int/rtc_test.py b/PROVESFlightControllerReference/test/int/rtc_test.py index 2c0ec765..f706dc99 100644 --- a/PROVESFlightControllerReference/test/int/rtc_test.py +++ b/PROVESFlightControllerReference/test/int/rtc_test.py @@ -436,3 +436,20 @@ def test_10_double_set_test(fprime_test_api: IntegrationTestAPI, start_gds): fprime_test_api.send_command(f"{rtcManager}.ALARM_SET", [alarm_time_data_str]) # Assert that we receive an AlarmNotSet event within 10 seconds fprime_test_api.await_event(f"{rtcManager}.AlarmNotSet", timeout=10) + + +@pytest.mark.uart_only(reason="Test functionality of to_proc_time") +def test_proc_toggle(fprime_test_api: IntegrationTestAPI, start_gds): + """Test for events emitted by proc time toggle""" + + # Set time to Curiosity landing on Mars (7 minutes of terror! https://youtu.be/Ki_Af_o9Q9s) + curiosity_landing = datetime(2012, 8, 6, 5, 17, 57, tzinfo=timezone.utc) + set_time(fprime_test_api, curiosity_landing) + + # Assert that we receive a TimeBase event within 10 seconds + fprime_test_api.await_event(f"{rtcManager}.TimeBase", timeout=10) + + fprime_test_api.send_command(f"{rtcManager}.TO_PROC_TIME") + + # Assert that we receive a TimeBase event within 10 seconds + fprime_test_api.await_event(f"{rtcManager}.TimeBase", timeout=10) From dc987080973a524a7102f2d183a5e7d45e09aad9 Mon Sep 17 00:00:00 2001 From: Collin Date: Sat, 25 Jul 2026 22:05:03 -0500 Subject: [PATCH 12/17] Don't set proc time if dev not ready --- .../Components/Drv/RtcManager/RtcManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PROVESFlightControllerReference/Components/Drv/RtcManager/RtcManager.cpp b/PROVESFlightControllerReference/Components/Drv/RtcManager/RtcManager.cpp index 824f4327..60b35f4f 100644 --- a/PROVESFlightControllerReference/Components/Drv/RtcManager/RtcManager.cpp +++ b/PROVESFlightControllerReference/Components/Drv/RtcManager/RtcManager.cpp @@ -59,7 +59,7 @@ void RtcManager ::timeGetPort_handler(FwIndexType portNum, Fw::Time& time) { // Check device readiness if (!device_is_ready(this->m_dev)) { this->log_CONSOLE_RtcNotReady(); - this->m_ProcTimeSet = true; // proc time flag + // Don't set the proc time flag if device is not ready // Use uptime as fallback time.set(TimeBase::TB_PROC_TIME, 0, seconds_since_boot, useconds_since_boot); From 1909b0b71c98602e645f0608923655c68a431f82 Mon Sep 17 00:00:00 2001 From: Collin Date: Sun, 26 Jul 2026 03:33:24 -0500 Subject: [PATCH 13/17] change latch --- .../Components/Drv/RtcManager/RtcManager.cpp | 8 ++++++++ .../Components/Drv/RtcManager/RtcManager.fpp | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/PROVESFlightControllerReference/Components/Drv/RtcManager/RtcManager.cpp b/PROVESFlightControllerReference/Components/Drv/RtcManager/RtcManager.cpp index 60b35f4f..a79247b5 100644 --- a/PROVESFlightControllerReference/Components/Drv/RtcManager/RtcManager.cpp +++ b/PROVESFlightControllerReference/Components/Drv/RtcManager/RtcManager.cpp @@ -175,6 +175,14 @@ void RtcManager ::TIME_SET_cmdHandler(FwOpcodeType opCode, U32 cmdSeq, Drv::Time } void RtcManager ::TO_PROC_TIME_cmdHandler(FwOpcodeType opCode, U32 cmdSeq) { + // Cancel any running sequences before setting time, as time change may impact their behavior + for (FwIndexType i = 0; i < this->getNum_cancelSequences_OutputPorts(); i++) { + if (!this->isConnected_cancelSequences_OutputPort(i)) { + continue; + } + this->cancelSequences_out(i); + } + // Switch the time source to proc time Fw::Time proc_time; int64_t t = k_uptime_get(); diff --git a/PROVESFlightControllerReference/Components/Drv/RtcManager/RtcManager.fpp b/PROVESFlightControllerReference/Components/Drv/RtcManager/RtcManager.fpp index f407bd50..4c8d57ad 100644 --- a/PROVESFlightControllerReference/Components/Drv/RtcManager/RtcManager.fpp +++ b/PROVESFlightControllerReference/Components/Drv/RtcManager/RtcManager.fpp @@ -63,7 +63,7 @@ module Drv { seconds: U32 @< Uptime in seconds ) severity activity high id 17 format "Proc time set, current uptime: {}" - @ Timebase even fires when the timebase changes and indicates the current timebase + @ Timebase event fires when the timebase changes and indicates the current timebase event TimeBase( timeBase: string size 4 ) severity activity high id 18 format "Timebase is currently: {}" From a97296e2b481dd1f33ab01882f792751497a3908 Mon Sep 17 00:00:00 2001 From: Collin Date: Sun, 26 Jul 2026 20:45:09 -0500 Subject: [PATCH 14/17] Removed useless variables --- .../Components/Drv/RtcManager/RtcManager.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/PROVESFlightControllerReference/Components/Drv/RtcManager/RtcManager.cpp b/PROVESFlightControllerReference/Components/Drv/RtcManager/RtcManager.cpp index a79247b5..c7fab904 100644 --- a/PROVESFlightControllerReference/Components/Drv/RtcManager/RtcManager.cpp +++ b/PROVESFlightControllerReference/Components/Drv/RtcManager/RtcManager.cpp @@ -184,14 +184,11 @@ void RtcManager ::TO_PROC_TIME_cmdHandler(FwOpcodeType opCode, U32 cmdSeq) { } // Switch the time source to proc time - Fw::Time proc_time; - int64_t t = k_uptime_get(); - U32 seconds_since_boot = static_cast(t / 1000); - U32 useconds_since_boot = static_cast((t % 1000) * 1000); + int64_t uptime = k_uptime_get(); + U32 seconds_since_boot = static_cast(uptime / 1000); this->log_ACTIVITY_HI_ProcTimeSet(seconds_since_boot); // Log the current uptime in seconds this->m_ProcTimeSet = true; // proc time flag - proc_time.set(TimeBase::TB_PROC_TIME, 0, seconds_since_boot, useconds_since_boot); this->log_ACTIVITY_HI_TimeBase(Fw::String("PROC")); // Command response From 0e0589db839779b24d153a9b012fe3cf2b25d7f3 Mon Sep 17 00:00:00 2001 From: Collin Date: Mon, 27 Jul 2026 03:32:15 -0500 Subject: [PATCH 15/17] removed extra flag --- .../Components/Drv/RtcManager/RtcManager.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/PROVESFlightControllerReference/Components/Drv/RtcManager/RtcManager.cpp b/PROVESFlightControllerReference/Components/Drv/RtcManager/RtcManager.cpp index c7fab904..b91a1d79 100644 --- a/PROVESFlightControllerReference/Components/Drv/RtcManager/RtcManager.cpp +++ b/PROVESFlightControllerReference/Components/Drv/RtcManager/RtcManager.cpp @@ -96,8 +96,6 @@ void RtcManager ::timeGetPort_handler(FwIndexType portNum, Fw::Time& time) { } this->log_CONSOLE_RtcInvalidTime_ThrottleClear(); - this->m_ProcTimeSet = false; // proc time flag - // Set FPrime time object time.set(TimeBase::TB_SC_TIME, 0, seconds_real_time, this->m_rtcHelper.rescaleUseconds(seconds_real_time, useconds_since_boot)); From 779e77a8002a18511068f1b9258a714f6a2e375f Mon Sep 17 00:00:00 2001 From: Collin Date: Mon, 27 Jul 2026 03:50:44 -0500 Subject: [PATCH 16/17] I already fixed the typo why isn't this working --- .../Components/Drv/RtcManager/docs/sdd.md | 28 +++++++++++++++++++ .../test/int/rtc_test.py | 2 +- docs-site/components/RtcManager.md | 28 +++++++++++++++++++ 3 files changed, 57 insertions(+), 1 deletion(-) diff --git a/PROVESFlightControllerReference/Components/Drv/RtcManager/docs/sdd.md b/PROVESFlightControllerReference/Components/Drv/RtcManager/docs/sdd.md index a90941d1..51db3a20 100644 --- a/PROVESFlightControllerReference/Components/Drv/RtcManager/docs/sdd.md +++ b/PROVESFlightControllerReference/Components/Drv/RtcManager/docs/sdd.md @@ -11,13 +11,22 @@ The RTC Manager component interfaces with the Real Time Clock (RTC) to provide t 1. The component is instantiated and initialized during system startup 2. A ground station sends a `TIME_SET` command with the desired time 3. On each command, the component: + - Cancels any running sequences - Validates the time data (year >= 1900, month [1-12], day [1-31], hour [0-23], minute [0-59], second [0-59]) - Emits validation failure events if any field is invalid - Sets the time on the RTC if validation passes - Emits a `TimeSet` event with the previous time if the time is set successfully + - Emits a `TimeBase` event with RTC time if time was set successfully - Emits a `TimeNotSet` event if the time is not set successfully - Emits a `DeviceNotReady` event if the device is not ready +#### `TO_PROC_TIME` Command Usage +1. A ground station sends a `TO_PROC_TIME` command to switch the timebase +2. When the command is received the component: + - Cancels any running sequences + - Emits a `TimeBase` event with proc time + - Emits a `ProcTimeSet` event with seconds since boot + #### `ALARM_SET` Command Usage 1. The component is instantiated and initialized during system startup 2. A ground station sends a `ALARM_SET` command with the desired time @@ -99,6 +108,7 @@ This logic applies both when using the RTC (`TB_SC_TIME`) and when in failover m | RtcManager-015 | Alarm is set with an impossible time and an event is emitted, the alarm is not set | Integration test | | RtcManager-016 | Alarm is set and then another alarm is set. An event is emitted and the second alarm is not set | Integration test | | RtcManager-017 | Errors occurring during timeGetPort calls are logged to the console with throttling to prevent flooding | Manual testing and code review | +| RtcManager-018 | Spacecraft switches between RTC time and PROC time and listens for event emission | Integration test | ## Port Descriptions @@ -322,6 +332,24 @@ sequenceDiagram RTC Manager-->>Ground Station: Command response EXECUTION_ERROR ``` +### `TO_PROC_TIME` Command + +The `TO_PROC_TIME` command is called to toggle the timebase + +#### Success + +```mermaid +sequenceDiagram + participant Ground Station + participant Event Log + participant RTC Manager + participant Zephyr RTC API + participant RTC Sensor + + Ground Station->>RTC Manager: Command TO_PROC_TIME + RTC Manager->>RTC Manager: set m_ProcTimeSet to true +``` + ### `ALARM_SET` Command The `ALARM_SET` command is called to set the current time on the RTC alarm. The component validates that the time is in the future before setting the alarm diff --git a/PROVESFlightControllerReference/test/int/rtc_test.py b/PROVESFlightControllerReference/test/int/rtc_test.py index f706dc99..40920492 100644 --- a/PROVESFlightControllerReference/test/int/rtc_test.py +++ b/PROVESFlightControllerReference/test/int/rtc_test.py @@ -439,7 +439,7 @@ def test_10_double_set_test(fprime_test_api: IntegrationTestAPI, start_gds): @pytest.mark.uart_only(reason="Test functionality of to_proc_time") -def test_proc_toggle(fprime_test_api: IntegrationTestAPI, start_gds): +def test_11_proc_toggle(fprime_test_api: IntegrationTestAPI, start_gds): """Test for events emitted by proc time toggle""" # Set time to Curiosity landing on Mars (7 minutes of terror! https://youtu.be/Ki_Af_o9Q9s) diff --git a/docs-site/components/RtcManager.md b/docs-site/components/RtcManager.md index a90941d1..51db3a20 100644 --- a/docs-site/components/RtcManager.md +++ b/docs-site/components/RtcManager.md @@ -11,13 +11,22 @@ The RTC Manager component interfaces with the Real Time Clock (RTC) to provide t 1. The component is instantiated and initialized during system startup 2. A ground station sends a `TIME_SET` command with the desired time 3. On each command, the component: + - Cancels any running sequences - Validates the time data (year >= 1900, month [1-12], day [1-31], hour [0-23], minute [0-59], second [0-59]) - Emits validation failure events if any field is invalid - Sets the time on the RTC if validation passes - Emits a `TimeSet` event with the previous time if the time is set successfully + - Emits a `TimeBase` event with RTC time if time was set successfully - Emits a `TimeNotSet` event if the time is not set successfully - Emits a `DeviceNotReady` event if the device is not ready +#### `TO_PROC_TIME` Command Usage +1. A ground station sends a `TO_PROC_TIME` command to switch the timebase +2. When the command is received the component: + - Cancels any running sequences + - Emits a `TimeBase` event with proc time + - Emits a `ProcTimeSet` event with seconds since boot + #### `ALARM_SET` Command Usage 1. The component is instantiated and initialized during system startup 2. A ground station sends a `ALARM_SET` command with the desired time @@ -99,6 +108,7 @@ This logic applies both when using the RTC (`TB_SC_TIME`) and when in failover m | RtcManager-015 | Alarm is set with an impossible time and an event is emitted, the alarm is not set | Integration test | | RtcManager-016 | Alarm is set and then another alarm is set. An event is emitted and the second alarm is not set | Integration test | | RtcManager-017 | Errors occurring during timeGetPort calls are logged to the console with throttling to prevent flooding | Manual testing and code review | +| RtcManager-018 | Spacecraft switches between RTC time and PROC time and listens for event emission | Integration test | ## Port Descriptions @@ -322,6 +332,24 @@ sequenceDiagram RTC Manager-->>Ground Station: Command response EXECUTION_ERROR ``` +### `TO_PROC_TIME` Command + +The `TO_PROC_TIME` command is called to toggle the timebase + +#### Success + +```mermaid +sequenceDiagram + participant Ground Station + participant Event Log + participant RTC Manager + participant Zephyr RTC API + participant RTC Sensor + + Ground Station->>RTC Manager: Command TO_PROC_TIME + RTC Manager->>RTC Manager: set m_ProcTimeSet to true +``` + ### `ALARM_SET` Command The `ALARM_SET` command is called to set the current time on the RTC alarm. The component validates that the time is in the future before setting the alarm From 3d5dd0fb5d9755d1f8efba241262ee1d3766c856 Mon Sep 17 00:00:00 2001 From: Collin Date: Mon, 27 Jul 2026 13:37:07 -0500 Subject: [PATCH 17/17] remove latch --- .../Components/Drv/RtcManager/RtcManager.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/PROVESFlightControllerReference/Components/Drv/RtcManager/RtcManager.cpp b/PROVESFlightControllerReference/Components/Drv/RtcManager/RtcManager.cpp index b91a1d79..3129d68b 100644 --- a/PROVESFlightControllerReference/Components/Drv/RtcManager/RtcManager.cpp +++ b/PROVESFlightControllerReference/Components/Drv/RtcManager/RtcManager.cpp @@ -72,7 +72,6 @@ void RtcManager ::timeGetPort_handler(FwIndexType portNum, Fw::Time& time) { const int rc = rtc_get_time(this->m_dev, &time_rtc); if (rc != 0) { this->log_CONSOLE_RtcGetTimeFailed(rc); - this->m_ProcTimeSet = true; // proc time flag // Use uptime as fallback time.set(TimeBase::TB_PROC_TIME, 0, seconds_since_boot, useconds_since_boot); @@ -88,7 +87,6 @@ void RtcManager ::timeGetPort_handler(FwIndexType portNum, Fw::Time& time) { U32 seconds_real_time = static_cast(timeutil_timegm(time_tm)); if (errno == ERANGE) { this->log_CONSOLE_RtcInvalidTime(); - this->m_ProcTimeSet = true; // proc time flag // Use uptime as fallback time.set(TimeBase::TB_PROC_TIME, 0, seconds_since_boot, useconds_since_boot);