Skip to main content

Folder Structure

The OSSM firmware follows a modular, feature-based architecture. Each feature lives in its own namespace folder, making the codebase easier to navigate and maintain.
Browse the source code on GitHub: Software/src/

Overview

Software
src
main.cpp
ossm
services
components
constants
structs
utils
extensions
test
platformio.ini
FolderPurpose
include/boost/Header-only libraries (Boost.SML state machine)
lib/StrokeEngine/Motion pattern library (modified)
src/Main source code
test/Unit tests

Design Philosophy

The firmware uses a feature-based organization where related code lives together:
  • Namespaces over classes - Features are organized as namespace functions rather than class methods
  • Co-located files - Each feature’s header, implementation, and related code live in the same folder
  • Global state structs - Shared state is managed through dedicated state structs rather than class members
  • Stateless modules - Feature functions operate on global state, making them easier to test and reason about
The OSSM class in ossm/OSSM.h is retained for backward compatibility with BLE command handling. New features should use stateless namespace functions.

Core Application (src/ossm/)

The ossm/ folder contains the core application logic, organized by feature.
ossm
Events.h
OSSM.h
OSSM.cpp
state
pages
homing
menu
simple_penetration
stroke_engine
pattern_controls
play_controls
FolderPurpose
state/State machine architecture
pages/UI screens
homing/Homing sequence
menu/Menu navigation
simple_penetration/Simple Penetration mode
stroke_engine/Stroke Engine mode
pattern_controls/Pattern selection UI
play_controls/Play/pause/speed controls

State Machine (ossm/state/)

The state machine components are separated for clarity and testability.
FilePurpose
machine.hTransition table definition using Boost.SML
actions.h / actions.cppState transition actions (display updates, motor control)
guards.h / guards.cppConditional checks for transitions
state.h / state.cppState machine initialization and global instance
State structs manage different aspects of the application:
FilePurpose
session.hCurrent session (start time, stroke count, distance)
settings.hUser settings (speed, stroke, sensation, depth, pattern)
calibration.hHoming state (sensor offset, stroke steps, homed status)
motion.hMotion targets (position, velocity, time)
menu.hCurrent menu selection
ble.hBluetooth connection state
error.hError messages
For details on how the state machine works, see State Machine Architecture.

UI Pages (ossm/pages/)

Each screen in the user interface has its own module.
ModuleDescription
hello.hBoot splash screen with animated logos
preflight.h”Reduce speed to start” safety check screen
error.hError display with help option
update.hOTA update screens (checking, updating, no update)
wifi.hWiFi configuration portal
help.hHelp and support information

Operating Modes

Each operating mode is a self-contained module with its motion control logic.
ModuleDescription
simple_penetration/Basic back-and-forth motion at controlled speed
stroke_engine/Complex patterns using the StrokeEngine library

Control UIs

ModuleDescription
menu/Main menu navigation and rendering
pattern_controls/Pattern selection interface for Stroke Engine mode
play_controls/Speed, stroke, depth, and sensation controls

Feature Modules

ModuleDescription
homing/Homing sequence (forward scan, backward scan, calibration)

Hardware Services (src/services/)

The services/ folder provides hardware abstraction layers.
services
stepper.h
stepper.cpp
display.h
display.cpp
encoder.h
encoder.cpp
led.h
led.cpp
board.h
board.cpp
tasks.h
tasks.cpp
wm.h
wm.cpp
communication
nimble.h
nimble.cpp
queue.h
queue.cpp
command.hpp
state.hpp
patterns.hpp
gpio.hpp
wifi.hpp
config.hpp
FilePurpose
stepper.h/.cppMotor control (FastAccelStepper)
display.h/.cppOLED display (U8g2)
encoder.h/.cppRotary encoder input
led.h/.cppRGB LED status indication
board.h/.cppBoard initialization
tasks.h/.cppFreeRTOS task management
wm.h/.cppWiFi Manager
communication/BLE and WiFi communication
For BLE protocol details, see BLE Communication.

Constants (src/constants/)

Configuration values and enums are centralized in the constants/ folder.
constants
Config.h
Pins.h
Menu.h
Version.h
UserConfig.h
Images.h
LogTags.h
FilePurpose
Config.hSystem configuration (speeds, limits, timeouts)
Pins.hGPIO pin definitions
Menu.hMenu option enum
Version.hFirmware version information
UserConfig.hUser-configurable settings
Images.hDisplay bitmap assets
LogTags.hESP-IDF logging tags
copy/Localized strings
For configuration options, see Configuration.

Utilities (src/utils/)

Helper functions and classes used throughout the codebase.
utils
StateLogger.h
RecursiveMutex.h
StrokeEngineHelper.h
format.h
analog.h
update.h
ble.h
FilePurpose
StateLogger.hLogs state machine transitions for debugging
RecursiveMutex.hThread-safe mutex wrapper for ESP32
StrokeEngineHelper.hStrokeEngine integration utilities
format.hString formatting helpers
analog.hAnalog input averaging and processing
update.hOTA update utilities
ble.hBLE helper functions

Data Structures (src/structs/)

Shared data types used across modules.
structs
SettingPercents.h
LanguageStruct.h
Points.h
FilePurpose
SettingPercents.hUser settings as percentages (0-100)
LanguageStruct.hLanguage configuration
Points.hCoordinate and point structures

Libraries

Boost.SML (include/boost/sml.hpp)

Boost.SML is a header-only state machine library. It’s included directly in the project for version stability.

StrokeEngine (lib/StrokeEngine/)

A modified version of theelims/StrokeEngine that generates motion patterns. The library is vendored and customized for OSSM-specific requirements.

Build Configuration

The platformio.ini file defines build environments:
EnvironmentPurpose
developmentLocal development with debug logging
stagingPre-release testing
productionRelease builds with optimizations
testUnit test configuration

Further Reading