Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
a563640
Add load switch component
kevinthegreat1 Oct 9, 2025
5d5648f
Fix tables
kevinthegreat1 Oct 23, 2025
8f00e03
Sarah Kevin MoMata Squad Load Switch
hyuncat Oct 23, 2025
628fcbe
Sarah Kevin and MoMata fixed a bug
hyuncat Oct 23, 2025
91b25fe
Commit farming
hyuncat Oct 23, 2025
076bf65
Added mcp23017 to v5 dtsi
moisesmata Oct 23, 2025
24a2e97
Rough initial implementation + add to topology
moisesmata Oct 23, 2025
3761180
Ion even know any mane
moisesmata Oct 23, 2025
bcb6f24
Merged in Main
Mikefly123 Nov 3, 2025
3fec032
Working Device Tree (But F Prime Crash)
Mikefly123 Nov 3, 2025
09c61fd
Update CommandDispatcherImplCfg.hpp
Mikefly123 Nov 3, 2025
b5544e7
Update Submodules
moisesmata Nov 4, 2025
5351c58
Revert "Update Submodules"
Mikefly123 Nov 5, 2025
46e6604
Add Reset port functionality
moisesmata Nov 6, 2025
98326f2
Add remaining load switch instances
kevinthegreat1 Nov 6, 2025
9c72d7a
Small updates to extra loadSwitch instances, update max packets
moisesmata Nov 6, 2025
d7fce15
Remove output read port, add output write port
moisesmata Nov 6, 2025
c633bf9
add magnetorquer component
hrfarmer Nov 6, 2025
b456c1d
switch to use new device initialization pattern
hrfarmer Nov 6, 2025
7ee7e14
increase command limit
hrfarmer Nov 7, 2025
bdb6202
update dtsi
hrfarmer Nov 7, 2025
d476593
update everything to handle multiple devices initialized
hrfarmer Nov 7, 2025
42106ed
Merge branch 'load-switch' into magnetorquer
hrfarmer Nov 7, 2025
194a67a
Hello World
Mikefly123 Nov 7, 2025
4558004
bump thread count and switch to use DT_NODELABEL
hrfarmer Nov 11, 2025
30f9f13
switch to using 5 drv2605 and define wip function to set magnetorquers
hrfarmer Nov 11, 2025
62fa54d
sdd
hrfarmer Nov 11, 2025
c257d68
Merge branch 'main' into magnetorquer
hrfarmer Nov 11, 2025
9d8554f
format
hrfarmer Nov 11, 2025
211446c
i cant spell
hrfarmer Nov 11, 2025
c4970a7
Merge branch 'main' into magnetorquer
hrfarmer Nov 13, 2025
91e55ef
thx git
hrfarmer Nov 13, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions FprimeZephyrReference/Components/Drv/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/Lis2mdlManager/")
add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/Lsm6dsoManager/")
add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/RtcManager")
add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/Types/")
add_fprime_subdirectory("${CMAKE_CURRENT_LIST_DIR}/MagnetorquerManager/")
Original file line number Diff line number Diff line change
@@ -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}/MagnetorquerManager.fpp"
SOURCES
"${CMAKE_CURRENT_LIST_DIR}/MagnetorquerManager.cpp"
# DEPENDS
# MyPackage_MyOtherModule
)

### Unit Tests ###
# register_fprime_ut(
# AUTOCODER_INPUTS
# "${CMAKE_CURRENT_LIST_DIR}/MagnetorquerManager.fpp"
# SOURCES
# "${CMAKE_CURRENT_LIST_DIR}/test/ut/MagnetorquerManagerTestMain.cpp"
# "${CMAKE_CURRENT_LIST_DIR}/test/ut/MagnetorquerManagerTester.cpp"
# DEPENDS
# STest # For rules-based testing
# UT_AUTO_HELPERS
# )
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
// ======================================================================
// \title MagnetorquerManager.cpp
// \author aychar
// \brief cpp file for MagnetorquerManager component implementation class
// ======================================================================

#include "FprimeZephyrReference/Components/Drv/MagnetorquerManager/MagnetorquerManager.hpp"

#include <zephyr/drivers/haptics/drv2605.h>
#include <zephyr/kernel.h>

