mirror of
https://github.com/MarekZegare4/MeshCore-Solo.git
synced 2026-11-01 10:21:59 +00:00
Add Simpson board support
This commit is contained in:
@@ -670,6 +670,16 @@ public:
|
|||||||
: _task(task), _rtc(rtc), _sensors(sensors), _node_prefs(node_prefs), _page(0),
|
: _task(task), _rtc(rtc), _sensors(sensors), _node_prefs(node_prefs), _page(0),
|
||||||
_prev_page(0), _shutdown_init(false), sensors_lpp(200) { }
|
_prev_page(0), _shutdown_init(false), sensors_lpp(200) { }
|
||||||
|
|
||||||
|
void showBluetoothPage() {
|
||||||
|
_page = BLUETOOTH;
|
||||||
|
_quick_sel = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void showGpsPage() {
|
||||||
|
_page = STATUS;
|
||||||
|
_quick_sel = 0;
|
||||||
|
}
|
||||||
|
|
||||||
// Flips home screen between LOCK page and the page that was showing before locking
|
// Flips home screen between LOCK page and the page that was showing before locking
|
||||||
void setLocked(bool locked) {
|
void setLocked(bool locked) {
|
||||||
if (locked) {
|
if (locked) {
|
||||||
|
|||||||
@@ -291,6 +291,9 @@ struct KeyboardWidget {
|
|||||||
// next letter, then reverts) — Hold-Enter on Shift toggles caps_lock, which
|
// next letter, then reverts) — Hold-Enter on Shift toggles caps_lock, which
|
||||||
// keeps it on for a whole run of capitals instead.
|
// keeps it on for a whole run of capitals instead.
|
||||||
bool caps_lock = false;
|
bool caps_lock = false;
|
||||||
|
bool _physical_t9_input = false;
|
||||||
|
const char* input_mode_hint = nullptr;
|
||||||
|
bool hide_keyboard_grid = false;
|
||||||
// Set by render() every time it's actually called; UITask clears it before
|
// Set by render() every time it's actually called; UITask clears it before
|
||||||
// curr->render() each frame (beginFrame()) so it reflects only "was the
|
// curr->render() each frame (beginFrame()) so it reflects only "was the
|
||||||
// keyboard the thing on screen this frame" -- lets the alert overlay (new
|
// keyboard the thing on screen this frame" -- lets the alert overlay (new
|
||||||
@@ -355,6 +358,16 @@ struct KeyboardWidget {
|
|||||||
// the #@/abc key's existing cycle (case 4 below) reaches it for free.
|
// the #@/abc key's existing cycle (case 4 below) reaches it for free.
|
||||||
int totalPages() const { return hasAltAlphabet() ? 3 : 2; }
|
int totalPages() const { return hasAltAlphabet() ? 3 : 2; }
|
||||||
bool pageIsSymbols(int pg) const { return pg == totalPages() - 1; }
|
bool pageIsSymbols(int pg) const { return pg == totalPages() - 1; }
|
||||||
|
void openSymbolsPage() {
|
||||||
|
if (!_visible || isPin() || _ph_menu.active || cursor_mode || accent_active) return;
|
||||||
|
page = totalPages() - 1;
|
||||||
|
t9_cell = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void backspaceTyped() {
|
||||||
|
if (_visible) handleInput(0x08);
|
||||||
|
}
|
||||||
|
|
||||||
// Which script (Latin/Cyrillic/Greek) the given non-symbols page shows.
|
// Which script (Latin/Cyrillic/Greek) the given non-symbols page shows.
|
||||||
uint8_t scriptAt(int pg) const { return pg == 0 ? mainScript() : altScript(); }
|
uint8_t scriptAt(int pg) const { return pg == 0 ? mainScript() : altScript(); }
|
||||||
|
|
||||||
@@ -492,6 +505,29 @@ struct KeyboardWidget {
|
|||||||
insertGlyph(one, false);
|
insertGlyph(one, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(SIMPSON)
|
||||||
|
void typePhysicalT9Cell(int cell, bool uppercase) {
|
||||||
|
if (!_visible || isPin() || cell < 0 || cell >= KB_T9_ROWS * KB_T9_COLS ||
|
||||||
|
_ph_menu.active || cursor_mode || accent_active) return;
|
||||||
|
|
||||||
|
const int saved_row = row;
|
||||||
|
const int saved_col = col;
|
||||||
|
const int saved_page = page;
|
||||||
|
const bool saved_caps = caps;
|
||||||
|
row = cell / KB_T9_COLS;
|
||||||
|
col = cell % KB_T9_COLS;
|
||||||
|
page = 0;
|
||||||
|
caps = uppercase;
|
||||||
|
_physical_t9_input = true;
|
||||||
|
handleInput(KEY_ENTER);
|
||||||
|
_physical_t9_input = false;
|
||||||
|
row = saved_row;
|
||||||
|
col = saved_col;
|
||||||
|
page = saved_page;
|
||||||
|
caps = saved_caps;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void clearPlaceholders() { _ph_count = 0; }
|
void clearPlaceholders() { _ph_count = 0; }
|
||||||
|
|
||||||
void addPlaceholder(const char* ph) {
|
void addPlaceholder(const char* ph) {
|
||||||
@@ -604,7 +640,8 @@ struct KeyboardWidget {
|
|||||||
// lines, so the preview keeps the same height whichever mode is on.
|
// lines, so the preview keeps the same height whichever mode is on.
|
||||||
// A tall screen (the 4.2" panel: 20 lines) gives the keys half a line more each.
|
// A tall screen (the 4.2" panel: 20 lines) gives the keys half a line more each.
|
||||||
const int key_lh = display.height() >= 18 * lh ? lh * 3 / 2 : lh;
|
const int key_lh = display.height() >= 18 * lh ? lh * 3 / 2 : lh;
|
||||||
const int kb_h = compact_ui ? (KB_T9_ROWS + 1) * lh : (rows + 1) * key_lh;
|
const bool hide_grid = hide_keyboard_grid && !isPin();
|
||||||
|
const int kb_h = hide_grid ? lh : (compact_ui ? (KB_T9_ROWS + 1) * lh : (rows + 1) * key_lh);
|
||||||
const int preview_h = display.height() - kb_h - display.sepH();
|
const int preview_h = display.height() - kb_h - display.sepH();
|
||||||
const int prev_lines = (preview_h / lh) > 1 ? (preview_h / lh) : 1;
|
const int prev_lines = (preview_h / lh) > 1 ? (preview_h / lh) : 1;
|
||||||
const int sep_y = prev_lines * lh;
|
const int sep_y = prev_lines * lh;
|
||||||
@@ -794,13 +831,21 @@ struct KeyboardWidget {
|
|||||||
// submit -- so they get no hint of their own). Physical buttons (if used
|
// submit -- so they get no hint of their own). Physical buttons (if used
|
||||||
// instead of/alongside CardKB) still drive row/col/page as normal; it
|
// instead of/alongside CardKB) still drive row/col/page as normal; it
|
||||||
// just won't be visible on this screen which cell is selected.
|
// just won't be visible on this screen which cell is selected.
|
||||||
if (compact_ui) {
|
if (compact_ui || hide_grid) {
|
||||||
display.setColor(UIColor::primary_txt);
|
if (!hide_grid) {
|
||||||
if (cursor_mode) {
|
display.setColor(UIColor::primary_txt);
|
||||||
display.drawTextCentered(display.width() / 2, chars_y, "<> char ^v word");
|
if (cursor_mode) {
|
||||||
} else {
|
display.drawTextCentered(display.width() / 2, chars_y, "<> char ^v word");
|
||||||
display.drawTextCentered(display.width() / 2, chars_y, "Tab: placeholders");
|
} else {
|
||||||
display.drawTextCentered(display.width() / 2, chars_y + lh, "Fn+letter: accent");
|
display.drawTextCentered(display.width() / 2, chars_y, "Tab: placeholders");
|
||||||
|
display.drawTextCentered(display.width() / 2, chars_y + lh, "Fn+letter: accent");
|
||||||
|
}
|
||||||
|
} else if (input_mode_hint) {
|
||||||
|
char hint[40];
|
||||||
|
snprintf(hint, sizeof(hint), "FN: %s", input_mode_hint);
|
||||||
|
display.setColor(UIColor::primary_txt);
|
||||||
|
display.setCursor(display.width() - display.getTextWidth(hint) - 2, display.height() - lh);
|
||||||
|
display.print(hint);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// character grid
|
// character grid
|
||||||
@@ -1228,7 +1273,11 @@ struct KeyboardWidget {
|
|||||||
// the special row's DONE cell -- same as a physical button. CardKB's
|
// the special row's DONE cell -- same as a physical button. CardKB's
|
||||||
// own Enter is only ever KEY_ENTER when that's true (see pollCardKB()'s
|
// own Enter is only ever KEY_ENTER when that's true (see pollCardKB()'s
|
||||||
// KEY_KB_ENTER cases just above), so there's no ambiguity here.
|
// KEY_KB_ENTER cases just above), so there's no ambiguity here.
|
||||||
if (row < rows && isT9()) {
|
if (row < rows && isT9()
|
||||||
|
#if defined(SIMPSON)
|
||||||
|
&& !_physical_t9_input
|
||||||
|
#endif
|
||||||
|
) {
|
||||||
int cell = row * cols + col;
|
int cell = row * cols + col;
|
||||||
const char* group = t9GroupStr(cell);
|
const char* group = t9GroupStr(cell);
|
||||||
int glen = kbUtf8Len(group); // codepoint count, not byte length
|
int glen = kbUtf8Len(group); // codepoint count, not byte length
|
||||||
|
|||||||
@@ -11,6 +11,9 @@
|
|||||||
#include "target.h"
|
#include "target.h"
|
||||||
|
|
||||||
#include "CardKB.h"
|
#include "CardKB.h"
|
||||||
|
#if defined(SIMPSON)
|
||||||
|
#include <string.h>
|
||||||
|
#endif
|
||||||
#ifdef WIFI_SSID
|
#ifdef WIFI_SSID
|
||||||
#include <WiFi.h>
|
#include <WiFi.h>
|
||||||
#endif
|
#endif
|
||||||
@@ -120,6 +123,13 @@ void UITask::begin(DisplayDriver* display, SensorManager* sensors, NodePrefs* no
|
|||||||
_sensors = sensors;
|
_sensors = sensors;
|
||||||
_node_prefs = node_prefs;
|
_node_prefs = node_prefs;
|
||||||
_kb.prefs = node_prefs;
|
_kb.prefs = node_prefs;
|
||||||
|
#if defined(SIMPSON)
|
||||||
|
if (!_simpson_keypad.begin()) {
|
||||||
|
MESH_DEBUG_PRINTLN("Simpson keypad initialization failed");
|
||||||
|
}
|
||||||
|
_kb.input_mode_hint = "Ctl";
|
||||||
|
_kb.hide_keyboard_grid = true;
|
||||||
|
#endif
|
||||||
if (node_prefs) battery::useCurve(node_prefs->batt_curve_mv); // Settings > Battery curve
|
if (node_prefs) battery::useCurve(node_prefs->batt_curve_mv); // Settings > Battery curve
|
||||||
uint32_t aoff = autoOffMillis();
|
uint32_t aoff = autoOffMillis();
|
||||||
_auto_off = millis() + (aoff > 0 ? aoff : AUTO_OFF_MILLIS);
|
_auto_off = millis() + (aoff > 0 ? aoff : AUTO_OFF_MILLIS);
|
||||||
@@ -402,6 +412,20 @@ void UITask::gotoMessagesScreen() {
|
|||||||
setCurrScreen(messages_screen);
|
setCurrScreen(messages_screen);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(SIMPSON)
|
||||||
|
void UITask::gotoBluetoothHomePage() {
|
||||||
|
setCurrScreen(home);
|
||||||
|
static_cast<HomeScreen*>(home)->showBluetoothPage();
|
||||||
|
_next_refresh = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UITask::gotoGpsHomePage() {
|
||||||
|
setCurrScreen(home);
|
||||||
|
static_cast<HomeScreen*>(home)->showGpsPage();
|
||||||
|
_next_refresh = 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef SIM_PLATFORM
|
#ifdef SIM_PLATFORM
|
||||||
void UITask::simMessage(const char* text) {
|
void UITask::simMessage(const char* text) {
|
||||||
UiEvent ev = {};
|
UiEvent ev = {};
|
||||||
@@ -1066,6 +1090,114 @@ void UITask::pollHallSensor() {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(SIMPSON)
|
||||||
|
void UITask::pollSimpsonKeypad() {
|
||||||
|
const uint8_t key = _simpson_keypad.poll();
|
||||||
|
if (key != SIMPSON_KEY_NONE) handleSimpsonKeypadKey(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UITask::handleSimpsonKeypadKey(uint8_t key) {
|
||||||
|
if (checkDisplayOn(KEY_ENTER) == 0 || (_locked && !_unlock_kb)) return;
|
||||||
|
|
||||||
|
const uint32_t auto_off = autoOffMillis();
|
||||||
|
if (auto_off > 0) _auto_off = millis() + auto_off;
|
||||||
|
|
||||||
|
if (key == SIMPSON_KEY_MODE_CHANGED) {
|
||||||
|
static const char* const modes[] = { "Ctl", "abc", "ABC", "123" };
|
||||||
|
_kb.input_mode_hint = modes[_simpson_keypad.mode()];
|
||||||
|
_kb.hide_keyboard_grid = true;
|
||||||
|
showAlert(modes[_simpson_keypad.mode()], 1200);
|
||||||
|
_next_refresh = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (key) {
|
||||||
|
case SIMPSON_KEY_CANCEL:
|
||||||
|
enqueueKey(KEY_CANCEL);
|
||||||
|
break;
|
||||||
|
case SIMPSON_KEY_UP:
|
||||||
|
enqueueKey(KEY_UP);
|
||||||
|
break;
|
||||||
|
case SIMPSON_KEY_DOWN:
|
||||||
|
enqueueKey(KEY_DOWN);
|
||||||
|
break;
|
||||||
|
case SIMPSON_KEY_LEFT:
|
||||||
|
enqueueKey(KEY_LEFT);
|
||||||
|
break;
|
||||||
|
case SIMPSON_KEY_RIGHT:
|
||||||
|
enqueueKey(KEY_RIGHT);
|
||||||
|
break;
|
||||||
|
case SIMPSON_KEY_ENTER:
|
||||||
|
enqueueKey(_unlock_kb ? KEY_KB_ENTER : KEY_ENTER);
|
||||||
|
break;
|
||||||
|
case SIMPSON_KEY_BLUETOOTH:
|
||||||
|
if (!_unlock_kb) gotoBluetoothHomePage();
|
||||||
|
break;
|
||||||
|
case SIMPSON_KEY_GPS:
|
||||||
|
if (!_unlock_kb) gotoGpsHomePage();
|
||||||
|
break;
|
||||||
|
case SIMPSON_KEY_MESSAGES:
|
||||||
|
if (!_unlock_kb) gotoMessagesScreen();
|
||||||
|
break;
|
||||||
|
case SIMPSON_KEY_BRIGHTNESS_UP:
|
||||||
|
case SIMPSON_KEY_BRIGHTNESS_DOWN:
|
||||||
|
if (!_unlock_kb && _node_prefs) {
|
||||||
|
uint8_t& brightness = _node_prefs->display_brightness;
|
||||||
|
if (key == SIMPSON_KEY_BRIGHTNESS_UP && brightness < 4) ++brightness;
|
||||||
|
if (key == SIMPSON_KEY_BRIGHTNESS_DOWN && brightness > 0) --brightness;
|
||||||
|
applyBrightness();
|
||||||
|
bool dirty = true;
|
||||||
|
savePrefsIfDirty(dirty);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SIMPSON_KEY_SYMBOLS:
|
||||||
|
if (_unlock_kb) break;
|
||||||
|
if (_kb.isVisible()) _kb.openSymbolsPage();
|
||||||
|
else showAlert("Open a text field first", 1200);
|
||||||
|
break;
|
||||||
|
case SIMPSON_KEY_BACKSPACE:
|
||||||
|
if (_kb.isVisible()) {
|
||||||
|
if (_unlock_kb) handleUnlockKey(0x08);
|
||||||
|
else _kb.backspaceTyped();
|
||||||
|
} else {
|
||||||
|
enqueueKey(KEY_CANCEL);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (_kb.isVisible()) {
|
||||||
|
const auto typeInput = [this](char c) {
|
||||||
|
if (_unlock_kb) handleUnlockKey(c);
|
||||||
|
else _kb.handleInput(c);
|
||||||
|
};
|
||||||
|
switch (_simpson_keypad.mode()) {
|
||||||
|
case SIMPSON_KEYPAD_ABC:
|
||||||
|
case SIMPSON_KEYPAD_ABC_UPPER:
|
||||||
|
if (key == ',') {
|
||||||
|
_kb.typePhysicalT9Cell(0, _simpson_keypad.mode() == SIMPSON_KEYPAD_ABC_UPPER);
|
||||||
|
} else {
|
||||||
|
static const char t9_keys[] = "ADGJMPTW";
|
||||||
|
const char* found = strchr(t9_keys, (char)key);
|
||||||
|
if (found) {
|
||||||
|
_kb.typePhysicalT9Cell((int)(found - t9_keys) + 1,
|
||||||
|
_simpson_keypad.mode() == SIMPSON_KEYPAD_ABC_UPPER);
|
||||||
|
} else if (key == ' ') {
|
||||||
|
typeInput(' ');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SIMPSON_KEYPAD_NUMERIC:
|
||||||
|
if (key >= '0' && key <= '9') typeInput((char)key);
|
||||||
|
break;
|
||||||
|
case SIMPSON_KEYPAD_CONTROL:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
_next_refresh = 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "PerfL1.h"
|
#include "PerfL1.h"
|
||||||
|
|
||||||
void UITask::loop() {
|
void UITask::loop() {
|
||||||
@@ -1293,6 +1425,9 @@ void UITask::loop() {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
pollCardKB();
|
pollCardKB();
|
||||||
|
#if defined(SIMPSON)
|
||||||
|
pollSimpsonKeypad();
|
||||||
|
#endif
|
||||||
pollHallSensor();
|
pollHallSensor();
|
||||||
#ifdef ENV_USE_TCA8418
|
#ifdef ENV_USE_TCA8418
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -8,6 +8,9 @@
|
|||||||
#include <helpers/ContactInfo.h>
|
#include <helpers/ContactInfo.h>
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
#include <helpers/sensors/LPPDataHelpers.h>
|
#include <helpers/sensors/LPPDataHelpers.h>
|
||||||
|
#if defined(SIMPSON)
|
||||||
|
#include <SimpsonKeypad.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef LED_STATE_ON
|
#ifndef LED_STATE_ON
|
||||||
#define LED_STATE_ON 1
|
#define LED_STATE_ON 1
|
||||||
@@ -80,6 +83,9 @@ class UITask : public UITaskBase, public UiCoreHost {
|
|||||||
// each) + NUL = 372B, rounded up with margin.
|
// each) + NUL = 372B, rounded up with margin.
|
||||||
char _bot_buzz_buf[400];
|
char _bot_buzz_buf[400];
|
||||||
KeyboardWidget _kb; // shared across all screens — only one active at a time
|
KeyboardWidget _kb; // shared across all screens — only one active at a time
|
||||||
|
#if defined(SIMPSON)
|
||||||
|
SimpsonKeypad _simpson_keypad;
|
||||||
|
#endif
|
||||||
unsigned long _alert_expiry;
|
unsigned long _alert_expiry;
|
||||||
unsigned long _alert_t0 = 0; // when the banner began to come down
|
unsigned long _alert_t0 = 0; // when the banner began to come down
|
||||||
// Settings > Message alert Compact: the alert is an envelope and a count
|
// Settings > Message alert Compact: the alert is an envelope and a count
|
||||||
@@ -231,6 +237,10 @@ private:
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
void pollCardKB();
|
void pollCardKB();
|
||||||
|
#if defined(SIMPSON)
|
||||||
|
void pollSimpsonKeypad();
|
||||||
|
void handleSimpsonKeypadKey(uint8_t key);
|
||||||
|
#endif
|
||||||
void handleCardKBByte(uint8_t raw);
|
void handleCardKBByte(uint8_t raw);
|
||||||
void setCardKBBackground(bool on); // no-op without CardKB / the poll task
|
void setCardKBBackground(bool on); // no-op without CardKB / the poll task
|
||||||
void startCardKBCapture(); // end of begin(): start the poll task
|
void startCardKBCapture(); // end of begin(): start the poll task
|
||||||
@@ -306,6 +316,10 @@ public:
|
|||||||
void gotoHomeScreen() { setCurrScreen(home); }
|
void gotoHomeScreen() { setCurrScreen(home); }
|
||||||
void gotoSettingsScreen();
|
void gotoSettingsScreen();
|
||||||
void gotoMessagesScreen();
|
void gotoMessagesScreen();
|
||||||
|
#if defined(SIMPSON)
|
||||||
|
void gotoBluetoothHomePage();
|
||||||
|
void gotoGpsHomePage();
|
||||||
|
#endif
|
||||||
#ifdef SIM_PLATFORM
|
#ifdef SIM_PLATFORM
|
||||||
void simCompose(const char* text); // sim tests: a channel post's keyboard holding `text`
|
void simCompose(const char* text); // sim tests: a channel post's keyboard holding `text`
|
||||||
void simMessage(const char* text); // sim tests: a channel message arrives
|
void simMessage(const char* text); // sim tests: a channel message arrives
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
[env:Simpson_companion_solo]
|
||||||
|
extends = Simpson
|
||||||
|
board_build.ldscript = boards/nrf52840_s140_v6_extrafs.ld
|
||||||
|
board_upload.maximum_size = 712704
|
||||||
|
build_unflags = -Ofast -D OFFLINE_QUEUE_SIZE=256
|
||||||
|
build_flags = ${Simpson.build_flags}
|
||||||
|
-I examples/companion_radio/ui-new
|
||||||
|
-D MAX_CONTACTS=350
|
||||||
|
-D MAX_GROUP_CHANNELS=40
|
||||||
|
-D BLE_PIN_CODE=123456
|
||||||
|
-D DUAL_SERIAL=1
|
||||||
|
-D OFFLINE_QUEUE_SIZE=128
|
||||||
|
-D DISPLAY_CLASS=SH1106Display
|
||||||
|
-D FIRMWARE_SOLO_BUILD=1
|
||||||
|
-D UI_SENSORS_PAGE=1
|
||||||
|
-Os
|
||||||
|
build_src_filter = ${Simpson.build_src_filter}
|
||||||
|
+<helpers/nrf52/SerialBLEInterface.cpp>
|
||||||
|
+<helpers/ui/SH1106Display.cpp>
|
||||||
|
+<helpers/ui/MomentaryButton.cpp>
|
||||||
|
+<helpers/ui/buzzer.cpp>
|
||||||
|
+<helpers/ui/GenericVibration.cpp>
|
||||||
|
+<../examples/companion_radio/*.cpp>
|
||||||
|
+<../examples/companion_radio/ui-new/*.cpp>
|
||||||
|
lib_deps = ${Simpson.lib_deps}
|
||||||
|
adafruit/RTClib @ ^2.1.3
|
||||||
|
densaugeo/base64 @ ~1.4.0
|
||||||
@@ -40,6 +40,9 @@ bool SH1106Display::begin()
|
|||||||
// spi_dev NULL, and UITask::begin() calls turnOn() regardless of our
|
// spi_dev NULL, and UITask::begin() calls turnOn() regardless of our
|
||||||
// return value, which then dereferences the null spi_dev.
|
// return value, which then dereferences the null spi_dev.
|
||||||
bool ok = display.begin(addr ? addr : DISPLAY_ADDRESS, true);
|
bool ok = display.begin(addr ? addr : DISPLAY_ADDRESS, true);
|
||||||
|
#ifdef DISPLAY_ROTATION
|
||||||
|
display.setRotation(DISPLAY_ROTATION);
|
||||||
|
#endif
|
||||||
return addr != 0 && ok;
|
return addr != 0 && ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,9 @@
|
|||||||
#include <helpers/NRF52Board.h>
|
#include <helpers/NRF52Board.h>
|
||||||
|
|
||||||
#define PIN_VBAT_READ 17
|
#define PIN_VBAT_READ 17
|
||||||
#define ADC_MULTIPLIER (1.815f) // dependent on voltage divider resistors. TODO: more accurate battery tracking
|
#ifndef ADC_MULTIPLIER
|
||||||
|
#define ADC_MULTIPLIER (1.815f) // dependent on voltage divider resistors. TODO: more accurate battery tracking
|
||||||
|
#endif
|
||||||
|
|
||||||
class PromicroBoard : public NRF52BoardDCDC {
|
class PromicroBoard : public NRF52BoardDCDC {
|
||||||
protected:
|
protected:
|
||||||
|
|||||||
@@ -7,7 +7,11 @@
|
|||||||
#include <helpers/radiolib/CustomSX1262Wrapper.h>
|
#include <helpers/radiolib/CustomSX1262Wrapper.h>
|
||||||
#include <helpers/AutoDiscoverRTCClock.h>
|
#include <helpers/AutoDiscoverRTCClock.h>
|
||||||
#ifdef DISPLAY_CLASS
|
#ifdef DISPLAY_CLASS
|
||||||
#include <helpers/ui/SSD1306Display.h>
|
#if defined(SIMPSON)
|
||||||
|
#include <helpers/ui/SH1106Display.h>
|
||||||
|
#else
|
||||||
|
#include <helpers/ui/SSD1306Display.h>
|
||||||
|
#endif
|
||||||
#include <helpers/ui/MomentaryButton.h>
|
#include <helpers/ui/MomentaryButton.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -25,4 +29,3 @@ extern EnvironmentSensorManager sensors;
|
|||||||
|
|
||||||
bool radio_init();
|
bool radio_init();
|
||||||
mesh::LocalIdentity radio_new_identity();
|
mesh::LocalIdentity radio_new_identity();
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,70 @@
|
|||||||
|
#include "SimpsonKeypad.h"
|
||||||
|
|
||||||
|
#include <Wire.h>
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
char control_keymap[19] = {
|
||||||
|
SIMPSON_KEY_CANCEL, SIMPSON_KEY_UP, 0, SIMPSON_KEY_BLUETOOTH,
|
||||||
|
SIMPSON_KEY_LEFT, SIMPSON_KEY_ENTER, SIMPSON_KEY_RIGHT, SIMPSON_KEY_BRIGHTNESS_UP,
|
||||||
|
SIMPSON_KEY_SYMBOLS, SIMPSON_KEY_DOWN, 0, SIMPSON_KEY_BRIGHTNESS_DOWN,
|
||||||
|
SIMPSON_KEY_MESSAGES, 0, SIMPSON_KEY_FN, SIMPSON_KEY_GPS, 0, 0, 0
|
||||||
|
};
|
||||||
|
|
||||||
|
char alphabet_keymap[19] = {
|
||||||
|
',', 'A', 'D', SIMPSON_KEY_BLUETOOTH,
|
||||||
|
'G', 'J', 'M', SIMPSON_KEY_BRIGHTNESS_UP,
|
||||||
|
'P', 'T', 'W', SIMPSON_KEY_BRIGHTNESS_DOWN,
|
||||||
|
SIMPSON_KEY_BACKSPACE, ' ', SIMPSON_KEY_FN, SIMPSON_KEY_GPS, 0, 0, 0
|
||||||
|
};
|
||||||
|
|
||||||
|
char numeric_keymap[19] = {
|
||||||
|
'1', '2', '3', SIMPSON_KEY_BLUETOOTH,
|
||||||
|
'4', '5', '6', SIMPSON_KEY_BRIGHTNESS_UP,
|
||||||
|
'7', '8', '9', SIMPSON_KEY_BRIGHTNESS_DOWN,
|
||||||
|
SIMPSON_KEY_BACKSPACE, '0', SIMPSON_KEY_FN, SIMPSON_KEY_GPS, 0, 0, 0
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SimpsonKeypad::begin() {
|
||||||
|
if (!_keypad.begin()) return false;
|
||||||
|
_keypad.setKeyPadMode(I2C_KEYPAD_4x4);
|
||||||
|
_keypad.setDebounceThreshold(50);
|
||||||
|
loadModeMap();
|
||||||
|
_ready = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SimpsonKeypad::loadModeMap() {
|
||||||
|
switch (_mode) {
|
||||||
|
case SIMPSON_KEYPAD_CONTROL:
|
||||||
|
_keypad.loadKeyMap(control_keymap);
|
||||||
|
break;
|
||||||
|
case SIMPSON_KEYPAD_ABC:
|
||||||
|
case SIMPSON_KEYPAD_ABC_UPPER:
|
||||||
|
_keypad.loadKeyMap(alphabet_keymap);
|
||||||
|
break;
|
||||||
|
case SIMPSON_KEYPAD_NUMERIC:
|
||||||
|
_keypad.loadKeyMap(numeric_keymap);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t SimpsonKeypad::poll() {
|
||||||
|
if (!_ready) return SIMPSON_KEY_NONE;
|
||||||
|
|
||||||
|
uint8_t key = _keypad.getChar();
|
||||||
|
if (key == I2C_KEYPAD_THRESHOLD) return SIMPSON_KEY_NONE;
|
||||||
|
if (key == SIMPSON_KEY_NONE) {
|
||||||
|
_last_key = SIMPSON_KEY_NONE;
|
||||||
|
return SIMPSON_KEY_NONE;
|
||||||
|
}
|
||||||
|
if (key == _last_key) return SIMPSON_KEY_NONE;
|
||||||
|
_last_key = key;
|
||||||
|
|
||||||
|
if (key == SIMPSON_KEY_FN) {
|
||||||
|
_mode = static_cast<SimpsonKeypadMode>((_mode + 1) % 4);
|
||||||
|
loadModeMap();
|
||||||
|
return SIMPSON_KEY_MODE_CHANGED;
|
||||||
|
}
|
||||||
|
return key;
|
||||||
|
}
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
#include <I2CKeyPad.h>
|
||||||
|
|
||||||
|
#ifndef SIMPSON_KEYPAD_ADDR
|
||||||
|
#define SIMPSON_KEYPAD_ADDR 0x20
|
||||||
|
#endif
|
||||||
|
|
||||||
|
enum SimpsonKeypadMode : uint8_t {
|
||||||
|
SIMPSON_KEYPAD_CONTROL,
|
||||||
|
SIMPSON_KEYPAD_ABC,
|
||||||
|
SIMPSON_KEYPAD_ABC_UPPER,
|
||||||
|
SIMPSON_KEYPAD_NUMERIC
|
||||||
|
};
|
||||||
|
|
||||||
|
enum SimpsonKeypadKey : uint8_t {
|
||||||
|
SIMPSON_KEY_NONE = 0,
|
||||||
|
SIMPSON_KEY_CANCEL = 1,
|
||||||
|
SIMPSON_KEY_UP,
|
||||||
|
SIMPSON_KEY_BLUETOOTH,
|
||||||
|
SIMPSON_KEY_LEFT,
|
||||||
|
SIMPSON_KEY_ENTER,
|
||||||
|
SIMPSON_KEY_RIGHT,
|
||||||
|
SIMPSON_KEY_BRIGHTNESS_UP,
|
||||||
|
SIMPSON_KEY_SYMBOLS,
|
||||||
|
SIMPSON_KEY_DOWN,
|
||||||
|
SIMPSON_KEY_BRIGHTNESS_DOWN,
|
||||||
|
SIMPSON_KEY_MESSAGES,
|
||||||
|
SIMPSON_KEY_FN,
|
||||||
|
SIMPSON_KEY_GPS,
|
||||||
|
SIMPSON_KEY_BACKSPACE,
|
||||||
|
SIMPSON_KEY_MODE_CHANGED
|
||||||
|
};
|
||||||
|
|
||||||
|
class SimpsonKeypad {
|
||||||
|
I2CKeyPad _keypad;
|
||||||
|
SimpsonKeypadMode _mode = SIMPSON_KEYPAD_CONTROL;
|
||||||
|
uint8_t _last_key = SIMPSON_KEY_NONE;
|
||||||
|
bool _ready = false;
|
||||||
|
|
||||||
|
void loadModeMap();
|
||||||
|
|
||||||
|
public:
|
||||||
|
SimpsonKeypad() : _keypad(SIMPSON_KEYPAD_ADDR, &Wire) {}
|
||||||
|
bool begin();
|
||||||
|
uint8_t poll();
|
||||||
|
SimpsonKeypadMode mode() const { return _mode; }
|
||||||
|
};
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
[Simpson]
|
||||||
|
extends = Promicro
|
||||||
|
build_unflags = -D PIN_GPS_RX=3 -D PIN_GPS_TX=4 -D ENV_INCLUDE_AHTX0=1 -D ENV_INCLUDE_BME280=1 -D ENV_INCLUDE_BMP280=1 -D ENV_INCLUDE_INA3221=1 -D ENV_INCLUDE_INA219=1 -D ENV_INCLUDE_INA226=1
|
||||||
|
build_flags = ${Promicro.build_flags}
|
||||||
|
-I variants/simpson
|
||||||
|
-D SIMPSON
|
||||||
|
-D PIN_GPS_TX=3
|
||||||
|
-D PIN_GPS_RX=4
|
||||||
|
-D PIN_VIBRATION=1
|
||||||
|
-D ADC_MULTIPLIER=1.71
|
||||||
|
-D SIMPSON_KEYPAD_ADDR=0x20
|
||||||
|
-D DISPLAY_ROTATION=2
|
||||||
|
-D ENV_SKIP_GPS_DETECT
|
||||||
|
build_src_filter = ${nrf52_base.build_src_filter}
|
||||||
|
+<helpers/sensors>
|
||||||
|
+<../variants/simpson>
|
||||||
|
+<../variants/promicro/target.cpp>
|
||||||
|
+<../variants/promicro/PromicroBoard.cpp>
|
||||||
|
lib_deps = ${Promicro.lib_deps}
|
||||||
|
adafruit/Adafruit SH110X @ ^2.1.13
|
||||||
|
RobTillaart/I2CKeyPad @ ^0.5.2
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
#include "variant.h"
|
||||||
|
#include "wiring_constants.h"
|
||||||
|
#include "wiring_digital.h"
|
||||||
|
|
||||||
|
const uint32_t g_ADigitalPinMap[] = {
|
||||||
|
8, 6, 17, 20, 22, 24, 32, 11, 36, 38, 9, 10, 43, 45, 47, 2, 29, 31, 33, 34, 37, 13, 15
|
||||||
|
};
|
||||||
|
|
||||||
|
void initVariant() {}
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
/*
|
||||||
|
* Simpson variant for the Pro Micro nRF52840 carrier used by this device.
|
||||||
|
* Arduino pin indices map to physical nRF52840 GPIOs in variant.cpp.
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "WVariant.h"
|
||||||
|
|
||||||
|
#define VARIANT_MCK (64000000ul)
|
||||||
|
#define USE_LFRC
|
||||||
|
|
||||||
|
#define PIN_EXT_VCC (21)
|
||||||
|
#define EXT_VCC PIN_EXT_VCC
|
||||||
|
|
||||||
|
#define BATTERY_PIN (17)
|
||||||
|
#define ADC_RESOLUTION 12
|
||||||
|
|
||||||
|
#define PINS_COUNT (23)
|
||||||
|
#define NUM_DIGITAL_PINS (23)
|
||||||
|
#define NUM_ANALOG_INPUTS (1)
|
||||||
|
#define NUM_ANALOG_OUTPUTS (0)
|
||||||
|
|
||||||
|
#define PIN_SERIAL1_TX (4)
|
||||||
|
#define PIN_SERIAL1_RX (3)
|
||||||
|
|
||||||
|
#define WIRE_INTERFACES_COUNT 1
|
||||||
|
#define PIN_WIRE_SDA (8)
|
||||||
|
#define PIN_WIRE_SCL (7)
|
||||||
|
|
||||||
|
#define SPI_INTERFACES_COUNT 1
|
||||||
|
#define PIN_SPI_SCK (12)
|
||||||
|
#define PIN_SPI_MISO (15)
|
||||||
|
#define PIN_SPI_MOSI (14)
|
||||||
|
#define PIN_SPI_NSS (13)
|
||||||
|
|
||||||
|
#define PIN_LED (22)
|
||||||
|
#define LED_PIN PIN_LED
|
||||||
|
#define LED_BLUE PIN_LED
|
||||||
|
#define LED_BUILTIN PIN_LED
|
||||||
|
#define LED_STATE_ON 1
|
||||||
|
|
||||||
|
#define PIN_BUTTON1 (6)
|
||||||
|
#define BUTTON_PIN PIN_BUTTON1
|
||||||
|
|
||||||
|
#define PIN_BUZZER (0)
|
||||||
|
#ifndef PIN_VIBRATION
|
||||||
|
#define PIN_VIBRATION (1)
|
||||||
|
#endif
|
||||||
|
#define PIN_GPS_EN (5)
|
||||||
|
|
||||||
|
#define P_LORA_NSS (13)
|
||||||
|
#define P_LORA_DIO_1 (11)
|
||||||
|
#define P_LORA_RESET (10)
|
||||||
|
#define P_LORA_BUSY (16)
|
||||||
|
#define P_LORA_MISO (15)
|
||||||
|
#define P_LORA_SCLK (12)
|
||||||
|
#define P_LORA_MOSI (14)
|
||||||
|
#define SX126X_POWER_EN (21)
|
||||||
|
#define SX126X_RXEN (2)
|
||||||
|
#define SX126X_TXEN (-1)
|
||||||
|
#define SX126X_DIO2_AS_RF_SWITCH true
|
||||||
|
#define SX126X_DIO3_TCXO_VOLTAGE (1.8f)
|
||||||
Reference in New Issue
Block a user