Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
11 changes: 11 additions & 0 deletions .clang-format
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
BasedOnStyle: LLVM
ColumnLimit: 100
BinPackArguments: false
BinPackParameters: false
AllowAllArgumentsOnNextLine: false
AlignAfterOpenBracket: BlockIndent
UseTab: ForIndentation
IndentWidth: 4
TabWidth: 4
ContinuationIndentWidth: 4
AllowShortFunctionsOnASingleLine: None
11 changes: 11 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
root = true

[*]
end_of_line = lf
insert_final_newline = true
charset = utf-8

[*.{c,cc,cpp,h,hpp,ino}]
indent_style = tab
indent_size = tab
tab_width = 4
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
.venv
build/
build_prev_runner/
.vscode
19 changes: 19 additions & 0 deletions .vscode/bin/clang-format
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#!/usr/bin/env bash

set -euo pipefail

if command -v clang-format >/dev/null 2>&1; then
exec clang-format "$@"
fi

_home_dir="${HOME:-}"
if [ -n "$_home_dir" ]; then
_candidate="$(ls -1d "$_home_dir"/.vscode/extensions/ms-vscode.cpptools-*-linux-x64/LLVM/bin/clang-format 2>/dev/null | tail -n 1 || true)"
if [ -n "$_candidate" ] && [ -x "$_candidate" ]; then
exec "$_candidate" "$@"
fi
fi

echo "clang-format executable not found." >&2
echo "Install clang-format system-wide or install/update ms-vscode.cpptools." >&2
exit 127
9 changes: 9 additions & 0 deletions .vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"recommendations": [
"pioarduino.pioarduino-ide",
"xaver.clang-format"
],
"unwantedRecommendations": [
"ms-vscode.cpptools-extension-pack"
]
}
30 changes: 30 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"files.associations": {
"*.ino": "cpp"
},
"editor.defaultFormatter": "xaver.clang-format",
"C_Cpp.formatting": "Disabled",
"clang-format.style": "file",
"clang-format.executable": "${workspaceRoot}/.vscode/bin/clang-format",
"[cpp]": {
"editor.defaultFormatter": "xaver.clang-format",
"editor.detectIndentation": false,
"editor.insertSpaces": false,
"editor.tabSize": 4,
"editor.formatOnSave": true
},
"[c]": {
"editor.defaultFormatter": "xaver.clang-format",
"editor.detectIndentation": false,
"editor.insertSpaces": false,
"editor.tabSize": 4,
"editor.formatOnSave": true
},
"[arduino]": {
"editor.defaultFormatter": "xaver.clang-format",
"editor.detectIndentation": false,
"editor.insertSpaces": false,
"editor.tabSize": 4,
"editor.formatOnSave": true
}
}
12 changes: 12 additions & 0 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "Format Firmware Sources",
"type": "shell",
"command": "bash ${workspaceFolder}/scripts/format_cpp.sh",
"group": "build",
"problemMatcher": []
}
]
}
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,13 @@ Stack sizes are expressed in bytes.
## Tests
Unity-based smoke tests live in `test/test_basic`. Drop the folder into your PlatformIO workspace (or add your own `platformio.ini` at the repo root) and run `pio test -e esp32dev` against an ESP32 dev kit. The test harness is Arduino friendly and exercises every timer type.

## Formatting Baseline

This repository follows the firmware formatting baseline from `esptoolkit-template`:
- `.clang-format` is the source of truth for C/C++/INO layout.
- `.editorconfig` enforces tabs (`tab_width = 4`), LF endings, and final newline.
- Format all tracked firmware sources with `bash scripts/format_cpp.sh`.

## License
MIT — see [LICENSE.md](LICENSE.md).

Expand Down
121 changes: 66 additions & 55 deletions examples/Basic/Basic.ino
Original file line number Diff line number Diff line change
Expand Up @@ -2,77 +2,88 @@
#include <Arduino.h>
#include <ESPTimer.h>

ESPTimer timer; // Create your own instance
ESPTimer timer; // Create your own instance
volatile bool shouldDeinit = false;

