sforkowany z mirror/meshtastic-firmware
Merge branch 'master' of https://github.com/mc-hamster/Meshtastic-device
commit
5ebac0cd54
|
@ -53,6 +53,7 @@
|
||||||
},
|
},
|
||||||
"cSpell.words": [
|
"cSpell.words": [
|
||||||
"Blox",
|
"Blox",
|
||||||
|
"EINK",
|
||||||
"HFSR",
|
"HFSR",
|
||||||
"Meshtastic",
|
"Meshtastic",
|
||||||
"NEMAGPS",
|
"NEMAGPS",
|
||||||
|
|
|
@ -0,0 +1,61 @@
|
||||||
|
{
|
||||||
|
"build": {
|
||||||
|
"arduino": {
|
||||||
|
"ldscript": "nrf52840_s140_v6.ld"
|
||||||
|
},
|
||||||
|
"core": "nRF5",
|
||||||
|
"cpu": "cortex-m4",
|
||||||
|
"extra_flags": "-DARDUINO_NRF52840_LORA_RELAY_V1 -DNRF52840_XXAA",
|
||||||
|
"f_cpu": "64000000L",
|
||||||
|
"hwids": [
|
||||||
|
[
|
||||||
|
"0x239A",
|
||||||
|
"0x4405"
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"usb_product": "TTGO_eink",
|
||||||
|
"mcu": "nrf52840",
|
||||||
|
"variant": "eink",
|
||||||
|
"variants_dir": "variants",
|
||||||
|
"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",
|
||||||
|
"onboard_tools": [
|
||||||
|
"jlink"
|
||||||
|
],
|
||||||
|
"svd_path": "nrf52840.svd"
|
||||||
|
},
|
||||||
|
"frameworks": [
|
||||||
|
"arduino"
|
||||||
|
],
|
||||||
|
"name": "TTGO eink (Adafruit BSP)",
|
||||||
|
"upload": {
|
||||||
|
"maximum_ram_size": 248832,
|
||||||
|
"maximum_size": 815104,
|
||||||
|
"require_upload_port": true,
|
||||||
|
"speed": 115200,
|
||||||
|
"protocol": "jlink",
|
||||||
|
"protocols": [
|
||||||
|
"jlink",
|
||||||
|
"nrfjprog",
|
||||||
|
"stlink"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"url": "FIXME",
|
||||||
|
"vendor": "TTGO"
|
||||||
|
}
|
Plik binarny nie jest wyświetlany.
Plik binarny nie jest wyświetlany.
|
@ -227,6 +227,20 @@ lib_deps =
|
||||||
${arduino_base.lib_deps}
|
${arduino_base.lib_deps}
|
||||||
UC1701
|
UC1701
|
||||||
|
|
||||||
|
; Prototype eink/nrf52840/sx1262 device
|
||||||
|
[env:eink]
|
||||||
|
extends = nrf52_base
|
||||||
|
board = eink
|
||||||
|
# add our variants files to the include and src paths
|
||||||
|
# define build flags for the TFT_eSPI library
|
||||||
|
build_flags = ${nrf52_base.build_flags} -Ivariants/eink
|
||||||
|
-DBUSY_PIN=3 -DRST_PIN=2 -DDC_PIN=28 -DCS_PIN=30
|
||||||
|
src_filter = ${nrf52_base.src_filter} +<../variants/eink>
|
||||||
|
lib_deps =
|
||||||
|
${arduino_base.lib_deps}
|
||||||
|
https://github.com/geeksville/EPD_Libraries.git
|
||||||
|
TFT_eSPI
|
||||||
|
|
||||||
; The https://github.com/BigCorvus/SX1262-LoRa-BLE-Relay board by @BigCorvus
|
; The https://github.com/BigCorvus/SX1262-LoRa-BLE-Relay board by @BigCorvus
|
||||||
[env:lora-relay-v1]
|
[env:lora-relay-v1]
|
||||||
extends = nrf52_base
|
extends = nrf52_base
|
||||||
|
|
192
src/GPSStatus.h
192
src/GPSStatus.h
|
@ -1,126 +1,98 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <Arduino.h>
|
|
||||||
#include "Status.h"
|
#include "Status.h"
|
||||||
#include "configuration.h"
|
#include "configuration.h"
|
||||||
|
#include <Arduino.h>
|
||||||
|
|
||||||
namespace meshtastic {
|
namespace meshtastic
|
||||||
|
{
|
||||||
|
|
||||||
/// Describes the state of the GPS system.
|
/// Describes the state of the GPS system.
|
||||||
class GPSStatus : public Status
|
class GPSStatus : public Status
|
||||||
|
{
|
||||||
|
|
||||||
|
private:
|
||||||
|
CallbackObserver<GPSStatus, const GPSStatus *> statusObserver =
|
||||||
|
CallbackObserver<GPSStatus, const GPSStatus *>(this, &GPSStatus::updateStatus);
|
||||||
|
|
||||||
|
bool hasLock = false; // default to false, until we complete our first read
|
||||||
|
bool isConnected = false; // Do we have a GPS we are talking to
|
||||||
|
int32_t latitude = 0, longitude = 0; // as an int mult by 1e-7 to get value as double
|
||||||
|
int32_t altitude = 0;
|
||||||
|
uint32_t dop = 0; // Diminution of position; PDOP where possible (UBlox), HDOP otherwise (TinyGPS) in 10^2 units (needs
|
||||||
|
// scaling before use)
|
||||||
|
uint32_t heading = 0;
|
||||||
|
uint32_t numSatellites = 0;
|
||||||
|
|
||||||
|
public:
|
||||||
|
GPSStatus() { statusType = STATUS_TYPE_GPS; }
|
||||||
|
GPSStatus(bool hasLock, bool isConnected, int32_t latitude, int32_t longitude, int32_t altitude, uint32_t dop,
|
||||||
|
uint32_t heading, uint32_t numSatellites)
|
||||||
|
: Status()
|
||||||
{
|
{
|
||||||
|
this->hasLock = hasLock;
|
||||||
|
this->isConnected = isConnected;
|
||||||
|
this->latitude = latitude;
|
||||||
|
this->longitude = longitude;
|
||||||
|
this->altitude = altitude;
|
||||||
|
this->dop = dop;
|
||||||
|
this->heading = heading;
|
||||||
|
this->numSatellites = numSatellites;
|
||||||
|
}
|
||||||
|
GPSStatus(const GPSStatus &);
|
||||||
|
GPSStatus &operator=(const GPSStatus &);
|
||||||
|
|
||||||
private:
|
void observe(Observable<const GPSStatus *> *source) { statusObserver.observe(source); }
|
||||||
CallbackObserver<GPSStatus, const GPSStatus *> statusObserver = CallbackObserver<GPSStatus, const GPSStatus *>(this, &GPSStatus::updateStatus);
|
|
||||||
|
|
||||||
bool hasLock = false; // default to false, until we complete our first read
|
bool getHasLock() const { return hasLock; }
|
||||||
bool isConnected = false; // Do we have a GPS we are talking to
|
|
||||||
int32_t latitude = 0, longitude = 0; // as an int mult by 1e-7 to get value as double
|
|
||||||
int32_t altitude = 0;
|
|
||||||
uint32_t dop = 0; // Diminution of position; PDOP where possible (UBlox), HDOP otherwise (TinyGPS) in 10^2 units (needs scaling before use)
|
|
||||||
uint32_t heading = 0;
|
|
||||||
uint32_t numSatellites = 0;
|
|
||||||
|
|
||||||
public:
|
bool getIsConnected() const { return isConnected; }
|
||||||
|
|
||||||
GPSStatus() {
|
int32_t getLatitude() const { return latitude; }
|
||||||
statusType = STATUS_TYPE_GPS;
|
|
||||||
}
|
int32_t getLongitude() const { return longitude; }
|
||||||
GPSStatus( bool hasLock, bool isConnected, int32_t latitude, int32_t longitude, int32_t altitude, uint32_t dop, uint32_t heading, uint32_t numSatellites ) : Status()
|
|
||||||
|
int32_t getAltitude() const { return altitude; }
|
||||||
|
|
||||||
|
uint32_t getDOP() const { return dop; }
|
||||||
|
|
||||||
|
uint32_t getHeading() const { return heading; }
|
||||||
|
|
||||||
|
uint32_t getNumSatellites() const { return numSatellites; }
|
||||||
|
|
||||||
|
bool matches(const GPSStatus *newStatus) const
|
||||||
|
{
|
||||||
|
return (newStatus->hasLock != hasLock || newStatus->isConnected != isConnected || newStatus->latitude != latitude ||
|
||||||
|
newStatus->longitude != longitude || newStatus->altitude != altitude || newStatus->dop != dop ||
|
||||||
|
newStatus->heading != heading || newStatus->numSatellites != numSatellites);
|
||||||
|
}
|
||||||
|
int updateStatus(const GPSStatus *newStatus)
|
||||||
|
{
|
||||||
|
// Only update the status if values have actually changed
|
||||||
|
bool isDirty;
|
||||||
{
|
{
|
||||||
this->hasLock = hasLock;
|
isDirty = matches(newStatus);
|
||||||
this->isConnected = isConnected;
|
initialized = true;
|
||||||
this->latitude = latitude;
|
hasLock = newStatus->hasLock;
|
||||||
this->longitude = longitude;
|
isConnected = newStatus->isConnected;
|
||||||
this->altitude = altitude;
|
latitude = newStatus->latitude;
|
||||||
this->dop = dop;
|
longitude = newStatus->longitude;
|
||||||
this->heading = heading;
|
altitude = newStatus->altitude;
|
||||||
this->numSatellites = numSatellites;
|
dop = newStatus->dop;
|
||||||
|
heading = newStatus->heading;
|
||||||
|
numSatellites = newStatus->numSatellites;
|
||||||
}
|
}
|
||||||
GPSStatus(const GPSStatus &);
|
if (isDirty) {
|
||||||
GPSStatus &operator=(const GPSStatus &);
|
if (hasLock)
|
||||||
|
DEBUG_MSG("New GPS pos lat=%f, lon=%f, alt=%d, pdop=%f, heading=%f, sats=%d\n", latitude * 1e-7, longitude * 1e-7,
|
||||||
void observe(Observable<const GPSStatus *> *source)
|
altitude, dop * 1e-2, heading * 1e-5, numSatellites);
|
||||||
{
|
else
|
||||||
statusObserver.observe(source);
|
DEBUG_MSG("No GPS lock\n");
|
||||||
|
onNewStatus.notifyObservers(this);
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
bool getHasLock() const
|
} // namespace meshtastic
|
||||||
{
|
|
||||||
return hasLock;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool getIsConnected() const
|
|
||||||
{
|
|
||||||
return isConnected;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t getLatitude() const
|
|
||||||
{
|
|
||||||
return latitude;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t getLongitude() const
|
|
||||||
{
|
|
||||||
return longitude;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t getAltitude() const
|
|
||||||
{
|
|
||||||
return altitude;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t getDOP() const
|
|
||||||
{
|
|
||||||
return dop;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t getHeading() const
|
|
||||||
{
|
|
||||||
return heading;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t getNumSatellites() const
|
|
||||||
{
|
|
||||||
return numSatellites;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool matches(const GPSStatus *newStatus) const
|
|
||||||
{
|
|
||||||
return (
|
|
||||||
newStatus->hasLock != hasLock ||
|
|
||||||
newStatus->isConnected != isConnected ||
|
|
||||||
newStatus->latitude != latitude ||
|
|
||||||
newStatus->longitude != longitude ||
|
|
||||||
newStatus->altitude != altitude ||
|
|
||||||
newStatus->dop != dop ||
|
|
||||||
newStatus->heading != heading ||
|
|
||||||
newStatus->numSatellites != numSatellites
|
|
||||||
);
|
|
||||||
}
|
|
||||||
int updateStatus(const GPSStatus *newStatus) {
|
|
||||||
// Only update the status if values have actually changed
|
|
||||||
bool isDirty;
|
|
||||||
{
|
|
||||||
isDirty = matches(newStatus);
|
|
||||||
initialized = true;
|
|
||||||
hasLock = newStatus->hasLock;
|
|
||||||
isConnected = newStatus->isConnected;
|
|
||||||
latitude = newStatus->latitude;
|
|
||||||
longitude = newStatus->longitude;
|
|
||||||
altitude = newStatus->altitude;
|
|
||||||
dop = newStatus->dop;
|
|
||||||
heading = newStatus->heading;
|
|
||||||
numSatellites = newStatus->numSatellites;
|
|
||||||
}
|
|
||||||
if(isDirty) {
|
|
||||||
DEBUG_MSG("New GPS pos lat=%f, lon=%f, alt=%d, pdop=%f, heading=%f, sats=%d\n", latitude * 1e-7, longitude * 1e-7, altitude, dop * 1e-2, heading * 1e-5, numSatellites);
|
|
||||||
onNewStatus.notifyObservers(this);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
extern meshtastic::GPSStatus *gpsStatus;
|
extern meshtastic::GPSStatus *gpsStatus;
|
|
@ -66,7 +66,10 @@ bool Power::analogInit()
|
||||||
{
|
{
|
||||||
#ifdef BATTERY_PIN
|
#ifdef BATTERY_PIN
|
||||||
DEBUG_MSG("Using analog input for battery level\n");
|
DEBUG_MSG("Using analog input for battery level\n");
|
||||||
|
#ifndef NO_ESP32
|
||||||
|
// ESP32 needs special analog stuff
|
||||||
adcAttachPin(BATTERY_PIN);
|
adcAttachPin(BATTERY_PIN);
|
||||||
|
#endif
|
||||||
// adcStart(BATTERY_PIN);
|
// adcStart(BATTERY_PIN);
|
||||||
analogReadResolution(10); // Default of 12 is not very linear. Recommended to use 10 or 11 depending on needed resolution.
|
analogReadResolution(10); // Default of 12 is not very linear. Recommended to use 10 or 11 depending on needed resolution.
|
||||||
batteryLevel = &analogLevel;
|
batteryLevel = &analogLevel;
|
||||||
|
|
|
@ -11,16 +11,7 @@
|
||||||
|
|
||||||
static void sdsEnter()
|
static void sdsEnter()
|
||||||
{
|
{
|
||||||
/*
|
// FIXME - make sure GPS and LORA radio are off first - because we want close to zero current draw
|
||||||
|
|
||||||
// Don't deepsleep if we have USB power or if the user as pressed a button recently
|
|
||||||
// !isUSBPowered <- doesn't work yet because the axp192 isn't letting the battery fully charge when we are awake - FIXME
|
|
||||||
if (millis() - lastPressMs > radioConfig.preferences.mesh_sds_timeout_secs)
|
|
||||||
{
|
|
||||||
doDeepSleep(radioConfig.preferences.sds_secs);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
doDeepSleep(radioConfig.preferences.sds_secs * 1000LL);
|
doDeepSleep(radioConfig.preferences.sds_secs * 1000LL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -145,7 +145,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#define FLIP_SCREEN_VERTICALLY
|
#define FLIP_SCREEN_VERTICALLY
|
||||||
|
|
||||||
// DEBUG LED
|
// DEBUG LED
|
||||||
|
#ifndef LED_INVERTED
|
||||||
#define LED_INVERTED 0 // define as 1 if LED is active low (on)
|
#define LED_INVERTED 0 // define as 1 if LED is active low (on)
|
||||||
|
#endif
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// GPS
|
// GPS
|
||||||
|
|
|
@ -1,6 +1,51 @@
|
||||||
#include "NMEAGPS.h"
|
#include "NMEAGPS.h"
|
||||||
#include "configuration.h"
|
#include "configuration.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
Helpful translations from the Air530 GPS datasheet
|
||||||
|
|
||||||
|
Sat acquision mode
|
||||||
|
捕获电流值@3.3v 42.6 mA
|
||||||
|
|
||||||
|
sat tracking mode
|
||||||
|
跟踪电流值@3.3v 36.7 mA
|
||||||
|
|
||||||
|
Low power mode
|
||||||
|
低功耗模式@3.3V 0.85 mA
|
||||||
|
(发送指令:$PGKC051,0)
|
||||||
|
|
||||||
|
Super low power mode
|
||||||
|
超低功耗模式@3.3V 31 uA
|
||||||
|
(发送指令:$PGKC105,4)
|
||||||
|
|
||||||
|
To exit sleep use WAKE pin
|
||||||
|
|
||||||
|
Commands to enter sleep
|
||||||
|
6、Command: 105
|
||||||
|
进入周期性低功耗模式
|
||||||
|
Arguments:
|
||||||
|
|
||||||
|
Arg1: “0”,正常运行模式 (normal mode)
|
||||||
|
“1”,周期超低功耗跟踪模式,需要拉高 WAKE 来唤醒 (periodic low power tracking mode - keeps sat positions, use wake to wake up)
|
||||||
|
“2”,周期低功耗模式 (periodic low power mode)
|
||||||
|
“4”,直接进入超低功耗跟踪模式,需要拉高 WAKE 来唤醒 (super low power consumption mode immediately, need WAKE to resume)
|
||||||
|
“8”,自动低功耗模式,可以通过串口唤醒 (automatic low power mode, wake by sending characters to serial port)
|
||||||
|
“9”, 自动超低功耗跟踪模式,需要拉高 WAKE 来唤醒 (automatic low power tracking when possible, need wake pin to resume)
|
||||||
|
|
||||||
|
(Arg 2 & 3 only valid if Arg1 is "1" or "2")
|
||||||
|
Arg2:运行时间(毫秒),在 Arg1 为 1、2 的周期模式下,此参数起作用
|
||||||
|
ON time in msecs
|
||||||
|
|
||||||
|
Arg3:睡眠时间(毫秒),在 Arg1 为 1、2 的周期模式下,此参数起作用
|
||||||
|
Sleep time in msecs
|
||||||
|
|
||||||
|
Example:
|
||||||
|
$PGKC105,8*3F<CR><LF>
|
||||||
|
This will set automatic low power mode with waking when we send chars to the serial port. Possibly do this as soon as we get a new
|
||||||
|
location. When we wake again in a minute we send a character to wake up.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
static int32_t toDegInt(RawDegrees d)
|
static int32_t toDegInt(RawDegrees d)
|
||||||
{
|
{
|
||||||
int32_t degMult = 10000000; // 1e7
|
int32_t degMult = 10000000; // 1e7
|
||||||
|
@ -10,12 +55,27 @@ static int32_t toDegInt(RawDegrees d)
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool NMEAGPS::setup()
|
||||||
|
{
|
||||||
|
#ifdef PIN_GPS_PPS
|
||||||
|
// pulse per second
|
||||||
|
// FIXME - move into shared GPS code
|
||||||
|
pinMode(PIN_GPS_PPS, INPUT);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void NMEAGPS::loop()
|
void NMEAGPS::loop()
|
||||||
{
|
{
|
||||||
while (_serial_gps->available() > 0) {
|
while (_serial_gps->available() > 0) {
|
||||||
int c = _serial_gps->read();
|
int c = _serial_gps->read();
|
||||||
// Serial.write(c);
|
// DEBUG_MSG("%c", c);
|
||||||
reader.encode(c);
|
bool isValid = reader.encode(c);
|
||||||
|
|
||||||
|
// if we have received valid NMEA claim we are connected
|
||||||
|
if (isValid)
|
||||||
|
isConnected = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t now = millis();
|
uint32_t now = millis();
|
||||||
|
@ -39,8 +99,6 @@ void NMEAGPS::loop()
|
||||||
t.tm_year = d.year() - 1900;
|
t.tm_year = d.year() - 1900;
|
||||||
t.tm_isdst = false;
|
t.tm_isdst = false;
|
||||||
perhapsSetRTC(t);
|
perhapsSetRTC(t);
|
||||||
|
|
||||||
isConnected = true; // we seem to have a real GPS (but not necessarily a lock)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t fixtype = reader.fixQuality();
|
uint8_t fixtype = reader.fixQuality();
|
||||||
|
@ -68,7 +126,7 @@ void NMEAGPS::loop()
|
||||||
}
|
}
|
||||||
|
|
||||||
// expect gps pos lat=37.520825, lon=-122.309162, alt=158
|
// expect gps pos lat=37.520825, lon=-122.309162, alt=158
|
||||||
DEBUG_MSG("new NMEA GPS pos lat=%f, lon=%f, alt=%d, hdop=%f, heading=%f\n", latitude * 1e-7, longitude * 1e-7,
|
DEBUG_MSG("new NMEA GPS pos lat=%f, lon=%f, alt=%d, hdop=%g, heading=%f\n", latitude * 1e-7, longitude * 1e-7,
|
||||||
altitude, dop * 1e-2, heading * 1e-5);
|
altitude, dop * 1e-2, heading * 1e-5);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,5 +17,7 @@ class NMEAGPS : public GPS
|
||||||
uint32_t lastUpdateMsec = 0;
|
uint32_t lastUpdateMsec = 0;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
virtual bool setup();
|
||||||
|
|
||||||
virtual void loop();
|
virtual void loop();
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,125 @@
|
||||||
|
#include "configuration.h"
|
||||||
|
|
||||||
|
#ifdef HAS_EINK
|
||||||
|
#include "EInkDisplay.h"
|
||||||
|
#include "SPILock.h"
|
||||||
|
#include "epd1in54.h" // Screen specific library
|
||||||
|
#include "graphics/configs.h"
|
||||||
|
#include <SPI.h>
|
||||||
|
#include <TFT_eSPI.h> // Graphics library and Sprite class
|
||||||
|
|
||||||
|
Epd ePaper; // Create an instance ePaper
|
||||||
|
|
||||||
|
TFT_eSPI glc = TFT_eSPI(); // Invoke the graphics library class
|
||||||
|
TFT_eSprite frame = TFT_eSprite(&glc); // Invoke the Sprite class for the image frame buffer
|
||||||
|
uint8_t *framePtr; // Pointer for the black frame buffer
|
||||||
|
|
||||||
|
#define COLORED 0
|
||||||
|
#define UNCOLORED 1
|
||||||
|
|
||||||
|
#define INK COLORED // Black ink
|
||||||
|
#define PAPER UNCOLORED // 'paper' background colour
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
// Update display - different displays have different function names in the default
|
||||||
|
// Waveshare libraries :-(
|
||||||
|
//------------------------------------------------------------------------------------
|
||||||
|
#if defined(EPD1IN54B_H) || defined(EPD1IN54C_H) || defined(EPD2IN13B_H) || defined(EPD2IN7B_H) || defined(EPD2IN9B_H) || \
|
||||||
|
defined(EPD4IN2_H)
|
||||||
|
void updateDisplay(uint8_t *blackFrame = blackFramePtr, uint8_t *redFrame = redFramePtr)
|
||||||
|
{
|
||||||
|
ePaper.DisplayFrame(blackFrame, redFrame); // Update 3 colour display
|
||||||
|
#else
|
||||||
|
void updateDisplay(uint8_t *blackFrame = framePtr)
|
||||||
|
{
|
||||||
|
#if defined(EPD2IN7_H) || defined(EPD4IN2_H)
|
||||||
|
ePaper.DisplayFrame(blackFrame); // Update 2 color display
|
||||||
|
|
||||||
|
#elif defined(EPD1IN54_H) || defined(EPD2IN13_H) || defined(EPD2IN9_H)
|
||||||
|
ePaper.SetFrameMemory(blackFrame); // Update 2 colour display
|
||||||
|
ePaper.DisplayFrame();
|
||||||
|
#else
|
||||||
|
#error "Selected ePaper library is not supported"
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
EInkDisplay::EInkDisplay(uint8_t address, int sda, int scl)
|
||||||
|
{
|
||||||
|
setGeometry(GEOMETRY_128_64); // FIXME - currently we lie and claim 128x64 because I'm not yet sure other resolutions will
|
||||||
|
// work ie GEOMETRY_RAWMODE
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME quick hack to limit drawing to a very slow rate
|
||||||
|
uint32_t lastDrawMsec;
|
||||||
|
|
||||||
|
// Write the buffer to the display memory
|
||||||
|
void EInkDisplay::display(void)
|
||||||
|
{
|
||||||
|
concurrency::LockGuard g(spiLock);
|
||||||
|
|
||||||
|
uint32_t now = millis();
|
||||||
|
uint32_t sinceLast = now - lastDrawMsec;
|
||||||
|
|
||||||
|
if (framePtr && (sinceLast > 30 * 1000 || lastDrawMsec == 0)) {
|
||||||
|
lastDrawMsec = now;
|
||||||
|
|
||||||
|
// FIXME - only draw bits have changed (use backbuf similar to the other displays)
|
||||||
|
// tft.drawBitmap(0, 0, buffer, 128, 64, TFT_YELLOW, TFT_BLACK);
|
||||||
|
for (uint8_t y = 0; y < SCREEN_HEIGHT; y++) {
|
||||||
|
for (uint8_t x = 0; x < SCREEN_WIDTH; x++) {
|
||||||
|
|
||||||
|
// get src pixel in the page based ordering the OLED lib uses FIXME, super inefficent
|
||||||
|
auto b = buffer[x + (y / 8) * SCREEN_WIDTH];
|
||||||
|
auto isset = b & (1 << (y & 7));
|
||||||
|
frame.drawPixel(x, y, isset ? INK : PAPER);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
updateDisplay(); // Send image to display and refresh
|
||||||
|
|
||||||
|
// Put screen to sleep to save power (if wanted)
|
||||||
|
// ePaper.Sleep();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send a command to the display (low level function)
|
||||||
|
void EInkDisplay::sendCommand(uint8_t com)
|
||||||
|
{
|
||||||
|
(void)com;
|
||||||
|
// Drop all commands to device (we just update the buffer)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Connect to the display
|
||||||
|
bool EInkDisplay::connect()
|
||||||
|
{
|
||||||
|
DEBUG_MSG("Doing EInk init\n");
|
||||||
|
|
||||||
|
#ifdef PIN_EINK_EN
|
||||||
|
digitalWrite(PIN_EINK_EN, HIGH);
|
||||||
|
pinMode(PIN_EINK_EN, OUTPUT);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Initialise the ePaper library
|
||||||
|
// FIXME - figure out how to use lut_partial_update
|
||||||
|
if (ePaper.Init(lut_full_update) != 0) {
|
||||||
|
DEBUG_MSG("ePaper init failed\n");
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
frame.setColorDepth(1); // Must set the bits per pixel to 1 for ePaper displays
|
||||||
|
// Set bit depth BEFORE creating Sprite, default is 16!
|
||||||
|
|
||||||
|
// Create a frame buffer in RAM of defined size and save the pointer to it
|
||||||
|
// RAM needed is about (EPD_WIDTH * EPD_HEIGHT)/8 , ~5000 bytes for 200 x 200 pixels
|
||||||
|
// Note: always create the Sprite before setting the Sprite rotation
|
||||||
|
framePtr = (uint8_t *)frame.createSprite(EPD_WIDTH, EPD_HEIGHT);
|
||||||
|
|
||||||
|
frame.fillSprite(PAPER); // Fill frame with white
|
||||||
|
/* frame.drawLine(0, 0, frame.width() - 1, frame.height() - 1, INK);
|
||||||
|
frame.drawLine(0, frame.height() - 1, frame.width() - 1, 0, INK);
|
||||||
|
updateDisplay(); */
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,35 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <OLEDDisplay.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An adapter class that allows using the TFT_eSPI library as if it was an OLEDDisplay implementation.
|
||||||
|
*
|
||||||
|
* Remaining TODO:
|
||||||
|
* optimize display() to only draw changed pixels (see other OLED subclasses for examples)
|
||||||
|
* implement displayOn/displayOff to turn off the TFT device (and backlight)
|
||||||
|
* Use the fast NRF52 SPI API rather than the slow standard arduino version
|
||||||
|
*
|
||||||
|
* turn radio back on - currently with both on spi bus is fucked? or are we leaving chip select asserted?
|
||||||
|
*/
|
||||||
|
class EInkDisplay : public OLEDDisplay
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/* constructor
|
||||||
|
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);
|
||||||
|
|
||||||
|
// Write the buffer to the display memory
|
||||||
|
virtual void display(void);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// the header size of the buffer used, e.g. for the SPI command header
|
||||||
|
virtual int getBufferOffset(void) { return 0; }
|
||||||
|
|
||||||
|
// Send a command to the display (low level function)
|
||||||
|
virtual void sendCommand(uint8_t com);
|
||||||
|
|
||||||
|
// Connect to the display
|
||||||
|
virtual bool connect();
|
||||||
|
};
|
|
@ -10,7 +10,8 @@
|
||||||
#include <SSD1306Wire.h>
|
#include <SSD1306Wire.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "TFT.h"
|
#include "EInkDisplay.h"
|
||||||
|
#include "TFTDisplay.h"
|
||||||
#include "TypedQueue.h"
|
#include "TypedQueue.h"
|
||||||
#include "commands.h"
|
#include "commands.h"
|
||||||
#include "concurrency/LockGuard.h"
|
#include "concurrency/LockGuard.h"
|
||||||
|
@ -48,7 +49,6 @@ class DebugInfo
|
||||||
void drawFrameSettings(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y);
|
void drawFrameSettings(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y);
|
||||||
void drawFrameWiFi(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y);
|
void drawFrameWiFi(OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y);
|
||||||
|
|
||||||
|
|
||||||
std::string channelName;
|
std::string channelName;
|
||||||
|
|
||||||
/// Protects all of internal state.
|
/// Protects all of internal state.
|
||||||
|
@ -240,6 +240,8 @@ class Screen : public concurrency::PeriodicTask
|
||||||
/** FIXME cleanup display abstraction */
|
/** FIXME cleanup display abstraction */
|
||||||
#ifdef ST7735_CS
|
#ifdef ST7735_CS
|
||||||
TFTDisplay dispdev;
|
TFTDisplay dispdev;
|
||||||
|
#elif defined(HAS_EINK)
|
||||||
|
EInkDisplay dispdev;
|
||||||
#elif defined(USE_SH1106)
|
#elif defined(USE_SH1106)
|
||||||
SH1106Wire dispdev;
|
SH1106Wire dispdev;
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
#ifdef ST7735_CS
|
#ifdef ST7735_CS
|
||||||
#include "SPILock.h"
|
#include "SPILock.h"
|
||||||
#include "TFT.h"
|
#include "TFTDisplay.h"
|
||||||
#include "graphics/configs.h"
|
#include "graphics/configs.h"
|
||||||
#include <SPI.h>
|
#include <SPI.h>
|
||||||
#include <TFT_eSPI.h> // Graphics and font library for ST7735 driver chip
|
#include <TFT_eSPI.h> // Graphics and font library for ST7735 driver chip
|
||||||
|
@ -20,7 +20,6 @@ void TFTDisplay::display(void)
|
||||||
{
|
{
|
||||||
concurrency::LockGuard g(spiLock);
|
concurrency::LockGuard g(spiLock);
|
||||||
|
|
||||||
#if 1
|
|
||||||
// FIXME - only draw bits have changed (use backbuf similar to the other displays)
|
// FIXME - only draw bits have changed (use backbuf similar to the other displays)
|
||||||
// tft.drawBitmap(0, 0, buffer, 128, 64, TFT_YELLOW, TFT_BLACK);
|
// tft.drawBitmap(0, 0, buffer, 128, 64, TFT_YELLOW, TFT_BLACK);
|
||||||
for (uint8_t y = 0; y < SCREEN_HEIGHT; y++) {
|
for (uint8_t y = 0; y < SCREEN_HEIGHT; y++) {
|
||||||
|
@ -32,7 +31,6 @@ void TFTDisplay::display(void)
|
||||||
tft.drawPixel(x, y, isset ? TFT_WHITE : TFT_BLACK);
|
tft.drawPixel(x, y, isset ? TFT_WHITE : TFT_BLACK);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send a command to the display (low level function)
|
// Send a command to the display (low level function)
|
||||||
|
@ -52,12 +50,10 @@ bool TFTDisplay::connect()
|
||||||
pinMode(ST7735_BACKLIGHT_EN, OUTPUT);
|
pinMode(ST7735_BACKLIGHT_EN, OUTPUT);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if 1
|
|
||||||
tft.init();
|
tft.init();
|
||||||
tft.setRotation(3); // Orient horizontal and wide underneath the silkscreen name label
|
tft.setRotation(3); // Orient horizontal and wide underneath the silkscreen name label
|
||||||
tft.fillScreen(TFT_BLACK);
|
tft.fillScreen(TFT_BLACK);
|
||||||
// tft.drawRect(0, 0, 40, 10, TFT_PURPLE); // wide rectangle in upper left
|
// tft.drawRect(0, 0, 40, 10, TFT_PURPLE); // wide rectangle in upper left
|
||||||
#endif
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
10
src/main.cpp
10
src/main.cpp
|
@ -213,16 +213,16 @@ void setup()
|
||||||
esp32Setup();
|
esp32Setup();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef NRF52_SERIES
|
||||||
|
nrf52Setup();
|
||||||
|
#endif
|
||||||
|
|
||||||
// Currently only the tbeam has a PMU
|
// Currently only the tbeam has a PMU
|
||||||
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 NRF52_SERIES
|
|
||||||
nrf52Setup();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Init our SPI controller (must be before screen and lora)
|
// Init our SPI controller (must be before screen and lora)
|
||||||
initSPI();
|
initSPI();
|
||||||
#ifdef NO_ESP32
|
#ifdef NO_ESP32
|
||||||
|
@ -234,7 +234,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.
|
||||||
#ifdef ST7735_CS
|
#if defined(ST7735_CS) || defined(HAS_EINK)
|
||||||
screen.setup();
|
screen.setup();
|
||||||
#else
|
#else
|
||||||
if (ssd1306_found)
|
if (ssd1306_found)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#include "NRF52Bluetooth.h"
|
#include "NRF52Bluetooth.h"
|
||||||
#include "configuration.h"
|
#include "configuration.h"
|
||||||
#include "graphics/TFT.h"
|
#include "graphics/TFTDisplay.h"
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <ble_gap.h>
|
#include <ble_gap.h>
|
||||||
#include <memory.h>
|
#include <memory.h>
|
||||||
|
@ -49,14 +49,19 @@ void getMacAddr(uint8_t *dmac)
|
||||||
NRF52Bluetooth *nrf52Bluetooth;
|
NRF52Bluetooth *nrf52Bluetooth;
|
||||||
|
|
||||||
static bool bleOn = false;
|
static bool bleOn = false;
|
||||||
|
static const bool enableBle = true; // Set to false for easier debugging
|
||||||
|
|
||||||
void setBluetoothEnable(bool on)
|
void setBluetoothEnable(bool on)
|
||||||
{
|
{
|
||||||
if (on != bleOn) {
|
if (on != bleOn) {
|
||||||
if (on) {
|
if (on) {
|
||||||
if (!nrf52Bluetooth) {
|
if (!nrf52Bluetooth) {
|
||||||
// DEBUG_MSG("DISABLING NRF52 BLUETOOTH WHILE DEBUGGING\n");
|
if (!enableBle)
|
||||||
nrf52Bluetooth = new NRF52Bluetooth();
|
DEBUG_MSG("DISABLING NRF52 BLUETOOTH WHILE DEBUGGING\n");
|
||||||
nrf52Bluetooth->setup();
|
else {
|
||||||
|
nrf52Bluetooth = new NRF52Bluetooth();
|
||||||
|
nrf52Bluetooth->setup();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
DEBUG_MSG("FIXME: implement BLE disable\n");
|
DEBUG_MSG("FIXME: implement BLE disable\n");
|
||||||
|
@ -88,6 +93,11 @@ void nrf52Setup()
|
||||||
// This is the recommended setting for Monitor Mode Debugging
|
// This is the recommended setting for Monitor Mode Debugging
|
||||||
NVIC_SetPriority(DebugMonitor_IRQn, 6UL);
|
NVIC_SetPriority(DebugMonitor_IRQn, 6UL);
|
||||||
|
|
||||||
|
#ifdef PIN_PWR_ON
|
||||||
|
digitalWrite(PIN_PWR_ON, HIGH); // If we need to assert a pin to power external peripherals
|
||||||
|
pinMode(PIN_PWR_ON, OUTPUT);
|
||||||
|
#endif
|
||||||
|
|
||||||
// Not yet on board
|
// Not yet on board
|
||||||
// pmu.init();
|
// pmu.init();
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
// dummy file to keep old arduino code happy
|
||||||
|
#define PROGMEM
|
||||||
|
#define pgm_read_byte(addr) (*((unsigned const char *)addr))
|
|
@ -0,0 +1,44 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) 2014-2015 Arduino LLC. All right reserved.
|
||||||
|
Copyright (c) 2016 Sandeep Mistry All right reserved.
|
||||||
|
Copyright (c) 2018, Adafruit Industries (adafruit.com)
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
See the GNU Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with this library; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "variant.h"
|
||||||
|
#include "nrf.h"
|
||||||
|
#include "wiring_constants.h"
|
||||||
|
#include "wiring_digital.h"
|
||||||
|
|
||||||
|
const uint32_t g_ADigitalPinMap[] = {
|
||||||
|
// P0 - pins 0 and 1 are hardwired for xtal and should never be enabled
|
||||||
|
0xff, 0xff, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
|
||||||
|
|
||||||
|
// P1
|
||||||
|
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47};
|
||||||
|
|
||||||
|
void initVariant()
|
||||||
|
{
|
||||||
|
// LED1 & LED2
|
||||||
|
pinMode(PIN_LED1, OUTPUT);
|
||||||
|
ledOff(PIN_LED1);
|
||||||
|
|
||||||
|
pinMode(PIN_LED2, OUTPUT);
|
||||||
|
ledOff(PIN_LED2);
|
||||||
|
|
||||||
|
pinMode(PIN_LED3, OUTPUT);
|
||||||
|
ledOff(PIN_LED3);
|
||||||
|
}
|
|
@ -0,0 +1,218 @@
|
||||||
|
/*
|
||||||
|
Copyright (c) 2014-2015 Arduino LLC. All right reserved.
|
||||||
|
Copyright (c) 2016 Sandeep Mistry All right reserved.
|
||||||
|
Copyright (c) 2018, Adafruit Industries (adafruit.com)
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
This library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
See the GNU Lesser General Public License for more details.
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with this library; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _VARIANT_TTGO_EINK_V1_
|
||||||
|
#define _VARIANT_TTGO_EINK_V1_
|
||||||
|
|
||||||
|
/** Master clock frequency */
|
||||||
|
#define VARIANT_MCK (64000000ul)
|
||||||
|
|
||||||
|
#define USE_LFXO // Board uses 32khz crystal for LF
|
||||||
|
|
||||||
|
/*
|
||||||
|
@geeksville eink TODO:
|
||||||
|
|
||||||
|
confirm that watchdog reset (i.e. all pins now become inputs) won't cause the board to power down when we are not connected to USB
|
||||||
|
(I bet it will). If this happens recommended fix is to add an external pullup on PWR_ON GPIO.
|
||||||
|
|
||||||
|
fix bootloader to use two buttons - remove bootloader hacks
|
||||||
|
fix battery voltage sensing
|
||||||
|
fix floating point SEGGER printf on nrf52 - see "new NMEA GPS pos"
|
||||||
|
get second button working in app load
|
||||||
|
if battery falls too low deassert PWR_ON (to force board to shutdown)
|
||||||
|
fix display width and height
|
||||||
|
clean up eink drawing to not have the nasty timeout hack
|
||||||
|
put eink to sleep when we think the screen is off
|
||||||
|
enable flash on spi0, share chip selects on spi1.
|
||||||
|
https://infocenter.nordicsemi.com/index.jsp?topic=%2Fcom.nordic.infocenter.nrf52832.ps.v1.1%2Fspi.html enable reset as a button in
|
||||||
|
bootloader fix battery pin usage drive TCXO DIO3 enable high whenever we want the clock use PIN_GPS_WAKE to sleep the GPS use
|
||||||
|
tp_ser_io as a button, it goes high when pressed unify eink display classes
|
||||||
|
make screen.adjustBrightness() a nop on eink screens
|
||||||
|
enable gps sleep mode
|
||||||
|
use new flash chip
|
||||||
|
add factory/power on self test
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------
|
||||||
|
* 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 (1)
|
||||||
|
#define NUM_ANALOG_OUTPUTS (0)
|
||||||
|
|
||||||
|
// LEDs
|
||||||
|
#define PIN_LED1 (0 + 13) // green (but red on my prototype)
|
||||||
|
#define PIN_LED2 (0 + 15) // blue (but red on my prototype)
|
||||||
|
#define PIN_LED3 (0 + 14) // red (not functional on my prototype)
|
||||||
|
|
||||||
|
#define LED_RED PIN_LED3
|
||||||
|
#define LED_GREEN PIN_LED1
|
||||||
|
#define LED_BLUE PIN_LED2
|
||||||
|
|
||||||
|
#define LED_BUILTIN LED_GREEN
|
||||||
|
#define LED_CONN PIN_BLUE
|
||||||
|
|
||||||
|
#define LED_STATE_ON 0 // State when LED is lit
|
||||||
|
#define LED_INVERTED 1
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Buttons
|
||||||
|
*/
|
||||||
|
#define PIN_BUTTON1 (32 + 10)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Analog pins
|
||||||
|
*/
|
||||||
|
#define PIN_A0 (4) // Battery ADC
|
||||||
|
|
||||||
|
#define BATTERY_PIN PIN_A0
|
||||||
|
|
||||||
|
static const uint8_t A0 = PIN_A0;
|
||||||
|
|
||||||
|
#define ADC_RESOLUTION 14
|
||||||
|
|
||||||
|
#define PIN_NFC1 (9)
|
||||||
|
#define PIN_NFC2 (10)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Serial interfaces
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
This serial port is _also_ connected to the incoming D+/D- pins from the USB header. FIXME, figure out how that is supposed to
|
||||||
|
work.
|
||||||
|
*/
|
||||||
|
#define PIN_SERIAL2_RX (0 + 6)
|
||||||
|
#define PIN_SERIAL2_TX (0 + 8)
|
||||||
|
// #define PIN_SERIAL2_EN (0 + 17)
|
||||||
|
|
||||||
|
/**
|
||||||
|
Wire Interfaces
|
||||||
|
*/
|
||||||
|
#define WIRE_INTERFACES_COUNT 1
|
||||||
|
|
||||||
|
#define PIN_WIRE_SDA (26) // Not connected on board?
|
||||||
|
#define PIN_WIRE_SCL (27)
|
||||||
|
|
||||||
|
/* touch sensor, active high */
|
||||||
|
|
||||||
|
#define TP_SER_IO (0 + 11)
|
||||||
|
|
||||||
|
// Board power is enabled either by VBUS from USB or the CPU asserting PWR_ON
|
||||||
|
#define PIN_PWR_ON (0 + 12)
|
||||||
|
|
||||||
|
#define PIN_RTC_INT (0 + 16) // Interrupt from the PCF8563 RTC
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
FIXME define/FIX flash access
|
||||||
|
|
||||||
|
// QSPI Pins
|
||||||
|
#define PIN_QSPI_SCK 19
|
||||||
|
#define PIN_QSPI_CS 17
|
||||||
|
#define PIN_QSPI_IO0 20
|
||||||
|
#define PIN_QSPI_IO1 21
|
||||||
|
#define PIN_QSPI_IO2 22
|
||||||
|
#define PIN_QSPI_IO3 23
|
||||||
|
|
||||||
|
// On-board QSPI Flash
|
||||||
|
#define EXTERNAL_FLASH_DEVICES MX25R6435F
|
||||||
|
#define EXTERNAL_FLASH_USE_QSPI
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Lora radio
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define SX1262_CS (0 + 24) // FIXME - we really should define LORA_CS instead
|
||||||
|
#define SX1262_DIO1 (0 + 20)
|
||||||
|
// Note DIO2 is attached internally to the module to an analog switch for TX/RX switching
|
||||||
|
#define SX1262_DIO3 \
|
||||||
|
(0 + 21) // This is used as an *output* from the sx1262 and connected internally to power the tcxo, do not drive from the main
|
||||||
|
// CPU?
|
||||||
|
#define SX1262_BUSY (0 + 17)
|
||||||
|
#define SX1262_RESET (0 + 25)
|
||||||
|
#define SX1262_E22 // Not really an E22 but TTGO seems to be trying to clone that
|
||||||
|
// Internally the TTGO module hooks the SX1262-DIO2 in to control the TX/RX switch (which is the default for the sx1262interface
|
||||||
|
// code)
|
||||||
|
|
||||||
|
// #define LORA_DISABLE_SENDING // Define this to disable transmission for testing (power testing etc...)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* eink display pins
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define PIN_EINK_EN (32 + 11)
|
||||||
|
#define PIN_EINK_CS (0 + 30)
|
||||||
|
#define PIN_EINK_BUSY (0 + 3)
|
||||||
|
#define PIN_EINK_DC (0 + 28)
|
||||||
|
#define PIN_EINK_RES (0 + 2)
|
||||||
|
#define PIN_EINK_SCLK (0 + 31)
|
||||||
|
#define PIN_EINK_MOSI (0 + 29) // also called SDI
|
||||||
|
|
||||||
|
#define HAS_EINK
|
||||||
|
|
||||||
|
#define PIN_SPI1_MISO \
|
||||||
|
(32 + 7) // FIXME not really needed, but for now the SPI code requires something to be defined, pick an used GPIO
|
||||||
|
#define PIN_SPI1_MOSI PIN_EINK_MOSI
|
||||||
|
#define PIN_SPI1_SCK PIN_EINK_SCLK
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Air530 GPS pins
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define PIN_GPS_WAKE (32 + 2)
|
||||||
|
#define PIN_GPS_PPS (32 + 4)
|
||||||
|
#define PIN_GPS_TX (32 + 9) // This is for bits going TOWARDS the CPU
|
||||||
|
#define PIN_GPS_RX (32 + 8) // This is for bits going TOWARDS the GPS
|
||||||
|
|
||||||
|
#define PIN_SERIAL1_RX PIN_GPS_TX
|
||||||
|
#define PIN_SERIAL1_TX PIN_GPS_RX
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SPI Interfaces
|
||||||
|
*/
|
||||||
|
#define SPI_INTERFACES_COUNT 2
|
||||||
|
|
||||||
|
// For LORA
|
||||||
|
#define PIN_SPI_MISO (0 + 23)
|
||||||
|
#define PIN_SPI_MOSI (0 + 22)
|
||||||
|
#define PIN_SPI_SCK (0 + 19)
|
||||||
|
|
||||||
|
// To debug via the segger JLINK console rather than the CDC-ACM serial device
|
||||||
|
#define USE_SEGGER
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*----------------------------------------------------------------------------
|
||||||
|
* Arduino objects - C++ only
|
||||||
|
*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#endif
|
Ładowanie…
Reference in New Issue