namespace Drv {

// ----------------------------------------------------------------------
// Component construction and destruction
// ----------------------------------------------------------------------

MagnetorquerManager ::MagnetorquerManager(const char* const compName) : MagnetorquerManagerComponentBase(compName) {}

MagnetorquerManager ::~MagnetorquerManager() {}

// ----------------------------------------------------------------------
// Helper methods
// ----------------------------------------------------------------------

void MagnetorquerManager ::configure(const struct device* const devices[5]) {
for (int i = 0; i < 5; ++i) {
this->m_devices[i] = devices[i];
}
}

void MagnetorquerManager ::START_PLAYBACK_TEST_cmdHandler(FwOpcodeType opCode, U32 cmdSeq, U8 faceIdx) {
// Validate face index (0..4)
if (faceIdx >= 5) {
this->log_WARNING_LO_InvalidFaceIndex();
return;
}

const struct device* dev = this->m_devices[faceIdx];
if (!device_is_ready(dev)) {
this->log_WARNING_HI_DeviceNotReady();
return;
}

drv2605_haptic_config(dev, DRV2605_HAPTICS_SOURCE_ROM, (union drv2605_config_data*)&this->rom);
}

void MagnetorquerManager ::START_PLAYBACK_TEST2_cmdHandler(FwOpcodeType opCode, U32 cmdSeq, U8 faceIdx) {
// Validate face index (0..4)
if (faceIdx >= 5) {
this->log_WARNING_LO_InvalidFaceIndex();
return;
}

const struct device* dev = this->m_devices[faceIdx];
if (!device_is_ready(dev)) {
this->log_WARNING_HI_DeviceNotReady();
return;
}

struct drv2605_rom_data rom2 = {.library = DRV2605_LIBRARY_TS2200_A, .seq_regs = {50, 0, 0, 0, 0, 0, 0, 0}};
drv2605_haptic_config(dev, DRV2605_HAPTICS_SOURCE_ROM, (union drv2605_config_data*)&rom2);
}

void MagnetorquerManager ::SetMagnetorquers_handler(const FwIndexType portNum, const Drv::InputArray& value) {
// TODO(hrfarmer): Once its possible to properly interact with the DRV2605, I'll figure out how to
// determine how the passed in amps should translate to a specific pattern(s) that should be ran.
return;
}

} // namespace Drv
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
module Drv {
array InputArray = [5] I32;
port SetMagnetorquers(
value: InputArray @< Amp value for each face in the order x1, x2, y1, y2, z1
)
}