void setup() {
Serial.begin(115200);
delay(500);
Serial.begin(115200);
delay(500);

ESPTimerConfig cfg; // defaults are fine
timer.init(cfg);
ESPTimerConfig cfg; // defaults are fine
timer.init(cfg);

// Triggers once
uint32_t t1 = timer.setTimeout([]() {
Serial.println("1.5 sec is timed out!");
}, 1500);
// Triggers once
uint32_t t1 = timer.setTimeout([]() { Serial.println("1.5 sec is timed out!"); }, 1500);

// Retriggers every 1500ms
uint32_t t2 = timer.setInterval([]() {
Serial.println("1.5 sec is triggered!");
}, 1500);
// Retriggers every 1500ms
uint32_t t2 = timer.setInterval([]() { Serial.println("1.5 sec is triggered!"); }, 1500);

// Called every sec for 10000 ms
uint32_t t3 = timer.setSecCounter([](int secLeft) {
Serial.printf("%d sec left so far\n", secLeft);
}, 10000);
// Called every sec for 10000 ms
uint32_t t3 = timer.setSecCounter(
[](int secLeft) { Serial.printf("%d sec left so far\n", secLeft); },
10000
);

// Called every ms for 10000 ms
uint32_t t4 = timer.setMsCounter([](uint32_t msLeft) {
if (msLeft % 1000 == 0) {
Serial.printf("%lu ms left so far\n", static_cast<unsigned long>(msLeft));
}
}, 10000);
// Called every ms for 10000 ms
uint32_t t4 = timer.setMsCounter(
[](uint32_t msLeft) {
if (msLeft % 1000 == 0) {
Serial.printf("%lu ms left so far\n", static_cast<unsigned long>(msLeft));
}
},
10000
);

// Called every min for 10000 ms
uint32_t t5 = timer.setMinCounter([](int minLeft) {
Serial.printf("%d min left so far\n", minLeft);
}, 10000);
// Called every min for 10000 ms
uint32_t t5 = timer.setMinCounter(
[](int minLeft) { Serial.printf("%d min left so far\n", minLeft); },
10000
);

// Example: pause then resume interval, then clear
timer.setTimeout([t2]() {
bool paused = timer.pauseInterval(t2); // pause only
Serial.printf("Interval paused: %s\n", paused ? "ok" : "fail");
}, 5000);
// Example: pause then resume interval, then clear
timer.setTimeout(
[t2]() {
bool paused = timer.pauseInterval(t2); // pause only
Serial.printf("Interval paused: %s\n", paused ? "ok" : "fail");
},
5000
);

timer.setTimeout([t2]() {
bool resumed = timer.resumeInterval(t2);
Serial.printf("Interval resumed: %s\n", resumed ? "ok" : "fail");
}, 8000);
timer.setTimeout(
[t2]() {
bool resumed = timer.resumeInterval(t2);
Serial.printf("Interval resumed: %s\n", resumed ? "ok" : "fail");
},
8000
);

timer.setTimeout([t2]() {
bool cleared = timer.clearInterval(t2);
Serial.printf("Interval cleared: %s\n", cleared ? "ok" : "fail");
}, 12000);
timer.setTimeout(
[t2]() {
bool cleared = timer.clearInterval(t2);
Serial.printf("Interval cleared: %s\n", cleared ? "ok" : "fail");
},
12000
);

// Check status example
timer.setTimeout([t1]() {
auto s = timer.getStatus(t1);
Serial.printf("Timeout status: %d\n", static_cast<int>(s));
}, 2000);
// Check status example
timer.setTimeout(
[t1]() {
auto s = timer.getStatus(t1);
Serial.printf("Timeout status: %d\n", static_cast<int>(s));
},
2000
);

// Request teardown from loop context (not from timer worker tasks).
timer.setTimeout([]() {
shouldDeinit = true;
}, 15000);
// Request teardown from loop context (not from timer worker tasks).
timer.setTimeout([]() { shouldDeinit = true; }, 15000);
}

