-
Notifications
You must be signed in to change notification settings - Fork 964
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* T1000-E Peripherals - enable intelligent charge controller signals - enable Accelerometer - enable internal I2C bus - provide Power to Accelerometer * POC Accelerometer Code (wakeScreen is moot for that device, just test if the driver works) * fix building without the sensor
- Loading branch information
Showing
14 changed files
with
306 additions
and
22 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -39,6 +39,7 @@ class ScanI2C | |
QMC5883L, | ||
HMC5883L, | ||
PMSA0031, | ||
QMA6100P, | ||
MPU6050, | ||
LIS3DH, | ||
BMA423, | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,183 @@ | ||
#include "QMA6100PSensor.h" | ||
|
||
#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_I2C && HAS_QMA6100P | ||
|
||
// Flag when an interrupt has been detected | ||
volatile static bool QMA6100P_IRQ = false; | ||
|
||
// Interrupt service routine | ||
void QMA6100PSetInterrupt() | ||
{ | ||
QMA6100P_IRQ = true; | ||
} | ||
|
||
QMA6100PSensor::QMA6100PSensor(ScanI2C::FoundDevice foundDevice) : MotionSensor::MotionSensor(foundDevice) {} | ||
|
||
bool QMA6100PSensor::init() | ||
{ | ||
// Initialise the sensor | ||
sensor = QMA6100PSingleton::GetInstance(); | ||
if (!sensor->init(device)) | ||
return false; | ||
|
||
// Enable simple Wake on Motion | ||
return sensor->setWakeOnMotion(); | ||
} | ||
|
||
#ifdef QMA_6100P_INT_PIN | ||
|
||
int32_t QMA6100PSensor::runOnce() | ||
{ | ||
// Wake on motion using hardware interrupts - this is the most efficient way to check for motion | ||
if (QMA6100P_IRQ) { | ||
QMA6100P_IRQ = false; | ||
wakeScreen(); | ||
} | ||
return MOTION_SENSOR_CHECK_INTERVAL_MS; | ||
} | ||
|
||
#else | ||
|
||
int32_t QMA6100PSensor::runOnce() | ||
{ | ||
// Wake on motion using polling - this is not as efficient as using hardware interrupt pin (see above) | ||
|
||
uint8_t tempVal; | ||
if (!sensor->readRegisterRegion(SFE_QMA6100P_INT_ST0, &tempVal, 1)) { | ||
LOG_DEBUG("QMA6100PSensor::isWakeOnMotion failed to read interrupts"); | ||
return MOTION_SENSOR_CHECK_INTERVAL_MS; | ||
} | ||
|
||
if ((tempVal & 7) != 0) { | ||
// Wake up! | ||
wakeScreen(); | ||
} | ||
return MOTION_SENSOR_CHECK_INTERVAL_MS; | ||
} | ||
|
||
#endif | ||
|
||
// ---------------------------------------------------------------------- | ||
// QMA6100PSingleton | ||
// ---------------------------------------------------------------------- | ||
|
||
// Get a singleton wrapper for an Sparkfun QMA_6100P_I2C | ||
QMA6100PSingleton *QMA6100PSingleton::GetInstance() | ||
{ | ||
if (pinstance == nullptr) { | ||
pinstance = new QMA6100PSingleton(); | ||
} | ||
return pinstance; | ||
} | ||
|
||
QMA6100PSingleton::QMA6100PSingleton() {} | ||
|
||
QMA6100PSingleton::~QMA6100PSingleton() {} | ||
|
||
QMA6100PSingleton *QMA6100PSingleton::pinstance{nullptr}; | ||
|
||
// Initialise the QMA6100P Sensor | ||
bool QMA6100PSingleton::init(ScanI2C::FoundDevice device) | ||
{ | ||
|
||
// startup | ||
#ifdef Wire1 | ||
bool status = begin(device.address.address, device.address.port == ScanI2C::I2CPort::WIRE1 ? &Wire1 : &Wire); | ||
#else | ||
// check chip id | ||
bool status = begin(device.address.address, &Wire); | ||
#endif | ||
if (status != true) { | ||
LOG_WARN("QMA6100PSensor::init begin failed\n"); | ||
return false; | ||
} | ||
delay(20); | ||
// SW reset to make sure the device starts in a known state | ||
if (softwareReset() != true) { | ||
LOG_WARN("QMA6100PSensor::init reset failed\n"); | ||
return false; | ||
} | ||
delay(20); | ||
// Set range | ||
if (!setRange(QMA_6100P_MPU_ACCEL_SCALE)) { | ||
LOG_WARN("QMA6100PSensor::init range failed"); | ||
return false; | ||
} | ||
// set active mode | ||
if (!enableAccel()) { | ||
LOG_WARN("ERROR :QMA6100PSensor::active mode set failed"); | ||
} | ||
// set calibrateoffsets | ||
if (!calibrateOffsets()) { | ||
LOG_WARN("ERROR :QMA6100PSensor:: calibration failed"); | ||
} | ||
#ifdef QMA_6100P_INT_PIN | ||
|
||
// Active low & Open Drain | ||
uint8_t tempVal; | ||
if (!readRegisterRegion(SFE_QMA6100P_INTPINT_CONF, &tempVal, 1)) { | ||
LOG_WARN("QMA6100PSensor::init failed to read interrupt pin config"); | ||
return false; | ||
} | ||
|
||
tempVal |= 0b00000010; // Active low & Open Drain | ||
|
||
if (!writeRegisterByte(SFE_QMA6100P_INTPINT_CONF, tempVal)) { | ||
LOG_WARN("QMA6100PSensor::init failed to write interrupt pin config"); | ||
return false; | ||
} | ||
|
||
// Latch until cleared, all reads clear the latch | ||
if (!readRegisterRegion(SFE_QMA6100P_INT_CFG, &tempVal, 1)) { | ||
LOG_WARN("QMA6100PSensor::init failed to read interrupt config"); | ||
return false; | ||
} | ||
|
||
tempVal |= 0b10000001; // Latch until cleared, INT_RD_CLR1 | ||
|
||
if (!writeRegisterByte(SFE_QMA6100P_INT_CFG, tempVal)) { | ||
LOG_WARN("QMA6100PSensor::init failed to write interrupt config"); | ||
return false; | ||
} | ||
// Set up an interrupt pin with an internal pullup for active low | ||
pinMode(QMA_6100P_INT_PIN, INPUT_PULLUP); | ||
|
||
// Set up an interrupt service routine | ||
attachInterrupt(QMA_6100P_INT_PIN, QMA6100PSetInterrupt, FALLING); | ||
|
||
#endif | ||
return true; | ||
} | ||
|
||
bool QMA6100PSingleton::setWakeOnMotion() | ||
{ | ||
// Enable 'Any Motion' interrupt | ||
if (!writeRegisterByte(SFE_QMA6100P_INT_EN2, 0b00000111)) { | ||
LOG_WARN("QMA6100PSingleton::setWakeOnMotion failed to write interrupt enable"); | ||
return false; | ||
} | ||
|
||
// Set 'Significant Motion' interrupt map to INT1 | ||
uint8_t tempVal; | ||
|
||
if (!readRegisterRegion(SFE_QMA6100P_INT_MAP1, &tempVal, 1)) { | ||
LOG_WARN("QMA6100PSingleton::setWakeOnMotion failed to read interrupt map"); | ||
return false; | ||
} | ||
|
||
sfe_qma6100p_int_map1_bitfield_t int_map1; | ||
int_map1.all = tempVal; | ||
int_map1.bits.int1_any_mot = 1; // any motion interrupt to INT1 | ||
tempVal = int_map1.all; | ||
|
||
if (!writeRegisterByte(SFE_QMA6100P_INT_MAP1, tempVal)) { | ||
LOG_WARN("QMA6100PSingleton::setWakeOnMotion failed to write interrupt map"); | ||
return false; | ||
} | ||
|
||
// Clear any current interrupts | ||
QMA6100P_IRQ = false; | ||
return true; | ||
} | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
#pragma once | ||
#ifndef _QMA_6100P_SENSOR_H_ | ||
#define _QMA_6100P_SENSOR_H_ | ||
|
||
#include "MotionSensor.h" | ||
|
||
#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_I2C && HAS_QMA6100P | ||
|
||
#include <QMA6100P.h> | ||
|
||
// Set the default accelerometer scale - gpm2, gpm4, gpm8, gpm16 | ||
#ifndef QMA_6100P_MPU_ACCEL_SCALE | ||
#define QMA_6100P_MPU_ACCEL_SCALE SFE_QMA6100P_RANGE32G | ||
#endif | ||
|
||
// The I2C address of the Accelerometer (if found) from main.cpp | ||
extern ScanI2C::DeviceAddress accelerometer_found; | ||
|
||
// Singleton wrapper for the Sparkfun QMA_6100P_I2C class | ||
class QMA6100PSingleton : public QMA6100P | ||
{ | ||
private: | ||
static QMA6100PSingleton *pinstance; | ||
|
||
protected: | ||
QMA6100PSingleton(); | ||
~QMA6100PSingleton(); | ||
|
||
public: | ||
// Create a singleton instance (not thread safe) | ||
static QMA6100PSingleton *GetInstance(); | ||
|
||
// Singletons should not be cloneable. | ||
QMA6100PSingleton(QMA6100PSingleton &other) = delete; | ||
|
||
// Singletons should not be assignable. | ||
void operator=(const QMA6100PSingleton &) = delete; | ||
|
||
// Initialise the motion sensor singleton for normal operation | ||
bool init(ScanI2C::FoundDevice device); | ||
|
||
// Enable Wake on Motion interrupts (sensor must be initialised first) | ||
bool setWakeOnMotion(); | ||
}; | ||
|
||
class QMA6100PSensor : public MotionSensor | ||
{ | ||
private: | ||
QMA6100PSingleton *sensor = nullptr; | ||
|
||
public: | ||
explicit QMA6100PSensor(ScanI2C::FoundDevice foundDevice); | ||
|
||
// Initialise the motion sensor | ||
virtual bool init() override; | ||
|
||
// Called each time our sensor gets a chance to run | ||
virtual int32_t runOnce() override; | ||
}; | ||
|
||
#endif | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.