module Drv {
@ Component for F Prime FSW framework.
passive component MagnetorquerManager {

@ Event for reporting DRV2605 not ready error
event DeviceNotReady() severity warning high format "DRV2605 device not ready" throttle 5

@ Event to report an invalid face index passed in
event InvalidFaceIndex() severity warning low format "The faceIdx should be between 0-4"

@ Start DRV2605 playback on a device with effect #47 on a specific face
@ faceIdx: index of the face to actuate (valid range: 0..4)
sync command START_PLAYBACK_TEST(faceIdx: U8)

@ Start DRV2605 playback on a device with effect #50 on a specific face
@ faceIdx: index of the face to actuate (valid range: 0..4)
sync command START_PLAYBACK_TEST2(faceIdx: U8)

@ Input port to set magnetorquer values
sync input port SetMagnetorquers: SetMagnetorquers

###############################################################################
# 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

@ Port for sending telemetry channels to downlink
telemetry port tlmOut

@ Port to return the value of a parameter
param get port prmGetOut

@Port to set the value of a parameter
param set port prmSetOut

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// ======================================================================
// \title MagnetorquerManager.hpp
// \author aychar
// \brief hpp file for MagnetorquerManager component implementation class
// ======================================================================

#ifndef Drv_MagnetorquerManager_HPP
#define Drv_MagnetorquerManager_HPP

#include "FprimeZephyrReference/Components/Drv/MagnetorquerManager/MagnetorquerManagerComponentAc.hpp"
#include <zephyr/device.h>
#include <zephyr/drivers/haptics/drv2605.h>
#include <zephyr/drivers/sensor.h>
#include <zephyr/kernel.h>

namespace Drv {

class MagnetorquerManager final : public MagnetorquerManagerComponentBase {
public:
// ----------------------------------------------------------------------
// Component construction and destruction
// ----------------------------------------------------------------------

//! Construct MagnetorquerManager object
MagnetorquerManager(const char* const compName //!< The component name
);

//! Destroy MagnetorquerManager object
~MagnetorquerManager();

//! Configure the DRV2605 device
// Accept an array of six pointers to const device objects. The pointers themselves are const
// to match callers that provide const device* const* types.
void configure(const struct device* const devices[5]);

private:
//! Zephyr device to store initialized DRV2605 devices
const struct device* m_devices[5];
struct drv2605_rom_data rom = {.library = DRV2605_LIBRARY_TS2200_A, .seq_regs = {47, 0, 0, 0, 0, 0, 0, 0}};

// Command handlers updated to accept a face index (0..5)
void START_PLAYBACK_TEST_cmdHandler(FwOpcodeType opCode, U32 cmdSeq, U8 faceIdx) override;
void START_PLAYBACK_TEST2_cmdHandler(FwOpcodeType opCode, U32 cmdSeq, U8 faceIdx) override;

void SetMagnetorquers_handler(const FwIndexType portNum, const Drv::InputArray& value) override;
};

} // namespace Drv

#endif
134 changes: 134 additions & 0 deletions FprimeZephyrReference/Components/Drv/MagnetorquerManager/docs/sdd.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
# Drv::MagnetorquerManager

The Magnetorquer Manager component interfaces with the five DRV2605 devices on a PROVES CubeSat to control the current of the magnetorquers.

## Usage Examples

This component is designed to be used by the detumble service to be able to detumble the cubesat when launched.

### Diagrams

```mermaid
graph LR
A[Detumble Service] -->|SetMagnetorquers| B[MagnetorquerManager]
B -->|Configure| C[DRV2605 Device 0<br/>X1 Face]
B -->|Configure| D[DRV2605 Device 1<br/>X2 Face]
B -->|Configure| E[DRV2605 Device 2<br/>Y1 Face]
B -->|Configure| F[DRV2605 Device 3<br/>Y2 Face]
B -->|Configure| G[DRV2605 Device 4<br/>Z1 Face]
```

### Typical Usage

1. The component is instantiated and initialized during system startup
2. The detumble service calls the `SetMagnetorquers` input port.
3. On each call, the component:
- Takes in an `InputArray` parameter of 5 I32 for the amps for each face.
- Translates the passed in values to a sequence value from the DRV2605 library.
- Runs the sequence for each device.

## Class Diagram

```mermaid
classDiagram
class MagnetorquerManager {
-device* m_devices[5]
+configure(devices[5])
+SetMagnetorquers_handler(portNum, value)
+START_PLAYBACK_TEST_cmdHandler(opCode, cmdSeq, faceIdx)
+START_PLAYBACK_TEST2_cmdHandler(opCode, cmdSeq, faceIdx)
}

class MagnetorquerManagerComponentBase {
<<F' Component Base>>
}

class DRV2605 {
<<Zephyr Driver>>
+device_is_ready()
+drv2605_haptic_config()
}

MagnetorquerManager --|> MagnetorquerManagerComponentBase
MagnetorquerManager --> DRV2605 : uses (5 devices)
```

## Port Descriptions

| Name | Description |
| ---------------- | ------------------------------------------------------------------------------------------- |
| SetMagnetorquers | Input port that takes in an array (I32[5]) and applies each value to the corresponding face |

## Sequence Diagrams

### SetMagnetorquers Operation

```mermaid
sequenceDiagram
participant DS as Detumble Service
participant MM as MagnetorquerManager
participant DRV as DRV2605 Devices

DS->>MM: SetMagnetorquers([x1, x2, y1, y2, z1])
Note over MM: Validate input array
Note over MM: Translate amps to sequences
loop For each face (0-4)
MM->>DRV: Check device_is_ready()
alt Device Ready
MM->>DRV: drv2605_haptic_config(sequence)
else Device Not Ready
MM->>MM: log_WARNING_HI_DeviceNotReady()
end
end
MM-->>DS: Return
```

### Test Command Operation

```mermaid
sequenceDiagram
participant GS as Ground Station
participant MM as MagnetorquerManager
participant DRV as DRV2605 Device

GS->>MM: START_PLAYBACK_TEST(faceIdx)
MM->>MM: Validate faceIdx (0-4)
alt Invalid faceIdx
MM->>MM: log_WARNING_LO_InvalidFaceIndex()
else Valid faceIdx
MM->>DRV: device_is_ready()
alt Device Ready
MM->>DRV: drv2605_haptic_config(effect #47)
else Device Not Ready
MM->>MM: log_WARNING_HI_DeviceNotReady()
end
end
MM-->>GS: Command Response
```

## Commands

| Name | Description |
| -------------------- | ------------------------------------------------------------------------------------------------ |
| START_PLAYBACK_TEST | Start DRV2605 playback on a device with effect #47 on a specific face (faceIdx: 0-4). Test only. |
| START_PLAYBACK_TEST2 | Start DRV2605 playback on a device with effect #50 on a specific face (faceIdx: 0-4). Test only. |

## Events

| Name | Description |
| ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
| DeviceNotReady | Output whenever a magnetorquer is attempted to be used while it is not initialized. |
| InvalidFaceIndex | Output whenever one of the manual test comamands are ran with an invalid face index (will be removed if/when the test commands are removed) |

## Requirements

Add requirements in the chart below
| Name | Description | Validation |
|---|---|---|
|---|---|---|

## Change Log

| Date | Description |
| ---------- | ------------- |
| 11/11/2025 | Initial Draft |
Loading
Loading