void loop() {
if (shouldDeinit && timer.isInitialized()) {
timer.deinit();
shouldDeinit = false;
Serial.println("Timer runtime deinitialized");
}
if (shouldDeinit && timer.isInitialized()) {
timer.deinit();
shouldDeinit = false;
Serial.println("Timer runtime deinitialized");
}

// App code does other things; timers run in background FreeRTOS tasks
// App code does other things; timers run in background FreeRTOS tasks
}
87 changes: 46 additions & 41 deletions examples/PauseResume/PauseResume.ino
Original file line number Diff line number Diff line change
Expand Up @@ -8,48 +8,53 @@ volatile bool shouldDeinit = false;
uint32_t intervalId;

void setup() {
Serial.begin(115200);
delay(500);

timer.init();

intervalId = timer.setInterval([]() {
Serial.println("Tick from interval");
}, 1000);

// Pause after 3s
timer.setTimeout([]() {
bool ok = timer.pauseInterval(intervalId);
Serial.printf("Paused interval: %s\n", ok ? "ok" : "fail");
auto s = timer.getStatus(intervalId);
Serial.printf("Status now: %d (Paused=2)\n", (int)s);
}, 3000);

// Resume after 6s
timer.setTimeout([]() {
bool ok = timer.resumeInterval(intervalId);
Serial.printf("Resumed interval: %s\n", ok ? "ok" : "fail");
auto s = timer.getStatus(intervalId);
Serial.printf("Status now: %d (Running=1)\n", (int)s);
}, 6000);

// Clear after 10s
timer.setTimeout([]() {
bool ok = timer.clearInterval(intervalId);
Serial.printf("Cleared interval: %s\n", ok ? "ok" : "fail");
auto s = timer.getStatus(intervalId);
Serial.printf("Status now: %d (Invalid=0 if removed)\n", (int)s);
}, 10000);

timer.setTimeout([]() {
shouldDeinit = true;
}, 12000);
Serial.begin(115200);
delay(500);

timer.init();

intervalId = timer.setInterval([]() { Serial.println("Tick from interval"); }, 1000);

// Pause after 3s
timer.setTimeout(
[]() {
bool ok = timer.pauseInterval(intervalId);
Serial.printf("Paused interval: %s\n", ok ? "ok" : "fail");
auto s = timer.getStatus(intervalId);
Serial.printf("Status now: %d (Paused=2)\n", (int)s);
},
3000
);

// Resume after 6s
timer.setTimeout(
[]() {
bool ok = timer.resumeInterval(intervalId);
Serial.printf("Resumed interval: %s\n", ok ? "ok" : "fail");
auto s = timer.getStatus(intervalId);
Serial.printf("Status now: %d (Running=1)\n", (int)s);
},
6000
);

// Clear after 10s
timer.setTimeout(
[]() {
bool ok = timer.clearInterval(intervalId);
Serial.printf("Cleared interval: %s\n", ok ? "ok" : "fail");
auto s = timer.getStatus(intervalId);
Serial.printf("Status now: %d (Invalid=0 if removed)\n", (int)s);
},
10000
);

timer.setTimeout([]() { shouldDeinit = true; }, 12000);
}

void loop() {
if (shouldDeinit && timer.isInitialized()) {
timer.deinit();
shouldDeinit = false;
Serial.println("ESPTimer deinitialized");
}
if (shouldDeinit && timer.isInitialized()) {
timer.deinit();
shouldDeinit = false;
Serial.println("ESPTimer deinitialized");
}
}
24 changes: 24 additions & 0 deletions scripts/format_cpp.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#!/usr/bin/env bash

set -euo pipefail

_repo_root="$(git rev-parse --show-toplevel 2>/dev/null || pwd)"
_clang_format="${_repo_root}/.vscode/bin/clang-format"

if [ ! -x "${_clang_format}" ]; then
echo "clang-format wrapper not found: ${_clang_format}" >&2
exit 1
fi

mapfile -d '' _format_files < <(
git -C "${_repo_root}" ls-files -z -- '*.c' '*.cc' '*.cpp' '*.h' '*.hpp' '*.ino'
)

if [ "${#_format_files[@]}" -eq 0 ]; then
echo "No tracked C/C++/INO files found to format."
exit 0
fi

"${_clang_format}" -i --style=file "${_format_files[@]}"

echo "Formatted ${#_format_files[@]} files."
Loading