Add Heltec mesh node t1 (#10416)
* add heltec-mesh-node-t1 * fixed low power * Update the sensor enumeration values. Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * Fix memory leak in ICM42607PSensor * fix ST7735_MISO error --------- Co-authored-by: Ben Meadors <benmmeadors@gmail.com> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
co-authored by
GitHub
Ben Meadors
Copilot Autofix powered by AI
parent
d3c7f05baa
commit
60303968bb
@@ -0,0 +1,54 @@
|
|||||||
|
{
|
||||||
|
"build": {
|
||||||
|
"arduino": {
|
||||||
|
"ldscript": "nrf52840_s140_v6.ld"
|
||||||
|
},
|
||||||
|
"core": "nRF5",
|
||||||
|
"cpu": "cortex-m4",
|
||||||
|
"extra_flags": "-DNRF52840_XXAA",
|
||||||
|
"f_cpu": "64000000L",
|
||||||
|
"hwids": [
|
||||||
|
["0x239A", "0x4405"],
|
||||||
|
["0x239A", "0x0029"],
|
||||||
|
["0x239A", "0x002A"],
|
||||||
|
["0x2886", "0x1667"]
|
||||||
|
],
|
||||||
|
"usb_product": "HT-n5262",
|
||||||
|
"mcu": "nrf52840",
|
||||||
|
"variant": "heltec_mesh_node_t1",
|
||||||
|
"variants_dir": "variants",
|
||||||
|
"bsp": {
|
||||||
|
"name": "adafruit"
|
||||||
|
},
|
||||||
|
"softdevice": {
|
||||||
|
"sd_flags": "-DS140",
|
||||||
|
"sd_name": "s140",
|
||||||
|
"sd_version": "6.1.1",
|
||||||
|
"sd_fwid": "0x00B6"
|
||||||
|
},
|
||||||
|
"bootloader": {
|
||||||
|
"settings_addr": "0xFF000"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"connectivity": ["bluetooth"],
|
||||||
|
"debug": {
|
||||||
|
"jlink_device": "nRF52840_xxAA",
|
||||||
|
"onboard_tools": ["jlink"],
|
||||||
|
"svd_path": "nrf52840.svd",
|
||||||
|
"openocd_target": "nrf52840-mdk-rs"
|
||||||
|
},
|
||||||
|
"frameworks": ["arduino"],
|
||||||
|
"name": "Heltec Mesh Node T1",
|
||||||
|
"upload": {
|
||||||
|
"maximum_ram_size": 248832,
|
||||||
|
"maximum_size": 815104,
|
||||||
|
"speed": 115200,
|
||||||
|
"protocol": "nrfutil",
|
||||||
|
"protocols": ["jlink", "nrfjprog", "nrfutil", "stlink"],
|
||||||
|
"use_1200bps_touch": true,
|
||||||
|
"require_upload_port": true,
|
||||||
|
"wait_for_upload_port": true
|
||||||
|
},
|
||||||
|
"url": "https://heltec.org",
|
||||||
|
"vendor": "Heltec"
|
||||||
|
}
|
||||||
@@ -186,12 +186,16 @@ lib_deps =
|
|||||||
https://github.com/sparkfun/SparkFun_MAX3010x_Sensor_Library/archive/refs/tags/v1.1.2.zip
|
https://github.com/sparkfun/SparkFun_MAX3010x_Sensor_Library/archive/refs/tags/v1.1.2.zip
|
||||||
# renovate: datasource=github-tags depName=SparkFun 9DoF IMU Breakout ICM 20948 packageName=sparkfun/SparkFun_ICM-20948_ArduinoLibrary
|
# renovate: datasource=github-tags depName=SparkFun 9DoF IMU Breakout ICM 20948 packageName=sparkfun/SparkFun_ICM-20948_ArduinoLibrary
|
||||||
https://github.com/sparkfun/SparkFun_ICM-20948_ArduinoLibrary/archive/refs/tags/v1.3.2.zip
|
https://github.com/sparkfun/SparkFun_ICM-20948_ArduinoLibrary/archive/refs/tags/v1.3.2.zip
|
||||||
|
# renovate: datasource=github-tags depName=TDK InvenSense ICM42670P packageName=tdk-invn-oss/motion.arduino.ICM42670P
|
||||||
|
https://github.com/tdk-invn-oss/motion.arduino.ICM42670P/archive/refs/tags/1.0.8.zip
|
||||||
# renovate: datasource=github-tags depName=Adafruit LTR390 Library packageName=adafruit/Adafruit_LTR390
|
# renovate: datasource=github-tags depName=Adafruit LTR390 Library packageName=adafruit/Adafruit_LTR390
|
||||||
https://github.com/adafruit/Adafruit_LTR390/archive/refs/tags/1.1.2.zip
|
https://github.com/adafruit/Adafruit_LTR390/archive/refs/tags/1.1.2.zip
|
||||||
# renovate: datasource=github-tags depName=Adafruit PCT2075 packageName=adafruit/Adafruit_PCT2075
|
# renovate: datasource=github-tags depName=Adafruit PCT2075 packageName=adafruit/Adafruit_PCT2075
|
||||||
https://github.com/adafruit/Adafruit_PCT2075/archive/refs/tags/1.0.6.zip
|
https://github.com/adafruit/Adafruit_PCT2075/archive/refs/tags/1.0.6.zip
|
||||||
# renovate: datasource=github-tags depName=DFRobot_BMM150 packageName=dfrobot/DFRobot_BMM150
|
# renovate: datasource=github-tags depName=DFRobot_BMM150 packageName=dfrobot/DFRobot_BMM150
|
||||||
https://github.com/DFRobot/DFRobot_BMM150/archive/refs/tags/V1.0.0.zip
|
https://github.com/DFRobot/DFRobot_BMM150/archive/refs/tags/V1.0.0.zip
|
||||||
|
# renovate: datasource=github-tags depName=SparkFun MMC5983MA Magnetometer packageName=sparkfun/SparkFun_MMC5983MA_Magnetometer_Arduino_Library
|
||||||
|
https://github.com/sparkfun/SparkFun_MMC5983MA_Magnetometer_Arduino_Library/archive/refs/tags/v1.1.4.zip
|
||||||
# renovate: datasource=github-tags depName=Adafruit_TSL2561 packageName=adafruit/Adafruit_TSL2561
|
# renovate: datasource=github-tags depName=Adafruit_TSL2561 packageName=adafruit/Adafruit_TSL2561
|
||||||
https://github.com/adafruit/Adafruit_TSL2561/archive/refs/tags/1.1.3.zip
|
https://github.com/adafruit/Adafruit_TSL2561/archive/refs/tags/1.1.3.zip
|
||||||
# renovate: datasource=github-tags depName=BH1750_WE packageName=wollewald/BH1750_WE
|
# renovate: datasource=github-tags depName=BH1750_WE packageName=wollewald/BH1750_WE
|
||||||
|
|||||||
@@ -243,6 +243,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||||||
#define QMI8658_ADDR 0x6B
|
#define QMI8658_ADDR 0x6B
|
||||||
#define QMC5883L_ADDR 0x0D
|
#define QMC5883L_ADDR 0x0D
|
||||||
#define HMC5883L_ADDR 0x1E
|
#define HMC5883L_ADDR 0x1E
|
||||||
|
#define MMC5983MA_ADDR 0x30
|
||||||
#define SHTC3_ADDR 0x70
|
#define SHTC3_ADDR 0x70
|
||||||
#define LPS22HB_ADDR 0x5C
|
#define LPS22HB_ADDR 0x5C
|
||||||
#define LPS22HB_ADDR_ALT 0x5D
|
#define LPS22HB_ADDR_ALT 0x5D
|
||||||
@@ -292,6 +293,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||||||
#define DA217_ADDR 0x26
|
#define DA217_ADDR 0x26
|
||||||
#define BMI270_ADDR 0x68
|
#define BMI270_ADDR 0x68
|
||||||
#define BMI270_ADDR_ALT 0x69
|
#define BMI270_ADDR_ALT 0x69
|
||||||
|
#define ICM42607P_ADDR 0x68
|
||||||
|
#define ICM42607P_ADDR_ALT 0x69
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// LED
|
// LED
|
||||||
|
|||||||
@@ -37,8 +37,15 @@ ScanI2C::FoundDevice ScanI2C::firstKeyboard() const
|
|||||||
|
|
||||||
ScanI2C::FoundDevice ScanI2C::firstAccelerometer() const
|
ScanI2C::FoundDevice ScanI2C::firstAccelerometer() const
|
||||||
{
|
{
|
||||||
ScanI2C::DeviceType types[] = {MPU6050, LIS3DH, BMA423, LSM6DS3, BMX160, STK8BAXX, ICM20948, QMA6100P, BMM150, BMI270};
|
ScanI2C::DeviceType types[] = {MPU6050, LIS3DH, BMA423, LSM6DS3, BMX160, STK8BAXX,
|
||||||
return firstOfOrNONE(10, types);
|
ICM20948, QMA6100P, BMM150, BMI270, ICM42607P};
|
||||||
|
return firstOfOrNONE(11, types);
|
||||||
|
}
|
||||||
|
|
||||||
|
ScanI2C::FoundDevice ScanI2C::firstMagnetometer() const
|
||||||
|
{
|
||||||
|
ScanI2C::DeviceType types[] = {MMC5983MA};
|
||||||
|
return firstOfOrNONE(1, types);
|
||||||
}
|
}
|
||||||
|
|
||||||
ScanI2C::FoundDevice ScanI2C::firstAQI() const
|
ScanI2C::FoundDevice ScanI2C::firstAQI() const
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ class ScanI2C
|
|||||||
QMI8658,
|
QMI8658,
|
||||||
QMC5883L,
|
QMC5883L,
|
||||||
HMC5883L,
|
HMC5883L,
|
||||||
|
MMC5983MA,
|
||||||
PMSA003I,
|
PMSA003I,
|
||||||
QMA6100P,
|
QMA6100P,
|
||||||
MPU6050,
|
MPU6050,
|
||||||
@@ -65,6 +66,7 @@ class ScanI2C
|
|||||||
FT6336U,
|
FT6336U,
|
||||||
STK8BAXX,
|
STK8BAXX,
|
||||||
ICM20948,
|
ICM20948,
|
||||||
|
ICM42607P,
|
||||||
SCD4X,
|
SCD4X,
|
||||||
MAX30102,
|
MAX30102,
|
||||||
TPS65233,
|
TPS65233,
|
||||||
@@ -149,6 +151,8 @@ class ScanI2C
|
|||||||
|
|
||||||
FoundDevice firstAccelerometer() const;
|
FoundDevice firstAccelerometer() const;
|
||||||
|
|
||||||
|
FoundDevice firstMagnetometer() const;
|
||||||
|
|
||||||
FoundDevice firstAQI() const;
|
FoundDevice firstAQI() const;
|
||||||
|
|
||||||
FoundDevice firstRGBLED() const;
|
FoundDevice firstRGBLED() const;
|
||||||
|
|||||||
@@ -360,9 +360,6 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize)
|
|||||||
SCAN_SIMPLE_CASE(ST7567_ADDRESS, SCREEN_ST7567, "ST7567", (uint8_t)addr.address);
|
SCAN_SIMPLE_CASE(ST7567_ADDRESS, SCREEN_ST7567, "ST7567", (uint8_t)addr.address);
|
||||||
#ifdef HAS_NCP5623
|
#ifdef HAS_NCP5623
|
||||||
SCAN_SIMPLE_CASE(NCP5623_ADDR, NCP5623, "NCP5623", (uint8_t)addr.address);
|
SCAN_SIMPLE_CASE(NCP5623_ADDR, NCP5623, "NCP5623", (uint8_t)addr.address);
|
||||||
#endif
|
|
||||||
#ifdef HAS_LP5562
|
|
||||||
SCAN_SIMPLE_CASE(LP5562_ADDR, LP5562, "LP5562", (uint8_t)addr.address);
|
|
||||||
#endif
|
#endif
|
||||||
case XPOWERS_AXP192_AXP2101_ADDRESS:
|
case XPOWERS_AXP192_AXP2101_ADDRESS:
|
||||||
// Do we have the axp2101/192 or the TCA8418
|
// Do we have the axp2101/192 or the TCA8418
|
||||||
@@ -600,6 +597,18 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize)
|
|||||||
#else
|
#else
|
||||||
SCAN_SIMPLE_CASE(PMSA003I_ADDR, PMSA003I, "PMSA003I", (uint8_t)addr.address)
|
SCAN_SIMPLE_CASE(PMSA003I_ADDR, PMSA003I, "PMSA003I", (uint8_t)addr.address)
|
||||||
#endif
|
#endif
|
||||||
|
case MMC5983MA_ADDR:
|
||||||
|
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x2F), 1);
|
||||||
|
if (registerValue == 0x30) {
|
||||||
|
type = MMC5983MA;
|
||||||
|
logFoundDevice("MMC5983MA", (uint8_t)addr.address);
|
||||||
|
#ifdef HAS_LP5562
|
||||||
|
} else {
|
||||||
|
type = LP5562;
|
||||||
|
logFoundDevice("LP5562", (uint8_t)addr.address);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
break;
|
||||||
case BMA423_ADDR: // this can also be LIS3DH_ADDR_ALT
|
case BMA423_ADDR: // this can also be LIS3DH_ADDR_ALT
|
||||||
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x0F), 2);
|
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x0F), 2);
|
||||||
if (registerValue == 0x3300 || registerValue == 0x3333) { // RAK4631 WisBlock has LIS3DH register at 0x3333
|
if (registerValue == 0x3300 || registerValue == 0x3333) { // RAK4631 WisBlock has LIS3DH register at 0x3333
|
||||||
@@ -754,8 +763,8 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ICM20948_ADDR: // same as BMX160_ADDR, BMI270_ADDR_ALT, and SEN5X_ADDR
|
case ICM20948_ADDR: // same as BMX160_ADDR, BMI270_ADDR_ALT, ICM42607P_ADDR_ALT, and SEN5X_ADDR
|
||||||
case ICM20948_ADDR_ALT: // same as MPU6050_ADDR, BMI270_ADDR
|
case ICM20948_ADDR_ALT: // same as MPU6050_ADDR, BMI270_ADDR, and ICM42607P_ADDR
|
||||||
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x00), 1);
|
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x00), 1);
|
||||||
#ifdef HAS_ICM20948
|
#ifdef HAS_ICM20948
|
||||||
type = ICM20948;
|
type = ICM20948;
|
||||||
@@ -775,6 +784,12 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize)
|
|||||||
logFoundDevice("BMX160", (uint8_t)addr.address);
|
logFoundDevice("BMX160", (uint8_t)addr.address);
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
|
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x75), 1); // WHO_AM_I
|
||||||
|
if (registerValue == 0x60) {
|
||||||
|
type = ICM42607P;
|
||||||
|
logFoundDevice("ICM-42607-P", (uint8_t)addr.address);
|
||||||
|
break;
|
||||||
|
}
|
||||||
#if HAS_TELEMETRY && !MESHTASTIC_EXCLUDE_AIR_QUALITY_SENSOR
|
#if HAS_TELEMETRY && !MESHTASTIC_EXCLUDE_AIR_QUALITY_SENSOR
|
||||||
String prod = "";
|
String prod = "";
|
||||||
prod = readSEN5xProductName(i2cBus, addr.address);
|
prod = readSEN5xProductName(i2cBus, addr.address);
|
||||||
|
|||||||
@@ -1458,7 +1458,8 @@ void TFTDisplay::sendCommand(uint8_t com)
|
|||||||
digitalWrite(portduino_config.displayBacklight.pin, TFT_BACKLIGHT_ON);
|
digitalWrite(portduino_config.displayBacklight.pin, TFT_BACKLIGHT_ON);
|
||||||
#elif defined(HACKADAY_COMMUNICATOR)
|
#elif defined(HACKADAY_COMMUNICATOR)
|
||||||
tft->displayOn();
|
tft->displayOn();
|
||||||
#elif !defined(RAK14014) && !defined(M5STACK) && !defined(UNPHONE) && !defined(HELTEC_MESH_NODE_T096)
|
#elif !defined(RAK14014) && !defined(M5STACK) && !defined(UNPHONE) && !defined(HELTEC_MESH_NODE_T096) && \
|
||||||
|
!defined(HELTEC_MESH_NODE_T1)
|
||||||
tft->wakeup();
|
tft->wakeup();
|
||||||
tft->powerSaveOff();
|
tft->powerSaveOff();
|
||||||
#endif
|
#endif
|
||||||
@@ -1469,7 +1470,7 @@ void TFTDisplay::sendCommand(uint8_t com)
|
|||||||
#ifdef UNPHONE
|
#ifdef UNPHONE
|
||||||
unphone.backlight(true); // using unPhone library
|
unphone.backlight(true); // using unPhone library
|
||||||
#endif
|
#endif
|
||||||
#if defined(RAK14014) || defined(HELTEC_MESH_NODE_T096)
|
#if defined(RAK14014) || defined(HELTEC_MESH_NODE_T096) || defined(HELTEC_MESH_NODE_T1)
|
||||||
#elif !defined(M5STACK) && !defined(ST7789_CS) && \
|
#elif !defined(M5STACK) && !defined(ST7789_CS) && \
|
||||||
!defined(HACKADAY_COMMUNICATOR) // T-Deck gets brightness set in Screen.cpp in the handleSetOn function
|
!defined(HACKADAY_COMMUNICATOR) // T-Deck gets brightness set in Screen.cpp in the handleSetOn function
|
||||||
tft->setBrightness(172);
|
tft->setBrightness(172);
|
||||||
@@ -1485,7 +1486,8 @@ void TFTDisplay::sendCommand(uint8_t com)
|
|||||||
digitalWrite(portduino_config.displayBacklight.pin, !TFT_BACKLIGHT_ON);
|
digitalWrite(portduino_config.displayBacklight.pin, !TFT_BACKLIGHT_ON);
|
||||||
#elif defined(HACKADAY_COMMUNICATOR)
|
#elif defined(HACKADAY_COMMUNICATOR)
|
||||||
tft->displayOff();
|
tft->displayOff();
|
||||||
#elif !defined(RAK14014) && !defined(M5STACK) && !defined(UNPHONE) && !defined(HELTEC_MESH_NODE_T096)
|
#elif !defined(RAK14014) && !defined(M5STACK) && !defined(UNPHONE) && !defined(HELTEC_MESH_NODE_T096) && \
|
||||||
|
!defined(HELTEC_MESH_NODE_T1)
|
||||||
tft->sleep();
|
tft->sleep();
|
||||||
tft->powerSaveOn();
|
tft->powerSaveOn();
|
||||||
#endif
|
#endif
|
||||||
@@ -1496,7 +1498,7 @@ void TFTDisplay::sendCommand(uint8_t com)
|
|||||||
#ifdef UNPHONE
|
#ifdef UNPHONE
|
||||||
unphone.backlight(false); // using unPhone library
|
unphone.backlight(false); // using unPhone library
|
||||||
#endif
|
#endif
|
||||||
#if defined(RAK14014) || defined(HELTEC_MESH_NODE_T096)
|
#if defined(RAK14014) || defined(HELTEC_MESH_NODE_T096) || defined(HELTEC_MESH_NODE_T1)
|
||||||
#elif !defined(M5STACK) && !defined(HACKADAY_COMMUNICATOR)
|
#elif !defined(M5STACK) && !defined(HACKADAY_COMMUNICATOR)
|
||||||
tft->setBrightness(0);
|
tft->setBrightness(0);
|
||||||
#endif
|
#endif
|
||||||
@@ -1511,7 +1513,7 @@ void TFTDisplay::sendCommand(uint8_t com)
|
|||||||
|
|
||||||
void TFTDisplay::setDisplayBrightness(uint8_t _brightness)
|
void TFTDisplay::setDisplayBrightness(uint8_t _brightness)
|
||||||
{
|
{
|
||||||
#if defined(RAK14014) || defined(HELTEC_MESH_NODE_T096)
|
#if defined(RAK14014) || defined(HELTEC_MESH_NODE_T096) || defined(HELTEC_MESH_NODE_T1)
|
||||||
// todo
|
// todo
|
||||||
#elif !defined(HACKADAY_COMMUNICATOR)
|
#elif !defined(HACKADAY_COMMUNICATOR)
|
||||||
tft->setBrightness(_brightness);
|
tft->setBrightness(_brightness);
|
||||||
@@ -1531,7 +1533,8 @@ bool TFTDisplay::hasTouch(void)
|
|||||||
{
|
{
|
||||||
#ifdef RAK14014
|
#ifdef RAK14014
|
||||||
return true;
|
return true;
|
||||||
#elif !defined(M5STACK) && !defined(HACKADAY_COMMUNICATOR) && !defined(HELTEC_MESH_NODE_T096)
|
#elif !defined(M5STACK) && !defined(HACKADAY_COMMUNICATOR) && !defined(HELTEC_MESH_NODE_T096) && \
|
||||||
|
!defined(HELTEC_MESH_NODE_T1)
|
||||||
return tft->touch() != nullptr;
|
return tft->touch() != nullptr;
|
||||||
#else
|
#else
|
||||||
return false;
|
return false;
|
||||||
@@ -1550,7 +1553,8 @@ bool TFTDisplay::getTouch(int16_t *x, int16_t *y)
|
|||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#elif !defined(M5STACK) && !defined(HACKADAY_COMMUNICATOR) && !defined(HELTEC_MESH_NODE_T096)
|
#elif !defined(M5STACK) && !defined(HACKADAY_COMMUNICATOR) && !defined(HELTEC_MESH_NODE_T096) && \
|
||||||
|
!defined(HELTEC_MESH_NODE_T1)
|
||||||
return tft->getTouch(x, y);
|
return tft->getTouch(x, y);
|
||||||
#else
|
#else
|
||||||
return false;
|
return false;
|
||||||
@@ -1567,7 +1571,7 @@ bool TFTDisplay::connect()
|
|||||||
{
|
{
|
||||||
concurrency::LockGuard g(spiLock);
|
concurrency::LockGuard g(spiLock);
|
||||||
LOG_INFO("Do TFT init");
|
LOG_INFO("Do TFT init");
|
||||||
#if defined(RAK14014) || defined(HELTEC_MESH_NODE_T096)
|
#if defined(RAK14014) || defined(HELTEC_MESH_NODE_T096) || defined(HELTEC_MESH_NODE_T1)
|
||||||
tft = new TFT_eSPI;
|
tft = new TFT_eSPI;
|
||||||
#elif defined(HACKADAY_COMMUNICATOR)
|
#elif defined(HACKADAY_COMMUNICATOR)
|
||||||
bus = new Arduino_ESP32SPI(TFT_DC, TFT_CS, 38 /* SCK */, 21 /* MOSI */, GFX_NOT_DEFINED /* MISO */, HSPI /* spi_num */);
|
bus = new Arduino_ESP32SPI(TFT_DC, TFT_CS, 38 /* SCK */, 21 /* MOSI */, GFX_NOT_DEFINED /* MISO */, HSPI /* spi_num */);
|
||||||
|
|||||||
@@ -1333,6 +1333,11 @@ void menuHandler::positionBaseMenu()
|
|||||||
if (accelerometerThread) {
|
if (accelerometerThread) {
|
||||||
accelerometerThread->calibrate(30);
|
accelerometerThread->calibrate(30);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
#if !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_I2C && !MESHTASTIC_EXCLUDE_MAGNETOMETER
|
||||||
|
if (magnetometerThread) {
|
||||||
|
magnetometerThread->calibrate(30);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
case PositionAction::GPSSmartPosition:
|
case PositionAction::GPSSmartPosition:
|
||||||
|
|||||||
@@ -136,6 +136,10 @@ void printPartitionTable()
|
|||||||
#include "motion/AccelerometerThread.h"
|
#include "motion/AccelerometerThread.h"
|
||||||
AccelerometerThread *accelerometerThread = nullptr;
|
AccelerometerThread *accelerometerThread = nullptr;
|
||||||
#endif
|
#endif
|
||||||
|
#if !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_I2C && !MESHTASTIC_EXCLUDE_MAGNETOMETER
|
||||||
|
#include "motion/MagnetometerThread.h"
|
||||||
|
MagnetometerThread *magnetometerThread = nullptr;
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef HAS_I2S
|
#ifdef HAS_I2S
|
||||||
#include "AudioThread.h"
|
#include "AudioThread.h"
|
||||||
@@ -206,6 +210,8 @@ bool osk_found = false;
|
|||||||
ScanI2C::DeviceAddress rtc_found = ScanI2C::ADDRESS_NONE;
|
ScanI2C::DeviceAddress rtc_found = ScanI2C::ADDRESS_NONE;
|
||||||
// The I2C address of the Accelerometer (if found)
|
// The I2C address of the Accelerometer (if found)
|
||||||
ScanI2C::DeviceAddress accelerometer_found = ScanI2C::ADDRESS_NONE;
|
ScanI2C::DeviceAddress accelerometer_found = ScanI2C::ADDRESS_NONE;
|
||||||
|
// The I2C address of the Magnetometer (if found)
|
||||||
|
ScanI2C::DeviceAddress magnetometer_found = ScanI2C::ADDRESS_NONE;
|
||||||
// The I2C address of the RGB LED (if found)
|
// The I2C address of the RGB LED (if found)
|
||||||
ScanI2C::FoundDevice rgb_found = ScanI2C::FoundDevice(ScanI2C::DeviceType::NONE, ScanI2C::ADDRESS_NONE);
|
ScanI2C::FoundDevice rgb_found = ScanI2C::FoundDevice(ScanI2C::DeviceType::NONE, ScanI2C::ADDRESS_NONE);
|
||||||
/// The I2C address of our Air Quality Indicator (if found)
|
/// The I2C address of our Air Quality Indicator (if found)
|
||||||
@@ -431,6 +437,11 @@ void setup()
|
|||||||
digitalWrite(VEXT_ENABLE, VEXT_ON_VALUE); // turn on the display power
|
digitalWrite(VEXT_ENABLE, VEXT_ON_VALUE); // turn on the display power
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(PIN_SENSOR_EN)
|
||||||
|
pinMode(PIN_SENSOR_EN, OUTPUT);
|
||||||
|
digitalWrite(PIN_SENSOR_EN, PIN_SENSOR_EN_ACTIVE); // turn on sensor power
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(BIAS_T_ENABLE)
|
#if defined(BIAS_T_ENABLE)
|
||||||
pinMode(BIAS_T_ENABLE, OUTPUT);
|
pinMode(BIAS_T_ENABLE, OUTPUT);
|
||||||
digitalWrite(BIAS_T_ENABLE, BIAS_T_VALUE); // turn on 5V for GPS Antenna
|
digitalWrite(BIAS_T_ENABLE, BIAS_T_VALUE); // turn on 5V for GPS Antenna
|
||||||
@@ -671,6 +682,11 @@ void setup()
|
|||||||
accelerometer_found = acc_info.type != ScanI2C::DeviceType::NONE ? acc_info.address : accelerometer_found;
|
accelerometer_found = acc_info.type != ScanI2C::DeviceType::NONE ? acc_info.address : accelerometer_found;
|
||||||
LOG_DEBUG("acc_info = %i", acc_info.type);
|
LOG_DEBUG("acc_info = %i", acc_info.type);
|
||||||
#endif
|
#endif
|
||||||
|
#if !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_MAGNETOMETER
|
||||||
|
auto mag_info = i2cScanner->firstMagnetometer();
|
||||||
|
magnetometer_found = mag_info.type != ScanI2C::DeviceType::NONE ? mag_info.address : magnetometer_found;
|
||||||
|
LOG_DEBUG("mag_info = %i", mag_info.type);
|
||||||
|
#endif
|
||||||
|
|
||||||
scannerToSensorsMap(i2cScanner, ScanI2C::DeviceType::INA260, meshtastic_TelemetrySensorType_INA260);
|
scannerToSensorsMap(i2cScanner, ScanI2C::DeviceType::INA260, meshtastic_TelemetrySensorType_INA260);
|
||||||
scannerToSensorsMap(i2cScanner, ScanI2C::DeviceType::INA226, meshtastic_TelemetrySensorType_INA226);
|
scannerToSensorsMap(i2cScanner, ScanI2C::DeviceType::INA226, meshtastic_TelemetrySensorType_INA226);
|
||||||
@@ -683,6 +699,8 @@ void setup()
|
|||||||
scannerToSensorsMap(i2cScanner, ScanI2C::DeviceType::QMI8658, meshtastic_TelemetrySensorType_QMI8658);
|
scannerToSensorsMap(i2cScanner, ScanI2C::DeviceType::QMI8658, meshtastic_TelemetrySensorType_QMI8658);
|
||||||
scannerToSensorsMap(i2cScanner, ScanI2C::DeviceType::QMC5883L, meshtastic_TelemetrySensorType_QMC5883L);
|
scannerToSensorsMap(i2cScanner, ScanI2C::DeviceType::QMC5883L, meshtastic_TelemetrySensorType_QMC5883L);
|
||||||
scannerToSensorsMap(i2cScanner, ScanI2C::DeviceType::HMC5883L, meshtastic_TelemetrySensorType_QMC5883L);
|
scannerToSensorsMap(i2cScanner, ScanI2C::DeviceType::HMC5883L, meshtastic_TelemetrySensorType_QMC5883L);
|
||||||
|
scannerToSensorsMap(i2cScanner, ScanI2C::DeviceType::MMC5983MA, meshtastic_TelemetrySensorType_MMC5983MA);
|
||||||
|
scannerToSensorsMap(i2cScanner, ScanI2C::DeviceType::ICM42607P, meshtastic_TelemetrySensorType_ICM42607P);
|
||||||
scannerToSensorsMap(i2cScanner, ScanI2C::DeviceType::MLX90614, meshtastic_TelemetrySensorType_MLX90614);
|
scannerToSensorsMap(i2cScanner, ScanI2C::DeviceType::MLX90614, meshtastic_TelemetrySensorType_MLX90614);
|
||||||
scannerToSensorsMap(i2cScanner, ScanI2C::DeviceType::ICM20948, meshtastic_TelemetrySensorType_ICM20948);
|
scannerToSensorsMap(i2cScanner, ScanI2C::DeviceType::ICM20948, meshtastic_TelemetrySensorType_ICM20948);
|
||||||
scannerToSensorsMap(i2cScanner, ScanI2C::DeviceType::MAX30102, meshtastic_TelemetrySensorType_MAX30102);
|
scannerToSensorsMap(i2cScanner, ScanI2C::DeviceType::MAX30102, meshtastic_TelemetrySensorType_MAX30102);
|
||||||
@@ -766,6 +784,11 @@ void setup()
|
|||||||
accelerometerThread = new AccelerometerThread(acc_info.type);
|
accelerometerThread = new AccelerometerThread(acc_info.type);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#if !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_MAGNETOMETER
|
||||||
|
if (mag_info.type != ScanI2C::DeviceType::NONE) {
|
||||||
|
magnetometerThread = new MagnetometerThread(mag_info.type);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(HAS_NEOPIXEL) || defined(UNPHONE) || defined(RGBLED_RED)
|
#if defined(HAS_NEOPIXEL) || defined(UNPHONE) || defined(RGBLED_RED)
|
||||||
ambientLightingThread = new AmbientLightingThread(ScanI2C::DeviceType::NONE);
|
ambientLightingThread = new AmbientLightingThread(ScanI2C::DeviceType::NONE);
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ extern bool kb_found;
|
|||||||
extern bool osk_found;
|
extern bool osk_found;
|
||||||
extern ScanI2C::DeviceAddress rtc_found;
|
extern ScanI2C::DeviceAddress rtc_found;
|
||||||
extern ScanI2C::DeviceAddress accelerometer_found;
|
extern ScanI2C::DeviceAddress accelerometer_found;
|
||||||
|
extern ScanI2C::DeviceAddress magnetometer_found;
|
||||||
extern ScanI2C::FoundDevice rgb_found;
|
extern ScanI2C::FoundDevice rgb_found;
|
||||||
extern ScanI2C::DeviceAddress aqi_found;
|
extern ScanI2C::DeviceAddress aqi_found;
|
||||||
|
|
||||||
@@ -73,6 +74,10 @@ extern graphics::Screen *screen;
|
|||||||
#include "motion/AccelerometerThread.h"
|
#include "motion/AccelerometerThread.h"
|
||||||
extern AccelerometerThread *accelerometerThread;
|
extern AccelerometerThread *accelerometerThread;
|
||||||
#endif
|
#endif
|
||||||
|
#if !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_I2C && !MESHTASTIC_EXCLUDE_MAGNETOMETER
|
||||||
|
#include "motion/MagnetometerThread.h"
|
||||||
|
extern MagnetometerThread *magnetometerThread;
|
||||||
|
#endif
|
||||||
|
|
||||||
extern bool isVibrating;
|
extern bool isVibrating;
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
#endif
|
#endif
|
||||||
#include "BMM150Sensor.h"
|
#include "BMM150Sensor.h"
|
||||||
#include "BMX160Sensor.h"
|
#include "BMX160Sensor.h"
|
||||||
|
#include "ICM42607PSensor.h"
|
||||||
#include "ICM20948Sensor.h"
|
#include "ICM20948Sensor.h"
|
||||||
#include "LIS3DHSensor.h"
|
#include "LIS3DHSensor.h"
|
||||||
#include "LSM6DS3Sensor.h"
|
#include "LSM6DS3Sensor.h"
|
||||||
@@ -111,6 +112,9 @@ class AccelerometerThread : public concurrency::OSThread
|
|||||||
case ScanI2C::DeviceType::ICM20948:
|
case ScanI2C::DeviceType::ICM20948:
|
||||||
sensor = new ICM20948Sensor(device);
|
sensor = new ICM20948Sensor(device);
|
||||||
break;
|
break;
|
||||||
|
case ScanI2C::DeviceType::ICM42607P:
|
||||||
|
sensor = new ICM42607PSensor(device);
|
||||||
|
break;
|
||||||
case ScanI2C::DeviceType::BMM150:
|
case ScanI2C::DeviceType::BMM150:
|
||||||
sensor = new BMM150Sensor(device);
|
sensor = new BMM150Sensor(device);
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -0,0 +1,98 @@
|
|||||||
|
#include "ICM42607PSensor.h"
|
||||||
|
|
||||||
|
#if !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_I2C && __has_include(<ICM42670P.h>)
|
||||||
|
|
||||||
|
#include "detect/ScanI2CTwoWire.h"
|
||||||
|
#include <ICM42670P.h>
|
||||||
|
|
||||||
|
static constexpr uint16_t ICM42607P_ACCEL_ODR_HZ = 50;
|
||||||
|
static constexpr uint16_t ICM42607P_ACCEL_FSR_G = 2;
|
||||||
|
static constexpr float ICM42607P_COUNTS_PER_G = 32768.0f / ICM42607P_ACCEL_FSR_G;
|
||||||
|
|
||||||
|
#ifdef ICM_42607P_INT_PIN
|
||||||
|
volatile static bool ICM42607P_IRQ = false;
|
||||||
|
|
||||||
|
void ICM42607PSetInterrupt()
|
||||||
|
{
|
||||||
|
ICM42607P_IRQ = true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ICM42607PSensor::ICM42607PSensor(ScanI2C::FoundDevice foundDevice) : MotionSensor::MotionSensor(foundDevice)
|
||||||
|
{
|
||||||
|
wire = ScanI2CTwoWire::fetchI2CBus(foundDevice.address);
|
||||||
|
}
|
||||||
|
|
||||||
|
ICM42607PSensor::~ICM42607PSensor() = default;
|
||||||
|
|
||||||
|
bool ICM42607PSensor::init()
|
||||||
|
{
|
||||||
|
bool addressLsb = deviceAddress() == ICM42607P_ADDR_ALT;
|
||||||
|
|
||||||
|
LOG_DEBUG("ICM-42607-P begin on addr 0x%02X (port=%d)", deviceAddress(), devicePort());
|
||||||
|
sensor.reset();
|
||||||
|
auto newSensor = std::make_unique<ICM42670>(*wire, addressLsb);
|
||||||
|
|
||||||
|
int status = newSensor->begin();
|
||||||
|
// ICM42670P library returns -3 for ICM42607P because WHO_AM_I differs; the register map is compatible.
|
||||||
|
if (status != 0 && status != -3) {
|
||||||
|
LOG_DEBUG("ICM-42607-P init error %d", status);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = newSensor->startAccel(ICM42607P_ACCEL_ODR_HZ, ICM42607P_ACCEL_FSR_G);
|
||||||
|
if (status != 0) {
|
||||||
|
LOG_DEBUG("ICM-42607-P accel start error %d", status);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef ICM_42607P_INT_PIN
|
||||||
|
ICM42607P_IRQ = false;
|
||||||
|
status = newSensor->startWakeOnMotion(ICM_42607P_INT_PIN, ICM42607PSetInterrupt);
|
||||||
|
if (status != 0) {
|
||||||
|
LOG_DEBUG("ICM-42607-P wake-on-motion start error %d", status);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
LOG_DEBUG("ICM-42607-P wake-on-motion interrupt ok pin=%d", ICM_42607P_INT_PIN);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
sensor = std::move(newSensor);
|
||||||
|
LOG_DEBUG("ICM-42607-P init ok");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t ICM42607PSensor::runOnce()
|
||||||
|
{
|
||||||
|
#ifdef ICM_42607P_INT_PIN
|
||||||
|
if (ICM42607P_IRQ) {
|
||||||
|
ICM42607P_IRQ = false;
|
||||||
|
LOG_DEBUG("ICM-42607-P motion interrupt");
|
||||||
|
wakeScreen();
|
||||||
|
}
|
||||||
|
return MOTION_SENSOR_CHECK_INTERVAL_MS;
|
||||||
|
#else
|
||||||
|
int16_t x = 0;
|
||||||
|
int16_t y = 0;
|
||||||
|
int16_t z = 0;
|
||||||
|
inv_imu_sensor_event_t event = {};
|
||||||
|
|
||||||
|
if (sensor == nullptr || sensor->getDataFromRegisters(event) != 0) {
|
||||||
|
return MOTION_SENSOR_CHECK_INTERVAL_MS;
|
||||||
|
}
|
||||||
|
|
||||||
|
// getDataFromRegisters() fills accel[] but does not set sensor_mask in this library version.
|
||||||
|
if (event.accel[0] == 0 && event.accel[1] == 0 && event.accel[2] == 0) {
|
||||||
|
return MOTION_SENSOR_CHECK_INTERVAL_MS;
|
||||||
|
}
|
||||||
|
|
||||||
|
x = event.accel[0];
|
||||||
|
y = event.accel[1];
|
||||||
|
z = event.accel[2];
|
||||||
|
// LOG_DEBUG("ICM-42607-P accel read x=%.3fg y=%.3fg z=%.3fg", (float)x / ICM42607P_COUNTS_PER_G,
|
||||||
|
// (float)y / ICM42607P_COUNTS_PER_G, (float)z / ICM42607P_COUNTS_PER_G);
|
||||||
|
|
||||||
|
return MOTION_SENSOR_CHECK_INTERVAL_MS;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
#pragma once
|
||||||
|
#ifndef _ICM42607P_SENSOR_H_
|
||||||
|
#define _ICM42607P_SENSOR_H_
|
||||||
|
|
||||||
|
#include "MotionSensor.h"
|
||||||
|
|
||||||
|
#if !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_I2C && __has_include(<ICM42670P.h>)
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
class ICM42670;
|
||||||
|
|
||||||
|
class ICM42607PSensor : public MotionSensor
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
std::unique_ptr<ICM42670> sensor;
|
||||||
|
TwoWire *wire = nullptr;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit ICM42607PSensor(ScanI2C::FoundDevice foundDevice);
|
||||||
|
~ICM42607PSensor() override;
|
||||||
|
virtual bool init() override;
|
||||||
|
virtual int32_t runOnce() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,115 @@
|
|||||||
|
#include "MMC5983MASensor.h"
|
||||||
|
|
||||||
|
#if !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_I2C && __has_include(<SparkFun_MMC5983MA_Arduino_Library.h>)
|
||||||
|
|
||||||
|
#include "detect/ScanI2CTwoWire.h"
|
||||||
|
|
||||||
|
#if !defined(MESHTASTIC_EXCLUDE_SCREEN)
|
||||||
|
extern graphics::Screen *screen;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static constexpr float MMC5983MA_ZERO_FIELD = 131072.0f;
|
||||||
|
static constexpr float MMC5983MA_COUNTS_PER_GAUSS = 16384.0f;
|
||||||
|
static constexpr uint16_t MMC5983MA_CONTINUOUS_FREQUENCY_HZ = 10;
|
||||||
|
static constexpr float MMC5983MA_HEADING_OFFSET_DEG = 180.0f;
|
||||||
|
|
||||||
|
MMC5983MASensor::MMC5983MASensor(ScanI2C::FoundDevice foundDevice) : MotionSensor::MotionSensor(foundDevice) {}
|
||||||
|
|
||||||
|
bool MMC5983MASensor::init()
|
||||||
|
{
|
||||||
|
LOG_DEBUG("MMC5983MA begin on addr 0x%02X (port=%d)", device.address.address, device.address.port);
|
||||||
|
TwoWire *wire = ScanI2CTwoWire::fetchI2CBus(device.address);
|
||||||
|
|
||||||
|
if (!sensor.begin(*wire)) {
|
||||||
|
LOG_DEBUG("MMC5983MA init error");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
sensor.softReset();
|
||||||
|
sensor.setFilterBandwidth(100);
|
||||||
|
sensor.performSetOperation();
|
||||||
|
sensor.enableAutomaticSetReset();
|
||||||
|
continuousMode = sensor.setContinuousModeFrequency(MMC5983MA_CONTINUOUS_FREQUENCY_HZ);
|
||||||
|
continuousMode &= sensor.enableContinuousMode();
|
||||||
|
|
||||||
|
if (!continuousMode) {
|
||||||
|
LOG_DEBUG("MMC5983MA continuous mode failed, using single-shot reads");
|
||||||
|
sensor.disableContinuousMode();
|
||||||
|
}
|
||||||
|
|
||||||
|
loadMagnetometerCalibration(compassCalibrationFileName, highestX, lowestX, highestY, lowestY, highestZ, lowestZ);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MMC5983MASensor::readMagnetometer(float &xGauss, float &yGauss, float &zGauss)
|
||||||
|
{
|
||||||
|
uint32_t rawX = 0;
|
||||||
|
uint32_t rawY = 0;
|
||||||
|
uint32_t rawZ = 0;
|
||||||
|
|
||||||
|
if (!(continuousMode ? sensor.readFieldsXYZ(&rawX, &rawY, &rawZ) : sensor.getMeasurementXYZ(&rawX, &rawY, &rawZ))) {
|
||||||
|
LOG_DEBUG("MMC5983MA read failed");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
xGauss = ((float)rawX - MMC5983MA_ZERO_FIELD) / MMC5983MA_COUNTS_PER_GAUSS;
|
||||||
|
yGauss = ((float)rawY - MMC5983MA_ZERO_FIELD) / MMC5983MA_COUNTS_PER_GAUSS;
|
||||||
|
zGauss = ((float)rawZ - MMC5983MA_ZERO_FIELD) / MMC5983MA_COUNTS_PER_GAUSS;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t MMC5983MASensor::runOnce()
|
||||||
|
{
|
||||||
|
float magX = 0, magY = 0, magZ = 0;
|
||||||
|
if (!readMagnetometer(magX, magY, magZ)) {
|
||||||
|
return MOTION_SENSOR_CHECK_INTERVAL_MS;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !defined(MESHTASTIC_EXCLUDE_SCREEN)
|
||||||
|
if (doCalibration) {
|
||||||
|
beginCalibrationDisplay(showingScreen);
|
||||||
|
updateCalibrationExtrema(magX, magY, magZ, highestX, lowestX, highestY, lowestY, highestZ, lowestZ);
|
||||||
|
finishCalibrationIfExpired(showingScreen, compassCalibrationFileName, highestX, lowestX, highestY, lowestY, highestZ,
|
||||||
|
lowestZ);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
magX -= (highestX + lowestX) / 2;
|
||||||
|
magY -= (highestY + lowestY) / 2;
|
||||||
|
magZ -= (highestZ + lowestZ) / 2;
|
||||||
|
|
||||||
|
#if !defined(MESHTASTIC_EXCLUDE_SCREEN) && HAS_SCREEN
|
||||||
|
float heading = atan2f(magY, magX) * RAD_TO_DEG + MMC5983MA_HEADING_OFFSET_DEG;
|
||||||
|
if (heading < 0.0f) {
|
||||||
|
heading += 360.0f;
|
||||||
|
} else if (heading >= 360.0f) {
|
||||||
|
heading -= 360.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
heading = applyCompassOrientation(heading);
|
||||||
|
if (screen) {
|
||||||
|
screen->setHeading(heading);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return MOTION_SENSOR_CHECK_INTERVAL_MS;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MMC5983MASensor::calibrate(uint16_t forSeconds)
|
||||||
|
{
|
||||||
|
#if !defined(MESHTASTIC_EXCLUDE_SCREEN)
|
||||||
|
float xGauss = 0.0f;
|
||||||
|
float yGauss = 0.0f;
|
||||||
|
float zGauss = 0.0f;
|
||||||
|
|
||||||
|
LOG_DEBUG("MMC5983MA calibration started for %is", forSeconds);
|
||||||
|
if (readMagnetometer(xGauss, yGauss, zGauss)) {
|
||||||
|
seedCalibrationExtrema(xGauss, yGauss, zGauss, highestX, lowestX, highestY, lowestY, highestZ, lowestZ);
|
||||||
|
} else {
|
||||||
|
seedCalibrationExtrema(0.0f, 0.0f, 0.0f, highestX, lowestX, highestY, lowestY, highestZ, lowestZ);
|
||||||
|
}
|
||||||
|
startCalibrationWindow(forSeconds);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
#pragma once
|
||||||
|
#ifndef _MMC5983MA_SENSOR_H_
|
||||||
|
#define _MMC5983MA_SENSOR_H_
|
||||||
|
|
||||||
|
#include "MotionSensor.h"
|
||||||
|
|
||||||
|
#if !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_I2C && __has_include(<SparkFun_MMC5983MA_Arduino_Library.h>)
|
||||||
|
|
||||||
|
#include <SparkFun_MMC5983MA_Arduino_Library.h>
|
||||||
|
|
||||||
|
class MMC5983MASensor : public MotionSensor
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
SFE_MMC5983MA sensor;
|
||||||
|
bool continuousMode = false;
|
||||||
|
bool showingScreen = false;
|
||||||
|
static constexpr const char *compassCalibrationFileName = "/prefs/compass_mmc5983ma.dat";
|
||||||
|
float highestX = 0, lowestX = 0, highestY = 0, lowestY = 0, highestZ = 0, lowestZ = 0;
|
||||||
|
|
||||||
|
bool readMagnetometer(float &xGauss, float &yGauss, float &zGauss);
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit MMC5983MASensor(ScanI2C::FoundDevice foundDevice);
|
||||||
|
virtual bool init() override;
|
||||||
|
virtual int32_t runOnce() override;
|
||||||
|
virtual void calibrate(uint16_t forSeconds) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,115 @@
|
|||||||
|
#pragma once
|
||||||
|
#ifndef _MAGNETOMETER_THREAD_H_
|
||||||
|
#define _MAGNETOMETER_THREAD_H_
|
||||||
|
|
||||||
|
#include "configuration.h"
|
||||||
|
|
||||||
|
#if !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_I2C && !MESHTASTIC_EXCLUDE_MAGNETOMETER
|
||||||
|
|
||||||
|
#include "../concurrency/OSThread.h"
|
||||||
|
#include "MMC5983MASensor.h"
|
||||||
|
#include "MotionSensor.h"
|
||||||
|
|
||||||
|
extern ScanI2C::DeviceAddress magnetometer_found;
|
||||||
|
|
||||||
|
class MagnetometerThread : public concurrency::OSThread
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
MotionSensor *sensor = nullptr;
|
||||||
|
ScanI2C::FoundDevice device;
|
||||||
|
bool isInitialised = false;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit MagnetometerThread(ScanI2C::FoundDevice foundDevice) : OSThread("Magnetometer")
|
||||||
|
{
|
||||||
|
device = foundDevice;
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
explicit MagnetometerThread(ScanI2C::DeviceType type) : MagnetometerThread(ScanI2C::FoundDevice{type, magnetometer_found}) {}
|
||||||
|
|
||||||
|
void start()
|
||||||
|
{
|
||||||
|
init();
|
||||||
|
setIntervalFromNow(0);
|
||||||
|
};
|
||||||
|
|
||||||
|
void calibrate(uint16_t forSeconds)
|
||||||
|
{
|
||||||
|
if (sensor) {
|
||||||
|
sensor->calibrate(forSeconds);
|
||||||
|
setIntervalFromNow(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
int32_t runOnce() override
|
||||||
|
{
|
||||||
|
canSleep = true;
|
||||||
|
|
||||||
|
if (isInitialised) {
|
||||||
|
return sensor->runOnce();
|
||||||
|
}
|
||||||
|
|
||||||
|
return MOTION_SENSOR_CHECK_INTERVAL_MS;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void init()
|
||||||
|
{
|
||||||
|
if (isInitialised) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (device.address.port == ScanI2C::I2CPort::NO_I2C || device.address.address == 0 || device.type == ScanI2C::NONE) {
|
||||||
|
LOG_DEBUG("MagnetometerThread Disable due to no sensors found");
|
||||||
|
disable();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (device.type) {
|
||||||
|
case ScanI2C::DeviceType::MMC5983MA:
|
||||||
|
sensor = new MMC5983MASensor(device);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
disable();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
isInitialised = sensor->init();
|
||||||
|
if (!isInitialised) {
|
||||||
|
clean();
|
||||||
|
}
|
||||||
|
LOG_DEBUG("MagnetometerThread::init %s", isInitialised ? "ok" : "failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
MagnetometerThread(const MagnetometerThread &other) : OSThread::OSThread("Magnetometer") { this->copy(other); }
|
||||||
|
|
||||||
|
virtual ~MagnetometerThread() { clean(); }
|
||||||
|
|
||||||
|
MagnetometerThread &operator=(const MagnetometerThread &other)
|
||||||
|
{
|
||||||
|
this->copy(other);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void copy(const MagnetometerThread &other)
|
||||||
|
{
|
||||||
|
if (this != &other) {
|
||||||
|
clean();
|
||||||
|
this->device = ScanI2C::FoundDevice(other.device.type,
|
||||||
|
ScanI2C::DeviceAddress(other.device.address.port, other.device.address.address));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void clean()
|
||||||
|
{
|
||||||
|
isInitialised = false;
|
||||||
|
delete sensor;
|
||||||
|
sensor = nullptr;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -117,6 +117,8 @@
|
|||||||
#define HW_VENDOR meshtastic_HardwareModel_PRIVATE_HW
|
#define HW_VENDOR meshtastic_HardwareModel_PRIVATE_HW
|
||||||
#elif defined(HELTEC_T114)
|
#elif defined(HELTEC_T114)
|
||||||
#define HW_VENDOR meshtastic_HardwareModel_HELTEC_MESH_NODE_T114
|
#define HW_VENDOR meshtastic_HardwareModel_HELTEC_MESH_NODE_T114
|
||||||
|
#elif defined(HELTEC_MESH_NODE_T1)
|
||||||
|
#define HW_VENDOR meshtastic_HardwareModel_HELTEC_MESH_NODE_T1
|
||||||
#elif defined(MESHLINK)
|
#elif defined(MESHLINK)
|
||||||
#define HW_VENDOR meshtastic_HardwareModel_MESHLINK
|
#define HW_VENDOR meshtastic_HardwareModel_MESHLINK
|
||||||
#elif defined(SEEED_XIAO_NRF52840_KIT)
|
#elif defined(SEEED_XIAO_NRF52840_KIT)
|
||||||
|
|||||||
@@ -0,0 +1,35 @@
|
|||||||
|
; Heltec Mesh Node T1 nRF52840/SX1262 device
|
||||||
|
[env:heltec-mesh-node-t1]
|
||||||
|
custom_meshtastic_hw_model = 133
|
||||||
|
custom_meshtastic_hw_model_slug = HELTEC_MESH_NODE_T1
|
||||||
|
custom_meshtastic_architecture = nrf52840
|
||||||
|
custom_meshtastic_actively_supported = true
|
||||||
|
custom_meshtastic_support_level = 1
|
||||||
|
custom_meshtastic_display_name = Heltec Mesh Node T1
|
||||||
|
custom_meshtastic_images = heltec-mesh-node-t1.svg
|
||||||
|
custom_meshtastic_tags = Heltec
|
||||||
|
|
||||||
|
extends = nrf52840_base
|
||||||
|
board = heltec_mesh_node_t1
|
||||||
|
board_level = pr
|
||||||
|
debug_tool = jlink
|
||||||
|
|
||||||
|
build_flags = ${nrf52840_base.build_flags}
|
||||||
|
-Ivariants/nrf52840/heltec_mesh_node_t1
|
||||||
|
-DHELTEC_MESH_NODE_T1
|
||||||
|
-DUSE_TFTDISPLAY
|
||||||
|
-DUSER_SETUP_LOADED
|
||||||
|
-DST7735_DRIVER
|
||||||
|
-DST7735_REDTAB160x80
|
||||||
|
-D TFT_SPI_PORT=SPI1
|
||||||
|
-D TFT_CS=ST7735_CS
|
||||||
|
-D TFT_DC=ST7735_RS
|
||||||
|
-D TFT_RST=ST7735_RESET
|
||||||
|
-D TFT_BL=ST7735_BL
|
||||||
|
-D TFT_BACKLIGHT_ON=LOW
|
||||||
|
|
||||||
|
build_src_filter = ${nrf52_base.build_src_filter} +<../variants/nrf52840/heltec_mesh_node_t1>
|
||||||
|
lib_deps =
|
||||||
|
${nrf52840_base.lib_deps}
|
||||||
|
lewisxhe/PCF8563_Library@^1.0.1
|
||||||
|
bodmer/TFT_eSPI@2.5.43
|
||||||
@@ -0,0 +1,85 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) 2014-2015 Arduino LLC. All right reserved.
|
||||||
|
Copyright (c) 2016 Sandeep Mistry All right reserved.
|
||||||
|
Copyright (c) 2018, Adafruit Industries (adafruit.com)
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
See the GNU Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with this library; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "variant.h"
|
||||||
|
#include "nrf.h"
|
||||||
|
#include "wiring_constants.h"
|
||||||
|
#include "wiring_digital.h"
|
||||||
|
|
||||||
|
const uint32_t g_ADigitalPinMap[] = {
|
||||||
|
// P0 - pins 0 and 1 are hardwired for xtal and should never be enabled
|
||||||
|
0xff, 0xff, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
|
||||||
|
26, 27, 28, 29, 30, 31,
|
||||||
|
|
||||||
|
// P1
|
||||||
|
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47};
|
||||||
|
|
||||||
|
void initVariant()
|
||||||
|
{
|
||||||
|
pinMode(PIN_BUZZER_VOLTAGE_MULTIPLIER_1, OUTPUT);
|
||||||
|
pinMode(PIN_BUZZER_VOLTAGE_MULTIPLIER_2, OUTPUT);
|
||||||
|
digitalWrite(PIN_BUZZER_VOLTAGE_MULTIPLIER_1, HIGH);
|
||||||
|
digitalWrite(PIN_BUZZER_VOLTAGE_MULTIPLIER_2, HIGH);
|
||||||
|
}
|
||||||
|
|
||||||
|
void variant_shutdown()
|
||||||
|
{
|
||||||
|
nrf_gpio_cfg_default(ST7735_CS);
|
||||||
|
nrf_gpio_cfg_default(ST7735_RS);
|
||||||
|
nrf_gpio_cfg_default(ST7735_SDA);
|
||||||
|
nrf_gpio_cfg_default(ST7735_SCK);
|
||||||
|
nrf_gpio_cfg_default(ST7735_RESET);
|
||||||
|
nrf_gpio_cfg_default(ST7735_BL);
|
||||||
|
nrf_gpio_cfg_default(VTFT_CTRL);
|
||||||
|
|
||||||
|
nrf_gpio_cfg_default(PIN_WIRE_SDA);
|
||||||
|
nrf_gpio_cfg_default(PIN_WIRE_SCL);
|
||||||
|
|
||||||
|
nrf_gpio_cfg_default(SX126X_CS);
|
||||||
|
nrf_gpio_cfg_default(SX126X_DIO1);
|
||||||
|
nrf_gpio_cfg_default(SX126X_BUSY);
|
||||||
|
nrf_gpio_cfg_default(SX126X_RESET);
|
||||||
|
|
||||||
|
nrf_gpio_cfg_default(PIN_SPI_MISO);
|
||||||
|
nrf_gpio_cfg_default(PIN_SPI_MOSI);
|
||||||
|
nrf_gpio_cfg_default(PIN_SPI_SCK);
|
||||||
|
|
||||||
|
// nrf_gpio_cfg_default(PIN_SPI1_MISO);// ST7735 doesn't support MISO, so we don't configure it at all
|
||||||
|
nrf_gpio_cfg_default(PIN_SPI1_MOSI);
|
||||||
|
nrf_gpio_cfg_default(PIN_SPI1_SCK);
|
||||||
|
|
||||||
|
nrf_gpio_cfg_default(PIN_GPS_RESET);
|
||||||
|
nrf_gpio_cfg_default(PIN_GPS_EN);
|
||||||
|
nrf_gpio_cfg_default(PIN_GPS_PPS);
|
||||||
|
nrf_gpio_cfg_default(GPS_TX_PIN);
|
||||||
|
nrf_gpio_cfg_default(GPS_RX_PIN);
|
||||||
|
|
||||||
|
nrf_gpio_cfg_default(PIN_BUZZER_VOLTAGE_MULTIPLIER_1);
|
||||||
|
nrf_gpio_cfg_default(PIN_BUZZER_VOLTAGE_MULTIPLIER_2);
|
||||||
|
|
||||||
|
pinMode(PIN_BUZZER, OUTPUT);
|
||||||
|
digitalWrite(PIN_BUZZER, LOW);
|
||||||
|
|
||||||
|
pinMode(PIN_SENSOR_EN, OUTPUT);
|
||||||
|
digitalWrite(PIN_SENSOR_EN, !PIN_SENSOR_EN_ACTIVE); // Turn off sensor power
|
||||||
|
|
||||||
|
pinMode(PIN_LED1, OUTPUT);
|
||||||
|
digitalWrite(PIN_LED1, HIGH);
|
||||||
|
}
|
||||||
@@ -0,0 +1,177 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) 2014-2015 Arduino LLC. All right reserved.
|
||||||
|
Copyright (c) 2016 Sandeep Mistry All right reserved.
|
||||||
|
Copyright (c) 2018, Adafruit Industries (adafruit.com)
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
This library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
See the GNU Lesser General Public License for more details.
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with this library; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _VARIANT_HELTEC_MESH_NODE_T1_
|
||||||
|
#define _VARIANT_HELTEC_MESH_NODE_T1_
|
||||||
|
/** Master clock frequency */
|
||||||
|
#define VARIANT_MCK (64000000ul)
|
||||||
|
|
||||||
|
#define USE_LFXO // Board uses 32khz crystal for LF
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------
|
||||||
|
* Headers
|
||||||
|
*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "WVariant.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif // __cplusplus
|
||||||
|
|
||||||
|
#define ST7735_CS (0 + 12)
|
||||||
|
#define ST7735_RS (0 + 22) // DC
|
||||||
|
#define ST7735_SDA (0 + 24)
|
||||||
|
#define ST7735_SCK (32 + 0)
|
||||||
|
#define ST7735_RESET (0 + 20)
|
||||||
|
#define ST7735_MISO -1
|
||||||
|
#define ST7735_BUSY -1
|
||||||
|
#define ST7735_BL (0 + 15)
|
||||||
|
#define VTFT_CTRL (0 + 13) // Active HIGH, powers the ST7735 display
|
||||||
|
#define SPI_FREQUENCY 80000000
|
||||||
|
#define SPI_READ_FREQUENCY 16000000
|
||||||
|
#define SCREEN_ROTATE
|
||||||
|
#define TFT_HEIGHT 160
|
||||||
|
#define TFT_WIDTH 80
|
||||||
|
#define TFT_OFFSET_X 24
|
||||||
|
#define TFT_OFFSET_Y 0
|
||||||
|
#define TFT_INVERT false
|
||||||
|
#define SCREEN_TRANSITION_FRAMERATE 3 // fps
|
||||||
|
#define DISPLAY_FORCE_SMALL_FONTS
|
||||||
|
|
||||||
|
// Number of pins defined in PinDescription array
|
||||||
|
#define PINS_COUNT (48)
|
||||||
|
#define NUM_DIGITAL_PINS (48)
|
||||||
|
#define NUM_ANALOG_INPUTS (1)
|
||||||
|
#define NUM_ANALOG_OUTPUTS (0)
|
||||||
|
|
||||||
|
// LEDs
|
||||||
|
#define PIN_LED1 (0 + 16)
|
||||||
|
#define LED_BLUE PIN_LED1 // fake for bluefruit library
|
||||||
|
#define LED_GREEN PIN_LED1
|
||||||
|
#define LED_STATE_ON 0 // State when LED is lit
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Buttons
|
||||||
|
*/
|
||||||
|
#define PIN_BUTTON1 (32 + 10)
|
||||||
|
#define PIN_BUTTON2 (0 + 14)
|
||||||
|
|
||||||
|
/*
|
||||||
|
No longer populated on PCB
|
||||||
|
*/
|
||||||
|
#define PIN_SERIAL2_RX (-1)
|
||||||
|
#define PIN_SERIAL2_TX (-1)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* I2C
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define WIRE_INTERFACES_COUNT 1
|
||||||
|
|
||||||
|
// I2C bus 1
|
||||||
|
#define PIN_WIRE_SDA (32 + 3)
|
||||||
|
#define PIN_WIRE_SCL (0 + 10)
|
||||||
|
|
||||||
|
#define PIN_SENSOR_EN (32 + 6) // Power control pin for sensors
|
||||||
|
#define PIN_SENSOR_EN_ACTIVE LOW // Power control active state
|
||||||
|
// #define ICM_42607P_INT_PIN (32 + 1) // ICM42607P INT1, Arduino pin 33 / nRF P1.01
|
||||||
|
// #define ICM_42607P_INT2_PIN (32 + 7) // ICM42607P INT2, Arduino pin 39 / nRF P1.07
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Lora radio
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define USE_SX1262
|
||||||
|
#define SX126X_CS (32 + 11) // FIXME - we really should define LORA_CS instead
|
||||||
|
#define LORA_CS SX126X_CS
|
||||||
|
#define SX126X_DIO1 (0 + 31)
|
||||||
|
#define SX126X_BUSY (0 + 29)
|
||||||
|
#define SX126X_RESET (0 + 2)
|
||||||
|
#define SX126X_DIO2_AS_RF_SWITCH
|
||||||
|
#define SX126X_DIO3_TCXO_VOLTAGE 1.8
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SPI Interfaces
|
||||||
|
*/
|
||||||
|
#define SPI_INTERFACES_COUNT 2
|
||||||
|
|
||||||
|
// For LORA, spi 0
|
||||||
|
#define PIN_SPI_MISO (0 + 3)
|
||||||
|
#define PIN_SPI_MOSI (32 + 14)
|
||||||
|
#define PIN_SPI_SCK (32 + 13)
|
||||||
|
|
||||||
|
#define PIN_SPI1_MISO ST7735_MISO
|
||||||
|
#define PIN_SPI1_MOSI ST7735_SDA
|
||||||
|
#define PIN_SPI1_SCK ST7735_SCK
|
||||||
|
|
||||||
|
/*
|
||||||
|
* GPS pins
|
||||||
|
*/
|
||||||
|
#define GPS_UC6580
|
||||||
|
#define GPS_BAUDRATE 115200
|
||||||
|
#define PIN_GPS_RESET (0 + 26)
|
||||||
|
#define GPS_RESET_MODE LOW
|
||||||
|
#define PIN_GPS_EN (0 + 4)
|
||||||
|
#define GPS_EN_ACTIVE LOW
|
||||||
|
#define PERIPHERAL_WARMUP_MS 1000 // Make sure I2C QuickLink has stable power before continuing
|
||||||
|
#define PIN_GPS_PPS (32 + 9) // Pulse per second input from the GPS
|
||||||
|
#define GPS_TX_PIN (0 + 7)
|
||||||
|
#define GPS_RX_PIN (0 + 8)
|
||||||
|
|
||||||
|
#define GPS_THREAD_INTERVAL 50
|
||||||
|
|
||||||
|
#define PIN_SERIAL1_RX GPS_RX_PIN
|
||||||
|
#define PIN_SERIAL1_TX GPS_TX_PIN
|
||||||
|
|
||||||
|
#define PIN_BUZZER (0 + 9)
|
||||||
|
#define PIN_BUZZER_VOLTAGE_MULTIPLIER_1 (32 + 2)
|
||||||
|
#define PIN_BUZZER_VOLTAGE_MULTIPLIER_2 (32 + 5)
|
||||||
|
|
||||||
|
#define ADC_CTRL 11
|
||||||
|
#define ADC_CTRL_ENABLED HIGH
|
||||||
|
#define BATTERY_PIN 5
|
||||||
|
#define ADC_RESOLUTION 14
|
||||||
|
|
||||||
|
#define BATTERY_SENSE_RESOLUTION_BITS 12
|
||||||
|
#define BATTERY_SENSE_RESOLUTION 4096.0
|
||||||
|
#undef AREF_VOLTAGE
|
||||||
|
#define AREF_VOLTAGE 3.0
|
||||||
|
#define VBAT_AR_INTERNAL AR_INTERNAL_3_0
|
||||||
|
#define ADC_MULTIPLIER (4.916F)
|
||||||
|
|
||||||
|
// nrf52840 AIN3 = Pin 5
|
||||||
|
// commented out due to power leakage of 2.9mA in shutdown state see reported issue #8801
|
||||||
|
#define BATTERY_LPCOMP_INPUT NRF_LPCOMP_INPUT_3
|
||||||
|
|
||||||
|
// We have AIN3 with a VBAT divider so AIN3 = VBAT * (100/490)
|
||||||
|
// We have the device going deep sleep under 3.1V, which is AIN3 = 0.63V
|
||||||
|
// So we can wake up when VBAT>=VDD is restored to 3.3V, where AIN3 = 0.67V
|
||||||
|
// Ratio 0.67/3.3 = 0.20, so we can pick a bit higher, 2/8 VDD, which means
|
||||||
|
// VBAT=4.04V
|
||||||
|
#define BATTERY_LPCOMP_THRESHOLD NRF_LPCOMP_REF_SUPPLY_2_8
|
||||||
|
|
||||||
|
#define HAS_RTC 0
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------
|
||||||
|
* Arduino objects - C++ only
|
||||||
|
*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#endif
|
||||||
Reference in New Issue
Block a user