mirror of
https://github.com/meshtastic/firmware.git
synced 2026-05-31 04:06:24 -04:00
87 lines
2.2 KiB
C++
87 lines
2.2 KiB
C++
#include "HapticFeedback.h"
|
|
|
|
#ifdef HAPTIC_FEEDBACK_PIN
|
|
|
|
#include <Arduino.h>
|
|
|
|
#ifdef HAPTIC_FEEDBACK_ACTIVE_LOW
|
|
#define HAPTIC_FEEDBACK_ON_STATE LOW
|
|
#define HAPTIC_FEEDBACK_OFF_STATE HIGH
|
|
#else
|
|
#define HAPTIC_FEEDBACK_ON_STATE HIGH
|
|
#define HAPTIC_FEEDBACK_OFF_STATE LOW
|
|
#endif
|
|
|
|
HapticFeedback *hapticFeedback = nullptr;
|
|
|
|
void initHapticFeedback()
|
|
{
|
|
if (!hapticFeedback)
|
|
hapticFeedback = new HapticFeedback();
|
|
}
|
|
|
|
HapticFeedback::HapticFeedback() : concurrency::OSThread("Haptic")
|
|
{
|
|
pinMode(HAPTIC_FEEDBACK_PIN, OUTPUT);
|
|
digitalWrite(HAPTIC_FEEDBACK_PIN, HAPTIC_FEEDBACK_OFF_STATE);
|
|
}
|
|
|
|
void HapticFeedback::motorWrite(bool on)
|
|
{
|
|
digitalWrite(HAPTIC_FEEDBACK_PIN, on ? HAPTIC_FEEDBACK_ON_STATE : HAPTIC_FEEDBACK_OFF_STATE);
|
|
}
|
|
|
|
void HapticFeedback::pulse(uint16_t durationMs)
|
|
{
|
|
motorWrite(true);
|
|
pulseOffAt = millis() + durationMs;
|
|
if (pulseOffAt == 0) // disambiguate from "no pulse active" sentinel on millis() wrap
|
|
pulseOffAt = 1;
|
|
setIntervalFromNow(durationMs);
|
|
}
|
|
|
|
void HapticFeedback::armDelayedPulse(uint16_t delayMs, uint16_t durationMs)
|
|
{
|
|
delayedPulseAt = millis() + delayMs;
|
|
if (delayedPulseAt == 0)
|
|
delayedPulseAt = 1;
|
|
delayedPulseDuration = durationMs;
|
|
setIntervalFromNow(delayMs);
|
|
}
|
|
|
|
void HapticFeedback::cancelDelayedPulse()
|
|
{
|
|
delayedPulseAt = 0;
|
|
}
|
|
|
|
int32_t HapticFeedback::runOnce()
|
|
{
|
|
uint32_t now = millis();
|
|
|
|
// End an in-flight pulse if its time has come.
|
|
if (pulseOffAt != 0 && (int32_t)(now - pulseOffAt) >= 0) {
|
|
motorWrite(false);
|
|
pulseOffAt = 0;
|
|
}
|
|
|
|
// Fire an armed delayed pulse if its time has come.
|
|
if (delayedPulseAt != 0 && (int32_t)(now - delayedPulseAt) >= 0) {
|
|
uint16_t dur = delayedPulseDuration;
|
|
delayedPulseAt = 0;
|
|
pulse(dur);
|
|
}
|
|
|
|
// Sleep until the next scheduled event, or idle long if nothing pending.
|
|
uint32_t next = 0;
|
|
if (pulseOffAt != 0)
|
|
next = pulseOffAt;
|
|
if (delayedPulseAt != 0 && (next == 0 || (int32_t)(delayedPulseAt - next) < 0))
|
|
next = delayedPulseAt;
|
|
if (next == 0)
|
|
return 60 * 1000; // nothing pending — idle for a minute
|
|
int32_t delay = (int32_t)(next - now);
|
|
return delay > 0 ? delay : 0;
|
|
}
|
|
|
|
#endif // HAPTIC_FEEDBACK_PIN
|