mirror of
https://github.com/meshtastic/firmware.git
synced 2025-06-18 11:02:16 +00:00
Merge branch '2264-feature-check-for-low-heap-before-adding-to-nodedb-was-reboot-loop-heap-too-low' of github.com:meshtastic/firmware into 2264-feature-check-for-low-heap-before-adding-to-nodedb-was-reboot-loop-heap-too-low
This commit is contained in:
commit
e0a6a37bef
59
.github/workflows/build_esp32_s3.yml
vendored
Normal file
59
.github/workflows/build_esp32_s3.yml
vendored
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
name: Build ESP32-S3
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_call:
|
||||||
|
inputs:
|
||||||
|
board:
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-esp32-s3:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
- name: Build base
|
||||||
|
id: base
|
||||||
|
uses: ./.github/actions/setup-base
|
||||||
|
|
||||||
|
- name: Pull web ui
|
||||||
|
uses: dsaltares/fetch-gh-release-asset@master
|
||||||
|
with:
|
||||||
|
repo: "meshtastic/web"
|
||||||
|
file: "build.tar"
|
||||||
|
target: "build.tar"
|
||||||
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Unpack web ui
|
||||||
|
run: |
|
||||||
|
tar -xf build.tar -C data/static
|
||||||
|
rm build.tar
|
||||||
|
- name: Remove debug flags for release
|
||||||
|
if: ${{ github.event_name == 'workflow_dispatch' }}
|
||||||
|
run: |
|
||||||
|
sed -i '/DDEBUG_HEAP/d' ./arch/esp32/esp32.ini
|
||||||
|
sed -i '/DDEBUG_HEAP/d' ./arch/esp32/esp32s2.ini
|
||||||
|
sed -i '/DDEBUG_HEAP/d' ./arch/esp32/esp32s3.ini
|
||||||
|
- name: Build ESP32
|
||||||
|
run: bin/build-esp32.sh ${{ inputs.board }}
|
||||||
|
|
||||||
|
- name: Pull OTA Firmware
|
||||||
|
uses: dsaltares/fetch-gh-release-asset@master
|
||||||
|
with:
|
||||||
|
repo: "meshtastic/firmware-ota"
|
||||||
|
file: "firmware-s3.bin"
|
||||||
|
target: "release/bleota-s3.bin"
|
||||||
|
token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Get release version string
|
||||||
|
shell: bash
|
||||||
|
run: echo "version=$(./bin/buildinfo.py long)" >> $GITHUB_OUTPUT
|
||||||
|
id: version
|
||||||
|
|
||||||
|
- name: Store binaries as an artifact
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: firmware-${{ inputs.board }}-${{ steps.version.outputs.version }}.zip
|
||||||
|
path: |
|
||||||
|
release/*.bin
|
||||||
|
release/*.elf
|
21
.github/workflows/main_matrix.yml
vendored
21
.github/workflows/main_matrix.yml
vendored
@ -62,8 +62,6 @@ jobs:
|
|||||||
- board: heltec-v1
|
- board: heltec-v1
|
||||||
- board: heltec-v2.0
|
- board: heltec-v2.0
|
||||||
- board: heltec-v2.1
|
- board: heltec-v2.1
|
||||||
- board: heltec-v3
|
|
||||||
- board: heltec-wsl-v3
|
|
||||||
- board: tbeam0.7
|
- board: tbeam0.7
|
||||||
- board: meshtastic-diy-v1
|
- board: meshtastic-diy-v1
|
||||||
- board: meshtastic-dr-dev
|
- board: meshtastic-dr-dev
|
||||||
@ -71,13 +69,24 @@ jobs:
|
|||||||
- board: station-g1
|
- board: station-g1
|
||||||
- board: m5stack-core
|
- board: m5stack-core
|
||||||
- board: m5stack-coreink
|
- board: m5stack-coreink
|
||||||
- board: tbeam-s3-core
|
|
||||||
- board: tlora-t3s3-v1
|
|
||||||
- board: nano-g1-explorer
|
- board: nano-g1-explorer
|
||||||
uses: ./.github/workflows/build_esp32.yml
|
uses: ./.github/workflows/build_esp32.yml
|
||||||
with:
|
with:
|
||||||
board: ${{ matrix.board }}
|
board: ${{ matrix.board }}
|
||||||
|
|
||||||
|
build-esp32-s3:
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
- board: heltec-v3
|
||||||
|
- board: heltec-wsl-v3
|
||||||
|
- board: tbeam-s3-core
|
||||||
|
- board: tlora-t3s3-v1
|
||||||
|
uses: ./.github/workflows/build_esp32_s3.yml
|
||||||
|
with:
|
||||||
|
board: ${{ matrix.board }}
|
||||||
|
|
||||||
build-nrf52:
|
build-nrf52:
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
@ -176,7 +185,7 @@ jobs:
|
|||||||
|
|
||||||
gather-artifacts:
|
gather-artifacts:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
needs: [build-esp32, build-nrf52, build-native] #, build-rpi2040]
|
needs: [build-esp32, build-esp32-s3, build-nrf52, build-native] #, build-rpi2040]
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- name: Checkout code
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
@ -193,7 +202,7 @@ jobs:
|
|||||||
id: version
|
id: version
|
||||||
|
|
||||||
- name: Move files up
|
- name: Move files up
|
||||||
run: mv -b -t ./ ./*tbeam-2*/littlefs*.bin ./*tbeam-2*/bleota.bin ./**/firmware*.bin ./*t-echo*/Meshtastic_nRF52_factory_erase.uf2 ./**/firmware-*.uf2 ./**/firmware-*-ota.zip ./**/*.elf ./*native*/*device-*.sh ./*native*/*device-*.bat
|
run: mv -b -t ./ ./*tbeam-2*/littlefs*.bin ./*tbeam-2*/bleota.bin ./*tbeam-s3*/bleota-s3.bin ./**/firmware*.bin ./*t-echo*/Meshtastic_nRF52_factory_erase.uf2 ./**/firmware-*.uf2 ./**/firmware-*-ota.zip ./**/*.elf ./*native*/*device-*.sh ./*native*/*device-*.bat
|
||||||
|
|
||||||
- name: Repackage in single firmware zip
|
- name: Repackage in single firmware zip
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v3
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
; Common settings for ESP targes, mixin with extends = esp32_base
|
; Common settings for ESP targes, mixin with extends = esp32_base
|
||||||
[esp32_base]
|
[esp32_base]
|
||||||
extends = arduino_base
|
extends = arduino_base
|
||||||
platform = platformio/espressif32@^6.0.0
|
platform = platformio/espressif32@^6.1.0
|
||||||
build_src_filter =
|
build_src_filter =
|
||||||
${arduino_base.build_src_filter} -<platform/nrf52/> -<platform/stm32wl> -<platform/rp2040> -<mesh/eth/>
|
${arduino_base.build_src_filter} -<platform/nrf52/> -<platform/stm32wl> -<platform/rp2040> -<mesh/eth/>
|
||||||
upload_speed = 921600
|
upload_speed = 921600
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[esp32s2_base]
|
[esp32s2_base]
|
||||||
extends = arduino_base
|
extends = arduino_base
|
||||||
platform = platformio/espressif32@^6.0.0
|
platform = platformio/espressif32@^6.1.0
|
||||||
build_src_filter =
|
build_src_filter =
|
||||||
${arduino_base.build_src_filter} -<platform/nrf52/> -<platform/stm32wl> -<platform/rp2040> -<mesh/eth/> -<nimble/>
|
${arduino_base.build_src_filter} -<platform/nrf52/> -<platform/stm32wl> -<platform/rp2040> -<mesh/eth/> -<nimble/>
|
||||||
upload_speed = 961200
|
upload_speed = 961200
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[esp32s3_base]
|
[esp32s3_base]
|
||||||
extends = arduino_base
|
extends = arduino_base
|
||||||
platform = platformio/espressif32@^6.0.0
|
platform = platformio/espressif32@^6.1.0
|
||||||
build_src_filter =
|
build_src_filter =
|
||||||
${arduino_base.build_src_filter} -<platform/nrf52/> -<platform/stm32wl> -<platform/rp2040> -<mesh/eth/>
|
${arduino_base.build_src_filter} -<platform/nrf52/> -<platform/stm32wl> -<platform/rp2040> -<mesh/eth/>
|
||||||
upload_speed = 961200
|
upload_speed = 961200
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[nrf52_base]
|
[nrf52_base]
|
||||||
; Instead of the standard nordicnrf52 platform, we use our fork which has our added variant files
|
; Instead of the standard nordicnrf52 platform, we use our fork which has our added variant files
|
||||||
platform = platformio/nordicnrf52@^9.4.0
|
platform = platformio/nordicnrf52@^9.5.0
|
||||||
|
|
||||||
extends = arduino_base
|
extends = arduino_base
|
||||||
build_type = debug ; I'm debugging with ICE a lot now
|
build_type = debug ; I'm debugging with ICE a lot now
|
||||||
|
@ -34,7 +34,7 @@ SRCBIN=.pio/build/$1/firmware.bin
|
|||||||
cp $SRCBIN $OUTDIR/$basename-update.bin
|
cp $SRCBIN $OUTDIR/$basename-update.bin
|
||||||
|
|
||||||
echo "Building Filesystem for ESP32 targets"
|
echo "Building Filesystem for ESP32 targets"
|
||||||
pio run --environment tbeam -t buildfs
|
pio run --environment $1 -t buildfs
|
||||||
cp .pio/build/tbeam/littlefs.bin $OUTDIR/littlefs-$VERSION.bin
|
cp .pio/build/$1/littlefs.bin $OUTDIR/littlefs-$VERSION.bin
|
||||||
cp bin/device-install.* $OUTDIR
|
cp bin/device-install.* $OUTDIR
|
||||||
cp bin/device-update.* $OUTDIR
|
cp bin/device-update.* $OUTDIR
|
||||||
|
@ -30,7 +30,13 @@ IF EXIST %FILENAME% IF x%FILENAME:update=%==x%FILENAME% (
|
|||||||
echo Trying to flash update %FILENAME%, but first erasing and writing system information"
|
echo Trying to flash update %FILENAME%, but first erasing and writing system information"
|
||||||
%PYTHON% -m esptool --baud 115200 erase_flash
|
%PYTHON% -m esptool --baud 115200 erase_flash
|
||||||
%PYTHON% -m esptool --baud 115200 write_flash 0x00 %FILENAME%
|
%PYTHON% -m esptool --baud 115200 write_flash 0x00 %FILENAME%
|
||||||
%PYTHON% -m esptool --baud 115200 write_flash 0x260000 bleota.bin
|
|
||||||
|
@REM Account for S3 board's different OTA partition
|
||||||
|
IF x%FILENAME:s3=%==x%FILENAME% IF x%FILENAME:v3=%==x%FILENAME% (
|
||||||
|
%PYTHON% -m esptool --baud 115200 write_flash 0x260000 bleota.bin
|
||||||
|
) else (
|
||||||
|
%PYTHON% -m esptool --baud 115200 write_flash 0x260000 bleota-s3.bin
|
||||||
|
)
|
||||||
for %%f in (littlefs-*.bin) do (
|
for %%f in (littlefs-*.bin) do (
|
||||||
%PYTHON% -m esptool --baud 115200 write_flash 0x300000 %%f
|
%PYTHON% -m esptool --baud 115200 write_flash 0x300000 %%f
|
||||||
)
|
)
|
||||||
|
@ -49,7 +49,12 @@ if [ -f "${FILENAME}" ] && [ ! -z "${FILENAME##*"update"*}" ]; then
|
|||||||
echo "Trying to flash ${FILENAME}, but first erasing and writing system information"
|
echo "Trying to flash ${FILENAME}, but first erasing and writing system information"
|
||||||
"$PYTHON" -m esptool erase_flash
|
"$PYTHON" -m esptool erase_flash
|
||||||
"$PYTHON" -m esptool write_flash 0x00 ${FILENAME}
|
"$PYTHON" -m esptool write_flash 0x00 ${FILENAME}
|
||||||
"$PYTHON" -m esptool write_flash 0x260000 bleota.bin
|
# Account for S3 board's different OTA partition
|
||||||
|
if [ ! -z "${FILENAME##*"s3"*}" ] && [ ! -z "${FILENAME##*"-v3"*}" ]; then
|
||||||
|
"$PYTHON" -m esptool write_flash 0x260000 bleota.bin
|
||||||
|
else
|
||||||
|
"$PYTHON" -m esptool write_flash 0x260000 bleota-s3.bin
|
||||||
|
fi
|
||||||
"$PYTHON" -m esptool write_flash 0x300000 littlefs-*.bin
|
"$PYTHON" -m esptool write_flash 0x300000 littlefs-*.bin
|
||||||
|
|
||||||
else
|
else
|
||||||
|
@ -9,7 +9,8 @@
|
|||||||
"-DARDUINO_USB_CDC_ON_BOOT=1",
|
"-DARDUINO_USB_CDC_ON_BOOT=1",
|
||||||
"-DARDUINO_USB_MODE=0",
|
"-DARDUINO_USB_MODE=0",
|
||||||
"-DARDUINO_RUNNING_CORE=1",
|
"-DARDUINO_RUNNING_CORE=1",
|
||||||
"-DARDUINO_EVENT_RUNNING_CORE=1"
|
"-DARDUINO_EVENT_RUNNING_CORE=1",
|
||||||
|
"-DBOARD_HAS_PSRAM"
|
||||||
],
|
],
|
||||||
"f_cpu": "240000000L",
|
"f_cpu": "240000000L",
|
||||||
"f_flash": "80000000L",
|
"f_flash": "80000000L",
|
||||||
|
@ -59,15 +59,14 @@ build_flags = -Wno-missing-field-initializers
|
|||||||
monitor_speed = 115200
|
monitor_speed = 115200
|
||||||
|
|
||||||
lib_deps =
|
lib_deps =
|
||||||
https://github.com/meshtastic/esp8266-oled-ssd1306.git#da1ede4dfcd91074283b029080759fd744120909 ; ESP8266_SSD1306
|
https://github.com/meshtastic/esp8266-oled-ssd1306.git#b38094e03dfa964fbc0e799bc374e91a605c1223 ; ESP8266_SSD1306
|
||||||
mathertel/OneButton@^2.0.3 ; OneButton library for non-blocking button debounce
|
mathertel/OneButton@^2.0.3 ; OneButton library for non-blocking button debounce
|
||||||
https://github.com/meshtastic/arduino-fsm.git#7db3702bf0cfe97b783d6c72595e3f38e0b19159
|
https://github.com/meshtastic/arduino-fsm.git#7db3702bf0cfe97b783d6c72595e3f38e0b19159
|
||||||
https://github.com/meshtastic/TinyGPSPlus.git#127ad674ef85f0201cb68a065879653ed94792c4
|
https://github.com/meshtastic/TinyGPSPlus.git#127ad674ef85f0201cb68a065879653ed94792c4
|
||||||
https://github.com/meshtastic/ArduinoThread.git#72921ac222eed6f526ba1682023cee290d9aa1b3
|
https://github.com/meshtastic/ArduinoThread.git#72921ac222eed6f526ba1682023cee290d9aa1b3
|
||||||
nanopb/Nanopb@^0.4.6
|
nanopb/Nanopb@^0.4.7
|
||||||
erriez/ErriezCRC32@^1.0.1
|
erriez/ErriezCRC32@^1.0.1
|
||||||
; jgromes/RadioLib@^5.5.1
|
jgromes/RadioLib@^5.7.0
|
||||||
https://github.com/jgromes/RadioLib.git#1afa947030c5637f71f6563bc22aa75032e53a57
|
|
||||||
|
|
||||||
; Used for the code analysis in PIO Home / Inspect
|
; Used for the code analysis in PIO Home / Inspect
|
||||||
check_tool = cppcheck
|
check_tool = cppcheck
|
||||||
@ -101,7 +100,7 @@ lib_deps =
|
|||||||
[environmental_base]
|
[environmental_base]
|
||||||
lib_deps =
|
lib_deps =
|
||||||
adafruit/Adafruit BusIO@^1.11.4
|
adafruit/Adafruit BusIO@^1.11.4
|
||||||
adafruit/Adafruit Unified Sensor@^1.1.4
|
adafruit/Adafruit Unified Sensor@^1.1.9
|
||||||
adafruit/Adafruit BMP280 Library@^2.6.6
|
adafruit/Adafruit BMP280 Library@^2.6.6
|
||||||
adafruit/Adafruit BME280 Library@^2.2.2
|
adafruit/Adafruit BME280 Library@^2.2.2
|
||||||
adafruit/Adafruit BME680 Library@^2.0.1
|
adafruit/Adafruit BME680 Library@^2.0.1
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit b3d05ec995844ae888e1d43d6e5c770b7d654309
|
Subproject commit 19d49ec5280b6904f8c4cd1182ba4250d4122dbe
|
70
src/detect/ScanI2C.cpp
Normal file
70
src/detect/ScanI2C.cpp
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
#include "ScanI2C.h"
|
||||||
|
|
||||||
|
const ScanI2C::DeviceAddress ScanI2C::ADDRESS_NONE = ScanI2C::DeviceAddress();
|
||||||
|
const ScanI2C::FoundDevice ScanI2C::DEVICE_NONE = ScanI2C::FoundDevice(ScanI2C::DeviceType::NONE, ADDRESS_NONE);
|
||||||
|
|
||||||
|
ScanI2C::ScanI2C() = default;
|
||||||
|
|
||||||
|
void ScanI2C::scanPort(ScanI2C::I2CPort port) {}
|
||||||
|
|
||||||
|
void ScanI2C::setSuppressScreen()
|
||||||
|
{
|
||||||
|
shouldSuppressScreen = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
ScanI2C::FoundDevice ScanI2C::firstScreen() const
|
||||||
|
{
|
||||||
|
// Allow to override the scanner results for screen
|
||||||
|
if (shouldSuppressScreen)
|
||||||
|
return DEVICE_NONE;
|
||||||
|
|
||||||
|
ScanI2C::DeviceType types[] = {SCREEN_SSD1306, SCREEN_SH1106, SCREEN_ST7567, SCREEN_UNKNOWN};
|
||||||
|
return firstOfOrNONE(4, types);
|
||||||
|
}
|
||||||
|
|
||||||
|
ScanI2C::FoundDevice ScanI2C::firstRTC() const
|
||||||
|
{
|
||||||
|
ScanI2C::DeviceType types[] = {RTC_RV3028, RTC_PCF8563};
|
||||||
|
return firstOfOrNONE(2, types);
|
||||||
|
}
|
||||||
|
|
||||||
|
ScanI2C::FoundDevice ScanI2C::firstKeyboard() const
|
||||||
|
{
|
||||||
|
ScanI2C::DeviceType types[] = {CARDKB, RAK14004};
|
||||||
|
return firstOfOrNONE(2, types);
|
||||||
|
}
|
||||||
|
|
||||||
|
ScanI2C::FoundDevice ScanI2C::find(ScanI2C::DeviceType) const
|
||||||
|
{
|
||||||
|
return DEVICE_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ScanI2C::exists(ScanI2C::DeviceType) const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ScanI2C::FoundDevice ScanI2C::firstOfOrNONE(size_t count, ScanI2C::DeviceType *types) const
|
||||||
|
{
|
||||||
|
return DEVICE_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t ScanI2C::countDevices() const
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ScanI2C::DeviceAddress::DeviceAddress(ScanI2C::I2CPort port, uint8_t address) : port(port), address(address) {}
|
||||||
|
|
||||||
|
ScanI2C::DeviceAddress::DeviceAddress() : DeviceAddress(I2CPort::NO_I2C, 0) {}
|
||||||
|
|
||||||
|
bool ScanI2C::DeviceAddress::operator<(const ScanI2C::DeviceAddress &other) const
|
||||||
|
{
|
||||||
|
return
|
||||||
|
// If this one has no port and other has a port
|
||||||
|
(port == NO_I2C && other.port != NO_I2C)
|
||||||
|
// if both have a port and this one's address is lower
|
||||||
|
|| (port != NO_I2C && other.port != NO_I2C && (address < other.address));
|
||||||
|
}
|
||||||
|
|
||||||
|
ScanI2C::FoundDevice::FoundDevice(ScanI2C::DeviceType type, ScanI2C::DeviceAddress address) : type(type), address(address) {}
|
93
src/detect/ScanI2C.h
Normal file
93
src/detect/ScanI2C.h
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
class ScanI2C
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef enum DeviceType {
|
||||||
|
NONE,
|
||||||
|
SCREEN_SSD1306,
|
||||||
|
SCREEN_SH1106,
|
||||||
|
SCREEN_UNKNOWN, // has the same address as the two above but does not respond to the same commands
|
||||||
|
SCREEN_ST7567,
|
||||||
|
ATECC608B,
|
||||||
|
RTC_RV3028,
|
||||||
|
RTC_PCF8563,
|
||||||
|
CARDKB,
|
||||||
|
RAK14004,
|
||||||
|
PMU_AXP192_AXP2101,
|
||||||
|
BME_680,
|
||||||
|
BME_280,
|
||||||
|
BMP_280,
|
||||||
|
INA260,
|
||||||
|
INA219,
|
||||||
|
MCP9808,
|
||||||
|
SHT31,
|
||||||
|
SHTC3,
|
||||||
|
LPS22HB,
|
||||||
|
QMC6310,
|
||||||
|
QMI8658,
|
||||||
|
QMC5883L,
|
||||||
|
PMSA0031,
|
||||||
|
} DeviceType;
|
||||||
|
|
||||||
|
// typedef uint8_t DeviceAddress;
|
||||||
|
typedef enum I2CPort {
|
||||||
|
NO_I2C,
|
||||||
|
WIRE,
|
||||||
|
WIRE1,
|
||||||
|
} I2CPort;
|
||||||
|
|
||||||
|
typedef struct DeviceAddress {
|
||||||
|
I2CPort port;
|
||||||
|
uint8_t address;
|
||||||
|
|
||||||
|
explicit DeviceAddress(I2CPort port, uint8_t address);
|
||||||
|
DeviceAddress();
|
||||||
|
|
||||||
|
bool operator<(const DeviceAddress &other) const;
|
||||||
|
} DeviceAddress;
|
||||||
|
|
||||||
|
static const DeviceAddress ADDRESS_NONE;
|
||||||
|
|
||||||
|
typedef uint8_t RegisterAddress;
|
||||||
|
|
||||||
|
typedef struct FoundDevice {
|
||||||
|
DeviceType type;
|
||||||
|
DeviceAddress address;
|
||||||
|
|
||||||
|
explicit FoundDevice(DeviceType = DeviceType::NONE, DeviceAddress = ADDRESS_NONE);
|
||||||
|
} FoundDevice;
|
||||||
|
|
||||||
|
static const FoundDevice DEVICE_NONE;
|
||||||
|
|
||||||
|
public:
|
||||||
|
ScanI2C();
|
||||||
|
|
||||||
|
virtual void scanPort(ScanI2C::I2CPort);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* A bit of a hack, this tells the scanner not to tell later systems there is a screen to avoid enabling it.
|
||||||
|
*/
|
||||||
|
void setSuppressScreen();
|
||||||
|
|
||||||
|
FoundDevice firstScreen() const;
|
||||||
|
|
||||||
|
FoundDevice firstRTC() const;
|
||||||
|
|
||||||
|
FoundDevice firstKeyboard() const;
|
||||||
|
|
||||||
|
virtual FoundDevice find(DeviceType) const;
|
||||||
|
|
||||||
|
virtual bool exists(DeviceType) const;
|
||||||
|
|
||||||
|
virtual size_t countDevices() const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual FoundDevice firstOfOrNONE(size_t, DeviceType[]) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool shouldSuppressScreen = false;
|
||||||
|
};
|
297
src/detect/ScanI2CTwoWire.cpp
Normal file
297
src/detect/ScanI2CTwoWire.cpp
Normal file
@ -0,0 +1,297 @@
|
|||||||
|
#include "ScanI2CTwoWire.h"
|
||||||
|
|
||||||
|
#include "concurrency/LockGuard.h"
|
||||||
|
#include "configuration.h"
|
||||||
|
|
||||||
|
#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL)
|
||||||
|
#include "main.h" // atecc
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// AXP192 and AXP2101 have the same device address, we just need to identify it in Power.cpp
|
||||||
|
#ifndef XPOWERS_AXP192_AXP2101_ADDRESS
|
||||||
|
#define XPOWERS_AXP192_AXP2101_ADDRESS 0x34
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ScanI2C::FoundDevice ScanI2CTwoWire::find(ScanI2C::DeviceType type) const
|
||||||
|
{
|
||||||
|
concurrency::LockGuard guard((concurrency::Lock *)&lock);
|
||||||
|
|
||||||
|
return exists(type) ? ScanI2C::FoundDevice(type, deviceAddresses.at(type)) : DEVICE_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ScanI2CTwoWire::exists(ScanI2C::DeviceType type) const
|
||||||
|
{
|
||||||
|
return deviceAddresses.find(type) != deviceAddresses.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
ScanI2C::FoundDevice ScanI2CTwoWire::firstOfOrNONE(size_t count, DeviceType types[]) const
|
||||||
|
{
|
||||||
|
concurrency::LockGuard guard((concurrency::Lock *)&lock);
|
||||||
|
|
||||||
|
for (size_t k = 0; k < count; k++) {
|
||||||
|
ScanI2C::DeviceType current = types[k];
|
||||||
|
|
||||||
|
if (exists(current)) {
|
||||||
|
return ScanI2C::FoundDevice(current, deviceAddresses.at(current));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return DEVICE_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
ScanI2C::DeviceType ScanI2CTwoWire::probeOLED(ScanI2C::DeviceAddress addr) const
|
||||||
|
{
|
||||||
|
TwoWire *i2cBus = fetchI2CBus(addr);
|
||||||
|
|
||||||
|
uint8_t r = 0;
|
||||||
|
uint8_t r_prev = 0;
|
||||||
|
uint8_t c = 0;
|
||||||
|
ScanI2C::DeviceType o_probe = ScanI2C::DeviceType::SCREEN_UNKNOWN;
|
||||||
|
do {
|
||||||
|
r_prev = r;
|
||||||
|
i2cBus->beginTransmission(addr.address);
|
||||||
|
i2cBus->write((uint8_t)0x00);
|
||||||
|
i2cBus->endTransmission();
|
||||||
|
i2cBus->requestFrom((int)addr.address, 1);
|
||||||
|
if (i2cBus->available()) {
|
||||||
|
r = i2cBus->read();
|
||||||
|
}
|
||||||
|
r &= 0x0f;
|
||||||
|
|
||||||
|
if (r == 0x08 || r == 0x00) {
|
||||||
|
LOG_INFO("sh1106 display found\n");
|
||||||
|
o_probe = SCREEN_SH1106; // SH1106
|
||||||
|
} else if (r == 0x03 || r == 0x04 || r == 0x06 || r == 0x07) {
|
||||||
|
LOG_INFO("ssd1306 display found\n");
|
||||||
|
o_probe = SCREEN_SSD1306; // SSD1306
|
||||||
|
}
|
||||||
|
c++;
|
||||||
|
} while ((r != r_prev) && (c < 4));
|
||||||
|
LOG_DEBUG("0x%x subtype probed in %i tries \n", r, c);
|
||||||
|
|
||||||
|
return o_probe;
|
||||||
|
}
|
||||||
|
void ScanI2CTwoWire::printATECCInfo() const
|
||||||
|
{
|
||||||
|
#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL)
|
||||||
|
atecc.readConfigZone(false);
|
||||||
|
|
||||||
|
LOG_DEBUG("ATECC608B Serial Number: ");
|
||||||
|
for (int i = 0; i < 9; i++) {
|
||||||
|
LOG_DEBUG("%02x", atecc.serialNumber[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_DEBUG(", Rev Number: ");
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
LOG_DEBUG("%02x", atecc.revisionNumber[i]);
|
||||||
|
}
|
||||||
|
LOG_DEBUG("\n");
|
||||||
|
|
||||||
|
LOG_DEBUG("ATECC608B Config %s", atecc.configLockStatus ? "Locked" : "Unlocked");
|
||||||
|
LOG_DEBUG(", Data %s", atecc.dataOTPLockStatus ? "Locked" : "Unlocked");
|
||||||
|
LOG_DEBUG(", Slot 0 %s\n", atecc.slot0LockStatus ? "Locked" : "Unlocked");
|
||||||
|
|
||||||
|
if (atecc.configLockStatus && atecc.dataOTPLockStatus && atecc.slot0LockStatus) {
|
||||||
|
if (atecc.generatePublicKey() == false) {
|
||||||
|
LOG_DEBUG("ATECC608B Error generating public key\n");
|
||||||
|
} else {
|
||||||
|
LOG_DEBUG("ATECC608B Public Key: ");
|
||||||
|
for (int i = 0; i < 64; i++) {
|
||||||
|
LOG_DEBUG("%02x", atecc.publicKey64Bytes[i]);
|
||||||
|
}
|
||||||
|
LOG_DEBUG("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t ScanI2CTwoWire::getRegisterValue(const ScanI2CTwoWire::RegisterLocation ®isterLocation,
|
||||||
|
ScanI2CTwoWire::ResponseWidth responseWidth) const
|
||||||
|
{
|
||||||
|
uint16_t value = 0x00;
|
||||||
|
TwoWire *i2cBus = fetchI2CBus(registerLocation.i2cAddress);
|
||||||
|
|
||||||
|
i2cBus->beginTransmission(registerLocation.i2cAddress.address);
|
||||||
|
i2cBus->write(registerLocation.registerAddress);
|
||||||
|
i2cBus->endTransmission();
|
||||||
|
delay(20);
|
||||||
|
i2cBus->requestFrom(registerLocation.i2cAddress.address, responseWidth);
|
||||||
|
LOG_DEBUG("Wire.available() = %d\n", i2cBus->available());
|
||||||
|
if (i2cBus->available() == 2) {
|
||||||
|
// Read MSB, then LSB
|
||||||
|
value = (uint16_t)i2cBus->read() << 8;
|
||||||
|
value |= i2cBus->read();
|
||||||
|
} else if (i2cBus->available()) {
|
||||||
|
value = i2cBus->read();
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define SCAN_SIMPLE_CASE(ADDR, T, ...) \
|
||||||
|
case ADDR: \
|
||||||
|
LOG_INFO(__VA_ARGS__); \
|
||||||
|
type = T; \
|
||||||
|
break;
|
||||||
|
|
||||||
|
void ScanI2CTwoWire::scanPort(I2CPort port)
|
||||||
|
{
|
||||||
|
concurrency::LockGuard guard((concurrency::Lock *)&lock);
|
||||||
|
|
||||||
|
LOG_DEBUG("Scanning for i2c devices on port %d\n", port);
|
||||||
|
|
||||||
|
uint8_t err;
|
||||||
|
|
||||||
|
DeviceAddress addr(port, 0x00);
|
||||||
|
|
||||||
|
uint16_t registerValue = 0x00;
|
||||||
|
ScanI2C::DeviceType type;
|
||||||
|
TwoWire *i2cBus;
|
||||||
|
#ifdef RV3028_RTC
|
||||||
|
Melopero_RV3028 rtc;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef I2C_SDA1
|
||||||
|
if (port == I2CPort::WIRE1) {
|
||||||
|
i2cBus = &Wire1;
|
||||||
|
} else {
|
||||||
|
#endif
|
||||||
|
i2cBus = &Wire;
|
||||||
|
#ifdef I2C_SDA1
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
for (addr.address = 1; addr.address < 127; addr.address++) {
|
||||||
|
i2cBus->beginTransmission(addr.address);
|
||||||
|
err = i2cBus->endTransmission();
|
||||||
|
type = NONE;
|
||||||
|
if (err == 0) {
|
||||||
|
LOG_DEBUG("I2C device found at address 0x%x\n", addr.address);
|
||||||
|
|
||||||
|
switch (addr.address) {
|
||||||
|
case SSD1306_ADDRESS:
|
||||||
|
type = probeOLED(addr);
|
||||||
|
break;
|
||||||
|
|
||||||
|
#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL)
|
||||||
|
case ATECC608B_ADDR:
|
||||||
|
type = ATECC608B;
|
||||||
|
if (atecc.begin(addr.address) == true) {
|
||||||
|
LOG_INFO("ATECC608B initialized\n");
|
||||||
|
} else {
|
||||||
|
LOG_WARN("ATECC608B initialization failed\n");
|
||||||
|
}
|
||||||
|
printATECCInfo();
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef RV3028_RTC
|
||||||
|
case RV3028_RTC:
|
||||||
|
// foundDevices[addr] = RTC_RV3028;
|
||||||
|
type = RTC_RV3028;
|
||||||
|
LOG_INFO("RV3028 RTC found\n");
|
||||||
|
rtc.initI2C(*i2cBus);
|
||||||
|
rtc.writeToRegister(0x35, 0x07); // no Clkout
|
||||||
|
rtc.writeToRegister(0x37, 0xB4);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef PCF8563_RTC
|
||||||
|
SCAN_SIMPLE_CASE(PCF8563_RTC, RTC_PCF8563, "PCF8563 RTC found\n")
|
||||||
|
#endif
|
||||||
|
|
||||||
|
case CARDKB_ADDR:
|
||||||
|
// Do we have the RAK14006 instead?
|
||||||
|
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0x04), 1);
|
||||||
|
if (registerValue == 0x02) {
|
||||||
|
// KEYPAD_VERSION
|
||||||
|
LOG_INFO("RAK14004 found\n");
|
||||||
|
type = RAK14004;
|
||||||
|
} else {
|
||||||
|
LOG_INFO("m5 cardKB found\n");
|
||||||
|
type = CARDKB;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
SCAN_SIMPLE_CASE(ST7567_ADDRESS, SCREEN_ST7567, "st7567 display found\n")
|
||||||
|
|
||||||
|
#ifdef HAS_PMU
|
||||||
|
SCAN_SIMPLE_CASE(XPOWERS_AXP192_AXP2101_ADDRESS, PMU_AXP192_AXP2101, "axp192/axp2101 PMU found\n")
|
||||||
|
#endif
|
||||||
|
case BME_ADDR:
|
||||||
|
case BME_ADDR_ALTERNATE:
|
||||||
|
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0xD0), 1); // GET_ID
|
||||||
|
switch (registerValue) {
|
||||||
|
case 0x61:
|
||||||
|
LOG_INFO("BME-680 sensor found at address 0x%x\n", (uint8_t)addr.address);
|
||||||
|
type = BME_680;
|
||||||
|
break;
|
||||||
|
case 0x60:
|
||||||
|
LOG_INFO("BME-280 sensor found at address 0x%x\n", (uint8_t)addr.address);
|
||||||
|
type = BME_280;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
LOG_INFO("BMP-280 sensor found at address 0x%x\n", (uint8_t)addr.address);
|
||||||
|
type = BMP_280;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case INA_ADDR:
|
||||||
|
case INA_ADDR_ALTERNATE:
|
||||||
|
registerValue = getRegisterValue(ScanI2CTwoWire::RegisterLocation(addr, 0xFE), 2);
|
||||||
|
LOG_DEBUG("Register MFG_UID: 0x%x\n", registerValue);
|
||||||
|
if (registerValue == 0x5449) {
|
||||||
|
LOG_INFO("INA260 sensor found at address 0x%x\n", (uint8_t)addr.address);
|
||||||
|
type = INA260;
|
||||||
|
} else { // Assume INA219 if INA260 ID is not found
|
||||||
|
LOG_INFO("INA219 sensor found at address 0x%x\n", (uint8_t)addr.address);
|
||||||
|
type = INA219;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
SCAN_SIMPLE_CASE(MCP9808_ADDR, MCP9808, "MCP9808 sensor found\n")
|
||||||
|
|
||||||
|
SCAN_SIMPLE_CASE(SHT31_ADDR, SHT31, "SHT31 sensor found\n")
|
||||||
|
SCAN_SIMPLE_CASE(SHTC3_ADDR, SHTC3, "SHTC3 sensor found\n")
|
||||||
|
|
||||||
|
case LPS22HB_ADDR_ALT:
|
||||||
|
SCAN_SIMPLE_CASE(LPS22HB_ADDR, LPS22HB, "LPS22HB sensor found\n")
|
||||||
|
|
||||||
|
SCAN_SIMPLE_CASE(QMC6310_ADDR, QMC6310, "QMC6310 Highrate 3-Axis magnetic sensor found\n")
|
||||||
|
SCAN_SIMPLE_CASE(QMI8658_ADDR, QMI8658, "QMI8658 Highrate 6-Axis inertial measurement sensor found\n")
|
||||||
|
SCAN_SIMPLE_CASE(QMC5883L_ADDR, QMC5883L, "QMC5883L Highrate 3-Axis magnetic sensor found\n")
|
||||||
|
|
||||||
|
SCAN_SIMPLE_CASE(PMSA0031_ADDR, PMSA0031, "PMSA0031 air quality sensor found\n")
|
||||||
|
|
||||||
|
default:
|
||||||
|
LOG_INFO("Device found at address 0x%x was not able to be enumerated\n", addr.address);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (err == 4) {
|
||||||
|
LOG_ERROR("Unknown error at address 0x%x\n", addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if a type was found for the enumerated device - save, if so
|
||||||
|
if (type != NONE) {
|
||||||
|
deviceAddresses[type] = addr;
|
||||||
|
foundDevices[addr] = type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TwoWire *ScanI2CTwoWire::fetchI2CBus(ScanI2C::DeviceAddress address) const
|
||||||
|
{
|
||||||
|
if (address.port == ScanI2C::I2CPort::WIRE1) {
|
||||||
|
return &Wire;
|
||||||
|
} else {
|
||||||
|
#ifdef I2C_SDA1
|
||||||
|
return &Wire1;
|
||||||
|
#else
|
||||||
|
return &Wire;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t ScanI2CTwoWire::countDevices() const
|
||||||
|
{
|
||||||
|
return foundDevices.size();
|
||||||
|
}
|
56
src/detect/ScanI2CTwoWire.h
Normal file
56
src/detect/ScanI2CTwoWire.h
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <memory>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include <Wire.h>
|
||||||
|
|
||||||
|
#include "ScanI2C.h"
|
||||||
|
|
||||||
|
#include "../concurrency/Lock.h"
|
||||||
|
|
||||||
|
class ScanI2CTwoWire : public ScanI2C
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void scanPort(ScanI2C::I2CPort) override;
|
||||||
|
|
||||||
|
ScanI2C::FoundDevice find(ScanI2C::DeviceType) const override;
|
||||||
|
|
||||||
|
bool exists(ScanI2C::DeviceType) const override;
|
||||||
|
|
||||||
|
size_t countDevices() const override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
FoundDevice firstOfOrNONE(size_t, DeviceType[]) const override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
typedef struct RegisterLocation {
|
||||||
|
DeviceAddress i2cAddress;
|
||||||
|
RegisterAddress registerAddress;
|
||||||
|
|
||||||
|
RegisterLocation(DeviceAddress deviceAddress, RegisterAddress registerAddress)
|
||||||
|
: i2cAddress(deviceAddress), registerAddress(registerAddress)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
} RegisterLocation;
|
||||||
|
|
||||||
|
typedef uint8_t ResponseWidth;
|
||||||
|
|
||||||
|
std::map<ScanI2C::DeviceAddress, ScanI2C::DeviceType> foundDevices;
|
||||||
|
|
||||||
|
// note: prone to overwriting if multiple devices of a type are added at different addresses (rare?)
|
||||||
|
std::map<ScanI2C::DeviceType, ScanI2C::DeviceAddress> deviceAddresses;
|
||||||
|
|
||||||
|
concurrency::Lock lock;
|
||||||
|
|
||||||
|
void printATECCInfo() const;
|
||||||
|
|
||||||
|
uint16_t getRegisterValue(const RegisterLocation &, ResponseWidth) const;
|
||||||
|
|
||||||
|
DeviceType probeOLED(ScanI2C::DeviceAddress) const;
|
||||||
|
|
||||||
|
TwoWire *fetchI2CBus(ScanI2C::DeviceAddress) const;
|
||||||
|
};
|
@ -1,237 +0,0 @@
|
|||||||
#include "../configuration.h"
|
|
||||||
#include "../main.h"
|
|
||||||
#include "mesh/generated/meshtastic/telemetry.pb.h"
|
|
||||||
#include <Wire.h>
|
|
||||||
|
|
||||||
// AXP192 and AXP2101 have the same device address, we just need to identify it in Power.cpp
|
|
||||||
#ifndef XPOWERS_AXP192_AXP2101_ADDRESS
|
|
||||||
#define XPOWERS_AXP192_AXP2101_ADDRESS 0x34
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if HAS_WIRE
|
|
||||||
|
|
||||||
void printATECCInfo()
|
|
||||||
{
|
|
||||||
#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL)
|
|
||||||
atecc.readConfigZone(false);
|
|
||||||
|
|
||||||
LOG_DEBUG("ATECC608B Serial Number: ");
|
|
||||||
for (int i = 0; i < 9; i++) {
|
|
||||||
LOG_DEBUG("%02x", atecc.serialNumber[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
LOG_DEBUG(", Rev Number: ");
|
|
||||||
for (int i = 0; i < 4; i++) {
|
|
||||||
LOG_DEBUG("%02x", atecc.revisionNumber[i]);
|
|
||||||
}
|
|
||||||
LOG_DEBUG("\n");
|
|
||||||
|
|
||||||
LOG_DEBUG("ATECC608B Config %s", atecc.configLockStatus ? "Locked" : "Unlocked");
|
|
||||||
LOG_DEBUG(", Data %s", atecc.dataOTPLockStatus ? "Locked" : "Unlocked");
|
|
||||||
LOG_DEBUG(", Slot 0 %s\n", atecc.slot0LockStatus ? "Locked" : "Unlocked");
|
|
||||||
|
|
||||||
if (atecc.configLockStatus && atecc.dataOTPLockStatus && atecc.slot0LockStatus) {
|
|
||||||
if (atecc.generatePublicKey() == false) {
|
|
||||||
LOG_DEBUG("ATECC608B Error generating public key\n");
|
|
||||||
} else {
|
|
||||||
LOG_DEBUG("ATECC608B Public Key: ");
|
|
||||||
for (int i = 0; i < 64; i++) {
|
|
||||||
LOG_DEBUG("%02x", atecc.publicKey64Bytes[i]);
|
|
||||||
}
|
|
||||||
LOG_DEBUG("\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
uint16_t getRegisterValue(uint8_t address, uint8_t reg, uint8_t length)
|
|
||||||
{
|
|
||||||
uint16_t value = 0x00;
|
|
||||||
Wire.beginTransmission(address);
|
|
||||||
Wire.write(reg);
|
|
||||||
Wire.endTransmission();
|
|
||||||
delay(20);
|
|
||||||
Wire.requestFrom(address, length);
|
|
||||||
LOG_DEBUG("Wire.available() = %d\n", Wire.available());
|
|
||||||
if (Wire.available() == 2) {
|
|
||||||
// Read MSB, then LSB
|
|
||||||
value = (uint16_t)Wire.read() << 8;
|
|
||||||
value |= Wire.read();
|
|
||||||
} else if (Wire.available()) {
|
|
||||||
value = Wire.read();
|
|
||||||
}
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t oled_probe(byte addr)
|
|
||||||
{
|
|
||||||
uint8_t r = 0;
|
|
||||||
uint8_t r_prev = 0;
|
|
||||||
uint8_t c = 0;
|
|
||||||
uint8_t o_probe = 0;
|
|
||||||
do {
|
|
||||||
r_prev = r;
|
|
||||||
Wire.beginTransmission(addr);
|
|
||||||
Wire.write(0x00);
|
|
||||||
Wire.endTransmission();
|
|
||||||
Wire.requestFrom((int)addr, 1);
|
|
||||||
if (Wire.available()) {
|
|
||||||
r = Wire.read();
|
|
||||||
}
|
|
||||||
r &= 0x0f;
|
|
||||||
|
|
||||||
if (r == 0x08 || r == 0x00) {
|
|
||||||
o_probe = 2; // SH1106
|
|
||||||
} else if (r == 0x03 || r == 0x04 || r == 0x06 || r == 0x07) {
|
|
||||||
o_probe = 1; // SSD1306
|
|
||||||
}
|
|
||||||
c++;
|
|
||||||
} while ((r != r_prev) && (c < 4));
|
|
||||||
LOG_DEBUG("0x%x subtype probed in %i tries \n", r, c);
|
|
||||||
return o_probe;
|
|
||||||
}
|
|
||||||
|
|
||||||
void scanI2Cdevice()
|
|
||||||
{
|
|
||||||
byte err, addr;
|
|
||||||
uint16_t registerValue = 0x00;
|
|
||||||
int nDevices = 0;
|
|
||||||
for (addr = 1; addr < 127; addr++) {
|
|
||||||
Wire.beginTransmission(addr);
|
|
||||||
err = Wire.endTransmission();
|
|
||||||
if (err == 0) {
|
|
||||||
LOG_DEBUG("I2C device found at address 0x%x\n", addr);
|
|
||||||
|
|
||||||
nDevices++;
|
|
||||||
|
|
||||||
if (addr == SSD1306_ADDRESS) {
|
|
||||||
screen_found = addr;
|
|
||||||
screen_model = oled_probe(addr);
|
|
||||||
if (screen_model == 1) {
|
|
||||||
LOG_INFO("ssd1306 display found\n");
|
|
||||||
} else if (screen_model == 2) {
|
|
||||||
LOG_INFO("sh1106 display found\n");
|
|
||||||
} else {
|
|
||||||
LOG_INFO("unknown display found\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL)
|
|
||||||
if (addr == ATECC608B_ADDR) {
|
|
||||||
keystore_found = addr;
|
|
||||||
if (atecc.begin(keystore_found) == true) {
|
|
||||||
LOG_INFO("ATECC608B initialized\n");
|
|
||||||
} else {
|
|
||||||
LOG_WARN("ATECC608B initialization failed\n");
|
|
||||||
}
|
|
||||||
printATECCInfo();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef RV3028_RTC
|
|
||||||
if (addr == RV3028_RTC) {
|
|
||||||
rtc_found = addr;
|
|
||||||
LOG_INFO("RV3028 RTC found\n");
|
|
||||||
Melopero_RV3028 rtc;
|
|
||||||
rtc.initI2C();
|
|
||||||
rtc.writeToRegister(0x35, 0x07); // no Clkout
|
|
||||||
rtc.writeToRegister(0x37, 0xB4);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#ifdef PCF8563_RTC
|
|
||||||
if (addr == PCF8563_RTC) {
|
|
||||||
rtc_found = addr;
|
|
||||||
LOG_INFO("PCF8563 RTC found\n");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if (addr == CARDKB_ADDR) {
|
|
||||||
cardkb_found = addr;
|
|
||||||
// Do we have the RAK14006 instead?
|
|
||||||
registerValue = getRegisterValue(addr, 0x04, 1);
|
|
||||||
if (registerValue == 0x02) { // KEYPAD_VERSION
|
|
||||||
LOG_INFO("RAK14004 found\n");
|
|
||||||
kb_model = 0x02;
|
|
||||||
} else {
|
|
||||||
LOG_INFO("m5 cardKB found\n");
|
|
||||||
kb_model = 0x00;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (addr == ST7567_ADDRESS) {
|
|
||||||
screen_found = addr;
|
|
||||||
LOG_INFO("st7567 display found\n");
|
|
||||||
}
|
|
||||||
#ifdef HAS_PMU
|
|
||||||
if (addr == XPOWERS_AXP192_AXP2101_ADDRESS) {
|
|
||||||
pmu_found = true;
|
|
||||||
LOG_INFO("axp192/axp2101 PMU found\n");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if (addr == BME_ADDR || addr == BME_ADDR_ALTERNATE) {
|
|
||||||
registerValue = getRegisterValue(addr, 0xD0, 1); // GET_ID
|
|
||||||
if (registerValue == 0x61) {
|
|
||||||
LOG_INFO("BME-680 sensor found at address 0x%x\n", (uint8_t)addr);
|
|
||||||
nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_BME680] = addr;
|
|
||||||
} else if (registerValue == 0x60) {
|
|
||||||
LOG_INFO("BME-280 sensor found at address 0x%x\n", (uint8_t)addr);
|
|
||||||
nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_BME280] = addr;
|
|
||||||
} else {
|
|
||||||
LOG_INFO("BMP-280 sensor found at address 0x%x\n", (uint8_t)addr);
|
|
||||||
nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_BMP280] = addr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (addr == INA_ADDR || addr == INA_ADDR_ALTERNATE) {
|
|
||||||
registerValue = getRegisterValue(addr, 0xFE, 2);
|
|
||||||
LOG_DEBUG("Register MFG_UID: 0x%x\n", registerValue);
|
|
||||||
if (registerValue == 0x5449) {
|
|
||||||
LOG_INFO("INA260 sensor found at address 0x%x\n", (uint8_t)addr);
|
|
||||||
nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_INA260] = addr;
|
|
||||||
} else { // Assume INA219 if INA260 ID is not found
|
|
||||||
LOG_INFO("INA219 sensor found at address 0x%x\n", (uint8_t)addr);
|
|
||||||
nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_INA219] = addr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (addr == MCP9808_ADDR) {
|
|
||||||
nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_MCP9808] = addr;
|
|
||||||
LOG_INFO("MCP9808 sensor found\n");
|
|
||||||
}
|
|
||||||
if (addr == SHT31_ADDR) {
|
|
||||||
LOG_INFO("SHT31 sensor found\n");
|
|
||||||
nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_SHT31] = addr;
|
|
||||||
}
|
|
||||||
if (addr == SHTC3_ADDR) {
|
|
||||||
LOG_INFO("SHTC3 sensor found\n");
|
|
||||||
nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_SHTC3] = addr;
|
|
||||||
}
|
|
||||||
if (addr == LPS22HB_ADDR || addr == LPS22HB_ADDR_ALT) {
|
|
||||||
LOG_INFO("LPS22HB sensor found\n");
|
|
||||||
nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_LPS22] = addr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// High rate sensors, will be processed internally
|
|
||||||
if (addr == QMC6310_ADDR) {
|
|
||||||
LOG_INFO("QMC6310 Highrate 3-Axis magnetic sensor found\n");
|
|
||||||
nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_QMC6310] = addr;
|
|
||||||
}
|
|
||||||
if (addr == QMI8658_ADDR) {
|
|
||||||
LOG_INFO("QMI8658 Highrate 6-Axis inertial measurement sensor found\n");
|
|
||||||
nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_QMI8658] = addr;
|
|
||||||
}
|
|
||||||
if (addr == QMC5883L_ADDR) {
|
|
||||||
LOG_INFO("QMC5883L Highrate 3-Axis magnetic sensor found\n");
|
|
||||||
nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_QMC5883L] = addr;
|
|
||||||
}
|
|
||||||
if (addr == PMSA0031_ADDR) {
|
|
||||||
LOG_INFO("PMSA0031 air quality sensor found\n");
|
|
||||||
nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_PMSA003I] = addr;
|
|
||||||
}
|
|
||||||
} else if (err == 4) {
|
|
||||||
LOG_ERROR("Unknow error at address 0x%x\n", addr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nDevices == 0)
|
|
||||||
LOG_INFO("No I2C devices found\n");
|
|
||||||
else
|
|
||||||
LOG_INFO("%i I2C devices found\n", nDevices);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
void scanI2Cdevice() {}
|
|
||||||
#endif
|
|
@ -1,5 +1,6 @@
|
|||||||
#include "RTC.h"
|
#include "RTC.h"
|
||||||
#include "configuration.h"
|
#include "configuration.h"
|
||||||
|
#include "detect/ScanI2C.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
@ -20,10 +21,14 @@ void readFromRTC()
|
|||||||
{
|
{
|
||||||
struct timeval tv; /* btw settimeofday() is helpfull here too*/
|
struct timeval tv; /* btw settimeofday() is helpfull here too*/
|
||||||
#ifdef RV3028_RTC
|
#ifdef RV3028_RTC
|
||||||
if (rtc_found == RV3028_RTC) {
|
if (rtc_found.address == RV3028_RTC) {
|
||||||
uint32_t now = millis();
|
uint32_t now = millis();
|
||||||
Melopero_RV3028 rtc;
|
Melopero_RV3028 rtc;
|
||||||
|
#ifdef I2C_SDA1
|
||||||
|
rtc.initI2C(rtc_found.port == ScanI2C::I2CPort::WIRE1 ? Wire1 : Wire);
|
||||||
|
#else
|
||||||
rtc.initI2C();
|
rtc.initI2C();
|
||||||
|
#endif
|
||||||
tm t;
|
tm t;
|
||||||
t.tm_year = rtc.getYear() - 1900;
|
t.tm_year = rtc.getYear() - 1900;
|
||||||
t.tm_mon = rtc.getMonth() - 1;
|
t.tm_mon = rtc.getMonth() - 1;
|
||||||
@ -41,14 +46,16 @@ void readFromRTC()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#elif defined(PCF8563_RTC)
|
#elif defined(PCF8563_RTC)
|
||||||
if (rtc_found == PCF8563_RTC) {
|
if (rtc_found.address == PCF8563_RTC) {
|
||||||
uint32_t now = millis();
|
uint32_t now = millis();
|
||||||
PCF8563_Class rtc;
|
PCF8563_Class rtc;
|
||||||
#ifdef RTC_USE_WIRE1
|
|
||||||
rtc.begin(Wire1);
|
#ifdef I2C_SDA1
|
||||||
|
rtc.begin(rtc_found.port == ScanI2C::I2CPort::WIRE1 ? Wire1 : Wire);
|
||||||
#else
|
#else
|
||||||
rtc.begin();
|
rtc.begin();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
auto tc = rtc.getDateTime();
|
auto tc = rtc.getDateTime();
|
||||||
tm t;
|
tm t;
|
||||||
t.tm_year = tc.year - 1900;
|
t.tm_year = tc.year - 1900;
|
||||||
@ -103,19 +110,24 @@ bool perhapsSetRTC(RTCQuality q, const struct timeval *tv)
|
|||||||
|
|
||||||
// If this platform has a setable RTC, set it
|
// If this platform has a setable RTC, set it
|
||||||
#ifdef RV3028_RTC
|
#ifdef RV3028_RTC
|
||||||
if (rtc_found == RV3028_RTC) {
|
if (rtc_found.address == RV3028_RTC) {
|
||||||
Melopero_RV3028 rtc;
|
Melopero_RV3028 rtc;
|
||||||
|
#ifdef I2C_SDA1
|
||||||
|
rtc.initI2C(rtc_found.port == ScanI2C::I2CPort::WIRE1 ? Wire1 : Wire);
|
||||||
|
#else
|
||||||
rtc.initI2C();
|
rtc.initI2C();
|
||||||
|
#endif
|
||||||
tm *t = localtime(&tv->tv_sec);
|
tm *t = localtime(&tv->tv_sec);
|
||||||
rtc.setTime(t->tm_year + 1900, t->tm_mon + 1, t->tm_wday, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
|
rtc.setTime(t->tm_year + 1900, t->tm_mon + 1, t->tm_wday, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
|
||||||
LOG_DEBUG("RV3028_RTC setTime %02d-%02d-%02d %02d:%02d:%02d %ld\n", t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
|
LOG_DEBUG("RV3028_RTC setTime %02d-%02d-%02d %02d:%02d:%02d %ld\n", t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
|
||||||
t->tm_hour, t->tm_min, t->tm_sec, tv->tv_sec);
|
t->tm_hour, t->tm_min, t->tm_sec, tv->tv_sec);
|
||||||
}
|
}
|
||||||
#elif defined(PCF8563_RTC)
|
#elif defined(PCF8563_RTC)
|
||||||
if (rtc_found == PCF8563_RTC) {
|
if (rtc_found.address == PCF8563_RTC) {
|
||||||
PCF8563_Class rtc;
|
PCF8563_Class rtc;
|
||||||
#ifdef RTC_USE_WIRE1
|
|
||||||
rtc.begin(Wire1);
|
#ifdef I2C_SDA1
|
||||||
|
rtc.begin(rtc_found.port == ScanI2C::I2CPort::WIRE1 ? Wire1 : Wire);
|
||||||
#else
|
#else
|
||||||
rtc.begin();
|
rtc.begin();
|
||||||
#endif
|
#endif
|
||||||
|
@ -41,7 +41,7 @@
|
|||||||
|
|
||||||
GxEPD2_BW<TECHO_DISPLAY_MODEL, TECHO_DISPLAY_MODEL::HEIGHT> *adafruitDisplay;
|
GxEPD2_BW<TECHO_DISPLAY_MODEL, TECHO_DISPLAY_MODEL::HEIGHT> *adafruitDisplay;
|
||||||
|
|
||||||
EInkDisplay::EInkDisplay(uint8_t address, int sda, int scl, uint8_t screen_model)
|
EInkDisplay::EInkDisplay(uint8_t address, int sda, int scl, OLEDDISPLAY_GEOMETRY geometry, HW_I2C i2cBus)
|
||||||
{
|
{
|
||||||
#if defined(TTGO_T_ECHO)
|
#if defined(TTGO_T_ECHO)
|
||||||
setGeometry(GEOMETRY_RAWMODE, TECHO_DISPLAY_MODEL::WIDTH, TECHO_DISPLAY_MODEL::HEIGHT);
|
setGeometry(GEOMETRY_RAWMODE, TECHO_DISPLAY_MODEL::WIDTH, TECHO_DISPLAY_MODEL::HEIGHT);
|
||||||
|
@ -22,7 +22,7 @@ class EInkDisplay : public OLEDDisplay
|
|||||||
/* constructor
|
/* constructor
|
||||||
FIXME - the parameters are not used, just a temporary hack to keep working like the old displays
|
FIXME - the parameters are not used, just a temporary hack to keep working like the old displays
|
||||||
*/
|
*/
|
||||||
EInkDisplay(uint8_t address, int sda, int scl, uint8_t screen_model);
|
EInkDisplay(uint8_t, int, int, OLEDDISPLAY_GEOMETRY, HW_I2C);
|
||||||
|
|
||||||
// Write the buffer to the display memory (for eink we only do this occasionally)
|
// Write the buffer to the display memory (for eink we only do this occasionally)
|
||||||
virtual void display(void) override;
|
virtual void display(void) override;
|
||||||
|
@ -19,6 +19,7 @@ You should have received a copy of the GNU General Public License
|
|||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
#include "Screen.h"
|
||||||
#include "configuration.h"
|
#include "configuration.h"
|
||||||
#if HAS_SCREEN
|
#if HAS_SCREEN
|
||||||
#include <OLEDDisplay.h>
|
#include <OLEDDisplay.h>
|
||||||
@ -26,7 +27,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||||||
#include "GPS.h"
|
#include "GPS.h"
|
||||||
#include "MeshService.h"
|
#include "MeshService.h"
|
||||||
#include "NodeDB.h"
|
#include "NodeDB.h"
|
||||||
#include "Screen.h"
|
|
||||||
#include "gps/GeoCoord.h"
|
#include "gps/GeoCoord.h"
|
||||||
#include "gps/RTC.h"
|
#include "gps/RTC.h"
|
||||||
#include "graphics/images.h"
|
#include "graphics/images.h"
|
||||||
@ -886,13 +886,11 @@ static void drawNodeInfo(OLEDDisplay *display, OLEDDisplayUiState *state, int16_
|
|||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
// #else
|
// #else
|
||||||
Screen::Screen(uint8_t address, int sda, int scl)
|
Screen::Screen(ScanI2C::DeviceAddress address, meshtastic_Config_DisplayConfig_OledType screenType, OLEDDISPLAY_GEOMETRY geometry)
|
||||||
: OSThread("Screen"), cmdQueue(32),
|
: concurrency::OSThread("Screen"), address_found(address), model(screenType), geometry(geometry), cmdQueue(32),
|
||||||
dispdev(address, sda, scl,
|
dispdev(address.address, -1, -1, geometry, (address.port == ScanI2C::I2CPort::WIRE1) ? HW_I2C::I2C_TWO : HW_I2C::I2C_ONE),
|
||||||
screen_model == meshtastic_Config_DisplayConfig_OledType_OLED_SH1107 ? GEOMETRY_128_128 : GEOMETRY_128_64),
|
|
||||||
ui(&dispdev)
|
ui(&dispdev)
|
||||||
{
|
{
|
||||||
address_found = address;
|
|
||||||
cmdQueue.setReader(this);
|
cmdQueue.setReader(this);
|
||||||
}
|
}
|
||||||
// #endif
|
// #endif
|
||||||
@ -940,9 +938,11 @@ void Screen::setup()
|
|||||||
useDisplay = true;
|
useDisplay = true;
|
||||||
|
|
||||||
#ifdef AutoOLEDWire_h
|
#ifdef AutoOLEDWire_h
|
||||||
if (screen_model == meshtastic_Config_DisplayConfig_OledType_OLED_SH1107)
|
dispdev.setDetected(model);
|
||||||
screen_model = meshtastic_Config_DisplayConfig_OledType_OLED_SH1106;
|
#endif
|
||||||
dispdev.setDetected(screen_model);
|
|
||||||
|
#ifdef USE_SH1107_128_64
|
||||||
|
dispdev.setSubtype(7);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Initialising the UI will init the display too.
|
// Initialising the UI will init the display too.
|
||||||
@ -1177,7 +1177,7 @@ void Screen::drawDebugInfoWiFiTrampoline(OLEDDisplay *display, OLEDDisplayUiStat
|
|||||||
* it is expected that this will be used during the boot phase */
|
* it is expected that this will be used during the boot phase */
|
||||||
void Screen::setSSLFrames()
|
void Screen::setSSLFrames()
|
||||||
{
|
{
|
||||||
if (address_found) {
|
if (address_found.address) {
|
||||||
// LOG_DEBUG("showing SSL frames\n");
|
// LOG_DEBUG("showing SSL frames\n");
|
||||||
static FrameCallback sslFrames[] = {drawSSLScreen};
|
static FrameCallback sslFrames[] = {drawSSLScreen};
|
||||||
ui.setFrames(sslFrames, 1);
|
ui.setFrames(sslFrames, 1);
|
||||||
@ -1189,7 +1189,7 @@ void Screen::setSSLFrames()
|
|||||||
* it is expected that this will be used during the boot phase */
|
* it is expected that this will be used during the boot phase */
|
||||||
void Screen::setWelcomeFrames()
|
void Screen::setWelcomeFrames()
|
||||||
{
|
{
|
||||||
if (address_found) {
|
if (address_found.address) {
|
||||||
// LOG_DEBUG("showing Welcome frames\n");
|
// LOG_DEBUG("showing Welcome frames\n");
|
||||||
ui.disableAllIndicators();
|
ui.disableAllIndicators();
|
||||||
|
|
||||||
@ -1821,5 +1821,6 @@ int Screen::handleUIFrameEvent(const UIFrameEvent *event)
|
|||||||
}
|
}
|
||||||
|
|
||||||
} // namespace graphics
|
} // namespace graphics
|
||||||
|
#else
|
||||||
|
graphics::Screen::Screen(ScanI2C::DeviceAddress, meshtastic_Config_DisplayConfig_OledType, OLEDDISPLAY_GEOMETRY) {}
|
||||||
#endif // HAS_SCREEN
|
#endif // HAS_SCREEN
|
||||||
|
@ -2,6 +2,10 @@
|
|||||||
|
|
||||||
#include "configuration.h"
|
#include "configuration.h"
|
||||||
|
|
||||||
|
#include "detect/ScanI2C.h"
|
||||||
|
#include "mesh/generated/meshtastic/config.pb.h"
|
||||||
|
#include <OLEDDisplay.h>
|
||||||
|
|
||||||
#if !HAS_SCREEN
|
#if !HAS_SCREEN
|
||||||
#include "power.h"
|
#include "power.h"
|
||||||
namespace graphics
|
namespace graphics
|
||||||
@ -10,7 +14,7 @@ namespace graphics
|
|||||||
class Screen
|
class Screen
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit Screen(char) {}
|
explicit Screen(ScanI2C::DeviceAddress, meshtastic_Config_DisplayConfig_OledType, OLEDDISPLAY_GEOMETRY);
|
||||||
void onPress() {}
|
void onPress() {}
|
||||||
void setup() {}
|
void setup() {}
|
||||||
void setOn(bool) {}
|
void setOn(bool) {}
|
||||||
@ -24,7 +28,6 @@ class Screen
|
|||||||
void startFirmwareUpdateScreen() {}
|
void startFirmwareUpdateScreen() {}
|
||||||
};
|
};
|
||||||
} // namespace graphics
|
} // namespace graphics
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
@ -34,7 +37,7 @@ class Screen
|
|||||||
|
|
||||||
#ifdef USE_ST7567
|
#ifdef USE_ST7567
|
||||||
#include <ST7567Wire.h>
|
#include <ST7567Wire.h>
|
||||||
#elif defined(USE_SH1106) || defined(USE_SH1107)
|
#elif defined(USE_SH1106) || defined(USE_SH1107) || defined(USE_SH1107_128_64)
|
||||||
#include <SH1106Wire.h>
|
#include <SH1106Wire.h>
|
||||||
#elif defined(USE_SSD1306)
|
#elif defined(USE_SSD1306)
|
||||||
#include <SSD1306Wire.h>
|
#include <SSD1306Wire.h>
|
||||||
@ -116,12 +119,14 @@ class Screen : public concurrency::OSThread
|
|||||||
CallbackObserver<Screen, const UIFrameEvent *>(this, &Screen::handleUIFrameEvent);
|
CallbackObserver<Screen, const UIFrameEvent *>(this, &Screen::handleUIFrameEvent);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit Screen(uint8_t address, int sda = -1, int scl = -1);
|
explicit Screen(ScanI2C::DeviceAddress, meshtastic_Config_DisplayConfig_OledType, OLEDDISPLAY_GEOMETRY);
|
||||||
|
|
||||||
Screen(const Screen &) = delete;
|
Screen(const Screen &) = delete;
|
||||||
Screen &operator=(const Screen &) = delete;
|
Screen &operator=(const Screen &) = delete;
|
||||||
|
|
||||||
uint8_t address_found;
|
ScanI2C::DeviceAddress address_found;
|
||||||
|
meshtastic_Config_DisplayConfig_OledType model;
|
||||||
|
OLEDDISPLAY_GEOMETRY geometry;
|
||||||
|
|
||||||
/// Initializes the UI, turns on the display, starts showing boot screen.
|
/// Initializes the UI, turns on the display, starts showing boot screen.
|
||||||
//
|
//
|
||||||
@ -370,7 +375,7 @@ class Screen : public concurrency::OSThread
|
|||||||
|
|
||||||
/// Display device
|
/// Display device
|
||||||
|
|
||||||
#if defined(USE_SH1106) || defined(USE_SH1107)
|
#if defined(USE_SH1106) || defined(USE_SH1107) || defined(USE_SH1107_128_64)
|
||||||
SH1106Wire dispdev;
|
SH1106Wire dispdev;
|
||||||
#elif defined(USE_SSD1306)
|
#elif defined(USE_SSD1306)
|
||||||
SSD1306Wire dispdev;
|
SSD1306Wire dispdev;
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
static TFT_eSPI tft = TFT_eSPI(); // Invoke library, pins defined in User_Setup.h
|
static TFT_eSPI tft = TFT_eSPI(); // Invoke library, pins defined in User_Setup.h
|
||||||
|
|
||||||
TFTDisplay::TFTDisplay(uint8_t address, int sda, int scl, uint8_t screen_model)
|
TFTDisplay::TFTDisplay(uint8_t address, int sda, int scl, OLEDDISPLAY_GEOMETRY geometry, HW_I2C i2cBus)
|
||||||
{
|
{
|
||||||
#ifdef SCREEN_ROTATE
|
#ifdef SCREEN_ROTATE
|
||||||
setGeometry(GEOMETRY_RAWMODE, TFT_HEIGHT, TFT_WIDTH);
|
setGeometry(GEOMETRY_RAWMODE, TFT_HEIGHT, TFT_WIDTH);
|
||||||
|
@ -18,7 +18,7 @@ class TFTDisplay : public OLEDDisplay
|
|||||||
/* constructor
|
/* constructor
|
||||||
FIXME - the parameters are not used, just a temporary hack to keep working like the old displays
|
FIXME - the parameters are not used, just a temporary hack to keep working like the old displays
|
||||||
*/
|
*/
|
||||||
TFTDisplay(uint8_t address, int sda, int scl, uint8_t screen_model);
|
TFTDisplay(uint8_t, int, int, OLEDDISPLAY_GEOMETRY, HW_I2C);
|
||||||
|
|
||||||
// Write the buffer to the display memory
|
// Write the buffer to the display memory
|
||||||
virtual void display(void) override;
|
virtual void display(void) override;
|
||||||
|
@ -7,7 +7,7 @@ CardKbI2cImpl::CardKbI2cImpl() : KbI2cBase("cardKB") {}
|
|||||||
|
|
||||||
void CardKbI2cImpl::init()
|
void CardKbI2cImpl::init()
|
||||||
{
|
{
|
||||||
if (cardkb_found != CARDKB_ADDR) {
|
if (cardkb_found.address != CARDKB_ADDR) {
|
||||||
disable();
|
disable();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
#include "kbI2cBase.h"
|
#include "kbI2cBase.h"
|
||||||
#include "configuration.h"
|
|
||||||
#include <Wire.h>
|
|
||||||
|
|
||||||
extern uint8_t cardkb_found;
|
#include "configuration.h"
|
||||||
|
#include "detect/ScanI2C.h"
|
||||||
|
|
||||||
|
extern ScanI2C::DeviceAddress cardkb_found;
|
||||||
extern uint8_t kb_model;
|
extern uint8_t kb_model;
|
||||||
|
|
||||||
KbI2cBase::KbI2cBase(const char *name) : concurrency::OSThread(name)
|
KbI2cBase::KbI2cBase(const char *name) : concurrency::OSThread(name)
|
||||||
@ -10,43 +11,64 @@ KbI2cBase::KbI2cBase(const char *name) : concurrency::OSThread(name)
|
|||||||
this->_originName = name;
|
this->_originName = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t read_from_14004(uint8_t reg, uint8_t *data, uint8_t length)
|
uint8_t read_from_14004(TwoWire *i2cBus, uint8_t reg, uint8_t *data, uint8_t length)
|
||||||
{
|
{
|
||||||
uint8_t readflag = 0;
|
uint8_t readflag = 0;
|
||||||
Wire.beginTransmission(CARDKB_ADDR);
|
i2cBus->beginTransmission(CARDKB_ADDR);
|
||||||
Wire.write(reg);
|
i2cBus->write(reg);
|
||||||
Wire.endTransmission(); // stop transmitting
|
i2cBus->endTransmission(); // stop transmitting
|
||||||
delay(20);
|
delay(20);
|
||||||
Wire.requestFrom(CARDKB_ADDR, (int)length);
|
i2cBus->requestFrom(CARDKB_ADDR, (int)length);
|
||||||
int i = 0;
|
int i = 0;
|
||||||
while (Wire.available()) // slave may send less than requested
|
while (i2cBus->available()) // slave may send less than requested
|
||||||
{
|
{
|
||||||
data[i++] = Wire.read(); // receive a byte as a proper uint8_t
|
data[i++] = i2cBus->read(); // receive a byte as a proper uint8_t
|
||||||
readflag = 1;
|
readflag = 1;
|
||||||
}
|
}
|
||||||
return readflag;
|
return readflag;
|
||||||
}
|
}
|
||||||
|
|
||||||
void write_to_14004(uint8_t reg, uint8_t data)
|
// Unused for now - flagging it off
|
||||||
|
#if 0
|
||||||
|
void write_to_14004(const TwoWire * i2cBus, uint8_t reg, uint8_t data)
|
||||||
{
|
{
|
||||||
Wire.beginTransmission(CARDKB_ADDR);
|
i2cBus->beginTransmission(CARDKB_ADDR);
|
||||||
Wire.write(reg);
|
i2cBus->write(reg);
|
||||||
Wire.write(data);
|
i2cBus->write(data);
|
||||||
Wire.endTransmission(); // stop transmitting
|
i2cBus->endTransmission(); // stop transmitting
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
int32_t KbI2cBase::runOnce()
|
int32_t KbI2cBase::runOnce()
|
||||||
{
|
{
|
||||||
if (cardkb_found != CARDKB_ADDR) {
|
if (cardkb_found.address != CARDKB_ADDR) {
|
||||||
// Input device is not detected.
|
// Input device is not detected.
|
||||||
return INT32_MAX;
|
return INT32_MAX;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!i2cBus) {
|
||||||
|
switch (cardkb_found.port) {
|
||||||
|
case ScanI2C::WIRE1:
|
||||||
|
#ifdef I2C_SDA1
|
||||||
|
LOG_DEBUG("Using I2C Bus 1 (the second one)\n");
|
||||||
|
i2cBus = &Wire1;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
case ScanI2C::WIRE:
|
||||||
|
LOG_DEBUG("Using I2C Bus 0 (the first one)\n");
|
||||||
|
i2cBus = &Wire;
|
||||||
|
break;
|
||||||
|
case ScanI2C::NO_I2C:
|
||||||
|
default:
|
||||||
|
i2cBus = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (kb_model == 0x02) {
|
if (kb_model == 0x02) {
|
||||||
// RAK14004
|
// RAK14004
|
||||||
uint8_t rDataBuf[8] = {0};
|
uint8_t rDataBuf[8] = {0};
|
||||||
uint8_t PrintDataBuf = 0;
|
uint8_t PrintDataBuf = 0;
|
||||||
if (read_from_14004(0x01, rDataBuf, 0x04) == 1) {
|
if (read_from_14004(i2cBus, 0x01, rDataBuf, 0x04) == 1) {
|
||||||
for (uint8_t aCount = 0; aCount < 0x04; aCount++) {
|
for (uint8_t aCount = 0; aCount < 0x04; aCount++) {
|
||||||
for (uint8_t bCount = 0; bCount < 0x04; bCount++) {
|
for (uint8_t bCount = 0; bCount < 0x04; bCount++) {
|
||||||
if (((rDataBuf[aCount] >> bCount) & 0x01) == 0x01) {
|
if (((rDataBuf[aCount] >> bCount) & 0x01) == 0x01) {
|
||||||
@ -65,10 +87,10 @@ int32_t KbI2cBase::runOnce()
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// m5 cardkb
|
// m5 cardkb
|
||||||
Wire.requestFrom(CARDKB_ADDR, 1);
|
i2cBus->requestFrom(CARDKB_ADDR, 1);
|
||||||
|
|
||||||
while (Wire.available()) {
|
while (i2cBus->available()) {
|
||||||
char c = Wire.read();
|
char c = i2cBus->read();
|
||||||
InputEvent e;
|
InputEvent e;
|
||||||
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_NONE;
|
e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_NONE;
|
||||||
e.source = this->_originName;
|
e.source = this->_originName;
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include "InputBroker.h"
|
#include "InputBroker.h"
|
||||||
#include "SinglePortModule.h" // TODO: what header file to include?
|
#include "SinglePortModule.h" // TODO: what header file to include?
|
||||||
|
#include "Wire.h"
|
||||||
|
|
||||||
class KbI2cBase : public Observable<const InputEvent *>, public concurrency::OSThread
|
class KbI2cBase : public Observable<const InputEvent *>, public concurrency::OSThread
|
||||||
{
|
{
|
||||||
@ -13,4 +14,6 @@ class KbI2cBase : public Observable<const InputEvent *>, public concurrency::OST
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
const char *_originName;
|
const char *_originName;
|
||||||
|
|
||||||
|
TwoWire *i2cBus = 0;
|
||||||
};
|
};
|
||||||
|
149
src/main.cpp
149
src/main.cpp
@ -15,16 +15,19 @@
|
|||||||
#include "SPILock.h"
|
#include "SPILock.h"
|
||||||
#include "concurrency/OSThread.h"
|
#include "concurrency/OSThread.h"
|
||||||
#include "concurrency/Periodic.h"
|
#include "concurrency/Periodic.h"
|
||||||
|
#include "detect/ScanI2C.h"
|
||||||
|
#include "detect/ScanI2CTwoWire.h"
|
||||||
#include "detect/axpDebug.h"
|
#include "detect/axpDebug.h"
|
||||||
#include "detect/einkScan.h"
|
#include "detect/einkScan.h"
|
||||||
#include "detect/i2cScan.h"
|
|
||||||
#include "graphics/Screen.h"
|
#include "graphics/Screen.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
|
#include "mesh/generated/meshtastic/config.pb.h"
|
||||||
#include "modules/Modules.h"
|
#include "modules/Modules.h"
|
||||||
#include "shutdown.h"
|
#include "shutdown.h"
|
||||||
#include "sleep.h"
|
#include "sleep.h"
|
||||||
#include "target_specific.h"
|
#include "target_specific.h"
|
||||||
#include <Wire.h>
|
#include <Wire.h>
|
||||||
|
#include <memory>
|
||||||
// #include <driver/rtc_io.h>
|
// #include <driver/rtc_io.h>
|
||||||
|
|
||||||
#include "mesh/eth/ethClient.h"
|
#include "mesh/eth/ethClient.h"
|
||||||
@ -79,20 +82,19 @@ meshtastic::GPSStatus *gpsStatus = new meshtastic::GPSStatus();
|
|||||||
// Global Node status
|
// Global Node status
|
||||||
meshtastic::NodeStatus *nodeStatus = new meshtastic::NodeStatus();
|
meshtastic::NodeStatus *nodeStatus = new meshtastic::NodeStatus();
|
||||||
|
|
||||||
|
// Scan for I2C Devices
|
||||||
|
|
||||||
/// The I2C address of our display (if found)
|
/// The I2C address of our display (if found)
|
||||||
uint8_t screen_found;
|
ScanI2C::DeviceAddress screen_found = ScanI2C::ADDRESS_NONE;
|
||||||
uint8_t screen_model;
|
|
||||||
|
|
||||||
// The I2C address of the cardkb or RAK14004 (if found)
|
// The I2C address of the cardkb or RAK14004 (if found)
|
||||||
uint8_t cardkb_found;
|
ScanI2C::DeviceAddress cardkb_found = ScanI2C::ADDRESS_NONE;
|
||||||
// 0x02 for RAK14004 and 0x00 for cardkb
|
// 0x02 for RAK14004 and 0x00 for cardkb
|
||||||
uint8_t kb_model;
|
uint8_t kb_model;
|
||||||
|
|
||||||
// The I2C address of the RTC Module (if found)
|
// The I2C address of the RTC Module (if found)
|
||||||
uint8_t rtc_found;
|
ScanI2C::DeviceAddress rtc_found = ScanI2C::ADDRESS_NONE;
|
||||||
|
|
||||||
// Keystore Chips
|
|
||||||
uint8_t keystore_found;
|
|
||||||
#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL)
|
#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL)
|
||||||
ATECCX08A atecc;
|
ATECCX08A atecc;
|
||||||
#endif
|
#endif
|
||||||
@ -173,6 +175,9 @@ __attribute__((weak, noinline)) bool loopCanSleep()
|
|||||||
void setup()
|
void setup()
|
||||||
{
|
{
|
||||||
concurrency::hasBeenSetup = true;
|
concurrency::hasBeenSetup = true;
|
||||||
|
meshtastic_Config_DisplayConfig_OledType screen_model =
|
||||||
|
meshtastic_Config_DisplayConfig_OledType::meshtastic_Config_DisplayConfig_OledType_OLED_AUTO;
|
||||||
|
OLEDDISPLAY_GEOMETRY screen_geometry = GEOMETRY_128_64;
|
||||||
|
|
||||||
#ifdef SEGGER_STDOUT_CH
|
#ifdef SEGGER_STDOUT_CH
|
||||||
auto mode = false ? SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL : SEGGER_RTT_MODE_NO_BLOCK_TRIM;
|
auto mode = false ? SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL : SEGGER_RTT_MODE_NO_BLOCK_TRIM;
|
||||||
@ -259,23 +264,118 @@ void setup()
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Currently only the tbeam has a PMU
|
// Currently only the tbeam has a PMU
|
||||||
// PMU initialization needs to be placed before scanI2Cdevice
|
// PMU initialization needs to be placed before i2c scanning
|
||||||
power = new Power();
|
power = new Power();
|
||||||
power->setStatusHandler(powerStatus);
|
power->setStatusHandler(powerStatus);
|
||||||
powerStatus->observe(&power->newStatus);
|
powerStatus->observe(&power->newStatus);
|
||||||
power->setup(); // Must be after status handler is installed, so that handler gets notified of the initial configuration
|
power->setup(); // Must be after status handler is installed, so that handler gets notified of the initial configuration
|
||||||
|
|
||||||
#ifdef LILYGO_TBEAM_S3_CORE
|
// We need to scan here to decide if we have a screen for nodeDB.init() and because power has been applied to
|
||||||
// In T-Beam-S3-core, the I2C device cannot be scanned before power initialization, otherwise the device will be stuck
|
// accessories
|
||||||
// PCF8563 RTC in tbeam-s3 uses Wire1 to share I2C bus
|
auto i2cScanner = std::unique_ptr<ScanI2CTwoWire>(new ScanI2CTwoWire());
|
||||||
Wire1.beginTransmission(PCF8563_RTC);
|
|
||||||
if (Wire1.endTransmission() == 0) {
|
LOG_INFO("Scanning for i2c devices...\n");
|
||||||
rtc_found = PCF8563_RTC;
|
|
||||||
LOG_INFO("PCF8563 RTC found\n");
|
#ifdef I2C_SDA1
|
||||||
|
Wire1.begin(I2C_SDA1, I2C_SCL1);
|
||||||
|
i2cScanner->scanPort(ScanI2C::I2CPort::WIRE1);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef I2C_SDA
|
||||||
|
Wire.begin(I2C_SDA, I2C_SCL);
|
||||||
|
i2cScanner->scanPort(ScanI2C::I2CPort::WIRE);
|
||||||
|
#elif HAS_WIRE
|
||||||
|
i2cScanner->scanPort(ScanI2C::I2CPort::WIRE);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
auto i2cCount = i2cScanner->countDevices();
|
||||||
|
if (i2cCount == 0) {
|
||||||
|
LOG_INFO("No I2C devices found\n");
|
||||||
|
} else {
|
||||||
|
LOG_INFO("%i I2C devices found\n", i2cCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef ARCH_ESP32
|
||||||
|
// Don't init display if we don't have one or we are waking headless due to a timer event
|
||||||
|
if (wakeCause == ESP_SLEEP_WAKEUP_TIMER) {
|
||||||
|
LOG_DEBUG("suppress screen wake because this is a headless timer wakeup");
|
||||||
|
i2cScanner->setSuppressScreen();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
// We need to scan here to decide if we have a screen for nodeDB.init()
|
|
||||||
scanI2Cdevice();
|
auto screenInfo = i2cScanner->firstScreen();
|
||||||
|
screen_found = screenInfo.type != ScanI2C::DeviceType::NONE ? screenInfo.address : ScanI2C::ADDRESS_NONE;
|
||||||
|
|
||||||
|
if (screen_found.port != ScanI2C::I2CPort::NO_I2C) {
|
||||||
|
switch (screenInfo.type) {
|
||||||
|
case ScanI2C::DeviceType::SCREEN_SH1106:
|
||||||
|
screen_model = meshtastic_Config_DisplayConfig_OledType::meshtastic_Config_DisplayConfig_OledType_OLED_SH1106;
|
||||||
|
break;
|
||||||
|
case ScanI2C::DeviceType::SCREEN_SSD1306:
|
||||||
|
screen_model = meshtastic_Config_DisplayConfig_OledType::meshtastic_Config_DisplayConfig_OledType_OLED_SSD1306;
|
||||||
|
break;
|
||||||
|
case ScanI2C::DeviceType::SCREEN_ST7567:
|
||||||
|
case ScanI2C::DeviceType::SCREEN_UNKNOWN:
|
||||||
|
default:
|
||||||
|
screen_model = meshtastic_Config_DisplayConfig_OledType::meshtastic_Config_DisplayConfig_OledType_OLED_AUTO;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#define UPDATE_FROM_SCANNER(FIND_FN)
|
||||||
|
|
||||||
|
auto rtc_info = i2cScanner->firstRTC();
|
||||||
|
rtc_found = rtc_info.type != ScanI2C::DeviceType::NONE ? rtc_info.address : rtc_found;
|
||||||
|
|
||||||
|
auto kb_info = i2cScanner->firstKeyboard();
|
||||||
|
|
||||||
|
if (kb_info.type != ScanI2C::DeviceType::NONE) {
|
||||||
|
cardkb_found = kb_info.address;
|
||||||
|
switch (kb_info.type) {
|
||||||
|
case ScanI2C::DeviceType::RAK14004:
|
||||||
|
kb_model = 0x02;
|
||||||
|
break;
|
||||||
|
case ScanI2C::DeviceType::CARDKB:
|
||||||
|
default:
|
||||||
|
// use this as default since it's also just zero
|
||||||
|
kb_model = 0x00;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pmu_found = i2cScanner->exists(ScanI2C::DeviceType::PMU_AXP192_AXP2101);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* There are a bunch of sensors that have no further logic than to be found and stuffed into the
|
||||||
|
* nodeTelemetrySensorsMap singleton. This wraps that logic in a temporary scope to declare the temporary field
|
||||||
|
* "found".
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define STRING(S) #S
|
||||||
|
|
||||||
|
#define SCANNER_TO_SENSORS_MAP(SCANNER_T, PB_T) \
|
||||||
|
{ \
|
||||||
|
auto found = i2cScanner->find(SCANNER_T); \
|
||||||
|
if (found.type != ScanI2C::DeviceType::NONE) { \
|
||||||
|
nodeTelemetrySensorsMap[PB_T] = found.address.address; \
|
||||||
|
LOG_DEBUG("found i2c sensor %s\n", STRING(PB_T)); \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::BME_680, meshtastic_TelemetrySensorType_BME680)
|
||||||
|
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::BME_280, meshtastic_TelemetrySensorType_BME280)
|
||||||
|
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::BMP_280, meshtastic_TelemetrySensorType_BMP280)
|
||||||
|
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::INA260, meshtastic_TelemetrySensorType_INA260)
|
||||||
|
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::INA219, meshtastic_TelemetrySensorType_INA219)
|
||||||
|
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::MCP9808, meshtastic_TelemetrySensorType_MCP9808)
|
||||||
|
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::MCP9808, meshtastic_TelemetrySensorType_MCP9808)
|
||||||
|
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::SHT31, meshtastic_TelemetrySensorType_SHT31)
|
||||||
|
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::SHTC3, meshtastic_TelemetrySensorType_SHTC3)
|
||||||
|
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::LPS22HB, meshtastic_TelemetrySensorType_LPS22)
|
||||||
|
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::QMC6310, meshtastic_TelemetrySensorType_QMC6310)
|
||||||
|
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::QMI8658, meshtastic_TelemetrySensorType_QMI8658)
|
||||||
|
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::QMC5883L, meshtastic_TelemetrySensorType_QMC5883L)
|
||||||
|
SCANNER_TO_SENSORS_MAP(ScanI2C::DeviceType::PMSA0031, meshtastic_TelemetrySensorType_PMSA003I)
|
||||||
|
|
||||||
|
i2cScanner.reset();
|
||||||
|
|
||||||
#ifdef HAS_SDCARD
|
#ifdef HAS_SDCARD
|
||||||
setupSDCard();
|
setupSDCard();
|
||||||
@ -299,10 +399,6 @@ void setup()
|
|||||||
LOG_INFO("Meshtastic hwvendor=%d, swver=%s\n", HW_VENDOR, optstr(APP_VERSION));
|
LOG_INFO("Meshtastic hwvendor=%d, swver=%s\n", HW_VENDOR, optstr(APP_VERSION));
|
||||||
|
|
||||||
#ifdef ARCH_ESP32
|
#ifdef ARCH_ESP32
|
||||||
// Don't init display if we don't have one or we are waking headless due to a timer event
|
|
||||||
if (wakeCause == ESP_SLEEP_WAKEUP_TIMER)
|
|
||||||
screen_found = 0; // forget we even have the hardware
|
|
||||||
|
|
||||||
esp32Setup();
|
esp32Setup();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -324,7 +420,12 @@ void setup()
|
|||||||
screen_model = config.display.oled;
|
screen_model = config.display.oled;
|
||||||
|
|
||||||
#if defined(USE_SH1107)
|
#if defined(USE_SH1107)
|
||||||
screen_model = Config_DisplayConfig_OledType_OLED_SH1107; // set dimension of 128x128
|
screen_model = meshtastic_Config_DisplayConfig_OledType_OLED_SH1107; // set dimension of 128x128
|
||||||
|
display_geometry = GEOMETRY_128_128;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(USE_SH1107_128_64)
|
||||||
|
screen_model = meshtastic_Config_DisplayConfig_OledType_OLED_SH1107; // keep dimension of 128x64
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Init our SPI controller (must be before screen and lora)
|
// Init our SPI controller (must be before screen and lora)
|
||||||
@ -338,7 +439,7 @@ void setup()
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Initialize the screen first so we can show the logo while we start up everything else.
|
// Initialize the screen first so we can show the logo while we start up everything else.
|
||||||
screen = new graphics::Screen(screen_found);
|
screen = new graphics::Screen(screen_found, screen_model, screen_geometry);
|
||||||
|
|
||||||
readFromRTC(); // read the main CPU RTC at first (in case we can't get GPS time)
|
readFromRTC(); // read the main CPU RTC at first (in case we can't get GPS time)
|
||||||
|
|
||||||
@ -367,7 +468,7 @@ void setup()
|
|||||||
#if defined(ST7735_CS) || defined(USE_EINK) || defined(ILI9341_DRIVER)
|
#if defined(ST7735_CS) || defined(USE_EINK) || defined(ILI9341_DRIVER)
|
||||||
screen->setup();
|
screen->setup();
|
||||||
#else
|
#else
|
||||||
if (screen_found)
|
if (screen_found.port != ScanI2C::I2CPort::NO_I2C)
|
||||||
screen->setup();
|
screen->setup();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
10
src/main.h
10
src/main.h
@ -3,8 +3,10 @@
|
|||||||
#include "GPSStatus.h"
|
#include "GPSStatus.h"
|
||||||
#include "NodeStatus.h"
|
#include "NodeStatus.h"
|
||||||
#include "PowerStatus.h"
|
#include "PowerStatus.h"
|
||||||
|
#include "detect/ScanI2C.h"
|
||||||
#include "graphics/Screen.h"
|
#include "graphics/Screen.h"
|
||||||
#include "memGet.h"
|
#include "memGet.h"
|
||||||
|
#include "mesh/generated/meshtastic/config.pb.h"
|
||||||
#include "mesh/generated/meshtastic/telemetry.pb.h"
|
#include "mesh/generated/meshtastic/telemetry.pb.h"
|
||||||
#include <map>
|
#include <map>
|
||||||
#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL)
|
#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL)
|
||||||
@ -19,12 +21,10 @@ extern NimbleBluetooth *nimbleBluetooth;
|
|||||||
extern NRF52Bluetooth *nrf52Bluetooth;
|
extern NRF52Bluetooth *nrf52Bluetooth;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern uint8_t screen_found;
|
extern ScanI2C::DeviceAddress screen_found;
|
||||||
extern uint8_t screen_model;
|
extern ScanI2C::DeviceAddress cardkb_found;
|
||||||
extern uint8_t cardkb_found;
|
|
||||||
extern uint8_t kb_model;
|
extern uint8_t kb_model;
|
||||||
extern uint8_t rtc_found;
|
extern ScanI2C::DeviceAddress rtc_found;
|
||||||
extern uint8_t keystore_found;
|
|
||||||
|
|
||||||
extern bool eink_found;
|
extern bool eink_found;
|
||||||
extern bool pmu_found;
|
extern bool pmu_found;
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include "configuration.h"
|
#include "configuration.h"
|
||||||
|
|
||||||
|
#include "../detect/ScanI2C.h"
|
||||||
#include "Channels.h"
|
#include "Channels.h"
|
||||||
#include "CryptoEngine.h"
|
#include "CryptoEngine.h"
|
||||||
#include "FSCommon.h"
|
#include "FSCommon.h"
|
||||||
@ -181,7 +182,7 @@ void NodeDB::installDefaultConfig()
|
|||||||
#if defined(ST7735_CS) || defined(USE_EINK) || defined(ILI9341_DRIVER)
|
#if defined(ST7735_CS) || defined(USE_EINK) || defined(ILI9341_DRIVER)
|
||||||
bool hasScreen = true;
|
bool hasScreen = true;
|
||||||
#else
|
#else
|
||||||
bool hasScreen = screen_found;
|
bool hasScreen = screen_found.port != ScanI2C::I2CPort::NO_I2C;
|
||||||
#endif
|
#endif
|
||||||
config.bluetooth.mode = hasScreen ? meshtastic_Config_BluetoothConfig_PairingMode_RANDOM_PIN
|
config.bluetooth.mode = hasScreen ? meshtastic_Config_BluetoothConfig_PairingMode_RANDOM_PIN
|
||||||
: meshtastic_Config_BluetoothConfig_PairingMode_FIXED_PIN;
|
: meshtastic_Config_BluetoothConfig_PairingMode_FIXED_PIN;
|
||||||
|
@ -281,7 +281,7 @@ void printPacket(const char *prefix, const meshtastic_MeshPacket *p)
|
|||||||
if (p->priority != 0)
|
if (p->priority != 0)
|
||||||
out += DEBUG_PORT.mt_sprintf(" priority=%d", p->priority);
|
out += DEBUG_PORT.mt_sprintf(" priority=%d", p->priority);
|
||||||
|
|
||||||
out + ")\n";
|
out += ")\n";
|
||||||
LOG_DEBUG("%s", out.c_str());
|
LOG_DEBUG("%s", out.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -212,9 +212,10 @@ template <typename T> void SX126xInterface<T>::startReceive()
|
|||||||
|
|
||||||
setStandby();
|
setStandby();
|
||||||
|
|
||||||
// int err = lora.startReceive();
|
// We use a 16 bit preamble so this should save some power by letting radio sit in standby mostly.
|
||||||
int err = lora.startReceiveDutyCycleAuto(); // We use a 32 bit preamble so this should save some power by letting radio sit in
|
// Furthermore, we need the HEADER_VALID IRQ flag to detect whether we are actively receiving
|
||||||
// standby mostly.
|
int err =
|
||||||
|
lora.startReceiveDutyCycleAuto(preambleLength, 8, RADIOLIB_SX126X_IRQ_RX_DEFAULT | RADIOLIB_SX126X_IRQ_HEADER_VALID);
|
||||||
assert(err == RADIOLIB_ERR_NONE);
|
assert(err == RADIOLIB_ERR_NONE);
|
||||||
|
|
||||||
isReceiving = true;
|
isReceiving = true;
|
||||||
@ -224,7 +225,7 @@ template <typename T> void SX126xInterface<T>::startReceive()
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Could we send right now (i.e. either not actively receving or transmitting)? */
|
/** Is the channel currently active? */
|
||||||
template <typename T> bool SX126xInterface<T>::isChannelActive()
|
template <typename T> bool SX126xInterface<T>::isChannelActive()
|
||||||
{
|
{
|
||||||
// check if we can detect a LoRa preamble on the current channel
|
// check if we can detect a LoRa preamble on the current channel
|
||||||
@ -245,17 +246,12 @@ template <typename T> bool SX126xInterface<T>::isActivelyReceiving()
|
|||||||
{
|
{
|
||||||
// The IRQ status will be cleared when we start our read operation. Check if we've started a header, but haven't yet
|
// The IRQ status will be cleared when we start our read operation. Check if we've started a header, but haven't yet
|
||||||
// received and handled the interrupt for reading the packet/handling errors.
|
// received and handled the interrupt for reading the packet/handling errors.
|
||||||
// FIXME: it would be better to check for preamble, but we currently have our ISR not set to fire for packets that
|
|
||||||
// never even get a valid header, so we don't want preamble to get set and stay set due to noise on the network.
|
|
||||||
|
|
||||||
uint16_t irq = lora.getIrqStatus();
|
uint16_t irq = lora.getIrqStatus();
|
||||||
bool hasPreamble = (irq & RADIOLIB_SX126X_IRQ_HEADER_VALID);
|
bool headerValid = (irq & RADIOLIB_SX126X_IRQ_HEADER_VALID);
|
||||||
|
|
||||||
// this is not correct - often always true - need to add an extra conditional
|
// if (headerValid) LOG_DEBUG("rx headerValid\n");
|
||||||
// size_t bytesPending = lora.getPacketLength();
|
return headerValid;
|
||||||
|
|
||||||
// if (hasPreamble) LOG_DEBUG("rx hasPreamble\n");
|
|
||||||
return hasPreamble;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T> bool SX126xInterface<T>::sleep()
|
template <typename T> bool SX126xInterface<T>::sleep()
|
||||||
|
@ -203,7 +203,9 @@ template <typename T> void SX128xInterface<T>::startReceive()
|
|||||||
digitalWrite(SX128X_TXEN, LOW);
|
digitalWrite(SX128X_TXEN, LOW);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int err = lora.startReceive();
|
// We use the HEADER_VALID IRQ flag to detect whether we are actively receiving
|
||||||
|
int err =
|
||||||
|
lora.startReceive(RADIOLIB_SX128X_RX_TIMEOUT_INF, RADIOLIB_SX128X_IRQ_RX_DEFAULT | RADIOLIB_SX128X_IRQ_HEADER_VALID);
|
||||||
|
|
||||||
assert(err == RADIOLIB_ERR_NONE);
|
assert(err == RADIOLIB_ERR_NONE);
|
||||||
|
|
||||||
@ -214,7 +216,7 @@ template <typename T> void SX128xInterface<T>::startReceive()
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Could we send right now (i.e. either not actively receving or transmitting)? */
|
/** Is the channel currently active? */
|
||||||
template <typename T> bool SX128xInterface<T>::isChannelActive()
|
template <typename T> bool SX128xInterface<T>::isChannelActive()
|
||||||
{
|
{
|
||||||
// check if we can detect a LoRa preamble on the current channel
|
// check if we can detect a LoRa preamble on the current channel
|
||||||
@ -234,8 +236,8 @@ template <typename T> bool SX128xInterface<T>::isChannelActive()
|
|||||||
template <typename T> bool SX128xInterface<T>::isActivelyReceiving()
|
template <typename T> bool SX128xInterface<T>::isActivelyReceiving()
|
||||||
{
|
{
|
||||||
uint16_t irq = lora.getIrqStatus();
|
uint16_t irq = lora.getIrqStatus();
|
||||||
bool hasPreamble = (irq & RADIOLIB_SX128X_IRQ_HEADER_VALID);
|
bool hasHeader = (irq & RADIOLIB_SX128X_IRQ_HEADER_VALID);
|
||||||
return hasPreamble;
|
return hasHeader;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T> bool SX128xInterface<T>::sleep()
|
template <typename T> bool SX128xInterface<T>::sleep()
|
||||||
|
@ -135,7 +135,7 @@ typedef struct _meshtastic_AdminMessage {
|
|||||||
/* Tell the node to reboot into the OTA Firmware in this many seconds (or <0 to cancel reboot)
|
/* Tell the node to reboot into the OTA Firmware in this many seconds (or <0 to cancel reboot)
|
||||||
Only Implemented for ESP32 Devices. This needs to be issued to send a new main firmware via bluetooth. */
|
Only Implemented for ESP32 Devices. This needs to be issued to send a new main firmware via bluetooth. */
|
||||||
int32_t reboot_ota_seconds;
|
int32_t reboot_ota_seconds;
|
||||||
/* This message is only supported for the simulator porduino build.
|
/* This message is only supported for the simulator Portduino build.
|
||||||
If received the simulator will exit successfully. */
|
If received the simulator will exit successfully. */
|
||||||
bool exit_simulator;
|
bool exit_simulator;
|
||||||
/* Tell the node to reboot in this many seconds (or <0 to cancel reboot) */
|
/* Tell the node to reboot in this many seconds (or <0 to cancel reboot) */
|
||||||
|
@ -152,7 +152,7 @@ typedef enum _meshtastic_Config_LoRaConfig_RegionCode {
|
|||||||
meshtastic_Config_LoRaConfig_RegionCode_US = 1,
|
meshtastic_Config_LoRaConfig_RegionCode_US = 1,
|
||||||
/* European Union 433mhz */
|
/* European Union 433mhz */
|
||||||
meshtastic_Config_LoRaConfig_RegionCode_EU_433 = 2,
|
meshtastic_Config_LoRaConfig_RegionCode_EU_433 = 2,
|
||||||
/* European Union 433mhz */
|
/* European Union 868mhz */
|
||||||
meshtastic_Config_LoRaConfig_RegionCode_EU_868 = 3,
|
meshtastic_Config_LoRaConfig_RegionCode_EU_868 = 3,
|
||||||
/* China */
|
/* China */
|
||||||
meshtastic_Config_LoRaConfig_RegionCode_CN = 4,
|
meshtastic_Config_LoRaConfig_RegionCode_CN = 4,
|
||||||
@ -202,11 +202,11 @@ typedef enum _meshtastic_Config_LoRaConfig_ModemPreset {
|
|||||||
} meshtastic_Config_LoRaConfig_ModemPreset;
|
} meshtastic_Config_LoRaConfig_ModemPreset;
|
||||||
|
|
||||||
typedef enum _meshtastic_Config_BluetoothConfig_PairingMode {
|
typedef enum _meshtastic_Config_BluetoothConfig_PairingMode {
|
||||||
/* Device generates a random pin that will be shown on the screen of the device for pairing */
|
/* Device generates a random PIN that will be shown on the screen of the device for pairing */
|
||||||
meshtastic_Config_BluetoothConfig_PairingMode_RANDOM_PIN = 0,
|
meshtastic_Config_BluetoothConfig_PairingMode_RANDOM_PIN = 0,
|
||||||
/* Device requires a specified fixed pin for pairing */
|
/* Device requires a specified fixed PIN for pairing */
|
||||||
meshtastic_Config_BluetoothConfig_PairingMode_FIXED_PIN = 1,
|
meshtastic_Config_BluetoothConfig_PairingMode_FIXED_PIN = 1,
|
||||||
/* Device requires no pin for pairing */
|
/* Device requires no PIN for pairing */
|
||||||
meshtastic_Config_BluetoothConfig_PairingMode_NO_PIN = 2
|
meshtastic_Config_BluetoothConfig_PairingMode_NO_PIN = 2
|
||||||
} meshtastic_Config_BluetoothConfig_PairingMode;
|
} meshtastic_Config_BluetoothConfig_PairingMode;
|
||||||
|
|
||||||
@ -364,7 +364,7 @@ typedef struct _meshtastic_Config_DisplayConfig {
|
|||||||
|
|
||||||
/* Lora Config */
|
/* Lora Config */
|
||||||
typedef struct _meshtastic_Config_LoRaConfig {
|
typedef struct _meshtastic_Config_LoRaConfig {
|
||||||
/* When enabled, the `modem_preset` fields will be adheared to, else the `bandwidth`/`spread_factor`/`coding_rate`
|
/* When enabled, the `modem_preset` fields will be adhered to, else the `bandwidth`/`spread_factor`/`coding_rate`
|
||||||
will be taked from their respective manually defined fields */
|
will be taked from their respective manually defined fields */
|
||||||
bool use_preset;
|
bool use_preset;
|
||||||
/* Either modem_config or bandwidth/spreading/coding will be specified - NOT BOTH.
|
/* Either modem_config or bandwidth/spreading/coding will be specified - NOT BOTH.
|
||||||
@ -395,12 +395,12 @@ typedef struct _meshtastic_Config_LoRaConfig {
|
|||||||
/* Disable TX from the LoRa radio. Useful for hot-swapping antennas and other tests.
|
/* Disable TX from the LoRa radio. Useful for hot-swapping antennas and other tests.
|
||||||
Defaults to false */
|
Defaults to false */
|
||||||
bool tx_enabled;
|
bool tx_enabled;
|
||||||
/* If zero then, use default max legal continuous power (ie. something that won't
|
/* If zero, then use default max legal continuous power (ie. something that won't
|
||||||
burn out the radio hardware)
|
burn out the radio hardware)
|
||||||
In most cases you should use zero here.
|
In most cases you should use zero here.
|
||||||
Units are in dBm. */
|
Units are in dBm. */
|
||||||
int8_t tx_power;
|
int8_t tx_power;
|
||||||
/* This is controlling the actual hardware frequency the radio is transmitting on.
|
/* This controls the actual hardware frequency the radio transmits on.
|
||||||
Most users should never need to be exposed to this field/concept.
|
Most users should never need to be exposed to this field/concept.
|
||||||
A channel number between 1 and NUM_CHANNELS (whatever the max is in the current region).
|
A channel number between 1 and NUM_CHANNELS (whatever the max is in the current region).
|
||||||
If ZERO then the rule is "use the old channel name hash based
|
If ZERO then the rule is "use the old channel name hash based
|
||||||
@ -422,7 +422,7 @@ typedef struct _meshtastic_Config_LoRaConfig {
|
|||||||
float override_frequency;
|
float override_frequency;
|
||||||
/* For testing it is useful sometimes to force a node to never listen to
|
/* For testing it is useful sometimes to force a node to never listen to
|
||||||
particular other nodes (simulating radio out of range). All nodenums listed
|
particular other nodes (simulating radio out of range). All nodenums listed
|
||||||
in ignore_incoming will have packets they send droped on receive (by router.cpp) */
|
in ignore_incoming will have packets they send dropped on receive (by router.cpp) */
|
||||||
pb_size_t ignore_incoming_count;
|
pb_size_t ignore_incoming_count;
|
||||||
uint32_t ignore_incoming[3];
|
uint32_t ignore_incoming[3];
|
||||||
} meshtastic_Config_LoRaConfig;
|
} meshtastic_Config_LoRaConfig;
|
||||||
@ -432,7 +432,7 @@ typedef struct _meshtastic_Config_BluetoothConfig {
|
|||||||
bool enabled;
|
bool enabled;
|
||||||
/* Determines the pairing strategy for the device */
|
/* Determines the pairing strategy for the device */
|
||||||
meshtastic_Config_BluetoothConfig_PairingMode mode;
|
meshtastic_Config_BluetoothConfig_PairingMode mode;
|
||||||
/* Specified pin for PairingMode.FixedPin */
|
/* Specified PIN for PairingMode.FixedPin */
|
||||||
uint32_t fixed_pin;
|
uint32_t fixed_pin;
|
||||||
} meshtastic_Config_BluetoothConfig;
|
} meshtastic_Config_BluetoothConfig;
|
||||||
|
|
||||||
|
@ -27,9 +27,9 @@ typedef struct _meshtastic_WifiConnectionStatus {
|
|||||||
/* Connection status */
|
/* Connection status */
|
||||||
bool has_status;
|
bool has_status;
|
||||||
meshtastic_NetworkConnectionStatus status;
|
meshtastic_NetworkConnectionStatus status;
|
||||||
/* WiFi access point ssid */
|
/* WiFi access point SSID */
|
||||||
char ssid[33];
|
char ssid[33];
|
||||||
/* Rssi of wireless connection */
|
/* RSSI of wireless connection */
|
||||||
int32_t rssi;
|
int32_t rssi;
|
||||||
} meshtastic_WifiConnectionStatus;
|
} meshtastic_WifiConnectionStatus;
|
||||||
|
|
||||||
@ -42,9 +42,9 @@ typedef struct _meshtastic_EthernetConnectionStatus {
|
|||||||
|
|
||||||
/* Bluetooth connection status */
|
/* Bluetooth connection status */
|
||||||
typedef struct _meshtastic_BluetoothConnectionStatus {
|
typedef struct _meshtastic_BluetoothConnectionStatus {
|
||||||
/* The pairing pin for bluetooth */
|
/* The pairing PIN for bluetooth */
|
||||||
uint32_t pin;
|
uint32_t pin;
|
||||||
/* Rssi of bluetooth connection */
|
/* RSSI of bluetooth connection */
|
||||||
int32_t rssi;
|
int32_t rssi;
|
||||||
/* Whether the device has an active connection or not */
|
/* Whether the device has an active connection or not */
|
||||||
bool is_connected;
|
bool is_connected;
|
||||||
@ -52,7 +52,7 @@ typedef struct _meshtastic_BluetoothConnectionStatus {
|
|||||||
|
|
||||||
/* Serial connection status */
|
/* Serial connection status */
|
||||||
typedef struct _meshtastic_SerialConnectionStatus {
|
typedef struct _meshtastic_SerialConnectionStatus {
|
||||||
/* The serial baud rate */
|
/* Serial baud rate */
|
||||||
uint32_t baud;
|
uint32_t baud;
|
||||||
/* Whether the device has an active connection or not */
|
/* Whether the device has an active connection or not */
|
||||||
bool is_connected;
|
bool is_connected;
|
||||||
|
@ -54,7 +54,7 @@ typedef struct _meshtastic_DeviceState {
|
|||||||
/* Used only during development.
|
/* Used only during development.
|
||||||
Indicates developer is testing and changes should never be saved to flash. */
|
Indicates developer is testing and changes should never be saved to flash. */
|
||||||
bool no_save;
|
bool no_save;
|
||||||
/* Some GPSes seem to have bogus settings from the factory, so we always do one factory reset. */
|
/* Some GPS receivers seem to have bogus settings from the factory, so we always do one factory reset. */
|
||||||
bool did_gps_reset;
|
bool did_gps_reset;
|
||||||
} meshtastic_DeviceState;
|
} meshtastic_DeviceState;
|
||||||
|
|
||||||
@ -72,13 +72,13 @@ typedef struct _meshtastic_ChannelFile {
|
|||||||
typedef PB_BYTES_ARRAY_T(2048) meshtastic_OEMStore_oem_icon_bits_t;
|
typedef PB_BYTES_ARRAY_T(2048) meshtastic_OEMStore_oem_icon_bits_t;
|
||||||
typedef PB_BYTES_ARRAY_T(32) meshtastic_OEMStore_oem_aes_key_t;
|
typedef PB_BYTES_ARRAY_T(32) meshtastic_OEMStore_oem_aes_key_t;
|
||||||
/* This can be used for customizing the firmware distribution. If populated,
|
/* This can be used for customizing the firmware distribution. If populated,
|
||||||
show a secondary bootup screen with cuatom logo and text for 2.5 seconds. */
|
show a secondary bootup screen with custom logo and text for 2.5 seconds. */
|
||||||
typedef struct _meshtastic_OEMStore {
|
typedef struct _meshtastic_OEMStore {
|
||||||
/* The Logo width in Px */
|
/* The Logo width in Px */
|
||||||
uint32_t oem_icon_width;
|
uint32_t oem_icon_width;
|
||||||
/* The Logo height in Px */
|
/* The Logo height in Px */
|
||||||
uint32_t oem_icon_height;
|
uint32_t oem_icon_height;
|
||||||
/* The Logo in xbm bytechar format */
|
/* The Logo in XBM bytechar format */
|
||||||
meshtastic_OEMStore_oem_icon_bits_t oem_icon_bits;
|
meshtastic_OEMStore_oem_icon_bits_t oem_icon_bits;
|
||||||
/* Use this font for the OEM text. */
|
/* Use this font for the OEM text. */
|
||||||
meshtastic_ScreenFonts oem_font;
|
meshtastic_ScreenFonts oem_font;
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
#include "mqtt/MQTT.h"
|
#include "mqtt/MQTT.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define DEFAULT_REBOOT_SECONDS 5
|
#define DEFAULT_REBOOT_SECONDS 7
|
||||||
|
|
||||||
AdminModule *adminModule;
|
AdminModule *adminModule;
|
||||||
bool hasOpenEditTransaction;
|
bool hasOpenEditTransaction;
|
||||||
|
@ -5,12 +5,19 @@
|
|||||||
#include "MeshService.h"
|
#include "MeshService.h"
|
||||||
#include "NodeDB.h"
|
#include "NodeDB.h"
|
||||||
#include "PowerFSM.h" // neede for button bypass
|
#include "PowerFSM.h" // neede for button bypass
|
||||||
|
#include "detect/ScanI2C.h"
|
||||||
#include "mesh/generated/meshtastic/cannedmessages.pb.h"
|
#include "mesh/generated/meshtastic/cannedmessages.pb.h"
|
||||||
|
|
||||||
|
#include "main.h" // for cardkb_found
|
||||||
|
|
||||||
#ifdef OLED_RU
|
#ifdef OLED_RU
|
||||||
#include "graphics/fonts/OLEDDisplayFontsRU.h"
|
#include "graphics/fonts/OLEDDisplayFontsRU.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef OLED_UA
|
||||||
|
#include "graphics/fonts/OLEDDisplayFontsUA.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7735_CS)
|
#if defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ST7735_CS)
|
||||||
// The screen is bigger so use bigger fonts
|
// The screen is bigger so use bigger fonts
|
||||||
#define FONT_SMALL ArialMT_Plain_16
|
#define FONT_SMALL ArialMT_Plain_16
|
||||||
@ -20,8 +27,12 @@
|
|||||||
#ifdef OLED_RU
|
#ifdef OLED_RU
|
||||||
#define FONT_SMALL ArialMT_Plain_10_RU
|
#define FONT_SMALL ArialMT_Plain_10_RU
|
||||||
#else
|
#else
|
||||||
|
#ifdef OLED_UA
|
||||||
|
#define FONT_SMALL ArialMT_Plain_10_UA
|
||||||
|
#else
|
||||||
#define FONT_SMALL ArialMT_Plain_10
|
#define FONT_SMALL ArialMT_Plain_10
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
#define FONT_MEDIUM ArialMT_Plain_16
|
#define FONT_MEDIUM ArialMT_Plain_16
|
||||||
#define FONT_LARGE ArialMT_Plain_24
|
#define FONT_LARGE ArialMT_Plain_24
|
||||||
#endif
|
#endif
|
||||||
@ -35,7 +46,7 @@
|
|||||||
// Remove Canned message screen if no action is taken for some milliseconds
|
// Remove Canned message screen if no action is taken for some milliseconds
|
||||||
#define INACTIVATE_AFTER_MS 20000
|
#define INACTIVATE_AFTER_MS 20000
|
||||||
|
|
||||||
extern uint8_t cardkb_found;
|
extern ScanI2C::DeviceAddress cardkb_found;
|
||||||
|
|
||||||
static const char *cannedMessagesConfigFile = "/prefs/cannedConf.proto";
|
static const char *cannedMessagesConfigFile = "/prefs/cannedConf.proto";
|
||||||
|
|
||||||
@ -48,7 +59,7 @@ CannedMessageModule::CannedMessageModule()
|
|||||||
{
|
{
|
||||||
if (moduleConfig.canned_message.enabled) {
|
if (moduleConfig.canned_message.enabled) {
|
||||||
this->loadProtoForModule();
|
this->loadProtoForModule();
|
||||||
if ((this->splitConfiguredMessages() <= 0) && (cardkb_found != CARDKB_ADDR)) {
|
if ((this->splitConfiguredMessages() <= 0) && (cardkb_found.address != CARDKB_ADDR)) {
|
||||||
LOG_INFO("CannedMessageModule: No messages are configured. Module is disabled\n");
|
LOG_INFO("CannedMessageModule: No messages are configured. Module is disabled\n");
|
||||||
this->runState = CANNED_MESSAGE_RUN_STATE_DISABLED;
|
this->runState = CANNED_MESSAGE_RUN_STATE_DISABLED;
|
||||||
disable();
|
disable();
|
||||||
|
@ -12,6 +12,10 @@
|
|||||||
#include "graphics/fonts/OLEDDisplayFontsRU.h"
|
#include "graphics/fonts/OLEDDisplayFontsRU.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef OLED_UA
|
||||||
|
#include "graphics/fonts/OLEDDisplayFontsUA.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
AudioModule
|
AudioModule
|
||||||
A interface to send raw codec2 audio data over the mesh network. Based on the example code from the ESP32_codec2 project.
|
A interface to send raw codec2 audio data over the mesh network. Based on the example code from the ESP32_codec2 project.
|
||||||
@ -53,8 +57,12 @@ AudioModule *audioModule;
|
|||||||
#ifdef OLED_RU
|
#ifdef OLED_RU
|
||||||
#define FONT_SMALL ArialMT_Plain_10_RU
|
#define FONT_SMALL ArialMT_Plain_10_RU
|
||||||
#else
|
#else
|
||||||
|
#ifdef OLED_UA
|
||||||
|
#define FONT_SMALL ArialMT_Plain_10_UA
|
||||||
|
#else
|
||||||
#define FONT_SMALL ArialMT_Plain_10
|
#define FONT_SMALL ArialMT_Plain_10
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
#define FONT_MEDIUM ArialMT_Plain_16
|
#define FONT_MEDIUM ArialMT_Plain_16
|
||||||
#define FONT_LARGE ArialMT_Plain_24
|
#define FONT_LARGE ArialMT_Plain_24
|
||||||
#endif
|
#endif
|
||||||
|
@ -30,12 +30,14 @@ class MQTT : private concurrency::OSThread
|
|||||||
#if HAS_ETHERNET
|
#if HAS_ETHERNET
|
||||||
EthernetClient mqttClient;
|
EthernetClient mqttClient;
|
||||||
#endif
|
#endif
|
||||||
|
#if !defined(DEBUG_HEAP_MQTT)
|
||||||
PubSubClient pubSub;
|
PubSubClient pubSub;
|
||||||
|
|
||||||
// instead we supress sleep from our runOnce() callback
|
|
||||||
// CallbackObserver<MQTT, void *> preflightSleepObserver = CallbackObserver<MQTT, void *>(this, &MQTT::preflightSleepCb);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
#else
|
||||||
|
public:
|
||||||
|
PubSubClient pubSub;
|
||||||
|
#endif
|
||||||
MQTT();
|
MQTT();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,9 +1,6 @@
|
|||||||
[env:heltec-v3]
|
[env:heltec-v3]
|
||||||
platform = https://github.com/Baptou88/platform-espressif32.git
|
|
||||||
extends = esp32s3_base
|
extends = esp32s3_base
|
||||||
board = heltec_wifi_lora_32_V3
|
board = heltec_wifi_lora_32_V3
|
||||||
# Temporary until espressif creates a release with this new target
|
# Temporary until espressif creates a release with this new target
|
||||||
platform_packages =
|
|
||||||
framework-arduinoespressif32@https://github.com/espressif/arduino-esp32.git
|
|
||||||
build_flags =
|
build_flags =
|
||||||
${esp32s3_base.build_flags} -D HELTEC_V3 -I variants/heltec_v3
|
${esp32s3_base.build_flags} -D HELTEC_V3 -I variants/heltec_v3
|
||||||
|
@ -1,9 +1,6 @@
|
|||||||
[env:heltec-wsl-v3]
|
[env:heltec-wsl-v3]
|
||||||
platform = https://github.com/Baptou88/platform-espressif32.git
|
|
||||||
extends = esp32s3_base
|
extends = esp32s3_base
|
||||||
board = heltec_wifi_lora_32_V3
|
board = heltec_wifi_lora_32_V3
|
||||||
# Temporary until espressif creates a release with this new target
|
# Temporary until espressif creates a release with this new target
|
||||||
platform_packages =
|
|
||||||
framework-arduinoespressif32@https://github.com/espressif/arduino-esp32.git
|
|
||||||
build_flags =
|
build_flags =
|
||||||
${esp32s3_base.build_flags} -D HELTEC_WSL_V3 -I variants/heltec_wsl_v3
|
${esp32s3_base.build_flags} -D HELTEC_WSL_V3 -I variants/heltec_wsl_v3
|
||||||
|
@ -33,5 +33,4 @@
|
|||||||
#define BATTERY_SENSE_SAMPLES 15 // Set the number of samples, It has an effect of increasing sensitivity.
|
#define BATTERY_SENSE_SAMPLES 15 // Set the number of samples, It has an effect of increasing sensitivity.
|
||||||
#define ADC_MULTIPLIER 2
|
#define ADC_MULTIPLIER 2
|
||||||
|
|
||||||
//#define USE_SH1107 // Finally we will use SH1107 128x64 resolution driver, because SH1106 will shift the screen by 2 lines.
|
#define USE_SH1107_128_64
|
||||||
#define USE_SH1106
|
|
||||||
|
@ -13,6 +13,9 @@
|
|||||||
#define I2C_SDA 18 // I2C pins for this board
|
#define I2C_SDA 18 // I2C pins for this board
|
||||||
#define I2C_SCL 17
|
#define I2C_SCL 17
|
||||||
|
|
||||||
|
#define I2C_SDA1 43
|
||||||
|
#define I2C_SCL1 44
|
||||||
|
|
||||||
#define LED_PIN 37 // If defined we will blink this LED
|
#define LED_PIN 37 // If defined we will blink this LED
|
||||||
#define BUTTON_PIN 0 // If defined, this will be used for user button presses,
|
#define BUTTON_PIN 0 // If defined, this will be used for user button presses,
|
||||||
|
|
||||||
@ -28,26 +31,30 @@
|
|||||||
#define RF95_MISO 3
|
#define RF95_MISO 3
|
||||||
#define RF95_MOSI 6
|
#define RF95_MOSI 6
|
||||||
#define RF95_NSS 7
|
#define RF95_NSS 7
|
||||||
|
|
||||||
#define LORA_RESET 8
|
#define LORA_RESET 8
|
||||||
#define LORA_DIO0 9
|
|
||||||
#define LORA_DIO1 9
|
|
||||||
#define LORA_DIO2 33 // SX1262 BUSY
|
|
||||||
#define LORA_DIO3 34 // Not connected on PCB, but internally on the TTGO SX1262, if DIO3 is high the TXCO is enabled
|
|
||||||
|
|
||||||
|
// per SX1276_Receive_Interrupt/utilities.h
|
||||||
|
#define LORA_DIO0 9
|
||||||
|
#define LORA_DIO1 33 // TCXO_EN ?
|
||||||
|
#define LORA_DIO2 34
|
||||||
|
#define LORA_RXEN 21
|
||||||
|
#define LORA_TXEN 10
|
||||||
|
|
||||||
|
// per SX1262_Receive_Interrupt/utilities.h
|
||||||
#ifdef USE_SX1262
|
#ifdef USE_SX1262
|
||||||
#define SX126X_CS RF95_NSS // FIXME - we really should define LORA_CS instead
|
#define SX126X_CS RF95_NSS
|
||||||
#define SX126X_DIO1 33
|
#define SX126X_DIO1 33
|
||||||
#define SX126X_BUSY 34
|
#define SX126X_BUSY 34
|
||||||
#define SX126X_RESET LORA_RESET
|
#define SX126X_RESET LORA_RESET
|
||||||
//#define SX126X_RXEN 21
|
|
||||||
//#define SX126X_TXEN 10
|
|
||||||
#define SX126X_E22
|
#define SX126X_E22
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// per SX128x_Receive_Interrupt/utilities.h
|
||||||
#ifdef USE_SX1280
|
#ifdef USE_SX1280
|
||||||
#define SX128X_CS RF95_NSS
|
#define SX128X_CS RF95_NSS
|
||||||
#define SX128X_DIO1 LORA_DIO1
|
#define SX128X_DIO1 9
|
||||||
|
#define SX128X_DIO2 33
|
||||||
|
#define SX128X_DIO3 34
|
||||||
#define SX128X_BUSY 36
|
#define SX128X_BUSY 36
|
||||||
#define SX128X_RESET LORA_RESET
|
#define SX128X_RESET LORA_RESET
|
||||||
#define SX128X_RXEN 21
|
#define SX128X_RXEN 21
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
[VERSION]
|
[VERSION]
|
||||||
major = 2
|
major = 2
|
||||||
minor = 0
|
minor = 1
|
||||||
build = 24
|
build = 1
|
||||||
|
Loading…
Reference in New Issue
Block a user