mirror of
https://github.com/meshtastic/firmware.git
synced 2025-04-25 17:42:48 +00:00
Merge branch 'master' into 2.6
This commit is contained in:
commit
ac9cb235a8
52
boards/meshlink.json
Normal file
52
boards/meshlink.json
Normal file
@ -0,0 +1,52 @@
|
||||
{
|
||||
"build": {
|
||||
"arduino": {
|
||||
"ldscript": "nrf52840_s140_v6.ld"
|
||||
},
|
||||
"core": "nRF5",
|
||||
"cpu": "cortex-m4",
|
||||
"extra_flags": "-DMESHLINK -DNRF52840_XXAA",
|
||||
"f_cpu": "64000000L",
|
||||
"hwids": [
|
||||
["0x239A", "0x00B3"],
|
||||
["0x239A", "0x8029"],
|
||||
["0x239A", "0x0029"],
|
||||
["0x239A", "0x002A"],
|
||||
["0x239A", "0x802A"]
|
||||
],
|
||||
"usb_product": "MeshLink",
|
||||
"mcu": "nrf52840",
|
||||
"variant": "meshlink",
|
||||
"bsp": {
|
||||
"name": "adafruit"
|
||||
},
|
||||
"softdevice": {
|
||||
"sd_flags": "-DS140",
|
||||
"sd_name": "s140",
|
||||
"sd_version": "6.1.1",
|
||||
"sd_fwid": "0x00B6"
|
||||
},
|
||||
"bootloader": {
|
||||
"settings_addr": "0xFF000"
|
||||
}
|
||||
},
|
||||
"connectivity": ["bluetooth"],
|
||||
"debug": {
|
||||
"jlink_device": "nRF52840_xxAA",
|
||||
"svd_path": "nrf52840.svd"
|
||||
},
|
||||
"frameworks": ["arduino"],
|
||||
"name": "MeshLink",
|
||||
"upload": {
|
||||
"maximum_ram_size": 248832,
|
||||
"maximum_size": 815104,
|
||||
"speed": 115200,
|
||||
"protocol": "nrfutil",
|
||||
"protocols": ["nrfutil", "jlink", "nrfjprog", "stlink"],
|
||||
"use_1200bps_touch": true,
|
||||
"require_upload_port": true,
|
||||
"wait_for_upload_port": true
|
||||
},
|
||||
"url": "https://www.loraitalia.it",
|
||||
"vendor": "LoraItalia"
|
||||
}
|
@ -140,6 +140,15 @@ bool EInkDisplay::connect()
|
||||
adafruitDisplay->setRotation(3);
|
||||
adafruitDisplay->setPartialWindow(0, 0, displayWidth, displayHeight);
|
||||
}
|
||||
#elif defined(MESHLINK)
|
||||
{
|
||||
auto lowLevel = new EINK_DISPLAY_MODEL(PIN_EINK_CS, PIN_EINK_DC, PIN_EINK_RES, PIN_EINK_BUSY, SPI1);
|
||||
|
||||
adafruitDisplay = new GxEPD2_BW<EINK_DISPLAY_MODEL, EINK_DISPLAY_MODEL::HEIGHT>(*lowLevel);
|
||||
adafruitDisplay->init();
|
||||
adafruitDisplay->setRotation(3);
|
||||
adafruitDisplay->setPartialWindow(0, 0, displayWidth, displayHeight);
|
||||
}
|
||||
#elif defined(RAK4630) || defined(MAKERPYTHON)
|
||||
{
|
||||
if (eink_found) {
|
||||
|
@ -1775,4 +1775,4 @@ extern const pb_msgdesc_t meshtastic_ChunkedPayloadResponse_msg;
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif
|
@ -162,7 +162,9 @@ bool AdminModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshta
|
||||
|
||||
case meshtastic_AdminMessage_set_module_config_tag:
|
||||
LOG_INFO("Client set module config");
|
||||
handleSetModuleConfig(r->set_module_config);
|
||||
if (!handleSetModuleConfig(r->set_module_config)) {
|
||||
myReply = allocErrorResponse(meshtastic_Routing_Error_BAD_REQUEST, &mp);
|
||||
}
|
||||
break;
|
||||
|
||||
case meshtastic_AdminMessage_set_channel_tag:
|
||||
@ -651,15 +653,23 @@ void AdminModule::handleSetConfig(const meshtastic_Config &c)
|
||||
saveChanges(changes, requiresReboot);
|
||||
}
|
||||
|
||||
void AdminModule::handleSetModuleConfig(const meshtastic_ModuleConfig &c)
|
||||
bool AdminModule::handleSetModuleConfig(const meshtastic_ModuleConfig &c)
|
||||
{
|
||||
if (!hasOpenEditTransaction)
|
||||
disableBluetooth();
|
||||
switch (c.which_payload_variant) {
|
||||
case meshtastic_ModuleConfig_mqtt_tag:
|
||||
#if MESHTASTIC_EXCLUDE_MQTT
|
||||
LOG_WARN("Set module config: MESHTASTIC_EXCLUDE_MQTT is defined. Not setting MQTT config");
|
||||
return false;
|
||||
#else
|
||||
LOG_INFO("Set module config: MQTT");
|
||||
if (!MQTT::isValidConfig(c.payload_variant.mqtt)) {
|
||||
return false;
|
||||
}
|
||||
moduleConfig.has_mqtt = true;
|
||||
moduleConfig.mqtt = c.payload_variant.mqtt;
|
||||
#endif
|
||||
break;
|
||||
case meshtastic_ModuleConfig_serial_tag:
|
||||
LOG_INFO("Set module config: Serial");
|
||||
@ -727,6 +737,7 @@ void AdminModule::handleSetModuleConfig(const meshtastic_ModuleConfig &c)
|
||||
break;
|
||||
}
|
||||
saveChanges(SEGMENT_MODULECONFIG);
|
||||
return true;
|
||||
}
|
||||
|
||||
void AdminModule::handleSetChannel(const meshtastic_Channel &cc)
|
||||
|
@ -50,7 +50,7 @@ class AdminModule : public ProtobufModule<meshtastic_AdminMessage>, public Obser
|
||||
void handleSetOwner(const meshtastic_User &o);
|
||||
void handleSetChannel(const meshtastic_Channel &cc);
|
||||
void handleSetConfig(const meshtastic_Config &c);
|
||||
void handleSetModuleConfig(const meshtastic_ModuleConfig &c);
|
||||
bool handleSetModuleConfig(const meshtastic_ModuleConfig &c);
|
||||
void handleSetChannel();
|
||||
void handleSetHamMode(const meshtastic_HamParameters &req);
|
||||
void handleStoreDeviceUIConfig(const meshtastic_DeviceUIConfig &uicfg);
|
||||
|
@ -60,7 +60,7 @@
|
||||
SerialModule *serialModule;
|
||||
SerialModuleRadio *serialModuleRadio;
|
||||
|
||||
#if defined(TTGO_T_ECHO) || defined(CANARYONE)
|
||||
#if defined(TTGO_T_ECHO) || defined(CANARYONE) || defined(MESHLINK)
|
||||
SerialModule::SerialModule() : StreamAPI(&Serial), concurrency::OSThread("Serial") {}
|
||||
static Print *serialPrint = &Serial;
|
||||
#elif defined(CONFIG_IDF_TARGET_ESP32C6)
|
||||
@ -158,7 +158,7 @@ int32_t SerialModule::runOnce()
|
||||
Serial.begin(baud);
|
||||
Serial.setTimeout(moduleConfig.serial.timeout > 0 ? moduleConfig.serial.timeout : TIMEOUT);
|
||||
}
|
||||
#elif !defined(TTGO_T_ECHO) && !defined(CANARYONE)
|
||||
#elif !defined(TTGO_T_ECHO) && !defined(CANARYONE) && !defined(MESHLINK)
|
||||
if (moduleConfig.serial.rxd && moduleConfig.serial.txd) {
|
||||
#ifdef ARCH_RP2040
|
||||
Serial2.setFIFOSize(RX_BUFFER);
|
||||
@ -214,7 +214,7 @@ int32_t SerialModule::runOnce()
|
||||
}
|
||||
}
|
||||
|
||||
#if !defined(TTGO_T_ECHO) && !defined(CANARYONE)
|
||||
#if !defined(TTGO_T_ECHO) && !defined(CANARYONE) && !defined(MESHLINK)
|
||||
else if ((moduleConfig.serial.mode == meshtastic_ModuleConfig_SerialConfig_Serial_Mode_WS85)) {
|
||||
processWXSerial();
|
||||
|
||||
@ -416,7 +416,7 @@ uint32_t SerialModule::getBaudRate()
|
||||
*/
|
||||
void SerialModule::processWXSerial()
|
||||
{
|
||||
#if !defined(TTGO_T_ECHO) && !defined(CANARYONE) && !defined(CONFIG_IDF_TARGET_ESP32C6)
|
||||
#if !defined(TTGO_T_ECHO) && !defined(CANARYONE) && !defined(CONFIG_IDF_TARGET_ESP32C6) && !defined(MESHLINK)
|
||||
static unsigned int lastAveraged = 0;
|
||||
static unsigned int averageIntervalMillis = 300000; // 5 minutes hard coded.
|
||||
static double dir_sum_sin = 0;
|
||||
|
@ -41,6 +41,7 @@ MQTT *mqtt;
|
||||
namespace
|
||||
{
|
||||
constexpr int reconnectMax = 5;
|
||||
constexpr uint16_t mqttPort = 1883;
|
||||
|
||||
// FIXME - this size calculation is super sloppy, but it will go away once we dynamically alloc meshpackets
|
||||
static uint8_t bytes[meshtastic_MqttClientProxyMessage_size + 30]; // 12 for channel name and 16 for nodeid
|
||||
@ -245,6 +246,11 @@ std::pair<String, uint16_t> parseHostAndPort(String server, uint16_t port = 0)
|
||||
}
|
||||
return std::make_pair(std::move(server), port);
|
||||
}
|
||||
|
||||
bool isDefaultServer(const String &host)
|
||||
{
|
||||
return host.length() == 0 || host == default_mqtt_address;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
void MQTT::mqttCallback(char *topic, byte *payload, unsigned int length)
|
||||
@ -324,7 +330,7 @@ MQTT::MQTT() : concurrency::OSThread("mqtt"), mqttQueue(MAX_MQTT_QUEUE)
|
||||
}
|
||||
|
||||
String host = parseHostAndPort(moduleConfig.mqtt.address).first;
|
||||
isConfiguredForDefaultServer = host.length() == 0 || host == default_mqtt_address;
|
||||
isConfiguredForDefaultServer = isDefaultServer(host);
|
||||
IPAddress ip;
|
||||
isMqttServerAddressPrivate = ip.fromString(host.c_str()) && isPrivateIpAddress(ip);
|
||||
|
||||
@ -408,7 +414,7 @@ void MQTT::reconnect()
|
||||
}
|
||||
#if HAS_NETWORKING
|
||||
// Defaults
|
||||
int serverPort = 1883;
|
||||
int serverPort = mqttPort;
|
||||
const char *serverAddr = default_mqtt_address;
|
||||
const char *mqttUsername = default_mqtt_username;
|
||||
const char *mqttPassword = default_mqtt_password;
|
||||
@ -561,6 +567,23 @@ int32_t MQTT::runOnce()
|
||||
return 30000;
|
||||
}
|
||||
|
||||
bool MQTT::isValidConfig(const meshtastic_ModuleConfig_MQTTConfig &config)
|
||||
{
|
||||
String host;
|
||||
uint16_t port;
|
||||
std::tie(host, port) = parseHostAndPort(config.address, mqttPort);
|
||||
const bool defaultServer = isDefaultServer(host);
|
||||
if (defaultServer && config.tls_enabled) {
|
||||
LOG_ERROR("Invalid MQTT config: TLS was enabled, but the default server does not support TLS");
|
||||
return false;
|
||||
}
|
||||
if (defaultServer && port != mqttPort) {
|
||||
LOG_ERROR("Invalid MQTT config: Unsupported port '%d' for the default MQTT server", port);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void MQTT::publishNodeInfo()
|
||||
{
|
||||
// TODO: NodeInfo broadcast over MQTT only (NODENUM_BROADCAST_NO_LORA)
|
||||
|
@ -61,6 +61,8 @@ class MQTT : private concurrency::OSThread
|
||||
|
||||
bool isUsingDefaultServer() { return isConfiguredForDefaultServer; }
|
||||
|
||||
static bool isValidConfig(const meshtastic_ModuleConfig_MQTTConfig &config);
|
||||
|
||||
protected:
|
||||
struct QueueEntry {
|
||||
std::string topic;
|
||||
|
@ -127,4 +127,4 @@
|
||||
#if !defined(PIN_SERIAL_RX) && !defined(NRF52840_XXAA)
|
||||
// No serial ports on this board - ONLY use segger in memory console
|
||||
#define USE_SEGGER
|
||||
#endif
|
||||
#endif
|
@ -304,6 +304,11 @@ void cpuDeepSleep(uint32_t msecToWake)
|
||||
nrf_gpio_cfg_default(WB_I2C1_SDA);
|
||||
#endif
|
||||
#endif
|
||||
#ifdef MESHLINK
|
||||
#ifdef PIN_WD_EN
|
||||
digitalWrite(PIN_WD_EN, LOW);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef HELTEC_MESH_NODE_T114
|
||||
nrf_gpio_cfg_default(PIN_GPS_PPS);
|
||||
|
@ -249,6 +249,9 @@ void doDeepSleep(uint32_t msecToWake, bool skipPreflight = false, bool skipSaveN
|
||||
#ifdef PIN_3V3_EN
|
||||
digitalWrite(PIN_3V3_EN, LOW);
|
||||
#endif
|
||||
#ifdef PIN_WD_EN
|
||||
digitalWrite(PIN_WD_EN, LOW);
|
||||
#endif
|
||||
#endif
|
||||
ledBlink.set(false);
|
||||
|
||||
@ -533,4 +536,4 @@ void enableLoraInterrupt()
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
#endif
|
@ -800,6 +800,38 @@ void test_customMqttRoot(void)
|
||||
[] { return pubsub->subscriptions_.count("custom/2/e/test/+") && pubsub->subscriptions_.count("custom/2/e/PKI/+"); }));
|
||||
}
|
||||
|
||||
// Empty configuration is valid.
|
||||
void test_configurationEmptyIsValid(void)
|
||||
{
|
||||
meshtastic_ModuleConfig_MQTTConfig config;
|
||||
|
||||
TEST_ASSERT_TRUE(MQTT::isValidConfig(config));
|
||||
}
|
||||
|
||||
// Configuration with the default server is valid.
|
||||
void test_configWithDefaultServer(void)
|
||||
{
|
||||
meshtastic_ModuleConfig_MQTTConfig config = {.address = default_mqtt_address};
|
||||
|
||||
TEST_ASSERT_TRUE(MQTT::isValidConfig(config));
|
||||
}
|
||||
|
||||
// Configuration with the default server and port 8888 is invalid.
|
||||
void test_configWithDefaultServerAndInvalidPort(void)
|
||||
{
|
||||
meshtastic_ModuleConfig_MQTTConfig config = {.address = default_mqtt_address ":8888"};
|
||||
|
||||
TEST_ASSERT_FALSE(MQTT::isValidConfig(config));
|
||||
}
|
||||
|
||||
// Configuration with the default server and tls_enabled = true is invalid.
|
||||
void test_configWithDefaultServerAndInvalidTLSEnabled(void)
|
||||
{
|
||||
meshtastic_ModuleConfig_MQTTConfig config = {.tls_enabled = true};
|
||||
|
||||
TEST_ASSERT_FALSE(MQTT::isValidConfig(config));
|
||||
}
|
||||
|
||||
void setup()
|
||||
{
|
||||
initializeTestEnvironment();
|
||||
@ -843,6 +875,10 @@ void setup()
|
||||
RUN_TEST(test_enabled);
|
||||
RUN_TEST(test_disabled);
|
||||
RUN_TEST(test_customMqttRoot);
|
||||
RUN_TEST(test_configurationEmptyIsValid);
|
||||
RUN_TEST(test_configWithDefaultServer);
|
||||
RUN_TEST(test_configWithDefaultServerAndInvalidPort);
|
||||
RUN_TEST(test_configWithDefaultServerAndInvalidTLSEnabled);
|
||||
exit(UNITY_END());
|
||||
}
|
||||
#else
|
||||
|
@ -84,17 +84,15 @@ static const uint8_t A5 = PIN_A5;
|
||||
#define PIN_NFC2 (31)
|
||||
|
||||
// RX and TX pins
|
||||
#define PIN_SERIAL1_RX (6)
|
||||
#define PIN_SERIAL1_TX (7)
|
||||
#define PIN_SERIAL1_RX (-1)
|
||||
#define PIN_SERIAL1_TX (-1)
|
||||
// complains if not defined
|
||||
#define PIN_SERIAL2_RX (-1)
|
||||
#define PIN_SERIAL2_TX (-1)
|
||||
|
||||
// 4 is used as RF_SW and 5 for USR button so...
|
||||
#define PIN_WIRE_SDA (-1)
|
||||
#define PIN_WIRE_SCL (-1)
|
||||
// #define PIN_WIRE_SDA (6)
|
||||
// #define PIN_WIRE_SCL (7)
|
||||
#define PIN_WIRE_SDA (6)
|
||||
#define PIN_WIRE_SCL (7)
|
||||
|
||||
static const uint8_t SDA = PIN_WIRE_SDA;
|
||||
static const uint8_t SCL = PIN_WIRE_SCL;
|
||||
|
30
variants/meshlink/platformio.ini
Normal file
30
variants/meshlink/platformio.ini
Normal file
@ -0,0 +1,30 @@
|
||||
; MeshLink board developed by LoraItalia. NRF52840, eByte E22900M22S (Will also come with other frequencies), 25w MPPT solar charger (5v,12v,18v selectable), support for gps, buzzer, oled or e-ink display, 10 gpios, hardware watchdog
|
||||
; https://www.loraitalia.it
|
||||
; firmware for boards with or without oled display
|
||||
[env:meshlink]
|
||||
extends = nrf52840_base
|
||||
board = meshlink
|
||||
;board_check = true
|
||||
build_flags = ${nrf52840_base.build_flags} -I variants/meshlink -D MESHLINK
|
||||
-L "${platformio.libdeps_dir}/${this.__env__}/bsec2/src/cortex-m4/fpv4-sp-d16-hard"
|
||||
-D GPS_POWER_TOGGLE ; comment this line to disable triple press function on the user button to turn off gps entirely.
|
||||
-D EINK_DISPLAY_MODEL=GxEPD2_213_B74
|
||||
-D EINK_WIDTH=250
|
||||
-D EINK_HEIGHT=122
|
||||
-D USE_EINK_DYNAMICDISPLAY ; Enable Dynamic EInk
|
||||
-D EINK_LIMIT_FASTREFRESH=5 ; How many consecutive fast-refreshes are permitted
|
||||
-D EINK_LIMIT_RATE_BACKGROUND_SEC=30 ; Minimum interval between BACKGROUND updates
|
||||
-D EINK_LIMIT_RATE_RESPONSIVE_SEC=1 ; Minimum interval between RESPONSIVE updates
|
||||
-D EINK_LIMIT_GHOSTING_PX=2000 ; (Optional) How much image ghosting is tolerated
|
||||
-D EINK_BACKGROUND_USES_FAST ; (Optional) Use FAST refresh for both BACKGROUND and RESPONSIVE, until a limit is reached.
|
||||
-D EINK_HASQUIRK_VICIOUSFASTREFRESH ; Identify that pixels drawn by fast-refresh are harder to clear
|
||||
|
||||
|
||||
build_src_filter = ${nrf52_base.build_src_filter} +<../variants/meshlink>
|
||||
lib_deps =
|
||||
${nrf52840_base.lib_deps}
|
||||
https://github.com/meshtastic/GxEPD2#55f618961db45a23eff0233546430f1e5a80f63a
|
||||
debug_tool = jlink
|
||||
; If not set we will default to uploading over serial (first it forces bootloader entry by talking 1200bps to cdcacm)
|
||||
; Note: as of 6/2013 the serial/bootloader based programming takes approximately 30 seconds
|
||||
;upload_protocol = jlink
|
23
variants/meshlink/variant.cpp
Normal file
23
variants/meshlink/variant.cpp
Normal file
@ -0,0 +1,23 @@
|
||||
#include "variant.h"
|
||||
#include "nrf.h"
|
||||
#include "wiring_constants.h"
|
||||
#include "wiring_digital.h"
|
||||
|
||||
const uint32_t g_ADigitalPinMap[] = {
|
||||
// P0
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
|
||||
|
||||
// P1
|
||||
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47};
|
||||
|
||||
void initVariant()
|
||||
{
|
||||
pinMode(PIN_LED1, OUTPUT);
|
||||
digitalWrite(PIN_LED1, HIGH); // turn off the white led while booting
|
||||
// otherwise it will stay lit for several seconds (could be annoying)
|
||||
|
||||
#ifdef PIN_WD_EN
|
||||
pinMode(PIN_WD_EN, OUTPUT);
|
||||
digitalWrite(PIN_WD_EN, HIGH); // Enable the Watchdog at boot
|
||||
#endif
|
||||
}
|
153
variants/meshlink/variant.h
Normal file
153
variants/meshlink/variant.h
Normal file
@ -0,0 +1,153 @@
|
||||
#ifndef _VARIANT_MESHLINK_
|
||||
#define _VARIANT_MESHLINK_
|
||||
#ifndef MESHLINK
|
||||
#define MESHLINK
|
||||
#endif
|
||||
/** Master clock frequency */
|
||||
#define VARIANT_MCK (64000000ul)
|
||||
|
||||
// #define USE_LFXO // Board uses 32khz crystal for LF
|
||||
#define USE_LFRC // Board uses RC for LF
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Headers
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
#include "WVariant.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif // __cplusplus
|
||||
|
||||
// Number of pins defined in PinDescription array
|
||||
#define PINS_COUNT (48)
|
||||
#define NUM_DIGITAL_PINS (48)
|
||||
#define NUM_ANALOG_INPUTS (2)
|
||||
#define NUM_ANALOG_OUTPUTS (0)
|
||||
|
||||
#define BUTTON_PIN (-1) // If defined, this will be used for user button presses,
|
||||
#define BUTTON_NEED_PULLUP
|
||||
|
||||
// LEDs
|
||||
#define PIN_LED1 (24) // Built in white led for status
|
||||
#define LED_BLUE PIN_LED1
|
||||
#define LED_BUILTIN PIN_LED1
|
||||
|
||||
#define LED_STATE_ON 0 // State when LED is litted
|
||||
#define LED_INVERTED 1
|
||||
|
||||
// Testing USB detection
|
||||
// #define NRF_APM
|
||||
|
||||
/*
|
||||
* Analog pins
|
||||
*/
|
||||
#define PIN_A1 (3) // P0.03/AIN1
|
||||
#define ADC_RESOLUTION 14
|
||||
|
||||
// Other pins
|
||||
// #define PIN_AREF (2)
|
||||
// static const uint8_t AREF = PIN_AREF;
|
||||
|
||||
/*
|
||||
* Serial interfaces
|
||||
*/
|
||||
#define PIN_SERIAL1_RX (32 + 8)
|
||||
#define PIN_SERIAL1_TX (7)
|
||||
|
||||
/*
|
||||
* SPI Interfaces
|
||||
*/
|
||||
#define SPI_INTERFACES_COUNT 2
|
||||
|
||||
#define PIN_SPI_MISO (8)
|
||||
#define PIN_SPI_MOSI (32 + 9)
|
||||
#define PIN_SPI_SCK (11)
|
||||
|
||||
#define PIN_SPI1_MISO (23)
|
||||
#define PIN_SPI1_MOSI (21)
|
||||
#define PIN_SPI1_SCK (19)
|
||||
|
||||
static const uint8_t SS = 12;
|
||||
static const uint8_t MOSI = PIN_SPI_MOSI;
|
||||
static const uint8_t MISO = PIN_SPI_MISO;
|
||||
static const uint8_t SCK = PIN_SPI_SCK;
|
||||
|
||||
/*
|
||||
* eink display pins
|
||||
*/
|
||||
// #define USE_EINK
|
||||
|
||||
#define PIN_EINK_CS (15)
|
||||
#define PIN_EINK_BUSY (16)
|
||||
#define PIN_EINK_DC (14)
|
||||
#define PIN_EINK_RES (17)
|
||||
#define PIN_EINK_SCLK (19)
|
||||
#define PIN_EINK_MOSI (21) // also called SDI
|
||||
|
||||
/*
|
||||
* Wire Interfaces
|
||||
*/
|
||||
#define WIRE_INTERFACES_COUNT 1
|
||||
|
||||
#define PIN_WIRE_SDA (1)
|
||||
#define PIN_WIRE_SCL (27)
|
||||
|
||||
// QSPI Pins
|
||||
#define PIN_QSPI_SCK 19
|
||||
#define PIN_QSPI_CS 22
|
||||
#define PIN_QSPI_IO0 21
|
||||
#define PIN_QSPI_IO1 23
|
||||
#define PIN_QSPI_IO2 32
|
||||
#define PIN_QSPI_IO3 20
|
||||
|
||||
// On-board QSPI Flash
|
||||
#define EXTERNAL_FLASH_DEVICES W25Q16JVUXIQ
|
||||
#define EXTERNAL_FLASH_USE_QSPI
|
||||
|
||||
#define USE_SX1262
|
||||
#define SX126X_CS (12)
|
||||
#define SX126X_DIO1 (32 + 1)
|
||||
#define SX126X_BUSY (32 + 3)
|
||||
#define SX126X_RESET (6)
|
||||
// #define SX126X_RXEN (13)
|
||||
// DIO2 controlls an antenna switch and the TCXO voltage is controlled by DIO3
|
||||
#define SX126X_DIO2_AS_RF_SWITCH
|
||||
#define SX126X_DIO3_TCXO_VOLTAGE 1.8
|
||||
|
||||
// pin 25 is used to enable or disable the watchdog. This pin has to be disabled when cpu is put to sleep
|
||||
// otherwise the timer will expire and wd will reboot the cpu
|
||||
#define PIN_WD_EN (25)
|
||||
|
||||
#define PIN_GPS_PPS (26) // Pulse per second input from the GPS
|
||||
|
||||
#define GPS_TX_PIN PIN_SERIAL1_RX // This is for bits going TOWARDS the CPU
|
||||
#define GPS_RX_PIN PIN_SERIAL1_TX // This is for bits going TOWARDS the GPS
|
||||
|
||||
// #define GPS_THREAD_INTERVAL 50
|
||||
|
||||
// Define pin to enable GPS toggle (set GPIO to LOW) via user button triple press
|
||||
#define PIN_GPS_EN (0)
|
||||
#define GPS_EN_ACTIVE LOW
|
||||
|
||||
#define PIN_BUZZER (31) // P0.31/AIN7
|
||||
|
||||
// Battery
|
||||
// The battery sense is hooked to pin A0 (2)
|
||||
#define BATTERY_PIN (2)
|
||||
// and has 12 bit resolution
|
||||
#define BATTERY_SENSE_RESOLUTION_BITS 12
|
||||
#define BATTERY_SENSE_RESOLUTION 4096.0
|
||||
#undef AREF_VOLTAGE
|
||||
#define AREF_VOLTAGE 3.0
|
||||
#define VBAT_AR_INTERNAL AR_INTERNAL_3_0
|
||||
#define ADC_MULTIPLIER 1.42 // fine tuning of voltage
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Arduino objects - C++ only
|
||||
*----------------------------------------------------------------------------*/
|
||||
#endif
|
30
variants/meshlink_eink/platformio.ini
Normal file
30
variants/meshlink_eink/platformio.ini
Normal file
@ -0,0 +1,30 @@
|
||||
; MeshLink board developed by LoraItalia. NRF52840, eByte E22900M22S (Will also come with other frequencies), 25w MPPT solar charger (5v,12v,18v selectable), support for gps, buzzer, oled or e-ink display, 10 gpios, hardware watchdog
|
||||
; https://www.loraitalia.it
|
||||
; firmware for boards with a 250x122 e-ink display
|
||||
[env:meshlink_eink]
|
||||
extends = nrf52840_base
|
||||
board = meshlink
|
||||
;board_check = true
|
||||
build_flags = ${nrf52840_base.build_flags} -I variants/meshlink_eink -D MESHLINK
|
||||
-L "${platformio.libdeps_dir}/${this.__env__}/bsec2/src/cortex-m4/fpv4-sp-d16-hard"
|
||||
-D GPS_POWER_TOGGLE ; comment this line to disable triple press function on the user button to turn off gps entirely.
|
||||
-D EINK_DISPLAY_MODEL=GxEPD2_213_B74
|
||||
-D EINK_WIDTH=250
|
||||
-D EINK_HEIGHT=122
|
||||
-D USE_EINK_DYNAMICDISPLAY ; Enable Dynamic EInk
|
||||
-D EINK_LIMIT_FASTREFRESH=5 ; How many consecutive fast-refreshes are permitted
|
||||
-D EINK_LIMIT_RATE_BACKGROUND_SEC=30 ; Minimum interval between BACKGROUND updates
|
||||
-D EINK_LIMIT_RATE_RESPONSIVE_SEC=1 ; Minimum interval between RESPONSIVE updates
|
||||
-D EINK_LIMIT_GHOSTING_PX=2000 ; (Optional) How much image ghosting is tolerated
|
||||
-D EINK_BACKGROUND_USES_FAST ; (Optional) Use FAST refresh for both BACKGROUND and RESPONSIVE, until a limit is reached.
|
||||
-D EINK_HASQUIRK_VICIOUSFASTREFRESH ; Identify that pixels drawn by fast-refresh are harder to clear
|
||||
|
||||
|
||||
build_src_filter = ${nrf52_base.build_src_filter} +<../variants/meshlink_eink>
|
||||
lib_deps =
|
||||
${nrf52840_base.lib_deps}
|
||||
https://github.com/meshtastic/GxEPD2#55f618961db45a23eff0233546430f1e5a80f63a
|
||||
debug_tool = jlink
|
||||
; If not set we will default to uploading over serial (first it forces bootloader entry by talking 1200bps to cdcacm)
|
||||
; Note: as of 6/2013 the serial/bootloader based programming takes approximately 30 seconds
|
||||
;upload_protocol = jlink
|
23
variants/meshlink_eink/variant.cpp
Normal file
23
variants/meshlink_eink/variant.cpp
Normal file
@ -0,0 +1,23 @@
|
||||
#include "variant.h"
|
||||
#include "nrf.h"
|
||||
#include "wiring_constants.h"
|
||||
#include "wiring_digital.h"
|
||||
|
||||
const uint32_t g_ADigitalPinMap[] = {
|
||||
// P0
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
|
||||
|
||||
// P1
|
||||
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47};
|
||||
|
||||
void initVariant()
|
||||
{
|
||||
pinMode(PIN_LED1, OUTPUT);
|
||||
digitalWrite(PIN_LED1, HIGH); // turn off the white led while booting
|
||||
// otherwise it will stay lit for several seconds (could be annoying)
|
||||
|
||||
#ifdef PIN_WD_EN
|
||||
pinMode(PIN_WD_EN, OUTPUT);
|
||||
digitalWrite(PIN_WD_EN, HIGH); // Enable the Watchdog at boot
|
||||
#endif
|
||||
}
|
153
variants/meshlink_eink/variant.h
Normal file
153
variants/meshlink_eink/variant.h
Normal file
@ -0,0 +1,153 @@
|
||||
#ifndef _VARIANT_MESHLINK_
|
||||
#define _VARIANT_MESHLINK_
|
||||
#ifndef MESHLINK
|
||||
#define MESHLINK
|
||||
#endif
|
||||
/** Master clock frequency */
|
||||
#define VARIANT_MCK (64000000ul)
|
||||
|
||||
// #define USE_LFXO // Board uses 32khz crystal for LF
|
||||
#define USE_LFRC // Board uses RC for LF
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Headers
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
#include "WVariant.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif // __cplusplus
|
||||
|
||||
// Number of pins defined in PinDescription array
|
||||
#define PINS_COUNT (48)
|
||||
#define NUM_DIGITAL_PINS (48)
|
||||
#define NUM_ANALOG_INPUTS (2)
|
||||
#define NUM_ANALOG_OUTPUTS (0)
|
||||
|
||||
#define BUTTON_PIN (-1) // If defined, this will be used for user button presses,
|
||||
#define BUTTON_NEED_PULLUP
|
||||
|
||||
// LEDs
|
||||
#define PIN_LED1 (24) // Built in white led for status
|
||||
#define LED_BLUE PIN_LED1
|
||||
#define LED_BUILTIN PIN_LED1
|
||||
|
||||
#define LED_STATE_ON 0 // State when LED is litted
|
||||
#define LED_INVERTED 1
|
||||
|
||||
// Testing USB detection
|
||||
// #define NRF_APM
|
||||
|
||||
/*
|
||||
* Analog pins
|
||||
*/
|
||||
#define PIN_A1 (3) // P0.03/AIN1
|
||||
#define ADC_RESOLUTION 14
|
||||
|
||||
// Other pins
|
||||
// #define PIN_AREF (2)
|
||||
// static const uint8_t AREF = PIN_AREF;
|
||||
|
||||
/*
|
||||
* Serial interfaces
|
||||
*/
|
||||
#define PIN_SERIAL1_RX (32 + 8)
|
||||
#define PIN_SERIAL1_TX (7)
|
||||
|
||||
/*
|
||||
* SPI Interfaces
|
||||
*/
|
||||
#define SPI_INTERFACES_COUNT 2
|
||||
|
||||
#define PIN_SPI_MISO (8)
|
||||
#define PIN_SPI_MOSI (32 + 9)
|
||||
#define PIN_SPI_SCK (11)
|
||||
|
||||
#define PIN_SPI1_MISO (23)
|
||||
#define PIN_SPI1_MOSI (21)
|
||||
#define PIN_SPI1_SCK (19)
|
||||
|
||||
static const uint8_t SS = 12;
|
||||
static const uint8_t MOSI = PIN_SPI_MOSI;
|
||||
static const uint8_t MISO = PIN_SPI_MISO;
|
||||
static const uint8_t SCK = PIN_SPI_SCK;
|
||||
|
||||
/*
|
||||
* eink display pins
|
||||
*/
|
||||
#define USE_EINK
|
||||
|
||||
#define PIN_EINK_CS (15)
|
||||
#define PIN_EINK_BUSY (16)
|
||||
#define PIN_EINK_DC (14)
|
||||
#define PIN_EINK_RES (17)
|
||||
#define PIN_EINK_SCLK (19)
|
||||
#define PIN_EINK_MOSI (21) // also called SDI
|
||||
|
||||
/*
|
||||
* Wire Interfaces
|
||||
*/
|
||||
#define WIRE_INTERFACES_COUNT 1
|
||||
|
||||
#define PIN_WIRE_SDA (1)
|
||||
#define PIN_WIRE_SCL (27)
|
||||
|
||||
// QSPI Pins
|
||||
#define PIN_QSPI_SCK 19
|
||||
#define PIN_QSPI_CS 22
|
||||
#define PIN_QSPI_IO0 21
|
||||
#define PIN_QSPI_IO1 23
|
||||
#define PIN_QSPI_IO2 32
|
||||
#define PIN_QSPI_IO3 20
|
||||
|
||||
// On-board QSPI Flash
|
||||
#define EXTERNAL_FLASH_DEVICES W25Q16JVUXIQ
|
||||
#define EXTERNAL_FLASH_USE_QSPI
|
||||
|
||||
#define USE_SX1262
|
||||
#define SX126X_CS (12)
|
||||
#define SX126X_DIO1 (32 + 1)
|
||||
#define SX126X_BUSY (32 + 3)
|
||||
#define SX126X_RESET (6)
|
||||
// #define SX126X_RXEN (13)
|
||||
// DIO2 controlls an antenna switch and the TCXO voltage is controlled by DIO3
|
||||
#define SX126X_DIO2_AS_RF_SWITCH
|
||||
#define SX126X_DIO3_TCXO_VOLTAGE 1.8
|
||||
|
||||
// pin 25 is used to enable or disable the watchdog. This pin has to be disabled when cpu is put to sleep
|
||||
// otherwise the timer will expire and wd will reboot the cpu
|
||||
#define PIN_WD_EN (25)
|
||||
|
||||
#define PIN_GPS_PPS (26) // Pulse per second input from the GPS
|
||||
|
||||
#define GPS_TX_PIN PIN_SERIAL1_RX // This is for bits going TOWARDS the CPU
|
||||
#define GPS_RX_PIN PIN_SERIAL1_TX // This is for bits going TOWARDS the GPS
|
||||
|
||||
// #define GPS_THREAD_INTERVAL 50
|
||||
|
||||
// Define pin to enable GPS toggle (set GPIO to LOW) via user button triple press
|
||||
#define PIN_GPS_EN (0)
|
||||
#define GPS_EN_ACTIVE LOW
|
||||
|
||||
#define PIN_BUZZER (31) // P0.31/AIN7
|
||||
|
||||
// Battery
|
||||
// The battery sense is hooked to pin A0 (2)
|
||||
#define BATTERY_PIN (2)
|
||||
// and has 12 bit resolution
|
||||
#define BATTERY_SENSE_RESOLUTION_BITS 12
|
||||
#define BATTERY_SENSE_RESOLUTION 4096.0
|
||||
#undef AREF_VOLTAGE
|
||||
#define AREF_VOLTAGE 3.0
|
||||
#define VBAT_AR_INTERNAL AR_INTERNAL_3_0
|
||||
#define ADC_MULTIPLIER 1.42 // fine tuning of voltage
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Arduino objects - C++ only
|
||||
*----------------------------------------------------------------------------*/
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user