mirror of
https://github.com/meshtastic/firmware.git
synced 2025-09-06 19:49:19 +00:00
Compare commits
5 Commits
b58976735d
...
b5bcaf1f2c
Author | SHA1 | Date | |
---|---|---|---|
![]() |
b5bcaf1f2c | ||
![]() |
3b82d55176 | ||
![]() |
a6b8202cd4 | ||
![]() |
cfc1bf10c9 | ||
![]() |
4d9dbce55f |
@ -1,52 +0,0 @@
|
||||
{
|
||||
"build": {
|
||||
"arduino": {
|
||||
"ldscript": "nrf52840_s140_v6.ld"
|
||||
},
|
||||
"core": "nRF5",
|
||||
"cpu": "cortex-m4",
|
||||
"extra_flags": "-DARDUINO_NRF52840_FEATHER -DNRF52840_XXAA",
|
||||
"f_cpu": "64000000L",
|
||||
"hwids": [
|
||||
["0x239A", "0x8029"],
|
||||
["0x239A", "0x0029"],
|
||||
["0x239A", "0x002A"],
|
||||
["0x239A", "0x802A"]
|
||||
],
|
||||
"usb_product": "GAT562 Mesh Tracker Pro",
|
||||
"mcu": "nrf52840",
|
||||
"variant": "gat562_mesh_tracker_pro",
|
||||
"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",
|
||||
"svd_path": "nrf52840.svd",
|
||||
"openocd_target": "nrf52840-mdk-rs"
|
||||
},
|
||||
"frameworks": ["arduino", "freertos"],
|
||||
"name": "GAT562 Mesh Tracker Pro",
|
||||
"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": "http://www.gat-iot.com/",
|
||||
"vendor": "GAT"
|
||||
}
|
@ -1,7 +1,14 @@
|
||||
#include "DisplayFormatters.h"
|
||||
|
||||
const char *DisplayFormatters::getModemPresetDisplayName(meshtastic_Config_LoRaConfig_ModemPreset preset, bool useShortName)
|
||||
const char *DisplayFormatters::getModemPresetDisplayName(meshtastic_Config_LoRaConfig_ModemPreset preset, bool useShortName,
|
||||
bool usePreset)
|
||||
{
|
||||
|
||||
// If use_preset is false, always return "Custom"
|
||||
if (!usePreset) {
|
||||
return "Custom";
|
||||
}
|
||||
|
||||
switch (preset) {
|
||||
case meshtastic_Config_LoRaConfig_ModemPreset_SHORT_TURBO:
|
||||
return useShortName ? "ShortT" : "ShortTurbo";
|
||||
|
@ -4,5 +4,6 @@
|
||||
class DisplayFormatters
|
||||
{
|
||||
public:
|
||||
static const char *getModemPresetDisplayName(meshtastic_Config_LoRaConfig_ModemPreset preset, bool useShortName);
|
||||
static const char *getModemPresetDisplayName(meshtastic_Config_LoRaConfig_ModemPreset preset, bool useShortName,
|
||||
bool usePreset);
|
||||
};
|
||||
|
@ -843,9 +843,6 @@ void GPS::setPowerState(GPSPowerState newState, uint32_t sleepTime)
|
||||
setPowerPMU(true); // Power (PMU): on
|
||||
writePinStandby(false); // Standby (pin): awake (not standby)
|
||||
setPowerUBLOX(true); // Standby (UBLOX): awake
|
||||
#ifdef GNSS_AIROHA
|
||||
lastFixStartMsec = 0;
|
||||
#endif
|
||||
break;
|
||||
|
||||
case GPS_SOFTSLEEP:
|
||||
@ -863,9 +860,7 @@ void GPS::setPowerState(GPSPowerState newState, uint32_t sleepTime)
|
||||
writePinStandby(true); // Standby (pin): asleep (not awake)
|
||||
setPowerUBLOX(false, sleepTime); // Standby (UBLOX): asleep, timed
|
||||
#ifdef GNSS_AIROHA
|
||||
if (config.position.gps_update_interval * 1000 >= GPS_FIX_HOLD_TIME * 2) {
|
||||
digitalWrite(PIN_GPS_EN, LOW);
|
||||
}
|
||||
digitalWrite(PIN_GPS_EN, LOW);
|
||||
#endif
|
||||
break;
|
||||
|
||||
@ -877,9 +872,7 @@ void GPS::setPowerState(GPSPowerState newState, uint32_t sleepTime)
|
||||
writePinStandby(true); // Standby (pin): asleep
|
||||
setPowerUBLOX(false, 0); // Standby (UBLOX): asleep, indefinitely
|
||||
#ifdef GNSS_AIROHA
|
||||
if (config.position.gps_update_interval * 1000 >= GPS_FIX_HOLD_TIME * 2) {
|
||||
digitalWrite(PIN_GPS_EN, LOW);
|
||||
}
|
||||
digitalWrite(PIN_GPS_EN, LOW);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
@ -1062,6 +1055,8 @@ void GPS::down()
|
||||
}
|
||||
// If update interval long enough (or softsleep unsupported): hardsleep instead
|
||||
setPowerState(GPS_HARDSLEEP, sleepTime);
|
||||
// Reset the fix quality to 0, since we're off.
|
||||
fixQual = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1121,11 +1116,19 @@ int32_t GPS::runOnce()
|
||||
shouldPublish = true;
|
||||
}
|
||||
|
||||
uint8_t prev_fixQual = fixQual;
|
||||
bool gotLoc = lookForLocation();
|
||||
if (gotLoc && !hasValidLocation) { // declare that we have location ASAP
|
||||
LOG_DEBUG("hasValidLocation RISING EDGE");
|
||||
hasValidLocation = true;
|
||||
shouldPublish = true;
|
||||
// Hold for 20secs after getting a lock to download ephemeris etc
|
||||
fixHoldEnds = millis() + 20000;
|
||||
}
|
||||
|
||||
if (gotLoc && prev_fixQual == 0) { // just got a lock after turning back on.
|
||||
fixHoldEnds = millis() + 20000;
|
||||
shouldPublish = true; // Publish immediately, since next publish is at end of hold
|
||||
}
|
||||
|
||||
bool tooLong = scheduling.searchedTooLong();
|
||||
@ -1134,8 +1137,7 @@ int32_t GPS::runOnce()
|
||||
|
||||
// Once we get a location we no longer desperately want an update
|
||||
if ((gotLoc && gotTime) || tooLong) {
|
||||
|
||||
if (tooLong) {
|
||||
if (tooLong && !gotLoc) {
|
||||
// we didn't get a location during this ack window, therefore declare loss of lock
|
||||
if (hasValidLocation) {
|
||||
LOG_DEBUG("hasValidLocation FALLING EDGE");
|
||||
@ -1143,9 +1145,15 @@ int32_t GPS::runOnce()
|
||||
p = meshtastic_Position_init_default;
|
||||
hasValidLocation = false;
|
||||
}
|
||||
|
||||
down();
|
||||
shouldPublish = true; // publish our update for this just finished acquisition window
|
||||
if (millis() > fixHoldEnds) {
|
||||
shouldPublish = true; // publish our update at the end of the lock hold
|
||||
publishUpdate();
|
||||
down();
|
||||
#ifdef GPS_DEBUG
|
||||
} else {
|
||||
LOG_DEBUG("Holding for GPS data download: %d ms (numSats=%d)", fixHoldEnds - millis(), p.sats_in_view);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
// If state has changed do a publish
|
||||
@ -1508,24 +1516,6 @@ static int32_t toDegInt(RawDegrees d)
|
||||
*/
|
||||
bool GPS::lookForTime()
|
||||
{
|
||||
|
||||
#ifdef GNSS_AIROHA
|
||||
uint8_t fix = reader.fixQuality();
|
||||
if (fix >= 1 && fix <= 5) {
|
||||
if (lastFixStartMsec > 0) {
|
||||
if (Throttle::isWithinTimespanMs(lastFixStartMsec, GPS_FIX_HOLD_TIME)) {
|
||||
return false;
|
||||
} else {
|
||||
clearBuffer();
|
||||
}
|
||||
} else {
|
||||
lastFixStartMsec = millis();
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
auto ti = reader.time;
|
||||
auto d = reader.date;
|
||||
if (ti.isValid() && d.isValid()) { // Note: we don't check for updated, because we'll only be called if needed
|
||||
@ -1564,25 +1554,6 @@ The Unix epoch (or Unix time or POSIX time or Unix timestamp) is the number of s
|
||||
*/
|
||||
bool GPS::lookForLocation()
|
||||
{
|
||||
#ifdef GNSS_AIROHA
|
||||
if ((config.position.gps_update_interval * 1000) >= (GPS_FIX_HOLD_TIME * 2)) {
|
||||
uint8_t fix = reader.fixQuality();
|
||||
if (fix >= 1 && fix <= 5) {
|
||||
if (lastFixStartMsec > 0) {
|
||||
if (Throttle::isWithinTimespanMs(lastFixStartMsec, GPS_FIX_HOLD_TIME)) {
|
||||
return false;
|
||||
} else {
|
||||
clearBuffer();
|
||||
}
|
||||
} else {
|
||||
lastFixStartMsec = millis();
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
// By default, TinyGPS++ does not parse GPGSA lines, which give us
|
||||
// the 2D/3D fixType (see NMEAGPS.h)
|
||||
// At a minimum, use the fixQuality indicator in GPGGA (FIXME?)
|
||||
|
@ -159,7 +159,7 @@ class GPS : private concurrency::OSThread
|
||||
uint8_t fixType = 0; // fix type from GPGSA
|
||||
#endif
|
||||
|
||||
uint32_t lastWakeStartMsec = 0, lastSleepStartMsec = 0, lastFixStartMsec = 0;
|
||||
uint32_t fixHoldEnds = 0;
|
||||
uint32_t rx_gpio = 0;
|
||||
uint32_t tx_gpio = 0;
|
||||
|
||||
|
285
src/graphics/VirtualKeyboard.cpp
Normal file
285
src/graphics/VirtualKeyboard.cpp
Normal file
@ -0,0 +1,285 @@
|
||||
/*
|
||||
* VirtualKeyboard.cpp
|
||||
* Author TSAO (hey@tsao.dev) 2025
|
||||
*/
|
||||
|
||||
#include "VirtualKeyboard.h"
|
||||
|
||||
#ifdef MESHCORE
|
||||
#include "MeshCore.h"
|
||||
#elif defined(MESHTASTIC)
|
||||
#include "configuration.h"
|
||||
#include "graphics/ScreenFonts.h"
|
||||
#endif
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef MESHCORE
|
||||
VirtualKeyboard::VirtualKeyboard(DisplayDriver *displayDriver, int startX, int startY, int keyboardWidth,
|
||||
int keyboardHeight)
|
||||
: display(displayDriver) {
|
||||
#elif defined(MESHTASTIC)
|
||||
VirtualKeyboard::VirtualKeyboard(OLEDDisplay *displayDriver, int startX, int startY, int keyboardWidth,
|
||||
int keyboardHeight)
|
||||
: display(displayDriver) {
|
||||
#endif
|
||||
memset(inputBuffer, 0, sizeof(inputBuffer));
|
||||
bufferLength = 0;
|
||||
|
||||
this->startX = startX;
|
||||
this->startY = startY;
|
||||
this->keyboardWidth = keyboardWidth;
|
||||
this->keyboardHeight = keyboardHeight;
|
||||
}
|
||||
|
||||
void VirtualKeyboard::moveCursor(int deltaRow, int deltaColumn) {
|
||||
cursorRow += deltaRow;
|
||||
cursorColumn += deltaColumn;
|
||||
|
||||
// Handle column overflow/underflow with row wrapping
|
||||
if (cursorColumn >= getCols()) {
|
||||
cursorColumn = 0;
|
||||
cursorRow++;
|
||||
} else if (cursorColumn < 0) {
|
||||
cursorColumn = getCols() - 1;
|
||||
cursorRow--;
|
||||
}
|
||||
|
||||
// Handle row overflow/underflow
|
||||
if (cursorRow >= getRows()) {
|
||||
cursorRow = 0;
|
||||
} else if (cursorRow < 0) {
|
||||
cursorRow = getRows() - 1;
|
||||
}
|
||||
}
|
||||
|
||||
void VirtualKeyboard::moveRight(int steps) {
|
||||
moveCursor(0, steps);
|
||||
}
|
||||
|
||||
void VirtualKeyboard::moveLeft(int steps) {
|
||||
moveCursor(0, -steps);
|
||||
}
|
||||
|
||||
void VirtualKeyboard::moveUp(int steps) {
|
||||
moveCursor(-steps, 0);
|
||||
}
|
||||
|
||||
void VirtualKeyboard::moveDown(int steps) {
|
||||
moveCursor(steps, 0);
|
||||
}
|
||||
|
||||
const char *VirtualKeyboard::getKeyText(int row, int column) {
|
||||
const char *keyString = getKeyAt(row, column);
|
||||
if (!keyString || strlen(keyString) == 0) {
|
||||
return "";
|
||||
}
|
||||
|
||||
// Handle caps lock for letters
|
||||
if (capsLockEnabled && strlen(keyString) == 1 && keyString[0] >= 'a' && keyString[0] <= 'z') {
|
||||
static char uppercaseKey[2];
|
||||
uppercaseKey[0] = keyString[0] - 'a' + 'A';
|
||||
uppercaseKey[1] = '\0';
|
||||
return uppercaseKey;
|
||||
}
|
||||
|
||||
return keyString;
|
||||
}
|
||||
|
||||
const char *VirtualKeyboard::pressCurrentKey() {
|
||||
const char *pressedKey = getKeyText(cursorRow, cursorColumn);
|
||||
|
||||
if (strcmp(pressedKey, "DEL") == 0) {
|
||||
// Delete/Backspace
|
||||
if (bufferLength > 0) {
|
||||
bufferLength--;
|
||||
inputBuffer[bufferLength] = '\0';
|
||||
}
|
||||
} else if (strcmp(pressedKey, "OK") == 0) {
|
||||
// Enter - could trigger submission or new line
|
||||
if (bufferLength < sizeof(inputBuffer) - 1) {
|
||||
inputBuffer[bufferLength++] = '\n';
|
||||
inputBuffer[bufferLength] = '\0';
|
||||
}
|
||||
} else if (strcmp(pressedKey, "SPACE") == 0) {
|
||||
// Space
|
||||
if (bufferLength < sizeof(inputBuffer) - 1) {
|
||||
inputBuffer[bufferLength++] = ' ';
|
||||
inputBuffer[bufferLength] = '\0';
|
||||
}
|
||||
} else if (strcmp(pressedKey, "CAPS") == 0) {
|
||||
// Toggle caps lock
|
||||
capsLockEnabled = !capsLockEnabled;
|
||||
} else {
|
||||
// Regular character
|
||||
int keyLength = strlen(pressedKey);
|
||||
if (bufferLength + keyLength < sizeof(inputBuffer) - 1) {
|
||||
strcat(inputBuffer, pressedKey);
|
||||
bufferLength += keyLength;
|
||||
}
|
||||
}
|
||||
|
||||
// Call user callback if one is set
|
||||
if (keyPressCallback != nullptr) {
|
||||
keyPressCallback(pressedKey, inputBuffer);
|
||||
}
|
||||
|
||||
return pressedKey;
|
||||
}
|
||||
|
||||
void VirtualKeyboard::clear() {
|
||||
memset(inputBuffer, 0, sizeof(inputBuffer));
|
||||
bufferLength = 0;
|
||||
}
|
||||
|
||||
void VirtualKeyboard::reset() {
|
||||
clear();
|
||||
cursorRow = 0;
|
||||
cursorColumn = 0;
|
||||
}
|
||||
|
||||
void VirtualKeyboard::setKeyPressCallback(KeyPressCallback callback) {
|
||||
keyPressCallback = callback;
|
||||
}
|
||||
|
||||
void VirtualKeyboard::getTextBounds(const char *text, uint16_t *width, uint16_t *height) {
|
||||
if (!display || !text) {
|
||||
if (width) *width = 0;
|
||||
if (height) *height = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef MESHCORE
|
||||
Adafruit_SSD1306 *ssd1306Display = static_cast<Adafruit_SSD1306 *>(display->getDisplay());
|
||||
if (ssd1306Display) {
|
||||
int16_t x1, y1;
|
||||
uint16_t w, h;
|
||||
ssd1306Display->getTextBounds(text, 0, 0, &x1, &y1, &w, &h);
|
||||
if (width) *width = w;
|
||||
if (height) *height = h;
|
||||
} else {
|
||||
// Fallback if getDisplay() doesn't work
|
||||
if (width) *width = display->getTextWidth(text);
|
||||
if (height) *height = 8; // Default text height
|
||||
}
|
||||
#elif defined(MESHTASTIC)
|
||||
if (width) *width = display->getStringWidth(text);
|
||||
// FONT_SMALL is 7 by 🧐
|
||||
if (height) *height = 7; // FONT_HEIGHT_SMALL;
|
||||
#endif
|
||||
}
|
||||
|
||||
void VirtualKeyboard::drawKeyboard() {
|
||||
if (!display) return;
|
||||
|
||||
#ifdef MESHCORE
|
||||
display->setTextSize(1);
|
||||
#elif defined(MESHTASTIC)
|
||||
display->setFont(FONT_SMALL);
|
||||
// display->clear();
|
||||
#endif
|
||||
|
||||
// Calculate max standard key width (kw)
|
||||
uint16_t kw = 0;
|
||||
for (int row = 0; row < getRows(); row++) {
|
||||
for (int col = 0; col < getCols() - 1; col++) { // Exclude rightmost column (control keys)
|
||||
uint16_t keyWidth = 0;
|
||||
const char *keyText = getKeyText(row, col);
|
||||
getTextBounds(keyText, &keyWidth, nullptr);
|
||||
if (keyWidth > kw) {
|
||||
kw = keyWidth;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate max control key width (cw)
|
||||
uint16_t cw = 0;
|
||||
for (int row = 0; row < getRows(); row++) {
|
||||
int col = getCols() - 1; // Only check rightmost column
|
||||
uint16_t keyWidth = 0;
|
||||
const char *keyText = getKeyText(row, col);
|
||||
getTextBounds(keyText, &keyWidth, nullptr);
|
||||
if (keyWidth > cw) {
|
||||
cw = keyWidth;
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate horizontal spacing
|
||||
uint16_t totalKeyWidth = (getCols() - 1) * kw + cw;
|
||||
uint16_t spacingX = (keyboardWidth - totalKeyWidth) / (getCols() - 1);
|
||||
uint16_t fraction = (keyboardWidth - totalKeyWidth) % (getCols() - 1);
|
||||
|
||||
// Calculate key height and vertical spacing
|
||||
uint16_t keyH = 0;
|
||||
getTextBounds(getKeyText(0, 0), nullptr, &keyH);
|
||||
uint16_t spacingY = (keyboardHeight - getRows() * keyH) / (getRows() - 1);
|
||||
|
||||
#ifdef MESHTASTIC
|
||||
spacingY = 2;
|
||||
#endif
|
||||
|
||||
for (int row = 0; row < getRows(); row++) {
|
||||
for (int col = 0; col < getCols(); col++) {
|
||||
const char *label = getKeyText(row, col);
|
||||
|
||||
uint16_t currentKeyWidth = (col == getCols() - 1) ? cw : kw;
|
||||
|
||||
// Calculate x position dynamically
|
||||
int currentX = startX + col * (kw + spacingX) + ((col == getCols() - 1) ? (cw - kw) : 0);
|
||||
|
||||
if (col == getCols() - 1) {
|
||||
currentX = keyboardWidth - cw;
|
||||
// currentX += fraction * (getCols() - 1);
|
||||
}
|
||||
|
||||
// Calculate y position
|
||||
int y = startY + row * keyH + row * spacingY;
|
||||
|
||||
// Check if this is the currently selected key
|
||||
bool selected = (row == cursorRow && col == cursorColumn);
|
||||
|
||||
if (selected) {
|
||||
// Highlight the selected key with inverted colors
|
||||
#ifdef MESHCORE
|
||||
display->setColor(DisplayDriver::LIGHT);
|
||||
display->fillRect(currentX - 1, y - 1, currentKeyWidth + 2, keyH + 2);
|
||||
display->setColor(DisplayDriver::DARK); // Dark text on light background
|
||||
#elif defined(MESHTASTIC)
|
||||
display->setColor(OLEDDISPLAY_COLOR::WHITE);
|
||||
if (col == 0 && startX > 0) {
|
||||
display->fillRect(currentX - 1, y + 2, currentKeyWidth + 1, keyH + 2);
|
||||
} else {
|
||||
display->fillRect(currentX - 2, y + 2, currentKeyWidth + 1, keyH + 2);
|
||||
}
|
||||
display->setColor(OLEDDISPLAY_COLOR::BLACK); // Dark text on light background
|
||||
#endif
|
||||
} else {
|
||||
#ifdef MESHCORE
|
||||
display->setColor(DisplayDriver::LIGHT); // Light text on dark background
|
||||
#elif defined(MESHTASTIC)
|
||||
display->setColor(OLEDDISPLAY_COLOR::WHITE); // Light text on dark background
|
||||
#endif
|
||||
}
|
||||
|
||||
// Draw the key text at the key position
|
||||
#ifdef MESHCORE
|
||||
display->setCursor(currentX, y);
|
||||
display->print(label);
|
||||
#elif defined(MESHTASTIC)
|
||||
display->drawString(currentX, y, label);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
// Reset text color to default
|
||||
#ifdef MESHCORE
|
||||
display->setColor(DisplayDriver::LIGHT);
|
||||
#elif defined(MESHTASTIC)
|
||||
display->setColor(OLEDDISPLAY_COLOR::WHITE);
|
||||
#endif
|
||||
}
|
||||
|
||||
void VirtualKeyboard::render() {
|
||||
drawKeyboard();
|
||||
}
|
108
src/graphics/VirtualKeyboard.h
Normal file
108
src/graphics/VirtualKeyboard.h
Normal file
@ -0,0 +1,108 @@
|
||||
/*
|
||||
* VirtualKeyboard.h
|
||||
* Author TSAO (hey@tsao.dev) 2025
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef MESHCORE
|
||||
#include <Adafruit_SSD1306.h>
|
||||
#include <helpers/ui/DisplayDriver.h>
|
||||
#elif defined(MESHTASTIC)
|
||||
#include "graphics/Screen.h"
|
||||
|
||||
#include <OLEDDisplay.h>
|
||||
#endif
|
||||
|
||||
// Callback function type for key press events
|
||||
typedef void (*KeyPressCallback)(const char *pressedKey, const char *currentText);
|
||||
|
||||
#ifdef VIRTUAL_KEYBOARD_EN
|
||||
static const int VIRTUAL_KEYBOARD_ROWS = 4;
|
||||
static const int VIRTUAL_KEYBOARD_COLS = 11;
|
||||
|
||||
static const char *keyboardLayout[VIRTUAL_KEYBOARD_ROWS][VIRTUAL_KEYBOARD_COLS] = {
|
||||
{ "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "DEL" },
|
||||
{ "q", "w", "e", "r", "t", "y", "u", "i", "o", "p", "OK" },
|
||||
{ "a", "s", "d", "f", "g", "h", "j", "k", "l", ";", "SPACE" },
|
||||
{ "z", "x", "c", "v", "b", "n", "m", ".", ",", "?", "CAPS" },
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef VIRTUAL_KEYBOARD_CN
|
||||
static const int VIRTUAL_KEYBOARD_ROWS = 4;
|
||||
static const int VIRTUAL_KEYBOARD_COLS = 11;
|
||||
|
||||
static const char *keyboardLayout[VIRTUAL_KEYBOARD_ROWS][VIRTUAL_KEYBOARD_COLS] = {
|
||||
{ "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "DEL" },
|
||||
{ "q", "w", "e", "r", "t", "y", "u", "i", "o", "p", "OK" },
|
||||
{ "a", "s", "d", "f", "g", "h", "j", "k", "l", ";", "SPACE" },
|
||||
{ "z", "x", "c", "v", "b", "n", "m", ".", ",", "?", "EN/CN" },
|
||||
};
|
||||
#endif
|
||||
|
||||
class VirtualKeyboard {
|
||||
private:
|
||||
#ifdef MESHCORE
|
||||
DisplayDriver *display;
|
||||
#elif defined(MESHTASTIC)
|
||||
OLEDDisplay *display;
|
||||
#endif
|
||||
|
||||
int cursorRow = 0;
|
||||
int cursorColumn = 0;
|
||||
bool capsLockEnabled = false;
|
||||
|
||||
char inputBuffer[160];
|
||||
int bufferLength = 0;
|
||||
|
||||
// Keyboard positioning and dimensions
|
||||
int startX = 0;
|
||||
int startY = 0;
|
||||
int keyboardWidth = 0;
|
||||
int keyboardHeight = 0;
|
||||
|
||||
// Callback function for key press events
|
||||
KeyPressCallback keyPressCallback = nullptr;
|
||||
|
||||
void drawKeyboard();
|
||||
const char *getKeyText(int row, int col);
|
||||
|
||||
public:
|
||||
#ifdef MESHCORE
|
||||
VirtualKeyboard(DisplayDriver *display, int startX = 0, int startY = 0, int keyboardWidth = 0,
|
||||
int keyboardHeight = 0);
|
||||
#elif defined(MESHTASTIC)
|
||||
VirtualKeyboard(OLEDDisplay *display, int startX = 0, int startY = 0, int keyboardWidth = 0,
|
||||
int keyboardHeight = 0);
|
||||
#endif
|
||||
|
||||
void moveCursor(int deltaRow, int deltaColumn);
|
||||
void moveRight(int steps = 1);
|
||||
void moveLeft(int steps = 1);
|
||||
void moveUp(int steps = 1);
|
||||
void moveDown(int steps = 1);
|
||||
|
||||
const char *pressCurrentKey();
|
||||
void clear();
|
||||
void reset();
|
||||
|
||||
const char *getText() const { return inputBuffer; }
|
||||
int getTextLength() const { return bufferLength; }
|
||||
|
||||
// Usage: kb.setKeyPressCallback([](const char* key, const char* text) { ... });
|
||||
void setKeyPressCallback(KeyPressCallback callback);
|
||||
|
||||
void getTextBounds(const char *text, uint16_t *width, uint16_t *height);
|
||||
void render();
|
||||
|
||||
int getRows() const { return VIRTUAL_KEYBOARD_ROWS; }
|
||||
int getCols() const { return VIRTUAL_KEYBOARD_COLS; }
|
||||
|
||||
const char *getKeyAt(int row, int col) const {
|
||||
if (row >= 0 && row < VIRTUAL_KEYBOARD_ROWS && col >= 0 && col < VIRTUAL_KEYBOARD_COLS) {
|
||||
return keyboardLayout[row][col];
|
||||
}
|
||||
return "";
|
||||
}
|
||||
};
|
@ -263,12 +263,6 @@ void drawFrameSettings(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t
|
||||
display->drawString(x + 1, y, "USB");
|
||||
}
|
||||
|
||||
// auto mode = DisplayFormatters::getModemPresetDisplayName(config.lora.modem_preset, true);
|
||||
|
||||
// display->drawString(x + SCREEN_WIDTH - display->getStringWidth(mode), y, mode);
|
||||
// if (config.display.heading_bold)
|
||||
// display->drawString(x + SCREEN_WIDTH - display->getStringWidth(mode) - 1, y, mode);
|
||||
|
||||
uint32_t currentMillis = millis();
|
||||
uint32_t seconds = currentMillis / 1000;
|
||||
uint32_t minutes = seconds / 60;
|
||||
@ -398,7 +392,7 @@ void drawLoRaFocused(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x,
|
||||
display->drawString(nameX, getTextPositions(display)[line++], shortnameble);
|
||||
|
||||
// === Second Row: Radio Preset ===
|
||||
auto mode = DisplayFormatters::getModemPresetDisplayName(config.lora.modem_preset, false);
|
||||
auto mode = DisplayFormatters::getModemPresetDisplayName(config.lora.modem_preset, false, config.lora.use_preset);
|
||||
char regionradiopreset[25];
|
||||
const char *region = myRegion ? myRegion->name : NULL;
|
||||
if (region != nullptr) {
|
||||
|
@ -368,7 +368,7 @@ const char *Channels::getName(size_t chIndex)
|
||||
// Per mesh.proto spec, if bandwidth is specified we must ignore modemPreset enum, we assume that in that case
|
||||
// the app effed up and forgot to set channelSettings.name
|
||||
if (config.lora.use_preset) {
|
||||
channelName = DisplayFormatters::getModemPresetDisplayName(config.lora.modem_preset, false);
|
||||
channelName = DisplayFormatters::getModemPresetDisplayName(config.lora.modem_preset, false, config.lora.use_preset);
|
||||
} else {
|
||||
channelName = "Custom";
|
||||
}
|
||||
@ -382,7 +382,8 @@ bool Channels::isDefaultChannel(ChannelIndex chIndex)
|
||||
const auto &ch = getByIndex(chIndex);
|
||||
if (ch.settings.psk.size == 1 && ch.settings.psk.bytes[0] == 1) {
|
||||
const char *name = getName(chIndex);
|
||||
const char *presetName = DisplayFormatters::getModemPresetDisplayName(config.lora.modem_preset, false);
|
||||
const char *presetName =
|
||||
DisplayFormatters::getModemPresetDisplayName(config.lora.modem_preset, false, config.lora.use_preset);
|
||||
// Check if the name is the default derived from the modem preset
|
||||
if (strcmp(name, presetName) == 0)
|
||||
return true;
|
||||
|
@ -586,7 +586,8 @@ void RadioInterface::applyModemConfig()
|
||||
|
||||
// Check if we use the default frequency slot
|
||||
RadioInterface::uses_default_frequency_slot =
|
||||
channel_num == hash(DisplayFormatters::getModemPresetDisplayName(config.lora.modem_preset, false)) % numChannels;
|
||||
channel_num ==
|
||||
hash(DisplayFormatters::getModemPresetDisplayName(config.lora.modem_preset, false, config.lora.use_preset)) % numChannels;
|
||||
|
||||
// Old frequency selection formula
|
||||
// float freq = myRegion->freqStart + ((((myRegion->freqEnd - myRegion->freqStart) / numChannels) / 2) * channel_num);
|
||||
|
@ -1,15 +0,0 @@
|
||||
; GAT562 Mesh Tracker Pro with Trackball support
|
||||
[env:gat562_mesh_tracker_pro]
|
||||
extends = nrf52840_base
|
||||
board = gat562_mesh_tracker_pro
|
||||
board_check = true
|
||||
build_flags = ${nrf52840_base.build_flags}
|
||||
-I variants/nrf52840/gat562_mesh_tracker_pro
|
||||
-D GAT562_MESH_TRACKER_PRO
|
||||
-DGPS_POWER_TOGGLE ; comment this line to disable triple press function on the user button to turn off gps entirely.
|
||||
-DRADIOLIB_EXCLUDE_SX128X=1
|
||||
-DRADIOLIB_EXCLUDE_SX127X=1
|
||||
-DRADIOLIB_EXCLUDE_LR11X0=1
|
||||
build_src_filter = ${nrf52_base.build_src_filter} +<../variants/nrf52840/gat562_mesh_tracker_pro>
|
||||
lib_deps =
|
||||
${nrf52840_base.lib_deps}
|
@ -1,54 +0,0 @@
|
||||
/*
|
||||
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
|
||||
0, 1, 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()
|
||||
{
|
||||
// LED1 & LED2
|
||||
pinMode(PIN_LED1, OUTPUT);
|
||||
ledOff(PIN_LED1);
|
||||
|
||||
pinMode(PIN_LED2, OUTPUT);
|
||||
ledOff(PIN_LED2);
|
||||
|
||||
// 3V3 Power Rail
|
||||
pinMode(PIN_3V3_EN, OUTPUT);
|
||||
digitalWrite(PIN_3V3_EN, HIGH);
|
||||
|
||||
// Initialize trackball pins as inputs with pullup
|
||||
#ifdef HAS_TRACKBALL
|
||||
pinMode(TB_UP, INPUT_PULLUP);
|
||||
pinMode(TB_DOWN, INPUT_PULLUP);
|
||||
pinMode(TB_LEFT, INPUT_PULLUP);
|
||||
pinMode(TB_RIGHT, INPUT_PULLUP);
|
||||
pinMode(TB_PRESS, INPUT_PULLUP);
|
||||
#endif
|
||||
}
|
@ -1,300 +0,0 @@
|
||||
/*
|
||||
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_GAT562_MESH_TRACKER_PRO_
|
||||
#define _VARIANT_GAT562_MESH_TRACKER_PRO_
|
||||
|
||||
// led pin 2 (blue), see https://github.com/meshtastic/firmware/blob/master/src/mesh/NodeDB.cpp#L723
|
||||
#define RAK4630
|
||||
|
||||
/** Master clock frequency */
|
||||
#define VARIANT_MCK (64000000ul)
|
||||
|
||||
#define USE_LFXO // Board uses 32khz crystal for LF
|
||||
// define USE_LFRC // Board uses RC for LF
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Headers
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
#include "WVariant.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif // __cplusplus
|
||||
|
||||
// Number of pins defined in PinDescription array
|
||||
#define PINS_COUNT (48)
|
||||
#define NUM_DIGITAL_PINS (48)
|
||||
#define NUM_ANALOG_INPUTS (6)
|
||||
#define NUM_ANALOG_OUTPUTS (0)
|
||||
|
||||
// LEDs
|
||||
#define PIN_LED1 (35)
|
||||
#define PIN_LED2 (36)
|
||||
|
||||
#define LED_BUILTIN PIN_LED1
|
||||
#define LED_CONN PIN_LED2
|
||||
|
||||
#define LED_GREEN PIN_LED1
|
||||
#define LED_BLUE PIN_LED2
|
||||
|
||||
#define LED_STATE_ON 1 // State when LED is litted
|
||||
|
||||
/*
|
||||
* Buttons
|
||||
*/
|
||||
|
||||
#define CANCEL_BUTTON_PIN 9
|
||||
#define BUTTON_NEED_PULLUP
|
||||
#define CANCEL_BUTTON_ACTIVE_LOW true
|
||||
#define CANCEL_BUTTON_ACTIVE_PULLUP false
|
||||
|
||||
/*
|
||||
* Analog pins
|
||||
*/
|
||||
#define PIN_A0 (5)
|
||||
#define PIN_A1 (31)
|
||||
#define PIN_A2 (28)
|
||||
#define PIN_A3 (29)
|
||||
#define PIN_A4 (30)
|
||||
#define PIN_A5 (31)
|
||||
#define PIN_A6 (0xff)
|
||||
#define PIN_A7 (0xff)
|
||||
|
||||
static const uint8_t A0 = PIN_A0;
|
||||
static const uint8_t A1 = PIN_A1;
|
||||
static const uint8_t A2 = PIN_A2;
|
||||
static const uint8_t A3 = PIN_A3;
|
||||
static const uint8_t A4 = PIN_A4;
|
||||
static const uint8_t A5 = PIN_A5;
|
||||
static const uint8_t A6 = PIN_A6;
|
||||
static const uint8_t A7 = PIN_A7;
|
||||
#define ADC_RESOLUTION 14
|
||||
|
||||
// Other pins
|
||||
#define PIN_AREF (2)
|
||||
#define PIN_NFC1 (9)
|
||||
#define PIN_NFC2 (10)
|
||||
|
||||
static const uint8_t AREF = PIN_AREF;
|
||||
|
||||
/*
|
||||
* Serial interfaces
|
||||
*/
|
||||
#define PIN_SERIAL1_RX (15)
|
||||
#define PIN_SERIAL1_TX (16)
|
||||
|
||||
// Connected to Jlink CDC
|
||||
#define PIN_SERIAL2_RX (8)
|
||||
#define PIN_SERIAL2_TX (6)
|
||||
|
||||
/*
|
||||
* SPI Interfaces
|
||||
*/
|
||||
#define SPI_INTERFACES_COUNT 2
|
||||
|
||||
#define PIN_SPI_MISO (45)
|
||||
#define PIN_SPI_MOSI (44)
|
||||
#define PIN_SPI_SCK (43)
|
||||
|
||||
#define PIN_SPI1_MISO (29) // (0 + 29)
|
||||
#define PIN_SPI1_MOSI (30) // (0 + 30)
|
||||
#define PIN_SPI1_SCK (3) // (0 + 3)
|
||||
|
||||
static const uint8_t SS = 42;
|
||||
static const uint8_t MOSI = PIN_SPI_MOSI;
|
||||
static const uint8_t MISO = PIN_SPI_MISO;
|
||||
static const uint8_t SCK = PIN_SPI_SCK;
|
||||
|
||||
/*
|
||||
* eink display pins
|
||||
*/
|
||||
|
||||
// #define PIN_EINK_CS (0 + 26)
|
||||
// #define PIN_EINK_BUSY (0 + 4)
|
||||
// #define PIN_EINK_DC (0 + 17)
|
||||
// #define PIN_EINK_RES (-1)
|
||||
// #define PIN_EINK_SCLK (0 + 3)
|
||||
// #define PIN_EINK_MOSI (0 + 30) // also called SDI
|
||||
|
||||
// #define USE_EINK
|
||||
|
||||
// Display - OLED connected via I2C
|
||||
#define HAS_SCREEN 1
|
||||
#define USE_SSD1306
|
||||
|
||||
// RAKRGB
|
||||
// #define HAS_NCP5623
|
||||
|
||||
/*
|
||||
* Wire Interfaces
|
||||
*/
|
||||
#define WIRE_INTERFACES_COUNT 1
|
||||
|
||||
#define PIN_WIRE_SDA (13)
|
||||
#define PIN_WIRE_SCL (14)
|
||||
|
||||
// QSPI Pins
|
||||
#define PIN_QSPI_SCK 3
|
||||
#define PIN_QSPI_CS 26
|
||||
#define PIN_QSPI_IO0 30
|
||||
#define PIN_QSPI_IO1 29
|
||||
#define PIN_QSPI_IO2 28
|
||||
#define PIN_QSPI_IO3 2
|
||||
|
||||
// On-board QSPI Flash
|
||||
#define EXTERNAL_FLASH_DEVICES IS25LP080D
|
||||
#define EXTERNAL_FLASH_USE_QSPI
|
||||
|
||||
/* @note RAK5005-O GPIO mapping to RAK4631 GPIO ports
|
||||
RAK5005-O <-> nRF52840
|
||||
IO1 <-> P0.17 (Arduino GPIO number 17)
|
||||
IO2 <-> P1.02 (Arduino GPIO number 34)
|
||||
IO3 <-> P0.21 (Arduino GPIO number 21)
|
||||
IO4 <-> P0.04 (Arduino GPIO number 4)
|
||||
IO5 <-> P0.09 (Arduino GPIO number 9)
|
||||
IO6 <-> P0.10 (Arduino GPIO number 10)
|
||||
IO7 <-> P0.28 (Arduino GPIO number 28)
|
||||
SW1 <-> P0.01 (Arduino GPIO number 1)
|
||||
A0 <-> P0.04/AIN2 (Arduino Analog A2
|
||||
A1 <-> P0.31/AIN7 (Arduino Analog A7
|
||||
SPI_CS <-> P0.26 (Arduino GPIO number 26)
|
||||
*/
|
||||
|
||||
// RAK4630 LoRa module
|
||||
|
||||
/* Setup of the SX1262 LoRa module ( https://docs.rakwireless.com/Product-Categories/WisBlock/RAK4631/Datasheet/ )
|
||||
|
||||
P1.10 NSS SPI NSS (Arduino GPIO number 42)
|
||||
P1.11 SCK SPI CLK (Arduino GPIO number 43)
|
||||
P1.12 MOSI SPI MOSI (Arduino GPIO number 44)
|
||||
P1.13 MISO SPI MISO (Arduino GPIO number 45)
|
||||
P1.14 BUSY BUSY signal (Arduino GPIO number 46)
|
||||
P1.15 DIO1 DIO1 event interrupt (Arduino GPIO number 47)
|
||||
P1.06 NRESET NRESET manual reset of the SX1262 (Arduino GPIO number 38)
|
||||
|
||||
Important for successful SX1262 initialization:
|
||||
|
||||
* Setup DIO2 to control the antenna switch
|
||||
* Setup DIO3 to control the TCXO power supply
|
||||
* Setup the SX1262 to use it's DCDC regulator and not the LDO
|
||||
* RAK4630 schematics show GPIO P1.07 connected to the antenna switch, but it should not be initialized, as DIO2 will do the
|
||||
control of the antenna switch
|
||||
|
||||
SO GPIO 39/TXEN MAY NOT BE DEFINED FOR SUCCESSFUL OPERATION OF THE SX1262 - TG
|
||||
|
||||
*/
|
||||
|
||||
// configure the SET pin on the RAK12039 sensor board to disable the sensor while not reading
|
||||
// air quality telemetry. PIN_NFC2 doesn't seem to be used anywhere else in the codebase, but if
|
||||
// you're having problems with your node behaving weirdly when a RAK12039 board isn't connected,
|
||||
// try disabling this.
|
||||
// #define PMSA003I_ENABLE_PIN PIN_NFC2
|
||||
|
||||
// #define DETECTION_SENSOR_EN 4
|
||||
|
||||
#define USE_SX1262
|
||||
#define SX126X_CS (42)
|
||||
#define SX126X_DIO1 (47)
|
||||
#define SX126X_BUSY (46)
|
||||
#define SX126X_RESET (38)
|
||||
// #define SX126X_TXEN (39)
|
||||
// #define SX126X_RXEN (37)
|
||||
#define SX126X_POWER_EN (37)
|
||||
// DIO2 controlls an antenna switch and the TCXO voltage is controlled by DIO3
|
||||
#define SX126X_DIO2_AS_RF_SWITCH
|
||||
#define SX126X_DIO3_TCXO_VOLTAGE 1.8
|
||||
|
||||
// Testing USB detection
|
||||
#define NRF_APM
|
||||
|
||||
// enables 3.3V periphery like GPS or IO Module
|
||||
// Do not toggle this for GPS power savings
|
||||
#define PIN_3V3_EN (34)
|
||||
|
||||
// RAK1910 GPS module
|
||||
// If using the wisblock GPS module and pluged into Port A on WisBlock base
|
||||
// IO1 is hooked to PPS (pin 12 on header) = gpio 17
|
||||
// IO2 is hooked to GPS RESET = gpio 34, but it can not be used to this because IO2 is ALSO used to control 3V3_S power (1 is on).
|
||||
// Therefore must be 1 to keep peripherals powered
|
||||
// Power is on the controllable 3V3_S rail
|
||||
// #define PIN_GPS_RESET (34)
|
||||
// #define PIN_GPS_EN PIN_3V3_EN
|
||||
#define PIN_GPS_PPS (17) // Pulse per second input from the GPS
|
||||
|
||||
#define GPS_BAUDRATE 9600
|
||||
|
||||
#define GPS_RX_PIN PIN_SERIAL1_RX
|
||||
#define GPS_TX_PIN PIN_SERIAL1_TX
|
||||
|
||||
// Define pin to enable GPS toggle (set GPIO to LOW) via user button triple press
|
||||
|
||||
// RAK12002 RTC Module
|
||||
// #define RV3028_RTC (uint8_t)0b1010010
|
||||
|
||||
// RAK18001 Buzzer in Slot C
|
||||
// #define PIN_BUZZER 21 // IO3 is PWM2
|
||||
// NEW: set this via protobuf instead!
|
||||
|
||||
// Battery
|
||||
// The battery sense is hooked to pin A0 (5)
|
||||
#define BATTERY_PIN PIN_A0
|
||||
// and has 12 bit resolution
|
||||
#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 1.73
|
||||
|
||||
// #define HAS_RTC 1
|
||||
|
||||
// #define HAS_ETHERNET 1
|
||||
|
||||
// #define RAK_4631 1
|
||||
|
||||
// #define PIN_ETHERNET_RESET 21
|
||||
// #define PIN_ETHERNET_SS PIN_EINK_CS
|
||||
// #define ETH_SPI_PORT SPI1
|
||||
// #define AQ_SET_PIN 10
|
||||
|
||||
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
// Trackball Configuration
|
||||
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||
#define CANNED_MESSAGE_MODULE_ENABLE 1
|
||||
#define CANNED_MESSAGE_ADD_CONFIRMATION 1
|
||||
|
||||
// Trackball pins
|
||||
#define HAS_TRACKBALL 1
|
||||
#define TB_LEFT 30 // P0.30
|
||||
#define TB_DOWN 4 // P0.04
|
||||
#define TB_RIGHT 31 // P0.31
|
||||
#define TB_UP 28 // P0.28
|
||||
#define TB_PRESS 26 // P0.26 (SELECT)
|
||||
#define TB_DIRECTION FALLING
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Arduino objects - C++ only
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
#endif
|
@ -124,8 +124,7 @@ extern "C" {
|
||||
#define GPS_RTC_INT (0 + 15) // P0.15, normal is LOW, wake by HIGH
|
||||
#define GPS_RESETB_OUT (32 + 14) // P1.14, always input pull_up
|
||||
|
||||
#define GPS_FIX_HOLD_TIME 15000 // ms
|
||||
#define BATTERY_PIN 2 // P0.02/AIN0, BAT_ADC
|
||||
#define BATTERY_PIN 2 // P0.02/AIN0, BAT_ADC
|
||||
#define BATTERY_IMMUTABLE
|
||||
#define ADC_MULTIPLIER (2.0F)
|
||||
// P0.04/AIN2 is VCC_ADC, P0.05/AIN3 is CHARGER_DET, P1.03 is CHARGE_STA, P1.04 is CHARGE_DONE
|
||||
|
@ -123,7 +123,6 @@ extern "C" {
|
||||
#define GPS_RESETB_OUT (32 + 14) // P1.14, awlays input pull_up
|
||||
|
||||
// #define GPS_THREAD_INTERVAL 50
|
||||
#define GPS_FIX_HOLD_TIME 15000 // ms
|
||||
|
||||
#define BATTERY_PIN 2
|
||||
// #define ADC_CHANNEL ADC1_GPIO2_CHANNEL
|
||||
|
Loading…
Reference in New Issue
Block a user