mirror of
https://github.com/pelgraine/Meck.git
synced 2026-07-05 17:21:22 +02:00
81 lines
2.8 KiB
C++
81 lines
2.8 KiB
C++
#pragma once
|
|
|
|
#include <Arduino.h>
|
|
#include <Wire.h>
|
|
|
|
// Minimal inline DRV2605 haptic driver for the T-Deck Pro MAX.
|
|
//
|
|
// The DRV2605 sits on the shared Wire bus at I2C 0x5A. Its motor supply is
|
|
// gated by the XL9555 expander (board.motorEnable()), which MUST be switched on
|
|
// before begin() or the device will not ACK.
|
|
//
|
|
// The register sequence mirrors Adafruit_DRV2605::begin() followed by
|
|
// selectLibrary(1) + setMode(INTTRIG) - i.e. exactly what the LilyGo basic.ino
|
|
// example does: an ERM motor, open-loop, internal-trigger, effect library 1.
|
|
class DRV2605Haptic {
|
|
public:
|
|
DRV2605Haptic(uint8_t addr = 0x5A, TwoWire* wire = &Wire)
|
|
: _addr(addr), _wire(wire) {}
|
|
|
|
// Returns false if the DRV2605 does not ACK (e.g. motor rail still off).
|
|
bool begin() {
|
|
_wire->beginTransmission(_addr);
|
|
if (_wire->endTransmission() != 0) return false;
|
|
|
|
writeReg(REG_MODE, 0x00); // exit standby, internal trigger
|
|
writeReg(REG_RTPIN, 0x00); // no real-time playback input
|
|
writeReg(REG_WAVESEQ1, 1); // default effect: strong click
|
|
writeReg(REG_WAVESEQ2, 0); // end of sequence
|
|
writeReg(REG_OVERDRIVE, 0);
|
|
writeReg(REG_SUSTAINPOS, 0);
|
|
writeReg(REG_SUSTAINNEG, 0);
|
|
writeReg(REG_BREAK, 0);
|
|
writeReg(REG_AUDIOMAX, 0x64);
|
|
writeReg(REG_FEEDBACK, readReg(REG_FEEDBACK) & 0x7F); // N_ERM_LRA = 0 -> ERM
|
|
writeReg(REG_CONTROL3, readReg(REG_CONTROL3) | 0x20); // ERM_OPEN_LOOP = 1
|
|
writeReg(REG_LIBRARY, 1); // ERM effect library 1
|
|
writeReg(REG_MODE, 0x00); // internal trigger
|
|
return true;
|
|
}
|
|
|
|
// Fire a single library effect (1 = strong click, 100%).
|
|
void buzz(uint8_t effect = 1) {
|
|
writeReg(REG_WAVESEQ1, effect);
|
|
writeReg(REG_WAVESEQ2, 0);
|
|
writeReg(REG_GO, 1);
|
|
}
|
|
|
|
private:
|
|
static const uint8_t REG_MODE = 0x01;
|
|
static const uint8_t REG_RTPIN = 0x02;
|
|
static const uint8_t REG_LIBRARY = 0x03;
|
|
static const uint8_t REG_WAVESEQ1 = 0x04;
|
|
static const uint8_t REG_WAVESEQ2 = 0x05;
|
|
static const uint8_t REG_GO = 0x0C;
|
|
static const uint8_t REG_OVERDRIVE = 0x0D;
|
|
static const uint8_t REG_SUSTAINPOS = 0x0E;
|
|
static const uint8_t REG_SUSTAINNEG = 0x0F;
|
|
static const uint8_t REG_BREAK = 0x10;
|
|
static const uint8_t REG_AUDIOMAX = 0x13;
|
|
static const uint8_t REG_FEEDBACK = 0x1A;
|
|
static const uint8_t REG_CONTROL3 = 0x1D;
|
|
|
|
uint8_t _addr;
|
|
TwoWire* _wire;
|
|
|
|
void writeReg(uint8_t reg, uint8_t val) {
|
|
_wire->beginTransmission(_addr);
|
|
_wire->write(reg);
|
|
_wire->write(val);
|
|
_wire->endTransmission();
|
|
}
|
|
|
|
uint8_t readReg(uint8_t reg) {
|
|
_wire->beginTransmission(_addr);
|
|
_wire->write(reg);
|
|
_wire->endTransmission(false);
|
|
_wire->requestFrom(_addr, (uint8_t)1);
|
|
return _wire->available() ? _wire->read() : 0;
|
|
}
|
|
};
|