From 1dad937cb675ea1c6f32864458fcab65e4420676 Mon Sep 17 00:00:00 2001 From: Nate Gay Date: Sat, 6 Sep 2025 21:46:20 -0500 Subject: [PATCH 01/40] Use custom board definition --- .../Top/ReferenceDeploymentTopology.cpp | 2 +- .../Kconfig.defconfig | 14 ++ .../Kconfig.proves_flight_control_board_v5c | 5 + .../board.cmake | 20 +++ .../proves_flight_control_board_v5c/board.yml | 6 + ...oves_flight_control_board_v5c-pinctrl.dtsi | 20 +++ .../proves_flight_control_board_v5c.dtsi | 132 ++++++++++++++++++ ...s_flight_control_board_v5c_rp2350a_m33.dts | 19 +++ ..._flight_control_board_v5c_rp2350a_m33.yaml | 22 +++ ...ht_control_board_v5c_rp2350a_m33_defconfig | 13 ++ .../support/openocd.cfg | 11 ++ boards/rpi_pico.overlay | 11 -- boards/rpi_pico2_rp2350a_m33.overlay | 17 --- boards/teensy40.overlay | 15 -- boards/teensy41.overlay | 15 -- prj.conf | 33 ++++- settings.ini | 3 +- 17 files changed, 296 insertions(+), 62 deletions(-) create mode 100644 boards/bronco_space/proves_flight_control_board_v5c/Kconfig.defconfig create mode 100644 boards/bronco_space/proves_flight_control_board_v5c/Kconfig.proves_flight_control_board_v5c create mode 100644 boards/bronco_space/proves_flight_control_board_v5c/board.cmake create mode 100644 boards/bronco_space/proves_flight_control_board_v5c/board.yml create mode 100644 boards/bronco_space/proves_flight_control_board_v5c/proves_flight_control_board_v5c-pinctrl.dtsi create mode 100644 boards/bronco_space/proves_flight_control_board_v5c/proves_flight_control_board_v5c.dtsi create mode 100644 boards/bronco_space/proves_flight_control_board_v5c/proves_flight_control_board_v5c_rp2350a_m33.dts create mode 100644 boards/bronco_space/proves_flight_control_board_v5c/proves_flight_control_board_v5c_rp2350a_m33.yaml create mode 100644 boards/bronco_space/proves_flight_control_board_v5c/proves_flight_control_board_v5c_rp2350a_m33_defconfig create mode 100644 boards/bronco_space/proves_flight_control_board_v5c/support/openocd.cfg delete mode 100644 boards/rpi_pico.overlay delete mode 100644 boards/rpi_pico2_rp2350a_m33.overlay delete mode 100644 boards/teensy40.overlay delete mode 100644 boards/teensy41.overlay diff --git a/FprimeZephyrReference/ReferenceDeployment/Top/ReferenceDeploymentTopology.cpp b/FprimeZephyrReference/ReferenceDeployment/Top/ReferenceDeploymentTopology.cpp index e9bfd734..4e3bb311 100644 --- a/FprimeZephyrReference/ReferenceDeployment/Top/ReferenceDeploymentTopology.cpp +++ b/FprimeZephyrReference/ReferenceDeployment/Top/ReferenceDeploymentTopology.cpp @@ -13,7 +13,7 @@ #include -static const struct gpio_dt_spec ledGpio = GPIO_DT_SPEC_GET(DT_ALIAS(led0), gpios); +static const struct gpio_dt_spec ledGpio = GPIO_DT_SPEC_GET(DT_NODELABEL(led0), gpios); // Allows easy reference to objects in FPP/autocoder required namespaces using namespace ReferenceDeployment; diff --git a/boards/bronco_space/proves_flight_control_board_v5c/Kconfig.defconfig b/boards/bronco_space/proves_flight_control_board_v5c/Kconfig.defconfig new file mode 100644 index 00000000..296c23fc --- /dev/null +++ b/boards/bronco_space/proves_flight_control_board_v5c/Kconfig.defconfig @@ -0,0 +1,14 @@ +# Copyright (c) 2024 Andrew Featherstone +# SPDX-License-Identifier: Apache-2.0 + +if PROVES_FLIGHT_CONTROL_BOARD_V5C + +config USB_SELF_POWERED + default n + +config USB_CDC_ACM_LOG_LEVEL + default 0 + +config USB_DEVICE_LOG_LEVEL + default 1 +endif # PROVES_FLIGHT_CONTROL_BOARD_V5C diff --git a/boards/bronco_space/proves_flight_control_board_v5c/Kconfig.proves_flight_control_board_v5c b/boards/bronco_space/proves_flight_control_board_v5c/Kconfig.proves_flight_control_board_v5c new file mode 100644 index 00000000..805f5070 --- /dev/null +++ b/boards/bronco_space/proves_flight_control_board_v5c/Kconfig.proves_flight_control_board_v5c @@ -0,0 +1,5 @@ +# Copyright (c) 2024 Andrew Featherstone +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_PROVES_FLIGHT_CONTROL_BOARD_V5C + select SOC_RP2350A_M33 if BOARD_PROVES_FLIGHT_CONTROL_BOARD_V5C_RP2350A_M33 diff --git a/boards/bronco_space/proves_flight_control_board_v5c/board.cmake b/boards/bronco_space/proves_flight_control_board_v5c/board.cmake new file mode 100644 index 00000000..dc6406b4 --- /dev/null +++ b/boards/bronco_space/proves_flight_control_board_v5c/board.cmake @@ -0,0 +1,20 @@ +# SPDX-License-Identifier: Apache-2.0 + +if("${RPI_PICO_DEBUG_ADAPTER}" STREQUAL "") + set(RPI_PICO_DEBUG_ADAPTER "cmsis-dap") +endif() + +board_runner_args(openocd --cmd-pre-init "source [find interface/${RPI_PICO_DEBUG_ADAPTER}.cfg]") +board_runner_args(openocd --cmd-pre-init "source [find target/rp2350.cfg]") + +# The adapter speed is expected to be set by interface configuration. +# The Raspberry Pi's OpenOCD fork doesn't, so match their documentation at +# https://www.raspberrypi.com/documentation/microcontrollers/debug-probe.html#debugging-with-swd +board_runner_args(openocd --cmd-pre-init "set_adapter_speed_if_not_set 5000") + +board_runner_args(jlink "--device=RP2350_M33_0") +board_runner_args(uf2 "--board-id=RP2350") + +include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) +include(${ZEPHYR_BASE}/boards/common/uf2.board.cmake) diff --git a/boards/bronco_space/proves_flight_control_board_v5c/board.yml b/boards/bronco_space/proves_flight_control_board_v5c/board.yml new file mode 100644 index 00000000..8fcf693e --- /dev/null +++ b/boards/bronco_space/proves_flight_control_board_v5c/board.yml @@ -0,0 +1,6 @@ +board: + name: proves_flight_control_board_v5c + full_name: PROVES Flight Control Board v5c + vendor: Bronco Space + socs: + - name: rp2350a diff --git a/boards/bronco_space/proves_flight_control_board_v5c/proves_flight_control_board_v5c-pinctrl.dtsi b/boards/bronco_space/proves_flight_control_board_v5c/proves_flight_control_board_v5c-pinctrl.dtsi new file mode 100644 index 00000000..012ca613 --- /dev/null +++ b/boards/bronco_space/proves_flight_control_board_v5c/proves_flight_control_board_v5c-pinctrl.dtsi @@ -0,0 +1,20 @@ +#include + +&pinctrl { + spi1_default: spi1_default { + group1 { + pinmux = , ; + }; + + group2 { + pinmux = ; + input-enable; + }; + }; + i2c1_default: i2c1_default { + group1 { + pinmux = , ; + input-enable; + }; + }; +}; diff --git a/boards/bronco_space/proves_flight_control_board_v5c/proves_flight_control_board_v5c.dtsi b/boards/bronco_space/proves_flight_control_board_v5c/proves_flight_control_board_v5c.dtsi new file mode 100644 index 00000000..1583eaa0 --- /dev/null +++ b/boards/bronco_space/proves_flight_control_board_v5c/proves_flight_control_board_v5c.dtsi @@ -0,0 +1,132 @@ +#include + +#include +#include + +#include "proves_flight_control_board_v5c-pinctrl.dtsi" + +/ { + chosen { + zephyr,sram = &sram0; + zephyr,flash = &flash0; + zephyr,console = &cdc_acm_uart0; + zephyr,shell-uart = &cdc_acm_uart0; + zephyr,code-partition = &code_partition; + }; + + aliases { + watchdog0 = &wdt0; + }; + + leds { + compatible = "gpio-leds"; + led0: led0 { + gpios = <&gpio0 24 GPIO_ACTIVE_HIGH>; + label = "User LED GPIO24"; + }; + }; +}; + +zephyr_udc0: &usbd { + status = "okay"; +}; + +&zephyr_udc0 { + cdc_acm_uart0: cdc_acm_uart0 { + compatible = "zephyr,cdc-acm-uart"; + label = "CDC_ACM_0"; + }; +}; + +&flash0 { + reg = <0x10000000 DT_SIZE_M(4)>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + /* Reserved memory for an image definition block. The block is much + * smaller than 256 bytes, but in practice the linker places the vector + * table at a much larger alignment offset. + */ + image_def: partition@0 { + label = "image_def"; + reg = <0x00000000 0x100>; + read-only; + }; + + /* + * Usable flash. Starts at 0x100, after the image definition block. + * The partition size is 4MB minus the 0x100 bytes taken by the + * image definition. + */ + code_partition: partition@100 { + label = "code-partition"; + reg = <0x100 (DT_SIZE_M(4) - 0x100)>; + read-only; + }; + }; +}; + +&timer0 { + status = "okay"; +}; + +&wdt0 { + status = "okay"; +}; + +&gpio0 { + status = "okay"; +}; + +&spi1 { + status = "okay"; + cs-gpios = <&gpio0 9 GPIO_ACTIVE_LOW>; + pinctrl-0 = <&spi1_default>; + pinctrl-names = "default"; + + lora0: sx1276@0 { + compatible = "semtech,sx1276"; + reg = <0>; + spi-max-frequency = <125000>; + dio-gpios = <&gpio0 13 (GPIO_PULL_DOWN | GPIO_ACTIVE_HIGH)>,<&gpio0 12 (GPIO_PULL_DOWN | GPIO_ACTIVE_HIGH)>; + reset-gpios = <&gpio0 6 GPIO_ACTIVE_LOW>; + power-amplifier-output = "pa-boost"; + label = "HOPE_RF"; + }; +}; + +&i2c1 { + status = "okay"; + pinctrl-0 = <&i2c1_default>; + pinctrl-names = "default"; + clock-frequency = <100000>; + + lsm6dso0: lsm6dso0@6b { + compatible = "st,lsm6dso"; + reg = <0x6b>; + label = "LSM6DSO"; + }; + + lis2mdl: lis2mdl@1e { + compatible = "st,lis2mdl"; + reg = <0x1e>; + label = "LIS2MDL"; + }; + rv3028: rv3028@52 { + compatible = "microcrystal,rv3028"; + reg = <0x52>; + int-gpios = <&gpio0 27 GPIO_ACTIVE_HIGH>; + backup-switch-mode = "level"; + label = "RV3028"; + }; + ina219: ina219@40 { + compatible = "ti,ina219"; + reg = <0x40>; + shunt-milliohm = <2>; + lsb-microamp = <100>; + label = "INA219"; + }; +}; diff --git a/boards/bronco_space/proves_flight_control_board_v5c/proves_flight_control_board_v5c_rp2350a_m33.dts b/boards/bronco_space/proves_flight_control_board_v5c/proves_flight_control_board_v5c_rp2350a_m33.dts new file mode 100644 index 00000000..dc57761a --- /dev/null +++ b/boards/bronco_space/proves_flight_control_board_v5c/proves_flight_control_board_v5c_rp2350a_m33.dts @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2024 Andrew Featherstone + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +/* The build system assumes that there's a cpucluster-specific file. + * + * This file provides composition of the device tree: + * 1. The common features of the SoC + * 2. Core-specific configuration. + * 3. Board-specific configuration. + */ +#include +#include + +#include "proves_flight_control_board_v5c.dtsi" diff --git a/boards/bronco_space/proves_flight_control_board_v5c/proves_flight_control_board_v5c_rp2350a_m33.yaml b/boards/bronco_space/proves_flight_control_board_v5c/proves_flight_control_board_v5c_rp2350a_m33.yaml new file mode 100644 index 00000000..847a3eb5 --- /dev/null +++ b/boards/bronco_space/proves_flight_control_board_v5c/proves_flight_control_board_v5c_rp2350a_m33.yaml @@ -0,0 +1,22 @@ +identifier: proves_flight_control_board_v5c/rp2350a/m33 +name: PROVES Flight Control Board v5c (RP2350, Cortex-M33) +type: mcu +arch: arm +flash: 4096 +ram: 520 +toolchain: + - zephyr + - gnuarmemb +supported: + - adc + - clock + - counter + - dma + - gpio + - hwinfo + - i2c + - pwm + - spi + - uart + - usbd + - watchdog diff --git a/boards/bronco_space/proves_flight_control_board_v5c/proves_flight_control_board_v5c_rp2350a_m33_defconfig b/boards/bronco_space/proves_flight_control_board_v5c/proves_flight_control_board_v5c_rp2350a_m33_defconfig new file mode 100644 index 00000000..ff74ead6 --- /dev/null +++ b/boards/bronco_space/proves_flight_control_board_v5c/proves_flight_control_board_v5c_rp2350a_m33_defconfig @@ -0,0 +1,13 @@ +CONFIG_BUILD_OUTPUT_HEX=y +CONFIG_BUILD_OUTPUT_UF2=y +CONFIG_CLOCK_CONTROL=y +CONFIG_CONSOLE=y +CONFIG_GPIO=y +CONFIG_RESET=y +CONFIG_SERIAL=y +CONFIG_UART_CONSOLE=y +CONFIG_UART_INTERRUPT_DRIVEN=y +CONFIG_USE_DT_CODE_PARTITION=y +CONFIG_USB_DEVICE_STACK=y +CONFIG_USB_DEVICE_PRODUCT="PROVES Flight Control Board v5c" +CONFIG_USB_DEVICE_VID=0x0028 diff --git a/boards/bronco_space/proves_flight_control_board_v5c/support/openocd.cfg b/boards/bronco_space/proves_flight_control_board_v5c/support/openocd.cfg new file mode 100644 index 00000000..82666bb5 --- /dev/null +++ b/boards/bronco_space/proves_flight_control_board_v5c/support/openocd.cfg @@ -0,0 +1,11 @@ +# Copyright (c) 2024 TOKITA Hiroshi +# SPDX-License-Identifier: Apache-2.0 + +# Checking and set 'adapter speed'. +# Set the adaptor speed, if unset, and given as an argument. +proc set_adapter_speed_if_not_set { speed } { + puts "checking adapter speed..." + if { [catch {adapter speed} ret] } { + adapter speed $speed + } +} diff --git a/boards/rpi_pico.overlay b/boards/rpi_pico.overlay deleted file mode 100644 index 6abcbcfe..00000000 --- a/boards/rpi_pico.overlay +++ /dev/null @@ -1,11 +0,0 @@ -&zephyr_udc0 { - cdc_acm_uart0: cdc_acm_uart0 { - compatible = "zephyr,cdc-acm-uart"; - }; -}; - -/ { - chosen { - zephyr,console = &cdc_acm_uart0; - }; -}; diff --git a/boards/rpi_pico2_rp2350a_m33.overlay b/boards/rpi_pico2_rp2350a_m33.overlay deleted file mode 100644 index ea7ecb55..00000000 --- a/boards/rpi_pico2_rp2350a_m33.overlay +++ /dev/null @@ -1,17 +0,0 @@ -&zephyr_udc0 { - cdc_acm_uart0: cdc_acm_uart0 { - compatible = "zephyr,cdc-acm-uart"; - }; -}; - -/ { - chosen { - zephyr,console = &cdc_acm_uart0; - }; -}; - -/* Override the default LED definition to use GPIO 24 instead of GPIO 25 for PROVES FC board*/ -&led0 { - gpios = <&gpio0 24 GPIO_ACTIVE_HIGH>; - label = "User LED GPIO24"; -}; diff --git a/boards/teensy40.overlay b/boards/teensy40.overlay deleted file mode 100644 index 8f7d324b..00000000 --- a/boards/teensy40.overlay +++ /dev/null @@ -1,15 +0,0 @@ -&zephyr_udc0 { - cdc_acm_uart0: cdc_acm_uart0 { - compatible = "zephyr,cdc-acm-uart"; - }; -}; - -&lpuart1 { - status = "okay"; - current-speed = < 115200 >; -}; - -&lpuart2 { - status = "okay"; - current-speed = < 115200 >; -}; diff --git a/boards/teensy41.overlay b/boards/teensy41.overlay deleted file mode 100644 index 8f7d324b..00000000 --- a/boards/teensy41.overlay +++ /dev/null @@ -1,15 +0,0 @@ -&zephyr_udc0 { - cdc_acm_uart0: cdc_acm_uart0 { - compatible = "zephyr,cdc-acm-uart"; - }; -}; - -&lpuart1 { - status = "okay"; - current-speed = < 115200 >; -}; - -&lpuart2 { - status = "okay"; - current-speed = < 115200 >; -}; diff --git a/prj.conf b/prj.conf index 7bb63394..a6ec0633 100644 --- a/prj.conf +++ b/prj.conf @@ -35,8 +35,8 @@ CONFIG_SERIAL=y CONFIG_GPIO=y CONFIG_LED=y CONFIG_PWM=n -CONFIG_I2C=n -CONFIG_SPI=n +CONFIG_I2C=y +CONFIG_SPI=y CONFIG_PINCTRL=y CONFIG_ASSERT=y @@ -55,3 +55,32 @@ CONFIG_RING_BUFFER=y CONFIG_PRINTK=y CONFIG_UART_CONSOLE=y CONFIG_COMMON_LIBC_MALLOC=y + +# Sensors +CONFIG_SENSOR=y +CONFIG_LSM6DSO=y +CONFIG_LSM6DSO_ENABLE_TEMP=y +CONFIG_LIS2MDL=y +CONFIG_INA219=y + +# Zbus +# CONFIG_ZBUS=y +# CONFIG_ZBUS_CHANNEL_NAME=y +# CONFIG_ZBUS_OBSERVER_NAME=y +# CONFIG_ZBUS_MSG_SUBSCRIBER=y +# CONFIG_ZBUS_LOG_LEVEL_DBG=n +# CONFIG_ZBUS_LOG_LEVEL_INF=y + +# Lora +CONFIG_LORA=y +CONFIG_LORA_SX127X=y + +# RTC +CONFIG_RTC=y +CONFIG_RTC_RV3028=y + +# Logging +CONFIG_LOG=y +CONFIG_LOG_DEFAULT_LEVEL=3 +# Compiler settings +CONFIG_CBPRINTF_FP_SUPPORT=y diff --git a/settings.ini b/settings.ini index 888a8df8..d27e929f 100644 --- a/settings.ini +++ b/settings.ini @@ -6,4 +6,5 @@ default_toolchain: zephyr default_cmake_options: FPRIME_ENABLE_FRAMEWORK_UTS=OFF FPRIME_ENABLE_AUTOCODER_UTS=OFF - BOARD=rpi_pico2/rp2350a/m33 + BOARD_ROOT=. + BOARD=proves_flight_control_board_v5c/rp2350a/m33 From 7fd3d7b6790472fabc14a6f62f22baa6fe50b59d Mon Sep 17 00:00:00 2001 From: Nate Gay Date: Mon, 8 Sep 2025 17:57:48 -0500 Subject: [PATCH 02/40] Remove commented config --- prj.conf | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/prj.conf b/prj.conf index a6ec0633..ebef3fc3 100644 --- a/prj.conf +++ b/prj.conf @@ -1,17 +1,9 @@ #### Configure Device VID and PID --> Uncomment the desired device definitions #### -#### From Teensy41 USB definitions #### -# CONFIG_USB_DEVICE_VID=0x16C0 -# CONFIG_USB_DEVICE_PID=0x0483 - #### From Raspberry Pi Pico2 USB Definitions #### CONFIG_USB_DEVICE_PID=0x000F CONFIG_USB_DEVICE_VID=0x2E8A -#### From Raspberry Pi Pico USB Definitions #### -# CONFIG_USB_DEVICE_PID=0x0003 -# CONFIG_USB_DEVICE_VID=0x2E8A - #### F Prime C++ Dependencies #### CONFIG_CPP=y CONFIG_REQUIRES_FULL_LIBCPP=y @@ -63,14 +55,6 @@ CONFIG_LSM6DSO_ENABLE_TEMP=y CONFIG_LIS2MDL=y CONFIG_INA219=y -# Zbus -# CONFIG_ZBUS=y -# CONFIG_ZBUS_CHANNEL_NAME=y -# CONFIG_ZBUS_OBSERVER_NAME=y -# CONFIG_ZBUS_MSG_SUBSCRIBER=y -# CONFIG_ZBUS_LOG_LEVEL_DBG=n -# CONFIG_ZBUS_LOG_LEVEL_INF=y - # Lora CONFIG_LORA=y CONFIG_LORA_SX127X=y From bbf35a31f69e22d23cc266311501cf59f516c9a1 Mon Sep 17 00:00:00 2001 From: Nate Gay Date: Fri, 12 Sep 2025 17:36:40 -0500 Subject: [PATCH 03/40] Moving prj.conf sensors to board definition --- ...light_control_board_v5c_rp2350a_m33_defconfig | 14 ++++++++++++++ prj.conf | 16 +--------------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/boards/bronco_space/proves_flight_control_board_v5c/proves_flight_control_board_v5c_rp2350a_m33_defconfig b/boards/bronco_space/proves_flight_control_board_v5c/proves_flight_control_board_v5c_rp2350a_m33_defconfig index ff74ead6..6dcb23e3 100644 --- a/boards/bronco_space/proves_flight_control_board_v5c/proves_flight_control_board_v5c_rp2350a_m33_defconfig +++ b/boards/bronco_space/proves_flight_control_board_v5c/proves_flight_control_board_v5c_rp2350a_m33_defconfig @@ -11,3 +11,17 @@ CONFIG_USE_DT_CODE_PARTITION=y CONFIG_USB_DEVICE_STACK=y CONFIG_USB_DEVICE_PRODUCT="PROVES Flight Control Board v5c" CONFIG_USB_DEVICE_VID=0x0028 + +# Sensors +CONFIG_LSM6DSO=y +CONFIG_LSM6DSO_ENABLE_TEMP=y +CONFIG_LIS2MDL=y +CONFIG_INA219=y + +# Lora +CONFIG_LORA=y +CONFIG_LORA_SX127X=y + +# RTC +CONFIG_RTC=y +CONFIG_RTC_RV3028=y diff --git a/prj.conf b/prj.conf index ebef3fc3..96d07ad7 100644 --- a/prj.conf +++ b/prj.conf @@ -48,23 +48,9 @@ CONFIG_PRINTK=y CONFIG_UART_CONSOLE=y CONFIG_COMMON_LIBC_MALLOC=y -# Sensors CONFIG_SENSOR=y -CONFIG_LSM6DSO=y -CONFIG_LSM6DSO_ENABLE_TEMP=y -CONFIG_LIS2MDL=y -CONFIG_INA219=y -# Lora -CONFIG_LORA=y -CONFIG_LORA_SX127X=y - -# RTC -CONFIG_RTC=y -CONFIG_RTC_RV3028=y - -# Logging CONFIG_LOG=y CONFIG_LOG_DEFAULT_LEVEL=3 -# Compiler settings + CONFIG_CBPRINTF_FP_SUPPORT=y From 57e4183bb3840d4fed798a4e489b725d441eb985 Mon Sep 17 00:00:00 2001 From: Nate Gay Date: Fri, 12 Sep 2025 17:54:46 -0500 Subject: [PATCH 04/40] Add d board --- .../Kconfig.defconfig | 14 ++ .../Kconfig.proves_flight_control_board_v5d | 5 + .../board.cmake | 20 +++ .../proves_flight_control_board_v5d/board.yml | 6 + ...oves_flight_control_board_v5d-pinctrl.dtsi | 20 +++ .../proves_flight_control_board_v5d.dtsi | 132 ++++++++++++++++++ ...s_flight_control_board_v5d_rp2350a_m33.dts | 19 +++ ..._flight_control_board_v5d_rp2350a_m33.yaml | 22 +++ ...ht_control_board_v5d_rp2350a_m33_defconfig | 27 ++++ .../support/openocd.cfg | 11 ++ settings.ini | 2 +- 11 files changed, 277 insertions(+), 1 deletion(-) create mode 100644 boards/bronco_space/proves_flight_control_board_v5d/Kconfig.defconfig create mode 100644 boards/bronco_space/proves_flight_control_board_v5d/Kconfig.proves_flight_control_board_v5d create mode 100644 boards/bronco_space/proves_flight_control_board_v5d/board.cmake create mode 100644 boards/bronco_space/proves_flight_control_board_v5d/board.yml create mode 100644 boards/bronco_space/proves_flight_control_board_v5d/proves_flight_control_board_v5d-pinctrl.dtsi create mode 100644 boards/bronco_space/proves_flight_control_board_v5d/proves_flight_control_board_v5d.dtsi create mode 100644 boards/bronco_space/proves_flight_control_board_v5d/proves_flight_control_board_v5d_rp2350a_m33.dts create mode 100644 boards/bronco_space/proves_flight_control_board_v5d/proves_flight_control_board_v5d_rp2350a_m33.yaml create mode 100644 boards/bronco_space/proves_flight_control_board_v5d/proves_flight_control_board_v5d_rp2350a_m33_defconfig create mode 100644 boards/bronco_space/proves_flight_control_board_v5d/support/openocd.cfg diff --git a/boards/bronco_space/proves_flight_control_board_v5d/Kconfig.defconfig b/boards/bronco_space/proves_flight_control_board_v5d/Kconfig.defconfig new file mode 100644 index 00000000..d96b8a3f --- /dev/null +++ b/boards/bronco_space/proves_flight_control_board_v5d/Kconfig.defconfig @@ -0,0 +1,14 @@ +# Copyright (c) 2024 Andrew Featherstone +# SPDX-License-Identifier: Apache-2.0 + +if PROVES_FLIGHT_CONTROL_BOARD_V5D + +config USB_SELF_POWERED + default n + +config USB_CDC_ACM_LOG_LEVEL + default 0 + +config USB_DEVICE_LOG_LEVEL + default 1 +endif # PROVES_FLIGHT_CONTROL_BOARD_V5D diff --git a/boards/bronco_space/proves_flight_control_board_v5d/Kconfig.proves_flight_control_board_v5d b/boards/bronco_space/proves_flight_control_board_v5d/Kconfig.proves_flight_control_board_v5d new file mode 100644 index 00000000..a4ae3506 --- /dev/null +++ b/boards/bronco_space/proves_flight_control_board_v5d/Kconfig.proves_flight_control_board_v5d @@ -0,0 +1,5 @@ +# Copyright (c) 2024 Andrew Featherstone +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_PROVES_FLIGHT_CONTROL_BOARD_V5D + select SOC_RP2350A_M33 if BOARD_PROVES_FLIGHT_CONTROL_BOARD_V5D_RP2350A_M33 diff --git a/boards/bronco_space/proves_flight_control_board_v5d/board.cmake b/boards/bronco_space/proves_flight_control_board_v5d/board.cmake new file mode 100644 index 00000000..dc6406b4 --- /dev/null +++ b/boards/bronco_space/proves_flight_control_board_v5d/board.cmake @@ -0,0 +1,20 @@ +# SPDX-License-Identifier: Apache-2.0 + +if("${RPI_PICO_DEBUG_ADAPTER}" STREQUAL "") + set(RPI_PICO_DEBUG_ADAPTER "cmsis-dap") +endif() + +board_runner_args(openocd --cmd-pre-init "source [find interface/${RPI_PICO_DEBUG_ADAPTER}.cfg]") +board_runner_args(openocd --cmd-pre-init "source [find target/rp2350.cfg]") + +# The adapter speed is expected to be set by interface configuration. +# The Raspberry Pi's OpenOCD fork doesn't, so match their documentation at +# https://www.raspberrypi.com/documentation/microcontrollers/debug-probe.html#debugging-with-swd +board_runner_args(openocd --cmd-pre-init "set_adapter_speed_if_not_set 5000") + +board_runner_args(jlink "--device=RP2350_M33_0") +board_runner_args(uf2 "--board-id=RP2350") + +include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) +include(${ZEPHYR_BASE}/boards/common/uf2.board.cmake) diff --git a/boards/bronco_space/proves_flight_control_board_v5d/board.yml b/boards/bronco_space/proves_flight_control_board_v5d/board.yml new file mode 100644 index 00000000..32c6ada0 --- /dev/null +++ b/boards/bronco_space/proves_flight_control_board_v5d/board.yml @@ -0,0 +1,6 @@ +board: + name: proves_flight_control_board_v5d + full_name: PROVES Flight Control Board v5d + vendor: Bronco Space + socs: + - name: rp2350a diff --git a/boards/bronco_space/proves_flight_control_board_v5d/proves_flight_control_board_v5d-pinctrl.dtsi b/boards/bronco_space/proves_flight_control_board_v5d/proves_flight_control_board_v5d-pinctrl.dtsi new file mode 100644 index 00000000..012ca613 --- /dev/null +++ b/boards/bronco_space/proves_flight_control_board_v5d/proves_flight_control_board_v5d-pinctrl.dtsi @@ -0,0 +1,20 @@ +#include + +&pinctrl { + spi1_default: spi1_default { + group1 { + pinmux = , ; + }; + + group2 { + pinmux = ; + input-enable; + }; + }; + i2c1_default: i2c1_default { + group1 { + pinmux = , ; + input-enable; + }; + }; +}; diff --git a/boards/bronco_space/proves_flight_control_board_v5d/proves_flight_control_board_v5d.dtsi b/boards/bronco_space/proves_flight_control_board_v5d/proves_flight_control_board_v5d.dtsi new file mode 100644 index 00000000..89032e94 --- /dev/null +++ b/boards/bronco_space/proves_flight_control_board_v5d/proves_flight_control_board_v5d.dtsi @@ -0,0 +1,132 @@ +#include + +#include +#include + +#include "proves_flight_control_board_v5d-pinctrl.dtsi" + +/ { + chosen { + zephyr,sram = &sram0; + zephyr,flash = &flash0; + zephyr,console = &cdc_acm_uart0; + zephyr,shell-uart = &cdc_acm_uart0; + zephyr,code-partition = &code_partition; + }; + + aliases { + watchdog0 = &wdt0; + }; + + leds { + compatible = "gpio-leds"; + led0: led0 { + gpios = <&gpio0 23 GPIO_ACTIVE_HIGH>; + label = "User LED GPIO23"; + }; + }; +}; + +zephyr_udc0: &usbd { + status = "okay"; +}; + +&zephyr_udc0 { + cdc_acm_uart0: cdc_acm_uart0 { + compatible = "zephyr,cdc-acm-uart"; + label = "CDC_ACM_0"; + }; +}; + +&flash0 { + reg = <0x10000000 DT_SIZE_M(4)>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + /* Reserved memory for an image definition block. The block is much + * smaller than 256 bytes, but in practice the linker places the vector + * table at a much larger alignment offset. + */ + image_def: partition@0 { + label = "image_def"; + reg = <0x00000000 0x100>; + read-only; + }; + + /* + * Usable flash. Starts at 0x100, after the image definition block. + * The partition size is 4MB minus the 0x100 bytes taken by the + * image definition. + */ + code_partition: partition@100 { + label = "code-partition"; + reg = <0x100 (DT_SIZE_M(4) - 0x100)>; + read-only; + }; + }; +}; + +&timer0 { + status = "okay"; +}; + +&wdt0 { + status = "okay"; +}; + +&gpio0 { + status = "okay"; +}; + +&spi1 { + status = "okay"; + cs-gpios = <&gpio0 9 GPIO_ACTIVE_LOW>; + pinctrl-0 = <&spi1_default>; + pinctrl-names = "default"; + + lora0: sx1276@0 { + compatible = "semtech,sx1276"; + reg = <0>; + spi-max-frequency = <125000>; + dio-gpios = <&gpio0 13 (GPIO_PULL_DOWN | GPIO_ACTIVE_HIGH)>,<&gpio0 12 (GPIO_PULL_DOWN | GPIO_ACTIVE_HIGH)>; + reset-gpios = <&gpio0 6 GPIO_ACTIVE_LOW>; + power-amplifier-output = "pa-boost"; + label = "HOPE_RF"; + }; +}; + +&i2c1 { + status = "okay"; + pinctrl-0 = <&i2c1_default>; + pinctrl-names = "default"; + clock-frequency = <100000>; + + lsm6dso0: lsm6dso0@6b { + compatible = "st,lsm6dso"; + reg = <0x6b>; + label = "LSM6DSO"; + }; + + lis2mdl: lis2mdl@1e { + compatible = "st,lis2mdl"; + reg = <0x1e>; + label = "LIS2MDL"; + }; + rv3028: rv3028@52 { + compatible = "microcrystal,rv3028"; + reg = <0x52>; + int-gpios = <&gpio0 27 GPIO_ACTIVE_HIGH>; + backup-switch-mode = "level"; + label = "RV3028"; + }; + ina219: ina219@40 { + compatible = "ti,ina219"; + reg = <0x40>; + shunt-milliohm = <2>; + lsb-microamp = <100>; + label = "INA219"; + }; +}; diff --git a/boards/bronco_space/proves_flight_control_board_v5d/proves_flight_control_board_v5d_rp2350a_m33.dts b/boards/bronco_space/proves_flight_control_board_v5d/proves_flight_control_board_v5d_rp2350a_m33.dts new file mode 100644 index 00000000..92124e73 --- /dev/null +++ b/boards/bronco_space/proves_flight_control_board_v5d/proves_flight_control_board_v5d_rp2350a_m33.dts @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2024 Andrew Featherstone + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +/* The build system assumes that there's a cpucluster-specific file. + * + * This file provides composition of the device tree: + * 1. The common features of the SoC + * 2. Core-specific configuration. + * 3. Board-specific configuration. + */ +#include +#include + +#include "proves_flight_control_board_v5d.dtsi" diff --git a/boards/bronco_space/proves_flight_control_board_v5d/proves_flight_control_board_v5d_rp2350a_m33.yaml b/boards/bronco_space/proves_flight_control_board_v5d/proves_flight_control_board_v5d_rp2350a_m33.yaml new file mode 100644 index 00000000..6880c0c1 --- /dev/null +++ b/boards/bronco_space/proves_flight_control_board_v5d/proves_flight_control_board_v5d_rp2350a_m33.yaml @@ -0,0 +1,22 @@ +identifier: proves_flight_control_board_v5d/rp2350a/m33 +name: PROVES Flight Control Board v5d (RP2350, Cortex-M33) +type: mcu +arch: arm +flash: 4096 +ram: 520 +toolchain: + - zephyr + - gnuarmemb +supported: + - adc + - clock + - counter + - dma + - gpio + - hwinfo + - i2c + - pwm + - spi + - uart + - usbd + - watchdog diff --git a/boards/bronco_space/proves_flight_control_board_v5d/proves_flight_control_board_v5d_rp2350a_m33_defconfig b/boards/bronco_space/proves_flight_control_board_v5d/proves_flight_control_board_v5d_rp2350a_m33_defconfig new file mode 100644 index 00000000..cc694df0 --- /dev/null +++ b/boards/bronco_space/proves_flight_control_board_v5d/proves_flight_control_board_v5d_rp2350a_m33_defconfig @@ -0,0 +1,27 @@ +CONFIG_BUILD_OUTPUT_HEX=y +CONFIG_BUILD_OUTPUT_UF2=y +CONFIG_CLOCK_CONTROL=y +CONFIG_CONSOLE=y +CONFIG_GPIO=y +CONFIG_RESET=y +CONFIG_SERIAL=y +CONFIG_UART_CONSOLE=y +CONFIG_UART_INTERRUPT_DRIVEN=y +CONFIG_USE_DT_CODE_PARTITION=y +CONFIG_USB_DEVICE_STACK=y +CONFIG_USB_DEVICE_PRODUCT="PROVES Flight Control Board v5d" +CONFIG_USB_DEVICE_VID=0x0028 + +# Sensors +CONFIG_LSM6DSO=y +CONFIG_LSM6DSO_ENABLE_TEMP=y +CONFIG_LIS2MDL=y +CONFIG_INA219=y + +# Lora +CONFIG_LORA=y +CONFIG_LORA_SX127X=y + +# RTC +CONFIG_RTC=y +CONFIG_RTC_RV3028=y diff --git a/boards/bronco_space/proves_flight_control_board_v5d/support/openocd.cfg b/boards/bronco_space/proves_flight_control_board_v5d/support/openocd.cfg new file mode 100644 index 00000000..82666bb5 --- /dev/null +++ b/boards/bronco_space/proves_flight_control_board_v5d/support/openocd.cfg @@ -0,0 +1,11 @@ +# Copyright (c) 2024 TOKITA Hiroshi +# SPDX-License-Identifier: Apache-2.0 + +# Checking and set 'adapter speed'. +# Set the adaptor speed, if unset, and given as an argument. +proc set_adapter_speed_if_not_set { speed } { + puts "checking adapter speed..." + if { [catch {adapter speed} ret] } { + adapter speed $speed + } +} diff --git a/settings.ini b/settings.ini index d27e929f..dde51b9e 100644 --- a/settings.ini +++ b/settings.ini @@ -7,4 +7,4 @@ default_toolchain: zephyr default_cmake_options: FPRIME_ENABLE_FRAMEWORK_UTS=OFF FPRIME_ENABLE_AUTOCODER_UTS=OFF BOARD_ROOT=. - BOARD=proves_flight_control_board_v5c/rp2350a/m33 + BOARD=proves_flight_control_board_v5d/rp2350a/m33 From e98a4346fb847853308c3957b9ad51926b8b78ee Mon Sep 17 00:00:00 2001 From: Nate Gay Date: Fri, 12 Sep 2025 18:06:03 -0500 Subject: [PATCH 05/40] Try referencing c definitions in d board --- ...oves_flight_control_board_v5d-pinctrl.dtsi | 20 --- .../proves_flight_control_board_v5d.dtsi | 130 +----------------- 2 files changed, 5 insertions(+), 145 deletions(-) delete mode 100644 boards/bronco_space/proves_flight_control_board_v5d/proves_flight_control_board_v5d-pinctrl.dtsi diff --git a/boards/bronco_space/proves_flight_control_board_v5d/proves_flight_control_board_v5d-pinctrl.dtsi b/boards/bronco_space/proves_flight_control_board_v5d/proves_flight_control_board_v5d-pinctrl.dtsi deleted file mode 100644 index 012ca613..00000000 --- a/boards/bronco_space/proves_flight_control_board_v5d/proves_flight_control_board_v5d-pinctrl.dtsi +++ /dev/null @@ -1,20 +0,0 @@ -#include - -&pinctrl { - spi1_default: spi1_default { - group1 { - pinmux = , ; - }; - - group2 { - pinmux = ; - input-enable; - }; - }; - i2c1_default: i2c1_default { - group1 { - pinmux = , ; - input-enable; - }; - }; -}; diff --git a/boards/bronco_space/proves_flight_control_board_v5d/proves_flight_control_board_v5d.dtsi b/boards/bronco_space/proves_flight_control_board_v5d/proves_flight_control_board_v5d.dtsi index 89032e94..8d98535a 100644 --- a/boards/bronco_space/proves_flight_control_board_v5d/proves_flight_control_board_v5d.dtsi +++ b/boards/bronco_space/proves_flight_control_board_v5d/proves_flight_control_board_v5d.dtsi @@ -3,130 +3,10 @@ #include #include -#include "proves_flight_control_board_v5d-pinctrl.dtsi" +#include "../proves_flight_control_board_v5c/proves_flight_control_board_v5c.dtsi" +#include "../proves_flight_control_board_v5c/proves_flight_control_board_v5c-pinctrl.dtsi" -/ { - chosen { - zephyr,sram = &sram0; - zephyr,flash = &flash0; - zephyr,console = &cdc_acm_uart0; - zephyr,shell-uart = &cdc_acm_uart0; - zephyr,code-partition = &code_partition; - }; - - aliases { - watchdog0 = &wdt0; - }; - - leds { - compatible = "gpio-leds"; - led0: led0 { - gpios = <&gpio0 23 GPIO_ACTIVE_HIGH>; - label = "User LED GPIO23"; - }; - }; -}; - -zephyr_udc0: &usbd { - status = "okay"; -}; - -&zephyr_udc0 { - cdc_acm_uart0: cdc_acm_uart0 { - compatible = "zephyr,cdc-acm-uart"; - label = "CDC_ACM_0"; - }; -}; - -&flash0 { - reg = <0x10000000 DT_SIZE_M(4)>; - - partitions { - compatible = "fixed-partitions"; - #address-cells = <1>; - #size-cells = <1>; - - /* Reserved memory for an image definition block. The block is much - * smaller than 256 bytes, but in practice the linker places the vector - * table at a much larger alignment offset. - */ - image_def: partition@0 { - label = "image_def"; - reg = <0x00000000 0x100>; - read-only; - }; - - /* - * Usable flash. Starts at 0x100, after the image definition block. - * The partition size is 4MB minus the 0x100 bytes taken by the - * image definition. - */ - code_partition: partition@100 { - label = "code-partition"; - reg = <0x100 (DT_SIZE_M(4) - 0x100)>; - read-only; - }; - }; -}; - -&timer0 { - status = "okay"; -}; - -&wdt0 { - status = "okay"; -}; - -&gpio0 { - status = "okay"; -}; - -&spi1 { - status = "okay"; - cs-gpios = <&gpio0 9 GPIO_ACTIVE_LOW>; - pinctrl-0 = <&spi1_default>; - pinctrl-names = "default"; - - lora0: sx1276@0 { - compatible = "semtech,sx1276"; - reg = <0>; - spi-max-frequency = <125000>; - dio-gpios = <&gpio0 13 (GPIO_PULL_DOWN | GPIO_ACTIVE_HIGH)>,<&gpio0 12 (GPIO_PULL_DOWN | GPIO_ACTIVE_HIGH)>; - reset-gpios = <&gpio0 6 GPIO_ACTIVE_LOW>; - power-amplifier-output = "pa-boost"; - label = "HOPE_RF"; - }; -}; - -&i2c1 { - status = "okay"; - pinctrl-0 = <&i2c1_default>; - pinctrl-names = "default"; - clock-frequency = <100000>; - - lsm6dso0: lsm6dso0@6b { - compatible = "st,lsm6dso"; - reg = <0x6b>; - label = "LSM6DSO"; - }; - - lis2mdl: lis2mdl@1e { - compatible = "st,lis2mdl"; - reg = <0x1e>; - label = "LIS2MDL"; - }; - rv3028: rv3028@52 { - compatible = "microcrystal,rv3028"; - reg = <0x52>; - int-gpios = <&gpio0 27 GPIO_ACTIVE_HIGH>; - backup-switch-mode = "level"; - label = "RV3028"; - }; - ina219: ina219@40 { - compatible = "ti,ina219"; - reg = <0x40>; - shunt-milliohm = <2>; - lsb-microamp = <100>; - label = "INA219"; - }; +&led0 { + gpios = <&gpio0 23 GPIO_ACTIVE_HIGH>; + label = "User LED GPIO23"; }; From a75b69ffefbb834a6312c193421399f5b1c88a77 Mon Sep 17 00:00:00 2001 From: Nate Gay Date: Fri, 12 Sep 2025 19:14:18 -0500 Subject: [PATCH 06/40] Making a common v5 board definition --- .../Kconfig.defconfig | 12 ++++++++++++ .../proves_flight_control_board_v5-pinctrl.dtsi} | 0 .../proves_flight_control_board_v5.dtsi} | 2 +- .../Kconfig.defconfig | 14 -------------- .../Kconfig.proves_flight_control_board_v5c | 6 +----- ...proves_flight_control_board_v5c_rp2350a_m33.dts | 2 +- ..._flight_control_board_v5c_rp2350a_m33_defconfig | 2 +- .../Kconfig.defconfig | 14 -------------- .../Kconfig.proves_flight_control_board_v5d | 8 ++++---- .../proves_flight_control_board_v5d.dtsi | 12 ------------ ...proves_flight_control_board_v5d_rp2350a_m33.dts | 7 ++++++- ..._flight_control_board_v5d_rp2350a_m33_defconfig | 2 +- settings.ini | 2 +- 13 files changed, 28 insertions(+), 55 deletions(-) create mode 100644 boards/bronco_space/proves_flight_control_board_v5/Kconfig.defconfig rename boards/bronco_space/{proves_flight_control_board_v5c/proves_flight_control_board_v5c-pinctrl.dtsi => proves_flight_control_board_v5/proves_flight_control_board_v5-pinctrl.dtsi} (100%) rename boards/bronco_space/{proves_flight_control_board_v5c/proves_flight_control_board_v5c.dtsi => proves_flight_control_board_v5/proves_flight_control_board_v5.dtsi} (97%) delete mode 100644 boards/bronco_space/proves_flight_control_board_v5c/Kconfig.defconfig delete mode 100644 boards/bronco_space/proves_flight_control_board_v5d/Kconfig.defconfig delete mode 100644 boards/bronco_space/proves_flight_control_board_v5d/proves_flight_control_board_v5d.dtsi diff --git a/boards/bronco_space/proves_flight_control_board_v5/Kconfig.defconfig b/boards/bronco_space/proves_flight_control_board_v5/Kconfig.defconfig new file mode 100644 index 00000000..53c0c734 --- /dev/null +++ b/boards/bronco_space/proves_flight_control_board_v5/Kconfig.defconfig @@ -0,0 +1,12 @@ +config SOC_RP2350A_M33 + bool "Enable Arm cores" + default y + +config USB_SELF_POWERED + default n + +config USB_CDC_ACM_LOG_LEVEL + default 0 + +config USB_DEVICE_LOG_LEVEL + default 1 diff --git a/boards/bronco_space/proves_flight_control_board_v5c/proves_flight_control_board_v5c-pinctrl.dtsi b/boards/bronco_space/proves_flight_control_board_v5/proves_flight_control_board_v5-pinctrl.dtsi similarity index 100% rename from boards/bronco_space/proves_flight_control_board_v5c/proves_flight_control_board_v5c-pinctrl.dtsi rename to boards/bronco_space/proves_flight_control_board_v5/proves_flight_control_board_v5-pinctrl.dtsi diff --git a/boards/bronco_space/proves_flight_control_board_v5c/proves_flight_control_board_v5c.dtsi b/boards/bronco_space/proves_flight_control_board_v5/proves_flight_control_board_v5.dtsi similarity index 97% rename from boards/bronco_space/proves_flight_control_board_v5c/proves_flight_control_board_v5c.dtsi rename to boards/bronco_space/proves_flight_control_board_v5/proves_flight_control_board_v5.dtsi index 1583eaa0..cc25572f 100644 --- a/boards/bronco_space/proves_flight_control_board_v5c/proves_flight_control_board_v5c.dtsi +++ b/boards/bronco_space/proves_flight_control_board_v5/proves_flight_control_board_v5.dtsi @@ -3,7 +3,7 @@ #include #include -#include "proves_flight_control_board_v5c-pinctrl.dtsi" +#include "proves_flight_control_board_v5-pinctrl.dtsi" / { chosen { diff --git a/boards/bronco_space/proves_flight_control_board_v5c/Kconfig.defconfig b/boards/bronco_space/proves_flight_control_board_v5c/Kconfig.defconfig deleted file mode 100644 index 296c23fc..00000000 --- a/boards/bronco_space/proves_flight_control_board_v5c/Kconfig.defconfig +++ /dev/null @@ -1,14 +0,0 @@ -# Copyright (c) 2024 Andrew Featherstone -# SPDX-License-Identifier: Apache-2.0 - -if PROVES_FLIGHT_CONTROL_BOARD_V5C - -config USB_SELF_POWERED - default n - -config USB_CDC_ACM_LOG_LEVEL - default 0 - -config USB_DEVICE_LOG_LEVEL - default 1 -endif # PROVES_FLIGHT_CONTROL_BOARD_V5C diff --git a/boards/bronco_space/proves_flight_control_board_v5c/Kconfig.proves_flight_control_board_v5c b/boards/bronco_space/proves_flight_control_board_v5c/Kconfig.proves_flight_control_board_v5c index 805f5070..ce2e6e17 100644 --- a/boards/bronco_space/proves_flight_control_board_v5c/Kconfig.proves_flight_control_board_v5c +++ b/boards/bronco_space/proves_flight_control_board_v5c/Kconfig.proves_flight_control_board_v5c @@ -1,5 +1 @@ -# Copyright (c) 2024 Andrew Featherstone -# SPDX-License-Identifier: Apache-2.0 - -config BOARD_PROVES_FLIGHT_CONTROL_BOARD_V5C - select SOC_RP2350A_M33 if BOARD_PROVES_FLIGHT_CONTROL_BOARD_V5C_RP2350A_M33 +source "../../../boards/bronco_space/proves_flight_control_board_v5/Kconfig.defconfig" diff --git a/boards/bronco_space/proves_flight_control_board_v5c/proves_flight_control_board_v5c_rp2350a_m33.dts b/boards/bronco_space/proves_flight_control_board_v5c/proves_flight_control_board_v5c_rp2350a_m33.dts index dc57761a..e4290dd6 100644 --- a/boards/bronco_space/proves_flight_control_board_v5c/proves_flight_control_board_v5c_rp2350a_m33.dts +++ b/boards/bronco_space/proves_flight_control_board_v5c/proves_flight_control_board_v5c_rp2350a_m33.dts @@ -16,4 +16,4 @@ #include #include -#include "proves_flight_control_board_v5c.dtsi" +#include "../proves_flight_control_board_v5/proves_flight_control_board_v5.dtsi" diff --git a/boards/bronco_space/proves_flight_control_board_v5c/proves_flight_control_board_v5c_rp2350a_m33_defconfig b/boards/bronco_space/proves_flight_control_board_v5c/proves_flight_control_board_v5c_rp2350a_m33_defconfig index 6dcb23e3..02bb4603 100644 --- a/boards/bronco_space/proves_flight_control_board_v5c/proves_flight_control_board_v5c_rp2350a_m33_defconfig +++ b/boards/bronco_space/proves_flight_control_board_v5c/proves_flight_control_board_v5c_rp2350a_m33_defconfig @@ -18,7 +18,7 @@ CONFIG_LSM6DSO_ENABLE_TEMP=y CONFIG_LIS2MDL=y CONFIG_INA219=y -# Lora +# Radio CONFIG_LORA=y CONFIG_LORA_SX127X=y diff --git a/boards/bronco_space/proves_flight_control_board_v5d/Kconfig.defconfig b/boards/bronco_space/proves_flight_control_board_v5d/Kconfig.defconfig deleted file mode 100644 index d96b8a3f..00000000 --- a/boards/bronco_space/proves_flight_control_board_v5d/Kconfig.defconfig +++ /dev/null @@ -1,14 +0,0 @@ -# Copyright (c) 2024 Andrew Featherstone -# SPDX-License-Identifier: Apache-2.0 - -if PROVES_FLIGHT_CONTROL_BOARD_V5D - -config USB_SELF_POWERED - default n - -config USB_CDC_ACM_LOG_LEVEL - default 0 - -config USB_DEVICE_LOG_LEVEL - default 1 -endif # PROVES_FLIGHT_CONTROL_BOARD_V5D diff --git a/boards/bronco_space/proves_flight_control_board_v5d/Kconfig.proves_flight_control_board_v5d b/boards/bronco_space/proves_flight_control_board_v5d/Kconfig.proves_flight_control_board_v5d index a4ae3506..b3bd39fa 100644 --- a/boards/bronco_space/proves_flight_control_board_v5d/Kconfig.proves_flight_control_board_v5d +++ b/boards/bronco_space/proves_flight_control_board_v5d/Kconfig.proves_flight_control_board_v5d @@ -1,5 +1,5 @@ -# Copyright (c) 2024 Andrew Featherstone -# SPDX-License-Identifier: Apache-2.0 - config BOARD_PROVES_FLIGHT_CONTROL_BOARD_V5D - select SOC_RP2350A_M33 if BOARD_PROVES_FLIGHT_CONTROL_BOARD_V5D_RP2350A_M33 + bool "PROVES Flight Control Board v5d" + default y + +source "../../../boards/bronco_space/proves_flight_control_board_v5/Kconfig.defconfig" diff --git a/boards/bronco_space/proves_flight_control_board_v5d/proves_flight_control_board_v5d.dtsi b/boards/bronco_space/proves_flight_control_board_v5d/proves_flight_control_board_v5d.dtsi deleted file mode 100644 index 8d98535a..00000000 --- a/boards/bronco_space/proves_flight_control_board_v5d/proves_flight_control_board_v5d.dtsi +++ /dev/null @@ -1,12 +0,0 @@ -#include - -#include -#include - -#include "../proves_flight_control_board_v5c/proves_flight_control_board_v5c.dtsi" -#include "../proves_flight_control_board_v5c/proves_flight_control_board_v5c-pinctrl.dtsi" - -&led0 { - gpios = <&gpio0 23 GPIO_ACTIVE_HIGH>; - label = "User LED GPIO23"; -}; diff --git a/boards/bronco_space/proves_flight_control_board_v5d/proves_flight_control_board_v5d_rp2350a_m33.dts b/boards/bronco_space/proves_flight_control_board_v5d/proves_flight_control_board_v5d_rp2350a_m33.dts index 92124e73..e265d05f 100644 --- a/boards/bronco_space/proves_flight_control_board_v5d/proves_flight_control_board_v5d_rp2350a_m33.dts +++ b/boards/bronco_space/proves_flight_control_board_v5d/proves_flight_control_board_v5d_rp2350a_m33.dts @@ -16,4 +16,9 @@ #include #include -#include "proves_flight_control_board_v5d.dtsi" +#include "../proves_flight_control_board_v5/proves_flight_control_board_v5.dtsi" + +&led0 { + gpios = <&gpio0 23 GPIO_ACTIVE_HIGH>; + label = "User LED GPIO23"; +}; diff --git a/boards/bronco_space/proves_flight_control_board_v5d/proves_flight_control_board_v5d_rp2350a_m33_defconfig b/boards/bronco_space/proves_flight_control_board_v5d/proves_flight_control_board_v5d_rp2350a_m33_defconfig index cc694df0..fccf5b0f 100644 --- a/boards/bronco_space/proves_flight_control_board_v5d/proves_flight_control_board_v5d_rp2350a_m33_defconfig +++ b/boards/bronco_space/proves_flight_control_board_v5d/proves_flight_control_board_v5d_rp2350a_m33_defconfig @@ -18,7 +18,7 @@ CONFIG_LSM6DSO_ENABLE_TEMP=y CONFIG_LIS2MDL=y CONFIG_INA219=y -# Lora +# Radio CONFIG_LORA=y CONFIG_LORA_SX127X=y diff --git a/settings.ini b/settings.ini index dde51b9e..d27e929f 100644 --- a/settings.ini +++ b/settings.ini @@ -7,4 +7,4 @@ default_toolchain: zephyr default_cmake_options: FPRIME_ENABLE_FRAMEWORK_UTS=OFF FPRIME_ENABLE_AUTOCODER_UTS=OFF BOARD_ROOT=. - BOARD=proves_flight_control_board_v5d/rp2350a/m33 + BOARD=proves_flight_control_board_v5c/rp2350a/m33 From 649e44f0f5c0cf0422a6b2a87dad59e337b164c3 Mon Sep 17 00:00:00 2001 From: Nate Gay Date: Fri, 12 Sep 2025 21:09:18 -0500 Subject: [PATCH 07/40] Fix readme --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index da8d525b..9568b5c0 100644 --- a/README.md +++ b/README.md @@ -63,11 +63,11 @@ Now you want to install the firmware to the board. make install BOARD_DIR=[path-to-your-board] ``` -or +or ``` cp build-fprime-automatic-zephyr/zephyr/zephyr.uf2 [path-to-your-board] ``` -to copy the uf2 if the make install isnt working +to copy the uf2 if the make install isn't working Finally, run the fprime-gds. ```shell From 4aef1beb87a68c6e24afc3cc93d115b50845af2b Mon Sep 17 00:00:00 2001 From: Nate Gay Date: Wed, 17 Sep 2025 11:09:46 -0500 Subject: [PATCH 08/40] checkpoint rtc working --- .../Components/CMakeLists.txt | 1 + .../Components/RtcManager/CMakeLists.txt | 36 +++++++++ .../Components/RtcManager/RtcManager.cpp | 76 +++++++++++++++++++ .../Components/RtcManager/RtcManager.fpp | 60 +++++++++++++++ .../Components/RtcManager/RtcManager.hpp | 58 ++++++++++++++ .../Components/RtcManager/docs/sdd.md | 74 ++++++++++++++++++ .../ReferenceDeployment/Top/instances.fpp | 2 + .../ReferenceDeployment/Top/topology.fpp | 1 + 8 files changed, 308 insertions(+) create mode 100644 FprimeZephyrReference/Components/RtcManager/CMakeLists.txt create mode 100644 FprimeZephyrReference/Components/RtcManager/RtcManager.cpp create mode 100644 FprimeZephyrReference/Components/RtcManager/RtcManager.fpp create mode 100644 FprimeZephyrReference/Components/RtcManager/RtcManager.hpp create mode 100644 FprimeZephyrReference/Components/RtcManager/docs/sdd.md diff --git a/FprimeZephyrReference/Components/CMakeLists.txt b/FprimeZephyrReference/Components/CMakeLists.txt index 10c9dad2..43581929 100644 --- a/FprimeZephyrReference/Components/CMakeLists.txt +++ b/FprimeZephyrReference/Components/CMakeLists.txt @@ -2,3 +2,4 @@ add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/FatalHandler") add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/Watchdog") +add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/RtcManager/") diff --git a/FprimeZephyrReference/Components/RtcManager/CMakeLists.txt b/FprimeZephyrReference/Components/RtcManager/CMakeLists.txt new file mode 100644 index 00000000..e6063a25 --- /dev/null +++ b/FprimeZephyrReference/Components/RtcManager/CMakeLists.txt @@ -0,0 +1,36 @@ +#### +# F Prime CMakeLists.txt: +# +# SOURCES: list of source files (to be compiled) +# AUTOCODER_INPUTS: list of files to be passed to the autocoders +# DEPENDS: list of libraries that this module depends on +# +# More information in the F´ CMake API documentation: +# https://fprime.jpl.nasa.gov/latest/docs/reference/api/cmake/API/ +# +#### + +# Module names are derived from the path from the nearest project/library/framework +# root when not specifically overridden by the developer. i.e. The module defined by +# `Ref/SignalGen/CMakeLists.txt` will be named `Ref_SignalGen`. + +register_fprime_library( + AUTOCODER_INPUTS + "${CMAKE_CURRENT_LIST_DIR}/RtcManager.fpp" + SOURCES + "${CMAKE_CURRENT_LIST_DIR}/RtcManager.cpp" +# DEPENDS +# MyPackage_MyOtherModule +) + +### Unit Tests ### +# register_fprime_ut( +# AUTOCODER_INPUTS +# "${CMAKE_CURRENT_LIST_DIR}/RtcManager.fpp" +# SOURCES +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/RtcManagerTestMain.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/RtcManagerTester.cpp" +# DEPENDS +# STest # For rules-based testing +# UT_AUTO_HELPERS +# ) diff --git a/FprimeZephyrReference/Components/RtcManager/RtcManager.cpp b/FprimeZephyrReference/Components/RtcManager/RtcManager.cpp new file mode 100644 index 00000000..4a39d94b --- /dev/null +++ b/FprimeZephyrReference/Components/RtcManager/RtcManager.cpp @@ -0,0 +1,76 @@ +// ====================================================================== +// \title RtcManager.cpp +// \brief cpp file for RtcManager component implementation class +// ====================================================================== + +#include "FprimeZephyrReference/Components/RtcManager/RtcManager.hpp" + +namespace Components { + +// ---------------------------------------------------------------------- +// Component construction and destruction +// ---------------------------------------------------------------------- + +RtcManager ::RtcManager(const char* const compName) : RtcManagerComponentBase(compName) { + // Initialize device + this->rv3028 = device_get_binding("RV3028"); + FW_ASSERT(device_is_ready(this->rv3028)); +} + +RtcManager ::~RtcManager() {} + +// ---------------------------------------------------------------------- +// Handler implementations for commands +// ---------------------------------------------------------------------- + +void RtcManager ::SET_TIME_cmdHandler(FwOpcodeType opCode, U32 cmdSeq) { + if (!device_is_ready(this->rv3028)) { + this->log_WARNING_HI_RTC_NotReady(); + return; + } + + // set the time + const struct rtc_time timeptr = { + .tm_sec = 0, + .tm_min = 0, + .tm_hour = 12, + .tm_mday = 25, + .tm_mon = 11, + .tm_year = 125, // year since 1900 + .tm_wday = 0, + .tm_yday = 0, + .tm_isdst = 0, + }; + const int status = rtc_set_time(this->rv3028, &timeptr); + + if (status == 0) { + this->log_ACTIVITY_HI_RTC_Set(true); + } else { + this->log_ACTIVITY_HI_RTC_Set(false); + } + + this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK); +} + +void RtcManager ::GET_TIME_cmdHandler(FwOpcodeType opCode, U32 cmdSeq) { + if (!device_is_ready(this->rv3028)) { + this->log_WARNING_HI_RTC_NotReady(); + return; + } + + struct rtc_time timeptr = {}; + rtc_get_time(this->rv3028, &timeptr); + + this->log_ACTIVITY_HI_RTC_GetTime(timeptr.tm_year + 1900, timeptr.tm_mon + 1, timeptr.tm_mday, timeptr.tm_hour, + timeptr.tm_min, timeptr.tm_sec); + + // Try Fprime Time class + // const Fw::Time fwtime = this->getTime(); + // const U32 secs = fwtime.getSeconds(); + + // this->log_ACTIVITY_HI_RTC_GetTime(0, 0, 0, 0, 0, secs); + + this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK); +} + +} // namespace Components diff --git a/FprimeZephyrReference/Components/RtcManager/RtcManager.fpp b/FprimeZephyrReference/Components/RtcManager/RtcManager.fpp new file mode 100644 index 00000000..ae78c72c --- /dev/null +++ b/FprimeZephyrReference/Components/RtcManager/RtcManager.fpp @@ -0,0 +1,60 @@ +module Components { + @ Manages the real time clock + passive component RtcManager { + + @ SET_TIME command to set the time on the RTC + @ Requirement RtcManager-001 + sync command SET_TIME opcode 0 + + @ GET_TIME command to get the time from the RTC + @ Requirement RtcManager-002 + sync command GET_TIME opcode 1 + + ############################################################################## + #### Uncomment the following examples to start customizing your component #### + ############################################################################## + + # @ Example async command + # async command COMMAND_NAME(param_name: U32) + + # @ Example telemetry counter + # telemetry ExampleCounter: U64 + + # @ Example event + # event ExampleStateEvent(example_state: Fw.On) severity activity high id 0 format "State set to {}" + event RTC_Set(status: bool) severity activity high id 0 format "Reset status: {}" + + event RTC_GetTime(year: U32, month: U32, day: U32, hour:U32, minute:U32, second:U32) severity activity high id 1 format "Time: {}/{}/{} at {}:{}:{}" + + event RTC_NotReady() severity warning high id 2 format "RTC not ready" + + # @ Example port: receiving calls from the rate group + # sync input port run: Svc.Sched + output port SetTime: Fw.Time + + # @ Example parameter + # param PARAMETER_NAME: U32 + + ############################################################################### + # Standard AC Ports: Required for Channels, Events, Commands, and Parameters # + ############################################################################### + @ Port for requesting the current time + time get port timeCaller + + @ Port for sending command registrations + command reg port cmdRegOut + + @ Port for receiving commands + command recv port cmdIn + + @ Port for sending command responses + command resp port cmdResponseOut + + @ Port for sending textual representation of events + text event port logTextOut + + @ Port for sending events to downlink + event port logOut + + } +} diff --git a/FprimeZephyrReference/Components/RtcManager/RtcManager.hpp b/FprimeZephyrReference/Components/RtcManager/RtcManager.hpp new file mode 100644 index 00000000..0ae35916 --- /dev/null +++ b/FprimeZephyrReference/Components/RtcManager/RtcManager.hpp @@ -0,0 +1,58 @@ +// ====================================================================== +// \title RtcManager.hpp +// \brief hpp file for RtcManager component implementation class +// ====================================================================== + +#ifndef Components_RtcManager_HPP +#define Components_RtcManager_HPP + +#include "FprimeZephyrReference/Components/RtcManager/RtcManagerComponentAc.hpp" + +#include +#include +#include +#include + +namespace Components { + +class RtcManager final : public RtcManagerComponentBase { + public: + // ---------------------------------------------------------------------- + // Component construction and destruction + // ---------------------------------------------------------------------- + + //! Construct RtcManager object + RtcManager(const char* const compName //!< The component name + ); + + //! Destroy RtcManager object + ~RtcManager(); + + private: + // ---------------------------------------------------------------------- + // Handler implementations for commands + // ---------------------------------------------------------------------- + + //! Handler implementation for command SET_TIME + //! + //! SET_TIME command to set the time on the RTC + //! Requirement RtcManager-001 + void SET_TIME_cmdHandler(FwOpcodeType opCode, //!< The opcode + U32 cmdSeq //!< The command sequence number + ) override; + + //! Handler implementation for command GET_TIME + //! + //! GET_TIME command to get the time from the RTC + //! Requirement RtcManager-002 + void GET_TIME_cmdHandler(FwOpcodeType opCode, //!< The opcode + U32 cmdSeq //!< The command sequence number + ) override; + + //! Zephyr device stores the initialized RV2038 sensor + const struct device* rv3028; +}; + +} // namespace Components + +#endif diff --git a/FprimeZephyrReference/Components/RtcManager/docs/sdd.md b/FprimeZephyrReference/Components/RtcManager/docs/sdd.md new file mode 100644 index 00000000..00581f13 --- /dev/null +++ b/FprimeZephyrReference/Components/RtcManager/docs/sdd.md @@ -0,0 +1,74 @@ +# Components::RtcManager + +Manages the real time clock + +## Usage Examples +Add usage examples here + +### Diagrams +Add diagrams here + +### Typical Usage +And the typical usage of the component here + +## Class Diagram +Add a class diagram here + +## Requirements +Add requirements in the chart below +| Name | Description | Validation | +|---|---|---| +| RtcManager-001 | Caller can set time on the RTC | Manual | +| RtcManager-002 | Caller can receive time from FPrime | Manual | +| RtcManager-003 | Event when time is set, report success or failure | Manual | + +## Port Descriptions +| Name | Description | +|---|---| +| SetTime (output) | Port to reach out to driver to set the time | +| timeCaller (time) | Port to receive time | + +## Component States +Add component states in the chart below +| Name | Description | +|---|---| +|---|---| + +## Sequence Diagrams +Add sequence diagrams here + +## Parameters +| Name | Description | +|---|---| +|---|---| + +## Commands +| Name | Description | +|---|---| +| SET_TIME | Sets the time on the RTC | +| GET_TIME | Gets the time from the RTC | + + +## Events +| Name | Description | +|---|---| +| RTC_Set | Transmits success or failure RTC time when it is reset | +| RTC_NotReady | Emits on unsuccessful device connection | + + +## Telemetry +| Name | Description | +|---|---| +|---|---| + +## Unit Tests +Add unit test descriptions in the chart below +| Name | Description | Output | Coverage | +|---|---|---|---| +|---|---|---|---| + + +## Change Log +| Date | Description | +|---|---| +| 2025-09-17 | Initial Draft | diff --git a/FprimeZephyrReference/ReferenceDeployment/Top/instances.fpp b/FprimeZephyrReference/ReferenceDeployment/Top/instances.fpp index d3bce3e6..837f4430 100644 --- a/FprimeZephyrReference/ReferenceDeployment/Top/instances.fpp +++ b/FprimeZephyrReference/ReferenceDeployment/Top/instances.fpp @@ -63,4 +63,6 @@ module ReferenceDeployment { instance gpioDriver: Zephyr.ZephyrGpioDriver base id 0x10015000 instance watchdog: Components.Watchdog base id 0x10016000 + + instance rtcManager: Components.RtcManager base id 0x10017000 } diff --git a/FprimeZephyrReference/ReferenceDeployment/Top/topology.fpp b/FprimeZephyrReference/ReferenceDeployment/Top/topology.fpp index f1946b87..630d3092 100644 --- a/FprimeZephyrReference/ReferenceDeployment/Top/topology.fpp +++ b/FprimeZephyrReference/ReferenceDeployment/Top/topology.fpp @@ -29,6 +29,7 @@ module ReferenceDeployment { instance gpioDriver instance watchdog instance prmDb + instance rtcManager # ---------------------------------------------------------------------- # Pattern graph specifiers From d1613b030b4a5fc8e3c64fb26a102c84a88b23ee Mon Sep 17 00:00:00 2001 From: Nate Gay Date: Wed, 17 Sep 2025 11:52:47 -0500 Subject: [PATCH 09/40] Pushing what I have --- .../Components/RtcManager/RtcManager.cpp | 11 +++++++++++ .../Components/RtcManager/docs/sdd.md | 2 ++ .../ReferenceDeployment/Top/instances.fpp | 2 ++ 3 files changed, 15 insertions(+) diff --git a/FprimeZephyrReference/Components/RtcManager/RtcManager.cpp b/FprimeZephyrReference/Components/RtcManager/RtcManager.cpp index 4a39d94b..17ac2fe0 100644 --- a/FprimeZephyrReference/Components/RtcManager/RtcManager.cpp +++ b/FprimeZephyrReference/Components/RtcManager/RtcManager.cpp @@ -64,7 +64,18 @@ void RtcManager ::GET_TIME_cmdHandler(FwOpcodeType opCode, U32 cmdSeq) { this->log_ACTIVITY_HI_RTC_GetTime(timeptr.tm_year + 1900, timeptr.tm_mon + 1, timeptr.tm_mday, timeptr.tm_hour, timeptr.tm_min, timeptr.tm_sec); + // 3 parts. + // 1. fprime-zephyr reference need ZephyrTime SVC + instance/topology + // 2. RV3028Driver talk to zephyr and set the time on the RTC + // 3. RtcManager component to take commands and relay them to RV3028Driver and get/set + + // TODO - Need a way to sync Fprime time with RTC time, especially after + // satellite restarts. RTC has a battery backup and should keep time + // Fprime time will not know anything about the rtc + // need some kind of sync mechanism maybe 1Hz sync? + // Try Fprime Time class + // this->set_timeCaller_OutputPort(0, 0); // const Fw::Time fwtime = this->getTime(); // const U32 secs = fwtime.getSeconds(); diff --git a/FprimeZephyrReference/Components/RtcManager/docs/sdd.md b/FprimeZephyrReference/Components/RtcManager/docs/sdd.md index 00581f13..5b8cf852 100644 --- a/FprimeZephyrReference/Components/RtcManager/docs/sdd.md +++ b/FprimeZephyrReference/Components/RtcManager/docs/sdd.md @@ -21,6 +21,8 @@ Add requirements in the chart below | RtcManager-001 | Caller can set time on the RTC | Manual | | RtcManager-002 | Caller can receive time from FPrime | Manual | | RtcManager-003 | Event when time is set, report success or failure | Manual | +| RtcManager-003 | Able to sync RTC time with F Prime [TBR] | Manual | + ## Port Descriptions | Name | Description | diff --git a/FprimeZephyrReference/ReferenceDeployment/Top/instances.fpp b/FprimeZephyrReference/ReferenceDeployment/Top/instances.fpp index 837f4430..16b0b83e 100644 --- a/FprimeZephyrReference/ReferenceDeployment/Top/instances.fpp +++ b/FprimeZephyrReference/ReferenceDeployment/Top/instances.fpp @@ -65,4 +65,6 @@ module ReferenceDeployment { instance watchdog: Components.Watchdog base id 0x10016000 instance rtcManager: Components.RtcManager base id 0x10017000 + + instance posixTime: Svc.PosixTime base id 0x10020000 } From 651eb055ddf535cea903bef0e3d5522714526485 Mon Sep 17 00:00:00 2001 From: Nate Gay Date: Wed, 17 Sep 2025 11:53:07 -0500 Subject: [PATCH 10/40] poke --- FprimeZephyrReference/ReferenceDeployment/Top/instances.fpp | 1 - 1 file changed, 1 deletion(-) diff --git a/FprimeZephyrReference/ReferenceDeployment/Top/instances.fpp b/FprimeZephyrReference/ReferenceDeployment/Top/instances.fpp index 16b0b83e..945ad799 100644 --- a/FprimeZephyrReference/ReferenceDeployment/Top/instances.fpp +++ b/FprimeZephyrReference/ReferenceDeployment/Top/instances.fpp @@ -66,5 +66,4 @@ module ReferenceDeployment { instance rtcManager: Components.RtcManager base id 0x10017000 - instance posixTime: Svc.PosixTime base id 0x10020000 } From 08d1fbbb5cb1504d39026650cc666ca954929269 Mon Sep 17 00:00:00 2001 From: ineskhou Date: Wed, 17 Sep 2025 12:38:40 -0700 Subject: [PATCH 11/40] replaced chronotime with zepyhry time --- FprimeZephyrReference/ReferenceDeployment/Top/instances.fpp | 2 +- FprimeZephyrReference/ReferenceDeployment/Top/topology.fpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/FprimeZephyrReference/ReferenceDeployment/Top/instances.fpp b/FprimeZephyrReference/ReferenceDeployment/Top/instances.fpp index 945ad799..df71256b 100644 --- a/FprimeZephyrReference/ReferenceDeployment/Top/instances.fpp +++ b/FprimeZephyrReference/ReferenceDeployment/Top/instances.fpp @@ -50,7 +50,7 @@ module ReferenceDeployment { # Passive component instances # ---------------------------------------------------------------------- - instance chronoTime: Svc.ChronoTime base id 0x10010000 + instance zephyrTime: Svc.zephyrTime base id 0x10010000 instance rateGroupDriver: Svc.RateGroupDriver base id 0x10011000 diff --git a/FprimeZephyrReference/ReferenceDeployment/Top/topology.fpp b/FprimeZephyrReference/ReferenceDeployment/Top/topology.fpp index 630d3092..efc83e80 100644 --- a/FprimeZephyrReference/ReferenceDeployment/Top/topology.fpp +++ b/FprimeZephyrReference/ReferenceDeployment/Top/topology.fpp @@ -20,7 +20,7 @@ module ReferenceDeployment { # ---------------------------------------------------------------------- # Instances used in the topology # ---------------------------------------------------------------------- - instance chronoTime + instance zephyrTime instance rateGroup10Hz instance rateGroup1Hz instance rateGroupDriver @@ -39,7 +39,7 @@ module ReferenceDeployment { event connections instance CdhCore.events text event connections instance CdhCore.textLogger health connections instance CdhCore.$health - time connections instance chronoTime + time connections instance zephyrTime telemetry connections instance CdhCore.tlmSend param connections instance prmDb From 1ea370386e2f27bb16c12a3cb897a296aa4f0224 Mon Sep 17 00:00:00 2001 From: Nate Gay Date: Wed, 17 Sep 2025 14:51:28 -0500 Subject: [PATCH 12/40] use direct power for rtc backup --- .../proves_flight_control_board_v5.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boards/bronco_space/proves_flight_control_board_v5/proves_flight_control_board_v5.dtsi b/boards/bronco_space/proves_flight_control_board_v5/proves_flight_control_board_v5.dtsi index cc25572f..893dd802 100644 --- a/boards/bronco_space/proves_flight_control_board_v5/proves_flight_control_board_v5.dtsi +++ b/boards/bronco_space/proves_flight_control_board_v5/proves_flight_control_board_v5.dtsi @@ -119,7 +119,7 @@ zephyr_udc0: &usbd { compatible = "microcrystal,rv3028"; reg = <0x52>; int-gpios = <&gpio0 27 GPIO_ACTIVE_HIGH>; - backup-switch-mode = "level"; + backup-switch-mode = "direct"; label = "RV3028"; }; ina219: ina219@40 { From a674b21f2e7e78cc3fa4067aaeba88d5499a4fb1 Mon Sep 17 00:00:00 2001 From: Nate Gay Date: Wed, 17 Sep 2025 16:37:24 -0500 Subject: [PATCH 13/40] This builds and runs but Fprime still does not know the time --- .gitmodules | 3 ++- FprimeZephyrReference/Components/RtcManager/RtcManager.cpp | 7 +++---- FprimeZephyrReference/Components/RtcManager/RtcManager.fpp | 1 + .../ReferenceDeployment/Top/instances.fpp | 2 +- FprimeZephyrReference/ReferenceDeployment/Top/topology.fpp | 4 ++-- lib/fprime-zephyr | 2 +- 6 files changed, 10 insertions(+), 9 deletions(-) diff --git a/.gitmodules b/.gitmodules index ef179827..68bf0880 100644 --- a/.gitmodules +++ b/.gitmodules @@ -6,4 +6,5 @@ url = https://github.com/zephyrproject-rtos/zephyr.git [submodule "lib/fprime-zephyr"] path = lib/fprime-zephyr - url = https://github.com/fprime-community/fprime-zephyr.git + url = https://github.com/nateinaction/fprime-zephyr.git + branch = zephyrtime diff --git a/FprimeZephyrReference/Components/RtcManager/RtcManager.cpp b/FprimeZephyrReference/Components/RtcManager/RtcManager.cpp index 17ac2fe0..b03fec52 100644 --- a/FprimeZephyrReference/Components/RtcManager/RtcManager.cpp +++ b/FprimeZephyrReference/Components/RtcManager/RtcManager.cpp @@ -75,11 +75,10 @@ void RtcManager ::GET_TIME_cmdHandler(FwOpcodeType opCode, U32 cmdSeq) { // need some kind of sync mechanism maybe 1Hz sync? // Try Fprime Time class - // this->set_timeCaller_OutputPort(0, 0); - // const Fw::Time fwtime = this->getTime(); - // const U32 secs = fwtime.getSeconds(); + const Fw::Time fwtime = this->getTime(); + const U32 secs = fwtime.getSeconds(); - // this->log_ACTIVITY_HI_RTC_GetTime(0, 0, 0, 0, 0, secs); + this->log_ACTIVITY_HI_RTC_GetTime(0, 0, 0, 0, 0, secs); this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK); } diff --git a/FprimeZephyrReference/Components/RtcManager/RtcManager.fpp b/FprimeZephyrReference/Components/RtcManager/RtcManager.fpp index ae78c72c..5b070551 100644 --- a/FprimeZephyrReference/Components/RtcManager/RtcManager.fpp +++ b/FprimeZephyrReference/Components/RtcManager/RtcManager.fpp @@ -14,6 +14,7 @@ module Components { #### Uncomment the following examples to start customizing your component #### ############################################################################## + import Fw.Channel # @ Example async command # async command COMMAND_NAME(param_name: U32) diff --git a/FprimeZephyrReference/ReferenceDeployment/Top/instances.fpp b/FprimeZephyrReference/ReferenceDeployment/Top/instances.fpp index df71256b..483db3ac 100644 --- a/FprimeZephyrReference/ReferenceDeployment/Top/instances.fpp +++ b/FprimeZephyrReference/ReferenceDeployment/Top/instances.fpp @@ -50,7 +50,7 @@ module ReferenceDeployment { # Passive component instances # ---------------------------------------------------------------------- - instance zephyrTime: Svc.zephyrTime base id 0x10010000 + instance posixTime: Zephyr.PosixTime base id 0x10010000 instance rateGroupDriver: Svc.RateGroupDriver base id 0x10011000 diff --git a/FprimeZephyrReference/ReferenceDeployment/Top/topology.fpp b/FprimeZephyrReference/ReferenceDeployment/Top/topology.fpp index efc83e80..6941194c 100644 --- a/FprimeZephyrReference/ReferenceDeployment/Top/topology.fpp +++ b/FprimeZephyrReference/ReferenceDeployment/Top/topology.fpp @@ -20,7 +20,7 @@ module ReferenceDeployment { # ---------------------------------------------------------------------- # Instances used in the topology # ---------------------------------------------------------------------- - instance zephyrTime + instance posixTime instance rateGroup10Hz instance rateGroup1Hz instance rateGroupDriver @@ -39,7 +39,7 @@ module ReferenceDeployment { event connections instance CdhCore.events text event connections instance CdhCore.textLogger health connections instance CdhCore.$health - time connections instance zephyrTime + time connections instance posixTime telemetry connections instance CdhCore.tlmSend param connections instance prmDb diff --git a/lib/fprime-zephyr b/lib/fprime-zephyr index 4a149bbe..aea685c5 160000 --- a/lib/fprime-zephyr +++ b/lib/fprime-zephyr @@ -1 +1 @@ -Subproject commit 4a149bbed5c7c86fbac44ab8a65791eff97370f9 +Subproject commit aea685c5a6e7d5f37445ee2a7c843d39c96c219b From a1e5c4a1534bf7b40bb5fa12aede295ebe0d0eb9 Mon Sep 17 00:00:00 2001 From: Nate Gay Date: Thu, 18 Sep 2025 09:37:06 -0500 Subject: [PATCH 14/40] super working rtc component --- .../Components/RtcManager/RtcManager.cpp | 40 +++++++++++++++---- .../Components/RtcManager/RtcManager.fpp | 17 +++++++- .../Components/RtcManager/RtcManager.hpp | 10 ++++- .../ReferenceDeployment/Top/instances.fpp | 2 - .../ReferenceDeployment/Top/topology.fpp | 5 +-- 5 files changed, 58 insertions(+), 16 deletions(-) diff --git a/FprimeZephyrReference/Components/RtcManager/RtcManager.cpp b/FprimeZephyrReference/Components/RtcManager/RtcManager.cpp index b03fec52..2aff39d5 100644 --- a/FprimeZephyrReference/Components/RtcManager/RtcManager.cpp +++ b/FprimeZephyrReference/Components/RtcManager/RtcManager.cpp @@ -23,7 +23,7 @@ RtcManager ::~RtcManager() {} // Handler implementations for commands // ---------------------------------------------------------------------- -void RtcManager ::SET_TIME_cmdHandler(FwOpcodeType opCode, U32 cmdSeq) { +void RtcManager ::SET_TIME_cmdHandler(FwOpcodeType opCode, U32 cmdSeq, Components::RtcManager_TimeInput t) { if (!device_is_ready(this->rv3028)) { this->log_WARNING_HI_RTC_NotReady(); return; @@ -32,11 +32,11 @@ void RtcManager ::SET_TIME_cmdHandler(FwOpcodeType opCode, U32 cmdSeq) { // set the time const struct rtc_time timeptr = { .tm_sec = 0, - .tm_min = 0, - .tm_hour = 12, - .tm_mday = 25, - .tm_mon = 11, - .tm_year = 125, // year since 1900 + .tm_min = t.get_Minute(), + .tm_hour = t.get_Hour(), + .tm_mday = t.get_Day(), + .tm_mon = t.get_Month() - 1, // month [0-11] + .tm_year = t.get_Year() - 1900, // year since 1900 .tm_wday = 0, .tm_yday = 0, .tm_isdst = 0, @@ -61,7 +61,7 @@ void RtcManager ::GET_TIME_cmdHandler(FwOpcodeType opCode, U32 cmdSeq) { struct rtc_time timeptr = {}; rtc_get_time(this->rv3028, &timeptr); - this->log_ACTIVITY_HI_RTC_GetTime(timeptr.tm_year + 1900, timeptr.tm_mon + 1, timeptr.tm_mday, timeptr.tm_hour, + this->log_ACTIVITY_HI_RTC_GetTime(timeptr.tm_year + 1900, timeptr.tm_mon + 1, timeptr.tm_mday + 1, timeptr.tm_hour, timeptr.tm_min, timeptr.tm_sec); // 3 parts. @@ -83,4 +83,30 @@ void RtcManager ::GET_TIME_cmdHandler(FwOpcodeType opCode, U32 cmdSeq) { this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK); } +void RtcManager ::timeGetPort_handler(FwIndexType portNum, /*!< The port number*/ + Fw::Time& time /*!< The U32 cmd argument*/ +) { + if (!device_is_ready(this->rv3028)) { + this->log_WARNING_HI_RTC_NotReady(); + return; + } + + struct rtc_time timeptr = {}; + rtc_get_time(this->rv3028, &timeptr); + + // convert to timespec + struct tm* tcopy = rtc_time_to_tm(&timeptr); + time_t tcopy2 = timeutil_timegm(tcopy); + + // struct timespec stime = {0}; + // stime.tv_sec = tcopy2; + // stime.tv_nsec = timeptr.tm_sec * 1000000000L; + + // timespec stime; + // (void)clock_gettime(CLOCK_REALTIME, &stime); + time.set(TimeBase::TB_WORKSTATION_TIME, 0, static_cast(tcopy2), 0); + // time.set(TimeBase::TB_WORKSTATION_TIME, 0, static_cast(stime.tv_sec), static_cast(stime.tv_nsec / + // 1000)); +} + } // namespace Components diff --git a/FprimeZephyrReference/Components/RtcManager/RtcManager.fpp b/FprimeZephyrReference/Components/RtcManager/RtcManager.fpp index 5b070551..e83ea000 100644 --- a/FprimeZephyrReference/Components/RtcManager/RtcManager.fpp +++ b/FprimeZephyrReference/Components/RtcManager/RtcManager.fpp @@ -1,10 +1,23 @@ module Components { @ Manages the real time clock passive component RtcManager { - + import Svc.Time + + # time struct + struct TimeInput { + Year: U32 @< Set the year + Month: U32 @< Set the month + Day: U32 @< Set the day + Hour: U32 @< Set the hour + Minute: U32 @< Set the minute + } + + # Modify command @ SET_TIME command to set the time on the RTC @ Requirement RtcManager-001 - sync command SET_TIME opcode 0 + sync command SET_TIME( + t: TimeInput @< Set the time + ) opcode 0 @ GET_TIME command to get the time from the RTC @ Requirement RtcManager-002 diff --git a/FprimeZephyrReference/Components/RtcManager/RtcManager.hpp b/FprimeZephyrReference/Components/RtcManager/RtcManager.hpp index 0ae35916..7c34d5a9 100644 --- a/FprimeZephyrReference/Components/RtcManager/RtcManager.hpp +++ b/FprimeZephyrReference/Components/RtcManager/RtcManager.hpp @@ -12,6 +12,7 @@ #include #include #include +#include namespace Components { @@ -37,8 +38,9 @@ class RtcManager final : public RtcManagerComponentBase { //! //! SET_TIME command to set the time on the RTC //! Requirement RtcManager-001 - void SET_TIME_cmdHandler(FwOpcodeType opCode, //!< The opcode - U32 cmdSeq //!< The command sequence number + void SET_TIME_cmdHandler(FwOpcodeType opCode, //!< The opcode + U32 cmdSeq, //!< The command sequence number + Components::RtcManager_TimeInput t //!< Set the time ) override; //! Handler implementation for command GET_TIME @@ -49,6 +51,10 @@ class RtcManager final : public RtcManagerComponentBase { U32 cmdSeq //!< The command sequence number ) override; + void timeGetPort_handler(FwIndexType portNum, /*!< The port number*/ + Fw::Time& time /*!< The U32 cmd argument*/ + ); + //! Zephyr device stores the initialized RV2038 sensor const struct device* rv3028; }; diff --git a/FprimeZephyrReference/ReferenceDeployment/Top/instances.fpp b/FprimeZephyrReference/ReferenceDeployment/Top/instances.fpp index 483db3ac..fb72739b 100644 --- a/FprimeZephyrReference/ReferenceDeployment/Top/instances.fpp +++ b/FprimeZephyrReference/ReferenceDeployment/Top/instances.fpp @@ -50,8 +50,6 @@ module ReferenceDeployment { # Passive component instances # ---------------------------------------------------------------------- - instance posixTime: Zephyr.PosixTime base id 0x10010000 - instance rateGroupDriver: Svc.RateGroupDriver base id 0x10011000 instance version: Svc.Version base id 0x10012000 diff --git a/FprimeZephyrReference/ReferenceDeployment/Top/topology.fpp b/FprimeZephyrReference/ReferenceDeployment/Top/topology.fpp index 6941194c..8753ea32 100644 --- a/FprimeZephyrReference/ReferenceDeployment/Top/topology.fpp +++ b/FprimeZephyrReference/ReferenceDeployment/Top/topology.fpp @@ -20,16 +20,15 @@ module ReferenceDeployment { # ---------------------------------------------------------------------- # Instances used in the topology # ---------------------------------------------------------------------- - instance posixTime instance rateGroup10Hz instance rateGroup1Hz instance rateGroupDriver instance timer instance comDriver instance gpioDriver + instance rtcManager instance watchdog instance prmDb - instance rtcManager # ---------------------------------------------------------------------- # Pattern graph specifiers @@ -39,7 +38,7 @@ module ReferenceDeployment { event connections instance CdhCore.events text event connections instance CdhCore.textLogger health connections instance CdhCore.$health - time connections instance posixTime + time connections instance rtcManager telemetry connections instance CdhCore.tlmSend param connections instance prmDb From 09e097b9037d77a9cf4d5bba7953328b8c7970f3 Mon Sep 17 00:00:00 2001 From: Nate Gay Date: Thu, 18 Sep 2025 09:39:24 -0500 Subject: [PATCH 15/40] Set fprime-zephyr submodule to latest main --- .gitmodules | 3 +-- lib/fprime-zephyr | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/.gitmodules b/.gitmodules index 68bf0880..ef179827 100644 --- a/.gitmodules +++ b/.gitmodules @@ -6,5 +6,4 @@ url = https://github.com/zephyrproject-rtos/zephyr.git [submodule "lib/fprime-zephyr"] path = lib/fprime-zephyr - url = https://github.com/nateinaction/fprime-zephyr.git - branch = zephyrtime + url = https://github.com/fprime-community/fprime-zephyr.git diff --git a/lib/fprime-zephyr b/lib/fprime-zephyr index aea685c5..80e7ae5f 160000 --- a/lib/fprime-zephyr +++ b/lib/fprime-zephyr @@ -1 +1 @@ -Subproject commit aea685c5a6e7d5f37445ee2a7c843d39c96c219b +Subproject commit 80e7ae5fe25240e0301124ca6ac9a52b5bfce801 From b7b442e8a056165ac2c22f327ef65478106543fd Mon Sep 17 00:00:00 2001 From: Nate Gay Date: Thu, 18 Sep 2025 12:14:22 -0500 Subject: [PATCH 16/40] Split rtc manager/driver, confirmed working --- .../Components/CMakeLists.txt | 1 + .../Components/Drv/CMakeLists.txt | 1 + .../Drv/Rv3028Driver/CMakeLists.txt | 36 +++++++ .../Drv/Rv3028Driver/Rv3028Driver.cpp | 94 +++++++++++++++++++ .../Drv/Rv3028Driver/Rv3028Driver.fpp | 56 +++++++++++ .../Drv/Rv3028Driver/Rv3028Driver.hpp | 64 +++++++++++++ .../Components/Drv/Rv3028Driver/docs/sdd.md | 36 +++++++ .../Components/RtcManager/RtcManager.cpp | 91 ++---------------- .../Components/RtcManager/RtcManager.fpp | 37 ++------ .../Components/RtcManager/RtcManager.hpp | 17 +--- .../Components/RtcManager/docs/sdd.md | 31 +----- .../ReferenceDeployment/Top/instances.fpp | 16 ++-- .../ReferenceDeployment/Top/topology.fpp | 10 +- 13 files changed, 330 insertions(+), 160 deletions(-) create mode 100644 FprimeZephyrReference/Components/Drv/CMakeLists.txt create mode 100644 FprimeZephyrReference/Components/Drv/Rv3028Driver/CMakeLists.txt create mode 100644 FprimeZephyrReference/Components/Drv/Rv3028Driver/Rv3028Driver.cpp create mode 100644 FprimeZephyrReference/Components/Drv/Rv3028Driver/Rv3028Driver.fpp create mode 100644 FprimeZephyrReference/Components/Drv/Rv3028Driver/Rv3028Driver.hpp create mode 100644 FprimeZephyrReference/Components/Drv/Rv3028Driver/docs/sdd.md diff --git a/FprimeZephyrReference/Components/CMakeLists.txt b/FprimeZephyrReference/Components/CMakeLists.txt index 43581929..1fc004bc 100644 --- a/FprimeZephyrReference/Components/CMakeLists.txt +++ b/FprimeZephyrReference/Components/CMakeLists.txt @@ -1,5 +1,6 @@ # Include project-wide components here +add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/Drv") add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/FatalHandler") add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/Watchdog") add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/RtcManager/") diff --git a/FprimeZephyrReference/Components/Drv/CMakeLists.txt b/FprimeZephyrReference/Components/Drv/CMakeLists.txt new file mode 100644 index 00000000..16b6fead --- /dev/null +++ b/FprimeZephyrReference/Components/Drv/CMakeLists.txt @@ -0,0 +1 @@ +add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/Rv3028Driver") diff --git a/FprimeZephyrReference/Components/Drv/Rv3028Driver/CMakeLists.txt b/FprimeZephyrReference/Components/Drv/Rv3028Driver/CMakeLists.txt new file mode 100644 index 00000000..b832e352 --- /dev/null +++ b/FprimeZephyrReference/Components/Drv/Rv3028Driver/CMakeLists.txt @@ -0,0 +1,36 @@ +#### +# F Prime CMakeLists.txt: +# +# SOURCES: list of source files (to be compiled) +# AUTOCODER_INPUTS: list of files to be passed to the autocoders +# DEPENDS: list of libraries that this module depends on +# +# More information in the F´ CMake API documentation: +# https://fprime.jpl.nasa.gov/latest/docs/reference/api/cmake/API/ +# +#### + +# Module names are derived from the path from the nearest project/library/framework +# root when not specifically overridden by the developer. i.e. The module defined by +# `Ref/SignalGen/CMakeLists.txt` will be named `Ref_SignalGen`. + +register_fprime_library( + AUTOCODER_INPUTS + "${CMAKE_CURRENT_LIST_DIR}/Rv3028Driver.fpp" + SOURCES + "${CMAKE_CURRENT_LIST_DIR}/Rv3028Driver.cpp" +# DEPENDS +# MyPackage_MyOtherModule +) + +### Unit Tests ### +# register_fprime_ut( +# AUTOCODER_INPUTS +# "${CMAKE_CURRENT_LIST_DIR}/Rv3028Driver.fpp" +# SOURCES +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/Rv3028DriverTestMain.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/Rv3028DriverTester.cpp" +# DEPENDS +# STest # For rules-based testing +# UT_AUTO_HELPERS +# ) diff --git a/FprimeZephyrReference/Components/Drv/Rv3028Driver/Rv3028Driver.cpp b/FprimeZephyrReference/Components/Drv/Rv3028Driver/Rv3028Driver.cpp new file mode 100644 index 00000000..622c9622 --- /dev/null +++ b/FprimeZephyrReference/Components/Drv/Rv3028Driver/Rv3028Driver.cpp @@ -0,0 +1,94 @@ +// ====================================================================== +// \title Rv3028Driver.cpp +// \brief cpp file for Rv3028Driver component implementation class +// ====================================================================== + +#include "FprimeZephyrReference/Components/Drv/Rv3028Driver/Rv3028Driver.hpp" + +namespace Drv { + +// ---------------------------------------------------------------------- +// Component construction and destruction +// ---------------------------------------------------------------------- + +Rv3028Driver ::Rv3028Driver(const char* const compName) : Rv3028DriverComponentBase(compName) { + // Initialize device + this->rv3028 = device_get_binding("RV3028"); + FW_ASSERT(device_is_ready(this->rv3028)); +} + +Rv3028Driver ::~Rv3028Driver() {} + +// ---------------------------------------------------------------------- +// Handler implementations for commands +// ---------------------------------------------------------------------- + +void Rv3028Driver ::timeGetPort_handler(FwIndexType portNum, Fw::Time& time) { + // Check device readiness + if (!device_is_ready(this->rv3028)) { + this->log_WARNING_HI_DeviceNotReady(); + return; + } + + // Fetch time from RTC + struct rtc_time time_rtc = {}; + rtc_get_time(this->rv3028, &time_rtc); + + // Convert time to POSIX time_t format + struct tm* time_tm = rtc_time_to_tm(&time_rtc); + time_t time_posix = timeutil_timegm(time_tm); + + // Set FPrime time object + time.set(TimeBase::TB_WORKSTATION_TIME, 0, static_cast(time_posix), 0); +} + +U32 Rv3028Driver ::timeRead_handler(FwIndexType portNum) { + // Check device readiness + if (!device_is_ready(this->rv3028)) { + this->log_WARNING_HI_DeviceNotReady(); + return 0; + } + + // Fetch time from RTC + struct rtc_time time_rtc = {}; + rtc_get_time(this->rv3028, &time_rtc); + + // Convert time to POSIX time_t format + struct tm* time_tm = rtc_time_to_tm(&time_rtc); + time_t time_posix = timeutil_timegm(time_tm); + + return time_posix; +} + +void Rv3028Driver ::timeSet_handler(FwIndexType portNum, const Drv::TimeData& t) { + // Check device readiness + if (!device_is_ready(this->rv3028)) { + this->log_WARNING_HI_DeviceNotReady(); + return; + } + + // Populate rtc_time structure from TimeData + const struct rtc_time time_rtc = { + .tm_sec = 0, + .tm_min = t.get_Minute(), + .tm_hour = t.get_Hour(), + .tm_mday = t.get_Day(), + .tm_mon = t.get_Month() - 1, // month [0-11] + .tm_year = t.get_Year() - 1900, // year since 1900 + .tm_wday = 0, + .tm_yday = 0, + .tm_isdst = 0, + }; + + // Set time on RTC + const int status = rtc_set_time(this->rv3028, &time_rtc); + + // Report whether setting the time was successful + if (status == 0) { + this->log_ACTIVITY_HI_TimeSet(); + } else { + this->log_WARNING_HI_TimeNotSet(); + } +} + +} // namespace Drv diff --git a/FprimeZephyrReference/Components/Drv/Rv3028Driver/Rv3028Driver.fpp b/FprimeZephyrReference/Components/Drv/Rv3028Driver/Rv3028Driver.fpp new file mode 100644 index 00000000..89d85172 --- /dev/null +++ b/FprimeZephyrReference/Components/Drv/Rv3028Driver/Rv3028Driver.fpp @@ -0,0 +1,56 @@ +# Type definition +module Drv { + struct TimeData { + Year: U32 @< Year value. + Month: U32 @< Month value. + Day: U32 @< Day value. + Hour: U32 @< Hour value. + Minute: U32 @< Minute value. + } +} + +# Port definition +module Drv { + port TimeSet(t: TimeData) + port TimeRead -> U32 +} + +module Drv { + @ Manages the real time clock + passive component Rv3028Driver { + import Svc.Time + + @ timeSet port to set the time on the RTC + @ Requirement Rv3028Driver-001 + sync input port timeSet: TimeSet + + @ timeRead port to get the time from the RTC + @ Requirement Rv3028Driver-002 + sync input port timeRead: TimeRead + + ############################################################################## + #### Uncomment the following examples to start customizing your component #### + ############################################################################## + + @ DeviceNotReady event indicates that the RV3028 is not ready + event DeviceNotReady() severity warning high id 0 format "RV3028 not ready" + + @ TimeSet event indicates that the time was set successfully + event TimeSet() severity activity high id 1 format "Time set on RV3028" + + @ TimeNotSet event indicates that the time was not set successfully + event TimeNotSet() severity warning high id 2 format "Time not set on RV3028" + + ############################################################################### + # Standard AC Ports: Required for Channels, Events, Commands, and Parameters # + ############################################################################### + @ Port for requesting the current time + time get port timeCaller + + @ Port for sending textual representation of events + text event port logTextOut + + @ Port for sending events to downlink + event port logOut + } +} diff --git a/FprimeZephyrReference/Components/Drv/Rv3028Driver/Rv3028Driver.hpp b/FprimeZephyrReference/Components/Drv/Rv3028Driver/Rv3028Driver.hpp new file mode 100644 index 00000000..aa245450 --- /dev/null +++ b/FprimeZephyrReference/Components/Drv/Rv3028Driver/Rv3028Driver.hpp @@ -0,0 +1,64 @@ +// ====================================================================== +// \title Rv3028Driver.hpp +// \brief hpp file for Rv3028Driver component implementation class +// ====================================================================== + +#ifndef Components_Rv3028Driver_HPP +#define Components_Rv3028Driver_HPP + +#include "FprimeZephyrReference/Components/Drv/Rv3028Driver/Rv3028DriverComponentAc.hpp" + +#include +#include +#include +#include +#include + +namespace Drv { + +class Rv3028Driver final : public Rv3028DriverComponentBase { + public: + // ---------------------------------------------------------------------- + // Component construction and destruction + // ---------------------------------------------------------------------- + + //! Construct Rv3028Driver object + Rv3028Driver(const char* const compName //!< The component name + ); + + //! Destroy Rv3028Driver object + ~Rv3028Driver(); + + private: + // ---------------------------------------------------------------------- + // Handler implementations for commands + // ---------------------------------------------------------------------- + + //! Handler implementation for timeGetPort + //! + //! Port to retrieve time + void timeGetPort_handler(FwIndexType portNum, //!< The port number + Fw::Time& time //!< Reference to Time object + ) override; + + //! Handler implementation for timeRead + //! + //! timeRead port to get the time from the RTC + //! Requirement Rv3028Driver-002 + U32 timeRead_handler(FwIndexType portNum //!< The port number + ) override; + + //! Handler implementation for timeSet + //! + //! timeSet port to set the time on the RTC + //! Requirement Rv3028Driver-001 + void timeSet_handler(FwIndexType portNum, //!< The port number + const Drv::TimeData& time) override; + + //! Zephyr device stores the initialized RV2038 sensor + const struct device* rv3028; +}; + +} // namespace Drv + +#endif diff --git a/FprimeZephyrReference/Components/Drv/Rv3028Driver/docs/sdd.md b/FprimeZephyrReference/Components/Drv/Rv3028Driver/docs/sdd.md new file mode 100644 index 00000000..485ceeea --- /dev/null +++ b/FprimeZephyrReference/Components/Drv/Rv3028Driver/docs/sdd.md @@ -0,0 +1,36 @@ +# Components::Rv3028Driver + +Drives the real time clock + +## Requirements +Add requirements in the chart below +| Name | Description | Validation | +|---|---|---| +| Rv3028Driver-001 | Time can be set on the RTC through a port | Manual | +| Rv3028Driver-002 | Time can be gotten through a port | Manual | +| Rv3028Driver-003 | Not ready event and set event will be emitted from the driver | Manual | +| Rv3028Driver-003 | The time from the Rv3028 Driver will set the time in F Prime | Manual | + +## Port Descriptions +| Name | Description | +|---|---| +| SET_TIME (input) | Port that receives a command to set the time | +| timeCaller (time) | Output port to send the time | +|GET_TIME| Port that sends the time| + + +## Sequence Diagrams +Add sequence diagrams here + +## Events +| Name | Description | +|---|---| +| RTC_Set | Transmits success or failure RTC time when it is reset | +| DeviceNotReady | Emits on unsuccessful device connection | + + +## Unit Tests +Add unit test descriptions in the chart below +| Name | Description | Output | Coverage | +|---|---|---|---| +|---|---|---|---| diff --git a/FprimeZephyrReference/Components/RtcManager/RtcManager.cpp b/FprimeZephyrReference/Components/RtcManager/RtcManager.cpp index 2aff39d5..4f82deed 100644 --- a/FprimeZephyrReference/Components/RtcManager/RtcManager.cpp +++ b/FprimeZephyrReference/Components/RtcManager/RtcManager.cpp @@ -11,11 +11,7 @@ namespace Components { // Component construction and destruction // ---------------------------------------------------------------------- -RtcManager ::RtcManager(const char* const compName) : RtcManagerComponentBase(compName) { - // Initialize device - this->rv3028 = device_get_binding("RV3028"); - FW_ASSERT(device_is_ready(this->rv3028)); -} +RtcManager ::RtcManager(const char* const compName) : RtcManagerComponentBase(compName) {} RtcManager ::~RtcManager() {} @@ -23,90 +19,23 @@ RtcManager ::~RtcManager() {} // Handler implementations for commands // ---------------------------------------------------------------------- -void RtcManager ::SET_TIME_cmdHandler(FwOpcodeType opCode, U32 cmdSeq, Components::RtcManager_TimeInput t) { - if (!device_is_ready(this->rv3028)) { - this->log_WARNING_HI_RTC_NotReady(); - return; - } - - // set the time - const struct rtc_time timeptr = { - .tm_sec = 0, - .tm_min = t.get_Minute(), - .tm_hour = t.get_Hour(), - .tm_mday = t.get_Day(), - .tm_mon = t.get_Month() - 1, // month [0-11] - .tm_year = t.get_Year() - 1900, // year since 1900 - .tm_wday = 0, - .tm_yday = 0, - .tm_isdst = 0, - }; - const int status = rtc_set_time(this->rv3028, &timeptr); - - if (status == 0) { - this->log_ACTIVITY_HI_RTC_Set(true); - } else { - this->log_ACTIVITY_HI_RTC_Set(false); - } - +void RtcManager ::SET_TIME_cmdHandler(FwOpcodeType opCode, U32 cmdSeq, Drv::TimeData t) { + this->timeSet_out(0, t); this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK); } void RtcManager ::GET_TIME_cmdHandler(FwOpcodeType opCode, U32 cmdSeq) { - if (!device_is_ready(this->rv3028)) { - this->log_WARNING_HI_RTC_NotReady(); - return; - } - - struct rtc_time timeptr = {}; - rtc_get_time(this->rv3028, &timeptr); - - this->log_ACTIVITY_HI_RTC_GetTime(timeptr.tm_year + 1900, timeptr.tm_mon + 1, timeptr.tm_mday + 1, timeptr.tm_hour, - timeptr.tm_min, timeptr.tm_sec); - - // 3 parts. - // 1. fprime-zephyr reference need ZephyrTime SVC + instance/topology - // 2. RV3028Driver talk to zephyr and set the time on the RTC - // 3. RtcManager component to take commands and relay them to RV3028Driver and get/set + U32 t = this->timeRead_out(0); - // TODO - Need a way to sync Fprime time with RTC time, especially after - // satellite restarts. RTC has a battery backup and should keep time - // Fprime time will not know anything about the rtc - // need some kind of sync mechanism maybe 1Hz sync? + // Convert POSIX time to tm struct for human readable logging + time_t time_posix = static_cast(t); + struct tm time_tm_buf; + struct tm* time_tm = gmtime_r(&time_posix, &time_tm_buf); - // Try Fprime Time class - const Fw::Time fwtime = this->getTime(); - const U32 secs = fwtime.getSeconds(); - - this->log_ACTIVITY_HI_RTC_GetTime(0, 0, 0, 0, 0, secs); + this->log_ACTIVITY_HI_RTC_GetTime(time_tm->tm_year + 1900, time_tm->tm_mon + 1, time_tm->tm_mday + 1, + time_tm->tm_hour, time_tm->tm_min, time_tm->tm_sec); this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK); } -void RtcManager ::timeGetPort_handler(FwIndexType portNum, /*!< The port number*/ - Fw::Time& time /*!< The U32 cmd argument*/ -) { - if (!device_is_ready(this->rv3028)) { - this->log_WARNING_HI_RTC_NotReady(); - return; - } - - struct rtc_time timeptr = {}; - rtc_get_time(this->rv3028, &timeptr); - - // convert to timespec - struct tm* tcopy = rtc_time_to_tm(&timeptr); - time_t tcopy2 = timeutil_timegm(tcopy); - - // struct timespec stime = {0}; - // stime.tv_sec = tcopy2; - // stime.tv_nsec = timeptr.tm_sec * 1000000000L; - - // timespec stime; - // (void)clock_gettime(CLOCK_REALTIME, &stime); - time.set(TimeBase::TB_WORKSTATION_TIME, 0, static_cast(tcopy2), 0); - // time.set(TimeBase::TB_WORKSTATION_TIME, 0, static_cast(stime.tv_sec), static_cast(stime.tv_nsec / - // 1000)); -} - } // namespace Components diff --git a/FprimeZephyrReference/Components/RtcManager/RtcManager.fpp b/FprimeZephyrReference/Components/RtcManager/RtcManager.fpp index e83ea000..e1f82dee 100644 --- a/FprimeZephyrReference/Components/RtcManager/RtcManager.fpp +++ b/FprimeZephyrReference/Components/RtcManager/RtcManager.fpp @@ -1,22 +1,10 @@ module Components { @ Manages the real time clock passive component RtcManager { - import Svc.Time - - # time struct - struct TimeInput { - Year: U32 @< Set the year - Month: U32 @< Set the month - Day: U32 @< Set the day - Hour: U32 @< Set the hour - Minute: U32 @< Set the minute - } - - # Modify command @ SET_TIME command to set the time on the RTC @ Requirement RtcManager-001 sync command SET_TIME( - t: TimeInput @< Set the time + t: Drv.TimeData @< Set the time ) opcode 0 @ GET_TIME command to get the time from the RTC @@ -27,27 +15,16 @@ module Components { #### Uncomment the following examples to start customizing your component #### ############################################################################## - import Fw.Channel - # @ Example async command - # async command COMMAND_NAME(param_name: U32) - - # @ Example telemetry counter - # telemetry ExampleCounter: U64 - - # @ Example event - # event ExampleStateEvent(example_state: Fw.On) severity activity high id 0 format "State set to {}" - event RTC_Set(status: bool) severity activity high id 0 format "Reset status: {}" + # import Fw.Channel + @ Event to log the time retrieved from the Rv3028Driver event RTC_GetTime(year: U32, month: U32, day: U32, hour:U32, minute:U32, second:U32) severity activity high id 1 format "Time: {}/{}/{} at {}:{}:{}" - event RTC_NotReady() severity warning high id 2 format "RTC not ready" - - # @ Example port: receiving calls from the rate group - # sync input port run: Svc.Sched - output port SetTime: Fw.Time + @ Output port to set the time on the Rv3028Driver + output port timeSet: Drv.TimeSet - # @ Example parameter - # param PARAMETER_NAME: U32 + @ Output port to get the time from the Rv3028Driver + output port timeRead: Drv.TimeRead ############################################################################### # Standard AC Ports: Required for Channels, Events, Commands, and Parameters # diff --git a/FprimeZephyrReference/Components/RtcManager/RtcManager.hpp b/FprimeZephyrReference/Components/RtcManager/RtcManager.hpp index 7c34d5a9..78bc7956 100644 --- a/FprimeZephyrReference/Components/RtcManager/RtcManager.hpp +++ b/FprimeZephyrReference/Components/RtcManager/RtcManager.hpp @@ -8,10 +8,6 @@ #include "FprimeZephyrReference/Components/RtcManager/RtcManagerComponentAc.hpp" -#include -#include -#include -#include #include namespace Components { @@ -38,9 +34,9 @@ class RtcManager final : public RtcManagerComponentBase { //! //! SET_TIME command to set the time on the RTC //! Requirement RtcManager-001 - void SET_TIME_cmdHandler(FwOpcodeType opCode, //!< The opcode - U32 cmdSeq, //!< The command sequence number - Components::RtcManager_TimeInput t //!< Set the time + void SET_TIME_cmdHandler(FwOpcodeType opCode, //!< The opcode + U32 cmdSeq, //!< The command sequence number + Drv::TimeData t //!< Set the time ) override; //! Handler implementation for command GET_TIME @@ -50,13 +46,6 @@ class RtcManager final : public RtcManagerComponentBase { void GET_TIME_cmdHandler(FwOpcodeType opCode, //!< The opcode U32 cmdSeq //!< The command sequence number ) override; - - void timeGetPort_handler(FwIndexType portNum, /*!< The port number*/ - Fw::Time& time /*!< The U32 cmd argument*/ - ); - - //! Zephyr device stores the initialized RV2038 sensor - const struct device* rv3028; }; } // namespace Components diff --git a/FprimeZephyrReference/Components/RtcManager/docs/sdd.md b/FprimeZephyrReference/Components/RtcManager/docs/sdd.md index 5b8cf852..d63330c2 100644 --- a/FprimeZephyrReference/Components/RtcManager/docs/sdd.md +++ b/FprimeZephyrReference/Components/RtcManager/docs/sdd.md @@ -18,32 +18,17 @@ Add a class diagram here Add requirements in the chart below | Name | Description | Validation | |---|---|---| -| RtcManager-001 | Caller can set time on the RTC | Manual | -| RtcManager-002 | Caller can receive time from FPrime | Manual | -| RtcManager-003 | Event when time is set, report success or failure | Manual | -| RtcManager-003 | Able to sync RTC time with F Prime [TBR] | Manual | - +| RtcManager-001 | The RTC manager shall have a command to set and get times from the RTC Driver | Manual | +| RtcManager-002 | An Event is Emitted when time is gotten with the time | Manual | ## Port Descriptions | Name | Description | |---|---| | SetTime (output) | Port to reach out to driver to set the time | +| TimeSend (input) | Port to receive the time from driver | +| TimeRead (output) | Port to reach out to driver to ask for the time | | timeCaller (time) | Port to receive time | -## Component States -Add component states in the chart below -| Name | Description | -|---|---| -|---|---| - -## Sequence Diagrams -Add sequence diagrams here - -## Parameters -| Name | Description | -|---|---| -|---|---| - ## Commands | Name | Description | |---|---| @@ -54,14 +39,8 @@ Add sequence diagrams here ## Events | Name | Description | |---|---| -| RTC_Set | Transmits success or failure RTC time when it is reset | -| RTC_NotReady | Emits on unsuccessful device connection | - +| RTC_GetTime | Transmits time gotten from the driver | -## Telemetry -| Name | Description | -|---|---| -|---|---| ## Unit Tests Add unit test descriptions in the chart below diff --git a/FprimeZephyrReference/ReferenceDeployment/Top/instances.fpp b/FprimeZephyrReference/ReferenceDeployment/Top/instances.fpp index fb72739b..7a980a31 100644 --- a/FprimeZephyrReference/ReferenceDeployment/Top/instances.fpp +++ b/FprimeZephyrReference/ReferenceDeployment/Top/instances.fpp @@ -49,19 +49,21 @@ module ReferenceDeployment { # ---------------------------------------------------------------------- # Passive component instances # ---------------------------------------------------------------------- + instance rateGroupDriver: Svc.RateGroupDriver base id 0x10010000 - instance rateGroupDriver: Svc.RateGroupDriver base id 0x10011000 + instance version: Svc.Version base id 0x10011000 - instance version: Svc.Version base id 0x10012000 + instance timer: Zephyr.ZephyrRateDriver base id 0x10012000 - instance timer: Zephyr.ZephyrRateDriver base id 0x10013000 + instance comDriver: Zephyr.ZephyrUartDriver base id 0x10013000 - instance comDriver: Zephyr.ZephyrUartDriver base id 0x10014000 + instance gpioDriver: Zephyr.ZephyrGpioDriver base id 0x10014000 - instance gpioDriver: Zephyr.ZephyrGpioDriver base id 0x10015000 + instance watchdog: Components.Watchdog base id 0x10015000 - instance watchdog: Components.Watchdog base id 0x10016000 + instance rtcManager: Components.RtcManager base id 0x10016000 + + instance rv3028Driver: Drv.Rv3028Driver base id 0x10017000 - instance rtcManager: Components.RtcManager base id 0x10017000 } diff --git a/FprimeZephyrReference/ReferenceDeployment/Top/topology.fpp b/FprimeZephyrReference/ReferenceDeployment/Top/topology.fpp index 8753ea32..a2bfed56 100644 --- a/FprimeZephyrReference/ReferenceDeployment/Top/topology.fpp +++ b/FprimeZephyrReference/ReferenceDeployment/Top/topology.fpp @@ -26,9 +26,10 @@ module ReferenceDeployment { instance timer instance comDriver instance gpioDriver - instance rtcManager instance watchdog instance prmDb + instance rv3028Driver + instance rtcManager # ---------------------------------------------------------------------- # Pattern graph specifiers @@ -38,7 +39,7 @@ module ReferenceDeployment { event connections instance CdhCore.events text event connections instance CdhCore.textLogger health connections instance CdhCore.$health - time connections instance rtcManager + time connections instance rv3028Driver telemetry connections instance CdhCore.tlmSend param connections instance prmDb @@ -98,6 +99,11 @@ module ReferenceDeployment { watchdog.gpioSet -> gpioDriver.gpioWrite } + connections RtcManager { + rtcManager.timeSet -> rv3028Driver.timeSet + rtcManager.timeRead -> rv3028Driver.timeRead + } + connections ReferenceDeployment { } From 6d893658652106a065dbcbcdd92626afb590b00c Mon Sep 17 00:00:00 2001 From: Nate Gay Date: Thu, 18 Sep 2025 12:24:53 -0500 Subject: [PATCH 17/40] Working on sdds --- .../Components/Drv/Rv3028Driver/docs/sdd.md | 25 +++++++------------ .../Components/RtcManager/RtcManager.cpp | 5 ++-- .../Components/RtcManager/RtcManager.fpp | 6 +---- .../Components/RtcManager/docs/sdd.md | 12 ++++----- 4 files changed, 19 insertions(+), 29 deletions(-) diff --git a/FprimeZephyrReference/Components/Drv/Rv3028Driver/docs/sdd.md b/FprimeZephyrReference/Components/Drv/Rv3028Driver/docs/sdd.md index 485ceeea..34e28355 100644 --- a/FprimeZephyrReference/Components/Drv/Rv3028Driver/docs/sdd.md +++ b/FprimeZephyrReference/Components/Drv/Rv3028Driver/docs/sdd.md @@ -6,18 +6,17 @@ Drives the real time clock Add requirements in the chart below | Name | Description | Validation | |---|---|---| -| Rv3028Driver-001 | Time can be set on the RTC through a port | Manual | -| Rv3028Driver-002 | Time can be gotten through a port | Manual | -| Rv3028Driver-003 | Not ready event and set event will be emitted from the driver | Manual | -| Rv3028Driver-003 | The time from the Rv3028 Driver will set the time in F Prime | Manual | +| Rv3028Driver-001 | Time can be set on the RV3028 through a port | Manual | +| Rv3028Driver-002 | Time can be read from the RV3028 through a port | Manual | +| Rv3028Driver-003 | A device not ready event is emitted if the RV3028 is not ready | Manual | +| Rv3028Driver-004 | A time set event is emitted if the time is set successfully | Manual | +| Rv3028Driver-005 | A time not set event is emitted if the time is not set successfully | Manual | ## Port Descriptions | Name | Description | |---|---| -| SET_TIME (input) | Port that receives a command to set the time | -| timeCaller (time) | Output port to send the time | -|GET_TIME| Port that sends the time| - +| timeSet | Input port sets the time on the RV3028 | +| timeRead | Input port reads the time from the RV3028 | ## Sequence Diagrams Add sequence diagrams here @@ -25,12 +24,6 @@ Add sequence diagrams here ## Events | Name | Description | |---|---| -| RTC_Set | Transmits success or failure RTC time when it is reset | | DeviceNotReady | Emits on unsuccessful device connection | - - -## Unit Tests -Add unit test descriptions in the chart below -| Name | Description | Output | Coverage | -|---|---|---|---| -|---|---|---|---| +| TimeSet | Emits on successful time set | +| TimeNotSet | Emits on unsuccessful time set | diff --git a/FprimeZephyrReference/Components/RtcManager/RtcManager.cpp b/FprimeZephyrReference/Components/RtcManager/RtcManager.cpp index 4f82deed..cafb7a17 100644 --- a/FprimeZephyrReference/Components/RtcManager/RtcManager.cpp +++ b/FprimeZephyrReference/Components/RtcManager/RtcManager.cpp @@ -32,8 +32,9 @@ void RtcManager ::GET_TIME_cmdHandler(FwOpcodeType opCode, U32 cmdSeq) { struct tm time_tm_buf; struct tm* time_tm = gmtime_r(&time_posix, &time_tm_buf); - this->log_ACTIVITY_HI_RTC_GetTime(time_tm->tm_year + 1900, time_tm->tm_mon + 1, time_tm->tm_mday + 1, - time_tm->tm_hour, time_tm->tm_min, time_tm->tm_sec); + // Report time retrieved + this->log_ACTIVITY_HI_GetTime(time_tm->tm_year + 1900, time_tm->tm_mon + 1, time_tm->tm_mday + 1, time_tm->tm_hour, + time_tm->tm_min, time_tm->tm_sec); this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK); } diff --git a/FprimeZephyrReference/Components/RtcManager/RtcManager.fpp b/FprimeZephyrReference/Components/RtcManager/RtcManager.fpp index e1f82dee..2aa57452 100644 --- a/FprimeZephyrReference/Components/RtcManager/RtcManager.fpp +++ b/FprimeZephyrReference/Components/RtcManager/RtcManager.fpp @@ -2,23 +2,19 @@ module Components { @ Manages the real time clock passive component RtcManager { @ SET_TIME command to set the time on the RTC - @ Requirement RtcManager-001 sync command SET_TIME( t: Drv.TimeData @< Set the time ) opcode 0 @ GET_TIME command to get the time from the RTC - @ Requirement RtcManager-002 sync command GET_TIME opcode 1 ############################################################################## #### Uncomment the following examples to start customizing your component #### ############################################################################## - # import Fw.Channel - @ Event to log the time retrieved from the Rv3028Driver - event RTC_GetTime(year: U32, month: U32, day: U32, hour:U32, minute:U32, second:U32) severity activity high id 1 format "Time: {}/{}/{} at {}:{}:{}" + event GetTime(year: U32, month: U32, day: U32, hour:U32, minute:U32, second:U32) severity activity high id 1 format "Time: {}/{}/{} at {}:{}:{}" @ Output port to set the time on the Rv3028Driver output port timeSet: Drv.TimeSet diff --git a/FprimeZephyrReference/Components/RtcManager/docs/sdd.md b/FprimeZephyrReference/Components/RtcManager/docs/sdd.md index d63330c2..04e3589d 100644 --- a/FprimeZephyrReference/Components/RtcManager/docs/sdd.md +++ b/FprimeZephyrReference/Components/RtcManager/docs/sdd.md @@ -18,16 +18,15 @@ Add a class diagram here Add requirements in the chart below | Name | Description | Validation | |---|---|---| -| RtcManager-001 | The RTC manager shall have a command to set and get times from the RTC Driver | Manual | -| RtcManager-002 | An Event is Emitted when time is gotten with the time | Manual | +| RtcM-001 | The RTC manager shall have a command that calls a port that get time from the RTC Driver | Manual | +| RtcM-002 | An Event is Emitted when time is gotten with the time | Manual | +| RtcM-003 | The RTC manager shall have a command that calls a port that makes the RTC Driver set the time | Manual | ## Port Descriptions | Name | Description | |---|---| -| SetTime (output) | Port to reach out to driver to set the time | -| TimeSend (input) | Port to receive the time from driver | +| timeSet (output) | Port to reach out to driver to set the time | | TimeRead (output) | Port to reach out to driver to ask for the time | -| timeCaller (time) | Port to receive time | ## Commands | Name | Description | @@ -39,7 +38,7 @@ Add requirements in the chart below ## Events | Name | Description | |---|---| -| RTC_GetTime | Transmits time gotten from the driver | +| GetTime | Event to log the time retrieved from the Rv3028Driver | ## Unit Tests @@ -53,3 +52,4 @@ Add unit test descriptions in the chart below | Date | Description | |---|---| | 2025-09-17 | Initial Draft | +| 2025-09-18 | Update that connects to driver/manager | From 8cb2b34a6de69d0d15fe1e5e336bb843b5633c28 Mon Sep 17 00:00:00 2001 From: Nate Gay Date: Thu, 18 Sep 2025 13:11:33 -0500 Subject: [PATCH 18/40] Update the RV3028 sdd --- .../Components/Drv/Rv3028Driver/docs/sdd.md | 181 +++++++++++++++++- 1 file changed, 177 insertions(+), 4 deletions(-) diff --git a/FprimeZephyrReference/Components/Drv/Rv3028Driver/docs/sdd.md b/FprimeZephyrReference/Components/Drv/Rv3028Driver/docs/sdd.md index 34e28355..215a20c1 100644 --- a/FprimeZephyrReference/Components/Drv/Rv3028Driver/docs/sdd.md +++ b/FprimeZephyrReference/Components/Drv/Rv3028Driver/docs/sdd.md @@ -1,6 +1,28 @@ # Components::Rv3028Driver -Drives the real time clock +The RV3028 Driver component interfaces with the RV3028 Real Time Clock (RTC) to provide time measurements. + +### Typical Usage + +#### `timeGetPort` Port Usage +1. The component is instantiated and initialized during system startup +2. In a deployment topology, a `time connection` is made to the component's `timeGetPort` port + +#### `timeRead` Port Usage +1. The component is instantiated and initialized during system startup +2. A manager calls the `timeRead` ports +3. On each call, the component: + - Fetches and returns the time from the RV3028 RTC + - Emits a `DeviceNotReady` event if the device is not ready + +#### `timeSet` Port Usage +1. The component is instantiated and initialized during system startup +2. A manager calls the `timeSet` ports +3. On each call, the component: + - Sets the time on the RV3028 RTC + - Emits a `TimeSet` event if the time is set successfully + - Emits a `TimeNotSet` event if the time is not set successfully + - Emits a `DeviceNotReady` event if the device is not ready ## Requirements Add requirements in the chart below @@ -15,15 +37,166 @@ Add requirements in the chart below ## Port Descriptions | Name | Description | |---|---| +| timeGetPort | Time port for FPrime topology connection to get the time from the RV3028 | | timeSet | Input port sets the time on the RV3028 | | timeRead | Input port reads the time from the RV3028 | -## Sequence Diagrams -Add sequence diagrams here - ## Events | Name | Description | |---|---| | DeviceNotReady | Emits on unsuccessful device connection | | TimeSet | Emits on successful time set | | TimeNotSet | Emits on unsuccessful time set | + +## Class Diagram + +```mermaid +classDiagram + namespace Drv { + class Rv3028DriverComponentBase { + <> + } + class Rv3028Driver { + - rv3028: device* + + Rv3028Driver(char* compName) + + ~Rv3028Driver() + - void timeGetPort_handler(FwIndexType portNum, Fw::Time& time) + - U32 timeRead_handler(FwIndexType portNum) + - void timeSet_handler(FwIndexType portNum, const Drv::TimeData& time) + } + } + Rv3028DriverComponentBase <|-- Rv3028Driver : inherits +``` + +## Sequence Diagrams + +### timeGetPort + +The `timeGetPort` is called from a `time connection` in a deployment topology to sync the RTC's time with FPrime's internal clock. + +#### Success +```mermaid +sequenceDiagram + participant Deployment Time Connection + participant RV3028 Driver + participant Zephyr Time API + participant RV3028 RTC + Deployment Time Connection-->>RV3028 Driver: Call timeGetPort time port + RV3028 Driver->>Zephyr Time API: Read time + Zephyr Time API->>RV3028 RTC: Read time + RV3028 RTC->>Zephyr Time API: Return time + Zephyr Time API->>RV3028 Driver: Return time + RV3028 Driver-->>Deployment Time Connection: Return time +``` + +#### Device Not Ready +```mermaid +sequenceDiagram + participant Event Log + participant Deployment Time Connection + participant RV3028 Driver + participant Zephyr Time API + participant RV3028 RTC + Deployment Time Connection->>RV3028 Driver: Call timeGetPort time port + RV3028 Driver->>Zephyr Time API: Read time + Zephyr Time API->>RV3028 RTC: Read time + RV3028 RTC->>Zephyr Time API: Return device not ready + Zephyr Time API->>RV3028 Driver: Return device not ready + RV3028 Driver->>Event Log: Emit DeviceNotReady event + RV3028 Driver->>Deployment Time Connection: Return 0 time +``` + +### timeRead + +#### Success +```mermaid +sequenceDiagram + participant Event Log + participant Manager + participant RV3028 Driver + participant Zephyr Time API + participant RV3028 RTC + Manager-->>RV3028 Driver: Call timeRead synchronous input port + RV3028 Driver->>Zephyr Time API: Read time + Zephyr Time API->>RV3028 RTC: Read time + RV3028 RTC->>Zephyr Time API: Return time + Zephyr Time API->>RV3028 Driver: Return time + RV3028 Driver->>Event Log: Emit event GetTime +``` + +#### Device Not Ready +```mermaid +sequenceDiagram + participant Event Log + participant Manager + participant RV3028 Driver + participant Zephyr Time API + participant RV3028 RTC + Manager-->>RV3028 Driver: Call timeRead synchronous input port + RV3028 Driver->>Zephyr Time API: Read time + Zephyr Time API->>RV3028 RTC: Read time + RV3028 RTC->>Zephyr Time API: Return device not ready + Zephyr Time API->>RV3028 Driver: Return device not ready + RV3028 Driver->>Event Log: Emit event DeviceNotReady +``` + +### timeSet + +#### Success +```mermaid +sequenceDiagram + participant Ground Station + participant Event Log + participant Manager + participant RV3028 Driver + participant Zephyr Time API + participant RV3028 RTC + Ground Station-->>Manager: Command to set time with Drv::TimeData struct + Manager->>RV3028 Driver: Call the timeSet synchronous input port with Drv::TimeData struct + RV3028 Driver->>Zephyr Time API: Set time + Zephyr Time API->>RV3028 RTC: Set time + RV3028 RTC->>Zephyr Time API: Return set success + Zephyr Time API->>RV3028 Driver: Return set success + RV3028 Driver->>Event Log: Emit event TimeSet +``` + +#### Device Not Ready +```mermaid +sequenceDiagram + participant Ground Station + participant Event Log + participant Manager + participant RV3028 Driver + participant Zephyr Time API + participant RV3028 RTC + Ground Station-->>Manager: Command to set time with Drv::TimeData struct + Manager->>RV3028 Driver: Call the timeSet synchronous input port with Drv::TimeData struct + RV3028 Driver->>Zephyr Time API: Set time + Zephyr Time API->>RV3028 RTC: Set time + RV3028 RTC->>Zephyr Time API: Return device not ready + Zephyr Time API->>RV3028 Driver: Return device not ready + RV3028 Driver->>Event Log: Emit event DeviceNotReady +``` + +#### Time Not Set +```mermaid +sequenceDiagram + participant Ground Station + participant Event Log + participant Manager + participant RV3028 Driver + participant Zephyr Time API + participant RV3028 RTC + Ground Station-->>Manager: Command to set time with Drv::TimeData struct + Manager->>RV3028 Driver: Call the timeSet synchronous input port with Drv::TimeData struct + RV3028 Driver->>Zephyr Time API: Set time + Zephyr Time API->>RV3028 RTC: Set time + RV3028 RTC->>Zephyr Time API: Return set failure + Zephyr Time API->>RV3028 Driver: Return set failure + RV3028 Driver->>Event Log: Emit event TimeNotSet +``` + +## Change Log +| Date | Description | +|---|---| +| 2025-9-18 | Initial RV3028 Driver component | From 3de364a2dafc92c93a14dbec3194a818bd958f86 Mon Sep 17 00:00:00 2001 From: Nate Gay Date: Thu, 18 Sep 2025 13:27:23 -0500 Subject: [PATCH 19/40] Update SDDs --- .../Components/Drv/Rv3028Driver/docs/sdd.md | 14 ++-- .../Components/RtcManager/docs/sdd.md | 84 +++++++++++++------ 2 files changed, 68 insertions(+), 30 deletions(-) diff --git a/FprimeZephyrReference/Components/Drv/Rv3028Driver/docs/sdd.md b/FprimeZephyrReference/Components/Drv/Rv3028Driver/docs/sdd.md index 215a20c1..9c9d84b6 100644 --- a/FprimeZephyrReference/Components/Drv/Rv3028Driver/docs/sdd.md +++ b/FprimeZephyrReference/Components/Drv/Rv3028Driver/docs/sdd.md @@ -25,7 +25,6 @@ The RV3028 Driver component interfaces with the RV3028 Real Time Clock (RTC) to - Emits a `DeviceNotReady` event if the device is not ready ## Requirements -Add requirements in the chart below | Name | Description | Validation | |---|---|---| | Rv3028Driver-001 | Time can be set on the RV3028 through a port | Manual | @@ -49,7 +48,6 @@ Add requirements in the chart below | TimeNotSet | Emits on unsuccessful time set | ## Class Diagram - ```mermaid classDiagram namespace Drv { @@ -70,9 +68,9 @@ classDiagram ## Sequence Diagrams -### timeGetPort +### `timeGetPort` port -The `timeGetPort` is called from a `time connection` in a deployment topology to sync the RTC's time with FPrime's internal clock. +The `timeGetPort` port is called from a `time connection` in a deployment topology to sync the RTC's time with FPrime's internal clock. #### Success ```mermaid @@ -106,7 +104,9 @@ sequenceDiagram RV3028 Driver->>Deployment Time Connection: Return 0 time ``` -### timeRead +### `timeRead` port + +The `timeRead` port is called from a manager component to get the current time from the RTC. #### Success ```mermaid @@ -140,7 +140,9 @@ sequenceDiagram RV3028 Driver->>Event Log: Emit event DeviceNotReady ``` -### timeSet +### `timeSet` port + +The `timeSet` port is called from a manager component to set the current time on the RTC. #### Success ```mermaid diff --git a/FprimeZephyrReference/Components/RtcManager/docs/sdd.md b/FprimeZephyrReference/Components/RtcManager/docs/sdd.md index 04e3589d..52561b2b 100644 --- a/FprimeZephyrReference/Components/RtcManager/docs/sdd.md +++ b/FprimeZephyrReference/Components/RtcManager/docs/sdd.md @@ -1,32 +1,34 @@ # Components::RtcManager -Manages the real time clock - -## Usage Examples -Add usage examples here - -### Diagrams -Add diagrams here +The RtcManager component manages interactions with a Real Time Clock (RTC) device. It interfaces with the Rv3028Driver component to set and get the current time. ### Typical Usage -And the typical usage of the component here -## Class Diagram -Add a class diagram here +#### `SET_TIME` Command Usage +1. The component is instantiated and initialized during system startup +2. A ground station sends a `SET_TIME` command with the desired time +3. On each command, the component: + - Calls the `timeSet` port to set the time on the RTC device + +#### `GET_TIME` Command Usage +1. The component is instantiated and initialized during system startup +2. A ground station sends a `GET_TIME` command +3. On each command, the component: + - Calls the `timeRead` port to get the current time from the RTC device + - Emits a `GetTime` event with the retrieved time ## Requirements -Add requirements in the chart below | Name | Description | Validation | |---|---|---| -| RtcM-001 | The RTC manager shall have a command that calls a port that get time from the RTC Driver | Manual | -| RtcM-002 | An Event is Emitted when time is gotten with the time | Manual | -| RtcM-003 | The RTC manager shall have a command that calls a port that makes the RTC Driver set the time | Manual | +| RtcManager-001 | The RTC manager has a command that reads the time from the RTC | Manual | +| RtcManager-002 | An event with time information is emitted when time is read | Manual | +| RtcManager-003 | The RTC manager has a command that sets the time on the RTC | Manual | ## Port Descriptions | Name | Description | |---|---| -| timeSet (output) | Port to reach out to driver to set the time | -| TimeRead (output) | Port to reach out to driver to ask for the time | +| timeSet | Output port to reach out to driver to set the time | +| TimeRead | Output port to reach out to driver to read the time | ## Commands | Name | Description | @@ -34,22 +36,56 @@ Add requirements in the chart below | SET_TIME | Sets the time on the RTC | | GET_TIME | Gets the time from the RTC | - ## Events | Name | Description | |---|---| | GetTime | Event to log the time retrieved from the Rv3028Driver | +## Class Diagram +```mermaid +classDiagram + namespace Drv { + class RtcManagerComponentBase { + <> + } + class RtcManager { + + RtcManager(char* compName) + + ~RtcManager() + - void SET_TIME_cmdHandler(FwOpcodeType opCode, U32 cmdSeq, Drv::TimeData t) + - void GET_TIME_cmdHandler(FwOpcodeType opCode, U32 cmdSeq) + } + } + RtcManagerComponentBase <|-- RtcManager : inherits +``` + +## Sequence Diagrams + +### `SET_TIME` Command + +```mermaid +sequenceDiagram + participant Ground Station + participant RtcManager + participant RV3028 Driver + Ground Station-->>RtcManager: Send SET_TIME command with time data + RtcManager->>RV3028 Driver: Call timeSet port with time data +``` -## Unit Tests -Add unit test descriptions in the chart below -| Name | Description | Output | Coverage | -|---|---|---|---| -|---|---|---|---| +### `GET_TIME` Command +```mermaid +sequenceDiagram + participant Ground Station + participant Event Log + participant RtcManager + participant RV3028 Driver + Ground Station-->>RtcManager: Send GET_TIME command + RtcManager->>RV3028 Driver: Call timeRead port + RV3028 Driver->>RtcManager: Return time data + RtcManager->>Event Log: Emit GetTime event with retrieved time +``` ## Change Log | Date | Description | |---|---| -| 2025-09-17 | Initial Draft | -| 2025-09-18 | Update that connects to driver/manager | +| 2025-9-18 | Initial RTC Manager component | From 72671c7b4362f268f4d339936b822107396a6348 Mon Sep 17 00:00:00 2001 From: Nate Gay Date: Thu, 18 Sep 2025 17:42:31 -0500 Subject: [PATCH 20/40] Revert submodule change --- lib/fprime-zephyr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/fprime-zephyr b/lib/fprime-zephyr index 80e7ae5f..4a149bbe 160000 --- a/lib/fprime-zephyr +++ b/lib/fprime-zephyr @@ -1 +1 @@ -Subproject commit 80e7ae5fe25240e0301124ca6ac9a52b5bfce801 +Subproject commit 4a149bbed5c7c86fbac44ab8a65791eff97370f9 From e11fb04fa252bf4c9e7c24f873e70c3313b1787d Mon Sep 17 00:00:00 2001 From: SamuelGomezG Date: Mon, 22 Sep 2025 18:18:46 -0500 Subject: [PATCH 21/40] Rename driver to `Rv3028Manager` Co-authored-by: Nate Gay --- FprimeZephyrReference/Components/Drv/CMakeLists.txt | 2 +- .../Drv/{Rv3028Driver => Rv3028Manager}/CMakeLists.txt | 6 +++--- .../Rv3028Driver.cpp => Rv3028Manager/Rv3028Manager.cpp} | 4 ++-- .../Rv3028Driver.fpp => Rv3028Manager/Rv3028Manager.fpp} | 0 .../Rv3028Driver.hpp => Rv3028Manager/Rv3028Manager.hpp} | 6 +++--- .../Drv/{Rv3028Driver => Rv3028Manager}/docs/sdd.md | 4 ++-- 6 files changed, 11 insertions(+), 11 deletions(-) rename FprimeZephyrReference/Components/Drv/{Rv3028Driver => Rv3028Manager}/CMakeLists.txt (85%) rename FprimeZephyrReference/Components/Drv/{Rv3028Driver/Rv3028Driver.cpp => Rv3028Manager/Rv3028Manager.cpp} (96%) rename FprimeZephyrReference/Components/Drv/{Rv3028Driver/Rv3028Driver.fpp => Rv3028Manager/Rv3028Manager.fpp} (100%) rename FprimeZephyrReference/Components/Drv/{Rv3028Driver/Rv3028Driver.hpp => Rv3028Manager/Rv3028Manager.hpp} (91%) rename FprimeZephyrReference/Components/Drv/{Rv3028Driver => Rv3028Manager}/docs/sdd.md (98%) diff --git a/FprimeZephyrReference/Components/Drv/CMakeLists.txt b/FprimeZephyrReference/Components/Drv/CMakeLists.txt index 16b6fead..fc46133a 100644 --- a/FprimeZephyrReference/Components/Drv/CMakeLists.txt +++ b/FprimeZephyrReference/Components/Drv/CMakeLists.txt @@ -1 +1 @@ -add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/Rv3028Driver") +add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/Rv3028Manager") diff --git a/FprimeZephyrReference/Components/Drv/Rv3028Driver/CMakeLists.txt b/FprimeZephyrReference/Components/Drv/Rv3028Manager/CMakeLists.txt similarity index 85% rename from FprimeZephyrReference/Components/Drv/Rv3028Driver/CMakeLists.txt rename to FprimeZephyrReference/Components/Drv/Rv3028Manager/CMakeLists.txt index b832e352..e1c0e6e6 100644 --- a/FprimeZephyrReference/Components/Drv/Rv3028Driver/CMakeLists.txt +++ b/FprimeZephyrReference/Components/Drv/Rv3028Manager/CMakeLists.txt @@ -16,9 +16,9 @@ register_fprime_library( AUTOCODER_INPUTS - "${CMAKE_CURRENT_LIST_DIR}/Rv3028Driver.fpp" + "${CMAKE_CURRENT_LIST_DIR}/Rv3028Manager.fpp" SOURCES - "${CMAKE_CURRENT_LIST_DIR}/Rv3028Driver.cpp" + "${CMAKE_CURRENT_LIST_DIR}/Rv3028Manager.cpp" # DEPENDS # MyPackage_MyOtherModule ) @@ -26,7 +26,7 @@ register_fprime_library( ### Unit Tests ### # register_fprime_ut( # AUTOCODER_INPUTS -# "${CMAKE_CURRENT_LIST_DIR}/Rv3028Driver.fpp" +# "${CMAKE_CURRENT_LIST_DIR}/Rv3028Manager.fpp" # SOURCES # "${CMAKE_CURRENT_LIST_DIR}/test/ut/Rv3028DriverTestMain.cpp" # "${CMAKE_CURRENT_LIST_DIR}/test/ut/Rv3028DriverTester.cpp" diff --git a/FprimeZephyrReference/Components/Drv/Rv3028Driver/Rv3028Driver.cpp b/FprimeZephyrReference/Components/Drv/Rv3028Manager/Rv3028Manager.cpp similarity index 96% rename from FprimeZephyrReference/Components/Drv/Rv3028Driver/Rv3028Driver.cpp rename to FprimeZephyrReference/Components/Drv/Rv3028Manager/Rv3028Manager.cpp index 622c9622..5f11612a 100644 --- a/FprimeZephyrReference/Components/Drv/Rv3028Driver/Rv3028Driver.cpp +++ b/FprimeZephyrReference/Components/Drv/Rv3028Manager/Rv3028Manager.cpp @@ -1,9 +1,9 @@ // ====================================================================== -// \title Rv3028Driver.cpp +// \title Rv3028Manager.cpp // \brief cpp file for Rv3028Driver component implementation class // ====================================================================== -#include "FprimeZephyrReference/Components/Drv/Rv3028Driver/Rv3028Driver.hpp" +#include "FprimeZephyrReference/Components/Drv/Rv3028Manager/Rv3028Manager.hpp" namespace Drv { diff --git a/FprimeZephyrReference/Components/Drv/Rv3028Driver/Rv3028Driver.fpp b/FprimeZephyrReference/Components/Drv/Rv3028Manager/Rv3028Manager.fpp similarity index 100% rename from FprimeZephyrReference/Components/Drv/Rv3028Driver/Rv3028Driver.fpp rename to FprimeZephyrReference/Components/Drv/Rv3028Manager/Rv3028Manager.fpp diff --git a/FprimeZephyrReference/Components/Drv/Rv3028Driver/Rv3028Driver.hpp b/FprimeZephyrReference/Components/Drv/Rv3028Manager/Rv3028Manager.hpp similarity index 91% rename from FprimeZephyrReference/Components/Drv/Rv3028Driver/Rv3028Driver.hpp rename to FprimeZephyrReference/Components/Drv/Rv3028Manager/Rv3028Manager.hpp index aa245450..1ea3a1cd 100644 --- a/FprimeZephyrReference/Components/Drv/Rv3028Driver/Rv3028Driver.hpp +++ b/FprimeZephyrReference/Components/Drv/Rv3028Manager/Rv3028Manager.hpp @@ -1,12 +1,12 @@ // ====================================================================== -// \title Rv3028Driver.hpp -// \brief hpp file for Rv3028Driver component implementation class +// \title Rv3028Manager.hpp +// \brief hpp file for Rv3028Manager component implementation class // ====================================================================== #ifndef Components_Rv3028Driver_HPP #define Components_Rv3028Driver_HPP -#include "FprimeZephyrReference/Components/Drv/Rv3028Driver/Rv3028DriverComponentAc.hpp" +#include "FprimeZephyrReference/Components/Drv/Rv3028Manager/Rv3028ManagerComponentAc.hpp" #include #include diff --git a/FprimeZephyrReference/Components/Drv/Rv3028Driver/docs/sdd.md b/FprimeZephyrReference/Components/Drv/Rv3028Manager/docs/sdd.md similarity index 98% rename from FprimeZephyrReference/Components/Drv/Rv3028Driver/docs/sdd.md rename to FprimeZephyrReference/Components/Drv/Rv3028Manager/docs/sdd.md index 9c9d84b6..421c780d 100644 --- a/FprimeZephyrReference/Components/Drv/Rv3028Driver/docs/sdd.md +++ b/FprimeZephyrReference/Components/Drv/Rv3028Manager/docs/sdd.md @@ -1,6 +1,6 @@ -# Components::Rv3028Driver +# Components::Rv3028Manager -The RV3028 Driver component interfaces with the RV3028 Real Time Clock (RTC) to provide time measurements. +The RV3028 Manager component interfaces with the RV3028 Real Time Clock (RTC) to provide time measurements. ### Typical Usage From 85cb11ae6d3eb21c8563477b0590aafdef3ff207 Mon Sep 17 00:00:00 2001 From: SamuelGomezG Date: Mon, 22 Sep 2025 18:27:56 -0500 Subject: [PATCH 22/40] Rename references from Rv3028Driver to Rv3028Manager Co-authored-by: Nate Gay --- .../Drv/Rv3028Manager/CMakeLists.txt | 4 +- .../Drv/Rv3028Manager/Rv3028Manager.cpp | 12 +-- .../Drv/Rv3028Manager/Rv3028Manager.fpp | 6 +- .../Drv/Rv3028Manager/Rv3028Manager.hpp | 18 ++-- .../Components/Drv/Rv3028Manager/docs/sdd.md | 94 +++++++++---------- .../Components/RtcManager/RtcManager.fpp | 6 +- .../Components/RtcManager/docs/sdd.md | 4 +- .../ReferenceDeployment/Top/instances.fpp | 2 +- .../ReferenceDeployment/Top/topology.fpp | 8 +- 9 files changed, 77 insertions(+), 77 deletions(-) diff --git a/FprimeZephyrReference/Components/Drv/Rv3028Manager/CMakeLists.txt b/FprimeZephyrReference/Components/Drv/Rv3028Manager/CMakeLists.txt index e1c0e6e6..a79a7bb5 100644 --- a/FprimeZephyrReference/Components/Drv/Rv3028Manager/CMakeLists.txt +++ b/FprimeZephyrReference/Components/Drv/Rv3028Manager/CMakeLists.txt @@ -28,8 +28,8 @@ register_fprime_library( # AUTOCODER_INPUTS # "${CMAKE_CURRENT_LIST_DIR}/Rv3028Manager.fpp" # SOURCES -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/Rv3028DriverTestMain.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/Rv3028DriverTester.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/Rv3028ManagerTestMain.cpp" +# "${CMAKE_CURRENT_LIST_DIR}/test/ut/Rv3028ManagerTester.cpp" # DEPENDS # STest # For rules-based testing # UT_AUTO_HELPERS diff --git a/FprimeZephyrReference/Components/Drv/Rv3028Manager/Rv3028Manager.cpp b/FprimeZephyrReference/Components/Drv/Rv3028Manager/Rv3028Manager.cpp index 5f11612a..f86c8524 100644 --- a/FprimeZephyrReference/Components/Drv/Rv3028Manager/Rv3028Manager.cpp +++ b/FprimeZephyrReference/Components/Drv/Rv3028Manager/Rv3028Manager.cpp @@ -1,6 +1,6 @@ // ====================================================================== // \title Rv3028Manager.cpp -// \brief cpp file for Rv3028Driver component implementation class +// \brief cpp file for Rv3028Manager component implementation class // ====================================================================== #include "FprimeZephyrReference/Components/Drv/Rv3028Manager/Rv3028Manager.hpp" @@ -11,19 +11,19 @@ namespace Drv { // Component construction and destruction // ---------------------------------------------------------------------- -Rv3028Driver ::Rv3028Driver(const char* const compName) : Rv3028DriverComponentBase(compName) { +Rv3028Manager ::Rv3028Manager(const char* const compName) : Rv3028ManagerComponentBase(compName) { // Initialize device this->rv3028 = device_get_binding("RV3028"); FW_ASSERT(device_is_ready(this->rv3028)); } -Rv3028Driver ::~Rv3028Driver() {} +Rv3028Manager ::~Rv3028Manager() {} // ---------------------------------------------------------------------- // Handler implementations for commands // ---------------------------------------------------------------------- -void Rv3028Driver ::timeGetPort_handler(FwIndexType portNum, Fw::Time& time) { +void Rv3028Manager ::timeGetPort_handler(FwIndexType portNum, Fw::Time& time) { // Check device readiness if (!device_is_ready(this->rv3028)) { this->log_WARNING_HI_DeviceNotReady(); @@ -42,7 +42,7 @@ void Rv3028Driver ::timeGetPort_handler(FwIndexType portNum, Fw::Time& time) { time.set(TimeBase::TB_WORKSTATION_TIME, 0, static_cast(time_posix), 0); } -U32 Rv3028Driver ::timeRead_handler(FwIndexType portNum) { +U32 Rv3028Manager ::timeRead_handler(FwIndexType portNum) { // Check device readiness if (!device_is_ready(this->rv3028)) { this->log_WARNING_HI_DeviceNotReady(); @@ -60,7 +60,7 @@ U32 Rv3028Driver ::timeRead_handler(FwIndexType portNum) { return time_posix; } -void Rv3028Driver ::timeSet_handler(FwIndexType portNum, const Drv::TimeData& t) { +void Rv3028Manager ::timeSet_handler(FwIndexType portNum, const Drv::TimeData& t) { // Check device readiness if (!device_is_ready(this->rv3028)) { this->log_WARNING_HI_DeviceNotReady(); diff --git a/FprimeZephyrReference/Components/Drv/Rv3028Manager/Rv3028Manager.fpp b/FprimeZephyrReference/Components/Drv/Rv3028Manager/Rv3028Manager.fpp index 89d85172..836e2af8 100644 --- a/FprimeZephyrReference/Components/Drv/Rv3028Manager/Rv3028Manager.fpp +++ b/FprimeZephyrReference/Components/Drv/Rv3028Manager/Rv3028Manager.fpp @@ -17,15 +17,15 @@ module Drv { module Drv { @ Manages the real time clock - passive component Rv3028Driver { + passive component Rv3028Manager { import Svc.Time @ timeSet port to set the time on the RTC - @ Requirement Rv3028Driver-001 + @ Requirement Rv3028Manager-001 sync input port timeSet: TimeSet @ timeRead port to get the time from the RTC - @ Requirement Rv3028Driver-002 + @ Requirement Rv3028Manager-002 sync input port timeRead: TimeRead ############################################################################## diff --git a/FprimeZephyrReference/Components/Drv/Rv3028Manager/Rv3028Manager.hpp b/FprimeZephyrReference/Components/Drv/Rv3028Manager/Rv3028Manager.hpp index 1ea3a1cd..f123c5c8 100644 --- a/FprimeZephyrReference/Components/Drv/Rv3028Manager/Rv3028Manager.hpp +++ b/FprimeZephyrReference/Components/Drv/Rv3028Manager/Rv3028Manager.hpp @@ -3,8 +3,8 @@ // \brief hpp file for Rv3028Manager component implementation class // ====================================================================== -#ifndef Components_Rv3028Driver_HPP -#define Components_Rv3028Driver_HPP +#ifndef Components_Rv3028Manager_HPP +#define Components_Rv3028Manager_HPP #include "FprimeZephyrReference/Components/Drv/Rv3028Manager/Rv3028ManagerComponentAc.hpp" @@ -16,18 +16,18 @@ namespace Drv { -class Rv3028Driver final : public Rv3028DriverComponentBase { +class Rv3028Manager final : public Rv3028ManagerComponentBase { public: // ---------------------------------------------------------------------- // Component construction and destruction // ---------------------------------------------------------------------- - //! Construct Rv3028Driver object - Rv3028Driver(const char* const compName //!< The component name + //! Construct Rv3028Manager object + Rv3028Manager(const char* const compName //!< The component name ); - //! Destroy Rv3028Driver object - ~Rv3028Driver(); + //! Destroy Rv3028Manager object + ~Rv3028Manager(); private: // ---------------------------------------------------------------------- @@ -44,14 +44,14 @@ class Rv3028Driver final : public Rv3028DriverComponentBase { //! Handler implementation for timeRead //! //! timeRead port to get the time from the RTC - //! Requirement Rv3028Driver-002 + //! Requirement Rv3028Manager-002 U32 timeRead_handler(FwIndexType portNum //!< The port number ) override; //! Handler implementation for timeSet //! //! timeSet port to set the time on the RTC - //! Requirement Rv3028Driver-001 + //! Requirement Rv3028Manager-001 void timeSet_handler(FwIndexType portNum, //!< The port number const Drv::TimeData& time) override; diff --git a/FprimeZephyrReference/Components/Drv/Rv3028Manager/docs/sdd.md b/FprimeZephyrReference/Components/Drv/Rv3028Manager/docs/sdd.md index 421c780d..c6fbc366 100644 --- a/FprimeZephyrReference/Components/Drv/Rv3028Manager/docs/sdd.md +++ b/FprimeZephyrReference/Components/Drv/Rv3028Manager/docs/sdd.md @@ -27,11 +27,11 @@ The RV3028 Manager component interfaces with the RV3028 Real Time Clock (RTC) to ## Requirements | Name | Description | Validation | |---|---|---| -| Rv3028Driver-001 | Time can be set on the RV3028 through a port | Manual | -| Rv3028Driver-002 | Time can be read from the RV3028 through a port | Manual | -| Rv3028Driver-003 | A device not ready event is emitted if the RV3028 is not ready | Manual | -| Rv3028Driver-004 | A time set event is emitted if the time is set successfully | Manual | -| Rv3028Driver-005 | A time not set event is emitted if the time is not set successfully | Manual | +| Rv3028Manager-001 | Time can be set on the RV3028 through a port | Manual | +| Rv3028Manager-002 | Time can be read from the RV3028 through a port | Manual | +| Rv3028Manager-003 | A device not ready event is emitted if the RV3028 is not ready | Manual | +| Rv3028Manager-004 | A time set event is emitted if the time is set successfully | Manual | +| Rv3028Manager-005 | A time not set event is emitted if the time is not set successfully | Manual | ## Port Descriptions | Name | Description | @@ -51,19 +51,19 @@ The RV3028 Manager component interfaces with the RV3028 Real Time Clock (RTC) to ```mermaid classDiagram namespace Drv { - class Rv3028DriverComponentBase { + class Rv3028ManagerComponentBase { <> } - class Rv3028Driver { + class Rv3028Manager { - rv3028: device* - + Rv3028Driver(char* compName) - + ~Rv3028Driver() + + Rv3028Manager(char* compName) + + ~Rv3028Manager() - void timeGetPort_handler(FwIndexType portNum, Fw::Time& time) - U32 timeRead_handler(FwIndexType portNum) - void timeSet_handler(FwIndexType portNum, const Drv::TimeData& time) } } - Rv3028DriverComponentBase <|-- Rv3028Driver : inherits + Rv3028ManagerComponentBase <|-- Rv3028Manager : inherits ``` ## Sequence Diagrams @@ -76,15 +76,15 @@ The `timeGetPort` port is called from a `time connection` in a deployment topolo ```mermaid sequenceDiagram participant Deployment Time Connection - participant RV3028 Driver + participant RV3028 Manager participant Zephyr Time API participant RV3028 RTC - Deployment Time Connection-->>RV3028 Driver: Call timeGetPort time port - RV3028 Driver->>Zephyr Time API: Read time + Deployment Time Connection-->>RV3028 Manager: Call timeGetPort time port + RV3028 Manager->>Zephyr Time API: Read time Zephyr Time API->>RV3028 RTC: Read time RV3028 RTC->>Zephyr Time API: Return time - Zephyr Time API->>RV3028 Driver: Return time - RV3028 Driver-->>Deployment Time Connection: Return time + Zephyr Time API->>RV3028 Manager: Return time + RV3028 Manager-->>Deployment Time Connection: Return time ``` #### Device Not Ready @@ -92,16 +92,16 @@ sequenceDiagram sequenceDiagram participant Event Log participant Deployment Time Connection - participant RV3028 Driver + participant RV3028 Manager participant Zephyr Time API participant RV3028 RTC - Deployment Time Connection->>RV3028 Driver: Call timeGetPort time port - RV3028 Driver->>Zephyr Time API: Read time + Deployment Time Connection->>RV3028 Manager: Call timeGetPort time port + RV3028 Manager->>Zephyr Time API: Read time Zephyr Time API->>RV3028 RTC: Read time RV3028 RTC->>Zephyr Time API: Return device not ready - Zephyr Time API->>RV3028 Driver: Return device not ready - RV3028 Driver->>Event Log: Emit DeviceNotReady event - RV3028 Driver->>Deployment Time Connection: Return 0 time + Zephyr Time API->>RV3028 Manager: Return device not ready + RV3028 Manager->>Event Log: Emit DeviceNotReady event + RV3028 Manager->>Deployment Time Connection: Return 0 time ``` ### `timeRead` port @@ -113,15 +113,15 @@ The `timeRead` port is called from a manager component to get the current time f sequenceDiagram participant Event Log participant Manager - participant RV3028 Driver + participant RV3028 Manager participant Zephyr Time API participant RV3028 RTC - Manager-->>RV3028 Driver: Call timeRead synchronous input port - RV3028 Driver->>Zephyr Time API: Read time + Manager-->>RV3028 Manager: Call timeRead synchronous input port + RV3028 Manager->>Zephyr Time API: Read time Zephyr Time API->>RV3028 RTC: Read time RV3028 RTC->>Zephyr Time API: Return time - Zephyr Time API->>RV3028 Driver: Return time - RV3028 Driver->>Event Log: Emit event GetTime + Zephyr Time API->>RV3028 Manager: Return time + RV3028 Manager->>Event Log: Emit event GetTime ``` #### Device Not Ready @@ -129,15 +129,15 @@ sequenceDiagram sequenceDiagram participant Event Log participant Manager - participant RV3028 Driver + participant RV3028 Manager participant Zephyr Time API participant RV3028 RTC - Manager-->>RV3028 Driver: Call timeRead synchronous input port - RV3028 Driver->>Zephyr Time API: Read time + Manager-->>RV3028 Manager: Call timeRead synchronous input port + RV3028 Manager->>Zephyr Time API: Read time Zephyr Time API->>RV3028 RTC: Read time RV3028 RTC->>Zephyr Time API: Return device not ready - Zephyr Time API->>RV3028 Driver: Return device not ready - RV3028 Driver->>Event Log: Emit event DeviceNotReady + Zephyr Time API->>RV3028 Manager: Return device not ready + RV3028 Manager->>Event Log: Emit event DeviceNotReady ``` ### `timeSet` port @@ -150,16 +150,16 @@ sequenceDiagram participant Ground Station participant Event Log participant Manager - participant RV3028 Driver + participant RV3028 Manager participant Zephyr Time API participant RV3028 RTC Ground Station-->>Manager: Command to set time with Drv::TimeData struct - Manager->>RV3028 Driver: Call the timeSet synchronous input port with Drv::TimeData struct - RV3028 Driver->>Zephyr Time API: Set time + Manager->>RV3028 Manager: Call the timeSet synchronous input port with Drv::TimeData struct + RV3028 Manager->>Zephyr Time API: Set time Zephyr Time API->>RV3028 RTC: Set time RV3028 RTC->>Zephyr Time API: Return set success - Zephyr Time API->>RV3028 Driver: Return set success - RV3028 Driver->>Event Log: Emit event TimeSet + Zephyr Time API->>RV3028 Manager: Return set success + RV3028 Manager->>Event Log: Emit event TimeSet ``` #### Device Not Ready @@ -168,16 +168,16 @@ sequenceDiagram participant Ground Station participant Event Log participant Manager - participant RV3028 Driver + participant RV3028 Manager participant Zephyr Time API participant RV3028 RTC Ground Station-->>Manager: Command to set time with Drv::TimeData struct - Manager->>RV3028 Driver: Call the timeSet synchronous input port with Drv::TimeData struct - RV3028 Driver->>Zephyr Time API: Set time + Manager->>RV3028 Manager: Call the timeSet synchronous input port with Drv::TimeData struct + RV3028 Manager->>Zephyr Time API: Set time Zephyr Time API->>RV3028 RTC: Set time RV3028 RTC->>Zephyr Time API: Return device not ready - Zephyr Time API->>RV3028 Driver: Return device not ready - RV3028 Driver->>Event Log: Emit event DeviceNotReady + Zephyr Time API->>RV3028 Manager: Return device not ready + RV3028 Manager->>Event Log: Emit event DeviceNotReady ``` #### Time Not Set @@ -186,19 +186,19 @@ sequenceDiagram participant Ground Station participant Event Log participant Manager - participant RV3028 Driver + participant RV3028 Manager participant Zephyr Time API participant RV3028 RTC Ground Station-->>Manager: Command to set time with Drv::TimeData struct - Manager->>RV3028 Driver: Call the timeSet synchronous input port with Drv::TimeData struct - RV3028 Driver->>Zephyr Time API: Set time + Manager->>RV3028 Manager: Call the timeSet synchronous input port with Drv::TimeData struct + RV3028 Manager->>Zephyr Time API: Set time Zephyr Time API->>RV3028 RTC: Set time RV3028 RTC->>Zephyr Time API: Return set failure - Zephyr Time API->>RV3028 Driver: Return set failure - RV3028 Driver->>Event Log: Emit event TimeNotSet + Zephyr Time API->>RV3028 Manager: Return set failure + RV3028 Manager->>Event Log: Emit event TimeNotSet ``` ## Change Log | Date | Description | |---|---| -| 2025-9-18 | Initial RV3028 Driver component | +| 2025-9-18 | Initial RV3028 Manager component | diff --git a/FprimeZephyrReference/Components/RtcManager/RtcManager.fpp b/FprimeZephyrReference/Components/RtcManager/RtcManager.fpp index 2aa57452..0dcdcd30 100644 --- a/FprimeZephyrReference/Components/RtcManager/RtcManager.fpp +++ b/FprimeZephyrReference/Components/RtcManager/RtcManager.fpp @@ -13,13 +13,13 @@ module Components { #### Uncomment the following examples to start customizing your component #### ############################################################################## - @ Event to log the time retrieved from the Rv3028Driver + @ Event to log the time retrieved from the Rv3028Manager event GetTime(year: U32, month: U32, day: U32, hour:U32, minute:U32, second:U32) severity activity high id 1 format "Time: {}/{}/{} at {}:{}:{}" - @ Output port to set the time on the Rv3028Driver + @ Output port to set the time on the Rv3028Manager output port timeSet: Drv.TimeSet - @ Output port to get the time from the Rv3028Driver + @ Output port to get the time from the Rv3028Manager output port timeRead: Drv.TimeRead ############################################################################### diff --git a/FprimeZephyrReference/Components/RtcManager/docs/sdd.md b/FprimeZephyrReference/Components/RtcManager/docs/sdd.md index 52561b2b..32d67da2 100644 --- a/FprimeZephyrReference/Components/RtcManager/docs/sdd.md +++ b/FprimeZephyrReference/Components/RtcManager/docs/sdd.md @@ -1,6 +1,6 @@ # Components::RtcManager -The RtcManager component manages interactions with a Real Time Clock (RTC) device. It interfaces with the Rv3028Driver component to set and get the current time. +The RtcManager component manages interactions with a Real Time Clock (RTC) device. It interfaces with the Rv3028Manager component to set and get the current time. ### Typical Usage @@ -39,7 +39,7 @@ The RtcManager component manages interactions with a Real Time Clock (RTC) devic ## Events | Name | Description | |---|---| -| GetTime | Event to log the time retrieved from the Rv3028Driver | +| GetTime | Event to log the time retrieved from the Rv3028Manager | ## Class Diagram ```mermaid diff --git a/FprimeZephyrReference/ReferenceDeployment/Top/instances.fpp b/FprimeZephyrReference/ReferenceDeployment/Top/instances.fpp index 7a980a31..29f74c02 100644 --- a/FprimeZephyrReference/ReferenceDeployment/Top/instances.fpp +++ b/FprimeZephyrReference/ReferenceDeployment/Top/instances.fpp @@ -63,7 +63,7 @@ module ReferenceDeployment { instance rtcManager: Components.RtcManager base id 0x10016000 - instance rv3028Driver: Drv.Rv3028Driver base id 0x10017000 + instance rv3028Manager: Drv.Rv3028Manager base id 0x10017000 } diff --git a/FprimeZephyrReference/ReferenceDeployment/Top/topology.fpp b/FprimeZephyrReference/ReferenceDeployment/Top/topology.fpp index a2bfed56..4eacac19 100644 --- a/FprimeZephyrReference/ReferenceDeployment/Top/topology.fpp +++ b/FprimeZephyrReference/ReferenceDeployment/Top/topology.fpp @@ -28,7 +28,7 @@ module ReferenceDeployment { instance gpioDriver instance watchdog instance prmDb - instance rv3028Driver + instance rv3028Manager instance rtcManager # ---------------------------------------------------------------------- @@ -39,7 +39,7 @@ module ReferenceDeployment { event connections instance CdhCore.events text event connections instance CdhCore.textLogger health connections instance CdhCore.$health - time connections instance rv3028Driver + time connections instance rv3028Manager telemetry connections instance CdhCore.tlmSend param connections instance prmDb @@ -100,8 +100,8 @@ module ReferenceDeployment { } connections RtcManager { - rtcManager.timeSet -> rv3028Driver.timeSet - rtcManager.timeRead -> rv3028Driver.timeRead + rtcManager.timeSet -> rv3028Manager.timeSet + rtcManager.timeRead -> rv3028Manager.timeRead } connections ReferenceDeployment { From f2c18bde98d6bc72d2acf434c1a098ab4510e011 Mon Sep 17 00:00:00 2001 From: SamuelGomezG Date: Mon, 22 Sep 2025 18:33:04 -0500 Subject: [PATCH 23/40] Remove assertion in constructor Co-authored-by: Nate Gay --- .../Components/Drv/Rv3028Manager/Rv3028Manager.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/FprimeZephyrReference/Components/Drv/Rv3028Manager/Rv3028Manager.cpp b/FprimeZephyrReference/Components/Drv/Rv3028Manager/Rv3028Manager.cpp index f86c8524..ae9bc52c 100644 --- a/FprimeZephyrReference/Components/Drv/Rv3028Manager/Rv3028Manager.cpp +++ b/FprimeZephyrReference/Components/Drv/Rv3028Manager/Rv3028Manager.cpp @@ -14,7 +14,6 @@ namespace Drv { Rv3028Manager ::Rv3028Manager(const char* const compName) : Rv3028ManagerComponentBase(compName) { // Initialize device this->rv3028 = device_get_binding("RV3028"); - FW_ASSERT(device_is_ready(this->rv3028)); } Rv3028Manager ::~Rv3028Manager() {} From 7c40dd5d2b83a0accf526dfe227801e70f66f72b Mon Sep 17 00:00:00 2001 From: SamuelGomezG Date: Mon, 22 Sep 2025 18:45:33 -0500 Subject: [PATCH 24/40] Change logging to use `Fw::Logger` --- .../Components/Drv/Rv3028Manager/Rv3028Manager.cpp | 2 +- .../Components/Drv/Rv3028Manager/Rv3028Manager.hpp | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/FprimeZephyrReference/Components/Drv/Rv3028Manager/Rv3028Manager.cpp b/FprimeZephyrReference/Components/Drv/Rv3028Manager/Rv3028Manager.cpp index ae9bc52c..9854f592 100644 --- a/FprimeZephyrReference/Components/Drv/Rv3028Manager/Rv3028Manager.cpp +++ b/FprimeZephyrReference/Components/Drv/Rv3028Manager/Rv3028Manager.cpp @@ -25,7 +25,7 @@ Rv3028Manager ::~Rv3028Manager() {} void Rv3028Manager ::timeGetPort_handler(FwIndexType portNum, Fw::Time& time) { // Check device readiness if (!device_is_ready(this->rv3028)) { - this->log_WARNING_HI_DeviceNotReady(); + Fw::Logger::log("Rv2038 not ready"); return; } diff --git a/FprimeZephyrReference/Components/Drv/Rv3028Manager/Rv3028Manager.hpp b/FprimeZephyrReference/Components/Drv/Rv3028Manager/Rv3028Manager.hpp index f123c5c8..7a207eda 100644 --- a/FprimeZephyrReference/Components/Drv/Rv3028Manager/Rv3028Manager.hpp +++ b/FprimeZephyrReference/Components/Drv/Rv3028Manager/Rv3028Manager.hpp @@ -7,6 +7,7 @@ #define Components_Rv3028Manager_HPP #include "FprimeZephyrReference/Components/Drv/Rv3028Manager/Rv3028ManagerComponentAc.hpp" +#include #include #include From fab0b47f69f836b7e8ce7da80d6409d93360f75b Mon Sep 17 00:00:00 2001 From: Nate Gay Date: Mon, 22 Sep 2025 23:00:46 -0500 Subject: [PATCH 25/40] Most feedback covered --- .../Drv/Rv3028Manager/Rv3028Manager.cpp | 68 +++++++++++++------ .../Drv/Rv3028Manager/Rv3028Manager.fpp | 14 +++- .../Drv/Rv3028Manager/Rv3028Manager.hpp | 10 +++ .../Components/RtcManager/docs/sdd.md | 10 +-- 4 files changed, 72 insertions(+), 30 deletions(-) diff --git a/FprimeZephyrReference/Components/Drv/Rv3028Manager/Rv3028Manager.cpp b/FprimeZephyrReference/Components/Drv/Rv3028Manager/Rv3028Manager.cpp index 9854f592..139d11cd 100644 --- a/FprimeZephyrReference/Components/Drv/Rv3028Manager/Rv3028Manager.cpp +++ b/FprimeZephyrReference/Components/Drv/Rv3028Manager/Rv3028Manager.cpp @@ -25,20 +25,20 @@ Rv3028Manager ::~Rv3028Manager() {} void Rv3028Manager ::timeGetPort_handler(FwIndexType portNum, Fw::Time& time) { // Check device readiness if (!device_is_ready(this->rv3028)) { - Fw::Logger::log("Rv2038 not ready"); + // Use logger instead of events since this fn is in a critical path for FPrime + // to get time. Events require time, if this method fails an event will fail. + Fw::Logger::log("RV2038 not ready"); return; } - // Fetch time from RTC - struct rtc_time time_rtc = {}; - rtc_get_time(this->rv3028, &time_rtc); - - // Convert time to POSIX time_t format - struct tm* time_tm = rtc_time_to_tm(&time_rtc); - time_t time_posix = timeutil_timegm(time_tm); + I32 posix_time = this->getPosixTime(); + if (posix_time < 0) { + Fw::Logger::log("getPosixTime returned invalid time"); + return; + } // Set FPrime time object - time.set(TimeBase::TB_WORKSTATION_TIME, 0, static_cast(time_posix), 0); + time.set(TimeBase::TB_WORKSTATION_TIME, 0, static_cast(posix_time), 0); } U32 Rv3028Manager ::timeRead_handler(FwIndexType portNum) { @@ -47,16 +47,16 @@ U32 Rv3028Manager ::timeRead_handler(FwIndexType portNum) { this->log_WARNING_HI_DeviceNotReady(); return 0; } + this->log_WARNING_HI_DeviceNotReady_ThrottleClear(); - // Fetch time from RTC - struct rtc_time time_rtc = {}; - rtc_get_time(this->rv3028, &time_rtc); - - // Convert time to POSIX time_t format - struct tm* time_tm = rtc_time_to_tm(&time_rtc); - time_t time_posix = timeutil_timegm(time_tm); + I32 posix_time = this->getPosixTime(); + if (posix_time < 0) { + this->log_WARNING_HI_InvalidTime(); + return 0; + } + this->log_WARNING_HI_InvalidTime_ThrottleClear(); - return time_posix; + return static_cast(posix_time); } void Rv3028Manager ::timeSet_handler(FwIndexType portNum, const Drv::TimeData& t) { @@ -65,20 +65,24 @@ void Rv3028Manager ::timeSet_handler(FwIndexType portNum, const Drv::TimeData& t this->log_WARNING_HI_DeviceNotReady(); return; } + this->log_WARNING_HI_DeviceNotReady_ThrottleClear(); // Populate rtc_time structure from TimeData const struct rtc_time time_rtc = { .tm_sec = 0, - .tm_min = t.get_Minute(), - .tm_hour = t.get_Hour(), - .tm_mday = t.get_Day(), - .tm_mon = t.get_Month() - 1, // month [0-11] - .tm_year = t.get_Year() - 1900, // year since 1900 + .tm_min = static_cast(t.get_Minute()), + .tm_hour = static_cast(t.get_Hour()), + .tm_mday = static_cast(t.get_Day()), + .tm_mon = static_cast(t.get_Month() - 1), // month [0-11] + .tm_year = static_cast(t.get_Year() - 1900), // year since 1900 .tm_wday = 0, .tm_yday = 0, .tm_isdst = 0, }; + // Event current time to correlate prior events when new time is set + this->log_ACTIVITY_HI_TimeGet(this->getPosixTime()); + // Set time on RTC const int status = rtc_set_time(this->rv3028, &time_rtc); @@ -90,4 +94,24 @@ void Rv3028Manager ::timeSet_handler(FwIndexType portNum, const Drv::TimeData& t } } +// ---------------------------------------------------------------------- +// Private helper methods +// ---------------------------------------------------------------------- +I32 Rv3028Manager ::getPosixTime() { + struct rtc_time time_rtc = {}; + rtc_get_time(this->rv3028, &time_rtc); + + // Convert time to POSIX time_t format + struct tm* time_tm = rtc_time_to_tm(&time_rtc); + + errno = 0; + time_t posix_time = timeutil_timegm(time_tm); + if (errno == ERANGE) { + Fw::Logger::log("RV2038 returned invalid time"); + return -1; + } + + return posix_time; +} + } // namespace Drv diff --git a/FprimeZephyrReference/Components/Drv/Rv3028Manager/Rv3028Manager.fpp b/FprimeZephyrReference/Components/Drv/Rv3028Manager/Rv3028Manager.fpp index 836e2af8..22235bc4 100644 --- a/FprimeZephyrReference/Components/Drv/Rv3028Manager/Rv3028Manager.fpp +++ b/FprimeZephyrReference/Components/Drv/Rv3028Manager/Rv3028Manager.fpp @@ -33,13 +33,21 @@ module Drv { ############################################################################## @ DeviceNotReady event indicates that the RV3028 is not ready - event DeviceNotReady() severity warning high id 0 format "RV3028 not ready" + event DeviceNotReady() severity warning high id 0 format "RV3028 not ready" throttle 5 + + @ InvalidTime event indicates that the RV3028 returned an invalid time + event InvalidTime() severity warning high id 1 format "RV3028 returned invalid time" throttle 5 + + @ TimeGet event indicates that the time was read successfully + event TimeGet( + t: U32 @< POSIX time read from RTC + ) severity activity high id 2 format "RV3028 Time: {}" @ TimeSet event indicates that the time was set successfully - event TimeSet() severity activity high id 1 format "Time set on RV3028" + event TimeSet() severity activity high id 3 format "Time set on RV3028" @ TimeNotSet event indicates that the time was not set successfully - event TimeNotSet() severity warning high id 2 format "Time not set on RV3028" + event TimeNotSet() severity warning high id 4 format "Time not set on RV3028" ############################################################################### # Standard AC Ports: Required for Channels, Events, Commands, and Parameters # diff --git a/FprimeZephyrReference/Components/Drv/Rv3028Manager/Rv3028Manager.hpp b/FprimeZephyrReference/Components/Drv/Rv3028Manager/Rv3028Manager.hpp index 7a207eda..7dba381c 100644 --- a/FprimeZephyrReference/Components/Drv/Rv3028Manager/Rv3028Manager.hpp +++ b/FprimeZephyrReference/Components/Drv/Rv3028Manager/Rv3028Manager.hpp @@ -7,6 +7,9 @@ #define Components_Rv3028Manager_HPP #include "FprimeZephyrReference/Components/Drv/Rv3028Manager/Rv3028ManagerComponentAc.hpp" + +#include + #include #include @@ -56,6 +59,13 @@ class Rv3028Manager final : public Rv3028ManagerComponentBase { void timeSet_handler(FwIndexType portNum, //!< The port number const Drv::TimeData& time) override; + // ---------------------------------------------------------------------- + // Private helper methods + // ---------------------------------------------------------------------- + + //! Helper method to get POSIX time from RTC + I32 getPosixTime(); + //! Zephyr device stores the initialized RV2038 sensor const struct device* rv3028; }; diff --git a/FprimeZephyrReference/Components/RtcManager/docs/sdd.md b/FprimeZephyrReference/Components/RtcManager/docs/sdd.md index 32d67da2..59767d0f 100644 --- a/FprimeZephyrReference/Components/RtcManager/docs/sdd.md +++ b/FprimeZephyrReference/Components/RtcManager/docs/sdd.md @@ -66,9 +66,9 @@ classDiagram sequenceDiagram participant Ground Station participant RtcManager - participant RV3028 Driver + participant RV3028 Manager Ground Station-->>RtcManager: Send SET_TIME command with time data - RtcManager->>RV3028 Driver: Call timeSet port with time data + RtcManager->>RV3028 Manager: Call timeSet port with time data ``` ### `GET_TIME` Command @@ -78,10 +78,10 @@ sequenceDiagram participant Ground Station participant Event Log participant RtcManager - participant RV3028 Driver + participant RV3028 Manager Ground Station-->>RtcManager: Send GET_TIME command - RtcManager->>RV3028 Driver: Call timeRead port - RV3028 Driver->>RtcManager: Return time data + RtcManager->>RV3028 Manager: Call timeRead port + RV3028 Manager->>RtcManager: Return time data RtcManager->>Event Log: Emit GetTime event with retrieved time ``` From 2f447e8a4b8e60f79c2fd6074b50725a8a8efab1 Mon Sep 17 00:00:00 2001 From: ineskhou Date: Fri, 26 Sep 2025 10:48:44 -0700 Subject: [PATCH 26/40] appease linter --- .../Components/Drv/Rv3028Manager/Rv3028Manager.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/FprimeZephyrReference/Components/Drv/Rv3028Manager/Rv3028Manager.hpp b/FprimeZephyrReference/Components/Drv/Rv3028Manager/Rv3028Manager.hpp index 7a207eda..bd68a9ca 100644 --- a/FprimeZephyrReference/Components/Drv/Rv3028Manager/Rv3028Manager.hpp +++ b/FprimeZephyrReference/Components/Drv/Rv3028Manager/Rv3028Manager.hpp @@ -6,8 +6,8 @@ #ifndef Components_Rv3028Manager_HPP #define Components_Rv3028Manager_HPP -#include "FprimeZephyrReference/Components/Drv/Rv3028Manager/Rv3028ManagerComponentAc.hpp" #include +#include "FprimeZephyrReference/Components/Drv/Rv3028Manager/Rv3028ManagerComponentAc.hpp" #include #include From f659d5b2b1ddc4b200f399594f36946a1b48e186 Mon Sep 17 00:00:00 2001 From: Nate Gay Date: Sat, 27 Sep 2025 23:25:17 -0500 Subject: [PATCH 27/40] Add integration tests --- .../Drv/Rv3028Manager/Rv3028Manager.cpp | 4 +- .../Drv/Rv3028Manager/Rv3028Manager.fpp | 9 +- .../Drv/Rv3028Manager/Rv3028Manager.hpp | 8 +- .../Components/Drv/Rv3028Manager/docs/sdd.md | 16 +-- .../Components/RtcManager/RtcManager.cpp | 18 ++- .../Components/RtcManager/RtcManager.fpp | 6 +- .../Components/RtcManager/docs/sdd.md | 6 +- .../ReferenceDeployment/Top/topology.fpp | 2 +- FprimeZephyrReference/test/int/rtc_test.py | 106 ++++++++++++++++++ 9 files changed, 146 insertions(+), 29 deletions(-) create mode 100644 FprimeZephyrReference/test/int/rtc_test.py diff --git a/FprimeZephyrReference/Components/Drv/Rv3028Manager/Rv3028Manager.cpp b/FprimeZephyrReference/Components/Drv/Rv3028Manager/Rv3028Manager.cpp index 139d11cd..b5e54f9a 100644 --- a/FprimeZephyrReference/Components/Drv/Rv3028Manager/Rv3028Manager.cpp +++ b/FprimeZephyrReference/Components/Drv/Rv3028Manager/Rv3028Manager.cpp @@ -41,7 +41,7 @@ void Rv3028Manager ::timeGetPort_handler(FwIndexType portNum, Fw::Time& time) { time.set(TimeBase::TB_WORKSTATION_TIME, 0, static_cast(posix_time), 0); } -U32 Rv3028Manager ::timeRead_handler(FwIndexType portNum) { +U32 Rv3028Manager ::timeGet_handler(FwIndexType portNum) { // Check device readiness if (!device_is_ready(this->rv3028)) { this->log_WARNING_HI_DeviceNotReady(); @@ -69,7 +69,7 @@ void Rv3028Manager ::timeSet_handler(FwIndexType portNum, const Drv::TimeData& t // Populate rtc_time structure from TimeData const struct rtc_time time_rtc = { - .tm_sec = 0, + .tm_sec = static_cast(t.get_Second()), .tm_min = static_cast(t.get_Minute()), .tm_hour = static_cast(t.get_Hour()), .tm_mday = static_cast(t.get_Day()), diff --git a/FprimeZephyrReference/Components/Drv/Rv3028Manager/Rv3028Manager.fpp b/FprimeZephyrReference/Components/Drv/Rv3028Manager/Rv3028Manager.fpp index 22235bc4..3f78ea2a 100644 --- a/FprimeZephyrReference/Components/Drv/Rv3028Manager/Rv3028Manager.fpp +++ b/FprimeZephyrReference/Components/Drv/Rv3028Manager/Rv3028Manager.fpp @@ -6,13 +6,14 @@ module Drv { Day: U32 @< Day value. Hour: U32 @< Hour value. Minute: U32 @< Minute value. + Second: U32 @< Second value. } } # Port definition module Drv { port TimeSet(t: TimeData) - port TimeRead -> U32 + port TimeGet -> U32 } module Drv { @@ -24,9 +25,9 @@ module Drv { @ Requirement Rv3028Manager-001 sync input port timeSet: TimeSet - @ timeRead port to get the time from the RTC + @ timeGet port to get the time from the RTC @ Requirement Rv3028Manager-002 - sync input port timeRead: TimeRead + sync input port timeGet: TimeGet ############################################################################## #### Uncomment the following examples to start customizing your component #### @@ -41,7 +42,7 @@ module Drv { @ TimeGet event indicates that the time was read successfully event TimeGet( t: U32 @< POSIX time read from RTC - ) severity activity high id 2 format "RV3028 Time: {}" + ) severity activity high id 2 format "{}" @ TimeSet event indicates that the time was set successfully event TimeSet() severity activity high id 3 format "Time set on RV3028" diff --git a/FprimeZephyrReference/Components/Drv/Rv3028Manager/Rv3028Manager.hpp b/FprimeZephyrReference/Components/Drv/Rv3028Manager/Rv3028Manager.hpp index 7dba381c..26971f8e 100644 --- a/FprimeZephyrReference/Components/Drv/Rv3028Manager/Rv3028Manager.hpp +++ b/FprimeZephyrReference/Components/Drv/Rv3028Manager/Rv3028Manager.hpp @@ -45,12 +45,12 @@ class Rv3028Manager final : public Rv3028ManagerComponentBase { Fw::Time& time //!< Reference to Time object ) override; - //! Handler implementation for timeRead + //! Handler implementation for timeGet //! - //! timeRead port to get the time from the RTC + //! timeGet port to get the time from the RTC //! Requirement Rv3028Manager-002 - U32 timeRead_handler(FwIndexType portNum //!< The port number - ) override; + U32 timeGet_handler(FwIndexType portNum //!< The port number + ) override; //! Handler implementation for timeSet //! diff --git a/FprimeZephyrReference/Components/Drv/Rv3028Manager/docs/sdd.md b/FprimeZephyrReference/Components/Drv/Rv3028Manager/docs/sdd.md index c6fbc366..c42823b0 100644 --- a/FprimeZephyrReference/Components/Drv/Rv3028Manager/docs/sdd.md +++ b/FprimeZephyrReference/Components/Drv/Rv3028Manager/docs/sdd.md @@ -8,9 +8,9 @@ The RV3028 Manager component interfaces with the RV3028 Real Time Clock (RTC) to 1. The component is instantiated and initialized during system startup 2. In a deployment topology, a `time connection` is made to the component's `timeGetPort` port -#### `timeRead` Port Usage +#### `timeGet` Port Usage 1. The component is instantiated and initialized during system startup -2. A manager calls the `timeRead` ports +2. A manager calls the `timeGet` ports 3. On each call, the component: - Fetches and returns the time from the RV3028 RTC - Emits a `DeviceNotReady` event if the device is not ready @@ -38,7 +38,7 @@ The RV3028 Manager component interfaces with the RV3028 Real Time Clock (RTC) to |---|---| | timeGetPort | Time port for FPrime topology connection to get the time from the RV3028 | | timeSet | Input port sets the time on the RV3028 | -| timeRead | Input port reads the time from the RV3028 | +| timeGet | Input port reads the time from the RV3028 | ## Events | Name | Description | @@ -59,7 +59,7 @@ classDiagram + Rv3028Manager(char* compName) + ~Rv3028Manager() - void timeGetPort_handler(FwIndexType portNum, Fw::Time& time) - - U32 timeRead_handler(FwIndexType portNum) + - U32 timeGet_handler(FwIndexType portNum) - void timeSet_handler(FwIndexType portNum, const Drv::TimeData& time) } } @@ -104,9 +104,9 @@ sequenceDiagram RV3028 Manager->>Deployment Time Connection: Return 0 time ``` -### `timeRead` port +### `timeGet` port -The `timeRead` port is called from a manager component to get the current time from the RTC. +The `timeGet` port is called from a manager component to get the current time from the RTC. #### Success ```mermaid @@ -116,7 +116,7 @@ sequenceDiagram participant RV3028 Manager participant Zephyr Time API participant RV3028 RTC - Manager-->>RV3028 Manager: Call timeRead synchronous input port + Manager-->>RV3028 Manager: Call timeGet synchronous input port RV3028 Manager->>Zephyr Time API: Read time Zephyr Time API->>RV3028 RTC: Read time RV3028 RTC->>Zephyr Time API: Return time @@ -132,7 +132,7 @@ sequenceDiagram participant RV3028 Manager participant Zephyr Time API participant RV3028 RTC - Manager-->>RV3028 Manager: Call timeRead synchronous input port + Manager-->>RV3028 Manager: Call timeGet synchronous input port RV3028 Manager->>Zephyr Time API: Read time Zephyr Time API->>RV3028 RTC: Read time RV3028 RTC->>Zephyr Time API: Return device not ready diff --git a/FprimeZephyrReference/Components/RtcManager/RtcManager.cpp b/FprimeZephyrReference/Components/RtcManager/RtcManager.cpp index cafb7a17..2fe41ec9 100644 --- a/FprimeZephyrReference/Components/RtcManager/RtcManager.cpp +++ b/FprimeZephyrReference/Components/RtcManager/RtcManager.cpp @@ -4,6 +4,7 @@ // ====================================================================== #include "FprimeZephyrReference/Components/RtcManager/RtcManager.hpp" +#include namespace Components { @@ -25,16 +26,25 @@ void RtcManager ::SET_TIME_cmdHandler(FwOpcodeType opCode, U32 cmdSeq, Drv::Time } void RtcManager ::GET_TIME_cmdHandler(FwOpcodeType opCode, U32 cmdSeq) { - U32 t = this->timeRead_out(0); + U32 t = this->timeGet_out(0); // Convert POSIX time to tm struct for human readable logging time_t time_posix = static_cast(t); struct tm time_tm_buf; struct tm* time_tm = gmtime_r(&time_posix, &time_tm_buf); - // Report time retrieved - this->log_ACTIVITY_HI_GetTime(time_tm->tm_year + 1900, time_tm->tm_mon + 1, time_tm->tm_mday + 1, time_tm->tm_hour, - time_tm->tm_min, time_tm->tm_sec); + // Convert to ISO format + char iso_time[32]; + int result = snprintf(iso_time, sizeof(iso_time), "%04d-%02d-%02dT%02d:%02d:%02d", time_tm->tm_year + 1900, + time_tm->tm_mon + 1, time_tm->tm_mday, time_tm->tm_hour, time_tm->tm_min, time_tm->tm_sec); + + // Ensure snprintf succeeded and output was not truncated + FW_ASSERT(sizeof(iso_time) > static_cast(result)); + + Fw::String iso_time_str(iso_time); + + // Report time retrieved in ISO format + this->log_ACTIVITY_HI_GetTime(iso_time_str); this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK); } diff --git a/FprimeZephyrReference/Components/RtcManager/RtcManager.fpp b/FprimeZephyrReference/Components/RtcManager/RtcManager.fpp index 0dcdcd30..bb7c3921 100644 --- a/FprimeZephyrReference/Components/RtcManager/RtcManager.fpp +++ b/FprimeZephyrReference/Components/RtcManager/RtcManager.fpp @@ -13,14 +13,14 @@ module Components { #### Uncomment the following examples to start customizing your component #### ############################################################################## - @ Event to log the time retrieved from the Rv3028Manager - event GetTime(year: U32, month: U32, day: U32, hour:U32, minute:U32, second:U32) severity activity high id 1 format "Time: {}/{}/{} at {}:{}:{}" + @ Event to log the time retrieved from the Rv3028Manager in ISO 8601 format + event GetTime(t: string) severity activity high id 1 format "{}" @ Output port to set the time on the Rv3028Manager output port timeSet: Drv.TimeSet @ Output port to get the time from the Rv3028Manager - output port timeRead: Drv.TimeRead + output port timeGet: Drv.TimeGet ############################################################################### # Standard AC Ports: Required for Channels, Events, Commands, and Parameters # diff --git a/FprimeZephyrReference/Components/RtcManager/docs/sdd.md b/FprimeZephyrReference/Components/RtcManager/docs/sdd.md index 59767d0f..ba67c977 100644 --- a/FprimeZephyrReference/Components/RtcManager/docs/sdd.md +++ b/FprimeZephyrReference/Components/RtcManager/docs/sdd.md @@ -14,7 +14,7 @@ The RtcManager component manages interactions with a Real Time Clock (RTC) devic 1. The component is instantiated and initialized during system startup 2. A ground station sends a `GET_TIME` command 3. On each command, the component: - - Calls the `timeRead` port to get the current time from the RTC device + - Calls the `timeGet` port to get the current time from the RTC device - Emits a `GetTime` event with the retrieved time ## Requirements @@ -28,7 +28,7 @@ The RtcManager component manages interactions with a Real Time Clock (RTC) devic | Name | Description | |---|---| | timeSet | Output port to reach out to driver to set the time | -| TimeRead | Output port to reach out to driver to read the time | +| TimeGet | Output port to reach out to driver to read the time | ## Commands | Name | Description | @@ -80,7 +80,7 @@ sequenceDiagram participant RtcManager participant RV3028 Manager Ground Station-->>RtcManager: Send GET_TIME command - RtcManager->>RV3028 Manager: Call timeRead port + RtcManager->>RV3028 Manager: Call timeGet port RV3028 Manager->>RtcManager: Return time data RtcManager->>Event Log: Emit GetTime event with retrieved time ``` diff --git a/FprimeZephyrReference/ReferenceDeployment/Top/topology.fpp b/FprimeZephyrReference/ReferenceDeployment/Top/topology.fpp index 4eacac19..c6a286ba 100644 --- a/FprimeZephyrReference/ReferenceDeployment/Top/topology.fpp +++ b/FprimeZephyrReference/ReferenceDeployment/Top/topology.fpp @@ -101,7 +101,7 @@ module ReferenceDeployment { connections RtcManager { rtcManager.timeSet -> rv3028Manager.timeSet - rtcManager.timeRead -> rv3028Manager.timeRead + rtcManager.timeGet -> rv3028Manager.timeGet } connections ReferenceDeployment { diff --git a/FprimeZephyrReference/test/int/rtc_test.py b/FprimeZephyrReference/test/int/rtc_test.py new file mode 100644 index 00000000..28e047bd --- /dev/null +++ b/FprimeZephyrReference/test/int/rtc_test.py @@ -0,0 +1,106 @@ +""" +watchdog_test.py: + +Simple integration tests for the Watchdog component. +Tests are ordered so that stop tests run last. +""" + +import time +import pytest +from datetime import datetime, timezone +import json + +@pytest.fixture(autouse=True) +def set_now_time(fprime_test_api): + """Fixture to set the time to test runner's time before and after each test""" + set_time(fprime_test_api) + yield + set_time(fprime_test_api) + +def set_time(fprime_test_api, dt: datetime = None): + """Helper function to set the time to now or to a specified datetime""" + if dt is None: + dt = datetime.now(timezone.utc) + + time_data = dict( + Year=dt.year, + Month=dt.month, + Day=dt.day, + Hour=dt.hour, + Minute=dt.minute, + Second=dt.second, + ) + time_data_str = json.dumps(time_data) + fprime_test_api.send_and_assert_command( + "ReferenceDeployment.rtcManager.SET_TIME", + [ + time_data_str, + ], + max_delay=2 + ) + fprime_test_api.assert_event( + "ReferenceDeployment.rv3028Manager.TimeSet", + timeout=2 + ) + +def get_time(fprime_test_api): + """Helper function to request packet and get fresh WatchdogTransitions telemetry""" + fprime_test_api.clear_histories() + fprime_test_api.send_and_assert_command("ReferenceDeployment.rtcManager.GET_TIME", max_delay=2) + result = fprime_test_api.assert_event( + "ReferenceDeployment.rtcManager.GetTime", + timeout=2 + ) + + # EventData get_dict() https://github.com/nasa/fprime-gds/blob/67d0ec62f829ed23d72776f1d323f71eaafd31cc/src/fprime_gds/common/data_types/event_data.py#L130C9-L130C17 + return result.get_dict() + + +def test_01_current_time_set(fprime_test_api): + """Test that we can read WatchdogTransitions telemetry""" + event_data = get_time(fprime_test_api) + event_display_text_time = datetime.fromisoformat(event_data["display_text"]) + + # Assert time is within 30 seconds of now + pytest.approx(event_display_text_time, abs=30) == datetime.now(timezone.utc) + + +def test_02_set_time_in_past(fprime_test_api): + """Test that we can set the time to a past time""" + curiosity_landing = datetime(2012, 8, 6, 5, 17, 57, tzinfo=timezone.utc) + set_time(fprime_test_api, curiosity_landing) + + event_data = get_time(fprime_test_api) + event_display_text_time = datetime.fromisoformat(event_data["display_text"]) + + # Assert time is within 30 seconds of curiosity landing + pytest.approx(event_display_text_time, abs=30) == curiosity_landing + + +def test_03_time_incrementing(fprime_test_api): + """Test that time increments over time""" + initial_event_data = get_time(fprime_test_api) + initial_time = datetime.fromisoformat(initial_event_data["display_text"]) + + time.sleep(2.0) # Wait for time to increment + + updated_event_data = get_time(fprime_test_api) + updated_time = datetime.fromisoformat(updated_event_data["display_text"]) + + assert updated_time > initial_time, \ + f"Time should increase. Initial: {initial_time}, Updated: {updated_time}" + + +def test_04_time_in_telemetry(fprime_test_api): + """Test that we can get Time telemetry""" + # result in ChData object https://github.com/nasa/fprime-gds/blob/67d0ec62f829ed23d72776f1d323f71eaafd31cc/src/fprime_gds/common/data_types/ch_data.py#L18 + result = fprime_test_api.assert_telemetry( + "CdhCore.cmdDisp.CommandsDispatched", + timeout=3 + ) + + # result.time is TimeType object https://github.com/nasa/fprime-tools/blob/aaa5840181146ca38b195c2a4d3f1bcbb35234c1/src/fprime/common/models/serialize/time_type.py#L49 + tlm_time = datetime.fromtimestamp(result.time.seconds, tz=timezone.utc) + + # Assert time is within 30 seconds of now + pytest.approx(tlm_time, abs=30) == datetime.now(timezone.utc) From aab21fb70dfd67136b13ff800ebe0d4d5d1618df Mon Sep 17 00:00:00 2001 From: Nate Gay Date: Sun, 28 Sep 2025 00:13:11 -0500 Subject: [PATCH 28/40] Add typehinting --- FprimeZephyrReference/test/int/rtc_test.py | 55 ++++++++++++---------- 1 file changed, 30 insertions(+), 25 deletions(-) diff --git a/FprimeZephyrReference/test/int/rtc_test.py b/FprimeZephyrReference/test/int/rtc_test.py index 28e047bd..43904d83 100644 --- a/FprimeZephyrReference/test/int/rtc_test.py +++ b/FprimeZephyrReference/test/int/rtc_test.py @@ -1,23 +1,30 @@ """ -watchdog_test.py: +rtc_test.py: -Simple integration tests for the Watchdog component. +Simple integration tests for the RTC Manager component. Tests are ordered so that stop tests run last. """ +import json import time -import pytest from datetime import datetime, timezone -import json +from typing import Any + +import pytest +from fprime_gds.common.data_types.ch_data import ChData +from fprime_gds.common.data_types.event_data import EventData +from fprime_gds.common.testing_fw.api import IntegrationTestAPI + @pytest.fixture(autouse=True) -def set_now_time(fprime_test_api): +def set_now_time(fprime_test_api: IntegrationTestAPI): """Fixture to set the time to test runner's time before and after each test""" set_time(fprime_test_api) yield set_time(fprime_test_api) -def set_time(fprime_test_api, dt: datetime = None): + +def set_time(fprime_test_api: IntegrationTestAPI, dt: datetime = None): """Helper function to set the time to now or to a specified datetime""" if dt is None: dt = datetime.now(timezone.utc) @@ -36,27 +43,25 @@ def set_time(fprime_test_api, dt: datetime = None): [ time_data_str, ], - max_delay=2 - ) - fprime_test_api.assert_event( - "ReferenceDeployment.rv3028Manager.TimeSet", - timeout=2 + max_delay=2, ) + fprime_test_api.assert_event("ReferenceDeployment.rv3028Manager.TimeSet", timeout=2) + -def get_time(fprime_test_api): +def get_time(fprime_test_api: IntegrationTestAPI) -> dict[str, Any]: """Helper function to request packet and get fresh WatchdogTransitions telemetry""" fprime_test_api.clear_histories() - fprime_test_api.send_and_assert_command("ReferenceDeployment.rtcManager.GET_TIME", max_delay=2) - result = fprime_test_api.assert_event( - "ReferenceDeployment.rtcManager.GetTime", - timeout=2 + fprime_test_api.send_and_assert_command( + "ReferenceDeployment.rtcManager.GET_TIME", max_delay=2 + ) + result: EventData = fprime_test_api.assert_event( + "ReferenceDeployment.rtcManager.GetTime", timeout=2 ) - # EventData get_dict() https://github.com/nasa/fprime-gds/blob/67d0ec62f829ed23d72776f1d323f71eaafd31cc/src/fprime_gds/common/data_types/event_data.py#L130C9-L130C17 return result.get_dict() -def test_01_current_time_set(fprime_test_api): +def test_01_current_time_set(fprime_test_api: IntegrationTestAPI): """Test that we can read WatchdogTransitions telemetry""" event_data = get_time(fprime_test_api) event_display_text_time = datetime.fromisoformat(event_data["display_text"]) @@ -65,7 +70,7 @@ def test_01_current_time_set(fprime_test_api): pytest.approx(event_display_text_time, abs=30) == datetime.now(timezone.utc) -def test_02_set_time_in_past(fprime_test_api): +def test_02_set_time_in_past(fprime_test_api: IntegrationTestAPI): """Test that we can set the time to a past time""" curiosity_landing = datetime(2012, 8, 6, 5, 17, 57, tzinfo=timezone.utc) set_time(fprime_test_api, curiosity_landing) @@ -77,7 +82,7 @@ def test_02_set_time_in_past(fprime_test_api): pytest.approx(event_display_text_time, abs=30) == curiosity_landing -def test_03_time_incrementing(fprime_test_api): +def test_03_time_incrementing(fprime_test_api: IntegrationTestAPI): """Test that time increments over time""" initial_event_data = get_time(fprime_test_api) initial_time = datetime.fromisoformat(initial_event_data["display_text"]) @@ -87,16 +92,16 @@ def test_03_time_incrementing(fprime_test_api): updated_event_data = get_time(fprime_test_api) updated_time = datetime.fromisoformat(updated_event_data["display_text"]) - assert updated_time > initial_time, \ + assert updated_time > initial_time, ( f"Time should increase. Initial: {initial_time}, Updated: {updated_time}" + ) -def test_04_time_in_telemetry(fprime_test_api): +def test_04_time_in_telemetry(fprime_test_api: IntegrationTestAPI): """Test that we can get Time telemetry""" # result in ChData object https://github.com/nasa/fprime-gds/blob/67d0ec62f829ed23d72776f1d323f71eaafd31cc/src/fprime_gds/common/data_types/ch_data.py#L18 - result = fprime_test_api.assert_telemetry( - "CdhCore.cmdDisp.CommandsDispatched", - timeout=3 + result: ChData = fprime_test_api.assert_telemetry( + "CdhCore.cmdDisp.CommandsDispatched", timeout=3 ) # result.time is TimeType object https://github.com/nasa/fprime-tools/blob/aaa5840181146ca38b195c2a4d3f1bcbb35234c1/src/fprime/common/models/serialize/time_type.py#L49 From ff77b965f6d8c8148b2047df4103285d426d96f7 Mon Sep 17 00:00:00 2001 From: Nate Gay Date: Sun, 28 Sep 2025 00:14:00 -0500 Subject: [PATCH 29/40] Comment fix --- FprimeZephyrReference/test/int/rtc_test.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/FprimeZephyrReference/test/int/rtc_test.py b/FprimeZephyrReference/test/int/rtc_test.py index 43904d83..a4269f51 100644 --- a/FprimeZephyrReference/test/int/rtc_test.py +++ b/FprimeZephyrReference/test/int/rtc_test.py @@ -1,8 +1,7 @@ """ rtc_test.py: -Simple integration tests for the RTC Manager component. -Tests are ordered so that stop tests run last. +Integration tests for the RTC Manager component. """ import json From 582ae5c8310bb14f60afc1d5a7e59486e563132f Mon Sep 17 00:00:00 2001 From: Nate Gay Date: Sun, 28 Sep 2025 16:48:30 -0500 Subject: [PATCH 30/40] Test for previous time output when setting time --- .../Drv/Rv3028Manager/Rv3028Manager.cpp | 5 +-- .../Drv/Rv3028Manager/Rv3028Manager.fpp | 11 ++--- FprimeZephyrReference/test/int/rtc_test.py | 42 ++++++++++++++++--- 3 files changed, 41 insertions(+), 17 deletions(-) diff --git a/FprimeZephyrReference/Components/Drv/Rv3028Manager/Rv3028Manager.cpp b/FprimeZephyrReference/Components/Drv/Rv3028Manager/Rv3028Manager.cpp index b5e54f9a..c6911df5 100644 --- a/FprimeZephyrReference/Components/Drv/Rv3028Manager/Rv3028Manager.cpp +++ b/FprimeZephyrReference/Components/Drv/Rv3028Manager/Rv3028Manager.cpp @@ -80,15 +80,12 @@ void Rv3028Manager ::timeSet_handler(FwIndexType portNum, const Drv::TimeData& t .tm_isdst = 0, }; - // Event current time to correlate prior events when new time is set - this->log_ACTIVITY_HI_TimeGet(this->getPosixTime()); - // Set time on RTC const int status = rtc_set_time(this->rv3028, &time_rtc); // Report whether setting the time was successful if (status == 0) { - this->log_ACTIVITY_HI_TimeSet(); + this->log_ACTIVITY_HI_TimeSet(this->getPosixTime()); } else { this->log_WARNING_HI_TimeNotSet(); } diff --git a/FprimeZephyrReference/Components/Drv/Rv3028Manager/Rv3028Manager.fpp b/FprimeZephyrReference/Components/Drv/Rv3028Manager/Rv3028Manager.fpp index 3f78ea2a..2b79dc97 100644 --- a/FprimeZephyrReference/Components/Drv/Rv3028Manager/Rv3028Manager.fpp +++ b/FprimeZephyrReference/Components/Drv/Rv3028Manager/Rv3028Manager.fpp @@ -22,11 +22,9 @@ module Drv { import Svc.Time @ timeSet port to set the time on the RTC - @ Requirement Rv3028Manager-001 sync input port timeSet: TimeSet @ timeGet port to get the time from the RTC - @ Requirement Rv3028Manager-002 sync input port timeGet: TimeGet ############################################################################## @@ -39,13 +37,10 @@ module Drv { @ InvalidTime event indicates that the RV3028 returned an invalid time event InvalidTime() severity warning high id 1 format "RV3028 returned invalid time" throttle 5 - @ TimeGet event indicates that the time was read successfully - event TimeGet( - t: U32 @< POSIX time read from RTC - ) severity activity high id 2 format "{}" - @ TimeSet event indicates that the time was set successfully - event TimeSet() severity activity high id 3 format "Time set on RV3028" + event TimeSet( + t: U32 @< POSIX time read from RTC + ) severity activity high id 3 format "Time set on RV3028, previous time: {}" @ TimeNotSet event indicates that the time was not set successfully event TimeNotSet() severity warning high id 4 format "Time not set on RV3028" diff --git a/FprimeZephyrReference/test/int/rtc_test.py b/FprimeZephyrReference/test/int/rtc_test.py index a4269f51..f5c3be1d 100644 --- a/FprimeZephyrReference/test/int/rtc_test.py +++ b/FprimeZephyrReference/test/int/rtc_test.py @@ -10,6 +10,8 @@ from typing import Any import pytest +from fprime.common.models.serialize.numerical_types import U32Type +from fprime.common.models.serialize.time_type import TimeType from fprime_gds.common.data_types.ch_data import ChData from fprime_gds.common.data_types.event_data import EventData from fprime_gds.common.testing_fw.api import IntegrationTestAPI @@ -19,8 +21,10 @@ def set_now_time(fprime_test_api: IntegrationTestAPI): """Fixture to set the time to test runner's time before and after each test""" set_time(fprime_test_api) + fprime_test_api.clear_histories() yield set_time(fprime_test_api) + fprime_test_api.clear_histories() def set_time(fprime_test_api: IntegrationTestAPI, dt: datetime = None): @@ -61,7 +65,9 @@ def get_time(fprime_test_api: IntegrationTestAPI) -> dict[str, Any]: def test_01_current_time_set(fprime_test_api: IntegrationTestAPI): - """Test that we can read WatchdogTransitions telemetry""" + """Test that we can set current time""" + + # Fetch time from fixture setting current time event_data = get_time(fprime_test_api) event_display_text_time = datetime.fromisoformat(event_data["display_text"]) @@ -71,9 +77,28 @@ def test_01_current_time_set(fprime_test_api: IntegrationTestAPI): def test_02_set_time_in_past(fprime_test_api: IntegrationTestAPI): """Test that we can set the time to a past time""" + + # 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) + # Fetch event data + result: EventData = fprime_test_api.assert_event( + "ReferenceDeployment.rv3028Manager.TimeSet", timeout=2 + ) + event_data: dict[str, Any] = result.get_dict() + # args = event_data.args + + # Fetch previously set time from event args + event_previous_time_arg: U32Type = result.args[0] + previously_set_time = datetime.fromtimestamp( + event_previous_time_arg.val, tz=timezone.utc + ) + + # Assert previously set time is within 30 seconds of now + pytest.approx(previously_set_time, abs=30) == datetime.now(timezone.utc) + + # Fetch newly set time from event event_data = get_time(fprime_test_api) event_display_text_time = datetime.fromisoformat(event_data["display_text"]) @@ -83,14 +108,19 @@ def test_02_set_time_in_past(fprime_test_api: IntegrationTestAPI): def test_03_time_incrementing(fprime_test_api: IntegrationTestAPI): """Test that time increments over time""" + + # Fetch initial time initial_event_data = get_time(fprime_test_api) initial_time = datetime.fromisoformat(initial_event_data["display_text"]) - time.sleep(2.0) # Wait for time to increment + # Wait for time to increment + time.sleep(2.0) + # Fetch updated time updated_event_data = get_time(fprime_test_api) updated_time = datetime.fromisoformat(updated_event_data["display_text"]) + # Assert time has increased assert updated_time > initial_time, ( f"Time should increase. Initial: {initial_time}, Updated: {updated_time}" ) @@ -98,13 +128,15 @@ def test_03_time_incrementing(fprime_test_api: IntegrationTestAPI): def test_04_time_in_telemetry(fprime_test_api: IntegrationTestAPI): """Test that we can get Time telemetry""" - # result in ChData object https://github.com/nasa/fprime-gds/blob/67d0ec62f829ed23d72776f1d323f71eaafd31cc/src/fprime_gds/common/data_types/ch_data.py#L18 + + # Fetch telemetry packet result: ChData = fprime_test_api.assert_telemetry( "CdhCore.cmdDisp.CommandsDispatched", timeout=3 ) - # result.time is TimeType object https://github.com/nasa/fprime-tools/blob/aaa5840181146ca38b195c2a4d3f1bcbb35234c1/src/fprime/common/models/serialize/time_type.py#L49 - tlm_time = datetime.fromtimestamp(result.time.seconds, tz=timezone.utc) + # Convert FPrime time to datetime + fp_time: TimeType = result.time + tlm_time = datetime.fromtimestamp(fp_time.seconds, tz=timezone.utc) # Assert time is within 30 seconds of now pytest.approx(tlm_time, abs=30) == datetime.now(timezone.utc) From 6866735831f6de18dc75543aa621357c18a7c298 Mon Sep 17 00:00:00 2001 From: Nate Gay Date: Sun, 28 Sep 2025 17:00:29 -0500 Subject: [PATCH 31/40] Stop using EventData.get_dict() --- FprimeZephyrReference/test/int/rtc_test.py | 28 ++++++++-------------- 1 file changed, 10 insertions(+), 18 deletions(-) diff --git a/FprimeZephyrReference/test/int/rtc_test.py b/FprimeZephyrReference/test/int/rtc_test.py index f5c3be1d..c9d04b29 100644 --- a/FprimeZephyrReference/test/int/rtc_test.py +++ b/FprimeZephyrReference/test/int/rtc_test.py @@ -7,7 +7,6 @@ import json import time from datetime import datetime, timezone -from typing import Any import pytest from fprime.common.models.serialize.numerical_types import U32Type @@ -51,7 +50,7 @@ def set_time(fprime_test_api: IntegrationTestAPI, dt: datetime = None): fprime_test_api.assert_event("ReferenceDeployment.rv3028Manager.TimeSet", timeout=2) -def get_time(fprime_test_api: IntegrationTestAPI) -> dict[str, Any]: +def get_time(fprime_test_api: IntegrationTestAPI) -> datetime: """Helper function to request packet and get fresh WatchdogTransitions telemetry""" fprime_test_api.clear_histories() fprime_test_api.send_and_assert_command( @@ -60,19 +59,17 @@ def get_time(fprime_test_api: IntegrationTestAPI) -> dict[str, Any]: result: EventData = fprime_test_api.assert_event( "ReferenceDeployment.rtcManager.GetTime", timeout=2 ) - - return result.get_dict() + return datetime.fromisoformat(result.display_text) def test_01_current_time_set(fprime_test_api: IntegrationTestAPI): """Test that we can set current time""" # Fetch time from fixture setting current time - event_data = get_time(fprime_test_api) - event_display_text_time = datetime.fromisoformat(event_data["display_text"]) + event_time = get_time(fprime_test_api) # Assert time is within 30 seconds of now - pytest.approx(event_display_text_time, abs=30) == datetime.now(timezone.utc) + pytest.approx(event_time, abs=30) == datetime.now(timezone.utc) def test_02_set_time_in_past(fprime_test_api: IntegrationTestAPI): @@ -86,8 +83,6 @@ def test_02_set_time_in_past(fprime_test_api: IntegrationTestAPI): result: EventData = fprime_test_api.assert_event( "ReferenceDeployment.rv3028Manager.TimeSet", timeout=2 ) - event_data: dict[str, Any] = result.get_dict() - # args = event_data.args # Fetch previously set time from event args event_previous_time_arg: U32Type = result.args[0] @@ -99,30 +94,27 @@ def test_02_set_time_in_past(fprime_test_api: IntegrationTestAPI): pytest.approx(previously_set_time, abs=30) == datetime.now(timezone.utc) # Fetch newly set time from event - event_data = get_time(fprime_test_api) - event_display_text_time = datetime.fromisoformat(event_data["display_text"]) + event_time = get_time(fprime_test_api) # Assert time is within 30 seconds of curiosity landing - pytest.approx(event_display_text_time, abs=30) == curiosity_landing + pytest.approx(event_time, abs=30) == curiosity_landing def test_03_time_incrementing(fprime_test_api: IntegrationTestAPI): """Test that time increments over time""" # Fetch initial time - initial_event_data = get_time(fprime_test_api) - initial_time = datetime.fromisoformat(initial_event_data["display_text"]) + initial_event_time = get_time(fprime_test_api) # Wait for time to increment time.sleep(2.0) # Fetch updated time - updated_event_data = get_time(fprime_test_api) - updated_time = datetime.fromisoformat(updated_event_data["display_text"]) + updated_event_time = get_time(fprime_test_api) # Assert time has increased - assert updated_time > initial_time, ( - f"Time should increase. Initial: {initial_time}, Updated: {updated_time}" + assert updated_event_time > initial_event_time, ( + f"Time should increase. Initial: {initial_event_time}, Updated: {updated_event_time}" ) From b7c3ddbf633eb5f32b7537b36d76afbd9a3fd1b3 Mon Sep 17 00:00:00 2001 From: Nate Gay Date: Sun, 28 Sep 2025 23:20:29 -0500 Subject: [PATCH 32/40] Now with microseconds! MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Samuel Gómez Guio --- .../Drv/Rv3028Manager/Rv3028Manager.cpp | 41 +++++++++++-------- .../Drv/Rv3028Manager/Rv3028Manager.fpp | 3 -- .../Drv/Rv3028Manager/Rv3028Manager.hpp | 4 +- 3 files changed, 25 insertions(+), 23 deletions(-) diff --git a/FprimeZephyrReference/Components/Drv/Rv3028Manager/Rv3028Manager.cpp b/FprimeZephyrReference/Components/Drv/Rv3028Manager/Rv3028Manager.cpp index c6911df5..e55f42d2 100644 --- a/FprimeZephyrReference/Components/Drv/Rv3028Manager/Rv3028Manager.cpp +++ b/FprimeZephyrReference/Components/Drv/Rv3028Manager/Rv3028Manager.cpp @@ -31,14 +31,13 @@ void Rv3028Manager ::timeGetPort_handler(FwIndexType portNum, Fw::Time& time) { return; } - I32 posix_time = this->getPosixTime(); - if (posix_time < 0) { - Fw::Logger::log("getPosixTime returned invalid time"); - return; - } + // Get time from RTC + U32 posix_time; + U32 u_secs; + this->getTime(posix_time, u_secs); // Set FPrime time object - time.set(TimeBase::TB_WORKSTATION_TIME, 0, static_cast(posix_time), 0); + time.set(TimeBase::TB_WORKSTATION_TIME, 0, posix_time, u_secs); } U32 Rv3028Manager ::timeGet_handler(FwIndexType portNum) { @@ -49,14 +48,12 @@ U32 Rv3028Manager ::timeGet_handler(FwIndexType portNum) { } this->log_WARNING_HI_DeviceNotReady_ThrottleClear(); - I32 posix_time = this->getPosixTime(); - if (posix_time < 0) { - this->log_WARNING_HI_InvalidTime(); - return 0; - } - this->log_WARNING_HI_InvalidTime_ThrottleClear(); + // Get time from RTC + U32 posix_time; + U32 u_secs; + this->getTime(posix_time, u_secs); - return static_cast(posix_time); + return u_secs; } void Rv3028Manager ::timeSet_handler(FwIndexType portNum, const Drv::TimeData& t) { @@ -85,7 +82,10 @@ void Rv3028Manager ::timeSet_handler(FwIndexType portNum, const Drv::TimeData& t // Report whether setting the time was successful if (status == 0) { - this->log_ACTIVITY_HI_TimeSet(this->getPosixTime()); + U32 posix_time; + U32 u_secs; + this->getTime(posix_time, u_secs); + this->log_ACTIVITY_HI_TimeSet(posix_time); } else { this->log_WARNING_HI_TimeNotSet(); } @@ -94,7 +94,8 @@ void Rv3028Manager ::timeSet_handler(FwIndexType portNum, const Drv::TimeData& t // ---------------------------------------------------------------------- // Private helper methods // ---------------------------------------------------------------------- -I32 Rv3028Manager ::getPosixTime() { +void Rv3028Manager ::getTime(U32& posix_time, U32& u_secs) { + // Read time from RTC struct rtc_time time_rtc = {}; rtc_get_time(this->rv3028, &time_rtc); @@ -102,13 +103,17 @@ I32 Rv3028Manager ::getPosixTime() { struct tm* time_tm = rtc_time_to_tm(&time_rtc); errno = 0; - time_t posix_time = timeutil_timegm(time_tm); + time_t time_pt = timeutil_timegm(time_tm); if (errno == ERANGE) { Fw::Logger::log("RV2038 returned invalid time"); - return -1; + return; } - return posix_time; + uint32_t time_usecs = k_cyc_to_us_near32(k_cycle_get_32()); + + // Set output parameters + posix_time = static_cast(time_pt); + u_secs = static_cast(time_usecs); } } // namespace Drv diff --git a/FprimeZephyrReference/Components/Drv/Rv3028Manager/Rv3028Manager.fpp b/FprimeZephyrReference/Components/Drv/Rv3028Manager/Rv3028Manager.fpp index 2b79dc97..4052754c 100644 --- a/FprimeZephyrReference/Components/Drv/Rv3028Manager/Rv3028Manager.fpp +++ b/FprimeZephyrReference/Components/Drv/Rv3028Manager/Rv3028Manager.fpp @@ -34,9 +34,6 @@ module Drv { @ DeviceNotReady event indicates that the RV3028 is not ready event DeviceNotReady() severity warning high id 0 format "RV3028 not ready" throttle 5 - @ InvalidTime event indicates that the RV3028 returned an invalid time - event InvalidTime() severity warning high id 1 format "RV3028 returned invalid time" throttle 5 - @ TimeSet event indicates that the time was set successfully event TimeSet( t: U32 @< POSIX time read from RTC diff --git a/FprimeZephyrReference/Components/Drv/Rv3028Manager/Rv3028Manager.hpp b/FprimeZephyrReference/Components/Drv/Rv3028Manager/Rv3028Manager.hpp index 26971f8e..b32f289a 100644 --- a/FprimeZephyrReference/Components/Drv/Rv3028Manager/Rv3028Manager.hpp +++ b/FprimeZephyrReference/Components/Drv/Rv3028Manager/Rv3028Manager.hpp @@ -63,8 +63,8 @@ class Rv3028Manager final : public Rv3028ManagerComponentBase { // Private helper methods // ---------------------------------------------------------------------- - //! Helper method to get POSIX time from RTC - I32 getPosixTime(); + //! Helper method to get time from RTC + void getTime(U32& posix_time, U32& u_secs); //! Zephyr device stores the initialized RV2038 sensor const struct device* rv3028; From a454a0708dc39f4d7d497f3381f5a552edcd0cd6 Mon Sep 17 00:00:00 2001 From: Nate Gay Date: Mon, 29 Sep 2025 00:17:53 -0500 Subject: [PATCH 33/40] Fix FPrime microsecond range expectation --- .../Drv/Rv3028Manager/Rv3028Manager.cpp | 8 +++- FprimeZephyrReference/test/int/rtc_test.py | 47 ++++++++++--------- 2 files changed, 30 insertions(+), 25 deletions(-) diff --git a/FprimeZephyrReference/Components/Drv/Rv3028Manager/Rv3028Manager.cpp b/FprimeZephyrReference/Components/Drv/Rv3028Manager/Rv3028Manager.cpp index e55f42d2..48c8ba03 100644 --- a/FprimeZephyrReference/Components/Drv/Rv3028Manager/Rv3028Manager.cpp +++ b/FprimeZephyrReference/Components/Drv/Rv3028Manager/Rv3028Manager.cpp @@ -53,7 +53,7 @@ U32 Rv3028Manager ::timeGet_handler(FwIndexType portNum) { U32 u_secs; this->getTime(posix_time, u_secs); - return u_secs; + return posix_time; } void Rv3028Manager ::timeSet_handler(FwIndexType portNum, const Drv::TimeData& t) { @@ -109,7 +109,11 @@ void Rv3028Manager ::getTime(U32& posix_time, U32& u_secs) { return; } - uint32_t time_usecs = k_cyc_to_us_near32(k_cycle_get_32()); + // Get microsecond part from system clock cycles + // Note: RV3028 does not provide sub-second precision, so this is + // just an approximation based on system cycles. + // FPrime expects microseconds in the range [0, 999999] + uint32_t time_usecs = k_cyc_to_us_near32(k_cycle_get_32()) % 1000000; // Set output parameters posix_time = static_cast(time_pt); diff --git a/FprimeZephyrReference/test/int/rtc_test.py b/FprimeZephyrReference/test/int/rtc_test.py index c9d04b29..c7bcd510 100644 --- a/FprimeZephyrReference/test/int/rtc_test.py +++ b/FprimeZephyrReference/test/int/rtc_test.py @@ -72,7 +72,25 @@ def test_01_current_time_set(fprime_test_api: IntegrationTestAPI): pytest.approx(event_time, abs=30) == datetime.now(timezone.utc) -def test_02_set_time_in_past(fprime_test_api: IntegrationTestAPI): +def test_02_time_incrementing(fprime_test_api: IntegrationTestAPI): + """Test that time increments over time""" + + # Fetch initial time + initial_event_time = get_time(fprime_test_api) + + # Wait for time to increment + time.sleep(2.0) + + # Fetch updated time + updated_event_time = get_time(fprime_test_api) + + # Assert time has increased + assert updated_event_time > initial_event_time, ( + f"Time should increase. Initial: {initial_event_time}, Updated: {updated_event_time}" + ) + + +def test_03_set_time_in_past(fprime_test_api: IntegrationTestAPI): """Test that we can set the time to a past time""" # Set time to Curiosity landing on Mars (7 minutes of terror! https://youtu.be/Ki_Af_o9Q9s) @@ -90,34 +108,17 @@ def test_02_set_time_in_past(fprime_test_api: IntegrationTestAPI): event_previous_time_arg.val, tz=timezone.utc ) + # Fetch FPrime time from event + fp_time: TimeType = result.get_time() + event_time = datetime.fromtimestamp(fp_time.seconds, tz=timezone.utc) + # Assert previously set time is within 30 seconds of now pytest.approx(previously_set_time, abs=30) == datetime.now(timezone.utc) - # Fetch newly set time from event - event_time = get_time(fprime_test_api) - - # Assert time is within 30 seconds of curiosity landing + # Assert event time is within 30 seconds of curiosity landing pytest.approx(event_time, abs=30) == curiosity_landing -def test_03_time_incrementing(fprime_test_api: IntegrationTestAPI): - """Test that time increments over time""" - - # Fetch initial time - initial_event_time = get_time(fprime_test_api) - - # Wait for time to increment - time.sleep(2.0) - - # Fetch updated time - updated_event_time = get_time(fprime_test_api) - - # Assert time has increased - assert updated_event_time > initial_event_time, ( - f"Time should increase. Initial: {initial_event_time}, Updated: {updated_event_time}" - ) - - def test_04_time_in_telemetry(fprime_test_api: IntegrationTestAPI): """Test that we can get Time telemetry""" From 4b42cc4ffef93ce77f243135cb19362976590ef6 Mon Sep 17 00:00:00 2001 From: Nate Gay Date: Mon, 29 Sep 2025 18:36:05 -0500 Subject: [PATCH 34/40] Simplify RTC Manager --- .../Components/CMakeLists.txt | 1 - .../Components/Drv/CMakeLists.txt | 2 +- .../{ => Drv}/RtcManager/CMakeLists.txt | 0 .../RtcManager.cpp} | 75 ++++--- .../RtcManager.fpp} | 31 ++- .../RtcManager.hpp} | 47 ++-- .../Components/Drv/RtcManager/docs/sdd.md | 204 ++++++++++++++++++ .../Drv/Rv3028Manager/CMakeLists.txt | 36 ---- .../Components/Drv/Rv3028Manager/docs/sdd.md | 204 ------------------ .../Components/RtcManager/RtcManager.cpp | 52 ----- .../Components/RtcManager/RtcManager.fpp | 47 ---- .../Components/RtcManager/RtcManager.hpp | 53 ----- .../Components/RtcManager/docs/sdd.md | 91 -------- .../ReferenceDeployment/Top/instances.fpp | 5 +- .../ReferenceDeployment/Top/topology.fpp | 12 +- .../test/int/integration_test.py | 94 ++++---- FprimeZephyrReference/test/int/rtc_test.py | 101 +++++---- 17 files changed, 383 insertions(+), 672 deletions(-) rename FprimeZephyrReference/Components/{ => Drv}/RtcManager/CMakeLists.txt (100%) rename FprimeZephyrReference/Components/Drv/{Rv3028Manager/Rv3028Manager.cpp => RtcManager/RtcManager.cpp} (66%) rename FprimeZephyrReference/Components/Drv/{Rv3028Manager/Rv3028Manager.fpp => RtcManager/RtcManager.fpp} (68%) rename FprimeZephyrReference/Components/Drv/{Rv3028Manager/Rv3028Manager.hpp => RtcManager/RtcManager.hpp} (55%) create mode 100644 FprimeZephyrReference/Components/Drv/RtcManager/docs/sdd.md delete mode 100644 FprimeZephyrReference/Components/Drv/Rv3028Manager/CMakeLists.txt delete mode 100644 FprimeZephyrReference/Components/Drv/Rv3028Manager/docs/sdd.md delete mode 100644 FprimeZephyrReference/Components/RtcManager/RtcManager.cpp delete mode 100644 FprimeZephyrReference/Components/RtcManager/RtcManager.fpp delete mode 100644 FprimeZephyrReference/Components/RtcManager/RtcManager.hpp delete mode 100644 FprimeZephyrReference/Components/RtcManager/docs/sdd.md diff --git a/FprimeZephyrReference/Components/CMakeLists.txt b/FprimeZephyrReference/Components/CMakeLists.txt index 1fc004bc..7ff380dc 100644 --- a/FprimeZephyrReference/Components/CMakeLists.txt +++ b/FprimeZephyrReference/Components/CMakeLists.txt @@ -3,4 +3,3 @@ add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/Drv") add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/FatalHandler") add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/Watchdog") -add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/RtcManager/") diff --git a/FprimeZephyrReference/Components/Drv/CMakeLists.txt b/FprimeZephyrReference/Components/Drv/CMakeLists.txt index fc46133a..ad6b8614 100644 --- a/FprimeZephyrReference/Components/Drv/CMakeLists.txt +++ b/FprimeZephyrReference/Components/Drv/CMakeLists.txt @@ -1 +1 @@ -add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/Rv3028Manager") +add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/RtcManager") diff --git a/FprimeZephyrReference/Components/RtcManager/CMakeLists.txt b/FprimeZephyrReference/Components/Drv/RtcManager/CMakeLists.txt similarity index 100% rename from FprimeZephyrReference/Components/RtcManager/CMakeLists.txt rename to FprimeZephyrReference/Components/Drv/RtcManager/CMakeLists.txt diff --git a/FprimeZephyrReference/Components/Drv/Rv3028Manager/Rv3028Manager.cpp b/FprimeZephyrReference/Components/Drv/RtcManager/RtcManager.cpp similarity index 66% rename from FprimeZephyrReference/Components/Drv/Rv3028Manager/Rv3028Manager.cpp rename to FprimeZephyrReference/Components/Drv/RtcManager/RtcManager.cpp index 48c8ba03..c218bedb 100644 --- a/FprimeZephyrReference/Components/Drv/Rv3028Manager/Rv3028Manager.cpp +++ b/FprimeZephyrReference/Components/Drv/RtcManager/RtcManager.cpp @@ -1,9 +1,9 @@ // ====================================================================== -// \title Rv3028Manager.cpp -// \brief cpp file for Rv3028Manager component implementation class +// \title RtcManager.cpp +// \brief cpp file for RtcManager component implementation class // ====================================================================== -#include "FprimeZephyrReference/Components/Drv/Rv3028Manager/Rv3028Manager.hpp" +#include "FprimeZephyrReference/Components/Drv/RtcManager/RtcManager.hpp" namespace Drv { @@ -11,20 +11,20 @@ namespace Drv { // Component construction and destruction // ---------------------------------------------------------------------- -Rv3028Manager ::Rv3028Manager(const char* const compName) : Rv3028ManagerComponentBase(compName) { +RtcManager ::RtcManager(const char* const compName) : RtcManagerComponentBase(compName) { // Initialize device - this->rv3028 = device_get_binding("RV3028"); + this->dev = device_get_binding("RV3028"); } -Rv3028Manager ::~Rv3028Manager() {} +RtcManager ::~RtcManager() {} // ---------------------------------------------------------------------- -// Handler implementations for commands +// Handler implementations for typed input ports // ---------------------------------------------------------------------- -void Rv3028Manager ::timeGetPort_handler(FwIndexType portNum, Fw::Time& time) { +void RtcManager ::timeGetPort_handler(FwIndexType portNum, Fw::Time& time) { // Check device readiness - if (!device_is_ready(this->rv3028)) { + if (!device_is_ready(this->dev)) { // Use logger instead of events since this fn is in a critical path for FPrime // to get time. Events require time, if this method fails an event will fail. Fw::Logger::log("RV2038 not ready"); @@ -40,25 +40,13 @@ void Rv3028Manager ::timeGetPort_handler(FwIndexType portNum, Fw::Time& time) { time.set(TimeBase::TB_WORKSTATION_TIME, 0, posix_time, u_secs); } -U32 Rv3028Manager ::timeGet_handler(FwIndexType portNum) { - // Check device readiness - if (!device_is_ready(this->rv3028)) { - this->log_WARNING_HI_DeviceNotReady(); - return 0; - } - this->log_WARNING_HI_DeviceNotReady_ThrottleClear(); - - // Get time from RTC - U32 posix_time; - U32 u_secs; - this->getTime(posix_time, u_secs); - - return posix_time; -} +// ---------------------------------------------------------------------- +// Handler implementations for commands +// ---------------------------------------------------------------------- -void Rv3028Manager ::timeSet_handler(FwIndexType portNum, const Drv::TimeData& t) { +void RtcManager ::TIME_SET_cmdHandler(FwOpcodeType opCode, U32 cmdSeq, Drv::TimeData t) { // Check device readiness - if (!device_is_ready(this->rv3028)) { + if (!device_is_ready(this->dev)) { this->log_WARNING_HI_DeviceNotReady(); return; } @@ -77,27 +65,38 @@ void Rv3028Manager ::timeSet_handler(FwIndexType portNum, const Drv::TimeData& t .tm_isdst = 0, }; + // Store current time for logging + U32 posix_time; + U32 u_secs; + this->getTime(posix_time, u_secs); + // Set time on RTC - const int status = rtc_set_time(this->rv3028, &time_rtc); - - // Report whether setting the time was successful - if (status == 0) { - U32 posix_time; - U32 u_secs; - this->getTime(posix_time, u_secs); - this->log_ACTIVITY_HI_TimeSet(posix_time); - } else { + const int status = rtc_set_time(this->dev, &time_rtc); + + if (status != 0) { + // Emit time not set event this->log_WARNING_HI_TimeNotSet(); + + // Send command response + this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::EXECUTION_ERROR); + return; } + + // Emit time set event, include previous time for reference + this->log_ACTIVITY_HI_TimeSet(posix_time, u_secs); + + // Send command response + this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK); } // ---------------------------------------------------------------------- // Private helper methods // ---------------------------------------------------------------------- -void Rv3028Manager ::getTime(U32& posix_time, U32& u_secs) { + +void RtcManager ::getTime(U32& posix_time, U32& u_secs) { // Read time from RTC struct rtc_time time_rtc = {}; - rtc_get_time(this->rv3028, &time_rtc); + rtc_get_time(this->dev, &time_rtc); // Convert time to POSIX time_t format struct tm* time_tm = rtc_time_to_tm(&time_rtc); @@ -109,7 +108,7 @@ void Rv3028Manager ::getTime(U32& posix_time, U32& u_secs) { return; } - // Get microsecond part from system clock cycles + // Get microseconds from system clock cycles // Note: RV3028 does not provide sub-second precision, so this is // just an approximation based on system cycles. // FPrime expects microseconds in the range [0, 999999] diff --git a/FprimeZephyrReference/Components/Drv/Rv3028Manager/Rv3028Manager.fpp b/FprimeZephyrReference/Components/Drv/RtcManager/RtcManager.fpp similarity index 68% rename from FprimeZephyrReference/Components/Drv/Rv3028Manager/Rv3028Manager.fpp rename to FprimeZephyrReference/Components/Drv/RtcManager/RtcManager.fpp index 4052754c..9149b3c0 100644 --- a/FprimeZephyrReference/Components/Drv/Rv3028Manager/Rv3028Manager.fpp +++ b/FprimeZephyrReference/Components/Drv/RtcManager/RtcManager.fpp @@ -18,29 +18,29 @@ module Drv { module Drv { @ Manages the real time clock - passive component Rv3028Manager { + passive component RtcManager { import Svc.Time - @ timeSet port to set the time on the RTC - sync input port timeSet: TimeSet - - @ timeGet port to get the time from the RTC - sync input port timeGet: TimeGet + @ TIME_SET command to set the time on the RTC + sync command TIME_SET( + t: Drv.TimeData @< Set the time + ) opcode 0 ############################################################################## #### Uncomment the following examples to start customizing your component #### ############################################################################## - @ DeviceNotReady event indicates that the RV3028 is not ready - event DeviceNotReady() severity warning high id 0 format "RV3028 not ready" throttle 5 + @ DeviceNotReady event indicates that the RTC is not ready + event DeviceNotReady() severity warning high id 0 format "RTC not ready" throttle 5 @ TimeSet event indicates that the time was set successfully event TimeSet( - t: U32 @< POSIX time read from RTC - ) severity activity high id 3 format "Time set on RV3028, previous time: {}" + pt: U32 @< POSIX time in seconds + u: U32 @< Microseconds + ) severity activity high id 3 format "Time set on RTC, previous time: {}.{}" @ TimeNotSet event indicates that the time was not set successfully - event TimeNotSet() severity warning high id 4 format "Time not set on RV3028" + event TimeNotSet() severity warning high id 4 format "Time not set on RTC" ############################################################################### # Standard AC Ports: Required for Channels, Events, Commands, and Parameters # @@ -48,6 +48,15 @@ module Drv { @ Port for requesting the current time time get port timeCaller + @ Port for sending command registrations + command reg port cmdRegOut + + @ Port for receiving commands + command recv port cmdIn + + @ Port for sending command responses + command resp port cmdResponseOut + @ Port for sending textual representation of events text event port logTextOut diff --git a/FprimeZephyrReference/Components/Drv/Rv3028Manager/Rv3028Manager.hpp b/FprimeZephyrReference/Components/Drv/RtcManager/RtcManager.hpp similarity index 55% rename from FprimeZephyrReference/Components/Drv/Rv3028Manager/Rv3028Manager.hpp rename to FprimeZephyrReference/Components/Drv/RtcManager/RtcManager.hpp index b32f289a..783ce01d 100644 --- a/FprimeZephyrReference/Components/Drv/Rv3028Manager/Rv3028Manager.hpp +++ b/FprimeZephyrReference/Components/Drv/RtcManager/RtcManager.hpp @@ -1,12 +1,12 @@ // ====================================================================== -// \title Rv3028Manager.hpp -// \brief hpp file for Rv3028Manager component implementation class +// \title RtcManager.hpp +// \brief hpp file for RtcManager component implementation class // ====================================================================== -#ifndef Components_Rv3028Manager_HPP -#define Components_Rv3028Manager_HPP +#ifndef Components_RtcManager_HPP +#define Components_RtcManager_HPP -#include "FprimeZephyrReference/Components/Drv/Rv3028Manager/Rv3028ManagerComponentAc.hpp" +#include "FprimeZephyrReference/Components/Drv/RtcManager/RtcManagerComponentAc.hpp" #include @@ -20,22 +20,22 @@ namespace Drv { -class Rv3028Manager final : public Rv3028ManagerComponentBase { +class RtcManager final : public RtcManagerComponentBase { public: // ---------------------------------------------------------------------- // Component construction and destruction // ---------------------------------------------------------------------- - //! Construct Rv3028Manager object - Rv3028Manager(const char* const compName //!< The component name + //! Construct RtcManager object + RtcManager(const char* const compName //!< The component name ); - //! Destroy Rv3028Manager object - ~Rv3028Manager(); + //! Destroy RtcManager object + ~RtcManager(); private: // ---------------------------------------------------------------------- - // Handler implementations for commands + // Handler implementations for typed input ports // ---------------------------------------------------------------------- //! Handler implementation for timeGetPort @@ -45,19 +45,18 @@ class Rv3028Manager final : public Rv3028ManagerComponentBase { Fw::Time& time //!< Reference to Time object ) override; - //! Handler implementation for timeGet - //! - //! timeGet port to get the time from the RTC - //! Requirement Rv3028Manager-002 - U32 timeGet_handler(FwIndexType portNum //!< The port number - ) override; + private: + // ---------------------------------------------------------------------- + // Handler implementations for commands + // ---------------------------------------------------------------------- - //! Handler implementation for timeSet + //! Handler implementation for command TIME_SET //! - //! timeSet port to set the time on the RTC - //! Requirement Rv3028Manager-001 - void timeSet_handler(FwIndexType portNum, //!< The port number - const Drv::TimeData& time) override; + //! TIME_SET command to set the time on the RTC + void TIME_SET_cmdHandler(FwOpcodeType opCode, //!< The opcode + U32 cmdSeq, //!< The command sequence number + Drv::TimeData t //!< Set the time + ) override; // ---------------------------------------------------------------------- // Private helper methods @@ -66,8 +65,8 @@ class Rv3028Manager final : public Rv3028ManagerComponentBase { //! Helper method to get time from RTC void getTime(U32& posix_time, U32& u_secs); - //! Zephyr device stores the initialized RV2038 sensor - const struct device* rv3028; + //! device stores the initialized Zephyr RTC device + const struct device* dev; }; } // namespace Drv diff --git a/FprimeZephyrReference/Components/Drv/RtcManager/docs/sdd.md b/FprimeZephyrReference/Components/Drv/RtcManager/docs/sdd.md new file mode 100644 index 00000000..740726da --- /dev/null +++ b/FprimeZephyrReference/Components/Drv/RtcManager/docs/sdd.md @@ -0,0 +1,204 @@ +# Components::RtcManager + +The RTC Manager component interfaces with the RTC Real Time Clock (RTC) to provide time measurements. + +### Typical Usage + +#### `timeGetPort` Port Usage +1. The component is instantiated and initialized during system startup +2. In a deployment topology, a `time connection` is made to the component's `timeGetPort` port + +#### `timeGet` Port Usage +1. The component is instantiated and initialized during system startup +2. A manager calls the `timeGet` ports +3. On each call, the component: + - Fetches and returns the time from the RTC RTC + - Emits a `DeviceNotReady` event if the device is not ready + +#### `timeSet` Port Usage +1. The component is instantiated and initialized during system startup +2. A manager calls the `timeSet` ports +3. On each call, the component: + - Sets the time on the RTC RTC + - Emits a `TimeSet` event if the time is set successfully + - Emits a `TimeNotSet` event if the time is not set successfully + - Emits a `DeviceNotReady` event if the device is not ready + +## Requirements +| Name | Description | Validation | +|---|---|---| +| RtcManager-001 | Time can be set on the RTC through a port | Manual | +| RtcManager-002 | Time can be read from the RTC through a port | Manual | +| RtcManager-003 | A device not ready event is emitted if the RTC is not ready | Manual | +| RtcManager-004 | A time set event is emitted if the time is set successfully | Manual | +| RtcManager-005 | A time not set event is emitted if the time is not set successfully | Manual | + +## Port Descriptions +| Name | Description | +|---|---| +| timeGetPort | Time port for FPrime topology connection to get the time from the RTC | +| timeSet | Input port sets the time on the RTC | +| timeGet | Input port reads the time from the RTC | + +## Events +| Name | Description | +|---|---| +| DeviceNotReady | Emits on unsuccessful device connection | +| TimeSet | Emits on successful time set | +| TimeNotSet | Emits on unsuccessful time set | + +## Class Diagram +```mermaid +classDiagram + namespace Drv { + class RtcManagerComponentBase { + <> + } + class RtcManager { + - dev: device* + + RtcManager(char* compName) + + ~RtcManager() + - void timeGetPort_handler(FwIndexType portNum, Fw::Time& time) + - U32 timeGet_handler(FwIndexType portNum) + - void timeSet_handler(FwIndexType portNum, const Drv::TimeData& time) + } + } + RtcManagerComponentBase <|-- RtcManager : inherits +``` + +## Sequence Diagrams + +### `timeGetPort` port + +The `timeGetPort` port is called from a `time connection` in a deployment topology to sync the RTC's time with FPrime's internal clock. + +#### Success +```mermaid +sequenceDiagram + participant Deployment Time Connection + participant RTC Manager + participant Zephyr Time API + participant RTC RTC + Deployment Time Connection-->>RTC Manager: Call timeGetPort time port + RTC Manager->>Zephyr Time API: Read time + Zephyr Time API->>RTC RTC: Read time + RTC RTC->>Zephyr Time API: Return time + Zephyr Time API->>RTC Manager: Return time + RTC Manager-->>Deployment Time Connection: Return time +``` + +#### Device Not Ready +```mermaid +sequenceDiagram + participant Event Log + participant Deployment Time Connection + participant RTC Manager + participant Zephyr Time API + participant RTC RTC + Deployment Time Connection->>RTC Manager: Call timeGetPort time port + RTC Manager->>Zephyr Time API: Read time + Zephyr Time API->>RTC RTC: Read time + RTC RTC->>Zephyr Time API: Return device not ready + Zephyr Time API->>RTC Manager: Return device not ready + RTC Manager->>Event Log: Emit DeviceNotReady event + RTC Manager->>Deployment Time Connection: Return 0 time +``` + +### `timeGet` port + +The `timeGet` port is called from a manager component to get the current time from the RTC. + +#### Success +```mermaid +sequenceDiagram + participant Event Log + participant Manager + participant RTC Manager + participant Zephyr Time API + participant RTC RTC + Manager-->>RTC Manager: Call timeGet synchronous input port + RTC Manager->>Zephyr Time API: Read time + Zephyr Time API->>RTC RTC: Read time + RTC RTC->>Zephyr Time API: Return time + Zephyr Time API->>RTC Manager: Return time + RTC Manager->>Event Log: Emit event GetTime +``` + +#### Device Not Ready +```mermaid +sequenceDiagram + participant Event Log + participant Manager + participant RTC Manager + participant Zephyr Time API + participant RTC RTC + Manager-->>RTC Manager: Call timeGet synchronous input port + RTC Manager->>Zephyr Time API: Read time + Zephyr Time API->>RTC RTC: Read time + RTC RTC->>Zephyr Time API: Return device not ready + Zephyr Time API->>RTC Manager: Return device not ready + RTC Manager->>Event Log: Emit event DeviceNotReady +``` + +### `timeSet` port + +The `timeSet` port is called from a manager component to set the current time on the RTC. + +#### Success +```mermaid +sequenceDiagram + participant Ground Station + participant Event Log + participant Manager + participant RTC Manager + participant Zephyr Time API + participant RTC RTC + Ground Station-->>Manager: Command to set time with Drv::TimeData struct + Manager->>RTC Manager: Call the timeSet synchronous input port with Drv::TimeData struct + RTC Manager->>Zephyr Time API: Set time + Zephyr Time API->>RTC RTC: Set time + RTC RTC->>Zephyr Time API: Return set success + Zephyr Time API->>RTC Manager: Return set success + RTC Manager->>Event Log: Emit event TimeSet +``` + +#### Device Not Ready +```mermaid +sequenceDiagram + participant Ground Station + participant Event Log + participant Manager + participant RTC Manager + participant Zephyr Time API + participant RTC RTC + Ground Station-->>Manager: Command to set time with Drv::TimeData struct + Manager->>RTC Manager: Call the timeSet synchronous input port with Drv::TimeData struct + RTC Manager->>Zephyr Time API: Set time + Zephyr Time API->>RTC RTC: Set time + RTC RTC->>Zephyr Time API: Return device not ready + Zephyr Time API->>RTC Manager: Return device not ready + RTC Manager->>Event Log: Emit event DeviceNotReady +``` + +#### Time Not Set +```mermaid +sequenceDiagram + participant Ground Station + participant Event Log + participant Manager + participant RTC Manager + participant Zephyr Time API + participant RTC RTC + Ground Station-->>Manager: Command to set time with Drv::TimeData struct + Manager->>RTC Manager: Call the timeSet synchronous input port with Drv::TimeData struct + RTC Manager->>Zephyr Time API: Set time + Zephyr Time API->>RTC RTC: Set time + RTC RTC->>Zephyr Time API: Return set failure + Zephyr Time API->>RTC Manager: Return set failure + RTC Manager->>Event Log: Emit event TimeNotSet +``` + +## Change Log +| Date | Description | +|---|---| +| 2025-9-18 | Initial RTC Manager component | diff --git a/FprimeZephyrReference/Components/Drv/Rv3028Manager/CMakeLists.txt b/FprimeZephyrReference/Components/Drv/Rv3028Manager/CMakeLists.txt deleted file mode 100644 index a79a7bb5..00000000 --- a/FprimeZephyrReference/Components/Drv/Rv3028Manager/CMakeLists.txt +++ /dev/null @@ -1,36 +0,0 @@ -#### -# F Prime CMakeLists.txt: -# -# SOURCES: list of source files (to be compiled) -# AUTOCODER_INPUTS: list of files to be passed to the autocoders -# DEPENDS: list of libraries that this module depends on -# -# More information in the F´ CMake API documentation: -# https://fprime.jpl.nasa.gov/latest/docs/reference/api/cmake/API/ -# -#### - -# Module names are derived from the path from the nearest project/library/framework -# root when not specifically overridden by the developer. i.e. The module defined by -# `Ref/SignalGen/CMakeLists.txt` will be named `Ref_SignalGen`. - -register_fprime_library( - AUTOCODER_INPUTS - "${CMAKE_CURRENT_LIST_DIR}/Rv3028Manager.fpp" - SOURCES - "${CMAKE_CURRENT_LIST_DIR}/Rv3028Manager.cpp" -# DEPENDS -# MyPackage_MyOtherModule -) - -### Unit Tests ### -# register_fprime_ut( -# AUTOCODER_INPUTS -# "${CMAKE_CURRENT_LIST_DIR}/Rv3028Manager.fpp" -# SOURCES -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/Rv3028ManagerTestMain.cpp" -# "${CMAKE_CURRENT_LIST_DIR}/test/ut/Rv3028ManagerTester.cpp" -# DEPENDS -# STest # For rules-based testing -# UT_AUTO_HELPERS -# ) diff --git a/FprimeZephyrReference/Components/Drv/Rv3028Manager/docs/sdd.md b/FprimeZephyrReference/Components/Drv/Rv3028Manager/docs/sdd.md deleted file mode 100644 index c42823b0..00000000 --- a/FprimeZephyrReference/Components/Drv/Rv3028Manager/docs/sdd.md +++ /dev/null @@ -1,204 +0,0 @@ -# Components::Rv3028Manager - -The RV3028 Manager component interfaces with the RV3028 Real Time Clock (RTC) to provide time measurements. - -### Typical Usage - -#### `timeGetPort` Port Usage -1. The component is instantiated and initialized during system startup -2. In a deployment topology, a `time connection` is made to the component's `timeGetPort` port - -#### `timeGet` Port Usage -1. The component is instantiated and initialized during system startup -2. A manager calls the `timeGet` ports -3. On each call, the component: - - Fetches and returns the time from the RV3028 RTC - - Emits a `DeviceNotReady` event if the device is not ready - -#### `timeSet` Port Usage -1. The component is instantiated and initialized during system startup -2. A manager calls the `timeSet` ports -3. On each call, the component: - - Sets the time on the RV3028 RTC - - Emits a `TimeSet` event if the time is set successfully - - Emits a `TimeNotSet` event if the time is not set successfully - - Emits a `DeviceNotReady` event if the device is not ready - -## Requirements -| Name | Description | Validation | -|---|---|---| -| Rv3028Manager-001 | Time can be set on the RV3028 through a port | Manual | -| Rv3028Manager-002 | Time can be read from the RV3028 through a port | Manual | -| Rv3028Manager-003 | A device not ready event is emitted if the RV3028 is not ready | Manual | -| Rv3028Manager-004 | A time set event is emitted if the time is set successfully | Manual | -| Rv3028Manager-005 | A time not set event is emitted if the time is not set successfully | Manual | - -## Port Descriptions -| Name | Description | -|---|---| -| timeGetPort | Time port for FPrime topology connection to get the time from the RV3028 | -| timeSet | Input port sets the time on the RV3028 | -| timeGet | Input port reads the time from the RV3028 | - -## Events -| Name | Description | -|---|---| -| DeviceNotReady | Emits on unsuccessful device connection | -| TimeSet | Emits on successful time set | -| TimeNotSet | Emits on unsuccessful time set | - -## Class Diagram -```mermaid -classDiagram - namespace Drv { - class Rv3028ManagerComponentBase { - <> - } - class Rv3028Manager { - - rv3028: device* - + Rv3028Manager(char* compName) - + ~Rv3028Manager() - - void timeGetPort_handler(FwIndexType portNum, Fw::Time& time) - - U32 timeGet_handler(FwIndexType portNum) - - void timeSet_handler(FwIndexType portNum, const Drv::TimeData& time) - } - } - Rv3028ManagerComponentBase <|-- Rv3028Manager : inherits -``` - -## Sequence Diagrams - -### `timeGetPort` port - -The `timeGetPort` port is called from a `time connection` in a deployment topology to sync the RTC's time with FPrime's internal clock. - -#### Success -```mermaid -sequenceDiagram - participant Deployment Time Connection - participant RV3028 Manager - participant Zephyr Time API - participant RV3028 RTC - Deployment Time Connection-->>RV3028 Manager: Call timeGetPort time port - RV3028 Manager->>Zephyr Time API: Read time - Zephyr Time API->>RV3028 RTC: Read time - RV3028 RTC->>Zephyr Time API: Return time - Zephyr Time API->>RV3028 Manager: Return time - RV3028 Manager-->>Deployment Time Connection: Return time -``` - -#### Device Not Ready -```mermaid -sequenceDiagram - participant Event Log - participant Deployment Time Connection - participant RV3028 Manager - participant Zephyr Time API - participant RV3028 RTC - Deployment Time Connection->>RV3028 Manager: Call timeGetPort time port - RV3028 Manager->>Zephyr Time API: Read time - Zephyr Time API->>RV3028 RTC: Read time - RV3028 RTC->>Zephyr Time API: Return device not ready - Zephyr Time API->>RV3028 Manager: Return device not ready - RV3028 Manager->>Event Log: Emit DeviceNotReady event - RV3028 Manager->>Deployment Time Connection: Return 0 time -``` - -### `timeGet` port - -The `timeGet` port is called from a manager component to get the current time from the RTC. - -#### Success -```mermaid -sequenceDiagram - participant Event Log - participant Manager - participant RV3028 Manager - participant Zephyr Time API - participant RV3028 RTC - Manager-->>RV3028 Manager: Call timeGet synchronous input port - RV3028 Manager->>Zephyr Time API: Read time - Zephyr Time API->>RV3028 RTC: Read time - RV3028 RTC->>Zephyr Time API: Return time - Zephyr Time API->>RV3028 Manager: Return time - RV3028 Manager->>Event Log: Emit event GetTime -``` - -#### Device Not Ready -```mermaid -sequenceDiagram - participant Event Log - participant Manager - participant RV3028 Manager - participant Zephyr Time API - participant RV3028 RTC - Manager-->>RV3028 Manager: Call timeGet synchronous input port - RV3028 Manager->>Zephyr Time API: Read time - Zephyr Time API->>RV3028 RTC: Read time - RV3028 RTC->>Zephyr Time API: Return device not ready - Zephyr Time API->>RV3028 Manager: Return device not ready - RV3028 Manager->>Event Log: Emit event DeviceNotReady -``` - -### `timeSet` port - -The `timeSet` port is called from a manager component to set the current time on the RTC. - -#### Success -```mermaid -sequenceDiagram - participant Ground Station - participant Event Log - participant Manager - participant RV3028 Manager - participant Zephyr Time API - participant RV3028 RTC - Ground Station-->>Manager: Command to set time with Drv::TimeData struct - Manager->>RV3028 Manager: Call the timeSet synchronous input port with Drv::TimeData struct - RV3028 Manager->>Zephyr Time API: Set time - Zephyr Time API->>RV3028 RTC: Set time - RV3028 RTC->>Zephyr Time API: Return set success - Zephyr Time API->>RV3028 Manager: Return set success - RV3028 Manager->>Event Log: Emit event TimeSet -``` - -#### Device Not Ready -```mermaid -sequenceDiagram - participant Ground Station - participant Event Log - participant Manager - participant RV3028 Manager - participant Zephyr Time API - participant RV3028 RTC - Ground Station-->>Manager: Command to set time with Drv::TimeData struct - Manager->>RV3028 Manager: Call the timeSet synchronous input port with Drv::TimeData struct - RV3028 Manager->>Zephyr Time API: Set time - Zephyr Time API->>RV3028 RTC: Set time - RV3028 RTC->>Zephyr Time API: Return device not ready - Zephyr Time API->>RV3028 Manager: Return device not ready - RV3028 Manager->>Event Log: Emit event DeviceNotReady -``` - -#### Time Not Set -```mermaid -sequenceDiagram - participant Ground Station - participant Event Log - participant Manager - participant RV3028 Manager - participant Zephyr Time API - participant RV3028 RTC - Ground Station-->>Manager: Command to set time with Drv::TimeData struct - Manager->>RV3028 Manager: Call the timeSet synchronous input port with Drv::TimeData struct - RV3028 Manager->>Zephyr Time API: Set time - Zephyr Time API->>RV3028 RTC: Set time - RV3028 RTC->>Zephyr Time API: Return set failure - Zephyr Time API->>RV3028 Manager: Return set failure - RV3028 Manager->>Event Log: Emit event TimeNotSet -``` - -## Change Log -| Date | Description | -|---|---| -| 2025-9-18 | Initial RV3028 Manager component | diff --git a/FprimeZephyrReference/Components/RtcManager/RtcManager.cpp b/FprimeZephyrReference/Components/RtcManager/RtcManager.cpp deleted file mode 100644 index 2fe41ec9..00000000 --- a/FprimeZephyrReference/Components/RtcManager/RtcManager.cpp +++ /dev/null @@ -1,52 +0,0 @@ -// ====================================================================== -// \title RtcManager.cpp -// \brief cpp file for RtcManager component implementation class -// ====================================================================== - -#include "FprimeZephyrReference/Components/RtcManager/RtcManager.hpp" -#include - -namespace Components { - -// ---------------------------------------------------------------------- -// Component construction and destruction -// ---------------------------------------------------------------------- - -RtcManager ::RtcManager(const char* const compName) : RtcManagerComponentBase(compName) {} - -RtcManager ::~RtcManager() {} - -// ---------------------------------------------------------------------- -// Handler implementations for commands -// ---------------------------------------------------------------------- - -void RtcManager ::SET_TIME_cmdHandler(FwOpcodeType opCode, U32 cmdSeq, Drv::TimeData t) { - this->timeSet_out(0, t); - this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK); -} - -void RtcManager ::GET_TIME_cmdHandler(FwOpcodeType opCode, U32 cmdSeq) { - U32 t = this->timeGet_out(0); - - // Convert POSIX time to tm struct for human readable logging - time_t time_posix = static_cast(t); - struct tm time_tm_buf; - struct tm* time_tm = gmtime_r(&time_posix, &time_tm_buf); - - // Convert to ISO format - char iso_time[32]; - int result = snprintf(iso_time, sizeof(iso_time), "%04d-%02d-%02dT%02d:%02d:%02d", time_tm->tm_year + 1900, - time_tm->tm_mon + 1, time_tm->tm_mday, time_tm->tm_hour, time_tm->tm_min, time_tm->tm_sec); - - // Ensure snprintf succeeded and output was not truncated - FW_ASSERT(sizeof(iso_time) > static_cast(result)); - - Fw::String iso_time_str(iso_time); - - // Report time retrieved in ISO format - this->log_ACTIVITY_HI_GetTime(iso_time_str); - - this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK); -} - -} // namespace Components diff --git a/FprimeZephyrReference/Components/RtcManager/RtcManager.fpp b/FprimeZephyrReference/Components/RtcManager/RtcManager.fpp deleted file mode 100644 index bb7c3921..00000000 --- a/FprimeZephyrReference/Components/RtcManager/RtcManager.fpp +++ /dev/null @@ -1,47 +0,0 @@ -module Components { - @ Manages the real time clock - passive component RtcManager { - @ SET_TIME command to set the time on the RTC - sync command SET_TIME( - t: Drv.TimeData @< Set the time - ) opcode 0 - - @ GET_TIME command to get the time from the RTC - sync command GET_TIME opcode 1 - - ############################################################################## - #### Uncomment the following examples to start customizing your component #### - ############################################################################## - - @ Event to log the time retrieved from the Rv3028Manager in ISO 8601 format - event GetTime(t: string) severity activity high id 1 format "{}" - - @ Output port to set the time on the Rv3028Manager - output port timeSet: Drv.TimeSet - - @ Output port to get the time from the Rv3028Manager - output port timeGet: Drv.TimeGet - - ############################################################################### - # Standard AC Ports: Required for Channels, Events, Commands, and Parameters # - ############################################################################### - @ Port for requesting the current time - time get port timeCaller - - @ Port for sending command registrations - command reg port cmdRegOut - - @ Port for receiving commands - command recv port cmdIn - - @ Port for sending command responses - command resp port cmdResponseOut - - @ Port for sending textual representation of events - text event port logTextOut - - @ Port for sending events to downlink - event port logOut - - } -} diff --git a/FprimeZephyrReference/Components/RtcManager/RtcManager.hpp b/FprimeZephyrReference/Components/RtcManager/RtcManager.hpp deleted file mode 100644 index 78bc7956..00000000 --- a/FprimeZephyrReference/Components/RtcManager/RtcManager.hpp +++ /dev/null @@ -1,53 +0,0 @@ -// ====================================================================== -// \title RtcManager.hpp -// \brief hpp file for RtcManager component implementation class -// ====================================================================== - -#ifndef Components_RtcManager_HPP -#define Components_RtcManager_HPP - -#include "FprimeZephyrReference/Components/RtcManager/RtcManagerComponentAc.hpp" - -#include - -namespace Components { - -class RtcManager final : public RtcManagerComponentBase { - public: - // ---------------------------------------------------------------------- - // Component construction and destruction - // ---------------------------------------------------------------------- - - //! Construct RtcManager object - RtcManager(const char* const compName //!< The component name - ); - - //! Destroy RtcManager object - ~RtcManager(); - - private: - // ---------------------------------------------------------------------- - // Handler implementations for commands - // ---------------------------------------------------------------------- - - //! Handler implementation for command SET_TIME - //! - //! SET_TIME command to set the time on the RTC - //! Requirement RtcManager-001 - void SET_TIME_cmdHandler(FwOpcodeType opCode, //!< The opcode - U32 cmdSeq, //!< The command sequence number - Drv::TimeData t //!< Set the time - ) override; - - //! Handler implementation for command GET_TIME - //! - //! GET_TIME command to get the time from the RTC - //! Requirement RtcManager-002 - void GET_TIME_cmdHandler(FwOpcodeType opCode, //!< The opcode - U32 cmdSeq //!< The command sequence number - ) override; -}; - -} // namespace Components - -#endif diff --git a/FprimeZephyrReference/Components/RtcManager/docs/sdd.md b/FprimeZephyrReference/Components/RtcManager/docs/sdd.md deleted file mode 100644 index ba67c977..00000000 --- a/FprimeZephyrReference/Components/RtcManager/docs/sdd.md +++ /dev/null @@ -1,91 +0,0 @@ -# Components::RtcManager - -The RtcManager component manages interactions with a Real Time Clock (RTC) device. It interfaces with the Rv3028Manager component to set and get the current time. - -### Typical Usage - -#### `SET_TIME` Command Usage -1. The component is instantiated and initialized during system startup -2. A ground station sends a `SET_TIME` command with the desired time -3. On each command, the component: - - Calls the `timeSet` port to set the time on the RTC device - -#### `GET_TIME` Command Usage -1. The component is instantiated and initialized during system startup -2. A ground station sends a `GET_TIME` command -3. On each command, the component: - - Calls the `timeGet` port to get the current time from the RTC device - - Emits a `GetTime` event with the retrieved time - -## Requirements -| Name | Description | Validation | -|---|---|---| -| RtcManager-001 | The RTC manager has a command that reads the time from the RTC | Manual | -| RtcManager-002 | An event with time information is emitted when time is read | Manual | -| RtcManager-003 | The RTC manager has a command that sets the time on the RTC | Manual | - -## Port Descriptions -| Name | Description | -|---|---| -| timeSet | Output port to reach out to driver to set the time | -| TimeGet | Output port to reach out to driver to read the time | - -## Commands -| Name | Description | -|---|---| -| SET_TIME | Sets the time on the RTC | -| GET_TIME | Gets the time from the RTC | - -## Events -| Name | Description | -|---|---| -| GetTime | Event to log the time retrieved from the Rv3028Manager | - -## Class Diagram -```mermaid -classDiagram - namespace Drv { - class RtcManagerComponentBase { - <> - } - class RtcManager { - + RtcManager(char* compName) - + ~RtcManager() - - void SET_TIME_cmdHandler(FwOpcodeType opCode, U32 cmdSeq, Drv::TimeData t) - - void GET_TIME_cmdHandler(FwOpcodeType opCode, U32 cmdSeq) - } - } - RtcManagerComponentBase <|-- RtcManager : inherits -``` - -## Sequence Diagrams - -### `SET_TIME` Command - -```mermaid -sequenceDiagram - participant Ground Station - participant RtcManager - participant RV3028 Manager - Ground Station-->>RtcManager: Send SET_TIME command with time data - RtcManager->>RV3028 Manager: Call timeSet port with time data -``` - -### `GET_TIME` Command - -```mermaid -sequenceDiagram - participant Ground Station - participant Event Log - participant RtcManager - participant RV3028 Manager - Ground Station-->>RtcManager: Send GET_TIME command - RtcManager->>RV3028 Manager: Call timeGet port - RV3028 Manager->>RtcManager: Return time data - RtcManager->>Event Log: Emit GetTime event with retrieved time -``` - -## Change Log -| Date | Description | -|---|---| -| 2025-9-18 | Initial RTC Manager component | diff --git a/FprimeZephyrReference/ReferenceDeployment/Top/instances.fpp b/FprimeZephyrReference/ReferenceDeployment/Top/instances.fpp index 29f74c02..afdd11a8 100644 --- a/FprimeZephyrReference/ReferenceDeployment/Top/instances.fpp +++ b/FprimeZephyrReference/ReferenceDeployment/Top/instances.fpp @@ -61,9 +61,6 @@ module ReferenceDeployment { instance watchdog: Components.Watchdog base id 0x10015000 - instance rtcManager: Components.RtcManager base id 0x10016000 - - instance rv3028Manager: Drv.Rv3028Manager base id 0x10017000 - + instance rtcManager: Drv.RtcManager base id 0x10016000 } diff --git a/FprimeZephyrReference/ReferenceDeployment/Top/topology.fpp b/FprimeZephyrReference/ReferenceDeployment/Top/topology.fpp index c6a286ba..951998a7 100644 --- a/FprimeZephyrReference/ReferenceDeployment/Top/topology.fpp +++ b/FprimeZephyrReference/ReferenceDeployment/Top/topology.fpp @@ -28,7 +28,6 @@ module ReferenceDeployment { instance gpioDriver instance watchdog instance prmDb - instance rv3028Manager instance rtcManager # ---------------------------------------------------------------------- @@ -39,7 +38,7 @@ module ReferenceDeployment { event connections instance CdhCore.events text event connections instance CdhCore.textLogger health connections instance CdhCore.$health - time connections instance rv3028Manager + time connections instance rtcManager telemetry connections instance CdhCore.tlmSend param connections instance prmDb @@ -99,15 +98,6 @@ module ReferenceDeployment { watchdog.gpioSet -> gpioDriver.gpioWrite } - connections RtcManager { - rtcManager.timeSet -> rv3028Manager.timeSet - rtcManager.timeGet -> rv3028Manager.timeGet - } - - connections ReferenceDeployment { - - } - } } diff --git a/FprimeZephyrReference/test/int/integration_test.py b/FprimeZephyrReference/test/int/integration_test.py index 48fdd32c..a3cf3426 100644 --- a/FprimeZephyrReference/test/int/integration_test.py +++ b/FprimeZephyrReference/test/int/integration_test.py @@ -1,64 +1,64 @@ -""" -integration_test.py: +# """ +# integration_test.py: -Simple integration tests for the Watchdog component. -Tests are ordered so that stop tests run last. -""" +# Simple integration tests for the Watchdog component. +# Tests are ordered so that stop tests run last. +# """ -def get_watchdog_transitions(fprime_test_api): - """Helper function to request packet and get fresh WatchdogTransitions telemetry""" - fprime_test_api.clear_histories() - fprime_test_api.send_and_assert_command("CdhCore.tlmSend.SEND_PKT", ["5"], max_delay=2) - result = fprime_test_api.assert_telemetry( - "ReferenceDeployment.watchdog.WatchdogTransitions", - start="NOW", timeout=3 - ) - return result.get_val() +# def get_watchdog_transitions(fprime_test_api): +# """Helper function to request packet and get fresh WatchdogTransitions telemetry""" +# fprime_test_api.clear_histories() +# fprime_test_api.send_and_assert_command("CdhCore.tlmSend.SEND_PKT", ["5"], max_delay=2) +# result = fprime_test_api.assert_telemetry( +# "ReferenceDeployment.watchdog.WatchdogTransitions", +# start="NOW", timeout=3 +# ) +# return result.get_val() -def test_01_watchdog_telemetry_basic(fprime_test_api): - """Test that we can read WatchdogTransitions telemetry""" - value = get_watchdog_transitions(fprime_test_api) - assert value >= 0, f"WatchdogTransitions should be >= 0, got {value}" +# def test_01_watchdog_telemetry_basic(fprime_test_api): +# """Test that we can read WatchdogTransitions telemetry""" +# value = get_watchdog_transitions(fprime_test_api) +# assert value >= 0, f"WatchdogTransitions should be >= 0, got {value}" -def test_02_watchdog_increments(fprime_test_api): - """Test that WatchdogTransitions increments over time""" - import time +# def test_02_watchdog_increments(fprime_test_api): +# """Test that WatchdogTransitions increments over time""" +# import time - initial_value = get_watchdog_transitions(fprime_test_api) - time.sleep(2.0) # Wait for watchdog to run more cycles - updated_value = get_watchdog_transitions(fprime_test_api) +# initial_value = get_watchdog_transitions(fprime_test_api) +# time.sleep(2.0) # Wait for watchdog to run more cycles +# updated_value = get_watchdog_transitions(fprime_test_api) - assert updated_value > initial_value, \ - f"WatchdogTransitions should increase. Initial: {initial_value}, Updated: {updated_value}" +# assert updated_value > initial_value, \ +# f"WatchdogTransitions should increase. Initial: {initial_value}, Updated: {updated_value}" -def test_03_stop_watchdog_command(fprime_test_api): - """Test TEST_STOP_WATCHDOG command sends and emits WatchdogStop event""" - fprime_test_api.clear_histories() +# def test_03_stop_watchdog_command(fprime_test_api): +# """Test TEST_STOP_WATCHDOG command sends and emits WatchdogStop event""" +# fprime_test_api.clear_histories() - fprime_test_api.send_and_assert_command( - "ReferenceDeployment.watchdog.TEST_STOP_WATCHDOG", - max_delay=2 - ) +# fprime_test_api.send_and_assert_command( +# "ReferenceDeployment.watchdog.TEST_STOP_WATCHDOG", +# max_delay=2 +# ) - fprime_test_api.assert_event( - "ReferenceDeployment.watchdog.WatchdogStop", - timeout=2 - ) +# fprime_test_api.assert_event( +# "ReferenceDeployment.watchdog.WatchdogStop", +# timeout=2 +# ) -def test_04_watchdog_stops_incrementing(fprime_test_api): - """Test that WatchdogTransitions stops incrementing after TEST_STOP_WATCHDOG""" - import time +# def test_04_watchdog_stops_incrementing(fprime_test_api): +# """Test that WatchdogTransitions stops incrementing after TEST_STOP_WATCHDOG""" +# import time - # Get initial value (should be from stopped watchdog from previous test) - initial_value = get_watchdog_transitions(fprime_test_api) +# # Get initial value (should be from stopped watchdog from previous test) +# initial_value = get_watchdog_transitions(fprime_test_api) - # Wait and check that it's not incrementing (watchdog should already be stopped) - time.sleep(2.0) - final_value = get_watchdog_transitions(fprime_test_api) +# # Wait and check that it's not incrementing (watchdog should already be stopped) +# time.sleep(2.0) +# final_value = get_watchdog_transitions(fprime_test_api) - assert final_value == initial_value, \ - f"Watchdog should remain stopped. Initial: {initial_value}, Final: {final_value}" +# assert final_value == initial_value, \ +# f"Watchdog should remain stopped. Initial: {initial_value}, Final: {final_value}" diff --git a/FprimeZephyrReference/test/int/rtc_test.py b/FprimeZephyrReference/test/int/rtc_test.py index c7bcd510..62f06a48 100644 --- a/FprimeZephyrReference/test/int/rtc_test.py +++ b/FprimeZephyrReference/test/int/rtc_test.py @@ -18,9 +18,7 @@ @pytest.fixture(autouse=True) def set_now_time(fprime_test_api: IntegrationTestAPI): - """Fixture to set the time to test runner's time before and after each test""" - set_time(fprime_test_api) - fprime_test_api.clear_histories() + """Fixture to set the time to test runner's time after each test""" yield set_time(fprime_test_api) fprime_test_api.clear_histories() @@ -41,57 +39,29 @@ def set_time(fprime_test_api: IntegrationTestAPI, dt: datetime = None): ) time_data_str = json.dumps(time_data) fprime_test_api.send_and_assert_command( - "ReferenceDeployment.rtcManager.SET_TIME", + "ReferenceDeployment.rtcManager.TIME_SET", [ time_data_str, ], max_delay=2, ) - fprime_test_api.assert_event("ReferenceDeployment.rv3028Manager.TimeSet", timeout=2) - - -def get_time(fprime_test_api: IntegrationTestAPI) -> datetime: - """Helper function to request packet and get fresh WatchdogTransitions telemetry""" - fprime_test_api.clear_histories() - fprime_test_api.send_and_assert_command( - "ReferenceDeployment.rtcManager.GET_TIME", max_delay=2 - ) - result: EventData = fprime_test_api.assert_event( - "ReferenceDeployment.rtcManager.GetTime", timeout=2 - ) - return datetime.fromisoformat(result.display_text) - - -def test_01_current_time_set(fprime_test_api: IntegrationTestAPI): - """Test that we can set current time""" + fprime_test_api.assert_event("ReferenceDeployment.rtcManager.TimeSet", timeout=2) - # Fetch time from fixture setting current time - event_time = get_time(fprime_test_api) - - # Assert time is within 30 seconds of now - pytest.approx(event_time, abs=30) == datetime.now(timezone.utc) - -def test_02_time_incrementing(fprime_test_api: IntegrationTestAPI): - """Test that time increments over time""" - - # Fetch initial time - initial_event_time = get_time(fprime_test_api) - - # Wait for time to increment - time.sleep(2.0) - - # Fetch updated time - updated_event_time = get_time(fprime_test_api) - - # Assert time has increased - assert updated_event_time > initial_event_time, ( - f"Time should increase. Initial: {initial_event_time}, Updated: {updated_event_time}" - ) +# def get_time(fprime_test_api: IntegrationTestAPI) -> datetime: +# """Helper function to request packet and get fresh WatchdogTransitions telemetry""" +# fprime_test_api.clear_histories() +# fprime_test_api.send_and_assert_command( +# "ReferenceDeployment.rtcManager.GET_TIME", max_delay=2 +# ) +# result: EventData = fprime_test_api.assert_event( +# "ReferenceDeployment.rtcManager.GetTime", timeout=2 +# ) +# return datetime.fromisoformat(result.display_text) -def test_03_set_time_in_past(fprime_test_api: IntegrationTestAPI): - """Test that we can set the time to a past time""" +def test_01_time_set(fprime_test_api: IntegrationTestAPI): + """Test that we can set the time""" # 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) @@ -99,7 +69,7 @@ def test_03_set_time_in_past(fprime_test_api: IntegrationTestAPI): # Fetch event data result: EventData = fprime_test_api.assert_event( - "ReferenceDeployment.rv3028Manager.TimeSet", timeout=2 + "ReferenceDeployment.rtcManager.TimeSet", timeout=2 ) # Fetch previously set time from event args @@ -108,6 +78,10 @@ def test_03_set_time_in_past(fprime_test_api: IntegrationTestAPI): event_previous_time_arg.val, tz=timezone.utc ) + # Ensure microseconds are included in event + microseconds_arg: U32Type = result.args[1] + assert 0 <= microseconds_arg.val < 100_000_000, "Microseconds arg should be >= 0 and < 1 million" + # Fetch FPrime time from event fp_time: TimeType = result.get_time() event_time = datetime.fromtimestamp(fp_time.seconds, tz=timezone.utc) @@ -118,18 +92,41 @@ def test_03_set_time_in_past(fprime_test_api: IntegrationTestAPI): # Assert event time is within 30 seconds of curiosity landing pytest.approx(event_time, abs=30) == curiosity_landing + # Fetch event data + result: EventData = fprime_test_api.assert_event( + "ReferenceDeployment.rtcManager.TimeSet", timeout=2 + ) + + # Assert time is within 30 seconds of now + pytest.approx(event_time, abs=30) == datetime.now(timezone.utc) -def test_04_time_in_telemetry(fprime_test_api: IntegrationTestAPI): - """Test that we can get Time telemetry""" - # Fetch telemetry packet +def test_02_time_incrementing(fprime_test_api: IntegrationTestAPI): + """Test that time increments over time""" + + # Fetch initial time result: ChData = fprime_test_api.assert_telemetry( "CdhCore.cmdDisp.CommandsDispatched", timeout=3 ) # Convert FPrime time to datetime fp_time: TimeType = result.time - tlm_time = datetime.fromtimestamp(fp_time.seconds, tz=timezone.utc) + initial_time = datetime.fromtimestamp(fp_time.seconds, tz=timezone.utc) - # Assert time is within 30 seconds of now - pytest.approx(tlm_time, abs=30) == datetime.now(timezone.utc) + # Wait for time to increment + fprime_test_api.clear_histories() + time.sleep(2.0) + + # Fetch updated time + result: ChData = fprime_test_api.assert_telemetry( + "CdhCore.cmdDisp.CommandsDispatched", timeout=3 + ) + + # Convert FPrime time to datetime + fp_time: TimeType = result.time + updated_time = datetime.fromtimestamp(fp_time.seconds, tz=timezone.utc) + + # Assert time has increased + assert updated_time > initial_time, ( + f"Time should increase. Initial: {initial_time}, Updated: {updated_time}" + ) From d57ed5760cf6416b135b4a0c6a6ed5084538eb66 Mon Sep 17 00:00:00 2001 From: Nate Gay Date: Mon, 29 Sep 2025 21:15:13 -0500 Subject: [PATCH 35/40] Add command failure test --- .../Components/Drv/RtcManager/docs/sdd.md | 124 +++++++----------- .../test/int/integration_test.py | 94 ++++++------- FprimeZephyrReference/test/int/rtc_test.py | 35 +++++ 3 files changed, 126 insertions(+), 127 deletions(-) diff --git a/FprimeZephyrReference/Components/Drv/RtcManager/docs/sdd.md b/FprimeZephyrReference/Components/Drv/RtcManager/docs/sdd.md index 740726da..47f64a43 100644 --- a/FprimeZephyrReference/Components/Drv/RtcManager/docs/sdd.md +++ b/FprimeZephyrReference/Components/Drv/RtcManager/docs/sdd.md @@ -4,41 +4,47 @@ The RTC Manager component interfaces with the RTC Real Time Clock (RTC) to provi ### Typical Usage -#### `timeGetPort` Port Usage +#### `TIME_SET` Command Usage 1. The component is instantiated and initialized during system startup -2. In a deployment topology, a `time connection` is made to the component's `timeGetPort` port +2. A ground station sends a `TIME_SET` command with the desired time +3. On each command, the component: + - Sets the time on the RTC + - Emits a `TimeSet` event if the time is set successfully + - Emits a `TimeNotSet` event if the time is not set successfully + - Emits a `DeviceNotReady` event if the device is not ready -#### `timeGet` Port Usage +#### `timeGetPort` Port Usage 1. The component is instantiated and initialized during system startup -2. A manager calls the `timeGet` ports +2. In a deployment topology, a `time connection` relation is made. 3. On each call, the component: - - Fetches and returns the time from the RTC RTC + - Fetches and returns the time from the RTC - Emits a `DeviceNotReady` event if the device is not ready -#### `timeSet` Port Usage +#### `timeGet` Port Usage 1. The component is instantiated and initialized during system startup -2. A manager calls the `timeSet` ports +2. A manager calls the `timeGet` ports 3. On each call, the component: - - Sets the time on the RTC RTC - - Emits a `TimeSet` event if the time is set successfully - - Emits a `TimeNotSet` event if the time is not set successfully + - Fetches and returns the time from the RTC - Emits a `DeviceNotReady` event if the device is not ready ## Requirements | Name | Description | Validation | |---|---|---| -| RtcManager-001 | Time can be set on the RTC through a port | Manual | -| RtcManager-002 | Time can be read from the RTC through a port | Manual | +| RtcManager-001 | The RTC Manager has a command that sets the time on the RTC | Integration test | +| RtcManager-002 | The RTC Manager has a port which, when called, set the time in FPrime | Integration test | | RtcManager-003 | A device not ready event is emitted if the RTC is not ready | Manual | -| RtcManager-004 | A time set event is emitted if the time is set successfully | Manual | -| RtcManager-005 | A time not set event is emitted if the time is not set successfully | Manual | +| RtcManager-004 | A time set event is emitted if the time is set successfully | Integration test | +| RtcManager-005 | A time not set event is emitted if the time is not set successfully | Integration test | ## Port Descriptions | Name | Description | |---|---| | timeGetPort | Time port for FPrime topology connection to get the time from the RTC | -| timeSet | Input port sets the time on the RTC | -| timeGet | Input port reads the time from the RTC | + +## Commands +| Name | Description | +|---|---| +| SET_TIME | Sets the time on the RTC | ## Events | Name | Description | @@ -59,8 +65,8 @@ classDiagram + RtcManager(char* compName) + ~RtcManager() - void timeGetPort_handler(FwIndexType portNum, Fw::Time& time) - - U32 timeGet_handler(FwIndexType portNum) - - void timeSet_handler(FwIndexType portNum, const Drv::TimeData& time) + - Fw::CmdResponse timeSet_cmdHandler(const FwOpcodeType opCode, const U32 cmdSeq, const Drv::TimeData& time) + - Fw::Time timeGet(U32& posix_time, U32& u_secs) } } RtcManagerComponentBase <|-- RtcManager : inherits @@ -78,11 +84,11 @@ sequenceDiagram participant Deployment Time Connection participant RTC Manager participant Zephyr Time API - participant RTC RTC + participant RTC Deployment Time Connection-->>RTC Manager: Call timeGetPort time port RTC Manager->>Zephyr Time API: Read time - Zephyr Time API->>RTC RTC: Read time - RTC RTC->>Zephyr Time API: Return time + Zephyr Time API->>RTC: Read time + RTC->>Zephyr Time API: Return time Zephyr Time API->>RTC Manager: Return time RTC Manager-->>Deployment Time Connection: Return time ``` @@ -94,70 +100,32 @@ sequenceDiagram participant Deployment Time Connection participant RTC Manager participant Zephyr Time API - participant RTC RTC + participant RTC Deployment Time Connection->>RTC Manager: Call timeGetPort time port RTC Manager->>Zephyr Time API: Read time - Zephyr Time API->>RTC RTC: Read time - RTC RTC->>Zephyr Time API: Return device not ready + Zephyr Time API->>RTC: Read time + RTC->>Zephyr Time API: Return device not ready Zephyr Time API->>RTC Manager: Return device not ready RTC Manager->>Event Log: Emit DeviceNotReady event RTC Manager->>Deployment Time Connection: Return 0 time ``` -### `timeGet` port - -The `timeGet` port is called from a manager component to get the current time from the RTC. - -#### Success -```mermaid -sequenceDiagram - participant Event Log - participant Manager - participant RTC Manager - participant Zephyr Time API - participant RTC RTC - Manager-->>RTC Manager: Call timeGet synchronous input port - RTC Manager->>Zephyr Time API: Read time - Zephyr Time API->>RTC RTC: Read time - RTC RTC->>Zephyr Time API: Return time - Zephyr Time API->>RTC Manager: Return time - RTC Manager->>Event Log: Emit event GetTime -``` - -#### Device Not Ready -```mermaid -sequenceDiagram - participant Event Log - participant Manager - participant RTC Manager - participant Zephyr Time API - participant RTC RTC - Manager-->>RTC Manager: Call timeGet synchronous input port - RTC Manager->>Zephyr Time API: Read time - Zephyr Time API->>RTC RTC: Read time - RTC RTC->>Zephyr Time API: Return device not ready - Zephyr Time API->>RTC Manager: Return device not ready - RTC Manager->>Event Log: Emit event DeviceNotReady -``` - -### `timeSet` port +### `TIME_SET` Command -The `timeSet` port is called from a manager component to set the current time on the RTC. +The `TIME_SET` command is called to set the current time on the RTC. #### Success ```mermaid sequenceDiagram participant Ground Station participant Event Log - participant Manager participant RTC Manager participant Zephyr Time API - participant RTC RTC - Ground Station-->>Manager: Command to set time with Drv::TimeData struct - Manager->>RTC Manager: Call the timeSet synchronous input port with Drv::TimeData struct + participant RTC + Ground Station-->>RTC Manager: Command to set time with Drv::TimeData struct RTC Manager->>Zephyr Time API: Set time - Zephyr Time API->>RTC RTC: Set time - RTC RTC->>Zephyr Time API: Return set success + Zephyr Time API->>RTC: Set time + RTC->>Zephyr Time API: Return set success Zephyr Time API->>RTC Manager: Return set success RTC Manager->>Event Log: Emit event TimeSet ``` @@ -167,15 +135,13 @@ sequenceDiagram sequenceDiagram participant Ground Station participant Event Log - participant Manager participant RTC Manager participant Zephyr Time API - participant RTC RTC - Ground Station-->>Manager: Command to set time with Drv::TimeData struct - Manager->>RTC Manager: Call the timeSet synchronous input port with Drv::TimeData struct + participant RTC + Ground Station-->>RTC Manager: Command to set time with Drv::TimeData struct RTC Manager->>Zephyr Time API: Set time - Zephyr Time API->>RTC RTC: Set time - RTC RTC->>Zephyr Time API: Return device not ready + Zephyr Time API->>RTC: Set time + RTC->>Zephyr Time API: Return device not ready Zephyr Time API->>RTC Manager: Return device not ready RTC Manager->>Event Log: Emit event DeviceNotReady ``` @@ -185,15 +151,13 @@ sequenceDiagram sequenceDiagram participant Ground Station participant Event Log - participant Manager participant RTC Manager participant Zephyr Time API - participant RTC RTC - Ground Station-->>Manager: Command to set time with Drv::TimeData struct - Manager->>RTC Manager: Call the timeSet synchronous input port with Drv::TimeData struct + participant RTC + Ground Station-->>RTC Manager: Command to set time with Drv::TimeData struct RTC Manager->>Zephyr Time API: Set time - Zephyr Time API->>RTC RTC: Set time - RTC RTC->>Zephyr Time API: Return set failure + Zephyr Time API->>RTC: Set time + RTC->>Zephyr Time API: Return set failure Zephyr Time API->>RTC Manager: Return set failure RTC Manager->>Event Log: Emit event TimeNotSet ``` diff --git a/FprimeZephyrReference/test/int/integration_test.py b/FprimeZephyrReference/test/int/integration_test.py index a3cf3426..48fdd32c 100644 --- a/FprimeZephyrReference/test/int/integration_test.py +++ b/FprimeZephyrReference/test/int/integration_test.py @@ -1,64 +1,64 @@ -# """ -# integration_test.py: +""" +integration_test.py: -# Simple integration tests for the Watchdog component. -# Tests are ordered so that stop tests run last. -# """ +Simple integration tests for the Watchdog component. +Tests are ordered so that stop tests run last. +""" -# def get_watchdog_transitions(fprime_test_api): -# """Helper function to request packet and get fresh WatchdogTransitions telemetry""" -# fprime_test_api.clear_histories() -# fprime_test_api.send_and_assert_command("CdhCore.tlmSend.SEND_PKT", ["5"], max_delay=2) -# result = fprime_test_api.assert_telemetry( -# "ReferenceDeployment.watchdog.WatchdogTransitions", -# start="NOW", timeout=3 -# ) -# return result.get_val() +def get_watchdog_transitions(fprime_test_api): + """Helper function to request packet and get fresh WatchdogTransitions telemetry""" + fprime_test_api.clear_histories() + fprime_test_api.send_and_assert_command("CdhCore.tlmSend.SEND_PKT", ["5"], max_delay=2) + result = fprime_test_api.assert_telemetry( + "ReferenceDeployment.watchdog.WatchdogTransitions", + start="NOW", timeout=3 + ) + return result.get_val() -# def test_01_watchdog_telemetry_basic(fprime_test_api): -# """Test that we can read WatchdogTransitions telemetry""" -# value = get_watchdog_transitions(fprime_test_api) -# assert value >= 0, f"WatchdogTransitions should be >= 0, got {value}" +def test_01_watchdog_telemetry_basic(fprime_test_api): + """Test that we can read WatchdogTransitions telemetry""" + value = get_watchdog_transitions(fprime_test_api) + assert value >= 0, f"WatchdogTransitions should be >= 0, got {value}" -# def test_02_watchdog_increments(fprime_test_api): -# """Test that WatchdogTransitions increments over time""" -# import time +def test_02_watchdog_increments(fprime_test_api): + """Test that WatchdogTransitions increments over time""" + import time -# initial_value = get_watchdog_transitions(fprime_test_api) -# time.sleep(2.0) # Wait for watchdog to run more cycles -# updated_value = get_watchdog_transitions(fprime_test_api) + initial_value = get_watchdog_transitions(fprime_test_api) + time.sleep(2.0) # Wait for watchdog to run more cycles + updated_value = get_watchdog_transitions(fprime_test_api) -# assert updated_value > initial_value, \ -# f"WatchdogTransitions should increase. Initial: {initial_value}, Updated: {updated_value}" + assert updated_value > initial_value, \ + f"WatchdogTransitions should increase. Initial: {initial_value}, Updated: {updated_value}" -# def test_03_stop_watchdog_command(fprime_test_api): -# """Test TEST_STOP_WATCHDOG command sends and emits WatchdogStop event""" -# fprime_test_api.clear_histories() +def test_03_stop_watchdog_command(fprime_test_api): + """Test TEST_STOP_WATCHDOG command sends and emits WatchdogStop event""" + fprime_test_api.clear_histories() -# fprime_test_api.send_and_assert_command( -# "ReferenceDeployment.watchdog.TEST_STOP_WATCHDOG", -# max_delay=2 -# ) + fprime_test_api.send_and_assert_command( + "ReferenceDeployment.watchdog.TEST_STOP_WATCHDOG", + max_delay=2 + ) -# fprime_test_api.assert_event( -# "ReferenceDeployment.watchdog.WatchdogStop", -# timeout=2 -# ) + fprime_test_api.assert_event( + "ReferenceDeployment.watchdog.WatchdogStop", + timeout=2 + ) -# def test_04_watchdog_stops_incrementing(fprime_test_api): -# """Test that WatchdogTransitions stops incrementing after TEST_STOP_WATCHDOG""" -# import time +def test_04_watchdog_stops_incrementing(fprime_test_api): + """Test that WatchdogTransitions stops incrementing after TEST_STOP_WATCHDOG""" + import time -# # Get initial value (should be from stopped watchdog from previous test) -# initial_value = get_watchdog_transitions(fprime_test_api) + # Get initial value (should be from stopped watchdog from previous test) + initial_value = get_watchdog_transitions(fprime_test_api) -# # Wait and check that it's not incrementing (watchdog should already be stopped) -# time.sleep(2.0) -# final_value = get_watchdog_transitions(fprime_test_api) + # Wait and check that it's not incrementing (watchdog should already be stopped) + time.sleep(2.0) + final_value = get_watchdog_transitions(fprime_test_api) -# assert final_value == initial_value, \ -# f"Watchdog should remain stopped. Initial: {initial_value}, Final: {final_value}" + assert final_value == initial_value, \ + f"Watchdog should remain stopped. Initial: {initial_value}, Final: {final_value}" diff --git a/FprimeZephyrReference/test/int/rtc_test.py b/FprimeZephyrReference/test/int/rtc_test.py index 62f06a48..5ee9c78e 100644 --- a/FprimeZephyrReference/test/int/rtc_test.py +++ b/FprimeZephyrReference/test/int/rtc_test.py @@ -130,3 +130,38 @@ def test_02_time_incrementing(fprime_test_api: IntegrationTestAPI): assert updated_time > initial_time, ( f"Time should increase. Initial: {initial_time}, Updated: {updated_time}" ) + + +def test_03_time_not_set_event(fprime_test_api: IntegrationTestAPI): + """Test that a TimeNotSet event is emitted when setting time with invalid data""" + + # Clear histories + fprime_test_api.clear_histories() + + # Send command to set the time with invalid data + time_data = dict( + Year=0, + Month=12345, # Invalid month + Day=12345, + Hour=12345, + Minute=12345, + Second=12345, + ) + time_data_str = json.dumps(time_data) + fprime_test_api.send_command( + "ReferenceDeployment.rtcManager.TIME_SET", + [ + time_data_str, + ], + ) + + # Assert time not set event is emitted + fprime_test_api.assert_event( + "ReferenceDeployment.rtcManager.TimeNotSet", timeout=2 + ) + fprime_test_api.assert_event( + "CdhCore.cmdDisp.OpCodeDispatched", timeout=2 + ) + fprime_test_api.assert_event( + "CdhCore.cmdDisp.OpCodeError", timeout=2 + ) From ae3099e04c59dbf8183a8ee6c2c9ed26aa97259b Mon Sep 17 00:00:00 2001 From: Nate Gay Date: Mon, 29 Sep 2025 21:17:55 -0500 Subject: [PATCH 36/40] Remove commented code --- FprimeZephyrReference/test/int/rtc_test.py | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/FprimeZephyrReference/test/int/rtc_test.py b/FprimeZephyrReference/test/int/rtc_test.py index 5ee9c78e..e271302d 100644 --- a/FprimeZephyrReference/test/int/rtc_test.py +++ b/FprimeZephyrReference/test/int/rtc_test.py @@ -48,18 +48,6 @@ def set_time(fprime_test_api: IntegrationTestAPI, dt: datetime = None): fprime_test_api.assert_event("ReferenceDeployment.rtcManager.TimeSet", timeout=2) -# def get_time(fprime_test_api: IntegrationTestAPI) -> datetime: -# """Helper function to request packet and get fresh WatchdogTransitions telemetry""" -# fprime_test_api.clear_histories() -# fprime_test_api.send_and_assert_command( -# "ReferenceDeployment.rtcManager.GET_TIME", max_delay=2 -# ) -# result: EventData = fprime_test_api.assert_event( -# "ReferenceDeployment.rtcManager.GetTime", timeout=2 -# ) -# return datetime.fromisoformat(result.display_text) - - def test_01_time_set(fprime_test_api: IntegrationTestAPI): """Test that we can set the time""" From fe5b6e80c466bae7efba75b2249bd995db5d6e8f Mon Sep 17 00:00:00 2001 From: Nate Gay Date: Mon, 29 Sep 2025 23:30:00 -0500 Subject: [PATCH 37/40] Stop overwriting getTime --- .../Components/Drv/RtcManager/RtcManager.cpp | 8 ++++---- .../Components/Drv/RtcManager/RtcManager.hpp | 2 +- FprimeZephyrReference/ReferenceDeployment/Main.cpp | 7 +++---- FprimeZephyrReference/test/int/rtc_test.py | 2 +- 4 files changed, 9 insertions(+), 10 deletions(-) diff --git a/FprimeZephyrReference/Components/Drv/RtcManager/RtcManager.cpp b/FprimeZephyrReference/Components/Drv/RtcManager/RtcManager.cpp index c218bedb..662790ab 100644 --- a/FprimeZephyrReference/Components/Drv/RtcManager/RtcManager.cpp +++ b/FprimeZephyrReference/Components/Drv/RtcManager/RtcManager.cpp @@ -27,14 +27,14 @@ void RtcManager ::timeGetPort_handler(FwIndexType portNum, Fw::Time& time) { if (!device_is_ready(this->dev)) { // Use logger instead of events since this fn is in a critical path for FPrime // to get time. Events require time, if this method fails an event will fail. - Fw::Logger::log("RV2038 not ready"); + Fw::Logger::log("RTC not ready"); return; } // Get time from RTC U32 posix_time; U32 u_secs; - this->getTime(posix_time, u_secs); + this->timeGet(posix_time, u_secs); // Set FPrime time object time.set(TimeBase::TB_WORKSTATION_TIME, 0, posix_time, u_secs); @@ -68,7 +68,7 @@ void RtcManager ::TIME_SET_cmdHandler(FwOpcodeType opCode, U32 cmdSeq, Drv::Time // Store current time for logging U32 posix_time; U32 u_secs; - this->getTime(posix_time, u_secs); + this->timeGet(posix_time, u_secs); // Set time on RTC const int status = rtc_set_time(this->dev, &time_rtc); @@ -93,7 +93,7 @@ void RtcManager ::TIME_SET_cmdHandler(FwOpcodeType opCode, U32 cmdSeq, Drv::Time // Private helper methods // ---------------------------------------------------------------------- -void RtcManager ::getTime(U32& posix_time, U32& u_secs) { +void RtcManager ::timeGet(U32& posix_time, U32& u_secs) { // Read time from RTC struct rtc_time time_rtc = {}; rtc_get_time(this->dev, &time_rtc); diff --git a/FprimeZephyrReference/Components/Drv/RtcManager/RtcManager.hpp b/FprimeZephyrReference/Components/Drv/RtcManager/RtcManager.hpp index 783ce01d..d1f34242 100644 --- a/FprimeZephyrReference/Components/Drv/RtcManager/RtcManager.hpp +++ b/FprimeZephyrReference/Components/Drv/RtcManager/RtcManager.hpp @@ -63,7 +63,7 @@ class RtcManager final : public RtcManagerComponentBase { // ---------------------------------------------------------------------- //! Helper method to get time from RTC - void getTime(U32& posix_time, U32& u_secs); + void timeGet(U32& posix_time, U32& u_secs); //! device stores the initialized Zephyr RTC device const struct device* dev; diff --git a/FprimeZephyrReference/ReferenceDeployment/Main.cpp b/FprimeZephyrReference/ReferenceDeployment/Main.cpp index 209a863b..e3148ff0 100644 --- a/FprimeZephyrReference/ReferenceDeployment/Main.cpp +++ b/FprimeZephyrReference/ReferenceDeployment/Main.cpp @@ -4,12 +4,11 @@ // // ====================================================================== // Used to access topology functions -// clang-format off -// Keep the includes in this order for Zephyr + #include -#include + #include -// clang-format on +#include const struct device* serial = DEVICE_DT_GET(DT_NODELABEL(cdc_acm_uart0)); diff --git a/FprimeZephyrReference/test/int/rtc_test.py b/FprimeZephyrReference/test/int/rtc_test.py index e271302d..44645d1e 100644 --- a/FprimeZephyrReference/test/int/rtc_test.py +++ b/FprimeZephyrReference/test/int/rtc_test.py @@ -129,7 +129,7 @@ def test_03_time_not_set_event(fprime_test_api: IntegrationTestAPI): # Send command to set the time with invalid data time_data = dict( Year=0, - Month=12345, # Invalid month + Month=12345, Day=12345, Hour=12345, Minute=12345, From 7287ead40ca77ac92ff624014f0564870645c0ee Mon Sep 17 00:00:00 2001 From: Nate Gay Date: Mon, 29 Sep 2025 23:46:49 -0500 Subject: [PATCH 38/40] Use fprime getTime() to get the time --- .../Components/Drv/RtcManager/RtcManager.cpp | 60 +++++++------------ .../Components/Drv/RtcManager/RtcManager.hpp | 7 --- 2 files changed, 22 insertions(+), 45 deletions(-) diff --git a/FprimeZephyrReference/Components/Drv/RtcManager/RtcManager.cpp b/FprimeZephyrReference/Components/Drv/RtcManager/RtcManager.cpp index 662790ab..743a1af6 100644 --- a/FprimeZephyrReference/Components/Drv/RtcManager/RtcManager.cpp +++ b/FprimeZephyrReference/Components/Drv/RtcManager/RtcManager.cpp @@ -32,12 +32,28 @@ void RtcManager ::timeGetPort_handler(FwIndexType portNum, Fw::Time& time) { } // Get time from RTC - U32 posix_time; - U32 u_secs; - this->timeGet(posix_time, u_secs); + struct rtc_time time_rtc = {}; + rtc_get_time(this->dev, &time_rtc); + + // Convert to generic tm struct + struct tm* time_tm = rtc_time_to_tm(&time_rtc); + + // Convert to time_t (seconds since epoch) + errno = 0; + time_t seconds = timeutil_timegm(time_tm); + if (errno == ERANGE) { + Fw::Logger::log("RTC returned invalid time"); + return; + } + + // Get microseconds from system clock cycles + // Note: RV3028 does not provide sub-second precision, so this is + // just an approximation based on system cycles. + // FPrime expects microseconds in the range [0, 999999] + uint32_t useconds = k_cyc_to_us_near32(k_cycle_get_32()) % 1000000; // Set FPrime time object - time.set(TimeBase::TB_WORKSTATION_TIME, 0, posix_time, u_secs); + time.set(TimeBase::TB_WORKSTATION_TIME, 0, static_cast(seconds), static_cast(useconds)); } // ---------------------------------------------------------------------- @@ -66,9 +82,7 @@ void RtcManager ::TIME_SET_cmdHandler(FwOpcodeType opCode, U32 cmdSeq, Drv::Time }; // Store current time for logging - U32 posix_time; - U32 u_secs; - this->timeGet(posix_time, u_secs); + Fw::Time time_before_set = this->getTime(); // Set time on RTC const int status = rtc_set_time(this->dev, &time_rtc); @@ -83,40 +97,10 @@ 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(posix_time, u_secs); + this->log_ACTIVITY_HI_TimeSet(time_before_set.getSeconds(), time_before_set.getUSeconds()); // Send command response this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK); } -// ---------------------------------------------------------------------- -// Private helper methods -// ---------------------------------------------------------------------- - -void RtcManager ::timeGet(U32& posix_time, U32& u_secs) { - // Read time from RTC - struct rtc_time time_rtc = {}; - rtc_get_time(this->dev, &time_rtc); - - // Convert time to POSIX time_t format - struct tm* time_tm = rtc_time_to_tm(&time_rtc); - - errno = 0; - time_t time_pt = timeutil_timegm(time_tm); - if (errno == ERANGE) { - Fw::Logger::log("RV2038 returned invalid time"); - return; - } - - // Get microseconds from system clock cycles - // Note: RV3028 does not provide sub-second precision, so this is - // just an approximation based on system cycles. - // FPrime expects microseconds in the range [0, 999999] - uint32_t time_usecs = k_cyc_to_us_near32(k_cycle_get_32()) % 1000000; - - // Set output parameters - posix_time = static_cast(time_pt); - u_secs = static_cast(time_usecs); -} - } // namespace Drv diff --git a/FprimeZephyrReference/Components/Drv/RtcManager/RtcManager.hpp b/FprimeZephyrReference/Components/Drv/RtcManager/RtcManager.hpp index d1f34242..3ba68fbb 100644 --- a/FprimeZephyrReference/Components/Drv/RtcManager/RtcManager.hpp +++ b/FprimeZephyrReference/Components/Drv/RtcManager/RtcManager.hpp @@ -58,13 +58,6 @@ class RtcManager final : public RtcManagerComponentBase { Drv::TimeData t //!< Set the time ) override; - // ---------------------------------------------------------------------- - // Private helper methods - // ---------------------------------------------------------------------- - - //! Helper method to get time from RTC - void timeGet(U32& posix_time, U32& u_secs); - //! device stores the initialized Zephyr RTC device const struct device* dev; }; From ad4780f5c2d0c099e9de1d4503f83cc9fe46c6d7 Mon Sep 17 00:00:00 2001 From: Nate Gay Date: Mon, 29 Sep 2025 23:51:00 -0500 Subject: [PATCH 39/40] Send command failure response if dev not ready --- FprimeZephyrReference/Components/Drv/RtcManager/RtcManager.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/FprimeZephyrReference/Components/Drv/RtcManager/RtcManager.cpp b/FprimeZephyrReference/Components/Drv/RtcManager/RtcManager.cpp index 743a1af6..3f2cafaf 100644 --- a/FprimeZephyrReference/Components/Drv/RtcManager/RtcManager.cpp +++ b/FprimeZephyrReference/Components/Drv/RtcManager/RtcManager.cpp @@ -64,6 +64,7 @@ void RtcManager ::TIME_SET_cmdHandler(FwOpcodeType opCode, U32 cmdSeq, Drv::Time // Check device readiness if (!device_is_ready(this->dev)) { this->log_WARNING_HI_DeviceNotReady(); + this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::EXECUTION_ERROR); return; } this->log_WARNING_HI_DeviceNotReady_ThrottleClear(); From 16bea0b804f6eff4b982ef9b11f22c31845c3e6a Mon Sep 17 00:00:00 2001 From: Nate Gay Date: Wed, 1 Oct 2025 19:48:18 -0500 Subject: [PATCH 40/40] Add input validation Co-authored-by: Aaron Siemsen --- .../Components/Drv/RtcManager/RtcManager.cpp | 55 ++++++++++++++++++- .../Components/Drv/RtcManager/RtcManager.fpp | 34 +++++++++++- .../Components/Drv/RtcManager/RtcManager.hpp | 10 ++++ FprimeZephyrReference/test/int/rtc_test.py | 30 ++++++++-- 4 files changed, 120 insertions(+), 9 deletions(-) diff --git a/FprimeZephyrReference/Components/Drv/RtcManager/RtcManager.cpp b/FprimeZephyrReference/Components/Drv/RtcManager/RtcManager.cpp index 3f2cafaf..65b4f3e8 100644 --- a/FprimeZephyrReference/Components/Drv/RtcManager/RtcManager.cpp +++ b/FprimeZephyrReference/Components/Drv/RtcManager/RtcManager.cpp @@ -63,12 +63,28 @@ void RtcManager ::timeGetPort_handler(FwIndexType portNum, Fw::Time& time) { void RtcManager ::TIME_SET_cmdHandler(FwOpcodeType opCode, U32 cmdSeq, Drv::TimeData t) { // Check device readiness if (!device_is_ready(this->dev)) { + // Emit device not ready event this->log_WARNING_HI_DeviceNotReady(); + + // Send command response this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::EXECUTION_ERROR); return; } this->log_WARNING_HI_DeviceNotReady_ThrottleClear(); + // Validate time data + if (!this->timeDataIsValid(t)) { + // Emit time not set event + this->log_WARNING_HI_TimeNotSet(); + + // Send command response + this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::VALIDATION_ERROR); + return; + } + + // Store current time for logging + Fw::Time time_before_set = this->getTime(); + // Populate rtc_time structure from TimeData const struct rtc_time time_rtc = { .tm_sec = static_cast(t.get_Second()), @@ -82,9 +98,6 @@ void RtcManager ::TIME_SET_cmdHandler(FwOpcodeType opCode, U32 cmdSeq, Drv::Time .tm_isdst = 0, }; - // Store current time for logging - Fw::Time time_before_set = this->getTime(); - // Set time on RTC const int status = rtc_set_time(this->dev, &time_rtc); @@ -104,4 +117,40 @@ void RtcManager ::TIME_SET_cmdHandler(FwOpcodeType opCode, U32 cmdSeq, Drv::Time this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::OK); } +bool RtcManager ::timeDataIsValid(Drv::TimeData t) { + bool valid = true; + + if (t.get_Year() < 1900) { + this->log_WARNING_HI_YearValidationFailed(t.get_Year()); + valid = false; + } + + if (t.get_Month() < 1 || t.get_Month() > 12) { + this->log_WARNING_HI_MonthValidationFailed(t.get_Month()); + valid = false; + } + + if (t.get_Day() < 1 || t.get_Day() > 31) { + this->log_WARNING_HI_DayValidationFailed(t.get_Day()); + valid = false; + } + + if (t.get_Hour() > 23) { + this->log_WARNING_HI_HourValidationFailed(t.get_Hour()); + valid = false; + } + + if (t.get_Minute() > 59) { + this->log_WARNING_HI_MinuteValidationFailed(t.get_Minute()); + valid = false; + } + + if (t.get_Second() > 59) { + this->log_WARNING_HI_SecondValidationFailed(t.get_Second()); + valid = false; + } + + return valid; +} + } // namespace Drv diff --git a/FprimeZephyrReference/Components/Drv/RtcManager/RtcManager.fpp b/FprimeZephyrReference/Components/Drv/RtcManager/RtcManager.fpp index 9149b3c0..c0876e02 100644 --- a/FprimeZephyrReference/Components/Drv/RtcManager/RtcManager.fpp +++ b/FprimeZephyrReference/Components/Drv/RtcManager/RtcManager.fpp @@ -35,13 +35,43 @@ module Drv { @ TimeSet event indicates that the time was set successfully event TimeSet( - pt: U32 @< POSIX time in seconds - u: U32 @< Microseconds + seconds: U32 @< Seconds since epoch + useconds: U32 @< Microseconds ) severity activity high id 3 format "Time set on RTC, previous time: {}.{}" @ TimeNotSet event indicates that the time was not set successfully event TimeNotSet() severity warning high id 4 format "Time not set on RTC" + @ YearValidationFailed event indicates that the provided year is invalid + event YearValidationFailed( + year: U32 @< The invalid year + ) severity warning high id 5 format "Provided year is invalid should be >= 1900: {}" + + @ MonthValidationFailed event indicates that the provided month is invalid + event MonthValidationFailed( + month: U32 @< The invalid month + ) severity warning high id 6 format "Provided month is invalid should be in [1, 12]: {}" + + @ DayValidationFailed event indicates that the provided day is invalid + event DayValidationFailed( + day: U32 @< The invalid day + ) severity warning high id 7 format "Provided day is invalid should be in [1, 31]: {}" + + @ HourValidationFailed event indicates that the provided hour is invalid + event HourValidationFailed( + hour: U32 @< The invalid hour + ) severity warning high id 8 format "Provided hour is invalid should be in [0, 23]: {}" + + @ MinuteValidationFailed event indicates that the provided minute is invalid + event MinuteValidationFailed( + minute: U32 @< The invalid minute + ) severity warning high id 9 format "Provided minute is invalid should be in [0, 59]: {}" + + @ SecondValidationFailed event indicates that the provided second is invalid + event SecondValidationFailed( + second: U32 @< The invalid second + ) severity warning high id 10 format "Provided second is invalid should be in [0, 59]: {}" + ############################################################################### # Standard AC Ports: Required for Channels, Events, Commands, and Parameters # ############################################################################### diff --git a/FprimeZephyrReference/Components/Drv/RtcManager/RtcManager.hpp b/FprimeZephyrReference/Components/Drv/RtcManager/RtcManager.hpp index 3ba68fbb..48b3467b 100644 --- a/FprimeZephyrReference/Components/Drv/RtcManager/RtcManager.hpp +++ b/FprimeZephyrReference/Components/Drv/RtcManager/RtcManager.hpp @@ -9,6 +9,8 @@ #include "FprimeZephyrReference/Components/Drv/RtcManager/RtcManagerComponentAc.hpp" #include +#include +#include #include @@ -58,6 +60,14 @@ class RtcManager final : public RtcManagerComponentBase { Drv::TimeData t //!< Set the time ) override; + private: + // ---------------------------------------------------------------------- + // Private helper methods + // ---------------------------------------------------------------------- + + //! Validate time data + bool timeDataIsValid(Drv::TimeData t); + //! device stores the initialized Zephyr RTC device const struct device* dev; }; diff --git a/FprimeZephyrReference/test/int/rtc_test.py b/FprimeZephyrReference/test/int/rtc_test.py index 44645d1e..d0770248 100644 --- a/FprimeZephyrReference/test/int/rtc_test.py +++ b/FprimeZephyrReference/test/int/rtc_test.py @@ -68,7 +68,9 @@ def test_01_time_set(fprime_test_api: IntegrationTestAPI): # Ensure microseconds are included in event microseconds_arg: U32Type = result.args[1] - assert 0 <= microseconds_arg.val < 100_000_000, "Microseconds arg should be >= 0 and < 1 million" + assert 0 <= microseconds_arg.val < 100_000_000, ( + "Microseconds arg should be >= 0 and < 1 million" + ) # Fetch FPrime time from event fp_time: TimeType = result.get_time() @@ -145,11 +147,31 @@ def test_03_time_not_set_event(fprime_test_api: IntegrationTestAPI): # Assert time not set event is emitted fprime_test_api.assert_event( - "ReferenceDeployment.rtcManager.TimeNotSet", timeout=2 + "ReferenceDeployment.rtcManager.YearValidationFailed", timeout=2 + ) + + fprime_test_api.assert_event( + "ReferenceDeployment.rtcManager.MonthValidationFailed", timeout=2 ) + fprime_test_api.assert_event( - "CdhCore.cmdDisp.OpCodeDispatched", timeout=2 + "ReferenceDeployment.rtcManager.DayValidationFailed", timeout=2 ) + fprime_test_api.assert_event( - "CdhCore.cmdDisp.OpCodeError", timeout=2 + "ReferenceDeployment.rtcManager.HourValidationFailed", timeout=2 ) + + fprime_test_api.assert_event( + "ReferenceDeployment.rtcManager.MinuteValidationFailed", timeout=2 + ) + + fprime_test_api.assert_event( + "ReferenceDeployment.rtcManager.SecondValidationFailed", timeout=2 + ) + + fprime_test_api.assert_event("ReferenceDeployment.rtcManager.TimeNotSet", timeout=2) + + fprime_test_api.assert_event("CdhCore.cmdDisp.OpCodeDispatched", timeout=2) + + fprime_test_api.assert_event("CdhCore.cmdDisp.OpCodeError", timeout=2)