mirror of
https://github.com/MarekZegare4/MeshCore-Solo.git
synced 2026-11-02 10:51:57 +00:00
feat(eink): 4.2" 400x300 build with the misc-fixed 9x15 font, wide sim
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -4,13 +4,15 @@
|
|||||||
; variants in variants/, so this repo's Solo-specific additions don't get
|
; variants in variants/, so this repo's Solo-specific additions don't get
|
||||||
; mixed in with configs other MeshCore forks/upstream also carry.
|
; mixed in with configs other MeshCore forks/upstream also carry.
|
||||||
;
|
;
|
||||||
; Two builds, one per orientation: each screen is laid out for one shape, and
|
; Two builds for the 2.13" panel, one per orientation: each screen is laid out
|
||||||
; Settings > Rotation only turns it upside down. Landscape writes in the 8x13
|
; for one shape, and Settings > Rotation only turns it upside down. Landscape
|
||||||
; font at the panel's own resolution (EINK_LARGE_FONT); portrait keeps the 6x9,
|
; writes in the 8x13 font at the panel's own resolution (EINK_LARGE_FONT);
|
||||||
; whose narrow width wants the smaller cell. The joystick reads upright with the
|
; portrait keeps the 6x9, whose narrow width wants the smaller cell. The
|
||||||
; panel at rotation 1 (landscape) and turns with it (JOYSTICK_UPRIGHT_ROTATION).
|
; joystick reads upright with the panel at rotation 1 (landscape) and turns
|
||||||
|
; with it (JOYSTICK_UPRIGHT_ROTATION). A third for a 4.2" 400x300 panel on the
|
||||||
|
; same wiring, in the 9x15.
|
||||||
;
|
;
|
||||||
; Both: Dual BLE+USB with added Solo.
|
; All: Dual BLE+USB with added Solo.
|
||||||
[eink_solo]
|
[eink_solo]
|
||||||
extends = WioTrackerL1Eink
|
extends = WioTrackerL1Eink
|
||||||
; Optimise for size, not speed: the nRF52 Arduino core defaults to -Ofast
|
; Optimise for size, not speed: the nRF52 Arduino core defaults to -Ofast
|
||||||
@@ -43,3 +45,16 @@ extends = eink_solo
|
|||||||
build_unflags = ${eink_solo.build_unflags} -D DISPLAY_ROTATION=1
|
build_unflags = ${eink_solo.build_unflags} -D DISPLAY_ROTATION=1
|
||||||
build_flags = ${eink_solo.build_flags}
|
build_flags = ${eink_solo.build_flags}
|
||||||
-D DISPLAY_ROTATION=0
|
-D DISPLAY_ROTATION=0
|
||||||
|
|
||||||
|
; A 4.2" 400x300 panel (Good Display GDEY042T81, SSD1683 -- the 2.13"'s
|
||||||
|
; SSD1680's bigger sibling) in place of the 2.13", on the same wiring. Its
|
||||||
|
; native orientation is landscape (rotation 0); text in the 9x15.
|
||||||
|
[env:WioTrackerL1Eink42_solo_dual]
|
||||||
|
extends = eink_solo
|
||||||
|
build_unflags = ${eink_solo.build_unflags} -D EINK_DISPLAY_MODEL=GxEPD2_213_B74 -D DISPLAY_ROTATION=1
|
||||||
|
-D JOYSTICK_UPRIGHT_ROTATION=1
|
||||||
|
build_flags = ${eink_solo.build_flags}
|
||||||
|
-D EINK_DISPLAY_MODEL=GxEPD2_420_GDEY042T81
|
||||||
|
-D DISPLAY_ROTATION=0
|
||||||
|
-D JOYSTICK_UPRIGHT_ROTATION=0
|
||||||
|
-D EINK_LARGE_FONT=2
|
||||||
|
|||||||
@@ -14,7 +14,8 @@ class Adafruit_GFX;
|
|||||||
// (GxEPDDisplay.cpp on a board, the sim's target.cpp): it pulls in the font
|
// (GxEPDDisplay.cpp on a board, the sim's target.cpp): it pulls in the font
|
||||||
// tables.
|
// tables.
|
||||||
|
|
||||||
// EINK_LARGE_FONT: a landscape panel writes in the 8x13 at its own resolution.
|
// EINK_LARGE_FONT: a landscape panel writes in the 8x13 at its own resolution
|
||||||
|
// (1), or the 9x15 (2, the 4.2" 400x300).
|
||||||
// Without it a landscape panel doubles the 6x9 (every pixel 2x2) -- for small
|
// Without it a landscape panel doubles the 6x9 (every pixel 2x2) -- for small
|
||||||
// dense panels where 8x13 would be too fine. A portrait panel always uses the
|
// dense panels where 8x13 would be too fine. A portrait panel always uses the
|
||||||
// 6x9: its narrow width wants the smaller cell.
|
// 6x9: its narrow width wants the smaller cell.
|
||||||
|
|||||||
@@ -4,7 +4,13 @@
|
|||||||
|
|
||||||
#include "EinkGfxDisplay.h"
|
#include "EinkGfxDisplay.h"
|
||||||
#include "MiscFixedRenderer.h"
|
#include "MiscFixedRenderer.h"
|
||||||
#include "MiscFixed8x13Font.h"
|
#if EINK_LARGE_FONT == 2
|
||||||
|
#include "MiscFixed9x15Font.h"
|
||||||
|
#define EINK_LARGE_GFXFONT MiscFixed9x15
|
||||||
|
#else
|
||||||
|
#include "MiscFixed8x13Font.h"
|
||||||
|
#define EINK_LARGE_GFXFONT MiscFixed8x13
|
||||||
|
#endif
|
||||||
|
|
||||||
EinkGfxDisplay::EinkGfxDisplay(int w, int h, Adafruit_GFX& gfx, uint16_t ink, uint16_t paper)
|
EinkGfxDisplay::EinkGfxDisplay(int w, int h, Adafruit_GFX& gfx, uint16_t ink, uint16_t paper)
|
||||||
: DisplayDriver(w, h), _gfx(gfx), _ink(ink), _paper(paper), _curr(ink), _font(&MiscFixed) {
|
: DisplayDriver(w, h), _gfx(gfx), _ink(ink), _paper(paper), _curr(ink), _font(&MiscFixed) {
|
||||||
@@ -13,7 +19,7 @@ EinkGfxDisplay::EinkGfxDisplay(int w, int h, Adafruit_GFX& gfx, uint16_t ink, ui
|
|||||||
|
|
||||||
void EinkGfxDisplay::updateLayout() {
|
void EinkGfxDisplay::updateLayout() {
|
||||||
const bool landscape = width() >= height();
|
const bool landscape = width() >= height();
|
||||||
_font = (EINK_LARGE_FONT && landscape) ? &MiscFixed8x13 : &MiscFixed;
|
_font = (EINK_LARGE_FONT && landscape) ? &EINK_LARGE_GFXFONT : &MiscFixed;
|
||||||
_px = (!EINK_LARGE_FONT && landscape) ? 2 : 1;
|
_px = (!EINK_LARGE_FONT && landscape) ? 2 : 1;
|
||||||
_cell_w = miscFixedCellW(*_font);
|
_cell_w = miscFixedCellW(*_font);
|
||||||
_cell_h = _font->yAdvance;
|
_cell_h = _font->yAdvance;
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -463,7 +463,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
#ifdef SIM_EINK_PANEL_W
|
#ifdef SIM_EINK_PANEL_W
|
||||||
// An e-ink panel (the Wio Tracker L1 E-ink's 2.13", 122x250 before rotation):
|
// An e-ink panel (the Wio Tracker L1 E-ink's 2.13", 122x250 before rotation, or a 4.2" 400x300):
|
||||||
// EinkGfxDisplay draws, exactly as GxEPDDisplay does on the board, into a 1-bit
|
// EinkGfxDisplay draws, exactly as GxEPDDisplay does on the board, into a 1-bit
|
||||||
// canvas, and a frame that changed is put on the page in paper and ink. The
|
// canvas, and a frame that changed is put on the page in paper and ink. The
|
||||||
// host page counts refreshes from Module.__einkRefreshes. Bodies in target.cpp,
|
// host page counts refreshes from Module.__einkRefreshes. Bodies in target.cpp,
|
||||||
|
|||||||
@@ -194,15 +194,17 @@ if [ "$SIM_UI" = "lvgl" ]; then
|
|||||||
LINK_EXTRA=(-sFETCH=1) # map downloads (LvglPort.h) go through emscripten_fetch
|
LINK_EXTRA=(-sFETCH=1) # map downloads (LvglPort.h) go through emscripten_fetch
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# SIM_EINK=landscape|portrait: ui-new on the Wio Tracker L1 E-ink's 2.13" panel
|
# SIM_EINK=landscape|portrait|wide: ui-new on the Wio Tracker L1 E-ink's 2.13"
|
||||||
# (122x250, solo/wio-tracker-l1-eink's two builds) instead of the OLED ->
|
# panel (122x250, solo/wio-tracker-l1-eink's two builds) or the 4.2" one
|
||||||
# web/index.html?build=meshcore_sim_eink_landscape (or _portrait).
|
# (400x300, its third) instead of the OLED ->
|
||||||
|
# web/index.html?build=meshcore_sim_eink_landscape (or _portrait, _wide).
|
||||||
SIM_EINK="${SIM_EINK:-}"
|
SIM_EINK="${SIM_EINK:-}"
|
||||||
if [ -n "$SIM_EINK" ]; then
|
if [ -n "$SIM_EINK" ]; then
|
||||||
case "$SIM_EINK" in
|
case "$SIM_EINK" in
|
||||||
landscape) EINK_DEFS=(-DDISPLAY_ROTATION=1 -DEINK_LARGE_FONT=1); EXPORT_NAME=MeshCoreSimEinkLandscape ;;
|
landscape) EINK_DEFS=(-DDISPLAY_ROTATION=1 -DEINK_LARGE_FONT=1 -DSIM_EINK_PANEL_W=122 -DSIM_EINK_PANEL_H=250); EXPORT_NAME=MeshCoreSimEinkLandscape ;;
|
||||||
portrait) EINK_DEFS=(-DDISPLAY_ROTATION=0); EXPORT_NAME=MeshCoreSimEinkPortrait ;;
|
portrait) EINK_DEFS=(-DDISPLAY_ROTATION=0 -DSIM_EINK_PANEL_W=122 -DSIM_EINK_PANEL_H=250); EXPORT_NAME=MeshCoreSimEinkPortrait ;;
|
||||||
*) echo "error: SIM_EINK must be landscape or portrait" >&2; exit 1 ;;
|
wide) EINK_DEFS=(-DDISPLAY_ROTATION=0 -DEINK_LARGE_FONT=2 -DSIM_EINK_PANEL_W=400 -DSIM_EINK_PANEL_H=300); EXPORT_NAME=MeshCoreSimEinkWide ;;
|
||||||
|
*) echo "error: SIM_EINK must be landscape, portrait or wide" >&2; exit 1 ;;
|
||||||
esac
|
esac
|
||||||
OUT_NAME="meshcore_sim_eink_$SIM_EINK"
|
OUT_NAME="meshcore_sim_eink_$SIM_EINK"
|
||||||
# Distinct factories (set above): web/mesh.html?a=... loads one beside
|
# Distinct factories (set above): web/mesh.html?a=... loads one beside
|
||||||
@@ -213,7 +215,7 @@ if [ -n "$SIM_EINK" ]; then
|
|||||||
done
|
done
|
||||||
# EINK_DISPLAY_MODEL is only tested for presence outside GxEPDDisplay
|
# EINK_DISPLAY_MODEL is only tested for presence outside GxEPDDisplay
|
||||||
# (Features.h: the e-ink settings and timings), which the sim doesn't build.
|
# (Features.h: the e-ink settings and timings), which the sim doesn't build.
|
||||||
DEFINES=("${kept[@]}" -DDISPLAY_CLASS=SimEinkDisplay -DSIM_EINK_PANEL_W=122 -DSIM_EINK_PANEL_H=250
|
DEFINES=("${kept[@]}" -DDISPLAY_CLASS=SimEinkDisplay
|
||||||
-DEINK_DISPLAY_MODEL=SimEinkPanel -DMAX_GROUP_CHANNELS=40 "${EINK_DEFS[@]}")
|
-DEINK_DISPLAY_MODEL=SimEinkPanel -DMAX_GROUP_CHANNELS=40 "${EINK_DEFS[@]}")
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|||||||
@@ -158,7 +158,7 @@
|
|||||||
|
|
||||||
<div id="log"></div>
|
<div id="log"></div>
|
||||||
|
|
||||||
<!-- ?build=meshcore_sim_eink_landscape (or _portrait) loads another build of
|
<!-- ?build=meshcore_sim_eink_landscape (or _portrait, _wide) loads another build of
|
||||||
the same UI; the e-ink driver sizes the canvas itself. -->
|
the same UI; the e-ink driver sizes the canvas itself. -->
|
||||||
<script>
|
<script>
|
||||||
document.write('<script src="build/' +
|
document.write('<script src="build/' +
|
||||||
@@ -215,7 +215,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const SimFactory = window.MeshCoreSimEinkLandscape || window.MeshCoreSimEinkPortrait || window.MeshCoreSim;
|
const SimFactory = window.MeshCoreSimEinkLandscape || window.MeshCoreSimEinkPortrait || window.MeshCoreSimEinkWide || window.MeshCoreSim;
|
||||||
if (typeof SimFactory !== 'function') {
|
if (typeof SimFactory !== 'function') {
|
||||||
statusEl.textContent = 'error: build/meshcore_sim.js missing or failed to load -- run variants/sim/build_wasm.sh first.';
|
statusEl.textContent = 'error: build/meshcore_sim.js missing or failed to load -- run variants/sim/build_wasm.sh first.';
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -231,14 +231,14 @@
|
|||||||
|
|
||||||
<script src="build/meshcore_sim.js"></script>
|
<script src="build/meshcore_sim.js"></script>
|
||||||
<script src="build/repeater/meshcore_sim_repeater.js"></script>
|
<script src="build/repeater/meshcore_sim_repeater.js"></script>
|
||||||
<!-- ?a=meshcore_sim_eink_landscape (or _portrait): A is that e-ink build. -->
|
<!-- ?a=meshcore_sim_eink_landscape (or _portrait, _wide): A is that e-ink build. -->
|
||||||
<script>
|
<script>
|
||||||
const A_BUILD = (new URLSearchParams(location.search).get('a') || '').replace(/[^\w]/g, '');
|
const A_BUILD = (new URLSearchParams(location.search).get('a') || '').replace(/[^\w]/g, '');
|
||||||
if (A_BUILD) document.write('<script src="build/' + A_BUILD + '.js"><\/script>');
|
if (A_BUILD) document.write('<script src="build/' + A_BUILD + '.js"><\/script>');
|
||||||
</script>
|
</script>
|
||||||
<script>
|
<script>
|
||||||
const logEl = document.getElementById('log');
|
const logEl = document.getElementById('log');
|
||||||
const FactoryA = (opts) => (window.MeshCoreSimEinkLandscape || window.MeshCoreSimEinkPortrait || MeshCoreSim)(opts);
|
const FactoryA = (opts) => (window.MeshCoreSimEinkLandscape || window.MeshCoreSimEinkPortrait || window.MeshCoreSimEinkWide || MeshCoreSim)(opts);
|
||||||
function log(msg) {
|
function log(msg) {
|
||||||
const line = document.createElement('div');
|
const line = document.createElement('div');
|
||||||
line.textContent = '[' + new Date().toISOString().substr(11, 12) + '] ' + msg;
|
line.textContent = '[' + new Date().toISOString().substr(11, 12) + '] ' + msg;
|
||||||
|
|||||||
Reference in New Issue
Block a user