mirror of
https://github.com/alexhopeoconnor/firmware.git
synced 2026-10-18 17:31:42 +10:00
Merge branch 'master' into lora-type
This commit is contained in:
+90
-77
@@ -116,46 +116,55 @@ ButtonThread::ButtonThread() : OSThread("Button")
|
||||
#endif
|
||||
}
|
||||
|
||||
void ButtonThread::switchPage()
|
||||
{
|
||||
#ifdef BUTTON_PIN
|
||||
#if !defined(USERPREFS_BUTTON_PIN)
|
||||
if (((config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN) !=
|
||||
moduleConfig.canned_message.inputbroker_pin_press) ||
|
||||
!(moduleConfig.canned_message.updown1_enabled || moduleConfig.canned_message.rotary1_enabled) ||
|
||||
!moduleConfig.canned_message.enabled) {
|
||||
powerFSM.trigger(EVENT_PRESS);
|
||||
}
|
||||
#endif
|
||||
#if defined(USERPREFS_BUTTON_PIN)
|
||||
if (((config.device.button_gpio ? config.device.button_gpio : USERPREFS_BUTTON_PIN) !=
|
||||
moduleConfig.canned_message.inputbroker_pin_press) ||
|
||||
!(moduleConfig.canned_message.updown1_enabled || moduleConfig.canned_message.rotary1_enabled) ||
|
||||
!moduleConfig.canned_message.enabled) {
|
||||
powerFSM.trigger(EVENT_PRESS);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#if defined(ARCH_PORTDUINO)
|
||||
if ((settingsMap.count(user) != 0 && settingsMap[user] != RADIOLIB_NC) &&
|
||||
(settingsMap[user] != moduleConfig.canned_message.inputbroker_pin_press) ||
|
||||
!moduleConfig.canned_message.enabled) {
|
||||
powerFSM.trigger(EVENT_PRESS);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void ButtonThread::sendAdHocPosition()
|
||||
{
|
||||
service->refreshLocalMeshNode();
|
||||
auto sentPosition = service->trySendPosition(NODENUM_BROADCAST, true);
|
||||
if (screen) {
|
||||
if (sentPosition)
|
||||
screen->print("Sent ad-hoc position\n");
|
||||
else
|
||||
screen->print("Sent ad-hoc nodeinfo\n");
|
||||
screen->forceDisplay(true); // Force a new UI frame, then force an EInk update
|
||||
}
|
||||
}
|
||||
|
||||
int32_t ButtonThread::runOnce()
|
||||
{
|
||||
// If the button is pressed we suppress CPU sleep until release
|
||||
canSleep = true; // Assume we should not keep the board awake
|
||||
|
||||
#if defined(BUTTON_PIN) || defined(USERPREFS_BUTTON_PIN)
|
||||
// #if defined(ELECROW_ThinkNode_M1) || defined(ELECROW_ThinkNode_M2)
|
||||
// buzzer_updata();
|
||||
// if (buttonPressed) {
|
||||
// buttonPressed = false; // 清除标志
|
||||
// LOG_INFO("PIN_BUTTON2 pressed!"); // 串口打印信息
|
||||
// // off_currentTime = millis();
|
||||
// while (digitalRead(PIN_BUTTON2) == HIGH) {
|
||||
// if (cont < 40) {
|
||||
// // unsigned long currentTime = millis(); // 获取当前时间
|
||||
// // if (currentTime - off_currentTime >= 1000) {
|
||||
// cont++;
|
||||
// // off_currentTime = currentTime;
|
||||
// // }
|
||||
// delay(100);
|
||||
// } else {
|
||||
|
||||
// currentState = OFF;
|
||||
// isBuzzing = false;
|
||||
// cont = 0;
|
||||
// BEEP_STATE = false;
|
||||
// analogWrite(M2_buzzer, 0);
|
||||
// pinMode(M2_buzzer, INPUT);
|
||||
// screen->setOn(false);
|
||||
// cont = 0;
|
||||
// LOG_INFO("GGGGGGGGGGGGGGGGGGGGGGGGG");
|
||||
// pinMode(1, OUTPUT);
|
||||
// digitalWrite(1, LOW);
|
||||
// pinMode(6, OUTPUT);
|
||||
// digitalWrite(6, LOW);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// #endif
|
||||
userButton.tick();
|
||||
canSleep &= userButton.isIdle();
|
||||
#elif defined(ARCH_PORTDUINO)
|
||||
@@ -180,32 +189,27 @@ int32_t ButtonThread::runOnce()
|
||||
// If a nag notification is running, stop it and prevent other actions
|
||||
if (moduleConfig.external_notification.enabled && (externalNotificationModule->nagCycleCutoff != UINT32_MAX)) {
|
||||
externalNotificationModule->stopNow();
|
||||
return 50;
|
||||
}
|
||||
#ifdef BUTTON_PIN
|
||||
#if !defined(USERPREFS_BUTTON_PIN)
|
||||
if (((config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN) !=
|
||||
#endif
|
||||
#if defined(USERPREFS_BUTTON_PIN)
|
||||
if (((config.device.button_gpio ? config.device.button_gpio : USERPREFS_BUTTON_PIN) !=
|
||||
#endif
|
||||
moduleConfig.canned_message.inputbroker_pin_press) ||
|
||||
!(moduleConfig.canned_message.updown1_enabled || moduleConfig.canned_message.rotary1_enabled) ||
|
||||
!moduleConfig.canned_message.enabled) {
|
||||
powerFSM.trigger(EVENT_PRESS);
|
||||
}
|
||||
#endif
|
||||
#if defined(ARCH_PORTDUINO)
|
||||
if ((settingsMap.count(user) != 0 && settingsMap[user] != RADIOLIB_NC) &&
|
||||
(settingsMap[user] != moduleConfig.canned_message.inputbroker_pin_press) ||
|
||||
!moduleConfig.canned_message.enabled) {
|
||||
powerFSM.trigger(EVENT_PRESS);
|
||||
break;
|
||||
}
|
||||
#ifdef ELECROW_ThinkNode_M1
|
||||
sendAdHocPosition();
|
||||
break;
|
||||
#endif
|
||||
switchPage();
|
||||
break;
|
||||
}
|
||||
|
||||
case BUTTON_EVENT_PRESSED_SCREEN: {
|
||||
LOG_BUTTON("AltPress!");
|
||||
#ifdef ELECROW_ThinkNode_M1
|
||||
// If a nag notification is running, stop it and prevent other actions
|
||||
if (moduleConfig.external_notification.enabled && (externalNotificationModule->nagCycleCutoff != UINT32_MAX)) {
|
||||
externalNotificationModule->stopNow();
|
||||
break;
|
||||
}
|
||||
switchPage();
|
||||
break;
|
||||
#endif
|
||||
// turn screen on or off
|
||||
screen_flag = !screen_flag;
|
||||
if (screen)
|
||||
@@ -215,22 +219,18 @@ int32_t ButtonThread::runOnce()
|
||||
|
||||
case BUTTON_EVENT_DOUBLE_PRESSED: {
|
||||
LOG_BUTTON("Double press!");
|
||||
service->refreshLocalMeshNode();
|
||||
auto sentPosition = service->trySendPosition(NODENUM_BROADCAST, true);
|
||||
if (screen) {
|
||||
if (sentPosition)
|
||||
screen->print("Sent ad-hoc position\n");
|
||||
else
|
||||
screen->print("Sent ad-hoc nodeinfo\n");
|
||||
screen->forceDisplay(true); // Force a new UI frame, then force an EInk update
|
||||
}
|
||||
#ifdef ELECROW_ThinkNode_M1
|
||||
digitalWrite(PIN_EINK_EN, digitalRead(PIN_EINK_EN) == LOW);
|
||||
break;
|
||||
#endif
|
||||
sendAdHocPosition();
|
||||
break;
|
||||
}
|
||||
|
||||
case BUTTON_EVENT_MULTI_PRESSED: {
|
||||
LOG_BUTTON("Mulitipress! %hux", multipressClickCount);
|
||||
switch (multipressClickCount) {
|
||||
#if HAS_GPS
|
||||
#if HAS_GPS && !defined(ELECROW_ThinkNode_M1)
|
||||
// 3 clicks: toggle GPS
|
||||
case 3:
|
||||
if (!config.device.disable_triple_click && (gps != nullptr)) {
|
||||
@@ -239,23 +239,23 @@ int32_t ButtonThread::runOnce()
|
||||
screen->forceDisplay(true); // Force a new UI frame, then force an EInk update
|
||||
}
|
||||
break;
|
||||
#elif defined(ELECROW_ThinkNode_M2)
|
||||
#elif defined(ELECROW_ThinkNode_M1) || defined(ELECROW_ThinkNode_M2)
|
||||
case 3:
|
||||
LOG_INFO("3 clicks: toggle buzzer");
|
||||
buzzer_flag = !buzzer_flag;
|
||||
if (buzzer_flag) {
|
||||
playBeep();
|
||||
}
|
||||
if (!buzzer_flag)
|
||||
noTone(PIN_BUZZER);
|
||||
break;
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(USE_EINK) && defined(PIN_EINK_EN) // i.e. T-Echo
|
||||
#if defined(USE_EINK) && defined(PIN_EINK_EN) && !defined(ELECROW_ThinkNode_M1) // i.e. T-Echo
|
||||
// 4 clicks: toggle backlight
|
||||
case 4:
|
||||
digitalWrite(PIN_EINK_EN, digitalRead(PIN_EINK_EN) == LOW);
|
||||
break;
|
||||
#endif
|
||||
#if defined(RAK_4631)
|
||||
#if !MESHTASTIC_EXCLUDE_SCREEN && HAS_SCREEN
|
||||
// 5 clicks: start accelerometer/magenetometer calibration for 30 seconds
|
||||
case 5:
|
||||
if (accelerometerThread) {
|
||||
@@ -300,14 +300,23 @@ int32_t ButtonThread::runOnce()
|
||||
#ifdef BUTTON_PIN_TOUCH
|
||||
case BUTTON_EVENT_TOUCH_LONG_PRESSED: {
|
||||
LOG_BUTTON("Touch press!");
|
||||
if (screen) {
|
||||
// Wake if asleep
|
||||
if (powerFSM.getState() == &stateDARK)
|
||||
powerFSM.trigger(EVENT_PRESS);
|
||||
// Ignore if: no screen
|
||||
if (!screen)
|
||||
break;
|
||||
|
||||
// Update display (legacy behaviour)
|
||||
screen->forceDisplay();
|
||||
}
|
||||
#ifdef TTGO_T_ECHO
|
||||
// Ignore if: TX in progress
|
||||
// Uncommon T-Echo hardware bug, LoRa TX triggers touch button
|
||||
if (!RadioLibInterface::instance || RadioLibInterface::instance->isSending())
|
||||
break;
|
||||
#endif
|
||||
|
||||
// Wake if asleep
|
||||
if (powerFSM.getState() == &stateDARK)
|
||||
powerFSM.trigger(EVENT_PRESS);
|
||||
|
||||
// Update display (legacy behaviour)
|
||||
screen->forceDisplay();
|
||||
break;
|
||||
}
|
||||
#endif // BUTTON_PIN_TOUCH
|
||||
@@ -349,8 +358,12 @@ void ButtonThread::attachButtonInterrupts()
|
||||
#endif
|
||||
|
||||
#ifdef BUTTON_PIN_ALT
|
||||
#ifdef ELECROW_ThinkNode_M2
|
||||
wakeOnIrq(BUTTON_PIN_ALT, RISING);
|
||||
#else
|
||||
wakeOnIrq(BUTTON_PIN_ALT, FALLING);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef BUTTON_PIN_TOUCH
|
||||
wakeOnIrq(BUTTON_PIN_TOUCH, FALLING);
|
||||
|
||||
+7
-6
@@ -37,6 +37,9 @@ class ButtonThread : public concurrency::OSThread
|
||||
void attachButtonInterrupts();
|
||||
void detachButtonInterrupts();
|
||||
void storeClickCount();
|
||||
bool isBuzzing() { return buzzer_flag; }
|
||||
void setScreenFlag(bool flag) { screen_flag = flag; }
|
||||
bool getScreenFlag() { return screen_flag; }
|
||||
|
||||
// Disconnect and reconnect interrupts for light sleep
|
||||
#ifdef ARCH_ESP32
|
||||
@@ -72,14 +75,12 @@ class ButtonThread : public concurrency::OSThread
|
||||
|
||||
static void wakeOnIrq(int irq, int mode);
|
||||
|
||||
static void sendAdHocPosition();
|
||||
static void switchPage();
|
||||
|
||||
// IRQ callbacks
|
||||
static void userButtonPressed() { btnEvent = BUTTON_EVENT_PRESSED; }
|
||||
static void userButtonPressedScreen()
|
||||
{
|
||||
if (millis() > c_holdOffTime) {
|
||||
btnEvent = BUTTON_EVENT_PRESSED_SCREEN;
|
||||
}
|
||||
}
|
||||
static void userButtonPressedScreen() { btnEvent = BUTTON_EVENT_PRESSED_SCREEN; }
|
||||
static void userButtonDoublePressed() { btnEvent = BUTTON_EVENT_DOUBLE_PRESSED; }
|
||||
static void userButtonMultiPressed(void *callerThread); // Retrieve click count from non-static Onebutton while still valid
|
||||
static void userButtonPressedLongStart();
|
||||
|
||||
+5
-4
@@ -12,13 +12,14 @@
|
||||
#include "SPILock.h"
|
||||
#include "configuration.h"
|
||||
|
||||
#ifdef HAS_SDCARD
|
||||
// Software SPI is used by MUI so disable SD card here until it's also implemented
|
||||
#if defined(HAS_SDCARD) && !defined(SDCARD_USE_SOFT_SPI)
|
||||
#include <SD.h>
|
||||
#include <SPI.h>
|
||||
|
||||
#ifdef SDCARD_USE_SPI1
|
||||
SPIClass SPI1(HSPI);
|
||||
#define SDHandler SPI1
|
||||
SPIClass SPI_HSPI(HSPI);
|
||||
#define SDHandler SPI_HSPI
|
||||
#else
|
||||
#define SDHandler SPI
|
||||
#endif
|
||||
@@ -306,7 +307,7 @@ void fsInit()
|
||||
*/
|
||||
void setupSDCard()
|
||||
{
|
||||
#ifdef HAS_SDCARD
|
||||
#if defined(HAS_SDCARD) && !defined(SDCARD_USE_SOFT_SPI)
|
||||
concurrency::LockGuard g(spiLock);
|
||||
SDHandler.begin(SPI_SCK, SPI_MISO, SPI_MOSI);
|
||||
if (!SD.begin(SDCARD_CS, SDHandler, SD_SPI_FREQUENCY)) {
|
||||
|
||||
+52
-30
@@ -76,23 +76,47 @@ static const uint8_t ext_chrg_detect_value = EXT_CHRG_DETECT_VALUE;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if HAS_TELEMETRY && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR && !defined(ARCH_PORTDUINO)
|
||||
#if HAS_TELEMETRY && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
|
||||
#if __has_include(<Adafruit_INA219.h>)
|
||||
INA219Sensor ina219Sensor;
|
||||
INA226Sensor ina226Sensor;
|
||||
INA260Sensor ina260Sensor;
|
||||
INA3221Sensor ina3221Sensor;
|
||||
#else
|
||||
NullSensor ina219Sensor;
|
||||
#endif
|
||||
|
||||
#if !MESHTASTIC_EXCLUDE_I2C && !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL)
|
||||
#if __has_include(<INA226.h>)
|
||||
INA226Sensor ina226Sensor;
|
||||
#else
|
||||
NullSensor ina226Sensor;
|
||||
#endif
|
||||
|
||||
#if __has_include(<Adafruit_INA260.h>)
|
||||
INA260Sensor ina260Sensor;
|
||||
#else
|
||||
NullSensor ina260Sensor;
|
||||
#endif
|
||||
|
||||
#if __has_include(<INA3221.h>)
|
||||
INA3221Sensor ina3221Sensor;
|
||||
#else
|
||||
NullSensor ina3221Sensor;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#if !MESHTASTIC_EXCLUDE_I2C && !defined(ARCH_STM32WL)
|
||||
#include "modules/Telemetry/Sensor/MAX17048Sensor.h"
|
||||
#include <utility>
|
||||
extern std::pair<uint8_t, TwoWire *> nodeTelemetrySensorsMap[_meshtastic_TelemetrySensorType_MAX + 1];
|
||||
#if HAS_TELEMETRY && (!MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR || !MESHTASTIC_EXCLUDE_POWER_TELEMETRY)
|
||||
#if __has_include(<Adafruit_MAX1704X.h>)
|
||||
MAX17048Sensor max17048Sensor;
|
||||
#else
|
||||
NullSensor max17048Sensor;
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if HAS_TELEMETRY && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR && HAS_RAKPROT && !defined(ARCH_PORTDUINO)
|
||||
#if HAS_TELEMETRY && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR && HAS_RAKPROT
|
||||
RAK9154Sensor rak9154Sensor;
|
||||
#endif
|
||||
|
||||
@@ -203,7 +227,7 @@ class AnalogBatteryLevel : public HasBatteryLevel
|
||||
*/
|
||||
virtual int getBatteryPercent() override
|
||||
{
|
||||
#if defined(HAS_RAKPROT) && !defined(ARCH_PORTDUINO) && !defined(HAS_PMU)
|
||||
#if defined(HAS_RAKPROT) && !defined(HAS_PMU)
|
||||
if (hasRAK()) {
|
||||
return rak9154Sensor.getBusBatteryPercent();
|
||||
}
|
||||
@@ -248,15 +272,13 @@ class AnalogBatteryLevel : public HasBatteryLevel
|
||||
virtual uint16_t getBattVoltage() override
|
||||
{
|
||||
|
||||
#if HAS_TELEMETRY && defined(HAS_RAKPROT) && !defined(ARCH_PORTDUINO) && !defined(HAS_PMU) && \
|
||||
!MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
|
||||
#if HAS_TELEMETRY && defined(HAS_RAKPROT) && !defined(HAS_PMU) && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
|
||||
if (hasRAK()) {
|
||||
return getRAKVoltage();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if HAS_TELEMETRY && !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !defined(HAS_PMU) && \
|
||||
!MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
|
||||
#if HAS_TELEMETRY && !defined(ARCH_STM32WL) && !defined(HAS_PMU) && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR
|
||||
if (hasINA()) {
|
||||
return getINAVoltage();
|
||||
}
|
||||
@@ -380,6 +402,20 @@ class AnalogBatteryLevel : public HasBatteryLevel
|
||||
// if we have a integrated device with a battery, we can assume that the battery is always connected
|
||||
#ifdef BATTERY_IMMUTABLE
|
||||
virtual bool isBatteryConnect() override { return true; }
|
||||
#elif defined(ADC_V)
|
||||
virtual bool isBatteryConnect() override
|
||||
{
|
||||
int lastReading = digitalRead(ADC_V);
|
||||
// 判断值是否变化
|
||||
for (int i = 2; i < 500; i++) {
|
||||
int reading = digitalRead(ADC_V);
|
||||
if (reading != lastReading) {
|
||||
return false; // 有变化,USB供电, 没接电池
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
#else
|
||||
virtual bool isBatteryConnect() override { return getBatteryPercent() != -1; }
|
||||
#endif
|
||||
@@ -412,8 +448,7 @@ class AnalogBatteryLevel : public HasBatteryLevel
|
||||
/// we can't be smart enough to say 'full'?
|
||||
virtual bool isCharging() override
|
||||
{
|
||||
#if HAS_TELEMETRY && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR && defined(HAS_RAKPROT) && !defined(ARCH_PORTDUINO) && \
|
||||
!defined(HAS_PMU)
|
||||
#if HAS_TELEMETRY && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR && defined(HAS_RAKPROT) && !defined(HAS_PMU)
|
||||
if (hasRAK()) {
|
||||
return (rak9154Sensor.isCharging()) ? OptTrue : OptFalse;
|
||||
}
|
||||
@@ -421,7 +456,7 @@ class AnalogBatteryLevel : public HasBatteryLevel
|
||||
#ifdef EXT_CHRG_DETECT
|
||||
return digitalRead(EXT_CHRG_DETECT) == ext_chrg_detect_value;
|
||||
#else
|
||||
#if HAS_TELEMETRY && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR && !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && \
|
||||
#if HAS_TELEMETRY && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR && !defined(ARCH_STM32WL) && \
|
||||
!defined(DISABLE_INA_CHARGING_DETECTION)
|
||||
if (hasINA()) {
|
||||
// get current flow from INA sensor - negative value means power flowing into the battery
|
||||
@@ -436,6 +471,8 @@ class AnalogBatteryLevel : public HasBatteryLevel
|
||||
return isBatteryConnect() && isVbusIn();
|
||||
#endif
|
||||
#endif
|
||||
// by default, we check the battery voltage only
|
||||
return isVbusIn();
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -466,7 +503,7 @@ class AnalogBatteryLevel : public HasBatteryLevel
|
||||
}
|
||||
#endif
|
||||
|
||||
#if HAS_TELEMETRY && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR && !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL)
|
||||
#if HAS_TELEMETRY && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR && !defined(ARCH_STM32WL)
|
||||
uint16_t getINAVoltage()
|
||||
{
|
||||
if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_INA219].first == config.power.device_battery_ina_address) {
|
||||
@@ -533,9 +570,6 @@ Power::Power() : OSThread("Power")
|
||||
{
|
||||
statusHandler = {};
|
||||
low_voltage_counter = 0;
|
||||
#if defined(ELECROW_ThinkNode_M1) || defined(POWER_CFG)
|
||||
low_voltage_counter_led3 = 0;
|
||||
#endif
|
||||
#ifdef DEBUG_HEAP
|
||||
lastheap = memGet.getFreeHeap();
|
||||
#endif
|
||||
@@ -716,9 +750,6 @@ void Power::readPowerStatus()
|
||||
const PowerStatus powerStatus2 = PowerStatus(hasBattery, usbPowered, isChargingNow, batteryVoltageMv, batteryChargePercent);
|
||||
LOG_DEBUG("Battery: usbPower=%d, isCharging=%d, batMv=%d, batPct=%d", powerStatus2.getHasUSB(), powerStatus2.getIsCharging(),
|
||||
powerStatus2.getBatteryVoltageMv(), powerStatus2.getBatteryChargePercent());
|
||||
#if defined(ELECROW_ThinkNode_M1) || defined(POWER_CFG)
|
||||
power_num = powerStatus2.getBatteryVoltageMv();
|
||||
#endif
|
||||
newStatus.notifyObservers(&powerStatus2);
|
||||
#ifdef DEBUG_HEAP
|
||||
if (lastheap != memGet.getFreeHeap()) {
|
||||
@@ -766,9 +797,6 @@ void Power::readPowerStatus()
|
||||
if (batteryLevel && powerStatus2.getHasBattery() && !powerStatus2.getHasUSB()) {
|
||||
if (batteryLevel->getBattVoltage() < OCV[NUM_OCV_POINTS - 1]) {
|
||||
low_voltage_counter++;
|
||||
#if defined(ELECROW_ThinkNode_M1)
|
||||
low_voltage_counter_led3 = low_voltage_counter;
|
||||
#endif
|
||||
LOG_DEBUG("Low voltage counter: %d/10", low_voltage_counter);
|
||||
if (low_voltage_counter > 10) {
|
||||
#ifdef ARCH_NRF52
|
||||
@@ -781,13 +809,7 @@ void Power::readPowerStatus()
|
||||
}
|
||||
} else {
|
||||
low_voltage_counter = 0;
|
||||
#if defined(ELECROW_ThinkNode_M1)
|
||||
low_voltage_counter_led3 = low_voltage_counter;
|
||||
#endif
|
||||
}
|
||||
#ifdef POWER_CFG
|
||||
low_voltage_counter_led3 = low_voltage_counter;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+11
-6
@@ -19,7 +19,7 @@
|
||||
#include "sleep.h"
|
||||
#include "target_specific.h"
|
||||
|
||||
#if HAS_WIFI && !defined(ARCH_PORTDUINO)
|
||||
#if HAS_WIFI && !defined(ARCH_PORTDUINO) || defined(MESHTASTIC_EXCLUDE_WIFI)
|
||||
#include "mesh/wifi/WiFiAPClient.h"
|
||||
#endif
|
||||
|
||||
@@ -269,9 +269,6 @@ Fsm powerFSM(&stateBOOT);
|
||||
void PowerFSM_setup()
|
||||
{
|
||||
bool isRouter = (config.device.role == meshtastic_Config_DeviceConfig_Role_ROUTER ? 1 : 0);
|
||||
bool isTrackerOrSensor = config.device.role == meshtastic_Config_DeviceConfig_Role_TRACKER ||
|
||||
config.device.role == meshtastic_Config_DeviceConfig_Role_TAK_TRACKER ||
|
||||
config.device.role == meshtastic_Config_DeviceConfig_Role_SENSOR;
|
||||
bool hasPower = isPowered();
|
||||
|
||||
LOG_INFO("PowerFSM init, USB power=%d", hasPower ? 1 : 0);
|
||||
@@ -383,6 +380,12 @@ void PowerFSM_setup()
|
||||
// See: https://github.com/meshtastic/firmware/issues/1071
|
||||
// Don't add power saving transitions if we are a power saving tracker or sensor or have Wifi enabled. Sleep will be initiated
|
||||
// through the modules
|
||||
|
||||
#if HAS_WIFI || !defined(MESHTASTIC_EXCLUDE_WIFI)
|
||||
bool isTrackerOrSensor = config.device.role == meshtastic_Config_DeviceConfig_Role_TRACKER ||
|
||||
config.device.role == meshtastic_Config_DeviceConfig_Role_TAK_TRACKER ||
|
||||
config.device.role == meshtastic_Config_DeviceConfig_Role_SENSOR;
|
||||
|
||||
if ((isRouter || config.power.is_power_saving) && !isWifiAvailable() && !isTrackerOrSensor) {
|
||||
powerFSM.add_timed_transition(&stateNB, &stateLS,
|
||||
Default::getConfiguredOrDefaultMs(config.power.min_wake_secs, default_min_wake_secs), NULL,
|
||||
@@ -400,7 +403,9 @@ void PowerFSM_setup()
|
||||
Default::getConfiguredOrDefaultMs(config.display.screen_on_secs, default_screen_on_secs),
|
||||
NULL, "Screen-on timeout");
|
||||
}
|
||||
#else
|
||||
#endif // HAS_WIFI || !defined(MESHTASTIC_EXCLUDE_WIFI)
|
||||
|
||||
#else // (not) ARCH_ESP32
|
||||
// If not ESP32, light-sleep not used. Check periodically if config has drifted out of stateDark
|
||||
powerFSM.add_timed_transition(&stateDARK, &stateDARK,
|
||||
Default::getConfiguredOrDefaultMs(config.display.screen_on_secs, default_screen_on_secs), NULL,
|
||||
@@ -409,4 +414,4 @@ void PowerFSM_setup()
|
||||
|
||||
powerFSM.run_machine(); // run one iteration of the state machine, so we run our on enter tasks for the initial DARK state
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
+10
-5
@@ -80,10 +80,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
// Override user saved region, for producing region-locked builds
|
||||
// #define REGULATORY_LORA_REGIONCODE meshtastic_Config_LoRaConfig_RegionCode_SG_923
|
||||
|
||||
// Total system gain in dBm to subtract from Tx power to remain within regulatory ERP limit for non-licensed operators
|
||||
// This value should be set in variant.h and is PA gain + antenna gain (if system ships with an antenna)
|
||||
#ifndef REGULATORY_GAIN_LORA
|
||||
#define REGULATORY_GAIN_LORA 0
|
||||
// Total system gain in dBm to subtract from Tx power to remain within regulatory and Tx PA limits
|
||||
// This value should be set in variant.h and is PA gain + antenna gain (if variant has a non-removable antenna)
|
||||
#ifndef TX_GAIN_LORA
|
||||
#define TX_GAIN_LORA 0
|
||||
#endif
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
@@ -99,8 +99,12 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
// -----------------------------------------------------------------------------
|
||||
// OLED & Input
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
#if defined(SEEED_WIO_TRACKER_L1)
|
||||
#define SSD1306_ADDRESS 0x3D
|
||||
#define USE_SH1106
|
||||
#else
|
||||
#define SSD1306_ADDRESS 0x3C
|
||||
#endif
|
||||
#define ST7567_ADDRESS 0x3F
|
||||
|
||||
// The SH1106 controller is almost, but not quite, the same as SSD1306
|
||||
@@ -153,6 +157,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#define CGRADSENS_ADDR 0x66
|
||||
#define LTR390UV_ADDR 0x53
|
||||
#define XPOWERS_AXP192_AXP2101_ADDRESS 0x34 // same adress as TCA8418
|
||||
#define PCT2075_ADDR 0x37
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// ACCELEROMETER
|
||||
|
||||
@@ -71,6 +71,7 @@ class ScanI2C
|
||||
DPS310,
|
||||
LTR390UV,
|
||||
TCA8418KB,
|
||||
PCT2075,
|
||||
} DeviceType;
|
||||
|
||||
// typedef uint8_t DeviceAddress;
|
||||
|
||||
@@ -434,6 +434,7 @@ void ScanI2CTwoWire::scanPort(I2CPort port, uint8_t *address, uint8_t asize)
|
||||
SCAN_SIMPLE_CASE(MAX1704X_ADDR, MAX17048, "MAX17048", (uint8_t)addr.address);
|
||||
SCAN_SIMPLE_CASE(DFROBOT_RAIN_ADDR, DFROBOT_RAIN, "DFRobot Rain Gauge", (uint8_t)addr.address);
|
||||
SCAN_SIMPLE_CASE(LTR390UV_ADDR, LTR390UV, "LTR390UV", (uint8_t)addr.address);
|
||||
SCAN_SIMPLE_CASE(PCT2075_ADDR, PCT2075, "PCT2075", (uint8_t)addr.address);
|
||||
#ifdef HAS_TPS65233
|
||||
SCAN_SIMPLE_CASE(TPS65233_ADDR, TPS65233, "TPS65233", (uint8_t)addr.address);
|
||||
#endif
|
||||
|
||||
+64
-11
@@ -12,6 +12,7 @@
|
||||
#include "RTC.h"
|
||||
#include "Throttle.h"
|
||||
#include "buzz.h"
|
||||
#include "concurrency/Periodic.h"
|
||||
#include "meshUtils.h"
|
||||
|
||||
#include "main.h" // pmu_found
|
||||
@@ -89,6 +90,45 @@ static const char *getGPSPowerStateString(GPSPowerState state)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef PIN_GPS_SWITCH
|
||||
// If we have a hardware switch, define a periodic watcher outside of the GPS runOnce thread, since this can be sleeping
|
||||
// idefinitely
|
||||
|
||||
int lastState = LOW;
|
||||
bool firstrun = true;
|
||||
|
||||
static int32_t gpsSwitch()
|
||||
{
|
||||
if (gps) {
|
||||
int currentState = digitalRead(PIN_GPS_SWITCH);
|
||||
|
||||
// if the switch is set to zero, disable the GPS Thread
|
||||
if (firstrun)
|
||||
if (currentState == LOW)
|
||||
lastState = HIGH;
|
||||
|
||||
if (currentState != lastState) {
|
||||
if (currentState == LOW) {
|
||||
config.position.gps_mode = meshtastic_Config_PositionConfig_GpsMode_DISABLED;
|
||||
if (!firstrun)
|
||||
playGPSDisableBeep();
|
||||
gps->disable();
|
||||
} else {
|
||||
config.position.gps_mode = meshtastic_Config_PositionConfig_GpsMode_ENABLED;
|
||||
if (!firstrun)
|
||||
playGPSEnableBeep();
|
||||
gps->enable();
|
||||
}
|
||||
lastState = currentState;
|
||||
}
|
||||
firstrun = false;
|
||||
}
|
||||
return 1000;
|
||||
}
|
||||
|
||||
static concurrency::Periodic *gpsPeriodic;
|
||||
#endif
|
||||
|
||||
static void UBXChecksum(uint8_t *message, size_t length)
|
||||
{
|
||||
uint8_t CK_A = 0, CK_B = 0;
|
||||
@@ -530,6 +570,19 @@ bool GPS::setup()
|
||||
// Switch to Fitness Mode, for running and walking purpose with low speed (<5 m/s)
|
||||
_serial_gps->write("$PMTK886,1*29\r\n");
|
||||
delay(250);
|
||||
} else if (gnssModel == GNSS_MODEL_MTK_PA1010D) {
|
||||
// PA1010D is used in the Pimoroni GPS board.
|
||||
|
||||
// Enable all constellations.
|
||||
_serial_gps->write("$PMTK353,1,1,1,1,1*2A\r\n");
|
||||
// Above command will reset the GPS and takes longer before it will accept new commands
|
||||
delay(1000);
|
||||
// Only ask for RMC and GGA (GNRMC and GNGGA)
|
||||
_serial_gps->write("$PMTK314,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*28\r\n");
|
||||
delay(250);
|
||||
// Enable SBAS / WAAS
|
||||
_serial_gps->write("$PMTK301,2*2E\r\n");
|
||||
delay(250);
|
||||
} else if (gnssModel == GNSS_MODEL_MTK_PA1616S) {
|
||||
// PA1616S is used in some GPS breakout boards from Adafruit
|
||||
// PA1616S does not have GLONASS capability. PA1616D does, but is not implemented here.
|
||||
@@ -770,13 +823,6 @@ void GPS::setPowerState(GPSPowerState newState, uint32_t sleepTime)
|
||||
powerState = newState;
|
||||
LOG_INFO("GPS power state move from %s to %s", getGPSPowerStateString(oldState), getGPSPowerStateString(newState));
|
||||
|
||||
#ifdef HELTEC_MESH_NODE_T114
|
||||
if ((oldState == GPS_OFF || oldState == GPS_HARDSLEEP) && (newState != GPS_OFF && newState != GPS_HARDSLEEP)) {
|
||||
_serial_gps->begin(serialSpeeds[speedSelect]);
|
||||
} else if ((newState == GPS_OFF || newState == GPS_HARDSLEEP) && (oldState != GPS_OFF && oldState != GPS_HARDSLEEP)) {
|
||||
_serial_gps->end();
|
||||
}
|
||||
#endif
|
||||
switch (newState) {
|
||||
case GPS_ACTIVE:
|
||||
case GPS_IDLE:
|
||||
@@ -1204,10 +1250,11 @@ GnssModel_t GPS::probe(int serialSpeed)
|
||||
// Close all NMEA sentences, valid for MTK3333 and MTK3339 platforms
|
||||
_serial_gps->write("$PMTK514,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*2E\r\n");
|
||||
delay(20);
|
||||
std::vector<ChipInfo> mtk = {{"L76B", "Quectel-L76B", GNSS_MODEL_MTK_L76B},
|
||||
{"PA1616S", "1616S", GNSS_MODEL_MTK_PA1616S},
|
||||
{"LS20031", "MC-1513", GNSS_MODEL_MTK_L76B},
|
||||
{"L96", "Quectel-L96", GNSS_MODEL_MTK_L76B}};
|
||||
std::vector<ChipInfo> mtk = {{"L76B", "Quectel-L76B", GNSS_MODEL_MTK_L76B}, {"PA1010D", "1010D", GNSS_MODEL_MTK_PA1010D},
|
||||
{"PA1616S", "1616S", GNSS_MODEL_MTK_PA1616S}, {"LS20031", "MC-1513", GNSS_MODEL_MTK_L76B},
|
||||
{"L96", "Quectel-L96", GNSS_MODEL_MTK_L76B}, {"L80-R", "_3337_", GNSS_MODEL_MTK_L76B},
|
||||
{"L80", "_3339_", GNSS_MODEL_MTK_L76B}};
|
||||
|
||||
PROBE_FAMILY("MTK Family", "$PMTK605*31", mtk, 500);
|
||||
|
||||
uint8_t cfg_rate[] = {0xB5, 0x62, 0x06, 0x08, 0x00, 0x00, 0x00, 0x00};
|
||||
@@ -1390,6 +1437,12 @@ GPS *GPS::createGps()
|
||||
pinMode(PIN_GPS_PPS, INPUT);
|
||||
#endif
|
||||
|
||||
#ifdef PIN_GPS_SWITCH
|
||||
// toggle GPS via external GPIO switch
|
||||
pinMode(PIN_GPS_SWITCH, INPUT);
|
||||
gpsPeriodic = new concurrency::Periodic("GPSSwitch", gpsSwitch);
|
||||
#endif
|
||||
|
||||
// Currently disabled per issue #525 (TinyGPS++ crash bug)
|
||||
// when fixed upstream, can be un-disabled to enable 3D FixType and PDOP
|
||||
#ifndef TINYGPS_OPTION_NO_CUSTOM_FIELDS
|
||||
|
||||
@@ -27,6 +27,7 @@ typedef enum {
|
||||
GNSS_MODEL_UC6580,
|
||||
GNSS_MODEL_UNKNOWN,
|
||||
GNSS_MODEL_MTK_L76B,
|
||||
GNSS_MODEL_MTK_PA1010D,
|
||||
GNSS_MODEL_MTK_PA1616S,
|
||||
GNSS_MODEL_AG3335,
|
||||
GNSS_MODEL_AG3352,
|
||||
|
||||
+3
-3
@@ -224,7 +224,7 @@ static const uint8_t _message_GSA[] = {
|
||||
0x00, // Rate for DDC
|
||||
0x00, // Rate for UART1
|
||||
0x00, // Rate for UART2
|
||||
0x00, // Rate for USB usefull for native linux
|
||||
0x00, // Rate for USB useful for native linux
|
||||
0x00, // Rate for SPI
|
||||
0x00 // Reserved
|
||||
};
|
||||
@@ -258,7 +258,7 @@ static const uint8_t _message_RMC[] = {
|
||||
0x00, // Rate for DDC
|
||||
0x01, // Rate for UART1
|
||||
0x00, // Rate for UART2
|
||||
0x01, // Rate for USB usefull for native linux
|
||||
0x01, // Rate for USB useful for native linux
|
||||
0x00, // Rate for SPI
|
||||
0x00 // Reserved
|
||||
};
|
||||
@@ -269,7 +269,7 @@ static const uint8_t _message_GGA[] = {
|
||||
0x00, // Rate for DDC
|
||||
0x01, // Rate for UART1
|
||||
0x00, // Rate for UART2
|
||||
0x01, // Rate for USB, usefull for native linux
|
||||
0x01, // Rate for USB, useful for native linux
|
||||
0x00, // Rate for SPI
|
||||
0x00 // Reserved
|
||||
};
|
||||
|
||||
@@ -182,7 +182,6 @@ bool EInkDisplay::connect()
|
||||
// Start HSPI
|
||||
hspi = new SPIClass(HSPI);
|
||||
hspi->begin(PIN_EINK_SCLK, -1, PIN_EINK_MOSI, PIN_EINK_CS); // SCLK, MISO, MOSI, SS
|
||||
|
||||
// VExt already enabled in setup()
|
||||
// RTC GPIO hold disabled in setup()
|
||||
|
||||
@@ -225,6 +224,21 @@ bool EInkDisplay::connect()
|
||||
adafruitDisplay->setRotation(1);
|
||||
adafruitDisplay->setPartialWindow(0, 0, EINK_WIDTH, EINK_HEIGHT);
|
||||
}
|
||||
#elif defined(HELTEC_MESH_POCKET)
|
||||
{
|
||||
spi1 = &SPI1;
|
||||
spi1->begin();
|
||||
// VExt already enabled in setup()
|
||||
// RTC GPIO hold disabled in setup()
|
||||
|
||||
// Create GxEPD2 objects
|
||||
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);
|
||||
|
||||
// Init GxEPD2
|
||||
adafruitDisplay->init();
|
||||
adafruitDisplay->setRotation(3);
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
|
||||
@@ -73,6 +73,10 @@ class EInkDisplay : public OLEDDisplay
|
||||
SPIClass *hspi = NULL;
|
||||
#endif
|
||||
|
||||
#if defined(HELTEC_MESH_POCKET)
|
||||
SPIClass *spi1 = NULL;
|
||||
#endif
|
||||
|
||||
private:
|
||||
// FIXME quick hack to limit drawing to a very slow rate
|
||||
uint32_t lastDrawMsec = 0;
|
||||
|
||||
+21
-10
@@ -30,6 +30,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#if !MESHTASTIC_EXCLUDE_GPS
|
||||
#include "GPS.h"
|
||||
#endif
|
||||
#include "ButtonThread.h"
|
||||
#include "MeshService.h"
|
||||
#include "NodeDB.h"
|
||||
#include "error.h"
|
||||
@@ -1103,7 +1104,7 @@ static void drawNodes(OLEDDisplay *display, int16_t x, int16_t y, const NodeStat
|
||||
char usersString[20];
|
||||
snprintf(usersString, sizeof(usersString), "%d/%d", nodeStatus->getNumOnline(), nodeStatus->getNumTotal());
|
||||
#if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ILI9342_DRIVER) || defined(ST7701_CS) || defined(ST7735_CS) || \
|
||||
defined(ST7789_CS) || defined(USE_ST7789) || defined(HX8357_CS)) && \
|
||||
defined(ST7789_CS) || defined(USE_ST7789) || defined(ILI9488_CS) || defined(HX8357_CS)) && \
|
||||
!defined(DISPLAY_FORCE_SMALL_FONTS)
|
||||
display->drawFastImage(x, y + 3, 8, 8, imgUser);
|
||||
#else
|
||||
@@ -1544,7 +1545,7 @@ Screen::Screen(ScanI2C::DeviceAddress address, meshtastic_Config_DisplayConfig_O
|
||||
dispdev = new SSD1306Wire(address.address, -1, -1, geometry,
|
||||
(address.port == ScanI2C::I2CPort::WIRE1) ? HW_I2C::I2C_TWO : HW_I2C::I2C_ONE);
|
||||
#elif defined(ST7735_CS) || defined(ILI9341_DRIVER) || defined(ILI9342_DRIVER) || defined(ST7701_CS) || defined(ST7789_CS) || \
|
||||
defined(RAK14014) || defined(HX8357_CS)
|
||||
defined(RAK14014) || defined(HX8357_CS) || defined(ILI9488_CS)
|
||||
dispdev = new TFTDisplay(address.address, -1, -1, geometry,
|
||||
(address.port == ScanI2C::I2CPort::WIRE1) ? HW_I2C::I2C_TWO : HW_I2C::I2C_ONE);
|
||||
#elif defined(USE_EINK) && !defined(USE_EINK_DYNAMICDISPLAY)
|
||||
@@ -1606,10 +1607,14 @@ void Screen::handleSetOn(bool on, FrameCallback einkScreensaver)
|
||||
if (on != screenOn) {
|
||||
if (on) {
|
||||
LOG_INFO("Turn on screen");
|
||||
buttonThread->setScreenFlag(true);
|
||||
powerMon->setState(meshtastic_PowerMon_State_Screen_On);
|
||||
#ifdef T_WATCH_S3
|
||||
PMU->enablePowerOutput(XPOWERS_ALDO2);
|
||||
#endif
|
||||
#ifdef HELTEC_TRACKER_V1_X
|
||||
uint8_t tft_vext_enabled = digitalRead(VEXT_ENABLE);
|
||||
#endif
|
||||
#if !ARCH_PORTDUINO
|
||||
dispdev->displayOn();
|
||||
#endif
|
||||
@@ -1620,6 +1625,12 @@ void Screen::handleSetOn(bool on, FrameCallback einkScreensaver)
|
||||
#endif
|
||||
|
||||
dispdev->displayOn();
|
||||
#ifdef HELTEC_TRACKER_V1_X
|
||||
// If the TFT VEXT power is not enabled, initialize the UI.
|
||||
if (!tft_vext_enabled) {
|
||||
ui->init();
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_ST7789
|
||||
pinMode(VTFT_CTRL, OUTPUT);
|
||||
digitalWrite(VTFT_CTRL, LOW);
|
||||
@@ -1641,6 +1652,7 @@ void Screen::handleSetOn(bool on, FrameCallback einkScreensaver)
|
||||
setScreensaverFrames(einkScreensaver);
|
||||
#endif
|
||||
LOG_INFO("Turn off screen");
|
||||
buttonThread->setScreenFlag(false);
|
||||
#ifdef ELECROW_ThinkNode_M1
|
||||
if (digitalRead(PIN_EINK_EN) == HIGH) {
|
||||
digitalWrite(PIN_EINK_EN, LOW);
|
||||
@@ -1748,7 +1760,7 @@ void Screen::setup()
|
||||
// flip it. If you have a headache now, you're welcome.
|
||||
if (!config.display.flip_screen) {
|
||||
#if defined(ST7701_CS) || defined(ST7735_CS) || defined(ILI9341_DRIVER) || defined(ILI9342_DRIVER) || defined(ST7701_CS) || \
|
||||
defined(ST7789_CS) || defined(RAK14014) || defined(HX8357_CS)
|
||||
defined(ST7789_CS) || defined(RAK14014) || defined(HX8357_CS) || defined(ILI9488_CS)
|
||||
static_cast<TFTDisplay *>(dispdev)->flipScreenVertically();
|
||||
#elif defined(USE_ST7789)
|
||||
static_cast<ST7789Spi *>(dispdev)->flipScreenVertically();
|
||||
@@ -1793,7 +1805,9 @@ void Screen::setup()
|
||||
powerStatusObserver.observe(&powerStatus->onNewStatus);
|
||||
gpsStatusObserver.observe(&gpsStatus->onNewStatus);
|
||||
nodeStatusObserver.observe(&nodeStatus->onNewStatus);
|
||||
#if !MESHTASTIC_EXCLUDE_ADMIN
|
||||
adminMessageObserver.observe(adminModule);
|
||||
#endif
|
||||
if (textMessageModule)
|
||||
textMessageObserver.observe(textMessageModule);
|
||||
if (inputBroker)
|
||||
@@ -2487,7 +2501,7 @@ void DebugInfo::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16
|
||||
if (!Throttle::isWithinTimespanMs(storeForwardModule->lastHeartbeat,
|
||||
(storeForwardModule->heartbeatInterval * 1200))) { // no heartbeat, overlap a bit
|
||||
#if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ILI9342_DRIVER) || defined(ST7701_CS) || defined(ST7735_CS) || \
|
||||
defined(ST7789_CS) || defined(USE_ST7789) || defined(HX8357_CS) || ARCH_PORTDUINO) && \
|
||||
defined(ST7789_CS) || defined(USE_ST7789) || defined(HX8357_CS) || defined(ILI9488_CS) || ARCH_PORTDUINO) && \
|
||||
!defined(DISPLAY_FORCE_SMALL_FONTS)
|
||||
display->drawFastImage(x + SCREEN_WIDTH - 14 - display->getStringWidth(ourId), y + 3 + FONT_HEIGHT_SMALL, 12, 8,
|
||||
imgQuestionL1);
|
||||
@@ -2499,7 +2513,7 @@ void DebugInfo::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16
|
||||
#endif
|
||||
} else {
|
||||
#if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ILI9342_DRIVER) || defined(ST7701_CS) || defined(ST7735_CS) || \
|
||||
defined(ST7789_CS) || defined(USE_ST7789) || defined(HX8357_CS)) && \
|
||||
defined(ST7789_CS) || defined(USE_ST7789) || defined(ILI9488_CS) || defined(HX8357_CS)) && \
|
||||
!defined(DISPLAY_FORCE_SMALL_FONTS)
|
||||
display->drawFastImage(x + SCREEN_WIDTH - 18 - display->getStringWidth(ourId), y + 3 + FONT_HEIGHT_SMALL, 16, 8,
|
||||
imgSFL1);
|
||||
@@ -2514,7 +2528,7 @@ void DebugInfo::drawFrame(OLEDDisplay *display, OLEDDisplayUiState *state, int16
|
||||
} else {
|
||||
// TODO: Raspberry Pi supports more than just the one screen size
|
||||
#if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ILI9342_DRIVER) || defined(ST7701_CS) || defined(ST7735_CS) || \
|
||||
defined(ST7789_CS) || defined(USE_ST7789) || defined(HX8357_CS) || ARCH_PORTDUINO) && \
|
||||
defined(ST7789_CS) || defined(USE_ST7789) || defined(HX8357_CS) || defined(ILI9488_CS) || ARCH_PORTDUINO) && \
|
||||
!defined(DISPLAY_FORCE_SMALL_FONTS)
|
||||
display->drawFastImage(x + SCREEN_WIDTH - 14 - display->getStringWidth(ourId), y + 3 + FONT_HEIGHT_SMALL, 12, 8,
|
||||
imgInfoL1);
|
||||
@@ -2835,9 +2849,6 @@ int Screen::handleInputEvent(const InputEvent *event)
|
||||
|
||||
int Screen::handleAdminMessage(const meshtastic_AdminMessage *arg)
|
||||
{
|
||||
// Note: only selected admin messages notify this observer
|
||||
// If you wish to handle a new type of message, you should modify AdminModule.cpp first
|
||||
|
||||
switch (arg->which_payload_variant) {
|
||||
// Node removed manually (i.e. via app)
|
||||
case meshtastic_AdminMessage_remove_by_nodenum_tag:
|
||||
@@ -2854,4 +2865,4 @@ int Screen::handleAdminMessage(const meshtastic_AdminMessage *arg)
|
||||
} // namespace graphics
|
||||
#else
|
||||
graphics::Screen::Screen(ScanI2C::DeviceAddress, meshtastic_Config_DisplayConfig_OledType, OLEDDISPLAY_GEOMETRY) {}
|
||||
#endif // HAS_SCREEN
|
||||
#endif // HAS_SCREEN
|
||||
|
||||
@@ -65,7 +65,7 @@
|
||||
#endif
|
||||
|
||||
#if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ILI9342_DRIVER) || defined(ST7701_CS) || defined(ST7735_CS) || \
|
||||
defined(ST7789_CS) || defined(USE_ST7789) || defined(HX8357_CS)) && \
|
||||
defined(ST7789_CS) || defined(USE_ST7789) || defined(HX8357_CS) || defined(ILI9488_CS)) && \
|
||||
!defined(DISPLAY_FORCE_SMALL_FONTS)
|
||||
// The screen is bigger so use bigger fonts
|
||||
#define FONT_SMALL FONT_MEDIUM_LOCAL // Height: 19
|
||||
|
||||
+318
-12
@@ -120,6 +120,303 @@ static void rak14014_tpIntHandle(void)
|
||||
_rak14014_touch_int = true;
|
||||
}
|
||||
|
||||
#elif defined(ST72xx_DE)
|
||||
#include <LovyanGFX.hpp>
|
||||
#include <TCA9534.h>
|
||||
#include <lgfx/v1/platforms/esp32s3/Bus_RGB.hpp>
|
||||
#include <lgfx/v1/platforms/esp32s3/Panel_RGB.hpp>
|
||||
TCA9534 ioex;
|
||||
|
||||
class LGFX : public lgfx::LGFX_Device
|
||||
{
|
||||
lgfx::Bus_RGB _bus_instance;
|
||||
lgfx::Panel_RGB _panel_instance;
|
||||
lgfx::Touch_GT911 _touch_instance;
|
||||
|
||||
public:
|
||||
const uint16_t screenWidth = TFT_WIDTH;
|
||||
const uint16_t screenHeight = TFT_HEIGHT;
|
||||
|
||||
bool init_impl(bool use_reset, bool use_clear) override
|
||||
{
|
||||
ioex.attach(Wire);
|
||||
ioex.setDeviceAddress(0x18);
|
||||
ioex.config(1, TCA9534::Config::OUT);
|
||||
ioex.config(2, TCA9534::Config::OUT);
|
||||
ioex.config(3, TCA9534::Config::OUT);
|
||||
ioex.config(4, TCA9534::Config::OUT);
|
||||
|
||||
ioex.output(1, TCA9534::Level::H);
|
||||
ioex.output(3, TCA9534::Level::L);
|
||||
ioex.output(4, TCA9534::Level::H);
|
||||
|
||||
pinMode(1, OUTPUT);
|
||||
digitalWrite(1, LOW);
|
||||
ioex.output(2, TCA9534::Level::L);
|
||||
delay(20);
|
||||
ioex.output(2, TCA9534::Level::H);
|
||||
delay(100);
|
||||
pinMode(1, INPUT);
|
||||
|
||||
return LGFX_Device::init_impl(use_reset, use_clear);
|
||||
}
|
||||
|
||||
LGFX(void)
|
||||
{
|
||||
{
|
||||
auto cfg = _panel_instance.config();
|
||||
|
||||
cfg.memory_width = screenWidth;
|
||||
cfg.memory_height = screenHeight;
|
||||
cfg.panel_width = screenWidth;
|
||||
cfg.panel_height = screenHeight;
|
||||
cfg.offset_x = 0;
|
||||
cfg.offset_y = 0;
|
||||
cfg.offset_rotation = 0;
|
||||
_panel_instance.config(cfg);
|
||||
}
|
||||
|
||||
{
|
||||
auto cfg = _panel_instance.config_detail();
|
||||
cfg.use_psram = 0;
|
||||
_panel_instance.config_detail(cfg);
|
||||
}
|
||||
|
||||
{
|
||||
auto cfg = _bus_instance.config();
|
||||
cfg.panel = &_panel_instance;
|
||||
cfg.pin_d0 = ST72xx_B0; // B0
|
||||
cfg.pin_d1 = ST72xx_B1; // B1
|
||||
cfg.pin_d2 = ST72xx_B2; // B2
|
||||
cfg.pin_d3 = ST72xx_B3; // B3
|
||||
cfg.pin_d4 = ST72xx_B4; // B4
|
||||
cfg.pin_d5 = ST72xx_G0; // G0
|
||||
cfg.pin_d6 = ST72xx_G1; // G1
|
||||
cfg.pin_d7 = ST72xx_G2; // G2
|
||||
cfg.pin_d8 = ST72xx_G3; // G3
|
||||
cfg.pin_d9 = ST72xx_G4; // G4
|
||||
cfg.pin_d10 = ST72xx_G5; // G5
|
||||
cfg.pin_d11 = ST72xx_R0; // R0
|
||||
cfg.pin_d12 = ST72xx_R1; // R1
|
||||
cfg.pin_d13 = ST72xx_R2; // R2
|
||||
cfg.pin_d14 = ST72xx_R3; // R3
|
||||
cfg.pin_d15 = ST72xx_R4; // R4
|
||||
|
||||
cfg.pin_henable = ST72xx_DE;
|
||||
cfg.pin_vsync = ST72xx_VSYNC;
|
||||
cfg.pin_hsync = ST72xx_HSYNC;
|
||||
cfg.pin_pclk = ST72xx_PCLK;
|
||||
cfg.freq_write = 13000000;
|
||||
|
||||
#ifdef ST7265_HSYNC_POLARITY
|
||||
cfg.hsync_polarity = ST7265_HSYNC_POLARITY;
|
||||
cfg.hsync_front_porch = ST7265_HSYNC_FRONT_PORCH; // 8;
|
||||
cfg.hsync_pulse_width = ST7265_HSYNC_PULSE_WIDTH; // 4;
|
||||
cfg.hsync_back_porch = ST7265_HSYNC_BACK_PORCH; // 8;
|
||||
|
||||
cfg.vsync_polarity = ST7265_VSYNC_POLARITY; // 0;
|
||||
cfg.vsync_front_porch = ST7265_VSYNC_FRONT_PORCH; // 8;
|
||||
cfg.vsync_pulse_width = ST7265_VSYNC_PULSE_WIDTH; // 4;
|
||||
cfg.vsync_back_porch = ST7265_VSYNC_BACK_PORCH; // 8;
|
||||
|
||||
cfg.pclk_idle_high = 1;
|
||||
cfg.pclk_active_neg = ST7265_PCLK_ACTIVE_NEG; // 0;
|
||||
// cfg.pclk_idle_high = 0;
|
||||
// cfg.de_idle_high = 1;
|
||||
#endif
|
||||
|
||||
#ifdef ST7262_HSYNC_POLARITY
|
||||
cfg.hsync_polarity = ST7262_HSYNC_POLARITY;
|
||||
cfg.hsync_front_porch = ST7262_HSYNC_FRONT_PORCH; // 8;
|
||||
cfg.hsync_pulse_width = ST7262_HSYNC_PULSE_WIDTH; // 4;
|
||||
cfg.hsync_back_porch = ST7262_HSYNC_BACK_PORCH; // 8;
|
||||
|
||||
cfg.vsync_polarity = ST7262_VSYNC_POLARITY; // 0;
|
||||
cfg.vsync_front_porch = ST7262_VSYNC_FRONT_PORCH; // 8;
|
||||
cfg.vsync_pulse_width = ST7262_VSYNC_PULSE_WIDTH; // 4;
|
||||
cfg.vsync_back_porch = ST7262_VSYNC_BACK_PORCH; // 8;
|
||||
|
||||
cfg.pclk_idle_high = 1;
|
||||
cfg.pclk_active_neg = ST7262_PCLK_ACTIVE_NEG; // 0;
|
||||
// cfg.pclk_idle_high = 0;
|
||||
// cfg.de_idle_high = 1;
|
||||
#endif
|
||||
|
||||
#ifdef SC7277_HSYNC_POLARITY
|
||||
cfg.hsync_polarity = SC7277_HSYNC_POLARITY;
|
||||
cfg.hsync_front_porch = SC7277_HSYNC_FRONT_PORCH; // 8;
|
||||
cfg.hsync_pulse_width = SC7277_HSYNC_PULSE_WIDTH; // 4;
|
||||
cfg.hsync_back_porch = SC7277_HSYNC_BACK_PORCH; // 8;
|
||||
|
||||
cfg.vsync_polarity = SC7277_VSYNC_POLARITY; // 0;
|
||||
cfg.vsync_front_porch = SC7277_VSYNC_FRONT_PORCH; // 8;
|
||||
cfg.vsync_pulse_width = SC7277_VSYNC_PULSE_WIDTH; // 4;
|
||||
cfg.vsync_back_porch = SC7277_VSYNC_BACK_PORCH; // 8;
|
||||
|
||||
cfg.pclk_idle_high = 1;
|
||||
cfg.pclk_active_neg = SC7277_PCLK_ACTIVE_NEG; // 0;
|
||||
// cfg.pclk_idle_high = 0;
|
||||
// cfg.de_idle_high = 1;
|
||||
#endif
|
||||
|
||||
_bus_instance.config(cfg);
|
||||
}
|
||||
_panel_instance.setBus(&_bus_instance);
|
||||
|
||||
{
|
||||
auto cfg = _touch_instance.config();
|
||||
cfg.x_min = 0;
|
||||
cfg.x_max = TFT_WIDTH;
|
||||
cfg.y_min = 0;
|
||||
cfg.y_max = TFT_HEIGHT;
|
||||
cfg.pin_int = -1;
|
||||
cfg.pin_rst = -1;
|
||||
cfg.bus_shared = true;
|
||||
cfg.offset_rotation = 0;
|
||||
|
||||
cfg.i2c_port = 0;
|
||||
cfg.i2c_addr = 0x5D;
|
||||
cfg.pin_sda = I2C_SDA;
|
||||
cfg.pin_scl = I2C_SCL;
|
||||
cfg.freq = 400000;
|
||||
_touch_instance.config(cfg);
|
||||
_panel_instance.setTouch(&_touch_instance);
|
||||
}
|
||||
|
||||
setPanel(&_panel_instance);
|
||||
}
|
||||
};
|
||||
|
||||
static LGFX *tft = nullptr;
|
||||
|
||||
#elif defined(ILI9488_CS)
|
||||
#include <LovyanGFX.hpp> // Graphics and font library for ILI9488 driver chip
|
||||
|
||||
class LGFX : public lgfx::LGFX_Device
|
||||
{
|
||||
lgfx::Panel_ILI9488 _panel_instance;
|
||||
lgfx::Bus_SPI _bus_instance;
|
||||
lgfx::Light_PWM _light_instance;
|
||||
lgfx::Touch_GT911 _touch_instance;
|
||||
|
||||
public:
|
||||
LGFX(void)
|
||||
{
|
||||
{
|
||||
auto cfg = _bus_instance.config();
|
||||
|
||||
// configure SPI
|
||||
cfg.spi_host = ILI9488_SPI_HOST; // ESP32-S2,S3,C3 : SPI2_HOST or SPI3_HOST / ESP32 : VSPI_HOST or HSPI_HOST
|
||||
cfg.spi_mode = 0;
|
||||
cfg.freq_write = SPI_FREQUENCY; // SPI clock for transmission (up to 80MHz, rounded to the value obtained by dividing
|
||||
// 80MHz by an integer)
|
||||
cfg.freq_read = SPI_READ_FREQUENCY; // SPI clock when receiving
|
||||
cfg.spi_3wire = false; // Set to true if reception is done on the MOSI pin
|
||||
cfg.use_lock = true; // Set to true to use transaction locking
|
||||
cfg.dma_channel = SPI_DMA_CH_AUTO; // SPI_DMA_CH_AUTO; // Set DMA channel to use (0=not use DMA / 1=1ch / 2=ch /
|
||||
// SPI_DMA_CH_AUTO=auto setting)
|
||||
cfg.pin_sclk = ILI9488_SCK; // Set SPI SCLK pin number
|
||||
cfg.pin_mosi = ILI9488_SDA; // Set SPI MOSI pin number
|
||||
cfg.pin_miso = ILI9488_MISO; // Set SPI MISO pin number (-1 = disable)
|
||||
cfg.pin_dc = ILI9488_RS; // Set SPI DC pin number (-1 = disable)
|
||||
|
||||
_bus_instance.config(cfg); // applies the set value to the bus.
|
||||
_panel_instance.setBus(&_bus_instance); // set the bus on the panel.
|
||||
}
|
||||
|
||||
{ // Set the display panel control.
|
||||
auto cfg = _panel_instance.config(); // Gets a structure for display panel settings.
|
||||
|
||||
cfg.pin_cs = ILI9488_CS; // Pin number where CS is connected (-1 = disable)
|
||||
cfg.pin_rst = -1; // Pin number where RST is connected (-1 = disable)
|
||||
cfg.pin_busy = -1; // Pin number where BUSY is connected (-1 = disable)
|
||||
|
||||
// The following setting values are general initial values for each panel, so please comment out any
|
||||
// unknown items and try them.
|
||||
|
||||
cfg.memory_width = TFT_WIDTH; // Maximum width supported by the driver IC
|
||||
cfg.memory_height = TFT_HEIGHT; // Maximum height supported by the driver IC
|
||||
cfg.panel_width = TFT_WIDTH; // actual displayable width
|
||||
cfg.panel_height = TFT_HEIGHT; // actual displayable height
|
||||
cfg.offset_x = TFT_OFFSET_X; // Panel offset amount in X direction
|
||||
cfg.offset_y = TFT_OFFSET_Y; // Panel offset amount in Y direction
|
||||
cfg.offset_rotation = TFT_OFFSET_ROTATION; // Rotation direction value offset 0~7 (4~7 is mirrored)
|
||||
#ifdef TFT_DUMMY_READ_PIXELS
|
||||
cfg.dummy_read_pixel = TFT_DUMMY_READ_PIXELS; // Number of bits for dummy read before pixel readout
|
||||
#else
|
||||
cfg.dummy_read_pixel = 9; // Number of bits for dummy read before pixel readout
|
||||
#endif
|
||||
cfg.dummy_read_bits = 1; // Number of bits for dummy read before non-pixel data read
|
||||
cfg.readable = true; // Set to true if data can be read
|
||||
cfg.invert = true; // Set to true if the light/darkness of the panel is reversed
|
||||
cfg.rgb_order = false; // Set to true if the panel's red and blue are swapped
|
||||
cfg.dlen_16bit =
|
||||
false; // Set to true for panels that transmit data length in 16-bit units with 16-bit parallel or SPI
|
||||
cfg.bus_shared = true; // If the bus is shared with the SD card, set to true (bus control with drawJpgFile etc.)
|
||||
|
||||
// Set the following only when the display is shifted with a driver with a variable number of pixels, such as the
|
||||
// ST7735 or ILI9163.
|
||||
// cfg.memory_width = TFT_WIDTH; // Maximum width supported by the driver IC
|
||||
// cfg.memory_height = TFT_HEIGHT; // Maximum height supported by the driver IC
|
||||
_panel_instance.config(cfg);
|
||||
}
|
||||
|
||||
#ifdef ILI9488_BL
|
||||
// Set the backlight control
|
||||
{
|
||||
auto cfg = _light_instance.config(); // Gets a structure for backlight settings.
|
||||
|
||||
cfg.pin_bl = ILI9488_BL; // Pin number to which the backlight is connected
|
||||
cfg.invert = false; // true to invert the brightness of the backlight
|
||||
// cfg.freq = 44100; // PWM frequency of backlight
|
||||
// cfg.pwm_channel = 1; // PWM channel number to use
|
||||
|
||||
_light_instance.config(cfg);
|
||||
_panel_instance.setLight(&_light_instance); // Set the backlight on the panel.
|
||||
}
|
||||
#endif
|
||||
|
||||
#if HAS_TOUCHSCREEN
|
||||
// Configure settings for touch screen control.
|
||||
{
|
||||
auto cfg = _touch_instance.config();
|
||||
|
||||
cfg.pin_cs = -1;
|
||||
cfg.x_min = 0;
|
||||
cfg.x_max = TFT_HEIGHT - 1;
|
||||
cfg.y_min = 0;
|
||||
cfg.y_max = TFT_WIDTH - 1;
|
||||
cfg.pin_int = SCREEN_TOUCH_INT;
|
||||
#ifdef SCREEN_TOUCH_RST
|
||||
cfg.pin_rst = SCREEN_TOUCH_RST;
|
||||
#endif
|
||||
cfg.bus_shared = true;
|
||||
cfg.offset_rotation = TFT_OFFSET_ROTATION;
|
||||
// cfg.freq = 2500000;
|
||||
|
||||
// I2C
|
||||
cfg.i2c_port = TOUCH_I2C_PORT;
|
||||
cfg.i2c_addr = TOUCH_SLAVE_ADDRESS;
|
||||
#ifdef SCREEN_TOUCH_USE_I2C1
|
||||
cfg.pin_sda = I2C_SDA1;
|
||||
cfg.pin_scl = I2C_SCL1;
|
||||
#else
|
||||
cfg.pin_sda = I2C_SDA;
|
||||
cfg.pin_scl = I2C_SCL;
|
||||
#endif
|
||||
// cfg.freq = 400000;
|
||||
|
||||
_touch_instance.config(cfg);
|
||||
_panel_instance.setTouch(&_touch_instance);
|
||||
}
|
||||
#endif
|
||||
|
||||
setPanel(&_panel_instance);
|
||||
}
|
||||
};
|
||||
|
||||
static LGFX *tft = nullptr;
|
||||
|
||||
#elif defined(ST7789_CS)
|
||||
#include <LovyanGFX.hpp> // Graphics and font library for ST7735 driver chip
|
||||
|
||||
@@ -129,7 +426,7 @@ class LGFX : public lgfx::LGFX_Device
|
||||
lgfx::Bus_SPI _bus_instance;
|
||||
lgfx::Light_PWM _light_instance;
|
||||
#if HAS_TOUCHSCREEN
|
||||
#ifdef T_WATCH_S3
|
||||
#if defined(T_WATCH_S3) || defined(ELECROW)
|
||||
lgfx::Touch_FT5x06 _touch_instance;
|
||||
#else
|
||||
lgfx::Touch_GT911 _touch_instance;
|
||||
@@ -171,16 +468,22 @@ class LGFX : public lgfx::LGFX_Device
|
||||
// The following setting values are general initial values for each panel, so please comment out any
|
||||
// unknown items and try them.
|
||||
|
||||
cfg.panel_width = TFT_WIDTH; // actual displayable width
|
||||
cfg.panel_height = TFT_HEIGHT; // actual displayable height
|
||||
cfg.offset_x = TFT_OFFSET_X; // Panel offset amount in X direction
|
||||
cfg.offset_y = TFT_OFFSET_Y; // Panel offset amount in Y direction
|
||||
cfg.offset_rotation = TFT_OFFSET_ROTATION; // Rotation direction value offset 0~7 (4~7 is mirrored)
|
||||
cfg.dummy_read_pixel = 9; // Number of bits for dummy read before pixel readout
|
||||
cfg.dummy_read_bits = 1; // Number of bits for dummy read before non-pixel data read
|
||||
cfg.readable = true; // Set to true if data can be read
|
||||
cfg.invert = true; // Set to true if the light/darkness of the panel is reversed
|
||||
cfg.rgb_order = false; // Set to true if the panel's red and blue are swapped
|
||||
cfg.memory_width = TFT_WIDTH; // Maximum width supported by the driver IC
|
||||
cfg.memory_height = TFT_HEIGHT; // Maximum height supported by the driver IC
|
||||
cfg.panel_width = TFT_WIDTH; // actual displayable width
|
||||
cfg.panel_height = TFT_HEIGHT; // actual displayable height
|
||||
cfg.offset_x = TFT_OFFSET_X; // Panel offset amount in X direction
|
||||
cfg.offset_y = TFT_OFFSET_Y; // Panel offset amount in Y direction
|
||||
cfg.offset_rotation = TFT_OFFSET_ROTATION; // Rotation direction value offset 0~7 (4~7 is mirrored)
|
||||
#ifdef TFT_DUMMY_READ_PIXELS
|
||||
cfg.dummy_read_pixel = TFT_DUMMY_READ_PIXELS; // Number of bits for dummy read before pixel readout
|
||||
#else
|
||||
cfg.dummy_read_pixel = 9; // Number of bits for dummy read before pixel readout
|
||||
#endif
|
||||
cfg.dummy_read_bits = 1; // Number of bits for dummy read before non-pixel data read
|
||||
cfg.readable = true; // Set to true if data can be read
|
||||
cfg.invert = true; // Set to true if the light/darkness of the panel is reversed
|
||||
cfg.rgb_order = false; // Set to true if the panel's red and blue are swapped
|
||||
cfg.dlen_16bit =
|
||||
false; // Set to true for panels that transmit data length in 16-bit units with 16-bit parallel or SPI
|
||||
cfg.bus_shared = true; // If the bus is shared with the SD card, set to true (bus control with drawJpgFile etc.)
|
||||
@@ -217,6 +520,9 @@ class LGFX : public lgfx::LGFX_Device
|
||||
cfg.y_min = 0;
|
||||
cfg.y_max = TFT_WIDTH - 1;
|
||||
cfg.pin_int = SCREEN_TOUCH_INT;
|
||||
#ifdef SCREEN_TOUCH_RST
|
||||
cfg.pin_rst = SCREEN_TOUCH_RST;
|
||||
#endif
|
||||
cfg.bus_shared = true;
|
||||
cfg.offset_rotation = TFT_OFFSET_ROTATION;
|
||||
// cfg.freq = 2500000;
|
||||
@@ -640,7 +946,7 @@ static LGFX *tft = nullptr;
|
||||
#endif
|
||||
|
||||
#if defined(ST7701_CS) || defined(ST7735_CS) || defined(ST7789_CS) || defined(ILI9341_DRIVER) || defined(ILI9342_DRIVER) || \
|
||||
defined(RAK14014) || defined(HX8357_CS) || (ARCH_PORTDUINO && HAS_SCREEN != 0)
|
||||
defined(RAK14014) || defined(HX8357_CS) || defined(ILI9488_CS) || defined(ST72xx_DE) || (ARCH_PORTDUINO && HAS_SCREEN != 0)
|
||||
#include "SPILock.h"
|
||||
#include "TFTDisplay.h"
|
||||
#include <SPI.h>
|
||||
|
||||
@@ -21,7 +21,7 @@ const uint8_t bluetoothConnectedIcon[36] PROGMEM = {0xfe, 0x01, 0xff, 0x03, 0x03
|
||||
#endif
|
||||
|
||||
#if (defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ILI9342_DRIVER) || defined(ST7701_CS) || defined(ST7735_CS) || \
|
||||
defined(ST7789_CS) || defined(USE_ST7789) || defined(HX8357_CS) || ARCH_PORTDUINO) && \
|
||||
defined(ST7789_CS) || defined(USE_ST7789) || defined(HX8357_CS) || defined(ILI9488_CS) || ARCH_PORTDUINO) && \
|
||||
!defined(DISPLAY_FORCE_SMALL_FONTS)
|
||||
const uint8_t imgQuestionL1[] PROGMEM = {0xff, 0x01, 0x01, 0x32, 0x7b, 0x49, 0x49, 0x6f, 0x26, 0x01, 0x01, 0xff};
|
||||
const uint8_t imgQuestionL2[] PROGMEM = {0x0f, 0x08, 0x08, 0x08, 0x06, 0x0f, 0x0f, 0x06, 0x08, 0x08, 0x08, 0x0f};
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
#include "./DEPG0154BNS800.h"
|
||||
@@ -1,34 +0,0 @@
|
||||
/*
|
||||
|
||||
E-Ink display driver
|
||||
- DEPG0154BNS800
|
||||
- Manufacturer: DKE
|
||||
- Size: 1.54 inch
|
||||
- Resolution: 152px x 152px
|
||||
- Flex connector marking: FPC7525
|
||||
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef MESHTASTIC_INCLUDE_NICHE_GRAPHICS
|
||||
#include "configuration.h"
|
||||
|
||||
#include "./SSD16XX.h"
|
||||
|
||||
namespace NicheGraphics::Drivers
|
||||
{
|
||||
class DEPG0154BNS800 : public SSD16XX
|
||||
{
|
||||
// Display properties
|
||||
private:
|
||||
static constexpr uint32_t width = 152;
|
||||
static constexpr uint32_t height = 152;
|
||||
static constexpr UpdateTypes supported = (UpdateTypes)(FULL);
|
||||
|
||||
public:
|
||||
DEPG0154BNS800() : SSD16XX(width, height, supported, 1) {} // Note: left edge of this display is offset by 1 byte
|
||||
};
|
||||
|
||||
} // namespace NicheGraphics::Drivers
|
||||
#endif // MESHTASTIC_INCLUDE_NICHE_GRAPHICS
|
||||
@@ -0,0 +1,132 @@
|
||||
#include "./DEPG0213BNS800.h"
|
||||
|
||||
#ifdef MESHTASTIC_INCLUDE_NICHE_GRAPHICS
|
||||
|
||||
using namespace NicheGraphics::Drivers;
|
||||
|
||||
// Describes the operation performed when a "fast refresh" is performed
|
||||
// Source: Modified from GxEPD2 (GxEPD2_213_BN)
|
||||
static const uint8_t LUT_FAST[] = {
|
||||
// 1 2 3
|
||||
0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // B2B (Existing black pixels)
|
||||
0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // B2W (New white pixels)
|
||||
0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // W2B (New black pixels)
|
||||
0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // W2W (Existing white pixels)
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // VCOM
|
||||
|
||||
0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, // 1. Any pixels changing W2B or B2W. Two medium taps.
|
||||
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 2. All pixels. One short tap.
|
||||
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 3. Cooldown
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
|
||||
0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, //
|
||||
};
|
||||
|
||||
// How strongly the pixels are pulled and pushed
|
||||
void DEPG0213BNS800::configVoltages()
|
||||
{
|
||||
switch (updateType) {
|
||||
case FAST:
|
||||
// Reference: display datasheet, GxEPD1
|
||||
sendCommand(0x03); // Gate voltage
|
||||
sendData(0x17); // VGH: 20V
|
||||
|
||||
// Reference: display datasheet, GxEPD1
|
||||
sendCommand(0x04); // Source voltage
|
||||
sendData(0x41); // VSH1: 15V
|
||||
sendData(0x00); // VSH2: NA
|
||||
sendData(0x32); // VSL: -15V
|
||||
|
||||
// GxEPD1 sets this at -1.2V, but that seems to be drive the pixels very hard
|
||||
sendCommand(0x2C); // VCOM voltage
|
||||
sendData(0x08); // VCOM: -0.2V
|
||||
break;
|
||||
|
||||
case FULL:
|
||||
default:
|
||||
// From OTP memory
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Load settings about how the pixels are moved from old state to new state during a refresh
|
||||
// - manually specified,
|
||||
// - or with stored values from displays OTP memory
|
||||
void DEPG0213BNS800::configWaveform()
|
||||
{
|
||||
switch (updateType) {
|
||||
case FAST:
|
||||
sendCommand(0x3C); // Border waveform:
|
||||
sendData(0x80); // VSS
|
||||
|
||||
sendCommand(0x32); // Write LUT register from MCU:
|
||||
sendData(LUT_FAST, sizeof(LUT_FAST)); // (describes operation for a FAST refresh)
|
||||
break;
|
||||
|
||||
case FULL:
|
||||
default:
|
||||
// From OTP memory
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Describes the sequence of events performed by the displays controller IC during a refresh
|
||||
// Includes "power up", "load settings from memory", "update the pixels", etc
|
||||
void DEPG0213BNS800::configUpdateSequence()
|
||||
{
|
||||
switch (updateType) {
|
||||
case FAST:
|
||||
sendCommand(0x22); // Set "update sequence"
|
||||
sendData(0xCF); // Differential, use manually loaded waveform
|
||||
break;
|
||||
|
||||
case FULL:
|
||||
default:
|
||||
sendCommand(0x22); // Set "update sequence"
|
||||
sendData(0xF7); // Non-differential, load waveform from OTP
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Once the refresh operation has been started,
|
||||
// begin periodically polling the display to check for completion, using the normal Meshtastic threading code
|
||||
// Only used when refresh is "async"
|
||||
void DEPG0213BNS800::detachFromUpdate()
|
||||
{
|
||||
switch (updateType) {
|
||||
case FAST:
|
||||
return beginPolling(50, 500); // At least 500ms, then poll every 50ms
|
||||
case FULL:
|
||||
default:
|
||||
return beginPolling(100, 3500); // At least 3500ms, then poll every 100ms
|
||||
}
|
||||
}
|
||||
|
||||
// For this display, we do not need to re-write the new image.
|
||||
// We're overriding SSD16XX::finalizeUpdate to make this small optimization.
|
||||
// The display does also work just fine with the generic SSD16XX method, though.
|
||||
void DEPG0213BNS800::finalizeUpdate()
|
||||
{
|
||||
// Put a copy of the image into the "old memory".
|
||||
// Used with differential refreshes (e.g. FAST update), to determine which px need to move, and which can remain in place
|
||||
// We need to keep the "old memory" up to date, because don't know whether next refresh will be FULL or FAST etc.
|
||||
if (updateType != FULL) {
|
||||
// writeNewImage(); // Not required for this display
|
||||
writeOldImage();
|
||||
sendCommand(0x7F); // Terminate image write without update
|
||||
wait();
|
||||
}
|
||||
|
||||
// Enter deep-sleep to save a few µA
|
||||
// Waking from this requires that display's reset pin is broken out
|
||||
if (pin_rst != 0xFF)
|
||||
deepSleep();
|
||||
}
|
||||
#endif // MESHTASTIC_INCLUDE_NICHE_GRAPHICS
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
|
||||
E-Ink display driver
|
||||
- DEPG0213BNS800
|
||||
- Manufacturer: DKE
|
||||
- Size: 2.13 inch
|
||||
- Resolution: 122px x 250px
|
||||
- Flex connector marking: FPC-7528B
|
||||
|
||||
Note: this is from an older generation of DKE panels, which still used Solomon Systech controller ICs.
|
||||
DKE's website suggests that the latest DEPG0213BN displays may use Fitipower controllers instead.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef MESHTASTIC_INCLUDE_NICHE_GRAPHICS
|
||||
|
||||
#include "configuration.h"
|
||||
|
||||
#include "./SSD16XX.h"
|
||||
|
||||
namespace NicheGraphics::Drivers
|
||||
{
|
||||
class DEPG0213BNS800 : public SSD16XX
|
||||
{
|
||||
// Display properties
|
||||
private:
|
||||
static constexpr uint32_t width = 122;
|
||||
static constexpr uint32_t height = 250;
|
||||
static constexpr UpdateTypes supported = (UpdateTypes)(FULL | FAST);
|
||||
|
||||
public:
|
||||
DEPG0213BNS800() : SSD16XX(width, height, supported, 1) {} // Note: left edge of this display is offset by 1 byte
|
||||
|
||||
protected:
|
||||
void configVoltages() override;
|
||||
void configWaveform() override;
|
||||
void configUpdateSequence() override;
|
||||
void detachFromUpdate() override;
|
||||
void finalizeUpdate() override; // Only overriden for a slight optimization
|
||||
};
|
||||
|
||||
} // namespace NicheGraphics::Drivers
|
||||
#endif // MESHTASTIC_INCLUDE_NICHE_GRAPHICS
|
||||
@@ -116,5 +116,10 @@ void DEPG0290BNS800::finalizeUpdate()
|
||||
sendCommand(0x7F); // Terminate image write without update
|
||||
wait();
|
||||
}
|
||||
|
||||
// Enter deep-sleep to save a few µA
|
||||
// Waking from this requires that display's reset pin is broken out
|
||||
if (pin_rst != 0xFF)
|
||||
deepSleep();
|
||||
}
|
||||
#endif // MESHTASTIC_INCLUDE_NICHE_GRAPHICS
|
||||
@@ -0,0 +1,61 @@
|
||||
#include "./GDEY0213B74.h"
|
||||
|
||||
#ifdef MESHTASTIC_INCLUDE_NICHE_GRAPHICS
|
||||
|
||||
using namespace NicheGraphics::Drivers;
|
||||
|
||||
// Map the display controller IC's output to the connected panel
|
||||
void GDEY0213B74::configScanning()
|
||||
{
|
||||
// "Driver output control"
|
||||
sendCommand(0x01);
|
||||
sendData(0xF9);
|
||||
sendData(0x00);
|
||||
sendData(0x00);
|
||||
|
||||
// To-do: delete this method?
|
||||
// Values set here might be redundant: F9, 00, 00 seems to be default
|
||||
}
|
||||
|
||||
// Specify which information is used to control the sequence of voltages applied to move the pixels
|
||||
// - For this display, configUpdateSequence() specifies that a suitable LUT will be loaded from
|
||||
// the controller IC's OTP memory, when the update procedure begins.
|
||||
void GDEY0213B74::configWaveform()
|
||||
{
|
||||
sendCommand(0x3C); // Border waveform:
|
||||
sendData(0x05); // Screen border should follow LUT1 waveform (actively drive pixels white)
|
||||
|
||||
sendCommand(0x18); // Temperature sensor:
|
||||
sendData(0x80); // Use internal temperature sensor to select an appropriate refresh waveform
|
||||
}
|
||||
|
||||
void GDEY0213B74::configUpdateSequence()
|
||||
{
|
||||
switch (updateType) {
|
||||
case FAST:
|
||||
sendCommand(0x22); // Set "update sequence"
|
||||
sendData(0xFF); // Will load LUT from OTP memory, Display mode 2 "differential refresh"
|
||||
break;
|
||||
|
||||
case FULL:
|
||||
default:
|
||||
sendCommand(0x22); // Set "update sequence"
|
||||
sendData(0xF7); // Will load LUT from OTP memory
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Once the refresh operation has been started,
|
||||
// begin periodically polling the display to check for completion, using the normal Meshtastic threading code
|
||||
// Only used when refresh is "async"
|
||||
void GDEY0213B74::detachFromUpdate()
|
||||
{
|
||||
switch (updateType) {
|
||||
case FAST:
|
||||
return beginPolling(50, 500); // At least 500ms for fast refresh
|
||||
case FULL:
|
||||
default:
|
||||
return beginPolling(100, 2000); // At least 2 seconds for full refresh
|
||||
}
|
||||
}
|
||||
#endif // MESHTASTIC_INCLUDE_NICHE_GRAPHICS
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
|
||||
E-Ink display driver
|
||||
- GDEY0213B74
|
||||
- Manufacturer: Goodisplay
|
||||
- Size: 2.13 inch
|
||||
- Resolution: 250px x 122px
|
||||
- Flex connector marking: FPC-A002
|
||||
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef MESHTASTIC_INCLUDE_NICHE_GRAPHICS
|
||||
|
||||
#include "configuration.h"
|
||||
|
||||
#include "./SSD16XX.h"
|
||||
|
||||
namespace NicheGraphics::Drivers
|
||||
{
|
||||
class GDEY0213B74 : public SSD16XX
|
||||
{
|
||||
// Display properties
|
||||
private:
|
||||
static constexpr uint32_t width = 122;
|
||||
static constexpr uint32_t height = 250;
|
||||
static constexpr UpdateTypes supported = (UpdateTypes)(FULL | FAST);
|
||||
|
||||
public:
|
||||
GDEY0213B74() : SSD16XX(width, height, supported) {}
|
||||
|
||||
protected:
|
||||
virtual void configScanning() override;
|
||||
virtual void configWaveform() override;
|
||||
virtual void configUpdateSequence() override;
|
||||
void detachFromUpdate() override;
|
||||
};
|
||||
|
||||
} // namespace NicheGraphics::Drivers
|
||||
|
||||
#endif // MESHTASTIC_INCLUDE_NICHE_GRAPHICS
|
||||
@@ -0,0 +1,68 @@
|
||||
#include "./LCMEN2R13ECC1.h"
|
||||
|
||||
#ifdef MESHTASTIC_INCLUDE_NICHE_GRAPHICS
|
||||
|
||||
using namespace NicheGraphics::Drivers;
|
||||
|
||||
// Map the display controller IC's output to the connected panel
|
||||
void LCMEN2R13ECC1::configScanning()
|
||||
{
|
||||
// "Driver output control"
|
||||
sendCommand(0x01);
|
||||
sendData(0xF9);
|
||||
sendData(0x00);
|
||||
sendData(0x00);
|
||||
|
||||
// To-do: delete this method?
|
||||
// Values set here might be redundant: F9, 00, 00 seems to be default
|
||||
}
|
||||
|
||||
// Specify which information is used to control the sequence of voltages applied to move the pixels
|
||||
// - For this display, configUpdateSequence() specifies that a suitable LUT will be loaded from
|
||||
// the controller IC's OTP memory, when the update procedure begins.
|
||||
void LCMEN2R13ECC1::configWaveform()
|
||||
{
|
||||
switch (updateType) {
|
||||
case FAST:
|
||||
sendCommand(0x3C); // Border waveform:
|
||||
sendData(0x85);
|
||||
break;
|
||||
|
||||
case FULL:
|
||||
default:
|
||||
// From OTP memory
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void LCMEN2R13ECC1::configUpdateSequence()
|
||||
{
|
||||
switch (updateType) {
|
||||
case FAST:
|
||||
sendCommand(0x22); // Set "update sequence"
|
||||
sendData(0xFF); // Will load LUT from OTP memory, Display mode 2 "differential refresh"
|
||||
break;
|
||||
|
||||
case FULL:
|
||||
default:
|
||||
sendCommand(0x22); // Set "update sequence"
|
||||
sendData(0xF7); // Will load LUT from OTP memory
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Once the refresh operation has been started,
|
||||
// begin periodically polling the display to check for completion, using the normal Meshtastic threading code
|
||||
// Only used when refresh is "async"
|
||||
void LCMEN2R13ECC1::detachFromUpdate()
|
||||
{
|
||||
switch (updateType) {
|
||||
case FAST:
|
||||
return beginPolling(50, 800); // At least 500ms for fast refresh
|
||||
case FULL:
|
||||
default:
|
||||
return beginPolling(100, 2500); // At least 2 seconds for full refresh
|
||||
}
|
||||
}
|
||||
|
||||
#endif // MESHTASTIC_INCLUDE_NICHE_GRAPHICS
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
|
||||
E-Ink display driver
|
||||
- SSD1680
|
||||
- Manufacturer: WISEVAST
|
||||
- Size: 2.13 inch
|
||||
- Resolution: 122px x 255px
|
||||
- Flex connector marking: Soldering connector, no connector is needed
|
||||
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef MESHTASTIC_INCLUDE_NICHE_GRAPHICS
|
||||
|
||||
#include "configuration.h"
|
||||
|
||||
#include "./SSD16XX.h"
|
||||
|
||||
namespace NicheGraphics::Drivers
|
||||
{
|
||||
class LCMEN2R13ECC1 : public SSD16XX
|
||||
{
|
||||
// Display properties
|
||||
private:
|
||||
static constexpr uint32_t width = 122;
|
||||
static constexpr uint32_t height = 250;
|
||||
static constexpr UpdateTypes supported = (UpdateTypes)(FULL | FAST);
|
||||
|
||||
public:
|
||||
LCMEN2R13ECC1() : SSD16XX(width, height, supported, 1) {} // Note: left edge of this display is offset by 1 byte
|
||||
|
||||
protected:
|
||||
virtual void configScanning() override;
|
||||
virtual void configWaveform() override;
|
||||
virtual void configUpdateSequence() override;
|
||||
void detachFromUpdate() override;
|
||||
};
|
||||
|
||||
} // namespace NicheGraphics::Drivers
|
||||
#endif // MESHTASTIC_INCLUDE_NICHE_GRAPHICS
|
||||
@@ -1,9 +1,11 @@
|
||||
#include "./LCMEN2R13EFC1.h"
|
||||
|
||||
#ifdef MESHTASTIC_INCLUDE_NICHE_GRAPHICS
|
||||
|
||||
#include "./LCMEN2R13EFC1.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "SPILock.h"
|
||||
|
||||
using namespace NicheGraphics::Drivers;
|
||||
|
||||
// Look up table: fast refresh, common electrode
|
||||
@@ -42,11 +44,10 @@ static const uint8_t LUT_FAST_BW[] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
|
||||
};
|
||||
|
||||
// Look up table: fash refresh, pixels which change from white to black
|
||||
// Look up table: fast refresh, pixels which change from white to black
|
||||
static const uint8_t LUT_FAST_WB[] = {
|
||||
0x01, 0x46, 0x42, 0x01, 0x01, 0x01, 0x01, //
|
||||
0x01, 0x46, 0x42, 0x01, 0x01, 0x01, 0x01, //
|
||||
0x01, 0x46, 0x43, 0x02, 0x01, 0x01, 0x01, //
|
||||
0x01, 0x46, 0x42, 0x01, 0x01, 0x01, 0x01, //
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
|
||||
@@ -55,7 +56,7 @@ static const uint8_t LUT_FAST_WB[] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //
|
||||
};
|
||||
|
||||
// Look up table: fash refresh, pixels which remain black
|
||||
// Look up table: fast refresh, pixels which remain black
|
||||
static const uint8_t LUT_FAST_BB[] = {
|
||||
0x01, 0x06, 0x03, 0x42, 0x41, 0x01, 0x01, //
|
||||
0x01, 0x06, 0x02, 0x01, 0x01, 0x01, 0x01, //
|
||||
@@ -151,6 +152,9 @@ void LCMEN213EFC1::reset()
|
||||
|
||||
void LCMEN213EFC1::sendCommand(const uint8_t command)
|
||||
{
|
||||
// Take firmware's SPI lock
|
||||
spiLock->lock();
|
||||
|
||||
spi->beginTransaction(spiSettings);
|
||||
digitalWrite(pin_dc, LOW); // DC pin low indicates command
|
||||
digitalWrite(pin_cs, LOW);
|
||||
@@ -158,6 +162,8 @@ void LCMEN213EFC1::sendCommand(const uint8_t command)
|
||||
digitalWrite(pin_cs, HIGH);
|
||||
digitalWrite(pin_dc, HIGH);
|
||||
spi->endTransaction();
|
||||
|
||||
spiLock->unlock();
|
||||
}
|
||||
|
||||
void LCMEN213EFC1::sendData(uint8_t data)
|
||||
@@ -167,6 +173,9 @@ void LCMEN213EFC1::sendData(uint8_t data)
|
||||
|
||||
void LCMEN213EFC1::sendData(const uint8_t *data, uint32_t size)
|
||||
{
|
||||
// Take firmware's SPI lock
|
||||
spiLock->lock();
|
||||
|
||||
spi->beginTransaction(spiSettings);
|
||||
digitalWrite(pin_dc, HIGH); // DC pin HIGH indicates data, instead of command
|
||||
digitalWrite(pin_cs, LOW);
|
||||
@@ -184,6 +193,8 @@ void LCMEN213EFC1::sendData(const uint8_t *data, uint32_t size)
|
||||
digitalWrite(pin_cs, HIGH);
|
||||
digitalWrite(pin_dc, HIGH);
|
||||
spi->endTransaction();
|
||||
|
||||
spiLock->unlock();
|
||||
}
|
||||
|
||||
void LCMEN213EFC1::configFull()
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
#ifdef MESHTASTIC_INCLUDE_NICHE_GRAPHICS
|
||||
|
||||
#include "./SSD16XX.h"
|
||||
|
||||
#ifdef MESHTASTIC_INCLUDE_NICHE_GRAPHICS
|
||||
#include "SPILock.h"
|
||||
|
||||
using namespace NicheGraphics::Drivers;
|
||||
|
||||
SSD16XX::SSD16XX(uint16_t width, uint16_t height, UpdateTypes supported, uint8_t bufferOffsetX)
|
||||
@@ -82,6 +85,9 @@ void SSD16XX::sendCommand(const uint8_t command)
|
||||
if (failed)
|
||||
return;
|
||||
|
||||
// Take firmware's SPI lock
|
||||
spiLock->lock();
|
||||
|
||||
spi->beginTransaction(spiSettings);
|
||||
digitalWrite(pin_dc, LOW); // DC pin low indicates command
|
||||
digitalWrite(pin_cs, LOW);
|
||||
@@ -89,6 +95,8 @@ void SSD16XX::sendCommand(const uint8_t command)
|
||||
digitalWrite(pin_cs, HIGH);
|
||||
digitalWrite(pin_dc, HIGH);
|
||||
spi->endTransaction();
|
||||
|
||||
spiLock->unlock();
|
||||
}
|
||||
|
||||
void SSD16XX::sendData(uint8_t data)
|
||||
@@ -103,6 +111,9 @@ void SSD16XX::sendData(const uint8_t *data, uint32_t size)
|
||||
if (failed)
|
||||
return;
|
||||
|
||||
// Take firmware's SPI lock
|
||||
spiLock->lock();
|
||||
|
||||
spi->beginTransaction(spiSettings);
|
||||
digitalWrite(pin_dc, HIGH); // DC pin HIGH indicates data, instead of command
|
||||
digitalWrite(pin_cs, LOW);
|
||||
@@ -119,6 +130,8 @@ void SSD16XX::sendData(const uint8_t *data, uint32_t size)
|
||||
digitalWrite(pin_cs, HIGH);
|
||||
digitalWrite(pin_dc, HIGH);
|
||||
spi->endTransaction();
|
||||
|
||||
spiLock->unlock();
|
||||
}
|
||||
|
||||
void SSD16XX::configFullscreen()
|
||||
@@ -242,5 +255,18 @@ void SSD16XX::finalizeUpdate()
|
||||
sendCommand(0x7F); // Terminate image write without update
|
||||
wait();
|
||||
}
|
||||
|
||||
// Enter deep-sleep to save a few µA
|
||||
// Waking from this requires that display's reset pin is broken out
|
||||
if (pin_rst != 0xFF)
|
||||
deepSleep();
|
||||
}
|
||||
|
||||
// Enter a lower-power state
|
||||
// May only save a few µA..
|
||||
void SSD16XX::deepSleep()
|
||||
{
|
||||
sendCommand(0x10); // Enter deep sleep
|
||||
sendData(0x01); // Mode 1: preserve image RAM
|
||||
}
|
||||
#endif // MESHTASTIC_INCLUDE_NICHE_GRAPHICS
|
||||
@@ -44,6 +44,7 @@ class SSD16XX : public EInk
|
||||
virtual void detachFromUpdate();
|
||||
virtual bool isUpdateDone() override;
|
||||
virtual void finalizeUpdate() override;
|
||||
virtual void deepSleep();
|
||||
|
||||
protected:
|
||||
uint8_t bufferOffsetX = 0; // In bytes. Panel x=0 does not always align with controller x=0. Quirky internal wiring?
|
||||
|
||||
@@ -13,6 +13,7 @@ Avoid bloating everyone's protobuf code for our one-off UI implementations
|
||||
|
||||
#include "configuration.h"
|
||||
|
||||
#include "SPILock.h"
|
||||
#include "SafeFile.h"
|
||||
|
||||
namespace NicheGraphics
|
||||
@@ -46,6 +47,9 @@ template <typename T> class FlashData
|
||||
public:
|
||||
static bool load(T *data, const char *label)
|
||||
{
|
||||
// Take firmware's SPI lock
|
||||
concurrency::LockGuard guard(spiLock);
|
||||
|
||||
// Set false if we run into issues
|
||||
bool okay = true;
|
||||
|
||||
@@ -103,14 +107,18 @@ template <typename T> class FlashData
|
||||
return okay;
|
||||
}
|
||||
|
||||
// Save module's custom data (settings?) to flash. Does use protobufs
|
||||
// Save module's custom data (settings?) to flash. Doesn't use protobufs
|
||||
// Takes the firmware's SPI lock, in case the files are stored on SD card
|
||||
// Need to lock and unlock around specific FS methods, as the SafeFile class takes the lock for itself internally.
|
||||
static void save(T *data, const char *label)
|
||||
{
|
||||
// Get a filename based on the label
|
||||
std::string filename = getFilename(label);
|
||||
|
||||
#ifdef FSCom
|
||||
spiLock->lock();
|
||||
FSCom.mkdir("/NicheGraphics");
|
||||
spiLock->unlock();
|
||||
|
||||
auto f = SafeFile(filename.c_str(), true); // "true": full atomic. Write new data to temp file, then rename.
|
||||
|
||||
@@ -119,10 +127,10 @@ template <typename T> class FlashData
|
||||
// Calculate a hash of the data
|
||||
uint32_t hash = getHash(data);
|
||||
|
||||
spiLock->lock();
|
||||
f.write((uint8_t *)data, sizeof(T)); // Write the actual data
|
||||
f.write((uint8_t *)&hash, sizeof(hash)); // Append the hash
|
||||
|
||||
// f.flush();
|
||||
spiLock->unlock();
|
||||
|
||||
bool writeSucceeded = f.close();
|
||||
|
||||
@@ -135,6 +143,32 @@ template <typename T> class FlashData
|
||||
}
|
||||
};
|
||||
|
||||
// Erase contents of the NicheGraphics data directory
|
||||
inline void clearFlashData()
|
||||
{
|
||||
|
||||
// Take firmware's SPI lock, in case the files are stored on SD card
|
||||
concurrency::LockGuard guard(spiLock);
|
||||
|
||||
#ifdef FSCom
|
||||
File dir = FSCom.open("/NicheGraphics"); // Open the directory
|
||||
File file = dir.openNextFile(); // Attempt to open the first file in the directory
|
||||
|
||||
// While the directory still contains files
|
||||
while (file) {
|
||||
std::string path = "/NicheGraphics/";
|
||||
path += file.name();
|
||||
LOG_DEBUG("Erasing %s", path.c_str());
|
||||
file.close();
|
||||
FSCom.remove(path.c_str());
|
||||
|
||||
file = dir.openNextFile();
|
||||
}
|
||||
#else
|
||||
LOG_ERROR("ERROR: Filesystem not implemented\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace NicheGraphics
|
||||
|
||||
#endif
|
||||
@@ -1,129 +1,198 @@
|
||||
#pragma once
|
||||
|
||||
const uint8_t FreeSans6pt7bBitmaps[] PROGMEM = {
|
||||
0xAA, 0xA8, 0xC0, 0xF6, 0xA0, 0x24, 0x51, 0xF9, 0x42, 0x9F, 0x92, 0x28, 0x10, 0xE5, 0x55, 0x50, 0xE1, 0x65, 0x55, 0xE1, 0x00,
|
||||
0x71, 0x24, 0x89, 0x22, 0x50, 0x74, 0x02, 0x70, 0xA4, 0x49, 0x11, 0xC0, 0x70, 0x91, 0x23, 0x86, 0x12, 0xA2, 0x4E, 0xF4, 0xE0,
|
||||
0x5A, 0xAA, 0x94, 0x89, 0x12, 0x49, 0x29, 0x00, 0x27, 0x50, 0x21, 0x3E, 0x42, 0x00, 0xE0, 0xC0, 0x80, 0x24, 0xA4, 0xA4, 0x80,
|
||||
0x74, 0xE3, 0x18, 0xC6, 0x33, 0x70, 0x27, 0x92, 0x49, 0x20, 0x79, 0x10, 0x41, 0x08, 0xC6, 0x10, 0xFC, 0x79, 0x30, 0x43, 0x18,
|
||||
0x10, 0x71, 0x78, 0x08, 0x61, 0x8A, 0x49, 0x2F, 0xC2, 0x08, 0x7D, 0x04, 0x1E, 0x44, 0x10, 0x51, 0x78, 0x74, 0x61, 0xE8, 0xC6,
|
||||
0x31, 0x70, 0xF8, 0x44, 0x22, 0x11, 0x08, 0x40, 0x39, 0x34, 0x53, 0x39, 0x1C, 0x51, 0x38, 0x39, 0x3C, 0x71, 0x4C, 0xF0, 0x53,
|
||||
0x78, 0x82, 0x87, 0x01, 0xF1, 0x83, 0x04, 0xF8, 0x3E, 0x07, 0x06, 0x36, 0x40, 0x74, 0x42, 0x11, 0x10, 0x80, 0x20, 0x0F, 0x86,
|
||||
0x19, 0x9A, 0xA4, 0xD9, 0x13, 0x22, 0x56, 0xDA, 0x6E, 0x60, 0x06, 0x00, 0x3C, 0x00, 0x18, 0x18, 0x3C, 0x24, 0x24, 0x7E, 0x42,
|
||||
0x42, 0xC3, 0xFA, 0x18, 0x61, 0xFA, 0x18, 0x61, 0xFC, 0x3E, 0x63, 0x40, 0x40, 0xC0, 0x40, 0x41, 0x63, 0x3E, 0xF9, 0x0A, 0x1C,
|
||||
0x18, 0x30, 0x61, 0xC2, 0xF8, 0xFE, 0x08, 0x20, 0xFE, 0x08, 0x20, 0xFC, 0xFE, 0x08, 0x20, 0xFA, 0x08, 0x20, 0x80, 0x1E, 0x61,
|
||||
0x40, 0x40, 0xC7, 0x41, 0x41, 0x63, 0x1D, 0x83, 0x06, 0x0C, 0x1F, 0xF0, 0x60, 0xC1, 0x82, 0xFF, 0x80, 0x08, 0x42, 0x10, 0x87,
|
||||
0x29, 0x70, 0x85, 0x12, 0x45, 0x0D, 0x13, 0x22, 0x42, 0x86, 0x84, 0x21, 0x08, 0x42, 0x10, 0xF8, 0xC3, 0xC3, 0xC3, 0xA5, 0xA5,
|
||||
0xA5, 0x99, 0x99, 0x99, 0x83, 0x86, 0x8D, 0x19, 0x33, 0x62, 0xC3, 0x86, 0x1E, 0x31, 0x90, 0x68, 0x1C, 0x0A, 0x05, 0x06, 0xC6,
|
||||
0x1E, 0x00, 0xFA, 0x18, 0x61, 0xFA, 0x08, 0x20, 0x80, 0x1E, 0x31, 0x90, 0x68, 0x1C, 0x0A, 0x05, 0x06, 0xC6, 0x1F, 0x00, 0x00,
|
||||
0xFD, 0x0E, 0x1C, 0x2F, 0x90, 0xA1, 0x42, 0x86, 0x7A, 0x18, 0x30, 0x78, 0x38, 0x61, 0x78, 0xFE, 0x20, 0x40, 0x81, 0x02, 0x04,
|
||||
0x08, 0x10, 0x83, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xE2, 0x78, 0xC2, 0x42, 0x42, 0x64, 0x24, 0x24, 0x38, 0x18, 0x18, 0xC4, 0x28,
|
||||
0xCD, 0x29, 0x25, 0x24, 0xA4, 0x52, 0x8C, 0x61, 0x8C, 0x31, 0x80, 0x42, 0x66, 0x24, 0x18, 0x18, 0x18, 0x24, 0x46, 0x42, 0xC3,
|
||||
0x42, 0x24, 0x34, 0x18, 0x08, 0x08, 0x08, 0x08, 0x7E, 0x0C, 0x30, 0x41, 0x06, 0x18, 0x20, 0xFE, 0xEA, 0xAA, 0xAB, 0x92, 0x24,
|
||||
0x89, 0x20, 0xE9, 0x24, 0x92, 0x49, 0x70, 0x46, 0xA9, 0x10, 0xFE, 0x40, 0x79, 0x20, 0x4F, 0xC6, 0x37, 0x40, 0x84, 0x3D, 0x18,
|
||||
0xC6, 0x31, 0xF0, 0x39, 0x3C, 0x20, 0xC1, 0x33, 0x80, 0x04, 0x13, 0xD3, 0xC6, 0x1C, 0x53, 0x3C, 0x39, 0x38, 0x7F, 0x81, 0x13,
|
||||
0x80, 0x6B, 0xA4, 0x92, 0x40, 0x35, 0x3C, 0x61, 0xC5, 0x33, 0x41, 0x4D, 0xE0, 0x84, 0x3D, 0x38, 0xC6, 0x31, 0x88, 0xBF, 0x80,
|
||||
0x45, 0x55, 0x57, 0x84, 0x25, 0x4E, 0x52, 0xD2, 0x88, 0xFF, 0x80, 0xF7, 0x99, 0x91, 0x91, 0x91, 0x91, 0x91, 0xF4, 0x63, 0x18,
|
||||
0xC6, 0x20, 0x39, 0x3C, 0x61, 0xC5, 0x33, 0x80, 0xF4, 0x63, 0x18, 0xC7, 0xD0, 0x80, 0x3D, 0x3C, 0x61, 0xC5, 0x37, 0x41, 0x04,
|
||||
0xF2, 0x49, 0x20, 0x79, 0x24, 0x1C, 0x0B, 0x27, 0x80, 0x5D, 0x24, 0x93, 0x8C, 0x63, 0x18, 0xCF, 0xA0, 0x85, 0x24, 0x92, 0x30,
|
||||
0xC3, 0x00, 0x89, 0x2C, 0x96, 0x4A, 0xA5, 0x61, 0x30, 0x98, 0x49, 0x23, 0x08, 0x31, 0x2C, 0x80, 0x89, 0x24, 0x94, 0x50, 0xC2,
|
||||
0x08, 0x21, 0x00, 0x78, 0x44, 0x46, 0x23, 0xE0, 0x6A, 0xAA, 0xA9, 0xFF, 0xE0, 0x95, 0x55, 0x56, 0x66, 0x60};
|
||||
/* ' ' 0x20 */
|
||||
/* '!' 0x21 */ 0xFE, 0x80,
|
||||
/* '"' 0x22 */ 0xB6, 0x80,
|
||||
/* '#' 0x23 */ 0x24, 0x49, 0xF9, 0x42, 0x9F, 0x92, 0x28,
|
||||
/* '$' 0x24 */ 0x23, 0xAB, 0x5A, 0x38, 0xB5, 0xAB, 0x88,
|
||||
/* '%' 0x25 */ 0x71, 0x22, 0x88, 0xA2, 0x30, 0x74, 0x02, 0x60, 0xA4, 0x49, 0x11, 0x80,
|
||||
/* '&' 0x26 */ 0x31, 0x24, 0x8C, 0x72, 0x58, 0xA3, 0x74,
|
||||
/* ''' 0x27 */ 0xE0,
|
||||
/* '(' 0x28 */ 0x5A, 0xAA, 0x94,
|
||||
/* ')' 0x29 */ 0x89, 0x12, 0x49, 0x49, 0x00,
|
||||
/* '*' 0x2A */ 0x5E, 0x80,
|
||||
/* '+' 0x2B */ 0x21, 0x3E, 0x42, 0x00,
|
||||
/* ',' 0x2C */ 0xE0,
|
||||
/* '-' 0x2D */ 0xE0,
|
||||
/* '.' 0x2E */ 0x80,
|
||||
/* '/' 0x2F */ 0x25, 0x24, 0xA4, 0x80,
|
||||
/* '0' 0x30 */ 0x76, 0xE3, 0x18, 0xC6, 0x3B, 0x70,
|
||||
/* '1' 0x31 */ 0x5D, 0x55, 0x40,
|
||||
/* '2' 0x32 */ 0x74, 0x42, 0x11, 0x11, 0x10, 0xF8,
|
||||
/* '3' 0x33 */ 0x74, 0x42, 0x13, 0x04, 0x31, 0x70,
|
||||
/* '4' 0x34 */ 0x11, 0x8C, 0xA9, 0x4B, 0xE2, 0x10,
|
||||
/* '5' 0x35 */ 0x7D, 0x04, 0x1E, 0x4C, 0x10, 0x63, 0x78,
|
||||
/* '6' 0x36 */ 0x72, 0x61, 0xE8, 0xC6, 0x39, 0x70,
|
||||
/* '7' 0x37 */ 0xF8, 0x44, 0x22, 0x11, 0x08, 0x40,
|
||||
/* '8' 0x38 */ 0x7A, 0x18, 0x61, 0x7A, 0x18, 0x61, 0x78,
|
||||
/* '9' 0x39 */ 0x7B, 0x28, 0x61, 0xCD, 0xD0, 0x62, 0x70,
|
||||
/* ':' 0x3A */ 0x82,
|
||||
/* ';' 0x3B */ 0x87,
|
||||
/* '<' 0x3C */ 0x3E, 0x30, 0x60, 0x80,
|
||||
/* '=' 0x3D */ 0xF8, 0x3E,
|
||||
/* '>' 0x3E */ 0xE0, 0xC6, 0xC8, 0x00,
|
||||
/* '?' 0x3F */ 0x74, 0x42, 0x11, 0x10, 0x80, 0x20,
|
||||
/* '@' 0x40 */ 0x0F, 0x06, 0x19, 0x3B, 0xC4, 0x99, 0x13, 0x22, 0x64, 0x96, 0x6E, 0x40, 0x04, 0x00, 0x7C, 0x00,
|
||||
/* 'A' 0x41 */ 0x18, 0x18, 0x3C, 0x24, 0x24, 0x7E, 0x42, 0x42, 0xC3,
|
||||
/* 'B' 0x42 */ 0xFA, 0x18, 0x61, 0xFA, 0x18, 0x61, 0xF8,
|
||||
/* 'C' 0x43 */ 0x3E, 0x41, 0x80, 0x80, 0x80, 0x80, 0x81, 0x43, 0x3E,
|
||||
/* 'D' 0x44 */ 0xF9, 0x0A, 0x0C, 0x18, 0x30, 0x60, 0xC2, 0xF8,
|
||||
/* 'E' 0x45 */ 0xFE, 0x08, 0x20, 0xFA, 0x08, 0x20, 0xFC,
|
||||
/* 'F' 0x46 */ 0xFC, 0x21, 0x0F, 0xC2, 0x10, 0x80,
|
||||
/* 'G' 0x47 */ 0x3E, 0x41, 0x80, 0x80, 0x87, 0x81, 0xC1, 0x43, 0x3D,
|
||||
/* 'H' 0x48 */ 0x83, 0x06, 0x0C, 0x1F, 0xF0, 0x60, 0xC1, 0x82,
|
||||
/* 'I' 0x49 */ 0xFF, 0x80,
|
||||
/* 'J' 0x4A */ 0x08, 0x42, 0x10, 0x86, 0x31, 0x70,
|
||||
/* 'K' 0x4B */ 0x86, 0x29, 0x28, 0xD2, 0x48, 0xA1, 0x84,
|
||||
/* 'L' 0x4C */ 0x84, 0x21, 0x08, 0x42, 0x10, 0xF8,
|
||||
/* 'M' 0x4D */ 0xC3, 0xC3, 0xC3, 0xA5, 0xA5, 0xA5, 0x99, 0x99, 0x99,
|
||||
/* 'N' 0x4E */ 0xC3, 0x86, 0x8D, 0x19, 0x33, 0x62, 0xC3, 0x86,
|
||||
/* 'O' 0x4F */ 0x3E, 0x31, 0xB0, 0x70, 0x18, 0x0C, 0x07, 0x06, 0xC6, 0x3E, 0x00,
|
||||
/* 'P' 0x50 */ 0xFA, 0x18, 0x61, 0xFA, 0x08, 0x20, 0x80,
|
||||
/* 'Q' 0x51 */ 0x3E, 0x31, 0xB0, 0x70, 0x18, 0x0C, 0x07, 0x06, 0xC6, 0x3F, 0x00, 0x40,
|
||||
/* 'R' 0x52 */ 0xF9, 0x0A, 0x14, 0x2F, 0x90, 0xA1, 0x42, 0x86,
|
||||
/* 'S' 0x53 */ 0x7A, 0x18, 0x30, 0x78, 0x38, 0x71, 0x78,
|
||||
/* 'T' 0x54 */ 0xFC, 0x41, 0x04, 0x10, 0x41, 0x04, 0x10,
|
||||
/* 'U' 0x55 */ 0x83, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xE3, 0x7C,
|
||||
/* 'V' 0x56 */ 0xC2, 0x85, 0x0B, 0x22, 0x44, 0x8E, 0x0C, 0x18,
|
||||
/* 'W' 0x57 */ 0x84, 0x38, 0xCD, 0x29, 0x25, 0x24, 0xA4, 0xD2, 0x8C, 0x61, 0x8C, 0x31, 0x80,
|
||||
/* 'X' 0x58 */ 0x87, 0x34, 0x8C, 0x30, 0xC4, 0xA3, 0x84,
|
||||
/* 'Y' 0x59 */ 0x82, 0x89, 0x11, 0x43, 0x82, 0x04, 0x08, 0x10,
|
||||
/* 'Z' 0x5A */ 0x7E, 0x0C, 0x30, 0x41, 0x06, 0x18, 0x20, 0xFE,
|
||||
/* '[' 0x5B */ 0xEA, 0xAA, 0xAB,
|
||||
/* '\' 0x5C */ 0x92, 0x24, 0x91, 0x20,
|
||||
/* ']' 0x5D */ 0xD5, 0x55, 0x57,
|
||||
/* '^' 0x5E */ 0x46, 0xA9, 0x10,
|
||||
/* '_' 0x5F */ 0xFE,
|
||||
/* '`' 0x60 */ 0x80,
|
||||
/* 'a' 0x61 */ 0x79, 0x08, 0x11, 0xEC, 0x51, 0x9D, 0x80,
|
||||
/* 'b' 0x62 */ 0x84, 0x3D, 0xB8, 0xC6, 0x3B, 0xF0,
|
||||
/* 'c' 0x63 */ 0x7B, 0x18, 0x20, 0x83, 0x17, 0x80,
|
||||
/* 'd' 0x64 */ 0x04, 0x17, 0xF3, 0x86, 0x18, 0x73, 0x74,
|
||||
/* 'e' 0x65 */ 0x7B, 0x38, 0x7F, 0x83, 0x17, 0x80,
|
||||
/* 'f' 0x66 */ 0x6B, 0xA4, 0x92, 0x40,
|
||||
/* 'g' 0x67 */ 0x77, 0x38, 0x61, 0x87, 0x37, 0x41, 0x8D, 0xE0,
|
||||
/* 'h' 0x68 */ 0x84, 0x2D, 0x98, 0xC6, 0x31, 0x88,
|
||||
/* 'i' 0x69 */ 0xBF, 0x80,
|
||||
/* 'j' 0x6A */ 0x45, 0x55, 0x57,
|
||||
/* 'k' 0x6B */ 0x84, 0x25, 0x6E, 0x72, 0x52, 0x88,
|
||||
/* 'l' 0x6C */ 0xFF, 0x80,
|
||||
/* 'm' 0x6D */ 0xFF, 0x99, 0x91, 0x91, 0x91, 0x91, 0x91,
|
||||
/* 'n' 0x6E */ 0xB6, 0x63, 0x18, 0xC6, 0x20,
|
||||
/* 'o' 0x6F */ 0x7B, 0x38, 0x61, 0x87, 0x37, 0x80,
|
||||
/* 'p' 0x70 */ 0xF6, 0xE3, 0x18, 0xEF, 0xD0, 0x80,
|
||||
/* 'q' 0x71 */ 0x77, 0x38, 0x61, 0x87, 0x37, 0x41, 0x04,
|
||||
/* 'r' 0x72 */ 0xBA, 0x49, 0x20,
|
||||
/* 's' 0x73 */ 0x69, 0x8E, 0x19, 0x60,
|
||||
/* 't' 0x74 */ 0x5D, 0x24, 0x93,
|
||||
/* 'u' 0x75 */ 0x8C, 0x63, 0x18, 0xCD, 0xA0,
|
||||
/* 'v' 0x76 */ 0x85, 0x24, 0x92, 0x30, 0xC3, 0x00,
|
||||
/* 'w' 0x77 */ 0x89, 0x99, 0x59, 0x55, 0x56, 0x66, 0x26,
|
||||
/* 'x' 0x78 */ 0x4A, 0x4C, 0x43, 0x27, 0x20,
|
||||
/* 'y' 0x79 */ 0x85, 0x24, 0x92, 0x30, 0xC3, 0x08, 0x21, 0x80,
|
||||
/* 'z' 0x7A */ 0x78, 0x44, 0x46, 0x23, 0xE0,
|
||||
/* '{' 0x7B */ 0x69, 0x25, 0xB2, 0x49, 0x30,
|
||||
/* '|' 0x7C */ 0xFF, 0xE0,
|
||||
/* '}' 0x7D */ 0xC9, 0x24, 0xDA, 0x49, 0x60,
|
||||
/* '~' 0x7E */ 0x66, 0x70,
|
||||
};
|
||||
|
||||
const GFXglyph FreeSans6pt7bGlyphs[] PROGMEM = {{0, 0, 0, 3, 0, 1}, // 0x20 ' '
|
||||
{0, 2, 9, 4, 1, -8}, // 0x21 '!'
|
||||
{3, 4, 3, 4, 0, -8}, // 0x22 '"'
|
||||
{5, 7, 8, 7, 0, -7}, // 0x23 '#'
|
||||
{12, 6, 11, 7, 0, -9}, // 0x24 '$'
|
||||
{21, 10, 9, 11, 0, -8}, // 0x25 '%'
|
||||
{33, 7, 9, 8, 1, -8}, // 0x26 '&'
|
||||
{41, 1, 3, 2, 1, -8}, // 0x27 '''
|
||||
{42, 2, 11, 4, 1, -8}, // 0x28 '('
|
||||
{45, 3, 11, 4, 0, -8}, // 0x29 ')'
|
||||
{50, 4, 3, 5, 0, -8}, // 0x2A '*'
|
||||
{52, 5, 5, 7, 1, -4}, // 0x2B '+'
|
||||
{56, 1, 3, 3, 1, 0}, // 0x2C ','
|
||||
{57, 2, 1, 4, 1, -3}, // 0x2D '-'
|
||||
{58, 1, 1, 3, 1, 0}, // 0x2E '.'
|
||||
{59, 3, 9, 3, 0, -8}, // 0x2F '/'
|
||||
{63, 5, 9, 7, 1, -8}, // 0x30 '0'
|
||||
{69, 3, 9, 7, 1, -8}, // 0x31 '1'
|
||||
{73, 6, 9, 7, 0, -8}, // 0x32 '2'
|
||||
{80, 6, 9, 7, 0, -8}, // 0x33 '3'
|
||||
{87, 6, 9, 7, 0, -8}, // 0x34 '4'
|
||||
{94, 6, 9, 7, 0, -8}, // 0x35 '5'
|
||||
{101, 5, 9, 7, 1, -8}, // 0x36 '6'
|
||||
{107, 5, 9, 7, 1, -8}, // 0x37 '7'
|
||||
{113, 6, 9, 7, 0, -8}, // 0x38 '8'
|
||||
{120, 6, 9, 7, 0, -8}, // 0x39 '9'
|
||||
{127, 1, 7, 3, 1, -6}, // 0x3A ':'
|
||||
{128, 1, 8, 3, 1, -5}, // 0x3B ';'
|
||||
{129, 5, 6, 7, 1, -5}, // 0x3C '<'
|
||||
{133, 5, 3, 7, 1, -3}, // 0x3D '='
|
||||
{135, 5, 6, 7, 1, -5}, // 0x3E '>'
|
||||
{139, 5, 9, 7, 1, -8}, // 0x3F '?'
|
||||
{145, 11, 11, 12, 0, -8}, // 0x40 '@'
|
||||
{161, 8, 9, 8, 0, -8}, // 0x41 'A'
|
||||
{170, 6, 9, 8, 1, -8}, // 0x42 'B'
|
||||
{177, 8, 9, 9, 0, -8}, // 0x43 'C'
|
||||
{186, 7, 9, 8, 1, -8}, // 0x44 'D'
|
||||
{194, 6, 9, 8, 1, -8}, // 0x45 'E'
|
||||
{201, 6, 9, 7, 1, -8}, // 0x46 'F'
|
||||
{208, 8, 9, 9, 0, -8}, // 0x47 'G'
|
||||
{217, 7, 9, 9, 1, -8}, // 0x48 'H'
|
||||
{225, 1, 9, 3, 1, -8}, // 0x49 'I'
|
||||
{227, 5, 9, 6, 0, -8}, // 0x4A 'J'
|
||||
{233, 7, 9, 8, 1, -8}, // 0x4B 'K'
|
||||
{241, 5, 9, 7, 1, -8}, // 0x4C 'L'
|
||||
{247, 8, 9, 10, 1, -8}, // 0x4D 'M'
|
||||
{256, 7, 9, 9, 1, -8}, // 0x4E 'N'
|
||||
{264, 9, 9, 9, 0, -8}, // 0x4F 'O'
|
||||
{275, 6, 9, 8, 1, -8}, // 0x50 'P'
|
||||
{282, 9, 10, 9, 0, -8}, // 0x51 'Q'
|
||||
{294, 7, 9, 9, 1, -8}, // 0x52 'R'
|
||||
{302, 6, 9, 8, 1, -8}, // 0x53 'S'
|
||||
{309, 7, 9, 8, 0, -8}, // 0x54 'T'
|
||||
{317, 7, 9, 9, 1, -8}, // 0x55 'U'
|
||||
{325, 8, 9, 8, 0, -8}, // 0x56 'V'
|
||||
{334, 11, 9, 11, 0, -8}, // 0x57 'W'
|
||||
{347, 8, 9, 8, 0, -8}, // 0x58 'X'
|
||||
{356, 8, 9, 8, 0, -8}, // 0x59 'Y'
|
||||
{365, 7, 9, 7, 0, -8}, // 0x5A 'Z'
|
||||
{373, 2, 12, 3, 1, -8}, // 0x5B '['
|
||||
{376, 3, 9, 3, 0, -8}, // 0x5C '\'
|
||||
{380, 3, 12, 3, 0, -8}, // 0x5D ']'
|
||||
{385, 4, 5, 6, 1, -8}, // 0x5E '^'
|
||||
{388, 7, 1, 7, 0, 2}, // 0x5F '_'
|
||||
{389, 3, 1, 3, 0, -8}, // 0x60 '`'
|
||||
{390, 6, 7, 7, 0, -6}, // 0x61 'a'
|
||||
{396, 5, 9, 7, 1, -8}, // 0x62 'b'
|
||||
{402, 6, 7, 6, 0, -6}, // 0x63 'c'
|
||||
{408, 6, 9, 7, 0, -8}, // 0x64 'd'
|
||||
{415, 6, 7, 6, 0, -6}, // 0x65 'e'
|
||||
{421, 3, 9, 3, 0, -8}, // 0x66 'f'
|
||||
{425, 6, 10, 7, 0, -6}, // 0x67 'g'
|
||||
{433, 5, 9, 6, 1, -8}, // 0x68 'h'
|
||||
{439, 1, 9, 3, 1, -8}, // 0x69 'i'
|
||||
{441, 2, 12, 3, 0, -8}, // 0x6A 'j'
|
||||
{444, 5, 9, 6, 1, -8}, // 0x6B 'k'
|
||||
{450, 1, 9, 3, 1, -8}, // 0x6C 'l'
|
||||
{452, 8, 7, 10, 1, -6}, // 0x6D 'm'
|
||||
{459, 5, 7, 6, 1, -6}, // 0x6E 'n'
|
||||
{464, 6, 7, 6, 0, -6}, // 0x6F 'o'
|
||||
{470, 5, 9, 7, 1, -6}, // 0x70 'p'
|
||||
{476, 6, 9, 7, 0, -6}, // 0x71 'q'
|
||||
{483, 3, 7, 4, 1, -6}, // 0x72 'r'
|
||||
{486, 6, 7, 6, 0, -6}, // 0x73 's'
|
||||
{492, 3, 8, 3, 0, -7}, // 0x74 't'
|
||||
{495, 5, 7, 6, 1, -6}, // 0x75 'u'
|
||||
{500, 6, 7, 6, 0, -6}, // 0x76 'v'
|
||||
{506, 9, 7, 9, 0, -6}, // 0x77 'w'
|
||||
{514, 6, 7, 6, 0, -6}, // 0x78 'x'
|
||||
{520, 6, 10, 6, 0, -6}, // 0x79 'y'
|
||||
{528, 5, 7, 6, 0, -6}, // 0x7A 'z'
|
||||
{533, 2, 12, 4, 1, -8}, // 0x7B '{'
|
||||
{536, 1, 11, 3, 1, -8}, // 0x7C '|'
|
||||
{538, 2, 12, 4, 1, -8}, // 0x7D '}'
|
||||
{541, 6, 2, 6, 0, -4}}; // 0x7E '~'
|
||||
const GFXglyph FreeSans6pt7bGlyphs[] PROGMEM = {
|
||||
/* ' ' 0x20 */ {0, 0, 0, 3, 0, 0},
|
||||
/* '!' 0x21 */ {0, 1, 9, 4, 2, -8},
|
||||
/* '"' 0x22 */ {2, 3, 3, 4, 0, -8},
|
||||
/* '#' 0x23 */ {4, 7, 8, 7, 0, -7},
|
||||
/* '$' 0x24 */ {11, 5, 11, 7, 1, -9},
|
||||
/* '%' 0x25 */ {18, 10, 9, 11, 0, -8},
|
||||
/* '&' 0x26 */ {30, 6, 9, 8, 1, -8},
|
||||
/* ''' 0x27 */ {37, 1, 3, 2, 1, -8},
|
||||
/* '(' 0x28 */ {38, 2, 11, 4, 1, -8},
|
||||
/* ')' 0x29 */ {41, 3, 11, 4, 0, -8},
|
||||
/* '*' 0x2A */ {46, 3, 3, 5, 1, -8},
|
||||
/* '+' 0x2B */ {48, 5, 5, 7, 1, -4},
|
||||
/* ',' 0x2C */ {52, 1, 3, 3, 1, 0},
|
||||
/* '-' 0x2D */ {53, 3, 1, 4, 1, -3},
|
||||
/* '.' 0x2E */ {54, 1, 1, 3, 1, 0},
|
||||
/* '/' 0x2F */ {55, 3, 9, 3, 0, -8},
|
||||
/* '0' 0x30 */ {59, 5, 9, 7, 1, -8},
|
||||
/* '1' 0x31 */ {65, 2, 9, 7, 2, -8},
|
||||
/* '2' 0x32 */ {68, 5, 9, 7, 1, -8},
|
||||
/* '3' 0x33 */ {74, 5, 9, 7, 1, -8},
|
||||
/* '4' 0x34 */ {80, 5, 9, 7, 1, -8},
|
||||
/* '5' 0x35 */ {86, 6, 9, 7, 0, -8},
|
||||
/* '6' 0x36 */ {93, 5, 9, 7, 1, -8},
|
||||
/* '7' 0x37 */ {99, 5, 9, 7, 1, -8},
|
||||
/* '8' 0x38 */ {105, 6, 9, 7, 0, -8},
|
||||
/* '9' 0x39 */ {112, 6, 9, 7, 0, -8},
|
||||
/* ':' 0x3A */ {119, 1, 7, 3, 1, -6},
|
||||
/* ';' 0x3B */ {120, 1, 8, 3, 1, -5},
|
||||
/* '<' 0x3C */ {121, 5, 5, 7, 1, -4},
|
||||
/* '=' 0x3D */ {125, 5, 3, 7, 1, -3},
|
||||
/* '>' 0x3E */ {127, 5, 5, 7, 1, -4},
|
||||
/* '?' 0x3F */ {131, 5, 9, 7, 1, -8},
|
||||
/* '@' 0x40 */ {137, 11, 11, 12, 0, -8},
|
||||
/* 'A' 0x41 */ {153, 8, 9, 8, 0, -8},
|
||||
/* 'B' 0x42 */ {162, 6, 9, 8, 1, -8},
|
||||
/* 'C' 0x43 */ {169, 8, 9, 9, 0, -8},
|
||||
/* 'D' 0x44 */ {178, 7, 9, 8, 1, -8},
|
||||
/* 'E' 0x45 */ {186, 6, 9, 8, 1, -8},
|
||||
/* 'F' 0x46 */ {193, 5, 9, 7, 1, -8},
|
||||
/* 'G' 0x47 */ {199, 8, 9, 9, 0, -8},
|
||||
/* 'H' 0x48 */ {208, 7, 9, 9, 1, -8},
|
||||
/* 'I' 0x49 */ {216, 1, 9, 3, 1, -8},
|
||||
/* 'J' 0x4A */ {218, 5, 9, 6, 0, -8},
|
||||
/* 'K' 0x4B */ {224, 6, 9, 8, 1, -8},
|
||||
/* 'L' 0x4C */ {231, 5, 9, 7, 1, -8},
|
||||
/* 'M' 0x4D */ {237, 8, 9, 10, 1, -8},
|
||||
/* 'N' 0x4E */ {246, 7, 9, 9, 1, -8},
|
||||
/* 'O' 0x4F */ {254, 9, 9, 9, 0, -8},
|
||||
/* 'P' 0x50 */ {265, 6, 9, 8, 1, -8},
|
||||
/* 'Q' 0x51 */ {272, 9, 10, 9, 0, -8},
|
||||
/* 'R' 0x52 */ {284, 7, 9, 9, 1, -8},
|
||||
/* 'S' 0x53 */ {292, 6, 9, 8, 1, -8},
|
||||
/* 'T' 0x54 */ {299, 6, 9, 8, 0, -8},
|
||||
/* 'U' 0x55 */ {306, 7, 9, 9, 1, -8},
|
||||
/* 'V' 0x56 */ {314, 7, 9, 8, 0, -8},
|
||||
/* 'W' 0x57 */ {322, 11, 9, 11, 0, -8},
|
||||
/* 'X' 0x58 */ {335, 6, 9, 8, 1, -8},
|
||||
/* 'Y' 0x59 */ {342, 7, 9, 8, 1, -8},
|
||||
/* 'Z' 0x5A */ {350, 7, 9, 7, 0, -8},
|
||||
/* '[' 0x5B */ {358, 2, 12, 3, 1, -8},
|
||||
/* '\' 0x5C */ {361, 3, 9, 3, 0, -8},
|
||||
/* ']' 0x5D */ {365, 2, 12, 3, 0, -8},
|
||||
/* '^' 0x5E */ {368, 4, 5, 6, 1, -8},
|
||||
/* '_' 0x5F */ {371, 7, 1, 7, 0, 2},
|
||||
/* '`' 0x60 */ {372, 1, 1, 3, 1, -8},
|
||||
/* 'a' 0x61 */ {373, 7, 7, 7, 0, -6},
|
||||
/* 'b' 0x62 */ {380, 5, 9, 7, 1, -8},
|
||||
/* 'c' 0x63 */ {386, 6, 7, 6, 0, -6},
|
||||
/* 'd' 0x64 */ {392, 6, 9, 7, 0, -8},
|
||||
/* 'e' 0x65 */ {399, 6, 7, 6, 0, -6},
|
||||
/* 'f' 0x66 */ {405, 3, 9, 3, 0, -8},
|
||||
/* 'g' 0x67 */ {409, 6, 10, 7, 0, -6},
|
||||
/* 'h' 0x68 */ {417, 5, 9, 6, 1, -8},
|
||||
/* 'i' 0x69 */ {423, 1, 9, 3, 1, -8},
|
||||
/* 'j' 0x6A */ {425, 2, 12, 3, 0, -8},
|
||||
/* 'k' 0x6B */ {428, 5, 9, 6, 1, -8},
|
||||
/* 'l' 0x6C */ {434, 1, 9, 3, 1, -8},
|
||||
/* 'm' 0x6D */ {436, 8, 7, 10, 1, -6},
|
||||
/* 'n' 0x6E */ {443, 5, 7, 6, 1, -6},
|
||||
/* 'o' 0x6F */ {448, 6, 7, 6, 0, -6},
|
||||
/* 'p' 0x70 */ {454, 5, 9, 7, 1, -6},
|
||||
/* 'q' 0x71 */ {460, 6, 9, 7, 0, -6},
|
||||
/* 'r' 0x72 */ {467, 3, 7, 4, 1, -6},
|
||||
/* 's' 0x73 */ {470, 4, 7, 6, 1, -6},
|
||||
/* 't' 0x74 */ {474, 3, 8, 3, 0, -7},
|
||||
/* 'u' 0x75 */ {477, 5, 7, 6, 1, -6},
|
||||
/* 'v' 0x76 */ {482, 6, 7, 6, 0, -6},
|
||||
/* 'w' 0x77 */ {488, 8, 7, 9, 0, -6},
|
||||
/* 'x' 0x78 */ {495, 5, 7, 6, 0, -6},
|
||||
/* 'y' 0x79 */ {500, 6, 10, 6, 0, -6},
|
||||
/* 'z' 0x7A */ {508, 5, 7, 6, 0, -6},
|
||||
/* '{' 0x7B */ {513, 3, 12, 4, 0, -8},
|
||||
/* '|' 0x7C */ {518, 1, 11, 3, 1, -8},
|
||||
/* '}' 0x7D */ {520, 3, 12, 4, 1, -8},
|
||||
/* '~' 0x7E */ {525, 6, 2, 6, 0, -4},
|
||||
};
|
||||
|
||||
const GFXfont FreeSans6pt7b PROGMEM = {(uint8_t *)FreeSans6pt7bBitmaps, (GFXglyph *)FreeSans6pt7bGlyphs, 0x20, 0x7E, 14};
|
||||
|
||||
// Approx. 1215 bytes
|
||||
|
||||
@@ -1,302 +0,0 @@
|
||||
/*
|
||||
|
||||
Uses Windows-1251 encoding to map translingual Cyrillic characters to range between (uint8_t)127 and (uint8_t)255
|
||||
https://en.wikipedia.org/wiki/Windows-1251
|
||||
|
||||
Cyrillic characters present to the firmware as UTF8.
|
||||
A NicheGraphics implementation needs to identify these, and substitute the appropriate Windows-1251 char value.
|
||||
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
const uint8_t FreeSans6pt8bCyrillicBitmaps[] PROGMEM = {
|
||||
0xFF, 0xA0, 0xC0, 0xFF, 0xA0, 0xC0, 0xB6, 0x80, 0x24, 0x51, 0xF9, 0x42, 0x9F, 0x92, 0x28, 0x31, 0x75, 0x54, 0x78, 0x79, 0x75,
|
||||
0x7C, 0x41, 0x00, 0x01, 0x1C, 0x49, 0x22, 0x50, 0x74, 0x02, 0x60, 0xA4, 0x49, 0x11, 0xC0, 0x21, 0x44, 0x94, 0x62, 0x59, 0xE2,
|
||||
0xF4, 0xE0, 0x6A, 0xAA, 0x90, 0x48, 0x92, 0x49, 0x4A, 0x00, 0x5D, 0x40, 0x21, 0x09, 0xF2, 0x10, 0xE0, 0xC0, 0x80, 0x25, 0x25,
|
||||
0x24, 0x26, 0xA3, 0x18, 0xC6, 0x31, 0xF0, 0x27, 0x92, 0x49, 0x20, 0x11, 0xB4, 0x41, 0x0C, 0xC6, 0x10, 0xFC, 0x26, 0xA2, 0x13,
|
||||
0x04, 0x31, 0xF0, 0x08, 0x61, 0x8A, 0x49, 0x2F, 0xC2, 0x08, 0xFF, 0xE1, 0x4D, 0x84, 0x31, 0xF0, 0x26, 0xE3, 0x0F, 0x46, 0x31,
|
||||
0xF0, 0xFF, 0xC4, 0x22, 0x11, 0x08, 0x40, 0x11, 0xA4, 0x51, 0x39, 0x1C, 0x51, 0x78, 0x11, 0xA4, 0x71, 0x45, 0xF0, 0x51, 0x78,
|
||||
0xC0, 0x30, 0xC0, 0x36, 0x1F, 0x20, 0xE0, 0x80, 0xF8, 0x3E, 0xC1, 0xC2, 0xE8, 0x00, 0x74, 0x62, 0x11, 0x10, 0x80, 0x20, 0x0F,
|
||||
0x06, 0x18, 0x81, 0xA7, 0xD4, 0x93, 0x22, 0x64, 0x4A, 0x7E, 0x60, 0x06, 0x00, 0x3C, 0x00, 0x18, 0x18, 0x1C, 0x24, 0x24, 0x7E,
|
||||
0x42, 0x42, 0xC3, 0xFA, 0x38, 0x61, 0xFA, 0x18, 0x61, 0xFC, 0x38, 0x8A, 0x0C, 0x08, 0x10, 0x20, 0xE3, 0x7C, 0xF9, 0x1A, 0x1C,
|
||||
0x18, 0x30, 0x60, 0xC2, 0xF8, 0xFE, 0x08, 0x20, 0xFE, 0x08, 0x20, 0xFC, 0xFE, 0x08, 0x20, 0xFA, 0x08, 0x20, 0x80, 0x3C, 0x46,
|
||||
0x82, 0x80, 0x8F, 0x81, 0x83, 0xC3, 0x7D, 0x83, 0x06, 0x0C, 0x1F, 0xF0, 0x60, 0xC1, 0x82, 0xFF, 0x80, 0x08, 0x42, 0x10, 0x86,
|
||||
0x31, 0x78, 0x87, 0x1A, 0x65, 0x8F, 0x1A, 0x22, 0x42, 0x86, 0x84, 0x21, 0x08, 0x42, 0x10, 0xF8, 0xC3, 0xC3, 0xC3, 0xA5, 0xA5,
|
||||
0xA5, 0x99, 0x99, 0x99, 0x83, 0x87, 0x8D, 0x19, 0x32, 0x62, 0xC3, 0x86, 0x1E, 0x11, 0x90, 0x48, 0x1C, 0x0A, 0x05, 0x06, 0xC2,
|
||||
0x3E, 0x00, 0xFA, 0x18, 0x61, 0xFE, 0x08, 0x20, 0x80, 0x1E, 0x11, 0x90, 0x48, 0x1C, 0x0A, 0x05, 0x06, 0xC6, 0x3F, 0x00, 0xFD,
|
||||
0x0E, 0x0C, 0x1F, 0xD0, 0xA0, 0xC1, 0x82, 0x7A, 0x18, 0x70, 0x78, 0x38, 0x61, 0x7C, 0xFE, 0x20, 0x40, 0x81, 0x02, 0x04, 0x08,
|
||||
0x10, 0x83, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC3, 0x7C, 0xC3, 0x42, 0x42, 0x26, 0x24, 0x24, 0x14, 0x18, 0x18, 0xC4, 0x28, 0xC5,
|
||||
0x39, 0xA5, 0x24, 0xA4, 0x52, 0x8C, 0x71, 0x8C, 0x30, 0x80, 0x87, 0x34, 0x8C, 0x30, 0xC4, 0xB3, 0x84, 0xC3, 0x42, 0x26, 0x24,
|
||||
0x18, 0x18, 0x08, 0x08, 0x08, 0x7E, 0x0C, 0x10, 0x41, 0x06, 0x08, 0x20, 0xFE, 0xEA, 0xAA, 0xAB, 0x92, 0x24, 0x89, 0x20, 0xED,
|
||||
0xB6, 0xDB, 0x6D, 0xF0, 0x46, 0xAA, 0x90, 0xFC, 0x90, 0xFC, 0x4F, 0x98, 0xFC, 0x84, 0x21, 0xF8, 0xC6, 0x31, 0xF0, 0x79, 0x18,
|
||||
0x20, 0x45, 0xE0, 0x04, 0x10, 0x5F, 0xC6, 0x18, 0x51, 0x7C, 0xFC, 0x7F, 0x08, 0xF8, 0x29, 0x74, 0x92, 0x40, 0x7D, 0x18, 0x61,
|
||||
0x45, 0xF0, 0x52, 0x30, 0x84, 0x21, 0xF8, 0xC6, 0x31, 0x88, 0xDF, 0x80, 0x51, 0x55, 0x56, 0x84, 0x21, 0x2A, 0x72, 0x92, 0x98,
|
||||
0xFF, 0x80, 0xFF, 0x99, 0x99, 0x99, 0x99, 0x99, 0xFC, 0x63, 0x18, 0xC4, 0x79, 0x18, 0x71, 0x45, 0xE0, 0xFC, 0x63, 0x18, 0xFA,
|
||||
0x10, 0x80, 0x7D, 0x18, 0x61, 0x45, 0xF0, 0x41, 0x04, 0xF2, 0x49, 0x00, 0x79, 0x07, 0x02, 0xCD, 0xE0, 0x4B, 0xA4, 0x93, 0x8C,
|
||||
0x63, 0x18, 0xFC, 0xCD, 0x24, 0x94, 0x30, 0xC0, 0x99, 0x59, 0x55, 0x56, 0x66, 0x26, 0x96, 0x66, 0x99, 0xCA, 0x52, 0x63, 0x18,
|
||||
0x84, 0x40, 0x78, 0xC4, 0x44, 0x7C, 0x6A, 0xAA, 0xA9, 0xFF, 0xF0, 0xC9, 0x24, 0x4A, 0x49, 0x40, 0xE8, 0xC0, 0xFE, 0x18, 0x61,
|
||||
0x86, 0x18, 0x61, 0xFC, 0xFC, 0x08, 0x04, 0x02, 0x01, 0xF0, 0x8C, 0x46, 0x23, 0x11, 0x80, 0xC0, 0xC0, 0x10, 0x8F, 0xE0, 0x82,
|
||||
0x08, 0x20, 0x82, 0x08, 0x00, 0x64, 0x0F, 0x88, 0x88, 0x80, 0x3D, 0x0C, 0x2E, 0xF9, 0x04, 0x0F, 0x7C, 0x08, 0x81, 0x10, 0x22,
|
||||
0x04, 0x7C, 0x88, 0x51, 0x0A, 0x21, 0x87, 0xC0, 0x84, 0x10, 0x82, 0x10, 0x42, 0x0F, 0xFD, 0x08, 0xA1, 0x0C, 0x23, 0x87, 0xC0,
|
||||
0x10, 0x88, 0xE6, 0xB3, 0x8C, 0x28, 0x92, 0x28, 0xC0, 0xFC, 0x08, 0x04, 0x02, 0x01, 0xF0, 0x8C, 0x46, 0x23, 0x11, 0x80, 0x83,
|
||||
0x06, 0x0C, 0x18, 0x30, 0x60, 0xC1, 0xFE, 0x20, 0x40, 0x43, 0xC4, 0x1F, 0x45, 0x14, 0x51, 0x44, 0x11, 0x80, 0x78, 0x24, 0x13,
|
||||
0xC9, 0x14, 0x8E, 0x7C, 0x88, 0x44, 0x3F, 0xD1, 0x38, 0x8C, 0x78, 0x60, 0x9A, 0xCC, 0xA9, 0x43, 0xC4, 0x1F, 0x45, 0x14, 0x51,
|
||||
0x44, 0x8C, 0x63, 0x18, 0xFC, 0x80, 0x24, 0x33, 0x0A, 0x36, 0x45, 0x8E, 0x0C, 0x10, 0x60, 0x80, 0x70, 0x22, 0x95, 0xA8, 0xC4,
|
||||
0x23, 0x10, 0x08, 0x42, 0x10, 0x86, 0x31, 0x78, 0x07, 0xF8, 0x20, 0x82, 0x08, 0x20, 0x82, 0x00, 0x28, 0x0F, 0xE0, 0x82, 0x0F,
|
||||
0xE0, 0x82, 0x0F, 0xC0, 0x38, 0x8A, 0x0C, 0x0F, 0x90, 0x20, 0xE3, 0x7C, 0x51, 0x55, 0x56, 0xA1, 0x24, 0x92, 0x49, 0x00, 0xFF,
|
||||
0x80, 0xDF, 0x80, 0x27, 0xC9, 0x24, 0x8A, 0x28, 0xA2, 0x8B, 0xF8, 0x20, 0x80, 0x28, 0xA0, 0x1E, 0x47, 0xFC, 0x11, 0x78, 0x88,
|
||||
0x44, 0x32, 0x59, 0xDA, 0xCD, 0x66, 0x6B, 0x32, 0x89, 0x80, 0x79, 0x1F, 0x30, 0x45, 0xE0, 0x7A, 0x18, 0x70, 0x78, 0x38, 0x61,
|
||||
0x7C, 0x79, 0x07, 0x02, 0xCD, 0xE0, 0xB4, 0x24, 0x92, 0x40, 0x18, 0x18, 0x3C, 0x24, 0x24, 0x7E, 0x42, 0x42, 0xC3, 0xFE, 0x08,
|
||||
0x20, 0xFE, 0x18, 0x61, 0xFC, 0xFA, 0x38, 0x61, 0xFA, 0x18, 0x61, 0xFC, 0xFE, 0x08, 0x20, 0x82, 0x08, 0x20, 0x80, 0x1F, 0x08,
|
||||
0x84, 0x42, 0x21, 0x10, 0x88, 0x44, 0x42, 0xFF, 0xC0, 0x60, 0x20, 0xFE, 0x08, 0x20, 0xFE, 0x08, 0x20, 0xFC, 0x88, 0xA4, 0x9A,
|
||||
0x87, 0xC1, 0xC1, 0xF1, 0xAD, 0x92, 0x88, 0x80, 0x7A, 0x18, 0x41, 0x38, 0x18, 0x61, 0x7C, 0x87, 0x0E, 0x2C, 0x59, 0x34, 0x68,
|
||||
0xE1, 0xC2, 0x28, 0x22, 0x1C, 0x38, 0xB1, 0x64, 0xD1, 0xA3, 0x87, 0x08, 0x8E, 0x6B, 0x38, 0xC2, 0x89, 0x22, 0x8C, 0x3E, 0x44,
|
||||
0x89, 0x12, 0x24, 0x58, 0xA1, 0xC2, 0xC3, 0xC3, 0xC3, 0xA5, 0xA5, 0xA5, 0x99, 0x99, 0x99, 0x83, 0x06, 0x0C, 0x1F, 0xF0, 0x60,
|
||||
0xC1, 0x82, 0x3C, 0x46, 0x83, 0x81, 0x81, 0x81, 0x81, 0xC2, 0x7C, 0xFF, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC1, 0x82, 0xFA, 0x18,
|
||||
0x61, 0xFE, 0x08, 0x20, 0x80, 0x38, 0x8A, 0x0C, 0x08, 0x10, 0x20, 0xE3, 0x7C, 0xFE, 0x20, 0x40, 0x81, 0x02, 0x04, 0x08, 0x10,
|
||||
0xC2, 0x8D, 0x91, 0x63, 0x83, 0x04, 0x18, 0x20, 0x08, 0x1E, 0x32, 0xD1, 0x38, 0x8C, 0x4F, 0x2C, 0xFC, 0x08, 0x00, 0x87, 0x34,
|
||||
0x8C, 0x30, 0xC4, 0xB3, 0x84, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0xFF, 0x01, 0x01, 0x8E, 0x38, 0xE3, 0x8D, 0xF0,
|
||||
0xC3, 0x0C, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0xFF, 0x99, 0x4C, 0xA6, 0x53, 0x29, 0x94, 0xCA, 0x65, 0x32, 0xFF,
|
||||
0x80, 0x40, 0x20, 0xF0, 0x04, 0x01, 0x00, 0x40, 0x1F, 0x84, 0x21, 0x0C, 0x42, 0x1F, 0x00, 0x81, 0xC0, 0xE0, 0x70, 0x3F, 0xDC,
|
||||
0x2E, 0x17, 0x0B, 0xF9, 0x80, 0x82, 0x08, 0x20, 0xFE, 0x18, 0x61, 0xF8, 0x79, 0x8A, 0x18, 0x13, 0xE0, 0x60, 0xC2, 0x7C, 0x87,
|
||||
0x26, 0x39, 0x06, 0x41, 0xF0, 0x64, 0x19, 0x06, 0x63, 0x8F, 0x80, 0x7E, 0x18, 0x61, 0x7C, 0xD6, 0x71, 0x84, 0x79, 0x11, 0xD9,
|
||||
0xCD, 0xD0, 0x0D, 0xC4, 0x1E, 0x47, 0x1C, 0x51, 0x78, 0xF4, 0xBD, 0x29, 0xF8, 0xF8, 0x88, 0x88, 0x3C, 0x48, 0x91, 0x22, 0x5F,
|
||||
0xE0, 0x80, 0x79, 0x1F, 0xF0, 0x45, 0xE0, 0x92, 0x54, 0x38, 0x3C, 0x56, 0x93, 0x78, 0x23, 0x82, 0xCD, 0xE0, 0x9C, 0xEB, 0x5C,
|
||||
0xC4, 0x70, 0x27, 0x3A, 0xD7, 0x31, 0x9A, 0xCC, 0xA9, 0x7A, 0x52, 0x94, 0xE4, 0x8F, 0x3D, 0x6D, 0xA6, 0x90, 0x8C, 0x7F, 0x18,
|
||||
0xC4, 0x79, 0x1C, 0x71, 0x45, 0xE0, 0xFC, 0x63, 0x18, 0xC4, 0xFC, 0x63, 0x18, 0xFA, 0x10, 0x80, 0x79, 0x1C, 0x30, 0x45, 0xE0,
|
||||
0xF9, 0x08, 0x42, 0x10, 0x8A, 0x56, 0xA3, 0x10, 0x8C, 0x40, 0x04, 0x01, 0x07, 0xF9, 0x31, 0xC4, 0x71, 0x14, 0xC5, 0xFE, 0x04,
|
||||
0x01, 0x00, 0x40, 0x4B, 0x8C, 0x65, 0xE4, 0x8A, 0x28, 0xA2, 0x8B, 0xF0, 0x40, 0x99, 0x97, 0x11, 0x96, 0x59, 0x65, 0x97, 0xF0,
|
||||
0x95, 0x2A, 0x54, 0xA9, 0x5F, 0xC0, 0x80, 0xF0, 0x20, 0x78, 0x91, 0x23, 0xC0, 0x86, 0x1F, 0x63, 0x8F, 0xD0, 0x84, 0x3D, 0x18,
|
||||
0xF8, 0xF4, 0xDE, 0x19, 0xF8, 0x9E, 0xA2, 0xE1, 0xA1, 0xA2, 0x9E, 0xFC, 0x7E, 0xD4, 0xC4,
|
||||
};
|
||||
|
||||
const GFXglyph FreeSans6pt8bCyrillicGlyphs[] PROGMEM = {
|
||||
{0, 0, 0, 3, 0, 0}, // 0x20 ' '
|
||||
{3, 2, 9, 3, 1, -8}, // 0x21 '!'
|
||||
{6, 3, 3, 4, 1, -8}, // 0x22 '"'
|
||||
{8, 7, 8, 7, 0, -7}, // 0x23 '#'
|
||||
{15, 6, 11, 7, 0, -8}, // 0x24 '$'
|
||||
{24, 10, 9, 11, 0, -8}, // 0x25 '%'
|
||||
{36, 6, 9, 8, 1, -8}, // 0x26 '&'
|
||||
{43, 1, 3, 2, 1, -8}, // 0x27 '''
|
||||
{44, 2, 10, 4, 1, -7}, // 0x28 '('
|
||||
{47, 3, 11, 4, 0, -7}, // 0x29 ')'
|
||||
{52, 3, 4, 5, 1, -8}, // 0x2A '*'
|
||||
{54, 5, 6, 7, 1, -5}, // 0x2B '+'
|
||||
{58, 1, 3, 3, 1, 0}, // 0x2C ','
|
||||
{59, 2, 1, 4, 1, -3}, // 0x2D '-'
|
||||
{60, 1, 1, 3, 1, 0}, // 0x2E '.'
|
||||
{61, 3, 8, 3, 0, -7}, // 0x2F '/'
|
||||
{64, 5, 9, 7, 1, -8}, // 0x30 '0'
|
||||
{70, 3, 9, 7, 1, -8}, // 0x31 '1'
|
||||
{74, 6, 9, 7, 0, -8}, // 0x32 '2'
|
||||
{81, 5, 9, 7, 1, -8}, // 0x33 '3'
|
||||
{87, 6, 9, 7, 0, -8}, // 0x34 '4'
|
||||
{94, 5, 9, 7, 1, -8}, // 0x35 '5'
|
||||
{100, 5, 9, 7, 1, -8}, // 0x36 '6'
|
||||
{106, 5, 9, 7, 1, -8}, // 0x37 '7'
|
||||
{112, 6, 9, 7, 0, -8}, // 0x38 '8'
|
||||
{119, 6, 9, 7, 0, -8}, // 0x39 '9'
|
||||
{126, 2, 6, 3, 1, -5}, // 0x3A ':'
|
||||
{128, 2, 8, 3, 1, -5}, // 0x3B ';'
|
||||
{130, 5, 5, 7, 1, -4}, // 0x3C '<'
|
||||
{134, 5, 3, 7, 1, -3}, // 0x3D '='
|
||||
{136, 5, 5, 7, 1, -4}, // 0x3E '>'
|
||||
{140, 5, 9, 7, 1, -8}, // 0x3F '?'
|
||||
{146, 11, 11, 12, 0, -8}, // 0x40 '@'
|
||||
{162, 8, 9, 8, 0, -8}, // 0x41 'A'
|
||||
{171, 6, 9, 8, 1, -8}, // 0x42 'B'
|
||||
{178, 7, 9, 9, 1, -8}, // 0x43 'C'
|
||||
{186, 7, 9, 9, 1, -8}, // 0x44 'D'
|
||||
{194, 6, 9, 8, 1, -8}, // 0x45 'E'
|
||||
{201, 6, 9, 7, 1, -8}, // 0x46 'F'
|
||||
{208, 8, 9, 9, 1, -8}, // 0x47 'G'
|
||||
{217, 7, 9, 9, 1, -8}, // 0x48 'H'
|
||||
{225, 1, 9, 3, 1, -8}, // 0x49 'I'
|
||||
{227, 5, 9, 6, 0, -8}, // 0x4A 'J'
|
||||
{233, 7, 9, 8, 1, -8}, // 0x4B 'K'
|
||||
{241, 5, 9, 7, 1, -8}, // 0x4C 'L'
|
||||
{247, 8, 9, 10, 1, -8}, // 0x4D 'M'
|
||||
{256, 7, 9, 9, 1, -8}, // 0x4E 'N'
|
||||
{264, 9, 9, 9, 0, -8}, // 0x4F 'O'
|
||||
{275, 6, 9, 8, 1, -8}, // 0x50 'P'
|
||||
{282, 9, 9, 9, 0, -8}, // 0x51 'Q'
|
||||
{293, 7, 9, 9, 1, -8}, // 0x52 'R'
|
||||
{301, 6, 9, 8, 1, -8}, // 0x53 'S'
|
||||
{308, 7, 9, 7, 0, -8}, // 0x54 'T'
|
||||
{316, 7, 9, 9, 1, -8}, // 0x55 'U'
|
||||
{324, 8, 9, 8, 0, -8}, // 0x56 'V'
|
||||
{333, 11, 9, 11, 0, -8}, // 0x57 'W'
|
||||
{346, 6, 9, 8, 1, -8}, // 0x58 'X'
|
||||
{353, 8, 9, 8, 0, -8}, // 0x59 'Y'
|
||||
{362, 7, 9, 7, 0, -8}, // 0x5A 'Z'
|
||||
{370, 2, 12, 3, 1, -8}, // 0x5B '['
|
||||
{373, 3, 9, 3, 0, -8}, // 0x5C '\'
|
||||
{377, 3, 12, 3, 0, -8}, // 0x5D ']'
|
||||
{382, 4, 5, 6, 1, -8}, // 0x5E '^'
|
||||
{385, 6, 1, 7, 0, 2}, // 0x5F '_'
|
||||
{386, 2, 2, 4, 1, -8}, // 0x60 '`'
|
||||
{387, 5, 6, 7, 1, -5}, // 0x61 'a'
|
||||
{391, 5, 9, 7, 1, -8}, // 0x62 'b'
|
||||
{397, 6, 6, 6, 0, -5}, // 0x63 'c'
|
||||
{402, 6, 9, 7, 0, -8}, // 0x64 'd'
|
||||
{409, 5, 6, 7, 1, -5}, // 0x65 'e'
|
||||
{413, 3, 9, 3, 0, -8}, // 0x66 'f'
|
||||
{417, 6, 9, 7, 0, -5}, // 0x67 'g'
|
||||
{424, 5, 9, 7, 1, -8}, // 0x68 'h'
|
||||
{430, 1, 9, 3, 1, -8}, // 0x69 'i'
|
||||
{432, 2, 12, 3, 0, -8}, // 0x6A 'j'
|
||||
{435, 5, 9, 6, 1, -8}, // 0x6B 'k'
|
||||
{441, 1, 9, 3, 1, -8}, // 0x6C 'l'
|
||||
{443, 8, 6, 10, 1, -5}, // 0x6D 'm'
|
||||
{449, 5, 6, 7, 1, -5}, // 0x6E 'n'
|
||||
{453, 6, 6, 7, 0, -5}, // 0x6F 'o'
|
||||
{458, 5, 9, 7, 1, -5}, // 0x70 'p'
|
||||
{464, 6, 9, 7, 0, -5}, // 0x71 'q'
|
||||
{471, 3, 6, 4, 1, -5}, // 0x72 'r'
|
||||
{474, 6, 6, 6, 0, -5}, // 0x73 's'
|
||||
{479, 3, 8, 3, 0, -7}, // 0x74 't'
|
||||
{482, 5, 6, 7, 1, -5}, // 0x75 'u'
|
||||
{486, 6, 6, 6, 0, -5}, // 0x76 'v'
|
||||
{491, 8, 6, 9, 0, -5}, // 0x77 'w'
|
||||
{497, 4, 6, 6, 1, -5}, // 0x78 'x'
|
||||
{500, 5, 9, 6, 0, -5}, // 0x79 'y'
|
||||
{506, 5, 6, 6, 0, -5}, // 0x7A 'z'
|
||||
{510, 2, 12, 4, 1, -8}, // 0x7B '{'
|
||||
{513, 1, 12, 3, 1, -8}, // 0x7C '|'
|
||||
{515, 3, 12, 4, 0, -8}, // 0x7D '}'
|
||||
{520, 5, 2, 7, 1, -4}, // 0x7E '~'
|
||||
{522, 6, 9, 8, 1, -8}, //
|
||||
{529, 9, 11, 9, 0, -8}, //
|
||||
{542, 6, 11, 7, 1, -10}, //
|
||||
{551, 0, 0, 8, 0, 0}, //
|
||||
{551, 4, 9, 5, 1, -8}, //
|
||||
{556, 0, 0, 8, 0, 0}, //
|
||||
{556, 0, 0, 8, 0, 0}, //
|
||||
{556, 0, 0, 8, 0, 0}, //
|
||||
{556, 0, 0, 8, 0, 0}, //
|
||||
{556, 6, 8, 8, 1, -7}, //
|
||||
{562, 0, 0, 8, 0, 0}, //
|
||||
{562, 11, 9, 13, 1, -8}, //
|
||||
{575, 0, 0, 8, 0, 0}, //
|
||||
{575, 11, 9, 12, 1, -8}, //
|
||||
{588, 6, 11, 8, 1, -10}, //
|
||||
{597, 9, 9, 9, 0, -8}, //
|
||||
{608, 7, 11, 9, 1, -8}, //
|
||||
{618, 6, 11, 7, 0, -8}, //
|
||||
{627, 0, 0, 8, 0, 0}, //
|
||||
{627, 0, 0, 8, 0, 0}, //
|
||||
{627, 0, 0, 8, 0, 0}, //
|
||||
{627, 0, 0, 8, 0, 0}, //
|
||||
{627, 0, 0, 8, 0, 0}, //
|
||||
{627, 0, 0, 8, 0, 0}, //
|
||||
{627, 0, 0, 8, 0, 0}, //
|
||||
{627, 0, 0, 8, 0, 0}, //
|
||||
{627, 0, 0, 8, 0, 0}, //
|
||||
{627, 9, 6, 10, 0, -5}, //
|
||||
{634, 0, 0, 8, 0, 0}, //
|
||||
{634, 9, 6, 10, 1, -5}, //
|
||||
{641, 4, 8, 6, 1, -7}, //
|
||||
{645, 6, 9, 7, 0, -8}, //
|
||||
{652, 5, 7, 7, 1, -5}, //
|
||||
{657, 0, 0, 8, 0, 0}, //
|
||||
{657, 7, 11, 7, 0, -10}, //
|
||||
{667, 5, 11, 6, 0, -7}, //
|
||||
{674, 5, 9, 6, 0, -8}, //
|
||||
{680, 0, 0, 8, 0, 0}, //
|
||||
{680, 6, 10, 7, 1, -9}, //
|
||||
{688, 0, 0, 8, 0, 0}, //
|
||||
{688, 0, 0, 8, 0, 0}, //
|
||||
{688, 6, 11, 8, 1, -10}, //
|
||||
{697, 7, 9, 9, 1, -8}, //
|
||||
{705, 0, 0, 8, 0, 0}, //
|
||||
{705, 0, 0, 8, 0, 0}, //
|
||||
{705, 2, 12, 3, 0, -8}, //
|
||||
{708, 0, 0, 8, 0, 0}, //
|
||||
{708, 0, 0, 8, 0, 0}, //
|
||||
{708, 3, 11, 3, 0, -10}, //
|
||||
{713, 0, 0, 8, 0, 0}, //
|
||||
{713, 0, 0, 8, 0, 0}, //
|
||||
{713, 1, 9, 3, 1, -8}, //
|
||||
{715, 1, 9, 3, 1, -8}, //
|
||||
{717, 3, 8, 5, 1, -7}, //
|
||||
{720, 6, 9, 7, 1, -5}, //
|
||||
{727, 0, 0, 8, 0, 0}, //
|
||||
{727, 0, 0, 8, 0, 0}, //
|
||||
{727, 6, 9, 7, 0, -8}, //
|
||||
{734, 9, 9, 11, 1, -8}, //
|
||||
{745, 6, 6, 6, 0, -5}, //
|
||||
{750, 0, 0, 8, 0, 0}, //
|
||||
{750, 0, 0, 8, 0, 0}, //
|
||||
{750, 6, 9, 8, 1, -8}, //
|
||||
{757, 6, 6, 6, 0, -5}, //
|
||||
{762, 3, 9, 3, 0, -8}, //
|
||||
{766, 8, 9, 8, 0, -8}, //
|
||||
{775, 6, 9, 8, 1, -8}, //
|
||||
{782, 6, 9, 8, 1, -8}, //
|
||||
{789, 6, 9, 7, 1, -8}, //
|
||||
{796, 9, 11, 10, 0, -8}, //
|
||||
{809, 6, 9, 8, 1, -8}, //
|
||||
{816, 9, 9, 11, 1, -8}, //
|
||||
{827, 6, 9, 8, 1, -8}, //
|
||||
{834, 7, 9, 9, 1, -8}, //
|
||||
{842, 7, 11, 9, 1, -10}, //
|
||||
{852, 6, 9, 8, 1, -8}, //
|
||||
{859, 7, 9, 8, 0, -8}, //
|
||||
{867, 8, 9, 10, 1, -8}, //
|
||||
{876, 7, 9, 9, 1, -8}, //
|
||||
{884, 8, 9, 10, 1, -8}, //
|
||||
{893, 7, 9, 9, 1, -8}, //
|
||||
{901, 6, 9, 8, 1, -8}, //
|
||||
{908, 7, 9, 9, 1, -8}, //
|
||||
{916, 7, 9, 7, 0, -8}, //
|
||||
{924, 7, 9, 7, 0, -8}, //
|
||||
{932, 9, 9, 10, 1, -8}, //
|
||||
{943, 6, 9, 8, 1, -8}, //
|
||||
{950, 8, 11, 9, 1, -8}, //
|
||||
{961, 6, 9, 8, 1, -8}, //
|
||||
{968, 8, 9, 10, 1, -8}, //
|
||||
{977, 9, 11, 10, 1, -8}, //
|
||||
{990, 10, 9, 10, 0, -8}, //
|
||||
{1002, 9, 9, 10, 1, -8}, //
|
||||
{1013, 6, 9, 8, 1, -8}, //
|
||||
{1020, 7, 9, 9, 1, -8}, //
|
||||
{1028, 10, 9, 12, 1, -8}, //
|
||||
{1040, 6, 9, 8, 1, -8}, //
|
||||
{1047, 6, 6, 7, 0, -5}, //
|
||||
{1052, 6, 9, 7, 0, -8}, //
|
||||
{1059, 5, 6, 6, 1, -5}, //
|
||||
{1063, 4, 6, 5, 1, -5}, //
|
||||
{1066, 7, 7, 7, 0, -5}, //
|
||||
{1073, 6, 6, 7, 0, -5}, //
|
||||
{1078, 8, 6, 9, 1, -5}, //
|
||||
{1084, 6, 6, 6, 0, -5}, //
|
||||
{1089, 5, 6, 7, 1, -5}, //
|
||||
{1093, 5, 8, 7, 1, -7}, //
|
||||
{1098, 4, 6, 6, 1, -5}, //
|
||||
{1101, 5, 6, 6, 0, -5}, //
|
||||
{1105, 6, 6, 7, 1, -5}, //
|
||||
{1110, 5, 6, 7, 1, -5}, //
|
||||
{1114, 6, 6, 7, 0, -5}, //
|
||||
{1119, 5, 6, 7, 1, -5}, //
|
||||
{1123, 5, 9, 7, 1, -5}, //
|
||||
{1129, 6, 6, 6, 0, -5}, //
|
||||
{1134, 5, 6, 5, 0, -5}, //
|
||||
{1138, 5, 9, 6, 0, -5}, //
|
||||
{1144, 10, 11, 10, 0, -7}, //
|
||||
{1158, 5, 6, 6, 0, -5}, //
|
||||
{1162, 6, 7, 7, 1, -5}, //
|
||||
{1168, 4, 6, 6, 1, -5}, //
|
||||
{1171, 6, 6, 8, 1, -5}, //
|
||||
{1176, 7, 7, 9, 1, -5}, //
|
||||
{1183, 7, 6, 8, 0, -5}, //
|
||||
{1189, 6, 6, 8, 1, -5}, //
|
||||
{1194, 5, 6, 6, 1, -5}, //
|
||||
{1198, 5, 6, 6, 1, -5}, //
|
||||
{1202, 8, 6, 9, 1, -5}, //
|
||||
{1208, 5, 6, 7, 1, -5} //
|
||||
};
|
||||
|
||||
const GFXfont FreeSans6pt8bCyrillic PROGMEM = {(uint8_t *)FreeSans6pt8bCyrillicBitmaps, (GFXglyph *)FreeSans6pt8bCyrillicGlyphs,
|
||||
0x20, 0xFF, 16};
|
||||
@@ -0,0 +1,457 @@
|
||||
#pragma once
|
||||
const uint8_t FreeSans6pt_Win1250Bitmaps[] PROGMEM = {
|
||||
/* ' ' 0x20 */
|
||||
0xFC, 0x80, /* '!' 0x21 */
|
||||
0xB6, 0x80, /* '"' 0x22 */
|
||||
0x24, 0x51, 0xF9, 0x42, 0x9F, 0x92, 0x28, /* '#' 0x23 */
|
||||
0x10, 0xE5, 0x55, 0x50, 0xE1, 0x65, 0x55, 0xE1, 0x00, /* '$' 0x24 */
|
||||
0x71, 0x24, 0x89, 0x22, 0x50, 0x74, 0x02, 0x70, 0xA4, 0x49, 0x11, 0xC0, /* '%' 0x25 */
|
||||
0x71, 0x24, 0x9C, 0x62, 0x58, 0xA7, 0xF4, /* '&' 0x26 */
|
||||
0xE0, /* ''' 0x27 */
|
||||
0x5A, 0xAA, 0x94, /* '(' 0x28 */
|
||||
0x89, 0x12, 0x49, 0x29, 0x00, /* ')' 0x29 */
|
||||
0x5E, 0x80, /* '*' 0x2A */
|
||||
0x21, 0x3E, 0x42, 0x00, /* '+' 0x2B */
|
||||
0xE0, /* ',' 0x2C */
|
||||
0xC0, /* '-' 0x2D */
|
||||
0x80, /* '.' 0x2E */
|
||||
0x24, 0xA4, 0xA4, 0x80, /* '/' 0x2F */
|
||||
0x76, 0xE3, 0x18, 0xC6, 0x3B, 0x70, /* '0' 0x30 */
|
||||
0x27, 0x92, 0x49, 0x20, /* '1' 0x31 */
|
||||
0x79, 0x10, 0x41, 0x08, 0xC6, 0x10, 0xFC, /* '2' 0x32 */
|
||||
0x79, 0x30, 0x43, 0x18, 0x10, 0x71, 0x78, /* '3' 0x33 */
|
||||
0x08, 0x61, 0x8A, 0x49, 0x2F, 0xC2, 0x08, /* '4' 0x34 */
|
||||
0xFC, 0x21, 0xE8, 0x84, 0x31, 0xF0, /* '5' 0x35 */
|
||||
0x74, 0x61, 0xE8, 0xC6, 0x31, 0x70, /* '6' 0x36 */
|
||||
0xF8, 0x44, 0x22, 0x11, 0x08, 0x40, /* '7' 0x37 */
|
||||
0x39, 0x34, 0x53, 0x39, 0x1C, 0x51, 0x38, /* '8' 0x38 */
|
||||
0x39, 0x3C, 0x71, 0x4C, 0xF0, 0x53, 0x78, /* '9' 0x39 */
|
||||
0x82, /* ':' 0x3A */
|
||||
0x87, /* ';' 0x3B */
|
||||
0x3E, 0x30, 0x60, 0x80, /* '<' 0x3C */
|
||||
0xF8, 0x3E, /* '=' 0x3D */
|
||||
0xE0, 0xC6, 0xC8, 0x00, /* '>' 0x3E */
|
||||
0x74, 0x42, 0x11, 0x10, 0x80, 0x20, /* '?' 0x3F */
|
||||
0x0F, 0x86, 0x19, 0x9A, 0xA4, 0xD9, 0x13, 0x22, 0x56, 0xDA, 0x6E, 0x60, 0x06, 0x00, 0x3C, 0x00, /* '@' 0x40 */
|
||||
0x18, 0x18, 0x24, 0x24, 0x24, 0x7E, 0x42, 0x42, 0xC3, /* 'A' 0x41 */
|
||||
0xFA, 0x18, 0x61, 0xFA, 0x18, 0x61, 0xFC, /* 'B' 0x42 */
|
||||
0x3E, 0x63, 0x40, 0x40, 0xC0, 0x40, 0x41, 0x63, 0x3E, /* 'C' 0x43 */
|
||||
0xF9, 0x0A, 0x1C, 0x18, 0x30, 0x61, 0xC2, 0xF8, /* 'D' 0x44 */
|
||||
0xFE, 0x08, 0x20, 0xFE, 0x08, 0x20, 0xFC, /* 'E' 0x45 */
|
||||
0xFE, 0x08, 0x20, 0xFA, 0x08, 0x20, 0x80, /* 'F' 0x46 */
|
||||
0x1E, 0x61, 0x40, 0x40, 0xC7, 0x41, 0x41, 0x63, 0x1D, /* 'G' 0x47 */
|
||||
0x83, 0x06, 0x0C, 0x1F, 0xF0, 0x60, 0xC1, 0x82, /* 'H' 0x48 */
|
||||
0xFF, 0x80, /* 'I' 0x49 */
|
||||
0x08, 0x42, 0x10, 0x87, 0x29, 0x70, /* 'J' 0x4A */
|
||||
0x85, 0x12, 0x45, 0x0D, 0x13, 0x22, 0x42, 0x86, /* 'K' 0x4B */
|
||||
0x84, 0x21, 0x08, 0x42, 0x10, 0xF8, /* 'L' 0x4C */
|
||||
0xC3, 0xC3, 0xC3, 0xA5, 0xA5, 0xA5, 0x99, 0x99, 0x99, /* 'M' 0x4D */
|
||||
0x83, 0x86, 0x8D, 0x19, 0x33, 0x62, 0xC3, 0x86, /* 'N' 0x4E */
|
||||
0x1E, 0x31, 0x90, 0x68, 0x1C, 0x0A, 0x05, 0x06, 0xC6, 0x1E, 0x00, /* 'O' 0x4F */
|
||||
0xFA, 0x18, 0x61, 0xFA, 0x08, 0x20, 0x80, /* 'P' 0x50 */
|
||||
0x1E, 0x31, 0x90, 0x68, 0x1C, 0x0A, 0x05, 0x16, 0xC6, 0x1F, 0x00, 0x40, /* 'Q' 0x51 */
|
||||
0xFD, 0x0E, 0x1C, 0x2F, 0x90, 0xA1, 0x42, 0x86, /* 'R' 0x52 */
|
||||
0x7A, 0x18, 0x30, 0x78, 0x38, 0x61, 0x78, /* 'S' 0x53 */
|
||||
0xFE, 0x20, 0x40, 0x81, 0x02, 0x04, 0x08, 0x10, /* 'T' 0x54 */
|
||||
0x83, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xE2, 0x78, /* 'U' 0x55 */
|
||||
0xC2, 0x85, 0x0B, 0x22, 0x44, 0x8E, 0x0C, 0x18, /* 'V' 0x56 */
|
||||
0xC4, 0x28, 0xCD, 0x29, 0x25, 0x24, 0xA4, 0x52, 0x8C, 0x61, 0x8C, 0x31, 0x80, /* 'W' 0x57 */
|
||||
0x87, 0x34, 0x8C, 0x30, 0xC4, 0xA3, 0x84, /* 'X' 0x58 */
|
||||
0xC3, 0x42, 0x24, 0x34, 0x18, 0x08, 0x08, 0x08, 0x08, /* 'Y' 0x59 */
|
||||
0x7E, 0x0C, 0x30, 0x41, 0x06, 0x18, 0x20, 0xFE, /* 'Z' 0x5A */
|
||||
0xEA, 0xAA, 0xAB, /* '[' 0x5B */
|
||||
0x92, 0x24, 0x89, 0x20, /* '\' 0x5C */
|
||||
0xD5, 0x55, 0x57, /* ']' 0x5D */
|
||||
0x46, 0xA9, /* '^' 0x5E */
|
||||
0xFE, /* '_' 0x5F */
|
||||
0x80, /* '`' 0x60 */
|
||||
0x79, 0x20, 0x4F, 0xC6, 0x37, 0x40, /* 'a' 0x61 */
|
||||
0x84, 0x3D, 0x18, 0xC6, 0x31, 0xF0, /* 'b' 0x62 */
|
||||
0x39, 0x3C, 0x20, 0xC1, 0x33, 0x80, /* 'c' 0x63 */
|
||||
0x04, 0x13, 0xD3, 0xC6, 0x1C, 0x53, 0x3C, /* 'd' 0x64 */
|
||||
0x39, 0x38, 0x7F, 0x81, 0x13, 0x80, /* 'e' 0x65 */
|
||||
0x6B, 0xA4, 0x92, 0x40, /* 'f' 0x66 */
|
||||
0x35, 0x3C, 0x61, 0xC5, 0x33, 0x41, 0x4D, 0xE0, /* 'g' 0x67 */
|
||||
0x84, 0x3D, 0x38, 0xC6, 0x31, 0x88, /* 'h' 0x68 */
|
||||
0xBF, 0x80, /* 'i' 0x69 */
|
||||
0x45, 0x55, 0x57, /* 'j' 0x6A */
|
||||
0x84, 0x25, 0x4E, 0x52, 0xD2, 0x88, /* 'k' 0x6B */
|
||||
0xFF, 0x80, /* 'l' 0x6C */
|
||||
0xF7, 0x99, 0x91, 0x91, 0x91, 0x91, 0x91, /* 'm' 0x6D */
|
||||
0xF4, 0x63, 0x18, 0xC6, 0x20, /* 'n' 0x6E */
|
||||
0x39, 0x3C, 0x61, 0xC5, 0x33, 0x80, /* 'o' 0x6F */
|
||||
0xF4, 0x63, 0x18, 0xC7, 0xD0, 0x80, /* 'p' 0x70 */
|
||||
0x3D, 0x3C, 0x61, 0xC5, 0x37, 0x41, 0x04, /* 'q' 0x71 */
|
||||
0xF2, 0x49, 0x20, /* 'r' 0x72 */
|
||||
0x7A, 0x50, 0xE0, 0xE5, 0xE0, /* 's' 0x73 */
|
||||
0x5D, 0x24, 0x93, /* 't' 0x74 */
|
||||
0x8C, 0x63, 0x18, 0xCF, 0xA0, /* 'u' 0x75 */
|
||||
0x85, 0x24, 0x92, 0x30, 0xC3, 0x00, /* 'v' 0x76 */
|
||||
0x89, 0x59, 0x59, 0x55, 0x56, 0x26, 0x26, /* 'w' 0x77 */
|
||||
0x4A, 0x4C, 0x43, 0x27, 0x20, /* 'x' 0x78 */
|
||||
0x8A, 0x52, 0xA5, 0x18, 0x84, 0x22, 0x00, /* 'y' 0x79 */
|
||||
0x78, 0x44, 0x46, 0x23, 0xE0, /* 'z' 0x7A */
|
||||
0x6A, 0xAA, 0xA9, /* '{' 0x7B */
|
||||
0xFF, 0xE0, /* '|' 0x7C */
|
||||
0x95, 0x55, 0x56, /* '}' 0x7D */
|
||||
0x66, 0x60, /* '~' 0x7E */
|
||||
0xFF, 0xC0, 0x67, 0x34, 0x58, 0x4C, 0x46, 0x03, 0x11, 0x80, 0xFF, 0xC0, /* 0x7F */
|
||||
0x1C, 0x45, 0x07, 0xE4, 0x1F, 0x10, 0x10, 0x1E, /* 0x80 */
|
||||
/* 0x81 */
|
||||
0xE0, /* 0x82 */
|
||||
/* 0x83 */
|
||||
0xB6, 0x80, /* 0x84 */
|
||||
0xA8, /* 0x85 */
|
||||
0x21, 0x09, 0xF2, 0x10, 0x84, 0x21, 0x08, /* 0x86 */
|
||||
0x21, 0x09, 0xF2, 0x10, 0x84, 0xF9, 0x08, /* 0x87 */
|
||||
/* 0x88 */
|
||||
0x62, 0x09, 0x40, 0x98, 0x06, 0x80, 0x10, 0x01, 0x66, 0x29, 0x92, 0x99, 0x06, 0x60, /* 0x89 */
|
||||
0x28, 0x47, 0xA1, 0x83, 0x07, 0x83, 0x87, 0x17, 0x80, /* 0x8A */
|
||||
0x64, /* 0x8B */
|
||||
0x10, 0x87, 0xA1, 0x83, 0x07, 0x83, 0x87, 0x17, 0x80, /* 0x8C */
|
||||
0x28, 0x4F, 0xC4, 0x10, 0x41, 0x04, 0x10, 0x40, /* 0x8D */
|
||||
0x14, 0x11, 0xF8, 0x30, 0xC1, 0x04, 0x18, 0x61, 0xFC, /* 0x8E */
|
||||
0x08, 0x21, 0xF8, 0x30, 0xC1, 0x04, 0x18, 0x61, 0xFC, /* 0x8F */
|
||||
/* 0x90 */
|
||||
0xE0, /* 0x91 */
|
||||
0xE0, /* 0x92 */
|
||||
0xB6, 0x80, /* 0x93 */
|
||||
0xB6, 0x80, /* 0x94 */
|
||||
0xFF, 0x80, /* 0x95 */
|
||||
0xFC, /* 0x96 */
|
||||
0xFF, 0xF0, /* 0x97 */
|
||||
/* 0x98 */
|
||||
0xE6, 0x28, 0xCD, 0x19, 0xA3, 0x34, 0x6A, 0x8B, 0x51, 0x68, /* 0x99 */
|
||||
0x52, 0x69, 0x8E, 0x19, 0x60, /* 0x9A */
|
||||
0x98, /* 0x9B */
|
||||
0x24, 0x06, 0x98, 0xE1, 0x96, /* 0x9C */
|
||||
0x15, 0xE4, 0x44, 0x44, 0x60, /* 0x9D */
|
||||
0x51, 0x00, 0xF0, 0x88, 0x8C, 0x47, 0xC0, /* 0x9E */
|
||||
0x11, 0x00, 0xF0, 0x88, 0x8C, 0x47, 0xC0, /* 0x9F */
|
||||
/* 0xA0 */
|
||||
0xA8, /* 0xA1 */
|
||||
0x96, /* 0xA2 */
|
||||
0x41, 0x05, 0x18, 0x43, 0x04, 0x10, 0x7C, /* 0xA3 */
|
||||
0xFC, 0x63, 0xF0, /* 0xA4 */
|
||||
0x30, 0x38, 0x28, 0x48, 0x4C, 0x7C, 0x84, 0x86, 0x82, 0x04, 0x07, /* 0xA5 */
|
||||
0xF9, 0xF0, /* 0xA6 */
|
||||
0x32, 0x91, 0xC9, 0x47, 0x26, 0x14, 0xA4, 0xC0, /* 0xA7 */
|
||||
0xA0, /* 0xA8 */
|
||||
0x3E, 0x3F, 0xB8, 0xF4, 0x1A, 0x0D, 0x17, 0x76, 0xC6, 0x3E, 0x00, /* 0xA9 */
|
||||
0x7A, 0x18, 0x30, 0x78, 0x38, 0x61, 0x78, 0xC1, 0x0C, /* 0xAA */
|
||||
0x5A, 0xA5, /* 0xAB */
|
||||
0xFC, 0x10, 0x40, /* 0xAC */
|
||||
/* 0xAD */
|
||||
0x3E, 0x31, 0xB7, 0x72, 0x99, 0xCC, 0xC7, 0x56, 0xC6, 0x3E, 0x00, /* 0xAE */
|
||||
0x18, 0x31, 0xF8, 0x30, 0xC1, 0x04, 0x18, 0x61, 0xFC, /* 0xAF */
|
||||
0x69, 0x96, /* 0xB0 */
|
||||
0x21, 0x3E, 0x42, 0x03, 0xE0, /* 0xB1 */
|
||||
0x9C, /* 0xB2 */
|
||||
0x49, 0x35, 0x92, 0x40, /* 0xB3 */
|
||||
0x80, /* 0xB4 */
|
||||
0x8A, 0x28, 0xA2, 0x8A, 0x6E, 0xE0, 0x80, /* 0xB5 */
|
||||
0x7F, 0xAE, 0xBA, 0x68, 0xA2, 0x8A, 0x28, 0xA0, /* 0xB6 */
|
||||
0x80, /* 0xB7 */
|
||||
0x67, 0x80, /* 0xB8 */
|
||||
0x78, 0x84, 0x04, 0x3C, 0xC4, 0x8C, 0x76, 0x04, 0x07, /* 0xB9 */
|
||||
0x69, 0x8E, 0x19, 0x66, 0x26, /* 0xBA */
|
||||
0xA5, 0x5A, /* 0xBB */
|
||||
0xA5, 0x21, 0x08, 0x42, 0x10, 0xF8, /* 0xBC */
|
||||
0xA0, /* 0xBD */
|
||||
0xBA, 0x49, 0x24, 0x90, /* 0xBE */
|
||||
0x31, 0x9E, 0x11, 0x11, 0x88, 0xF8, /* 0xBF */
|
||||
0x10, 0x43, 0xE4, 0x28, 0x50, 0xBE, 0x42, 0x85, 0x0C, /* 0xC0 */
|
||||
0x08, 0x10, 0x00, 0x18, 0x3C, 0x24, 0x24, 0x7E, 0x42, 0xC3, /* 0xC1 */
|
||||
0x18, 0x24, 0x00, 0x18, 0x3C, 0x24, 0x24, 0x7E, 0x42, 0xC3, /* 0xC2 */
|
||||
0x24, 0x18, 0x00, 0x18, 0x3C, 0x24, 0x24, 0x7E, 0x42, 0xC3, /* 0xC3 */
|
||||
0x24, 0x00, 0x18, 0x3C, 0x24, 0x24, 0x7E, 0x42, 0x42, 0xC3, /* 0xC4 */
|
||||
0x11, 0x21, 0x08, 0x42, 0x10, 0x87, 0xC0, /* 0xC5 */
|
||||
0x08, 0x20, 0x01, 0xE4, 0x30, 0x20, 0x40, 0x82, 0x8C, 0xF0, /* 0xC6 */
|
||||
0x3E, 0x61, 0xC0, 0x80, 0x80, 0x80, 0xC1, 0x63, 0x3E, 0x0C, 0x04, 0x1C, /* 0xC7 */
|
||||
0x28, 0x20, 0x01, 0xE4, 0x30, 0x20, 0x40, 0x82, 0x8C, 0xF0, /* 0xC8 */
|
||||
0x08, 0x40, 0x3F, 0x82, 0x0F, 0xA0, 0x83, 0xF0, /* 0xC9 */
|
||||
0xFD, 0x02, 0x04, 0x0F, 0xD0, 0x20, 0x40, 0xFC, 0x10, 0x38, /* 0xCA */
|
||||
0x28, 0x0F, 0xE0, 0x83, 0xE8, 0x20, 0x83, 0xF0, /* 0xCB */
|
||||
0x28, 0x40, 0x3F, 0x82, 0x0F, 0xA0, 0x82, 0x0F, 0xC0, /* 0xCC */
|
||||
0x62, 0xAA, 0xA0, /* 0xCD */
|
||||
0x54, 0x24, 0x92, 0x48, /* 0xCE */
|
||||
0x50, 0x43, 0xE4, 0x28, 0x30, 0x60, 0xC1, 0x85, 0xF0, /* 0xCF */
|
||||
0x7C, 0x42, 0x41, 0x41, 0xF1, 0x41, 0x41, 0x42, 0x7C, /* 0xD0 */
|
||||
0x08, 0x23, 0x0F, 0x1B, 0x32, 0x66, 0xC7, 0x87, 0x04, /* 0xD1 */
|
||||
0x28, 0x23, 0x0F, 0x1B, 0x32, 0x66, 0xC7, 0x87, 0x04, /* 0xD2 */
|
||||
0x04, 0x04, 0x0F, 0x8C, 0x6C, 0x1C, 0x06, 0x03, 0x83, 0x63, 0x1F, 0x00, /* 0xD3 */
|
||||
0x08, 0x0A, 0x00, 0x07, 0xC6, 0x36, 0x0E, 0x03, 0x01, 0xC1, 0xB1, 0x8F, 0x80, /* 0xD4 */
|
||||
0x0A, 0x0A, 0x00, 0x07, 0xC6, 0x36, 0x0E, 0x03, 0x01, 0xC1, 0xB1, 0x8F, 0x80, /* 0xD5 */
|
||||
0x14, 0x00, 0x00, 0x07, 0xC6, 0x36, 0x0E, 0x03, 0x01, 0xC1, 0xB1, 0x8F, 0x80, /* 0xD6 */
|
||||
0x8A, 0x88, 0xA8, 0x80, /* 0xD7 */
|
||||
0x50, 0x43, 0xE4, 0x28, 0x50, 0xBE, 0x42, 0x85, 0x0C, /* 0xD8 */
|
||||
0x10, 0x52, 0x4C, 0x18, 0x30, 0x60, 0xC1, 0xC6, 0xF8, /* 0xD9 */
|
||||
0x08, 0x22, 0x0C, 0x18, 0x30, 0x60, 0xC1, 0xC6, 0xF8, /* 0xDA */
|
||||
0x14, 0x52, 0x0C, 0x18, 0x30, 0x60, 0xC1, 0xC6, 0xF8, /* 0xDB */
|
||||
0x29, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC1, 0xC6, 0xF8, /* 0xDC */
|
||||
0x09, 0x25, 0x12, 0x22, 0x87, 0x04, 0x08, 0x10, 0x20, /* 0xDD */
|
||||
0xFC, 0x41, 0x04, 0x10, 0x41, 0x04, 0x10, 0x60, 0x8E, /* 0xDE */
|
||||
0x7A, 0x18, 0x61, 0x8A, 0x18, 0x61, 0xB8, /* 0xDF */
|
||||
0x42, 0xE9, 0x24, 0x80, /* 0xE0 */
|
||||
0x10, 0x40, 0x03, 0xC8, 0x40, 0x8F, 0x62, 0x8C, 0xEC, /* 0xE1 */
|
||||
0x10, 0x50, 0x03, 0xC8, 0x40, 0x8F, 0x62, 0x8C, 0xEC, /* 0xE2 */
|
||||
0x48, 0x60, 0x03, 0xC8, 0x40, 0x8F, 0x62, 0x8C, 0xEC, /* 0xE3 */
|
||||
0x28, 0x01, 0xE4, 0x20, 0x47, 0xB1, 0x46, 0x76, /* 0xE4 */
|
||||
0x62, 0xAA, 0xA0, /* 0xE5 */
|
||||
0x10, 0x80, 0x1E, 0xC6, 0x08, 0x20, 0xC5, 0xE0, /* 0xE6 */
|
||||
0x7B, 0x18, 0x20, 0x83, 0x17, 0x8C, 0x11, 0xC0, /* 0xE7 */
|
||||
0x28, 0x40, 0x1E, 0xC6, 0x08, 0x20, 0xC5, 0xE0, /* 0xE8 */
|
||||
0x10, 0x80, 0x1E, 0xCE, 0x1F, 0xE0, 0xC5, 0xE0, /* 0xE9 */
|
||||
0x7B, 0x38, 0x7F, 0x83, 0x37, 0x84, 0x1C, /* 0xEA */
|
||||
0x28, 0x07, 0xB3, 0x87, 0xF8, 0x31, 0x78, /* 0xEB */
|
||||
0x28, 0x40, 0x1E, 0xCE, 0x1F, 0xE0, 0xC5, 0xE0, /* 0xEC */
|
||||
0x62, 0xAA, 0xA0, /* 0xED */
|
||||
0x54, 0x24, 0x92, 0x48, /* 0xEE */
|
||||
0x02, 0x0C, 0x13, 0xEC, 0xD0, 0xA1, 0x42, 0xCC, 0xE8, /* 0xEF */
|
||||
0x04, 0x1D, 0xD6, 0x68, 0x50, 0xA1, 0x66, 0x74, /* 0xF0 */
|
||||
0x11, 0x01, 0x6C, 0xC6, 0x31, 0x8C, 0x40, /* 0xF1 */
|
||||
0x20, 0x81, 0x6C, 0xC6, 0x31, 0x8C, 0x40, /* 0xF2 */
|
||||
0x10, 0x80, 0x1E, 0xCE, 0x18, 0x61, 0xCD, 0xE0, /* 0xF3 */
|
||||
0x10, 0xA0, 0x1E, 0xCE, 0x18, 0x61, 0xCD, 0xE0, /* 0xF4 */
|
||||
0x29, 0x40, 0x1E, 0xCE, 0x18, 0x61, 0xCD, 0xE0, /* 0xF5 */
|
||||
0x28, 0x07, 0xB3, 0x86, 0x18, 0x73, 0x78, /* 0xF6 */
|
||||
0x20, 0x3E, 0x02, 0x00, /* 0xF7 */
|
||||
0xA8, 0x5D, 0x24, 0x90, /* 0xF8 */
|
||||
0x22, 0x89, 0x18, 0xC6, 0x31, 0x9B, 0x40, /* 0xF9 */
|
||||
0x11, 0x23, 0x18, 0xC6, 0x33, 0x68, /* 0xFA */
|
||||
0x2A, 0x81, 0x18, 0xC6, 0x31, 0x9B, 0x40, /* 0xFB */
|
||||
0x50, 0x23, 0x18, 0xC6, 0x33, 0x68, /* 0xFC */
|
||||
0x10, 0x88, 0x52, 0x49, 0x23, 0x0C, 0x30, 0x82, 0x18, /* 0xFD */
|
||||
0x4E, 0x44, 0x44, 0x46, 0x31, 0x70, /* 0xFE */
|
||||
0x80, /* 0xFF */
|
||||
};
|
||||
|
||||
const GFXglyph FreeSans6pt_Win1250Glyphs[] PROGMEM = {
|
||||
/* ' ' 0x20 */ {0, 0, 0, 3, 0, 0},
|
||||
/* '!' 0x21 */ {0, 1, 9, 4, 2, -8},
|
||||
/* '"' 0x22 */ {2, 3, 3, 4, 0, -8},
|
||||
/* '#' 0x23 */ {4, 7, 8, 7, 0, -7},
|
||||
/* '$' 0x24 */ {11, 6, 11, 7, 0, -9},
|
||||
/* '%' 0x25 */ {20, 10, 9, 11, 0, -8},
|
||||
/* '&' 0x26 */ {32, 6, 9, 8, 1, -8},
|
||||
/* ''' 0x27 */ {39, 1, 3, 2, 1, -8},
|
||||
/* '(' 0x28 */ {40, 2, 11, 4, 1, -8},
|
||||
/* ')' 0x29 */ {43, 3, 11, 4, 0, -8},
|
||||
/* '*' 0x2A */ {48, 3, 3, 5, 1, -8},
|
||||
/* '+' 0x2B */ {50, 5, 5, 7, 1, -4},
|
||||
/* ',' 0x2C */ {54, 1, 3, 3, 1, 0},
|
||||
/* '-' 0x2D */ {55, 2, 1, 4, 1, -3},
|
||||
/* '.' 0x2E */ {56, 1, 1, 3, 1, 0},
|
||||
/* '/' 0x2F */ {57, 3, 9, 3, 0, -8},
|
||||
/* '0' 0x30 */ {61, 5, 9, 7, 1, -8},
|
||||
/* '1' 0x31 */ {67, 3, 9, 7, 1, -8},
|
||||
/* '2' 0x32 */ {71, 6, 9, 7, 0, -8},
|
||||
/* '3' 0x33 */ {78, 6, 9, 7, 0, -8},
|
||||
/* '4' 0x34 */ {85, 6, 9, 7, 0, -8},
|
||||
/* '5' 0x35 */ {92, 5, 9, 7, 1, -8},
|
||||
/* '6' 0x36 */ {98, 5, 9, 7, 1, -8},
|
||||
/* '7' 0x37 */ {104, 5, 9, 7, 1, -8},
|
||||
/* '8' 0x38 */ {110, 6, 9, 7, 0, -8},
|
||||
/* '9' 0x39 */ {117, 6, 9, 7, 0, -8},
|
||||
/* ':' 0x3A */ {124, 1, 7, 3, 1, -6},
|
||||
/* ';' 0x3B */ {125, 1, 8, 3, 1, -5},
|
||||
/* '<' 0x3C */ {126, 5, 5, 7, 1, -4},
|
||||
/* '=' 0x3D */ {130, 5, 3, 7, 1, -3},
|
||||
/* '>' 0x3E */ {132, 5, 5, 7, 1, -4},
|
||||
/* '?' 0x3F */ {136, 5, 9, 7, 1, -8},
|
||||
/* '@' 0x40 */ {142, 11, 11, 12, 0, -8},
|
||||
/* 'A' 0x41 */ {158, 8, 9, 8, 0, -8},
|
||||
/* 'B' 0x42 */ {167, 6, 9, 8, 1, -8},
|
||||
/* 'C' 0x43 */ {174, 8, 9, 9, 0, -8},
|
||||
/* 'D' 0x44 */ {183, 7, 9, 8, 1, -8},
|
||||
/* 'E' 0x45 */ {191, 6, 9, 8, 1, -8},
|
||||
/* 'F' 0x46 */ {198, 6, 9, 7, 1, -8},
|
||||
/* 'G' 0x47 */ {205, 8, 9, 9, 0, -8},
|
||||
/* 'H' 0x48 */ {214, 7, 9, 9, 1, -8},
|
||||
/* 'I' 0x49 */ {222, 1, 9, 3, 1, -8},
|
||||
/* 'J' 0x4A */ {224, 5, 9, 6, 0, -8},
|
||||
/* 'K' 0x4B */ {230, 7, 9, 8, 1, -8},
|
||||
/* 'L' 0x4C */ {238, 5, 9, 7, 1, -8},
|
||||
/* 'M' 0x4D */ {244, 8, 9, 10, 1, -8},
|
||||
/* 'N' 0x4E */ {253, 7, 9, 9, 1, -8},
|
||||
/* 'O' 0x4F */ {261, 9, 9, 9, 0, -8},
|
||||
/* 'P' 0x50 */ {272, 6, 9, 8, 1, -8},
|
||||
/* 'Q' 0x51 */ {279, 9, 10, 9, 0, -8},
|
||||
/* 'R' 0x52 */ {291, 7, 9, 9, 1, -8},
|
||||
/* 'S' 0x53 */ {299, 6, 9, 8, 1, -8},
|
||||
/* 'T' 0x54 */ {306, 7, 9, 8, 0, -8},
|
||||
/* 'U' 0x55 */ {314, 7, 9, 9, 1, -8},
|
||||
/* 'V' 0x56 */ {322, 7, 9, 8, 0, -8},
|
||||
/* 'W' 0x57 */ {330, 11, 9, 11, 0, -8},
|
||||
/* 'X' 0x58 */ {343, 6, 9, 8, 1, -8},
|
||||
/* 'Y' 0x59 */ {350, 8, 9, 8, 0, -8},
|
||||
/* 'Z' 0x5A */ {359, 7, 9, 7, 0, -8},
|
||||
/* '[' 0x5B */ {367, 2, 12, 3, 1, -8},
|
||||
/* '\' 0x5C */ {370, 3, 9, 3, 0, -8},
|
||||
/* ']' 0x5D */ {374, 2, 12, 3, 0, -8},
|
||||
/* '^' 0x5E */ {377, 4, 4, 6, 1, -8},
|
||||
/* '_' 0x5F */ {379, 7, 1, 7, 0, 2},
|
||||
/* '`' 0x60 */ {380, 1, 1, 3, 1, -8},
|
||||
/* 'a' 0x61 */ {381, 6, 7, 7, 0, -6},
|
||||
/* 'b' 0x62 */ {387, 5, 9, 7, 1, -8},
|
||||
/* 'c' 0x63 */ {393, 6, 7, 6, 0, -6},
|
||||
/* 'd' 0x64 */ {399, 6, 9, 7, 0, -8},
|
||||
/* 'e' 0x65 */ {406, 6, 7, 6, 0, -6},
|
||||
/* 'f' 0x66 */ {412, 3, 9, 3, 0, -8},
|
||||
/* 'g' 0x67 */ {416, 6, 10, 7, 0, -6},
|
||||
/* 'h' 0x68 */ {424, 5, 9, 6, 1, -8},
|
||||
/* 'i' 0x69 */ {430, 1, 9, 3, 1, -8},
|
||||
/* 'j' 0x6A */ {432, 2, 12, 3, 0, -8},
|
||||
/* 'k' 0x6B */ {435, 5, 9, 6, 1, -8},
|
||||
/* 'l' 0x6C */ {441, 1, 9, 3, 1, -8},
|
||||
/* 'm' 0x6D */ {443, 8, 7, 10, 1, -6},
|
||||
/* 'n' 0x6E */ {450, 5, 7, 6, 1, -6},
|
||||
/* 'o' 0x6F */ {455, 6, 7, 6, 0, -6},
|
||||
/* 'p' 0x70 */ {461, 5, 9, 7, 1, -6},
|
||||
/* 'q' 0x71 */ {467, 6, 9, 7, 0, -6},
|
||||
/* 'r' 0x72 */ {474, 3, 7, 4, 1, -6},
|
||||
/* 's' 0x73 */ {477, 5, 7, 6, 0, -6},
|
||||
/* 't' 0x74 */ {482, 3, 8, 3, 0, -7},
|
||||
/* 'u' 0x75 */ {485, 5, 7, 6, 1, -6},
|
||||
/* 'v' 0x76 */ {490, 6, 7, 6, 0, -6},
|
||||
/* 'w' 0x77 */ {496, 8, 7, 9, 0, -6},
|
||||
/* 'x' 0x78 */ {503, 5, 7, 6, 0, -6},
|
||||
/* 'y' 0x79 */ {508, 5, 10, 6, 0, -6},
|
||||
/* 'z' 0x7A */ {515, 5, 7, 6, 0, -6},
|
||||
/* '{' 0x7B */ {520, 2, 12, 4, 1, -8},
|
||||
/* '|' 0x7C */ {523, 1, 11, 3, 1, -8},
|
||||
/* '}' 0x7D */ {525, 2, 12, 4, 1, -8},
|
||||
/* '~' 0x7E */ {528, 6, 2, 6, 0, -4},
|
||||
/* 0x7F */ {530, 9, 10, 11, 1, -8},
|
||||
/* 0x80 */ {542, 7, 9, 8, 0, -8},
|
||||
/* 0x81 */ {550, 0, 0, 8, 0, 0},
|
||||
/* 0x82 */ {550, 1, 3, 3, 1, 0},
|
||||
/* 0x83 */ {551, 0, 0, 8, 0, 0},
|
||||
/* 0x84 */ {551, 3, 3, 5, 1, 0},
|
||||
/* 0x85 */ {553, 5, 1, 7, 1, 0},
|
||||
/* 0x86 */ {554, 5, 11, 7, 1, -8},
|
||||
/* 0x87 */ {561, 5, 11, 7, 1, -8},
|
||||
/* 0x88 */ {568, 0, 0, 8, 0, 0},
|
||||
/* 0x89 */ {568, 12, 9, 12, 0, -8},
|
||||
/* 0x8A */ {582, 6, 11, 8, 1, -9},
|
||||
/* 0x8B */ {591, 2, 3, 4, 1, -4},
|
||||
/* 0x8C */ {592, 6, 11, 8, 1, -10},
|
||||
/* 0x8D */ {601, 6, 10, 8, 0, -9},
|
||||
/* 0x8E */ {609, 7, 10, 7, 0, -9},
|
||||
/* 0x8F */ {618, 7, 10, 7, 0, -9},
|
||||
/* 0x90 */ {627, 0, 0, 8, 0, 0},
|
||||
/* 0x91 */ {627, 1, 3, 3, 1, -8},
|
||||
/* 0x92 */ {628, 1, 3, 2, 1, -8},
|
||||
/* 0x93 */ {629, 3, 3, 5, 1, -8},
|
||||
/* 0x94 */ {631, 3, 3, 5, 1, -8},
|
||||
/* 0x95 */ {633, 3, 3, 5, 1, -5},
|
||||
/* 0x96 */ {635, 6, 1, 6, 0, -3},
|
||||
/* 0x97 */ {636, 12, 1, 12, 0, -3},
|
||||
/* 0x98 */ {638, 0, 0, 8, 0, 0},
|
||||
/* 0x99 */ {638, 11, 7, 12, 1, -8},
|
||||
/* 0x9A */ {648, 4, 9, 6, 1, -8},
|
||||
/* 0x9B */ {653, 2, 3, 3, 1, -4},
|
||||
/* 0x9C */ {654, 4, 10, 6, 1, -9},
|
||||
/* 0x9D */ {659, 4, 9, 5, 0, -8},
|
||||
/* 0x9E */ {664, 5, 10, 6, 0, -9},
|
||||
/* 0x9F */ {671, 5, 10, 6, 0, -9},
|
||||
/* 0xA0 */ {678, 0, 0, 3, 0, 0},
|
||||
/* 0xA1 */ {678, 3, 2, 4, 0, -8},
|
||||
/* 0xA2 */ {679, 4, 2, 4, 0, -8},
|
||||
/* 0xA3 */ {680, 6, 9, 7, 0, -8},
|
||||
/* 0xA4 */ {687, 5, 4, 7, 1, -5},
|
||||
/* 0xA5 */ {690, 8, 11, 8, 1, -8},
|
||||
/* 0xA6 */ {701, 1, 12, 3, 1, -8},
|
||||
/* 0xA7 */ {703, 5, 12, 7, 1, -8},
|
||||
/* 0xA8 */ {711, 3, 1, 4, 0, -7},
|
||||
/* 0xA9 */ {712, 9, 9, 10, 0, -8},
|
||||
/* 0xAA */ {723, 6, 12, 8, 1, -8},
|
||||
/* 0xAB */ {732, 4, 4, 6, 1, -4},
|
||||
/* 0xAC */ {734, 6, 3, 7, 1, -4},
|
||||
/* 0xAD */ {737, 0, 0, 0, 0, 0},
|
||||
/* 0xAE */ {737, 9, 9, 10, 0, -8},
|
||||
/* 0xAF */ {748, 7, 10, 7, 0, -9},
|
||||
/* 0xB0 */ {757, 4, 4, 7, 2, -8},
|
||||
/* 0xB1 */ {759, 5, 7, 7, 1, -6},
|
||||
/* 0xB2 */ {764, 3, 2, 4, 1, 1},
|
||||
/* 0xB3 */ {765, 3, 9, 3, 0, -8},
|
||||
/* 0xB4 */ {769, 1, 1, 4, 1, -8},
|
||||
/* 0xB5 */ {770, 6, 9, 7, 1, -6},
|
||||
/* 0xB6 */ {777, 6, 10, 6, 1, -8},
|
||||
/* 0xB7 */ {785, 1, 1, 3, 1, -2},
|
||||
/* 0xB8 */ {786, 3, 3, 4, 1, 1},
|
||||
/* 0xB9 */ {788, 8, 9, 7, 0, -6},
|
||||
/* 0xBA */ {797, 4, 10, 6, 1, -6},
|
||||
/* 0xBB */ {802, 4, 4, 6, 1, -5},
|
||||
/* 0xBC */ {804, 5, 9, 7, 1, -8},
|
||||
/* 0xBD */ {810, 3, 1, 4, 0, -8},
|
||||
/* 0xBE */ {811, 3, 10, 3, 1, -9},
|
||||
/* 0xBF */ {815, 5, 9, 6, 0, -8},
|
||||
/* 0xC0 */ {821, 7, 10, 9, 1, -9},
|
||||
/* 0xC1 */ {830, 8, 10, 8, 0, -9},
|
||||
/* 0xC2 */ {840, 8, 10, 8, 0, -9},
|
||||
/* 0xC3 */ {850, 8, 10, 8, 0, -9},
|
||||
/* 0xC4 */ {860, 8, 10, 8, 0, -9},
|
||||
/* 0xC5 */ {870, 5, 10, 7, 1, -9},
|
||||
/* 0xC6 */ {877, 7, 11, 9, 0, -10},
|
||||
/* 0xC7 */ {887, 8, 12, 9, 0, -8},
|
||||
/* 0xC8 */ {899, 7, 11, 9, 0, -10},
|
||||
/* 0xC9 */ {909, 6, 10, 8, 1, -9},
|
||||
/* 0xCA */ {917, 7, 11, 8, 1, -8},
|
||||
/* 0xCB */ {927, 6, 10, 8, 1, -9},
|
||||
/* 0xCC */ {935, 6, 11, 8, 1, -10},
|
||||
/* 0xCD */ {944, 2, 10, 3, 1, -9},
|
||||
/* 0xCE */ {947, 3, 10, 4, 0, -9},
|
||||
/* 0xCF */ {951, 7, 10, 8, 1, -9},
|
||||
/* 0xD0 */ {960, 8, 9, 8, 0, -8},
|
||||
/* 0xD1 */ {969, 7, 10, 9, 1, -9},
|
||||
/* 0xD2 */ {978, 7, 10, 9, 1, -9},
|
||||
/* 0xD3 */ {987, 9, 10, 9, 0, -9},
|
||||
/* 0xD4 */ {999, 9, 11, 9, 0, -10},
|
||||
/* 0xD5 */ {1012, 9, 11, 9, 0, -10},
|
||||
/* 0xD6 */ {1025, 9, 11, 9, 0, -10},
|
||||
/* 0xD7 */ {1038, 5, 5, 7, 1, -5},
|
||||
/* 0xD8 */ {1042, 7, 10, 9, 1, -9},
|
||||
/* 0xD9 */ {1051, 7, 10, 9, 1, -9},
|
||||
/* 0xDA */ {1060, 7, 10, 9, 1, -9},
|
||||
/* 0xDB */ {1069, 7, 10, 9, 1, -9},
|
||||
/* 0xDC */ {1078, 7, 10, 9, 1, -9},
|
||||
/* 0xDD */ {1087, 7, 10, 8, 1, -9},
|
||||
/* 0xDE */ {1096, 6, 12, 7, 0, -8},
|
||||
/* 0xDF */ {1105, 6, 9, 7, 1, -8},
|
||||
/* 0xE0 */ {1112, 3, 9, 4, 1, -8},
|
||||
/* 0xE1 */ {1116, 7, 10, 7, 0, -9},
|
||||
/* 0xE2 */ {1125, 7, 10, 7, 0, -9},
|
||||
/* 0xE3 */ {1134, 7, 10, 7, 0, -9},
|
||||
/* 0xE4 */ {1143, 7, 9, 7, 0, -8},
|
||||
/* 0xE5 */ {1151, 2, 10, 3, 1, -9},
|
||||
/* 0xE6 */ {1154, 6, 10, 6, 0, -9},
|
||||
/* 0xE7 */ {1162, 6, 10, 6, 0, -6},
|
||||
/* 0xE8 */ {1170, 6, 10, 6, 0, -9},
|
||||
/* 0xE9 */ {1178, 6, 10, 6, 0, -9},
|
||||
/* 0xEA */ {1186, 6, 9, 6, 0, -6},
|
||||
/* 0xEB */ {1193, 6, 9, 6, 0, -8},
|
||||
/* 0xEC */ {1200, 6, 10, 6, 0, -9},
|
||||
/* 0xED */ {1208, 2, 10, 3, 1, -9},
|
||||
/* 0xEE */ {1211, 3, 10, 3, 0, -9},
|
||||
/* 0xEF */ {1215, 7, 10, 7, 0, -9},
|
||||
/* 0xF0 */ {1224, 7, 9, 7, 0, -8},
|
||||
/* 0xF1 */ {1232, 5, 10, 6, 1, -9},
|
||||
/* 0xF2 */ {1239, 5, 10, 6, 1, -9},
|
||||
/* 0xF3 */ {1246, 6, 10, 6, 0, -9},
|
||||
/* 0xF4 */ {1254, 6, 10, 6, 0, -9},
|
||||
/* 0xF5 */ {1262, 6, 10, 6, 0, -9},
|
||||
/* 0xF6 */ {1270, 6, 9, 6, 0, -8},
|
||||
/* 0xF7 */ {1277, 5, 5, 7, 1, -5},
|
||||
/* 0xF8 */ {1281, 3, 10, 4, 1, -9},
|
||||
/* 0xF9 */ {1285, 5, 10, 6, 1, -9},
|
||||
/* 0xFA */ {1292, 5, 9, 6, 1, -8},
|
||||
/* 0xFB */ {1298, 5, 10, 6, 1, -9},
|
||||
/* 0xFC */ {1305, 5, 9, 6, 1, -8},
|
||||
/* 0xFD */ {1311, 6, 12, 6, 0, -8},
|
||||
/* 0xFE */ {1320, 4, 11, 3, 0, -7},
|
||||
/* 0xFF */ {1326, 1, 1, 4, 1, -7},
|
||||
};
|
||||
|
||||
const GFXfont FreeSans6pt_Win1250 PROGMEM = {(uint8_t *)FreeSans6pt_Win1250Bitmaps, (GFXglyph *)FreeSans6pt_Win1250Glyphs, 0x20,
|
||||
0xFF, 14};
|
||||
@@ -0,0 +1,457 @@
|
||||
#pragma once
|
||||
const uint8_t FreeSans6pt_Win1251Bitmaps[] PROGMEM = {
|
||||
/* ' ' 0x20 */
|
||||
0xFC, 0x80, /* '!' 0x21 */
|
||||
0xB6, 0x80, /* '"' 0x22 */
|
||||
0x24, 0x51, 0xF9, 0x42, 0x9F, 0x92, 0x28, /* '#' 0x23 */
|
||||
0x10, 0xE5, 0x55, 0x50, 0xE1, 0x65, 0x55, 0xE1, 0x00, /* '$' 0x24 */
|
||||
0x71, 0x24, 0x89, 0x22, 0x50, 0x74, 0x02, 0x70, 0xA4, 0x49, 0x11, 0xC0, /* '%' 0x25 */
|
||||
0x71, 0x24, 0x9C, 0x62, 0x58, 0xA7, 0xF4, /* '&' 0x26 */
|
||||
0xE0, /* ''' 0x27 */
|
||||
0x5A, 0xAA, 0x94, /* '(' 0x28 */
|
||||
0x89, 0x12, 0x49, 0x29, 0x00, /* ')' 0x29 */
|
||||
0x5E, 0x80, /* '*' 0x2A */
|
||||
0x21, 0x3E, 0x42, 0x00, /* '+' 0x2B */
|
||||
0xE0, /* ',' 0x2C */
|
||||
0xC0, /* '-' 0x2D */
|
||||
0x80, /* '.' 0x2E */
|
||||
0x24, 0xA4, 0xA4, 0x80, /* '/' 0x2F */
|
||||
0x76, 0xE3, 0x18, 0xC6, 0x3B, 0x70, /* '0' 0x30 */
|
||||
0x27, 0x92, 0x49, 0x20, /* '1' 0x31 */
|
||||
0x79, 0x10, 0x41, 0x08, 0xC6, 0x10, 0xFC, /* '2' 0x32 */
|
||||
0x79, 0x30, 0x43, 0x18, 0x10, 0x71, 0x78, /* '3' 0x33 */
|
||||
0x08, 0x61, 0x8A, 0x49, 0x2F, 0xC2, 0x08, /* '4' 0x34 */
|
||||
0xFC, 0x21, 0xE8, 0x84, 0x31, 0xF0, /* '5' 0x35 */
|
||||
0x74, 0x61, 0xE8, 0xC6, 0x31, 0x70, /* '6' 0x36 */
|
||||
0xF8, 0x44, 0x22, 0x11, 0x08, 0x40, /* '7' 0x37 */
|
||||
0x39, 0x34, 0x53, 0x39, 0x1C, 0x51, 0x38, /* '8' 0x38 */
|
||||
0x39, 0x3C, 0x71, 0x4C, 0xF0, 0x53, 0x78, /* '9' 0x39 */
|
||||
0x82, /* ':' 0x3A */
|
||||
0x87, /* ';' 0x3B */
|
||||
0x3E, 0x30, 0x60, 0x80, /* '<' 0x3C */
|
||||
0xF8, 0x3E, /* '=' 0x3D */
|
||||
0xE0, 0xC6, 0xC8, 0x00, /* '>' 0x3E */
|
||||
0x74, 0x42, 0x11, 0x10, 0x80, 0x20, /* '?' 0x3F */
|
||||
0x0F, 0x86, 0x19, 0x9A, 0xA4, 0xD9, 0x13, 0x22, 0x56, 0xDA, 0x6E, 0x60, 0x06, 0x00, 0x3C, 0x00, /* '@' 0x40 */
|
||||
0x18, 0x18, 0x24, 0x24, 0x24, 0x7E, 0x42, 0x42, 0xC3, /* 'A' 0x41 */
|
||||
0xFA, 0x18, 0x61, 0xFA, 0x18, 0x61, 0xFC, /* 'B' 0x42 */
|
||||
0x3E, 0x63, 0x40, 0x40, 0xC0, 0x40, 0x41, 0x63, 0x3E, /* 'C' 0x43 */
|
||||
0xF9, 0x0A, 0x1C, 0x18, 0x30, 0x61, 0xC2, 0xF8, /* 'D' 0x44 */
|
||||
0xFE, 0x08, 0x20, 0xFE, 0x08, 0x20, 0xFC, /* 'E' 0x45 */
|
||||
0xFE, 0x08, 0x20, 0xFA, 0x08, 0x20, 0x80, /* 'F' 0x46 */
|
||||
0x1E, 0x61, 0x40, 0x40, 0xC7, 0x41, 0x41, 0x63, 0x1D, /* 'G' 0x47 */
|
||||
0x83, 0x06, 0x0C, 0x1F, 0xF0, 0x60, 0xC1, 0x82, /* 'H' 0x48 */
|
||||
0xFF, 0x80, /* 'I' 0x49 */
|
||||
0x08, 0x42, 0x10, 0x87, 0x29, 0x70, /* 'J' 0x4A */
|
||||
0x85, 0x12, 0x45, 0x0D, 0x13, 0x22, 0x42, 0x86, /* 'K' 0x4B */
|
||||
0x84, 0x21, 0x08, 0x42, 0x10, 0xF8, /* 'L' 0x4C */
|
||||
0xC3, 0xC3, 0xC3, 0xA5, 0xA5, 0xA5, 0x99, 0x99, 0x99, /* 'M' 0x4D */
|
||||
0x83, 0x86, 0x8D, 0x19, 0x33, 0x62, 0xC3, 0x86, /* 'N' 0x4E */
|
||||
0x1E, 0x31, 0x90, 0x68, 0x1C, 0x0A, 0x05, 0x06, 0xC6, 0x1E, 0x00, /* 'O' 0x4F */
|
||||
0xFA, 0x18, 0x61, 0xFA, 0x08, 0x20, 0x80, /* 'P' 0x50 */
|
||||
0x1E, 0x31, 0x90, 0x68, 0x1C, 0x0A, 0x05, 0x16, 0xC6, 0x1F, 0x00, 0x40, /* 'Q' 0x51 */
|
||||
0xFD, 0x0E, 0x1C, 0x2F, 0x90, 0xA1, 0x42, 0x86, /* 'R' 0x52 */
|
||||
0x7A, 0x18, 0x30, 0x78, 0x38, 0x61, 0x78, /* 'S' 0x53 */
|
||||
0xFE, 0x20, 0x40, 0x81, 0x02, 0x04, 0x08, 0x10, /* 'T' 0x54 */
|
||||
0x83, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xE2, 0x78, /* 'U' 0x55 */
|
||||
0xC2, 0x85, 0x0B, 0x22, 0x44, 0x8E, 0x0C, 0x18, /* 'V' 0x56 */
|
||||
0xC4, 0x28, 0xCD, 0x29, 0x25, 0x24, 0xA4, 0x52, 0x8C, 0x61, 0x8C, 0x31, 0x80, /* 'W' 0x57 */
|
||||
0x87, 0x34, 0x8C, 0x30, 0xC4, 0xA3, 0x84, /* 'X' 0x58 */
|
||||
0xC3, 0x42, 0x24, 0x34, 0x18, 0x08, 0x08, 0x08, 0x08, /* 'Y' 0x59 */
|
||||
0x7E, 0x0C, 0x30, 0x41, 0x06, 0x18, 0x20, 0xFE, /* 'Z' 0x5A */
|
||||
0xEA, 0xAA, 0xAB, /* '[' 0x5B */
|
||||
0x92, 0x24, 0x89, 0x20, /* '\' 0x5C */
|
||||
0xD5, 0x55, 0x57, /* ']' 0x5D */
|
||||
0x46, 0xA9, /* '^' 0x5E */
|
||||
0xFE, /* '_' 0x5F */
|
||||
0x80, /* '`' 0x60 */
|
||||
0x79, 0x20, 0x4F, 0xC6, 0x37, 0x40, /* 'a' 0x61 */
|
||||
0x84, 0x3D, 0x18, 0xC6, 0x31, 0xF0, /* 'b' 0x62 */
|
||||
0x39, 0x3C, 0x20, 0xC1, 0x33, 0x80, /* 'c' 0x63 */
|
||||
0x04, 0x13, 0xD3, 0xC6, 0x1C, 0x53, 0x3C, /* 'd' 0x64 */
|
||||
0x39, 0x38, 0x7F, 0x81, 0x13, 0x80, /* 'e' 0x65 */
|
||||
0x6B, 0xA4, 0x92, 0x40, /* 'f' 0x66 */
|
||||
0x35, 0x3C, 0x61, 0xC5, 0x33, 0x41, 0x4D, 0xE0, /* 'g' 0x67 */
|
||||
0x84, 0x3D, 0x38, 0xC6, 0x31, 0x88, /* 'h' 0x68 */
|
||||
0xBF, 0x80, /* 'i' 0x69 */
|
||||
0x45, 0x55, 0x57, /* 'j' 0x6A */
|
||||
0x84, 0x25, 0x4E, 0x52, 0xD2, 0x88, /* 'k' 0x6B */
|
||||
0xFF, 0x80, /* 'l' 0x6C */
|
||||
0xF7, 0x99, 0x91, 0x91, 0x91, 0x91, 0x91, /* 'm' 0x6D */
|
||||
0xF4, 0x63, 0x18, 0xC6, 0x20, /* 'n' 0x6E */
|
||||
0x39, 0x3C, 0x61, 0xC5, 0x33, 0x80, /* 'o' 0x6F */
|
||||
0xF4, 0x63, 0x18, 0xC7, 0xD0, 0x80, /* 'p' 0x70 */
|
||||
0x3D, 0x3C, 0x61, 0xC5, 0x37, 0x41, 0x04, /* 'q' 0x71 */
|
||||
0xF2, 0x49, 0x20, /* 'r' 0x72 */
|
||||
0x7A, 0x50, 0xE0, 0xE5, 0xE0, /* 's' 0x73 */
|
||||
0x5D, 0x24, 0x93, /* 't' 0x74 */
|
||||
0x8C, 0x63, 0x18, 0xCF, 0xA0, /* 'u' 0x75 */
|
||||
0x85, 0x24, 0x92, 0x30, 0xC3, 0x00, /* 'v' 0x76 */
|
||||
0x89, 0x59, 0x59, 0x55, 0x56, 0x26, 0x26, /* 'w' 0x77 */
|
||||
0x4A, 0x4C, 0x43, 0x27, 0x20, /* 'x' 0x78 */
|
||||
0x8A, 0x52, 0xA5, 0x18, 0x84, 0x22, 0x00, /* 'y' 0x79 */
|
||||
0x78, 0x44, 0x46, 0x23, 0xE0, /* 'z' 0x7A */
|
||||
0x6A, 0xAA, 0xA9, /* '{' 0x7B */
|
||||
0xFF, 0xE0, /* '|' 0x7C */
|
||||
0x95, 0x55, 0x56, /* '}' 0x7D */
|
||||
0x66, 0x60, /* '~' 0x7E */
|
||||
0xFF, 0xC0, 0x67, 0x34, 0x58, 0x4C, 0x46, 0x03, 0x11, 0x80, 0xFF, 0xC0, /* 0x7F */
|
||||
0xFC, 0x08, 0x04, 0x02, 0x01, 0xF0, 0x8C, 0x46, 0x23, 0x11, 0x80, 0xC0, 0xC0, /* 0x80 */
|
||||
0x10, 0x8F, 0xE0, 0x82, 0x08, 0x20, 0x82, 0x00, /* 0x81 */
|
||||
0xE0, /* 0x82 */
|
||||
0x24, 0x0F, 0x88, 0x88, 0x80, /* 0x83 */
|
||||
0xB6, 0x80, /* 0x84 */
|
||||
0xA8, /* 0x85 */
|
||||
0x21, 0x09, 0xF2, 0x10, 0x84, 0x21, 0x08, /* 0x86 */
|
||||
0x21, 0x09, 0xF2, 0x10, 0x84, 0xF9, 0x08, /* 0x87 */
|
||||
0x1C, 0x45, 0x07, 0xE4, 0x1F, 0x10, 0x10, 0x1E, /* 0x88 */
|
||||
0x62, 0x09, 0x40, 0x98, 0x06, 0x80, 0x10, 0x01, 0x66, 0x29, 0x92, 0x99, 0x06, 0x60, /* 0x89 */
|
||||
0x7C, 0x08, 0x81, 0x10, 0x22, 0x04, 0x7C, 0x88, 0x51, 0x0A, 0x21, 0x87, 0xC0, /* 0x8A */
|
||||
0x64, /* 0x8B */
|
||||
0x84, 0x10, 0x82, 0x10, 0x42, 0x0F, 0xFD, 0x08, 0xA1, 0x0C, 0x23, 0x87, 0xC0, /* 0x8C */
|
||||
0x10, 0x88, 0xE6, 0xB3, 0x8C, 0x28, 0x92, 0x28, 0xC0, /* 0x8D */
|
||||
0xFC, 0x08, 0x04, 0x02, 0x01, 0xF0, 0x8C, 0x46, 0x23, 0x11, 0x80, /* 0x8E */
|
||||
0x83, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC1, 0xFE, 0x20, 0x40, /* 0x8F */
|
||||
0x43, 0xC4, 0x1F, 0x45, 0x14, 0x51, 0x44, 0x11, 0x80, /* 0x90 */
|
||||
0xE0, /* 0x91 */
|
||||
0xE0, /* 0x92 */
|
||||
0xB6, 0x80, /* 0x93 */
|
||||
0xB6, 0x80, /* 0x94 */
|
||||
0xFF, 0x80, /* 0x95 */
|
||||
0xFC, /* 0x96 */
|
||||
0xFF, 0xF0, /* 0x97 */
|
||||
/* 0x98 */
|
||||
0xE6, 0x28, 0xCD, 0x19, 0xA3, 0x34, 0x6A, 0x8B, 0x51, 0x68, /* 0x99 */
|
||||
0x78, 0x24, 0x13, 0xC9, 0x14, 0x8E, 0x7C, /* 0x9A */
|
||||
0x98, /* 0x9B */
|
||||
0x88, 0x44, 0x3F, 0xD1, 0x38, 0x8C, 0x78, /* 0x9C */
|
||||
0x24, 0x09, 0xAC, 0xCA, 0x90, /* 0x9D */
|
||||
0x43, 0xC4, 0x1F, 0x45, 0x14, 0x51, 0x44, /* 0x9E */
|
||||
0x8C, 0x63, 0x18, 0xFC, 0x80, /* 0x9F */
|
||||
/* 0xA0 */
|
||||
0x24, 0x33, 0x0A, 0x36, 0x45, 0x8E, 0x0C, 0x10, 0x60, 0x80, /* 0xA1 */
|
||||
0x51, 0x22, 0x95, 0xA8, 0xC4, 0x23, 0x10, /* 0xA2 */
|
||||
0x08, 0x42, 0x10, 0x86, 0x31, 0x78, /* 0xA3 */
|
||||
0xFC, 0x63, 0xF0, /* 0xA4 */
|
||||
0x07, 0xF8, 0x20, 0x82, 0x08, 0x20, 0x82, 0x00, /* 0xA5 */
|
||||
0xF9, 0xF0, /* 0xA6 */
|
||||
0x32, 0x91, 0xC9, 0x47, 0x26, 0x14, 0xA4, 0xC0, /* 0xA7 */
|
||||
0x28, 0x0F, 0xE0, 0x82, 0x0F, 0xE0, 0x82, 0x0F, 0xC0, /* 0xA8 */
|
||||
0x3E, 0x3F, 0xB8, 0xF4, 0x1A, 0x0D, 0x17, 0x76, 0xC6, 0x3E, 0x00, /* 0xA9 */
|
||||
0x38, 0x8A, 0x0C, 0x0F, 0x90, 0x20, 0xE3, 0x7C, /* 0xAA */
|
||||
0x5A, 0xA5, /* 0xAB */
|
||||
0x51, 0x55, 0x56, /* 0xAC */
|
||||
/* 0xAD */
|
||||
0x3E, 0x31, 0xB7, 0x72, 0x99, 0xCC, 0xC7, 0x56, 0xC6, 0x3E, 0x00, /* 0xAE */
|
||||
0xA1, 0x24, 0x92, 0x49, 0x00, /* 0xAF */
|
||||
0x69, 0x96, /* 0xB0 */
|
||||
0x21, 0x3E, 0x42, 0x03, 0xE0, /* 0xB1 */
|
||||
0xFF, 0x80, /* 0xB2 */
|
||||
0xDF, 0x80, /* 0xB3 */
|
||||
0x27, 0xC9, 0x24, /* 0xB4 */
|
||||
0x8A, 0x28, 0xA2, 0x8A, 0x6E, 0xE0, 0x80, /* 0xB5 */
|
||||
0x7F, 0xAE, 0xBA, 0x68, 0xA2, 0x8A, 0x28, 0xA0, /* 0xB6 */
|
||||
0x80, /* 0xB7 */
|
||||
0x28, 0xA0, 0x1E, 0x47, 0xFC, 0x11, 0x78, /* 0xB8 */
|
||||
0x88, 0x44, 0x32, 0x59, 0xDA, 0xCD, 0x66, 0x6B, 0x32, 0x8B, 0x80, /* 0xB9 */
|
||||
0x79, 0x1F, 0x30, 0x45, 0xE0, /* 0xBA */
|
||||
0xA5, 0x5A, /* 0xBB */
|
||||
0x45, 0x55, 0x57, /* 0xBC */
|
||||
0x7A, 0x18, 0x70, 0x78, 0x38, 0x61, 0x7C, /* 0xBD */
|
||||
0x7A, 0x1C, 0x1C, 0xBC, /* 0xBE */
|
||||
0xB4, 0x24, 0x92, 0x40, /* 0xBF */
|
||||
0x18, 0x18, 0x3C, 0x24, 0x24, 0x7E, 0x42, 0x42, 0xC3, /* 0xC0 */
|
||||
0xFE, 0x08, 0x20, 0xFA, 0x18, 0x61, 0xF8, /* 0xC1 */
|
||||
0xFA, 0x18, 0x61, 0xFA, 0x18, 0x61, 0xFC, /* 0xC2 */
|
||||
0xFE, 0x08, 0x20, 0x82, 0x08, 0x20, 0x80, /* 0xC3 */
|
||||
0x1F, 0x08, 0x84, 0x42, 0x21, 0x10, 0x88, 0x44, 0x42, 0xFF, 0xC0, 0x60, 0x20, /* 0xC4 */
|
||||
0xFE, 0x08, 0x20, 0xFE, 0x08, 0x20, 0xFC, /* 0xC5 */
|
||||
0x88, 0xA4, 0x9A, 0x87, 0xC1, 0xC1, 0xF1, 0xAD, 0x92, 0x88, 0x80, /* 0xC6 */
|
||||
0x7A, 0x18, 0x41, 0x38, 0x18, 0x61, 0x7C, /* 0xC7 */
|
||||
0x87, 0x0E, 0x2C, 0x59, 0x34, 0x68, 0xE1, 0xC2, /* 0xC8 */
|
||||
0x28, 0x22, 0x1C, 0x38, 0xB1, 0x64, 0xD1, 0xA3, 0x87, 0x08, /* 0xC9 */
|
||||
0x8E, 0x6B, 0x38, 0xC2, 0x89, 0x22, 0x8C, /* 0xCA */
|
||||
0x3E, 0x44, 0x89, 0x12, 0x24, 0x58, 0xA1, 0xC2, /* 0xCB */
|
||||
0xC3, 0xC3, 0xC3, 0xA5, 0xA5, 0xA5, 0x99, 0x99, 0x99, /* 0xCC */
|
||||
0x83, 0x06, 0x0C, 0x1F, 0xF0, 0x60, 0xC1, 0x82, /* 0xCD */
|
||||
0x3C, 0x42, 0x81, 0x81, 0x81, 0x81, 0x81, 0xC2, 0x7C, /* 0xCE */
|
||||
0xFF, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC1, 0x82, /* 0xCF */
|
||||
0xFA, 0x18, 0x61, 0xFE, 0x08, 0x20, 0x80, /* 0xD0 */
|
||||
0x38, 0x8A, 0x0C, 0x08, 0x10, 0x20, 0xE3, 0x7C, /* 0xD1 */
|
||||
0xFE, 0x20, 0x40, 0x81, 0x02, 0x04, 0x08, 0x10, /* 0xD2 */
|
||||
0xC2, 0x8D, 0x91, 0x63, 0x83, 0x04, 0x18, 0x20, /* 0xD3 */
|
||||
0x08, 0x1F, 0x32, 0x71, 0x18, 0x8C, 0x47, 0x26, 0xFE, 0x08, 0x00, /* 0xD4 */
|
||||
0x87, 0x34, 0x8C, 0x30, 0xC4, 0xB3, 0x84, /* 0xD5 */
|
||||
0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0xFF, 0x01, 0x01, /* 0xD6 */
|
||||
0x8E, 0x38, 0xE3, 0x8D, 0xF0, 0xC3, 0x0C, /* 0xD7 */
|
||||
0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0xFF, /* 0xD8 */
|
||||
0x99, 0x4C, 0xA6, 0x53, 0x29, 0x94, 0xCA, 0x65, 0x32, 0xFF, 0x80, 0x40, 0x20, /* 0xD9 */
|
||||
0xF0, 0x04, 0x01, 0x00, 0x40, 0x1F, 0x84, 0x21, 0x0C, 0x42, 0x1F, 0x00, /* 0xDA */
|
||||
0x81, 0xC0, 0xE0, 0x70, 0x3F, 0xDC, 0x2E, 0x17, 0x0B, 0xF9, 0x80, /* 0xDB */
|
||||
0x82, 0x08, 0x20, 0xFE, 0x18, 0x61, 0xF8, /* 0xDC */
|
||||
0x79, 0x8A, 0x18, 0x13, 0xE0, 0x60, 0xC2, 0x7C, /* 0xDD */
|
||||
0x87, 0x26, 0x39, 0x06, 0x41, 0xF0, 0x64, 0x19, 0x06, 0x63, 0x8F, 0x80, /* 0xDE */
|
||||
0x7E, 0x18, 0x61, 0x7C, 0xD6, 0x71, 0x84, /* 0xDF */
|
||||
0x79, 0x11, 0xD9, 0xCD, 0xD0, /* 0xE0 */
|
||||
0x0D, 0xC4, 0x1E, 0x47, 0x1C, 0x51, 0x78, /* 0xE1 */
|
||||
0xF4, 0xBD, 0x29, 0xF8, /* 0xE2 */
|
||||
0xF8, 0x88, 0x88, /* 0xE3 */
|
||||
0x3C, 0x48, 0x91, 0x22, 0x5F, 0xE0, 0x80, /* 0xE4 */
|
||||
0x79, 0x1F, 0xF0, 0x45, 0xE0, /* 0xE5 */
|
||||
0x92, 0x54, 0x38, 0x3C, 0x56, 0x93, /* 0xE6 */
|
||||
0x78, 0x23, 0x82, 0xCD, 0xE0, /* 0xE7 */
|
||||
0x9C, 0xEB, 0x5C, 0xC4, /* 0xE8 */
|
||||
0x70, 0x27, 0x3A, 0xD7, 0x31, /* 0xE9 */
|
||||
0x9A, 0xCC, 0xA9, /* 0xEA */
|
||||
0x7A, 0x52, 0x94, 0xE4, /* 0xEB */
|
||||
0x8F, 0x3D, 0x6D, 0xA6, 0x90, /* 0xEC */
|
||||
0x8C, 0x7F, 0x18, 0xC4, /* 0xED */
|
||||
0x79, 0x1C, 0x71, 0x45, 0xE0, /* 0xEE */
|
||||
0xFC, 0x63, 0x18, 0xC4, /* 0xEF */
|
||||
0xFC, 0x63, 0x18, 0xFA, 0x10, 0x80, /* 0xF0 */
|
||||
0x79, 0x1C, 0x30, 0x45, 0xE0, /* 0xF1 */
|
||||
0xF9, 0x08, 0x42, 0x10, /* 0xF2 */
|
||||
0x8A, 0x56, 0xA3, 0x10, 0x8C, 0x40, /* 0xF3 */
|
||||
0x04, 0x01, 0x07, 0xF9, 0x31, 0xC4, 0x71, 0x14, 0xC5, 0xFE, 0x04, 0x01, 0x00, 0x40, /* 0xF4 */
|
||||
0x4B, 0x8C, 0x65, 0xE4, /* 0xF5 */
|
||||
0x8A, 0x28, 0xA2, 0x8B, 0xF0, 0x40, /* 0xF6 */
|
||||
0x99, 0x97, 0x11, /* 0xF7 */
|
||||
0x96, 0x59, 0x65, 0x97, 0xF0, /* 0xF8 */
|
||||
0x95, 0x2A, 0x54, 0xA9, 0x5F, 0xC0, 0x80, /* 0xF9 */
|
||||
0xF0, 0x20, 0x78, 0x91, 0x23, 0xC0, /* 0xFA */
|
||||
0x86, 0x1F, 0x63, 0x8F, 0xD0, /* 0xFB */
|
||||
0x84, 0x3D, 0x18, 0xF8, /* 0xFC */
|
||||
0xF4, 0xDE, 0x19, 0xF8, /* 0xFD */
|
||||
0x9E, 0xA2, 0xE1, 0xA1, 0xA2, 0x9E, /* 0xFE */
|
||||
0xFC, 0x7E, 0xD4, 0xC4, /* 0xFF */
|
||||
};
|
||||
|
||||
const GFXglyph FreeSans6pt_Win1251Glyphs[] PROGMEM = {
|
||||
/* ' ' 0x20 */ {0, 0, 0, 3, 0, 0},
|
||||
/* '!' 0x21 */ {0, 1, 9, 4, 2, -8},
|
||||
/* '"' 0x22 */ {2, 3, 3, 4, 0, -8},
|
||||
/* '#' 0x23 */ {4, 7, 8, 7, 0, -7},
|
||||
/* '$' 0x24 */ {11, 6, 11, 7, 0, -9},
|
||||
/* '%' 0x25 */ {20, 10, 9, 11, 0, -8},
|
||||
/* '&' 0x26 */ {32, 6, 9, 8, 1, -8},
|
||||
/* ''' 0x27 */ {39, 1, 3, 2, 1, -8},
|
||||
/* '(' 0x28 */ {40, 2, 11, 4, 1, -8},
|
||||
/* ')' 0x29 */ {43, 3, 11, 4, 0, -8},
|
||||
/* '*' 0x2A */ {48, 3, 3, 5, 1, -8},
|
||||
/* '+' 0x2B */ {50, 5, 5, 7, 1, -4},
|
||||
/* ',' 0x2C */ {54, 1, 3, 3, 1, 0},
|
||||
/* '-' 0x2D */ {55, 2, 1, 4, 1, -3},
|
||||
/* '.' 0x2E */ {56, 1, 1, 3, 1, 0},
|
||||
/* '/' 0x2F */ {57, 3, 9, 3, 0, -8},
|
||||
/* '0' 0x30 */ {61, 5, 9, 7, 1, -8},
|
||||
/* '1' 0x31 */ {67, 3, 9, 7, 1, -8},
|
||||
/* '2' 0x32 */ {71, 6, 9, 7, 0, -8},
|
||||
/* '3' 0x33 */ {78, 6, 9, 7, 0, -8},
|
||||
/* '4' 0x34 */ {85, 6, 9, 7, 0, -8},
|
||||
/* '5' 0x35 */ {92, 5, 9, 7, 1, -8},
|
||||
/* '6' 0x36 */ {98, 5, 9, 7, 1, -8},
|
||||
/* '7' 0x37 */ {104, 5, 9, 7, 1, -8},
|
||||
/* '8' 0x38 */ {110, 6, 9, 7, 0, -8},
|
||||
/* '9' 0x39 */ {117, 6, 9, 7, 0, -8},
|
||||
/* ':' 0x3A */ {124, 1, 7, 3, 1, -6},
|
||||
/* ';' 0x3B */ {125, 1, 8, 3, 1, -5},
|
||||
/* '<' 0x3C */ {126, 5, 5, 7, 1, -4},
|
||||
/* '=' 0x3D */ {130, 5, 3, 7, 1, -3},
|
||||
/* '>' 0x3E */ {132, 5, 5, 7, 1, -4},
|
||||
/* '?' 0x3F */ {136, 5, 9, 7, 1, -8},
|
||||
/* '@' 0x40 */ {142, 11, 11, 12, 0, -8},
|
||||
/* 'A' 0x41 */ {158, 8, 9, 8, 0, -8},
|
||||
/* 'B' 0x42 */ {167, 6, 9, 8, 1, -8},
|
||||
/* 'C' 0x43 */ {174, 8, 9, 9, 0, -8},
|
||||
/* 'D' 0x44 */ {183, 7, 9, 8, 1, -8},
|
||||
/* 'E' 0x45 */ {191, 6, 9, 8, 1, -8},
|
||||
/* 'F' 0x46 */ {198, 6, 9, 7, 1, -8},
|
||||
/* 'G' 0x47 */ {205, 8, 9, 9, 0, -8},
|
||||
/* 'H' 0x48 */ {214, 7, 9, 9, 1, -8},
|
||||
/* 'I' 0x49 */ {222, 1, 9, 3, 1, -8},
|
||||
/* 'J' 0x4A */ {224, 5, 9, 6, 0, -8},
|
||||
/* 'K' 0x4B */ {230, 7, 9, 8, 1, -8},
|
||||
/* 'L' 0x4C */ {238, 5, 9, 7, 1, -8},
|
||||
/* 'M' 0x4D */ {244, 8, 9, 10, 1, -8},
|
||||
/* 'N' 0x4E */ {253, 7, 9, 9, 1, -8},
|
||||
/* 'O' 0x4F */ {261, 9, 9, 9, 0, -8},
|
||||
/* 'P' 0x50 */ {272, 6, 9, 8, 1, -8},
|
||||
/* 'Q' 0x51 */ {279, 9, 10, 9, 0, -8},
|
||||
/* 'R' 0x52 */ {291, 7, 9, 9, 1, -8},
|
||||
/* 'S' 0x53 */ {299, 6, 9, 8, 1, -8},
|
||||
/* 'T' 0x54 */ {306, 7, 9, 8, 0, -8},
|
||||
/* 'U' 0x55 */ {314, 7, 9, 9, 1, -8},
|
||||
/* 'V' 0x56 */ {322, 7, 9, 8, 0, -8},
|
||||
/* 'W' 0x57 */ {330, 11, 9, 11, 0, -8},
|
||||
/* 'X' 0x58 */ {343, 6, 9, 8, 1, -8},
|
||||
/* 'Y' 0x59 */ {350, 8, 9, 8, 0, -8},
|
||||
/* 'Z' 0x5A */ {359, 7, 9, 7, 0, -8},
|
||||
/* '[' 0x5B */ {367, 2, 12, 3, 1, -8},
|
||||
/* '\' 0x5C */ {370, 3, 9, 3, 0, -8},
|
||||
/* ']' 0x5D */ {374, 2, 12, 3, 0, -8},
|
||||
/* '^' 0x5E */ {377, 4, 4, 6, 1, -8},
|
||||
/* '_' 0x5F */ {379, 7, 1, 7, 0, 2},
|
||||
/* '`' 0x60 */ {380, 1, 1, 3, 1, -8},
|
||||
/* 'a' 0x61 */ {381, 6, 7, 7, 0, -6},
|
||||
/* 'b' 0x62 */ {387, 5, 9, 7, 1, -8},
|
||||
/* 'c' 0x63 */ {393, 6, 7, 6, 0, -6},
|
||||
/* 'd' 0x64 */ {399, 6, 9, 7, 0, -8},
|
||||
/* 'e' 0x65 */ {406, 6, 7, 6, 0, -6},
|
||||
/* 'f' 0x66 */ {412, 3, 9, 3, 0, -8},
|
||||
/* 'g' 0x67 */ {416, 6, 10, 7, 0, -6},
|
||||
/* 'h' 0x68 */ {424, 5, 9, 6, 1, -8},
|
||||
/* 'i' 0x69 */ {430, 1, 9, 3, 1, -8},
|
||||
/* 'j' 0x6A */ {432, 2, 12, 3, 0, -8},
|
||||
/* 'k' 0x6B */ {435, 5, 9, 6, 1, -8},
|
||||
/* 'l' 0x6C */ {441, 1, 9, 3, 1, -8},
|
||||
/* 'm' 0x6D */ {443, 8, 7, 10, 1, -6},
|
||||
/* 'n' 0x6E */ {450, 5, 7, 6, 1, -6},
|
||||
/* 'o' 0x6F */ {455, 6, 7, 6, 0, -6},
|
||||
/* 'p' 0x70 */ {461, 5, 9, 7, 1, -6},
|
||||
/* 'q' 0x71 */ {467, 6, 9, 7, 0, -6},
|
||||
/* 'r' 0x72 */ {474, 3, 7, 4, 1, -6},
|
||||
/* 's' 0x73 */ {477, 5, 7, 6, 0, -6},
|
||||
/* 't' 0x74 */ {482, 3, 8, 3, 0, -7},
|
||||
/* 'u' 0x75 */ {485, 5, 7, 6, 1, -6},
|
||||
/* 'v' 0x76 */ {490, 6, 7, 6, 0, -6},
|
||||
/* 'w' 0x77 */ {496, 8, 7, 9, 0, -6},
|
||||
/* 'x' 0x78 */ {503, 5, 7, 6, 0, -6},
|
||||
/* 'y' 0x79 */ {508, 5, 10, 6, 0, -6},
|
||||
/* 'z' 0x7A */ {515, 5, 7, 6, 0, -6},
|
||||
/* '{' 0x7B */ {520, 2, 12, 4, 1, -8},
|
||||
/* '|' 0x7C */ {523, 1, 11, 3, 1, -8},
|
||||
/* '}' 0x7D */ {525, 2, 12, 4, 1, -8},
|
||||
/* '~' 0x7E */ {528, 6, 2, 6, 0, -4},
|
||||
/* 0x7F */ {530, 9, 10, 11, 1, -8},
|
||||
/* 0x80 */ {542, 9, 11, 9, 0, -8},
|
||||
/* 0x81 */ {555, 6, 10, 7, 1, -9},
|
||||
/* 0x82 */ {563, 1, 3, 3, 1, 0},
|
||||
/* 0x83 */ {564, 4, 9, 5, 1, -8},
|
||||
/* 0x84 */ {569, 3, 3, 5, 1, 0},
|
||||
/* 0x85 */ {571, 5, 1, 7, 1, 0},
|
||||
/* 0x86 */ {572, 5, 11, 7, 1, -8},
|
||||
/* 0x87 */ {579, 5, 11, 7, 1, -8},
|
||||
/* 0x88 */ {586, 7, 9, 8, 0, -8},
|
||||
/* 0x89 */ {594, 12, 9, 12, 0, -8},
|
||||
/* 0x8A */ {608, 11, 9, 13, 1, -8},
|
||||
/* 0x8B */ {621, 2, 3, 4, 1, -4},
|
||||
/* 0x8C */ {622, 11, 9, 12, 1, -8},
|
||||
/* 0x8D */ {635, 6, 11, 8, 1, -10},
|
||||
/* 0x8E */ {644, 9, 9, 9, 0, -8},
|
||||
/* 0x8F */ {655, 7, 11, 9, 1, -8},
|
||||
/* 0x90 */ {665, 6, 11, 7, 0, -8},
|
||||
/* 0x91 */ {674, 1, 3, 3, 1, -8},
|
||||
/* 0x92 */ {675, 1, 3, 2, 1, -8},
|
||||
/* 0x93 */ {676, 3, 3, 5, 1, -8},
|
||||
/* 0x94 */ {678, 3, 3, 5, 1, -8},
|
||||
/* 0x95 */ {680, 3, 3, 5, 1, -5},
|
||||
/* 0x96 */ {682, 6, 1, 6, 0, -3},
|
||||
/* 0x97 */ {683, 12, 1, 12, 0, -3},
|
||||
/* 0x98 */ {685, 0, 0, 8, 0, 0},
|
||||
/* 0x99 */ {685, 11, 7, 12, 1, -8},
|
||||
/* 0x9A */ {695, 9, 6, 10, 0, -5},
|
||||
/* 0x9B */ {702, 2, 3, 3, 1, -4},
|
||||
/* 0x9C */ {703, 9, 6, 10, 1, -5},
|
||||
/* 0x9D */ {710, 4, 9, 6, 1, -8},
|
||||
/* 0x9E */ {715, 6, 9, 7, 0, -8},
|
||||
/* 0x9F */ {722, 5, 7, 7, 1, -5},
|
||||
/* 0xA0 */ {727, 0, 0, 3, 0, 0},
|
||||
/* 0xA1 */ {727, 7, 11, 7, 0, -10},
|
||||
/* 0xA2 */ {737, 5, 11, 6, 0, -7},
|
||||
/* 0xA3 */ {744, 5, 9, 6, 0, -8},
|
||||
/* 0xA4 */ {750, 5, 4, 7, 1, -5},
|
||||
/* 0xA5 */ {753, 6, 10, 7, 1, -9},
|
||||
/* 0xA6 */ {761, 1, 12, 3, 1, -8},
|
||||
/* 0xA7 */ {763, 5, 12, 7, 1, -8},
|
||||
/* 0xA8 */ {771, 6, 11, 8, 1, -10},
|
||||
/* 0xA9 */ {780, 9, 9, 10, 0, -8},
|
||||
/* 0xAA */ {791, 7, 9, 9, 1, -8},
|
||||
/* 0xAB */ {799, 4, 4, 6, 1, -4},
|
||||
/* 0xAC */ {801, 2, 12, 3, 0, -8},
|
||||
/* 0xAD */ {804, 0, 0, 0, 0, 0},
|
||||
/* 0xAE */ {804, 9, 9, 10, 0, -8},
|
||||
/* 0xAF */ {815, 3, 11, 3, 0, -10},
|
||||
/* 0xB0 */ {820, 4, 4, 7, 2, -8},
|
||||
/* 0xB1 */ {822, 5, 7, 7, 1, -6},
|
||||
/* 0xB2 */ {827, 1, 9, 3, 1, -8},
|
||||
/* 0xB3 */ {829, 1, 9, 3, 1, -8},
|
||||
/* 0xB4 */ {831, 3, 8, 5, 1, -7},
|
||||
/* 0xB5 */ {834, 6, 9, 7, 1, -6},
|
||||
/* 0xB6 */ {841, 6, 10, 6, 1, -8},
|
||||
/* 0xB7 */ {849, 1, 1, 3, 1, -2},
|
||||
/* 0xB8 */ {850, 6, 9, 7, 0, -8},
|
||||
/* 0xB9 */ {857, 9, 9, 11, 1, -8},
|
||||
/* 0xBA */ {868, 6, 6, 6, 0, -5},
|
||||
/* 0xBB */ {873, 4, 4, 6, 1, -5},
|
||||
/* 0xBC */ {875, 2, 12, 3, 0, -8},
|
||||
/* 0xBD */ {878, 6, 9, 8, 1, -8},
|
||||
/* 0xBE */ {885, 5, 6, 6, 0, -5},
|
||||
/* 0xBF */ {889, 3, 9, 3, 0, -8},
|
||||
/* 0xC0 */ {893, 8, 9, 8, 0, -8},
|
||||
/* 0xC1 */ {902, 6, 9, 8, 1, -8},
|
||||
/* 0xC2 */ {909, 6, 9, 8, 1, -8},
|
||||
/* 0xC3 */ {916, 6, 9, 7, 1, -8},
|
||||
/* 0xC4 */ {923, 9, 11, 10, 0, -8},
|
||||
/* 0xC5 */ {936, 6, 9, 8, 1, -8},
|
||||
/* 0xC6 */ {943, 9, 9, 11, 1, -8},
|
||||
/* 0xC7 */ {954, 6, 9, 8, 1, -8},
|
||||
/* 0xC8 */ {961, 7, 9, 9, 1, -8},
|
||||
/* 0xC9 */ {969, 7, 11, 9, 1, -10},
|
||||
/* 0xCA */ {979, 6, 9, 8, 1, -8},
|
||||
/* 0xCB */ {986, 7, 9, 8, 0, -8},
|
||||
/* 0xCC */ {994, 8, 9, 10, 1, -8},
|
||||
/* 0xCD */ {1003, 7, 9, 9, 1, -8},
|
||||
/* 0xCE */ {1011, 8, 9, 10, 1, -8},
|
||||
/* 0xCF */ {1020, 7, 9, 9, 1, -8},
|
||||
/* 0xD0 */ {1028, 6, 9, 8, 1, -8},
|
||||
/* 0xD1 */ {1035, 7, 9, 9, 1, -8},
|
||||
/* 0xD2 */ {1043, 7, 9, 7, 0, -8},
|
||||
/* 0xD3 */ {1051, 7, 9, 7, 0, -8},
|
||||
/* 0xD4 */ {1059, 9, 9, 10, 1, -8},
|
||||
/* 0xD5 */ {1070, 6, 9, 8, 1, -8},
|
||||
/* 0xD6 */ {1077, 8, 11, 9, 1, -8},
|
||||
/* 0xD7 */ {1088, 6, 9, 8, 1, -8},
|
||||
/* 0xD8 */ {1095, 8, 9, 10, 1, -8},
|
||||
/* 0xD9 */ {1104, 9, 11, 10, 1, -8},
|
||||
/* 0xDA */ {1117, 10, 9, 10, 0, -8},
|
||||
/* 0xDB */ {1129, 9, 9, 10, 1, -8},
|
||||
/* 0xDC */ {1140, 6, 9, 8, 1, -8},
|
||||
/* 0xDD */ {1147, 7, 9, 9, 1, -8},
|
||||
/* 0xDE */ {1155, 10, 9, 12, 1, -8},
|
||||
/* 0xDF */ {1167, 6, 9, 8, 1, -8},
|
||||
/* 0xE0 */ {1174, 6, 6, 7, 0, -5},
|
||||
/* 0xE1 */ {1179, 6, 9, 7, 0, -8},
|
||||
/* 0xE2 */ {1186, 5, 6, 6, 1, -5},
|
||||
/* 0xE3 */ {1190, 4, 6, 5, 1, -5},
|
||||
/* 0xE4 */ {1193, 7, 7, 7, 0, -5},
|
||||
/* 0xE5 */ {1200, 6, 6, 7, 0, -5},
|
||||
/* 0xE6 */ {1205, 8, 6, 9, 1, -5},
|
||||
/* 0xE7 */ {1211, 6, 6, 6, 0, -5},
|
||||
/* 0xE8 */ {1216, 5, 6, 7, 1, -5},
|
||||
/* 0xE9 */ {1220, 5, 8, 7, 1, -7},
|
||||
/* 0xEA */ {1225, 4, 6, 6, 1, -5},
|
||||
/* 0xEB */ {1228, 5, 6, 6, 0, -5},
|
||||
/* 0xEC */ {1232, 6, 6, 7, 1, -5},
|
||||
/* 0xED */ {1237, 5, 6, 7, 1, -5},
|
||||
/* 0xEE */ {1241, 6, 6, 7, 0, -5},
|
||||
/* 0xEF */ {1246, 5, 6, 7, 1, -5},
|
||||
/* 0xF0 */ {1250, 5, 9, 7, 1, -5},
|
||||
/* 0xF1 */ {1256, 6, 6, 6, 0, -5},
|
||||
/* 0xF2 */ {1261, 5, 6, 5, 0, -5},
|
||||
/* 0xF3 */ {1265, 5, 9, 6, 0, -5},
|
||||
/* 0xF4 */ {1271, 10, 11, 10, 0, -7},
|
||||
/* 0xF5 */ {1285, 5, 6, 6, 0, -5},
|
||||
/* 0xF6 */ {1289, 6, 7, 7, 1, -5},
|
||||
/* 0xF7 */ {1295, 4, 6, 6, 1, -5},
|
||||
/* 0xF8 */ {1298, 6, 6, 8, 1, -5},
|
||||
/* 0xF9 */ {1303, 7, 7, 9, 1, -5},
|
||||
/* 0xFA */ {1310, 7, 6, 8, 0, -5},
|
||||
/* 0xFB */ {1316, 6, 6, 8, 1, -5},
|
||||
/* 0xFC */ {1321, 5, 6, 6, 1, -5},
|
||||
/* 0xFD */ {1325, 5, 6, 6, 1, -5},
|
||||
/* 0xFE */ {1329, 8, 6, 9, 1, -5},
|
||||
/* 0xFF */ {1335, 5, 6, 7, 1, -5},
|
||||
};
|
||||
|
||||
const GFXfont FreeSans6pt_Win1251 PROGMEM = {(uint8_t *)FreeSans6pt_Win1251Bitmaps, (GFXglyph *)FreeSans6pt_Win1251Glyphs, 0x20,
|
||||
0xFF, 14};
|
||||
@@ -0,0 +1,457 @@
|
||||
#pragma once
|
||||
const uint8_t FreeSans6pt_Win1252Bitmaps[] PROGMEM = {
|
||||
/* ' ' 0x20 */
|
||||
0xFC, 0x80, /* '!' 0x21 */
|
||||
0xB6, 0x80, /* '"' 0x22 */
|
||||
0x24, 0x51, 0xF9, 0x42, 0x9F, 0x92, 0x28, /* '#' 0x23 */
|
||||
0x10, 0xE5, 0x55, 0x50, 0xE1, 0x65, 0x55, 0xE1, 0x00, /* '$' 0x24 */
|
||||
0x71, 0x24, 0x89, 0x22, 0x50, 0x74, 0x02, 0x70, 0xA4, 0x49, 0x11, 0xC0, /* '%' 0x25 */
|
||||
0x71, 0x24, 0x9C, 0x62, 0x58, 0xA7, 0xF4, /* '&' 0x26 */
|
||||
0xE0, /* ''' 0x27 */
|
||||
0x5A, 0xAA, 0x94, /* '(' 0x28 */
|
||||
0x89, 0x12, 0x49, 0x29, 0x00, /* ')' 0x29 */
|
||||
0x5E, 0x80, /* '*' 0x2A */
|
||||
0x21, 0x3E, 0x42, 0x00, /* '+' 0x2B */
|
||||
0xE0, /* ',' 0x2C */
|
||||
0xC0, /* '-' 0x2D */
|
||||
0x80, /* '.' 0x2E */
|
||||
0x24, 0xA4, 0xA4, 0x80, /* '/' 0x2F */
|
||||
0x76, 0xE3, 0x18, 0xC6, 0x3B, 0x70, /* '0' 0x30 */
|
||||
0x27, 0x92, 0x49, 0x20, /* '1' 0x31 */
|
||||
0x79, 0x10, 0x41, 0x08, 0xC6, 0x10, 0xFC, /* '2' 0x32 */
|
||||
0x79, 0x30, 0x43, 0x18, 0x10, 0x71, 0x78, /* '3' 0x33 */
|
||||
0x08, 0x61, 0x8A, 0x49, 0x2F, 0xC2, 0x08, /* '4' 0x34 */
|
||||
0xFC, 0x21, 0xE8, 0x84, 0x31, 0xF0, /* '5' 0x35 */
|
||||
0x74, 0x61, 0xE8, 0xC6, 0x31, 0x70, /* '6' 0x36 */
|
||||
0xF8, 0x44, 0x22, 0x11, 0x08, 0x40, /* '7' 0x37 */
|
||||
0x39, 0x34, 0x53, 0x39, 0x1C, 0x51, 0x38, /* '8' 0x38 */
|
||||
0x39, 0x3C, 0x71, 0x4C, 0xF0, 0x53, 0x78, /* '9' 0x39 */
|
||||
0x82, /* ':' 0x3A */
|
||||
0x87, /* ';' 0x3B */
|
||||
0x3E, 0x30, 0x60, 0x80, /* '<' 0x3C */
|
||||
0xF8, 0x3E, /* '=' 0x3D */
|
||||
0xE0, 0xC6, 0xC8, 0x00, /* '>' 0x3E */
|
||||
0x74, 0x42, 0x11, 0x10, 0x80, 0x20, /* '?' 0x3F */
|
||||
0x0F, 0x86, 0x19, 0x9A, 0xA4, 0xD9, 0x13, 0x22, 0x56, 0xDA, 0x6E, 0x60, 0x06, 0x00, 0x3C, 0x00, /* '@' 0x40 */
|
||||
0x18, 0x18, 0x24, 0x24, 0x24, 0x7E, 0x42, 0x42, 0xC3, /* 'A' 0x41 */
|
||||
0xFA, 0x18, 0x61, 0xFA, 0x18, 0x61, 0xFC, /* 'B' 0x42 */
|
||||
0x3E, 0x63, 0x40, 0x40, 0xC0, 0x40, 0x41, 0x63, 0x3E, /* 'C' 0x43 */
|
||||
0xF9, 0x0A, 0x1C, 0x18, 0x30, 0x61, 0xC2, 0xF8, /* 'D' 0x44 */
|
||||
0xFE, 0x08, 0x20, 0xFE, 0x08, 0x20, 0xFC, /* 'E' 0x45 */
|
||||
0xFE, 0x08, 0x20, 0xFA, 0x08, 0x20, 0x80, /* 'F' 0x46 */
|
||||
0x1E, 0x61, 0x40, 0x40, 0xC7, 0x41, 0x41, 0x63, 0x1D, /* 'G' 0x47 */
|
||||
0x83, 0x06, 0x0C, 0x1F, 0xF0, 0x60, 0xC1, 0x82, /* 'H' 0x48 */
|
||||
0xFF, 0x80, /* 'I' 0x49 */
|
||||
0x08, 0x42, 0x10, 0x87, 0x29, 0x70, /* 'J' 0x4A */
|
||||
0x85, 0x12, 0x45, 0x0D, 0x13, 0x22, 0x42, 0x86, /* 'K' 0x4B */
|
||||
0x84, 0x21, 0x08, 0x42, 0x10, 0xF8, /* 'L' 0x4C */
|
||||
0xC3, 0xC3, 0xC3, 0xA5, 0xA5, 0xA5, 0x99, 0x99, 0x99, /* 'M' 0x4D */
|
||||
0x83, 0x86, 0x8D, 0x19, 0x33, 0x62, 0xC3, 0x86, /* 'N' 0x4E */
|
||||
0x1E, 0x31, 0x90, 0x68, 0x1C, 0x0A, 0x05, 0x06, 0xC6, 0x1E, 0x00, /* 'O' 0x4F */
|
||||
0xFA, 0x18, 0x61, 0xFA, 0x08, 0x20, 0x80, /* 'P' 0x50 */
|
||||
0x1E, 0x31, 0x90, 0x68, 0x1C, 0x0A, 0x05, 0x16, 0xC6, 0x1F, 0x00, 0x40, /* 'Q' 0x51 */
|
||||
0xFD, 0x0E, 0x1C, 0x2F, 0x90, 0xA1, 0x42, 0x86, /* 'R' 0x52 */
|
||||
0x7A, 0x18, 0x30, 0x78, 0x38, 0x61, 0x78, /* 'S' 0x53 */
|
||||
0xFE, 0x20, 0x40, 0x81, 0x02, 0x04, 0x08, 0x10, /* 'T' 0x54 */
|
||||
0x83, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xE2, 0x78, /* 'U' 0x55 */
|
||||
0xC2, 0x85, 0x0B, 0x22, 0x44, 0x8E, 0x0C, 0x18, /* 'V' 0x56 */
|
||||
0xC4, 0x28, 0xCD, 0x29, 0x25, 0x24, 0xA4, 0x52, 0x8C, 0x61, 0x8C, 0x31, 0x80, /* 'W' 0x57 */
|
||||
0x87, 0x34, 0x8C, 0x30, 0xC4, 0xA3, 0x84, /* 'X' 0x58 */
|
||||
0xC3, 0x42, 0x24, 0x34, 0x18, 0x08, 0x08, 0x08, 0x08, /* 'Y' 0x59 */
|
||||
0x7E, 0x0C, 0x30, 0x41, 0x06, 0x18, 0x20, 0xFE, /* 'Z' 0x5A */
|
||||
0xEA, 0xAA, 0xAB, /* '[' 0x5B */
|
||||
0x92, 0x24, 0x89, 0x20, /* '\' 0x5C */
|
||||
0xD5, 0x55, 0x57, /* ']' 0x5D */
|
||||
0x46, 0xA9, /* '^' 0x5E */
|
||||
0xFE, /* '_' 0x5F */
|
||||
0x80, /* '`' 0x60 */
|
||||
0x79, 0x20, 0x4F, 0xC6, 0x37, 0x40, /* 'a' 0x61 */
|
||||
0x84, 0x3D, 0x18, 0xC6, 0x31, 0xF0, /* 'b' 0x62 */
|
||||
0x39, 0x3C, 0x20, 0xC1, 0x33, 0x80, /* 'c' 0x63 */
|
||||
0x04, 0x13, 0xD3, 0xC6, 0x1C, 0x53, 0x3C, /* 'd' 0x64 */
|
||||
0x39, 0x38, 0x7F, 0x81, 0x13, 0x80, /* 'e' 0x65 */
|
||||
0x6B, 0xA4, 0x92, 0x40, /* 'f' 0x66 */
|
||||
0x35, 0x3C, 0x61, 0xC5, 0x33, 0x41, 0x4D, 0xE0, /* 'g' 0x67 */
|
||||
0x84, 0x3D, 0x38, 0xC6, 0x31, 0x88, /* 'h' 0x68 */
|
||||
0xBF, 0x80, /* 'i' 0x69 */
|
||||
0x45, 0x55, 0x57, /* 'j' 0x6A */
|
||||
0x84, 0x25, 0x4E, 0x52, 0xD2, 0x88, /* 'k' 0x6B */
|
||||
0xFF, 0x80, /* 'l' 0x6C */
|
||||
0xF7, 0x99, 0x91, 0x91, 0x91, 0x91, 0x91, /* 'm' 0x6D */
|
||||
0xF4, 0x63, 0x18, 0xC6, 0x20, /* 'n' 0x6E */
|
||||
0x39, 0x3C, 0x61, 0xC5, 0x33, 0x80, /* 'o' 0x6F */
|
||||
0xF4, 0x63, 0x18, 0xC7, 0xD0, 0x80, /* 'p' 0x70 */
|
||||
0x3D, 0x3C, 0x61, 0xC5, 0x37, 0x41, 0x04, /* 'q' 0x71 */
|
||||
0xF2, 0x49, 0x20, /* 'r' 0x72 */
|
||||
0x7A, 0x50, 0xE0, 0xE5, 0xE0, /* 's' 0x73 */
|
||||
0x5D, 0x24, 0x93, /* 't' 0x74 */
|
||||
0x8C, 0x63, 0x18, 0xCF, 0xA0, /* 'u' 0x75 */
|
||||
0x85, 0x24, 0x92, 0x30, 0xC3, 0x00, /* 'v' 0x76 */
|
||||
0x89, 0x59, 0x59, 0x55, 0x56, 0x26, 0x26, /* 'w' 0x77 */
|
||||
0x4A, 0x4C, 0x43, 0x27, 0x20, /* 'x' 0x78 */
|
||||
0x8A, 0x52, 0xA5, 0x18, 0x84, 0x22, 0x00, /* 'y' 0x79 */
|
||||
0x78, 0x44, 0x46, 0x23, 0xE0, /* 'z' 0x7A */
|
||||
0x6A, 0xAA, 0xA9, /* '{' 0x7B */
|
||||
0xFF, 0xE0, /* '|' 0x7C */
|
||||
0x95, 0x55, 0x56, /* '}' 0x7D */
|
||||
0x66, 0x60, /* '~' 0x7E */
|
||||
0xFF, 0xC0, 0x67, 0x34, 0x58, 0x4C, 0x46, 0x03, 0x11, 0x80, 0xFF, 0xC0, /* 0x7F */
|
||||
0x1C, 0x45, 0x07, 0xE4, 0x1F, 0x10, 0x10, 0x1E, /* 0x80 */
|
||||
/* 0x81 */
|
||||
0xE0, /* 0x82 */
|
||||
0x6B, 0xA4, 0x92, 0x49, 0x60, /* 0x83 */
|
||||
0xB6, 0x80, /* 0x84 */
|
||||
0xA8, /* 0x85 */
|
||||
0x21, 0x09, 0xF2, 0x10, 0x84, 0x21, 0x08, /* 0x86 */
|
||||
0x21, 0x09, 0xF2, 0x10, 0x84, 0xF9, 0x08, /* 0x87 */
|
||||
0x54, /* 0x88 */
|
||||
0x62, 0x09, 0x40, 0x98, 0x06, 0x80, 0x10, 0x01, 0x66, 0x29, 0x92, 0x99, 0x06, 0x60, /* 0x89 */
|
||||
0x28, 0x47, 0xA1, 0x83, 0x07, 0x83, 0x87, 0x17, 0x80, /* 0x8A */
|
||||
0x64, /* 0x8B */
|
||||
0x3B, 0xE8, 0xC2, 0x08, 0x41, 0x08, 0x3F, 0x04, 0x20, 0x82, 0x30, 0x3B, 0xE0, /* 0x8C */
|
||||
/* 0x8D */
|
||||
0x14, 0x11, 0xF8, 0x30, 0xC1, 0x04, 0x18, 0x61, 0xFC, /* 0x8E */
|
||||
/* 0x8F */
|
||||
/* 0x90 */
|
||||
0xE0, /* 0x91 */
|
||||
0xE0, /* 0x92 */
|
||||
0xB6, 0x80, /* 0x93 */
|
||||
0xB6, 0x80, /* 0x94 */
|
||||
0xFF, 0x80, /* 0x95 */
|
||||
0xFC, /* 0x96 */
|
||||
0xFF, 0xF0, /* 0x97 */
|
||||
0xDB, /* 0x98 */
|
||||
0xE6, 0x28, 0xCD, 0x19, 0xA3, 0x34, 0x6A, 0x8B, 0x51, 0x68, /* 0x99 */
|
||||
0x52, 0x69, 0x8E, 0x19, 0x60, /* 0x9A */
|
||||
0x98, /* 0x9B */
|
||||
0x7B, 0xD9, 0xCE, 0x10, 0xC3, 0xF8, 0x41, 0x9C, 0x5E, 0xF0, /* 0x9C */
|
||||
/* 0x9D */
|
||||
0x51, 0x1E, 0x11, 0x11, 0x88, 0xF8, /* 0x9E */
|
||||
0x29, 0x05, 0x12, 0x22, 0x87, 0x04, 0x08, 0x10, 0x20, /* 0x9F */
|
||||
/* 0xA0 */
|
||||
0xBF, 0x80, /* 0xA1 */
|
||||
0x23, 0xAB, 0x4A, 0x52, 0xAE, 0x20, /* 0xA2 */
|
||||
0x39, 0x14, 0x10, 0xF0, 0x82, 0x1C, 0x4C, /* 0xA3 */
|
||||
0xFC, 0x63, 0xF0, /* 0xA4 */
|
||||
0x8C, 0x54, 0xAF, 0x93, 0xE4, 0x20, /* 0xA5 */
|
||||
0xF9, 0xF0, /* 0xA6 */
|
||||
0x32, 0x91, 0xC9, 0x47, 0x26, 0x14, 0xA4, 0xC0, /* 0xA7 */
|
||||
0xA0, /* 0xA8 */
|
||||
0x3E, 0x3F, 0xB8, 0xF4, 0x1A, 0x0D, 0x17, 0x76, 0xC6, 0x3E, 0x00, /* 0xA9 */
|
||||
0x61, 0x79, 0x60, /* 0xAA */
|
||||
0x5A, 0xA5, /* 0xAB */
|
||||
0xFC, 0x10, 0x40, /* 0xAC */
|
||||
/* 0xAD */
|
||||
0x3E, 0x31, 0xB7, 0x72, 0x99, 0xCC, 0xC7, 0x56, 0xC6, 0x3E, 0x00, /* 0xAE */
|
||||
0xE0, /* 0xAF */
|
||||
0x69, 0x96, /* 0xB0 */
|
||||
0x21, 0x3E, 0x42, 0x03, 0xE0, /* 0xB1 */
|
||||
0x69, 0x3C, 0xF0, /* 0xB2 */
|
||||
0x79, 0x29, 0x70, /* 0xB3 */
|
||||
0x80, /* 0xB4 */
|
||||
0x8A, 0x28, 0xA2, 0x8A, 0x6E, 0xE0, 0x80, /* 0xB5 */
|
||||
0x7F, 0xAE, 0xBA, 0x68, 0xA2, 0x8A, 0x28, 0xA0, /* 0xB6 */
|
||||
0x80, /* 0xB7 */
|
||||
0x67, 0x80, /* 0xB8 */
|
||||
0x75, 0x50, /* 0xB9 */
|
||||
0x69, 0x96, 0xF0, /* 0xBA */
|
||||
0xA5, 0x5A, /* 0xBB */
|
||||
0x42, 0x30, 0x84, 0x41, 0x10, 0x48, 0x82, 0x61, 0x28, 0x8F, 0x20, 0x80, /* 0xBC */
|
||||
0x40, 0x63, 0x11, 0x09, 0x74, 0xA8, 0x84, 0x44, 0x44, 0x43, 0x80, /* 0xBD */
|
||||
0x71, 0x24, 0x82, 0x20, 0x50, 0x98, 0x9A, 0x61, 0x28, 0x4F, 0x20, 0x80, /* 0xBE */
|
||||
0x20, 0x08, 0x44, 0x42, 0x11, 0x70, /* 0xBF */
|
||||
0x10, 0x08, 0x00, 0x18, 0x3C, 0x24, 0x24, 0x7E, 0x42, 0xC3, /* 0xC0 */
|
||||
0x08, 0x10, 0x00, 0x18, 0x3C, 0x24, 0x24, 0x7E, 0x42, 0xC3, /* 0xC1 */
|
||||
0x18, 0x24, 0x00, 0x18, 0x3C, 0x24, 0x24, 0x7E, 0x42, 0xC3, /* 0xC2 */
|
||||
0x34, 0x2C, 0x00, 0x18, 0x3C, 0x24, 0x24, 0x7E, 0x42, 0xC3, /* 0xC3 */
|
||||
0x24, 0x00, 0x18, 0x3C, 0x24, 0x24, 0x7E, 0x42, 0x42, 0xC3, /* 0xC4 */
|
||||
0x18, 0x24, 0x18, 0x18, 0x3C, 0x24, 0x24, 0x7E, 0x42, 0xC3, /* 0xC5 */
|
||||
0x1F, 0xC5, 0x02, 0x40, 0x90, 0x47, 0xDF, 0x04, 0x42, 0x10, 0x87, 0xC0, /* 0xC6 */
|
||||
0x3E, 0x61, 0xC0, 0x80, 0x80, 0x80, 0xC1, 0x63, 0x3E, 0x0C, 0x04, 0x1C, /* 0xC7 */
|
||||
0x20, 0x40, 0x3F, 0x82, 0x0F, 0xA0, 0x83, 0xF0, /* 0xC8 */
|
||||
0x08, 0x40, 0x3F, 0x82, 0x0F, 0xA0, 0x83, 0xF0, /* 0xC9 */
|
||||
0x10, 0xA0, 0x3F, 0x82, 0x0F, 0xA0, 0x83, 0xF0, /* 0xCA */
|
||||
0x28, 0x0F, 0xE0, 0x83, 0xE8, 0x20, 0x83, 0xF0, /* 0xCB */
|
||||
0x91, 0x55, 0x50, /* 0xCC */
|
||||
0x62, 0xAA, 0xA0, /* 0xCD */
|
||||
0x54, 0x24, 0x92, 0x48, /* 0xCE */
|
||||
0xA1, 0x24, 0x92, 0x48, /* 0xCF */
|
||||
0x7C, 0x42, 0x41, 0x41, 0xF1, 0x41, 0x41, 0x42, 0x7C, /* 0xD0 */
|
||||
0x14, 0x53, 0x0F, 0x1B, 0x32, 0x66, 0xC7, 0x87, 0x04, /* 0xD1 */
|
||||
0x10, 0x04, 0x0F, 0x8C, 0x6C, 0x1C, 0x06, 0x03, 0x83, 0x63, 0x1F, 0x00, /* 0xD2 */
|
||||
0x04, 0x04, 0x0F, 0x8C, 0x6C, 0x1C, 0x06, 0x03, 0x83, 0x63, 0x1F, 0x00, /* 0xD3 */
|
||||
0x08, 0x0A, 0x00, 0x07, 0xC6, 0x36, 0x0E, 0x03, 0x01, 0xC1, 0xB1, 0x8F, 0x80, /* 0xD4 */
|
||||
0x1A, 0x0B, 0x00, 0x07, 0xC6, 0x36, 0x0E, 0x03, 0x01, 0xC1, 0xB1, 0x8F, 0x80, /* 0xD5 */
|
||||
0x14, 0x00, 0x00, 0x07, 0xC6, 0x36, 0x0E, 0x03, 0x01, 0xC1, 0xB1, 0x8F, 0x80, /* 0xD6 */
|
||||
0x8A, 0x88, 0xA8, 0x80, /* 0xD7 */
|
||||
0x3E, 0xB1, 0xB0, 0xF0, 0x98, 0x8C, 0x87, 0x86, 0xC6, 0xBE, 0x00, /* 0xD8 */
|
||||
0x20, 0x22, 0x0C, 0x18, 0x30, 0x60, 0xC1, 0xC6, 0xF8, /* 0xD9 */
|
||||
0x08, 0x22, 0x0C, 0x18, 0x30, 0x60, 0xC1, 0xC6, 0xF8, /* 0xDA */
|
||||
0x10, 0x52, 0x0C, 0x18, 0x30, 0x60, 0xC1, 0xC6, 0xF8, /* 0xDB */
|
||||
0x29, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC1, 0xC6, 0xF8, /* 0xDC */
|
||||
0x09, 0x25, 0x12, 0x22, 0x87, 0x04, 0x08, 0x10, 0x20, /* 0xDD */
|
||||
0x83, 0xE8, 0x61, 0x87, 0xE8, 0x20, 0x80, /* 0xDE */
|
||||
0x7A, 0x18, 0x61, 0x8A, 0x18, 0x61, 0xB8, /* 0xDF */
|
||||
0x20, 0x20, 0x03, 0xC8, 0x40, 0x8F, 0x62, 0x8C, 0xEC, /* 0xE0 */
|
||||
0x10, 0x40, 0x03, 0xC8, 0x40, 0x8F, 0x62, 0x8C, 0xEC, /* 0xE1 */
|
||||
0x10, 0x50, 0x03, 0xC8, 0x40, 0x8F, 0x62, 0x8C, 0xEC, /* 0xE2 */
|
||||
0x68, 0xB0, 0x03, 0xC8, 0x40, 0x8F, 0x62, 0x8C, 0xEC, /* 0xE3 */
|
||||
0x28, 0x01, 0xE4, 0x20, 0x47, 0xB1, 0x46, 0x76, /* 0xE4 */
|
||||
0x10, 0x50, 0x43, 0xC8, 0x40, 0x8F, 0x62, 0x8C, 0xEC, /* 0xE5 */
|
||||
0x7B, 0xA1, 0x90, 0x45, 0xFF, 0x84, 0x23, 0x17, 0x38, /* 0xE6 */
|
||||
0x7B, 0x18, 0x20, 0x83, 0x17, 0x8C, 0x11, 0xC0, /* 0xE7 */
|
||||
0x20, 0x40, 0x1E, 0xCE, 0x1F, 0xE0, 0xC5, 0xE0, /* 0xE8 */
|
||||
0x10, 0x80, 0x1E, 0xCE, 0x1F, 0xE0, 0xC5, 0xE0, /* 0xE9 */
|
||||
0x10, 0xA0, 0x1E, 0xCE, 0x1F, 0xE0, 0xC5, 0xE0, /* 0xEA */
|
||||
0x28, 0x07, 0xB3, 0x87, 0xF8, 0x31, 0x78, /* 0xEB */
|
||||
0x91, 0x55, 0x50, /* 0xEC */
|
||||
0x62, 0xAA, 0xA0, /* 0xED */
|
||||
0x54, 0x24, 0x92, 0x48, /* 0xEE */
|
||||
0xA1, 0x24, 0x92, 0x40, /* 0xEF */
|
||||
0x28, 0x42, 0x8F, 0x46, 0x18, 0x52, 0x30, /* 0xF0 */
|
||||
0x6A, 0xC1, 0x6C, 0xC6, 0x31, 0x8C, 0x40, /* 0xF1 */
|
||||
0x20, 0x40, 0x1E, 0xCE, 0x18, 0x61, 0xCD, 0xE0, /* 0xF2 */
|
||||
0x10, 0x80, 0x1E, 0xCE, 0x18, 0x61, 0xCD, 0xE0, /* 0xF3 */
|
||||
0x10, 0xA0, 0x1E, 0xCE, 0x18, 0x61, 0xCD, 0xE0, /* 0xF4 */
|
||||
0x69, 0x60, 0x1E, 0xCE, 0x18, 0x61, 0xCD, 0xE0, /* 0xF5 */
|
||||
0x28, 0x07, 0xB3, 0x86, 0x18, 0x73, 0x78, /* 0xF6 */
|
||||
0x20, 0x3E, 0x02, 0x00, /* 0xF7 */
|
||||
0x7F, 0x39, 0x69, 0xC7, 0x3F, 0x80, /* 0xF8 */
|
||||
0x41, 0x23, 0x18, 0xC6, 0x33, 0x68, /* 0xF9 */
|
||||
0x11, 0x23, 0x18, 0xC6, 0x33, 0x68, /* 0xFA */
|
||||
0x22, 0x81, 0x18, 0xC6, 0x31, 0x9B, 0x40, /* 0xFB */
|
||||
0x50, 0x23, 0x18, 0xC6, 0x33, 0x68, /* 0xFC */
|
||||
0x10, 0x88, 0x52, 0x49, 0x23, 0x0C, 0x30, 0x82, 0x18, /* 0xFD */
|
||||
0x84, 0x3D, 0xB8, 0xC6, 0x3B, 0xF4, 0x20, /* 0xFE */
|
||||
0x28, 0x08, 0x52, 0x49, 0x23, 0x0C, 0x30, 0x82, 0x18, /* 0xFF */
|
||||
};
|
||||
|
||||
const GFXglyph FreeSans6pt_Win1252Glyphs[] PROGMEM = {
|
||||
/* ' ' 0x20 */ {0, 0, 0, 3, 0, 0},
|
||||
/* '!' 0x21 */ {0, 1, 9, 4, 2, -8},
|
||||
/* '"' 0x22 */ {2, 3, 3, 4, 0, -8},
|
||||
/* '#' 0x23 */ {4, 7, 8, 7, 0, -7},
|
||||
/* '$' 0x24 */ {11, 6, 11, 7, 0, -9},
|
||||
/* '%' 0x25 */ {20, 10, 9, 11, 0, -8},
|
||||
/* '&' 0x26 */ {32, 6, 9, 8, 1, -8},
|
||||
/* ''' 0x27 */ {39, 1, 3, 2, 1, -8},
|
||||
/* '(' 0x28 */ {40, 2, 11, 4, 1, -8},
|
||||
/* ')' 0x29 */ {43, 3, 11, 4, 0, -8},
|
||||
/* '*' 0x2A */ {48, 3, 3, 5, 1, -8},
|
||||
/* '+' 0x2B */ {50, 5, 5, 7, 1, -4},
|
||||
/* ',' 0x2C */ {54, 1, 3, 3, 1, 0},
|
||||
/* '-' 0x2D */ {55, 2, 1, 4, 1, -3},
|
||||
/* '.' 0x2E */ {56, 1, 1, 3, 1, 0},
|
||||
/* '/' 0x2F */ {57, 3, 9, 3, 0, -8},
|
||||
/* '0' 0x30 */ {61, 5, 9, 7, 1, -8},
|
||||
/* '1' 0x31 */ {67, 3, 9, 7, 1, -8},
|
||||
/* '2' 0x32 */ {71, 6, 9, 7, 0, -8},
|
||||
/* '3' 0x33 */ {78, 6, 9, 7, 0, -8},
|
||||
/* '4' 0x34 */ {85, 6, 9, 7, 0, -8},
|
||||
/* '5' 0x35 */ {92, 5, 9, 7, 1, -8},
|
||||
/* '6' 0x36 */ {98, 5, 9, 7, 1, -8},
|
||||
/* '7' 0x37 */ {104, 5, 9, 7, 1, -8},
|
||||
/* '8' 0x38 */ {110, 6, 9, 7, 0, -8},
|
||||
/* '9' 0x39 */ {117, 6, 9, 7, 0, -8},
|
||||
/* ':' 0x3A */ {124, 1, 7, 3, 1, -6},
|
||||
/* ';' 0x3B */ {125, 1, 8, 3, 1, -5},
|
||||
/* '<' 0x3C */ {126, 5, 5, 7, 1, -4},
|
||||
/* '=' 0x3D */ {130, 5, 3, 7, 1, -3},
|
||||
/* '>' 0x3E */ {132, 5, 5, 7, 1, -4},
|
||||
/* '?' 0x3F */ {136, 5, 9, 7, 1, -8},
|
||||
/* '@' 0x40 */ {142, 11, 11, 12, 0, -8},
|
||||
/* 'A' 0x41 */ {158, 8, 9, 8, 0, -8},
|
||||
/* 'B' 0x42 */ {167, 6, 9, 8, 1, -8},
|
||||
/* 'C' 0x43 */ {174, 8, 9, 9, 0, -8},
|
||||
/* 'D' 0x44 */ {183, 7, 9, 8, 1, -8},
|
||||
/* 'E' 0x45 */ {191, 6, 9, 8, 1, -8},
|
||||
/* 'F' 0x46 */ {198, 6, 9, 7, 1, -8},
|
||||
/* 'G' 0x47 */ {205, 8, 9, 9, 0, -8},
|
||||
/* 'H' 0x48 */ {214, 7, 9, 9, 1, -8},
|
||||
/* 'I' 0x49 */ {222, 1, 9, 3, 1, -8},
|
||||
/* 'J' 0x4A */ {224, 5, 9, 6, 0, -8},
|
||||
/* 'K' 0x4B */ {230, 7, 9, 8, 1, -8},
|
||||
/* 'L' 0x4C */ {238, 5, 9, 7, 1, -8},
|
||||
/* 'M' 0x4D */ {244, 8, 9, 10, 1, -8},
|
||||
/* 'N' 0x4E */ {253, 7, 9, 9, 1, -8},
|
||||
/* 'O' 0x4F */ {261, 9, 9, 9, 0, -8},
|
||||
/* 'P' 0x50 */ {272, 6, 9, 8, 1, -8},
|
||||
/* 'Q' 0x51 */ {279, 9, 10, 9, 0, -8},
|
||||
/* 'R' 0x52 */ {291, 7, 9, 9, 1, -8},
|
||||
/* 'S' 0x53 */ {299, 6, 9, 8, 1, -8},
|
||||
/* 'T' 0x54 */ {306, 7, 9, 8, 0, -8},
|
||||
/* 'U' 0x55 */ {314, 7, 9, 9, 1, -8},
|
||||
/* 'V' 0x56 */ {322, 7, 9, 8, 0, -8},
|
||||
/* 'W' 0x57 */ {330, 11, 9, 11, 0, -8},
|
||||
/* 'X' 0x58 */ {343, 6, 9, 8, 1, -8},
|
||||
/* 'Y' 0x59 */ {350, 8, 9, 8, 0, -8},
|
||||
/* 'Z' 0x5A */ {359, 7, 9, 7, 0, -8},
|
||||
/* '[' 0x5B */ {367, 2, 12, 3, 1, -8},
|
||||
/* '\' 0x5C */ {370, 3, 9, 3, 0, -8},
|
||||
/* ']' 0x5D */ {374, 2, 12, 3, 0, -8},
|
||||
/* '^' 0x5E */ {377, 4, 4, 6, 1, -8},
|
||||
/* '_' 0x5F */ {379, 7, 1, 7, 0, 2},
|
||||
/* '`' 0x60 */ {380, 1, 1, 3, 1, -8},
|
||||
/* 'a' 0x61 */ {381, 6, 7, 7, 0, -6},
|
||||
/* 'b' 0x62 */ {387, 5, 9, 7, 1, -8},
|
||||
/* 'c' 0x63 */ {393, 6, 7, 6, 0, -6},
|
||||
/* 'd' 0x64 */ {399, 6, 9, 7, 0, -8},
|
||||
/* 'e' 0x65 */ {406, 6, 7, 6, 0, -6},
|
||||
/* 'f' 0x66 */ {412, 3, 9, 3, 0, -8},
|
||||
/* 'g' 0x67 */ {416, 6, 10, 7, 0, -6},
|
||||
/* 'h' 0x68 */ {424, 5, 9, 6, 1, -8},
|
||||
/* 'i' 0x69 */ {430, 1, 9, 3, 1, -8},
|
||||
/* 'j' 0x6A */ {432, 2, 12, 3, 0, -8},
|
||||
/* 'k' 0x6B */ {435, 5, 9, 6, 1, -8},
|
||||
/* 'l' 0x6C */ {441, 1, 9, 3, 1, -8},
|
||||
/* 'm' 0x6D */ {443, 8, 7, 10, 1, -6},
|
||||
/* 'n' 0x6E */ {450, 5, 7, 6, 1, -6},
|
||||
/* 'o' 0x6F */ {455, 6, 7, 6, 0, -6},
|
||||
/* 'p' 0x70 */ {461, 5, 9, 7, 1, -6},
|
||||
/* 'q' 0x71 */ {467, 6, 9, 7, 0, -6},
|
||||
/* 'r' 0x72 */ {474, 3, 7, 4, 1, -6},
|
||||
/* 's' 0x73 */ {477, 5, 7, 6, 0, -6},
|
||||
/* 't' 0x74 */ {482, 3, 8, 3, 0, -7},
|
||||
/* 'u' 0x75 */ {485, 5, 7, 6, 1, -6},
|
||||
/* 'v' 0x76 */ {490, 6, 7, 6, 0, -6},
|
||||
/* 'w' 0x77 */ {496, 8, 7, 9, 0, -6},
|
||||
/* 'x' 0x78 */ {503, 5, 7, 6, 0, -6},
|
||||
/* 'y' 0x79 */ {508, 5, 10, 6, 0, -6},
|
||||
/* 'z' 0x7A */ {515, 5, 7, 6, 0, -6},
|
||||
/* '{' 0x7B */ {520, 2, 12, 4, 1, -8},
|
||||
/* '|' 0x7C */ {523, 1, 11, 3, 1, -8},
|
||||
/* '}' 0x7D */ {525, 2, 12, 4, 1, -8},
|
||||
/* '~' 0x7E */ {528, 6, 2, 6, 0, -4},
|
||||
/* 0x7F */ {530, 9, 10, 11, 1, -8},
|
||||
/* 0x80 */ {542, 7, 9, 8, 0, -8},
|
||||
/* 0x81 */ {550, 0, 0, 8, 0, 0},
|
||||
/* 0x82 */ {550, 1, 3, 3, 1, 0},
|
||||
/* 0x83 */ {551, 3, 12, 3, 0, -8},
|
||||
/* 0x84 */ {556, 3, 3, 5, 1, 0},
|
||||
/* 0x85 */ {558, 5, 1, 7, 1, 0},
|
||||
/* 0x86 */ {559, 5, 11, 7, 1, -8},
|
||||
/* 0x87 */ {566, 5, 11, 7, 1, -8},
|
||||
/* 0x88 */ {573, 3, 2, 4, 0, -9},
|
||||
/* 0x89 */ {574, 12, 9, 12, 0, -8},
|
||||
/* 0x8A */ {588, 6, 11, 8, 1, -9},
|
||||
/* 0x8B */ {597, 2, 3, 4, 1, -4},
|
||||
/* 0x8C */ {598, 11, 9, 12, 0, -8},
|
||||
/* 0x8D */ {611, 0, 0, 8, 0, 0},
|
||||
/* 0x8E */ {611, 7, 10, 7, 0, -9},
|
||||
/* 0x8F */ {620, 0, 0, 8, 0, 0},
|
||||
/* 0x90 */ {620, 0, 0, 8, 0, 0},
|
||||
/* 0x91 */ {620, 1, 3, 3, 1, -8},
|
||||
/* 0x92 */ {621, 1, 3, 2, 1, -8},
|
||||
/* 0x93 */ {622, 3, 3, 5, 1, -8},
|
||||
/* 0x94 */ {624, 3, 3, 5, 1, -8},
|
||||
/* 0x95 */ {626, 3, 3, 5, 1, -5},
|
||||
/* 0x96 */ {628, 6, 1, 6, 0, -3},
|
||||
/* 0x97 */ {629, 12, 1, 12, 0, -3},
|
||||
/* 0x98 */ {631, 4, 2, 4, 0, -8},
|
||||
/* 0x99 */ {632, 11, 7, 12, 1, -8},
|
||||
/* 0x9A */ {642, 4, 9, 6, 1, -8},
|
||||
/* 0x9B */ {647, 2, 3, 3, 1, -4},
|
||||
/* 0x9C */ {648, 11, 7, 11, 0, -6},
|
||||
/* 0x9D */ {658, 0, 0, 8, 0, 0},
|
||||
/* 0x9E */ {658, 5, 9, 6, 0, -8},
|
||||
/* 0x9F */ {664, 7, 10, 8, 1, -9},
|
||||
/* 0xA0 */ {673, 0, 0, 3, 0, 0},
|
||||
/* 0xA1 */ {673, 1, 9, 4, 1, -5},
|
||||
/* 0xA2 */ {675, 5, 9, 7, 1, -7},
|
||||
/* 0xA3 */ {681, 6, 9, 7, 0, -8},
|
||||
/* 0xA4 */ {688, 5, 4, 7, 1, -5},
|
||||
/* 0xA5 */ {691, 5, 9, 7, 1, -8},
|
||||
/* 0xA6 */ {697, 1, 12, 3, 1, -8},
|
||||
/* 0xA7 */ {699, 5, 12, 7, 1, -8},
|
||||
/* 0xA8 */ {707, 3, 1, 4, 0, -7},
|
||||
/* 0xA9 */ {708, 9, 9, 10, 0, -8},
|
||||
/* 0xAA */ {719, 4, 5, 4, 0, -8},
|
||||
/* 0xAB */ {722, 4, 4, 6, 1, -4},
|
||||
/* 0xAC */ {724, 6, 3, 7, 1, -4},
|
||||
/* 0xAD */ {727, 0, 0, 0, 0, 0},
|
||||
/* 0xAE */ {727, 9, 9, 10, 0, -8},
|
||||
/* 0xAF */ {738, 3, 1, 4, 0, -8},
|
||||
/* 0xB0 */ {739, 4, 4, 7, 2, -8},
|
||||
/* 0xB1 */ {741, 5, 7, 7, 1, -6},
|
||||
/* 0xB2 */ {746, 4, 5, 4, 0, -9},
|
||||
/* 0xB3 */ {749, 4, 5, 4, 0, -9},
|
||||
/* 0xB4 */ {752, 1, 1, 4, 1, -8},
|
||||
/* 0xB5 */ {753, 6, 9, 7, 1, -6},
|
||||
/* 0xB6 */ {760, 6, 10, 6, 1, -8},
|
||||
/* 0xB7 */ {768, 1, 1, 3, 1, -2},
|
||||
/* 0xB8 */ {769, 3, 3, 4, 1, 1},
|
||||
/* 0xB9 */ {771, 2, 6, 4, 1, -9},
|
||||
/* 0xBA */ {773, 4, 5, 4, 0, -8},
|
||||
/* 0xBB */ {776, 4, 4, 6, 1, -5},
|
||||
/* 0xBC */ {778, 10, 9, 10, 1, -8},
|
||||
/* 0xBD */ {790, 9, 9, 10, 1, -8},
|
||||
/* 0xBE */ {801, 10, 9, 11, 0, -8},
|
||||
/* 0xBF */ {813, 5, 9, 7, 1, -5},
|
||||
/* 0xC0 */ {819, 8, 10, 8, 0, -9},
|
||||
/* 0xC1 */ {829, 8, 10, 8, 0, -9},
|
||||
/* 0xC2 */ {839, 8, 10, 8, 0, -9},
|
||||
/* 0xC3 */ {849, 8, 10, 8, 0, -9},
|
||||
/* 0xC4 */ {859, 8, 10, 8, 0, -9},
|
||||
/* 0xC5 */ {869, 8, 10, 8, 0, -9},
|
||||
/* 0xC6 */ {879, 10, 9, 12, 1, -8},
|
||||
/* 0xC7 */ {891, 8, 12, 9, 0, -8},
|
||||
/* 0xC8 */ {903, 6, 10, 8, 1, -9},
|
||||
/* 0xC9 */ {911, 6, 10, 8, 1, -9},
|
||||
/* 0xCA */ {919, 6, 10, 8, 1, -9},
|
||||
/* 0xCB */ {927, 6, 10, 8, 1, -9},
|
||||
/* 0xCC */ {935, 2, 10, 3, 0, -9},
|
||||
/* 0xCD */ {938, 2, 10, 3, 1, -9},
|
||||
/* 0xCE */ {941, 3, 10, 4, 0, -9},
|
||||
/* 0xCF */ {945, 3, 10, 4, 0, -9},
|
||||
/* 0xD0 */ {949, 8, 9, 8, 0, -8},
|
||||
/* 0xD1 */ {958, 7, 10, 9, 1, -9},
|
||||
/* 0xD2 */ {967, 9, 10, 9, 0, -9},
|
||||
/* 0xD3 */ {979, 9, 10, 9, 0, -9},
|
||||
/* 0xD4 */ {991, 9, 11, 9, 0, -10},
|
||||
/* 0xD5 */ {1004, 9, 11, 9, 0, -10},
|
||||
/* 0xD6 */ {1017, 9, 11, 9, 0, -10},
|
||||
/* 0xD7 */ {1030, 5, 5, 7, 1, -5},
|
||||
/* 0xD8 */ {1034, 9, 9, 9, 0, -8},
|
||||
/* 0xD9 */ {1045, 7, 10, 9, 1, -9},
|
||||
/* 0xDA */ {1054, 7, 10, 9, 1, -9},
|
||||
/* 0xDB */ {1063, 7, 10, 9, 1, -9},
|
||||
/* 0xDC */ {1072, 7, 10, 9, 1, -9},
|
||||
/* 0xDD */ {1081, 7, 10, 8, 1, -9},
|
||||
/* 0xDE */ {1090, 6, 9, 8, 1, -8},
|
||||
/* 0xDF */ {1097, 6, 9, 7, 1, -8},
|
||||
/* 0xE0 */ {1104, 7, 10, 7, 0, -9},
|
||||
/* 0xE1 */ {1113, 7, 10, 7, 0, -9},
|
||||
/* 0xE2 */ {1122, 7, 10, 7, 0, -9},
|
||||
/* 0xE3 */ {1131, 7, 10, 7, 0, -9},
|
||||
/* 0xE4 */ {1140, 7, 9, 7, 0, -8},
|
||||
/* 0xE5 */ {1148, 7, 10, 7, 0, -9},
|
||||
/* 0xE6 */ {1157, 10, 7, 10, 0, -6},
|
||||
/* 0xE7 */ {1166, 6, 10, 6, 0, -6},
|
||||
/* 0xE8 */ {1174, 6, 10, 6, 0, -9},
|
||||
/* 0xE9 */ {1182, 6, 10, 6, 0, -9},
|
||||
/* 0xEA */ {1190, 6, 10, 6, 0, -9},
|
||||
/* 0xEB */ {1198, 6, 9, 6, 0, -8},
|
||||
/* 0xEC */ {1205, 2, 10, 3, 0, -9},
|
||||
/* 0xED */ {1208, 2, 10, 3, 1, -9},
|
||||
/* 0xEE */ {1211, 3, 10, 3, 0, -9},
|
||||
/* 0xEF */ {1215, 3, 9, 3, 0, -8},
|
||||
/* 0xF0 */ {1219, 6, 9, 6, 0, -8},
|
||||
/* 0xF1 */ {1226, 5, 10, 6, 1, -9},
|
||||
/* 0xF2 */ {1233, 6, 10, 6, 0, -9},
|
||||
/* 0xF3 */ {1241, 6, 10, 6, 0, -9},
|
||||
/* 0xF4 */ {1249, 6, 10, 6, 0, -9},
|
||||
/* 0xF5 */ {1257, 6, 10, 6, 0, -9},
|
||||
/* 0xF6 */ {1265, 6, 9, 6, 0, -8},
|
||||
/* 0xF7 */ {1272, 5, 5, 7, 1, -5},
|
||||
/* 0xF8 */ {1276, 6, 7, 6, 0, -6},
|
||||
/* 0xF9 */ {1282, 5, 9, 6, 1, -8},
|
||||
/* 0xFA */ {1288, 5, 9, 6, 1, -8},
|
||||
/* 0xFB */ {1294, 5, 10, 6, 1, -9},
|
||||
/* 0xFC */ {1301, 5, 9, 6, 1, -8},
|
||||
/* 0xFD */ {1307, 6, 12, 6, 0, -8},
|
||||
/* 0xFE */ {1316, 5, 11, 7, 1, -8},
|
||||
/* 0xFF */ {1323, 6, 12, 6, 0, -8},
|
||||
};
|
||||
|
||||
const GFXfont FreeSans6pt_Win1252 PROGMEM = {(uint8_t *)FreeSans6pt_Win1252Bitmaps, (GFXglyph *)FreeSans6pt_Win1252Glyphs, 0x20,
|
||||
0xFF, 14};
|
||||
@@ -0,0 +1,494 @@
|
||||
#pragma once
|
||||
const uint8_t FreeSans9pt_Win1250Bitmaps[] PROGMEM = {
|
||||
/* ' ' 0x20 */
|
||||
0xFF, 0xFF, 0xF0, 0xC0, /* '!' 0x21 */
|
||||
0xDE, 0xF7, 0x20, /* '"' 0x22 */
|
||||
0x09, 0x86, 0x41, 0x91, 0xFF, 0x13, 0x04, 0xC3, 0x20, 0xC8, 0xFF, 0x89, 0x82, 0x61, 0x90, /* '#' 0x23 */
|
||||
0x10, 0x1F, 0x14, 0xDA, 0x3D, 0x1E, 0x83, 0x40, 0x78, 0x17, 0x08, 0xF4, 0x7A, 0x35, 0x33, 0xF0, 0x40, 0x20, /* '$' 0x24 */
|
||||
0x38, 0x10, 0xEC, 0x20, 0xC6, 0x20, 0xC6, 0x40, 0xC6, 0x40, 0x6C, 0x80, 0x39, 0x00, 0x01, 0x3C, 0x02, 0x77, 0x02, 0x63, 0x04,
|
||||
0x63, 0x04, 0x77, 0x08, 0x3C, /* '%' 0x25 */
|
||||
0x0E, 0x0C, 0xC3, 0x30, 0xCC, 0x1E, 0x03, 0x03, 0xC1, 0x9B, 0xC2, 0xF0, 0xEC, 0x19, 0x8F, 0x3C, 0x40, /* '&' 0x26 */
|
||||
0xFE, /* ''' 0x27 */
|
||||
0x13, 0x26, 0x6C, 0xCC, 0xCC, 0xC4, 0x66, 0x23, 0x10, /* '(' 0x28 */
|
||||
0x8C, 0x46, 0x63, 0x33, 0x33, 0x32, 0x66, 0x4C, 0x80, /* ')' 0x29 */
|
||||
0x25, 0x7E, 0xA5, 0x00, /* '*' 0x2A */
|
||||
0x30, 0xC3, 0x3F, 0x30, 0xC3, 0x0C, /* '+' 0x2B */
|
||||
0xD6, /* ',' 0x2C */
|
||||
0xF0, /* '-' 0x2D */
|
||||
0xC0, /* '.' 0x2E */
|
||||
0x08, 0x44, 0x21, 0x10, 0x84, 0x42, 0x11, 0x08, 0x00, /* '/' 0x2F */
|
||||
0x3C, 0x66, 0x42, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0x42, 0x66, 0x3C, /* '0' 0x30 */
|
||||
0x11, 0x3F, 0x33, 0x33, 0x33, 0x33, 0x30, /* '1' 0x31 */
|
||||
0x3E, 0x31, 0xB0, 0x78, 0x30, 0x18, 0x1C, 0x1C, 0x1C, 0x18, 0x18, 0x10, 0x08, 0x07, 0xF8, /* '2' 0x32 */
|
||||
0x3C, 0x66, 0xC3, 0xC3, 0x03, 0x06, 0x1C, 0x07, 0x03, 0xC3, 0xC3, 0x66, 0x3C, /* '3' 0x33 */
|
||||
0x0C, 0x18, 0x71, 0x62, 0xC9, 0xA3, 0x46, 0xFE, 0x18, 0x30, 0x60, 0xC0, /* '4' 0x34 */
|
||||
0x7F, 0x20, 0x10, 0x08, 0x08, 0x07, 0xF3, 0x8C, 0x03, 0x01, 0x80, 0xF0, 0x6C, 0x63, 0xE0, /* '5' 0x35 */
|
||||
0x1E, 0x31, 0x98, 0x78, 0x0C, 0x06, 0xF3, 0x8D, 0x83, 0xC1, 0xE0, 0xD0, 0x6C, 0x63, 0xE0, /* '6' 0x36 */
|
||||
0xFF, 0x03, 0x02, 0x06, 0x04, 0x0C, 0x08, 0x18, 0x18, 0x18, 0x10, 0x30, 0x30, /* '7' 0x37 */
|
||||
0x3E, 0x31, 0xB0, 0x78, 0x3C, 0x1B, 0x18, 0xF8, 0xC6, 0xC1, 0xE0, 0xF0, 0x6C, 0x63, 0xE0, /* '8' 0x38 */
|
||||
0x3C, 0x66, 0xC2, 0xC3, 0xC3, 0xC3, 0x67, 0x3B, 0x03, 0x03, 0xC2, 0x66, 0x3C, /* '9' 0x39 */
|
||||
0xC0, 0x00, 0x30, /* ':' 0x3A */
|
||||
0xC0, 0x00, 0x00, 0x64, 0xA0, /* ';' 0x3B */
|
||||
0x00, 0x81, 0xC7, 0x8E, 0x0C, 0x07, 0x80, 0x70, 0x0E, 0x01, 0x80, /* '<' 0x3C */
|
||||
0xFF, 0x80, 0x00, 0x1F, 0xF0, /* '=' 0x3D */
|
||||
0xE0, 0x1C, 0x03, 0x80, 0x30, 0x70, 0xE3, 0x81, 0x00, /* '>' 0x3E */
|
||||
0x3E, 0x31, 0xB0, 0x78, 0x30, 0x18, 0x18, 0x38, 0x18, 0x18, 0x0C, 0x00, 0x00, 0x01, 0x80, /* '?' 0x3F */
|
||||
0x03, 0xF0, 0x06, 0x0E, 0x06, 0x01, 0x86, 0x00, 0x66, 0x1D, 0xBB, 0x31, 0xCF, 0x18, 0xC7, 0x98, 0x63, 0xCC, 0x31, 0xE6, 0x11,
|
||||
0xB3, 0x99, 0xCC, 0xF7, 0x86, 0x00, 0x01, 0x80, 0x00, 0x70, 0x40, 0x0F, 0xE0, /* '@' 0x40 */
|
||||
0x06, 0x00, 0xF0, 0x0F, 0x00, 0x90, 0x19, 0x81, 0x98, 0x10, 0x83, 0x0C, 0x3F, 0xC2, 0x04, 0x60, 0x66, 0x06, 0xC0,
|
||||
0x30, /* 'A' 0x41 */
|
||||
0xFF, 0x18, 0x33, 0x03, 0x60, 0x6C, 0x0D, 0x83, 0x3F, 0xC6, 0x06, 0xC0, 0x78, 0x0F, 0x01, 0xE0, 0x6F, 0xF8, /* 'B' 0x42 */
|
||||
0x1F, 0x86, 0x19, 0x81, 0xA0, 0x3C, 0x01, 0x80, 0x30, 0x06, 0x00, 0xC0, 0x68, 0x0D, 0x83, 0x18, 0x61, 0xF0, /* 'C' 0x43 */
|
||||
0xFF, 0x18, 0x33, 0x03, 0x60, 0x3C, 0x07, 0x80, 0xF0, 0x1E, 0x03, 0xC0, 0x78, 0x0F, 0x03, 0x60, 0xCF, 0xF0, /* 'D' 0x44 */
|
||||
0xFF, 0xE0, 0x30, 0x18, 0x0C, 0x06, 0x03, 0xFD, 0x80, 0xC0, 0x60, 0x30, 0x18, 0x0F, 0xF8, /* 'E' 0x45 */
|
||||
0xFF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xFE, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, /* 'F' 0x46 */
|
||||
0x0F, 0x83, 0x0E, 0x60, 0x66, 0x03, 0xC0, 0x0C, 0x00, 0xC1, 0xFC, 0x03, 0xC0, 0x36, 0x03, 0x60, 0x73, 0x0F, 0x0F,
|
||||
0x10, /* 'G' 0x47 */
|
||||
0xC0, 0x78, 0x0F, 0x01, 0xE0, 0x3C, 0x07, 0x80, 0xFF, 0xFE, 0x03, 0xC0, 0x78, 0x0F, 0x01, 0xE0, 0x3C, 0x06, /* 'H' 0x48 */
|
||||
0xFF, 0xFF, 0xFF, 0xC0, /* 'I' 0x49 */
|
||||
0x06, 0x0C, 0x18, 0x30, 0x60, 0xC1, 0x83, 0x07, 0x8F, 0x1E, 0x27, 0x80, /* 'J' 0x4A */
|
||||
0xC0, 0xF0, 0x6C, 0x33, 0x18, 0xCC, 0x37, 0x0F, 0xC3, 0x98, 0xC3, 0x30, 0xCC, 0x1B, 0x03, 0xC0, 0xC0, /* 'K' 0x4B */
|
||||
0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xFF, /* 'L' 0x4C */
|
||||
0xE0, 0x3F, 0x01, 0xFC, 0x1F, 0xE0, 0xFD, 0x05, 0xEC, 0x6F, 0x63, 0x79, 0x13, 0xCD, 0x9E, 0x6C, 0xF1, 0x47, 0x8E, 0x3C, 0x71,
|
||||
0x80, /* 'M' 0x4D */
|
||||
0xE0, 0x7C, 0x0F, 0xC1, 0xE8, 0x3D, 0x87, 0x98, 0xF1, 0x1E, 0x33, 0xC3, 0x78, 0x6F, 0x07, 0xE0, 0x7C, 0x0E, /* 'N' 0x4E */
|
||||
0x0F, 0x81, 0x83, 0x18, 0x0C, 0xC0, 0x6C, 0x01, 0xE0, 0x0F, 0x00, 0x78, 0x03, 0xC0, 0x1B, 0x01, 0x98, 0x0C, 0x60, 0xC0, 0xF8,
|
||||
0x00, /* 'O' 0x4F */
|
||||
0xFF, 0x30, 0x6C, 0x0F, 0x03, 0xC0, 0xF0, 0x6F, 0xF3, 0x00, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x00, /* 'P' 0x50 */
|
||||
0x0F, 0x81, 0x83, 0x18, 0x0C, 0xC0, 0x6C, 0x01, 0xE0, 0x0F, 0x00, 0x78, 0x03, 0xC0, 0x1B, 0x01, 0x98, 0x6C, 0x60, 0xC0, 0xFB,
|
||||
0x00, 0x08, /* 'Q' 0x51 */
|
||||
0xFF, 0x8C, 0x0E, 0xC0, 0x6C, 0x06, 0xC0, 0x6C, 0x0C, 0xFF, 0x8C, 0x0E, 0xC0, 0x6C, 0x06, 0xC0, 0x6C, 0x06, 0xC0,
|
||||
0x70, /* 'R' 0x52 */
|
||||
0x3F, 0x18, 0x6C, 0x0F, 0x03, 0xC0, 0x1E, 0x01, 0xF0, 0x0E, 0x00, 0xF0, 0x3C, 0x0D, 0x86, 0x3F, 0x00, /* 'S' 0x53 */
|
||||
0xFF, 0x86, 0x03, 0x01, 0x80, 0xC0, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, 0x01, 0x80, 0xC0, /* 'T' 0x54 */
|
||||
0xC0, 0x78, 0x0F, 0x01, 0xE0, 0x3C, 0x07, 0x80, 0xF0, 0x1E, 0x03, 0xC0, 0x78, 0x0F, 0x01, 0xB0, 0x61, 0xF0, /* 'U' 0x55 */
|
||||
0xC0, 0x6C, 0x0D, 0x81, 0x10, 0x63, 0x0C, 0x61, 0x04, 0x60, 0xCC, 0x19, 0x01, 0x60, 0x3C, 0x07, 0x00, 0x60, /* 'V' 0x56 */
|
||||
0xC1, 0x81, 0x61, 0xC3, 0x61, 0xC3, 0x61, 0x43, 0x62, 0x62, 0x22, 0x66, 0x32, 0x26, 0x36, 0x26, 0x14, 0x34, 0x14, 0x34, 0x1C,
|
||||
0x1C, 0x18, 0x1C, 0x08, 0x18, /* 'W' 0x57 */
|
||||
0xC0, 0xD8, 0x66, 0x18, 0xCC, 0x1E, 0x07, 0x00, 0xC0, 0x78, 0x32, 0x0C, 0xC6, 0x1B, 0x07, 0xC0, 0xC0, /* 'X' 0x58 */
|
||||
0xC0, 0x36, 0x06, 0x30, 0xC3, 0x0C, 0x19, 0x81, 0xD8, 0x0F, 0x00, 0x60, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60, 0x06,
|
||||
0x00, /* 'Y' 0x59 */
|
||||
0xFF, 0xC0, 0x60, 0x30, 0x0C, 0x06, 0x03, 0x01, 0xC0, 0x60, 0x30, 0x18, 0x06, 0x03, 0x00, 0xFF, 0xC0, /* 'Z' 0x5A */
|
||||
0xFB, 0x6D, 0xB6, 0xDB, 0x6D, 0xB6, 0xE0, /* '[' 0x5B */
|
||||
0x84, 0x10, 0x84, 0x10, 0x84, 0x10, 0x84, 0x10, 0x80, /* '\' 0x5C */
|
||||
0xED, 0xB6, 0xDB, 0x6D, 0xB6, 0xDB, 0xE0, /* ']' 0x5D */
|
||||
0x30, 0x60, 0xA2, 0x44, 0xD8, 0xA1, 0x80, /* '^' 0x5E */
|
||||
0xFF, 0xC0, /* '_' 0x5F */
|
||||
0xC6, 0x30, /* '`' 0x60 */
|
||||
0x7E, 0x71, 0xB0, 0xC0, 0x60, 0xF3, 0xDB, 0x0D, 0x86, 0xC7, 0x3D, 0xC0, /* 'a' 0x61 */
|
||||
0xC0, 0x60, 0x30, 0x1B, 0xCE, 0x36, 0x0F, 0x07, 0x83, 0xC1, 0xE0, 0xF0, 0x7C, 0x6D, 0xE0, /* 'b' 0x62 */
|
||||
0x3C, 0x66, 0xC3, 0xC0, 0xC0, 0xC0, 0xC0, 0xC3, 0x66, 0x3C, /* 'c' 0x63 */
|
||||
0x03, 0x03, 0x03, 0x3B, 0x67, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0x67, 0x3B, /* 'd' 0x64 */
|
||||
0x3C, 0x66, 0xC3, 0xC3, 0xFF, 0xC0, 0xC0, 0xC3, 0x66, 0x3C, /* 'e' 0x65 */
|
||||
0x36, 0x6F, 0x66, 0x66, 0x66, 0x66, 0x60, /* 'f' 0x66 */
|
||||
0x3B, 0x67, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0x67, 0x3B, 0x03, 0x03, 0xC6, 0x7C, /* 'g' 0x67 */
|
||||
0xC0, 0xC0, 0xC0, 0xDE, 0xE3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, /* 'h' 0x68 */
|
||||
0xC3, 0xFF, 0xFF, 0xC0, /* 'i' 0x69 */
|
||||
0x30, 0x03, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0xE0, /* 'j' 0x6A */
|
||||
0xC0, 0xC0, 0xC0, 0xC2, 0xC4, 0xCC, 0xD8, 0xF8, 0xEC, 0xC4, 0xC6, 0xC3, 0xC3, /* 'k' 0x6B */
|
||||
0xFF, 0xFF, 0xFF, 0xC0, /* 'l' 0x6C */
|
||||
0xDE, 0xF7, 0x1C, 0xF0, 0xC7, 0x86, 0x3C, 0x31, 0xE1, 0x8F, 0x0C, 0x78, 0x63, 0xC3, 0x1E, 0x18, 0xC0, /* 'm' 0x6D */
|
||||
0xDE, 0xE3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, /* 'n' 0x6E */
|
||||
0x3C, 0x66, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0x66, 0x3C, /* 'o' 0x6F */
|
||||
0xDE, 0x71, 0xB0, 0x78, 0x3C, 0x1E, 0x0F, 0x07, 0x83, 0xE3, 0x6F, 0x30, 0x18, 0x0C, 0x00, /* 'p' 0x70 */
|
||||
0x3B, 0x67, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0x67, 0x3B, 0x03, 0x03, 0x03, /* 'q' 0x71 */
|
||||
0xDF, 0x31, 0x8C, 0x63, 0x18, 0xC6, 0x00, /* 'r' 0x72 */
|
||||
0x3E, 0xE3, 0xC0, 0xC0, 0xE0, 0x3C, 0x07, 0xC3, 0xE3, 0x7E, /* 's' 0x73 */
|
||||
0x66, 0xF6, 0x66, 0x66, 0x66, 0x67, /* 't' 0x74 */
|
||||
0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC7, 0x7B, /* 'u' 0x75 */
|
||||
0xC1, 0xA0, 0x98, 0xCC, 0x42, 0x21, 0xB0, 0xD0, 0x28, 0x1C, 0x0C, 0x00, /* 'v' 0x76 */
|
||||
0xC6, 0x1E, 0x38, 0x91, 0xC4, 0xCA, 0x66, 0xD3, 0x16, 0xD0, 0xA6, 0x87, 0x1C, 0x38, 0xC0, 0xC6, 0x00, /* 'w' 0x77 */
|
||||
0x87, 0x89, 0xB1, 0xC3, 0x07, 0x1E, 0x26, 0xC5, 0x0C, /* 'x' 0x78 */
|
||||
0xC1, 0x43, 0x63, 0x62, 0x26, 0x36, 0x34, 0x1C, 0x1C, 0x18, 0x18, 0x18, 0x10, 0x60, /* 'y' 0x79 */
|
||||
0xFE, 0x0C, 0x30, 0xC1, 0x86, 0x18, 0x20, 0xC1, 0xFC, /* 'z' 0x7A */
|
||||
0x36, 0x66, 0x66, 0x6E, 0xCE, 0x66, 0x66, 0x66, 0x30, /* '{' 0x7B */
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xC0, /* '|' 0x7C */
|
||||
0xC6, 0x66, 0x66, 0x67, 0x37, 0x66, 0x66, 0x66, 0xC0, /* '}' 0x7D */
|
||||
0x61, 0x24, 0x38, /* '~' 0x7E */
|
||||
0xFF, 0xFC, 0x00, 0x63, 0xE3, 0x31, 0x99, 0x04, 0xC8, 0x66, 0x06, 0x30, 0x61, 0x83, 0x0C, 0x18, 0x60, 0x03, 0x06, 0x18, 0x00,
|
||||
0xFF, 0xFC, /* 0x7F */
|
||||
0x07, 0xC6, 0x13, 0x00, 0xC0, 0x60, 0x3F, 0xE6, 0x03, 0xFC, 0x60, 0x0C, 0x03, 0x00, 0x61, 0x07, 0xC0, /* 0x80 */
|
||||
/* 0x81 */
|
||||
0xDC, /* 0x82 */
|
||||
/* 0x83 */
|
||||
0xDA, 0x76, /* 0x84 */
|
||||
0xCC, 0xC0, /* 0x85 */
|
||||
0x18, 0x18, 0x18, 0x18, 0xFF, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, /* 0x86 */
|
||||
0x18, 0x18, 0x18, 0x18, 0xFF, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xFF, 0x18, 0x18, 0x18, 0x18, /* 0x87 */
|
||||
/* 0x88 */
|
||||
0x70, 0x80, 0x22, 0x20, 0x08, 0x90, 0x02, 0x24, 0x00, 0x72, 0x00, 0x00, 0x80, 0x00, 0x40, 0x00, 0x10, 0x00, 0x09, 0xC7, 0x84,
|
||||
0x8B, 0x31, 0x22, 0x84, 0x88, 0xB3, 0x21, 0xC7, 0x80, /* 0x89 */
|
||||
0x1B, 0x03, 0x83, 0xF1, 0x86, 0xC0, 0xF0, 0x3C, 0x01, 0xE0, 0x1F, 0x00, 0xE0, 0x0F, 0x03, 0xC0, 0xD8, 0x63, 0xF0, /* 0x8A */
|
||||
0x69, /* 0x8B */
|
||||
0x06, 0x03, 0x03, 0xF1, 0x86, 0xC0, 0xF0, 0x3C, 0x01, 0xE0, 0x1F, 0x00, 0xE0, 0x0F, 0x03, 0xC0, 0xD8, 0x63, 0xF0, /* 0x8C */
|
||||
0x33, 0x0F, 0x3F, 0xE1, 0x80, 0xC0, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, 0x01, 0x80, 0xC0, 0x60, 0x30, /* 0x8D */
|
||||
0x1B, 0x03, 0x8F, 0xFC, 0x06, 0x03, 0x00, 0xC0, 0x60, 0x30, 0x1C, 0x06, 0x03, 0x01, 0x80, 0x60, 0x30, 0x0F, 0xFC, /* 0x8E */
|
||||
0x0C, 0x06, 0x0F, 0xFC, 0x06, 0x03, 0x00, 0xC0, 0x60, 0x30, 0x1C, 0x06, 0x03, 0x01, 0x80, 0x60, 0x30, 0x0F, 0xFC, /* 0x8F */
|
||||
/* 0x90 */
|
||||
0x6B, /* 0x91 */
|
||||
0xD6, /* 0x92 */
|
||||
0x4C, 0xA5, 0xB0, /* 0x93 */
|
||||
0xDA, 0x53, 0x20, /* 0x94 */
|
||||
0x6F, 0xFF, 0x60, /* 0x95 */
|
||||
0xFE, /* 0x96 */
|
||||
0xFF, 0xFF, /* 0x97 */
|
||||
/* 0x98 */
|
||||
0xFC, 0xE1, 0xCC, 0x38, 0x73, 0x0E, 0x1C, 0xC3, 0x8F, 0x30, 0xD2, 0xCC, 0x34, 0xB3, 0x0D, 0x6C, 0xC3, 0x53, 0x30, 0xCC, 0xCC,
|
||||
0x33, 0x30, /* 0x99 */
|
||||
0x24, 0x3C, 0x18, 0x7E, 0xE3, 0xC0, 0xC0, 0x60, 0x3C, 0x07, 0xC3, 0xE3, 0x7E, /* 0x9A */
|
||||
0x96, /* 0x9B */
|
||||
0x0C, 0x18, 0x10, 0x3E, 0xE3, 0xC0, 0xC0, 0xE0, 0x3C, 0x07, 0xC3, 0xE3, 0x7E, /* 0x9C */
|
||||
0x0D, 0xA7, 0x3C, 0x61, 0x86, 0x18, 0x61, 0x86, 0x18, 0x70, /* 0x9D */
|
||||
0x48, 0xF0, 0xC7, 0xF0, 0x61, 0x86, 0x0C, 0x30, 0xC1, 0x06, 0x0F, 0xE0, /* 0x9E */
|
||||
0x0C, 0x10, 0x47, 0xF0, 0x61, 0x86, 0x0C, 0x30, 0xC1, 0x06, 0x0F, 0xE0, /* 0x9F */
|
||||
/* 0xA0 */
|
||||
0x8A, 0x9C, /* 0xA1 */
|
||||
0x85, 0xE0, /* 0xA2 */
|
||||
0x60, 0x30, 0x18, 0x0C, 0x86, 0xC3, 0xC1, 0xC1, 0xC0, 0xE0, 0x30, 0x18, 0x0C, 0x07, 0xF8, /* 0xA3 */
|
||||
0xFF, 0xDF, 0x1E, 0x3E, 0xFF, 0xC0, /* 0xA4 */
|
||||
0x06, 0x00, 0xF0, 0x0F, 0x01, 0x30, 0x13, 0x81, 0x38, 0x21, 0x82, 0x1C, 0x3F, 0xC6, 0x04, 0x60, 0x66, 0x06, 0xC0, 0x30, 0x06,
|
||||
0x00, 0xC0, 0x0C, 0x00, 0x70, /* 0xA5 */
|
||||
0xFF, 0xFC, 0x0F, 0xFF, 0xC0, /* 0xA6 */
|
||||
0x0C, 0x09, 0x0C, 0xC6, 0x63, 0x81, 0xE3, 0x19, 0x87, 0xE1, 0xB8, 0xC6, 0x41, 0xC0, 0x73, 0x19, 0x8C, 0x66, 0x1E,
|
||||
0x00, /* 0xA7 */
|
||||
0xCC, /* 0xA8 */
|
||||
0x0F, 0xC0, 0x61, 0x87, 0x03, 0x9B, 0xC6, 0xD9, 0x8F, 0x60, 0x3D, 0x00, 0xF4, 0x03, 0xD8, 0x0D, 0xE6, 0x67, 0xF3, 0x86, 0x18,
|
||||
0x0F, 0xC0, /* 0xA9 */
|
||||
0x3F, 0x18, 0x6C, 0x0F, 0x03, 0xC0, 0x1E, 0x01, 0xF0, 0x0E, 0x00, 0xF0, 0x3C, 0x0D, 0x86, 0x3F, 0x02, 0x00, 0xE0, 0x18, 0x1C,
|
||||
0x00, /* 0xAA */
|
||||
0x22, 0xCF, 0x26, 0x46, 0x64, 0x40, /* 0xAB */
|
||||
0xFF, 0x80, 0xC0, 0x60, 0x30, 0x18, /* 0xAC */
|
||||
/* 0xAD */
|
||||
0x0F, 0xC0, 0x61, 0x87, 0x03, 0x9F, 0xE6, 0xD0, 0x8F, 0x42, 0x3D, 0xF0, 0xF4, 0x23, 0xD0, 0x8D, 0xC2, 0x67, 0x0B, 0x86, 0x18,
|
||||
0x0F, 0xC0, /* 0xAE */
|
||||
0x0C, 0x00, 0x0F, 0xFC, 0x06, 0x03, 0x00, 0xC0, 0x60, 0x30, 0x1C, 0x06, 0x03, 0x01, 0x80, 0x60, 0x30, 0x0F, 0xFC, /* 0xAF */
|
||||
0x74, 0x63, 0x17, 0x00, /* 0xB0 */
|
||||
0x0C, 0x06, 0x03, 0x07, 0xE0, 0xC0, 0x60, 0x30, 0x18, 0x00, 0x00, 0x3F, 0xE0, /* 0xB1 */
|
||||
0x6C, 0xC7, /* 0xB2 */
|
||||
0x66, 0x66, 0x67, 0x6E, 0x66, 0x66, 0x60, /* 0xB3 */
|
||||
0x36, 0xC0, /* 0xB4 */
|
||||
0xC3, 0x61, 0xB0, 0xD8, 0x6C, 0x36, 0x1B, 0x0D, 0x86, 0xE7, 0x7D, 0xF0, 0x18, 0x0C, 0x00, /* 0xB5 */
|
||||
0x3F, 0x7E, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0x72, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, /* 0xB6 */
|
||||
0xE0, /* 0xB7 */
|
||||
0x21, 0xC7, 0xE0, /* 0xB8 */
|
||||
0x7E, 0x38, 0xCC, 0x30, 0x0C, 0x0F, 0x1E, 0xCC, 0x33, 0x0C, 0xC7, 0x1E, 0xE0, 0x10, 0x0C, 0x03, 0x00, 0x70, /* 0xB9 */
|
||||
0x3E, 0xE3, 0xC0, 0xC0, 0xE0, 0x3C, 0x07, 0xC3, 0xC3, 0x7E, 0x10, 0x1C, 0x0C, 0x38, /* 0xBA */
|
||||
0x89, 0x98, 0x99, 0x3C, 0xD1, 0x00, /* 0xBB */
|
||||
0xC6, 0xC4, 0xC8, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xFF, /* 0xBC */
|
||||
0x6F, 0x69, 0x00, /* 0xBD */
|
||||
0xDE, 0xB9, 0x8C, 0x63, 0x18, 0xC6, 0x31, 0x8C, 0x00, /* 0xBE */
|
||||
0x30, 0x03, 0xF8, 0x30, 0xC3, 0x06, 0x18, 0x60, 0x83, 0x07, 0xF0, /* 0xBF */
|
||||
0x06, 0x00, 0xC0, 0xFF, 0x8C, 0x0E, 0xC0, 0x6C, 0x06, 0xC0, 0x6C, 0x0C, 0xFF, 0x8C, 0x0E, 0xC0, 0x6C, 0x06, 0xC0, 0x6C, 0x06,
|
||||
0xC0, 0x70, /* 0xC0 */
|
||||
0x06, 0x03, 0x00, 0x00, 0x30, 0x1E, 0x07, 0x81, 0x20, 0xCC, 0x33, 0x0F, 0xC6, 0x19, 0x86, 0x40, 0xB0, 0x30, /* 0xC1 */
|
||||
0x0C, 0x04, 0x80, 0x00, 0x30, 0x1E, 0x07, 0x81, 0x20, 0xCC, 0x33, 0x0F, 0xC6, 0x19, 0x86, 0x40, 0xB0, 0x30, /* 0xC2 */
|
||||
0x21, 0x07, 0x80, 0x00, 0x30, 0x1E, 0x07, 0x81, 0x20, 0xCC, 0x33, 0x0F, 0xC6, 0x19, 0x86, 0x40, 0xB0, 0x30, /* 0xC3 */
|
||||
0x33, 0x00, 0x00, 0xC0, 0x78, 0x1E, 0x04, 0x83, 0x30, 0xCC, 0x33, 0x1F, 0xE6, 0x19, 0x02, 0xC0, 0xF0, 0x30, /* 0xC4 */
|
||||
0x30, 0x60, 0x00, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xFF, /* 0xC5 */
|
||||
0x06, 0x01, 0x80, 0x00, 0x0F, 0xC3, 0x0C, 0xC0, 0xD0, 0x1E, 0x00, 0xC0, 0x18, 0x03, 0x01, 0xA0, 0x36, 0x0C, 0x61, 0x87,
|
||||
0xC0, /* 0xC6 */
|
||||
0x1F, 0x06, 0x19, 0x83, 0xA0, 0x3C, 0x01, 0x80, 0x30, 0x06, 0x00, 0xC0, 0x68, 0x0D, 0x83, 0x18, 0xE1, 0xF0, 0x08, 0x01, 0xC0,
|
||||
0x18, 0x0E, 0x00, /* 0xC7 */
|
||||
0x19, 0x81, 0xE0, 0x00, 0x0F, 0xC3, 0x0C, 0xC0, 0xF0, 0x1E, 0x00, 0xC0, 0x18, 0x03, 0x01, 0xA0, 0x36, 0x0C, 0x61, 0x87,
|
||||
0xC0, /* 0xC8 */
|
||||
0x0C, 0x0C, 0x00, 0x1F, 0xFC, 0x06, 0x03, 0x01, 0x80, 0xFF, 0x60, 0x30, 0x18, 0x0C, 0x07, 0xFC, /* 0xC9 */
|
||||
0xFF, 0xD8, 0x03, 0x00, 0x60, 0x0C, 0x01, 0x80, 0x3F, 0xF6, 0x00, 0xC0, 0x18, 0x03, 0x00, 0x60, 0x0F, 0xFC, 0x01, 0x80, 0x60,
|
||||
0x0C, 0x00, 0xE0, /* 0xCA */
|
||||
0x33, 0x00, 0x3F, 0xF8, 0x0C, 0x06, 0x03, 0x01, 0xFE, 0xC0, 0x60, 0x30, 0x18, 0x0C, 0x07, 0xFC, /* 0xCB */
|
||||
0x33, 0x0F, 0x00, 0x1F, 0xFC, 0x06, 0x03, 0x01, 0x80, 0xFF, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, 0xFE, /* 0xCC */
|
||||
0x78, 0x36, 0xDB, 0x6D, 0xB6, 0xC0, /* 0xCD */
|
||||
0x76, 0xC0, 0x63, 0x18, 0xC6, 0x31, 0x8C, 0x63, 0x18, /* 0xCE */
|
||||
0x66, 0x0F, 0x00, 0x03, 0xF8, 0xC3, 0x30, 0x6C, 0x0F, 0x03, 0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xC1, 0xB0, 0xEF, 0xE0, /* 0xCF */
|
||||
0x7F, 0x0C, 0x31, 0x83, 0x30, 0x36, 0x06, 0xC0, 0xFE, 0x1B, 0x03, 0x60, 0x6C, 0x0D, 0x83, 0x30, 0xE7, 0xF0, /* 0xD0 */
|
||||
0x03, 0x01, 0x83, 0x81, 0xF0, 0x3F, 0x07, 0xA0, 0xF6, 0x1E, 0x63, 0xC4, 0x78, 0xCF, 0x0D, 0xE1, 0xBC, 0x1F, 0x81,
|
||||
0xC0, /* 0xD1 */
|
||||
0x19, 0x81, 0xE3, 0x81, 0xF0, 0x3F, 0x07, 0xA0, 0xF6, 0x1E, 0x63, 0xC4, 0x78, 0xCF, 0x0D, 0xE1, 0xBC, 0x1F, 0x81,
|
||||
0xC0, /* 0xD2 */
|
||||
0x03, 0x00, 0x60, 0x00, 0x00, 0xF0, 0x39, 0xC6, 0x06, 0x60, 0x6C, 0x03, 0xC0, 0x3C, 0x03, 0xC0, 0x36, 0x06, 0x60, 0x63, 0x9C,
|
||||
0x0F, 0x00, /* 0xD3 */
|
||||
0x0F, 0x01, 0x98, 0x00, 0x00, 0xF0, 0x39, 0xC6, 0x06, 0x60, 0x6C, 0x03, 0xC0, 0x3C, 0x03, 0xC0, 0x36, 0x06, 0x60, 0x63, 0x9C,
|
||||
0x0F, 0x00, /* 0xD4 */
|
||||
0x0D, 0x81, 0xB0, 0x00, 0x00, 0xF0, 0x39, 0xC6, 0x06, 0x60, 0x6C, 0x03, 0xC0, 0x3C, 0x03, 0xC0, 0x36, 0x06, 0x60, 0x63, 0x9C,
|
||||
0x0F, 0x00, /* 0xD5 */
|
||||
0x19, 0x81, 0x98, 0x00, 0x00, 0xF0, 0x39, 0xC6, 0x06, 0x60, 0x6C, 0x03, 0xC0, 0x3C, 0x03, 0xC0, 0x36, 0x06, 0x60, 0x63, 0x9C,
|
||||
0x0F, 0x00, /* 0xD6 */
|
||||
0x83, 0x89, 0xA1, 0x83, 0x89, 0xA1, 0x80, /* 0xD7 */
|
||||
0x33, 0x01, 0xE0, 0xFF, 0x8C, 0x0E, 0xC0, 0x6C, 0x06, 0xC0, 0x6C, 0x0C, 0xFF, 0x8C, 0x0E, 0xC0, 0x6C, 0x06, 0xC0, 0x6C, 0x06,
|
||||
0xC0, 0x70, /* 0xD8 */
|
||||
0x04, 0x01, 0x43, 0x11, 0xE0, 0x3C, 0x07, 0x80, 0xF0, 0x1E, 0x03, 0xC0, 0x78, 0x0F, 0x01, 0xE0, 0x36, 0x0C, 0x3E,
|
||||
0x00, /* 0xD9 */
|
||||
0x06, 0x01, 0x83, 0x01, 0xE0, 0x3C, 0x07, 0x80, 0xF0, 0x1E, 0x03, 0xC0, 0x78, 0x0F, 0x01, 0xE0, 0x36, 0x0C, 0x3E,
|
||||
0x00, /* 0xDA */
|
||||
0x0D, 0x83, 0x63, 0x01, 0xE0, 0x3C, 0x07, 0x80, 0xF0, 0x1E, 0x03, 0xC0, 0x78, 0x0F, 0x01, 0xE0, 0x36, 0x0C, 0x3E,
|
||||
0x00, /* 0xDB */
|
||||
0x1B, 0x00, 0x03, 0x01, 0xE0, 0x3C, 0x07, 0x80, 0xF0, 0x1E, 0x03, 0xC0, 0x78, 0x0F, 0x01, 0xE0, 0x36, 0x0C, 0x3E,
|
||||
0x00, /* 0xDC */
|
||||
0x03, 0x0C, 0x63, 0x60, 0x63, 0x0C, 0x30, 0xC1, 0x98, 0x1D, 0x80, 0xF0, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60, 0x06, 0x00,
|
||||
0x60, /* 0xDD */
|
||||
0xFF, 0x86, 0x03, 0x01, 0x80, 0xC0, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, 0x01, 0x80, 0xC0, 0x40, 0x3C, 0x06, 0x1E,
|
||||
0x00, /* 0xDE */
|
||||
0x3C, 0x33, 0x30, 0xD8, 0x6C, 0x36, 0x33, 0x39, 0x86, 0xC1, 0xE0, 0xF0, 0x78, 0x6D, 0xE0, /* 0xDF */
|
||||
0x19, 0x89, 0xBE, 0x63, 0x18, 0xC6, 0x31, 0x8C, 0x00, /* 0xE0 */
|
||||
0x0C, 0x04, 0x04, 0x0F, 0xCE, 0x36, 0x18, 0x0C, 0x1E, 0x7B, 0x61, 0xB0, 0xD8, 0xE7, 0xB8, /* 0xE1 */
|
||||
0x10, 0x14, 0x1B, 0x0F, 0xCE, 0x36, 0x18, 0x0C, 0x1E, 0x7B, 0x61, 0xB0, 0xD8, 0xE7, 0xB8, /* 0xE2 */
|
||||
0x66, 0x1E, 0x00, 0x0F, 0xCE, 0x36, 0x18, 0x0C, 0x1E, 0x7B, 0x61, 0xB0, 0xD8, 0xE7, 0xB8, /* 0xE3 */
|
||||
0x66, 0x00, 0x1F, 0x9C, 0x6C, 0x30, 0x18, 0x3C, 0xF6, 0xC3, 0x61, 0xB1, 0xCF, 0x70, /* 0xE4 */
|
||||
0x78, 0x36, 0xDB, 0x6D, 0xB6, 0xD8, /* 0xE5 */
|
||||
0x0C, 0x08, 0x10, 0x3C, 0x66, 0xC3, 0xC0, 0xC0, 0xC0, 0xC0, 0xC3, 0x66, 0x3C, /* 0xE6 */
|
||||
0x3C, 0x66, 0xC3, 0xC0, 0xC0, 0xC0, 0xC0, 0xC3, 0x66, 0x3C, 0x10, 0x1C, 0x0C, 0x38, /* 0xE7 */
|
||||
0x44, 0x28, 0x38, 0x3C, 0x66, 0xC3, 0xC0, 0xC0, 0xC0, 0xC0, 0xC3, 0x66, 0x3C, /* 0xE8 */
|
||||
0x0C, 0x08, 0x18, 0x3C, 0x66, 0xC3, 0xC3, 0xFF, 0xC0, 0xC0, 0xC3, 0x66, 0x3C, /* 0xE9 */
|
||||
0x3C, 0x62, 0xC3, 0xC3, 0xFF, 0xC0, 0xC0, 0xC3, 0x66, 0x3E, 0x04, 0x0C, 0x0C, 0x06, /* 0xEA */
|
||||
0x66, 0x00, 0x3C, 0x66, 0xC3, 0xC3, 0xFF, 0xC0, 0xC0, 0xC3, 0x66, 0x3C, /* 0xEB */
|
||||
0x64, 0x2C, 0x18, 0x3C, 0x66, 0xC3, 0xC3, 0xFF, 0xC0, 0xC0, 0xC3, 0x66, 0x3C, /* 0xEC */
|
||||
0x7A, 0x6D, 0xB6, 0xDB, 0x6C, /* 0xED */
|
||||
0x69, 0x06, 0x66, 0x66, 0x66, 0x66, 0x60, /* 0xEE */
|
||||
0x03, 0x30, 0x32, 0x03, 0x43, 0xB0, 0x67, 0x0C, 0x30, 0xC3, 0x0C, 0x30, 0xC3, 0x0C, 0x30, 0xC3, 0x06, 0x70, 0x3B,
|
||||
0x00, /* 0xEF */
|
||||
0x03, 0x07, 0xC0, 0xC7, 0x66, 0x76, 0x1B, 0x0D, 0x86, 0xC3, 0x61, 0xB0, 0xCC, 0xE3, 0xB0, /* 0xF0 */
|
||||
0x0C, 0x18, 0x00, 0xDE, 0xE3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, /* 0xF1 */
|
||||
0x66, 0x3C, 0x00, 0xDE, 0xE3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, /* 0xF2 */
|
||||
0x0C, 0x18, 0x00, 0x3C, 0x66, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0x66, 0x3C, /* 0xF3 */
|
||||
0x18, 0x24, 0x00, 0x3C, 0x66, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0x66, 0x3C, /* 0xF4 */
|
||||
0x36, 0x6C, 0x00, 0x3C, 0x66, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0x66, 0x3C, /* 0xF5 */
|
||||
0x66, 0x00, 0x3C, 0x66, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0x66, 0x3C, /* 0xF6 */
|
||||
0x18, 0x00, 0x00, 0x1F, 0xF0, 0x00, 0x00, 0x00, 0x30, /* 0xF7 */
|
||||
0xDB, 0x81, 0xBE, 0x63, 0x18, 0xC6, 0x31, 0x8C, 0x00, /* 0xF8 */
|
||||
0x10, 0x28, 0x10, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC7, 0x7B, /* 0xF9 */
|
||||
0x06, 0x0C, 0x18, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC7, 0x7B, /* 0xFA */
|
||||
0x36, 0x6C, 0x00, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC7, 0x7B, /* 0xFB */
|
||||
0x66, 0x00, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC7, 0x7B, /* 0xFC */
|
||||
0x06, 0x04, 0x08, 0xC1, 0x43, 0x63, 0x62, 0x26, 0x36, 0x34, 0x1C, 0x1C, 0x18, 0x18, 0x18, 0x10, 0x60, /* 0xFD */
|
||||
0x63, 0x3C, 0xC6, 0x31, 0x8C, 0x63, 0x18, 0xE2, 0x1C, 0x6F, /* 0xFE */
|
||||
0xC0, /* 0xFF */
|
||||
};
|
||||
|
||||
const GFXglyph FreeSans9pt_Win1250Glyphs[] PROGMEM = {
|
||||
/* ' ' 0x20 */ {0, 0, 0, 5, 0, 0},
|
||||
/* '!' 0x21 */ {0, 2, 13, 6, 2, -12},
|
||||
/* '"' 0x22 */ {4, 5, 4, 6, 1, -12},
|
||||
/* '#' 0x23 */ {7, 10, 12, 10, 0, -11},
|
||||
/* '$' 0x24 */ {22, 9, 16, 10, 1, -13},
|
||||
/* '%' 0x25 */ {40, 16, 13, 16, 1, -12},
|
||||
/* '&' 0x26 */ {66, 10, 13, 12, 1, -12},
|
||||
/* ''' 0x27 */ {83, 2, 4, 4, 1, -12},
|
||||
/* '(' 0x28 */ {84, 4, 17, 6, 1, -12},
|
||||
/* ')' 0x29 */ {93, 4, 17, 6, 1, -12},
|
||||
/* '*' 0x2A */ {102, 5, 5, 7, 1, -12},
|
||||
/* '+' 0x2B */ {106, 6, 8, 11, 3, -7},
|
||||
/* ',' 0x2C */ {112, 2, 4, 5, 2, 0},
|
||||
/* '-' 0x2D */ {113, 4, 1, 6, 1, -4},
|
||||
/* '.' 0x2E */ {114, 2, 1, 5, 1, 0},
|
||||
/* '/' 0x2F */ {115, 5, 13, 5, 0, -12},
|
||||
/* '0' 0x30 */ {124, 8, 13, 10, 1, -12},
|
||||
/* '1' 0x31 */ {137, 4, 13, 10, 3, -12},
|
||||
/* '2' 0x32 */ {144, 9, 13, 10, 1, -12},
|
||||
/* '3' 0x33 */ {159, 8, 13, 10, 1, -12},
|
||||
/* '4' 0x34 */ {172, 7, 13, 10, 2, -12},
|
||||
/* '5' 0x35 */ {184, 9, 13, 10, 1, -12},
|
||||
/* '6' 0x36 */ {199, 9, 13, 10, 1, -12},
|
||||
/* '7' 0x37 */ {214, 8, 13, 10, 0, -12},
|
||||
/* '8' 0x38 */ {227, 9, 13, 10, 1, -12},
|
||||
/* '9' 0x39 */ {242, 8, 13, 10, 1, -12},
|
||||
/* ':' 0x3A */ {255, 2, 10, 5, 1, -9},
|
||||
/* ';' 0x3B */ {258, 3, 12, 5, 1, -8},
|
||||
/* '<' 0x3C */ {263, 9, 9, 11, 1, -8},
|
||||
/* '=' 0x3D */ {274, 9, 4, 11, 1, -5},
|
||||
/* '>' 0x3E */ {279, 9, 8, 11, 1, -7},
|
||||
/* '?' 0x3F */ {288, 9, 13, 10, 1, -12},
|
||||
/* '@' 0x40 */ {303, 17, 16, 18, 1, -12},
|
||||
/* 'A' 0x41 */ {337, 12, 13, 12, 0, -12},
|
||||
/* 'B' 0x42 */ {357, 11, 13, 12, 1, -12},
|
||||
/* 'C' 0x43 */ {375, 11, 13, 13, 1, -12},
|
||||
/* 'D' 0x44 */ {393, 11, 13, 13, 1, -12},
|
||||
/* 'E' 0x45 */ {411, 9, 13, 11, 1, -12},
|
||||
/* 'F' 0x46 */ {426, 8, 13, 11, 1, -12},
|
||||
/* 'G' 0x47 */ {439, 12, 13, 14, 1, -12},
|
||||
/* 'H' 0x48 */ {459, 11, 13, 13, 1, -12},
|
||||
/* 'I' 0x49 */ {477, 2, 13, 5, 2, -12},
|
||||
/* 'J' 0x4A */ {481, 7, 13, 10, 1, -12},
|
||||
/* 'K' 0x4B */ {493, 10, 13, 12, 1, -12},
|
||||
/* 'L' 0x4C */ {510, 8, 13, 10, 1, -12},
|
||||
/* 'M' 0x4D */ {523, 13, 13, 15, 1, -12},
|
||||
/* 'N' 0x4E */ {545, 11, 13, 13, 1, -12},
|
||||
/* 'O' 0x4F */ {563, 13, 13, 14, 1, -12},
|
||||
/* 'P' 0x50 */ {585, 10, 13, 12, 1, -12},
|
||||
/* 'Q' 0x51 */ {602, 13, 14, 14, 1, -12},
|
||||
/* 'R' 0x52 */ {625, 12, 13, 13, 1, -12},
|
||||
/* 'S' 0x53 */ {645, 10, 13, 12, 1, -12},
|
||||
/* 'T' 0x54 */ {662, 9, 13, 11, 1, -12},
|
||||
/* 'U' 0x55 */ {677, 11, 13, 13, 1, -12},
|
||||
/* 'V' 0x56 */ {695, 11, 13, 11, 0, -12},
|
||||
/* 'W' 0x57 */ {713, 16, 13, 17, 0, -12},
|
||||
/* 'X' 0x58 */ {739, 10, 13, 12, 1, -12},
|
||||
/* 'Y' 0x59 */ {756, 12, 13, 12, 0, -12},
|
||||
/* 'Z' 0x5A */ {776, 10, 13, 11, 1, -12},
|
||||
/* '[' 0x5B */ {793, 3, 17, 5, 1, -12},
|
||||
/* '\' 0x5C */ {800, 5, 13, 5, 0, -12},
|
||||
/* ']' 0x5D */ {809, 3, 17, 5, 0, -12},
|
||||
/* '^' 0x5E */ {816, 7, 7, 8, 1, -12},
|
||||
/* '_' 0x5F */ {823, 10, 1, 10, 0, 3},
|
||||
/* '`' 0x60 */ {825, 4, 3, 5, 0, -12},
|
||||
/* 'a' 0x61 */ {827, 9, 10, 10, 1, -9},
|
||||
/* 'b' 0x62 */ {839, 9, 13, 10, 1, -12},
|
||||
/* 'c' 0x63 */ {854, 8, 10, 9, 1, -9},
|
||||
/* 'd' 0x64 */ {864, 8, 13, 10, 1, -12},
|
||||
/* 'e' 0x65 */ {877, 8, 10, 10, 1, -9},
|
||||
/* 'f' 0x66 */ {887, 4, 13, 5, 1, -12},
|
||||
/* 'g' 0x67 */ {894, 8, 14, 10, 1, -9},
|
||||
/* 'h' 0x68 */ {908, 8, 13, 10, 1, -12},
|
||||
/* 'i' 0x69 */ {921, 2, 13, 4, 1, -12},
|
||||
/* 'j' 0x6A */ {925, 4, 17, 4, 0, -12},
|
||||
/* 'k' 0x6B */ {934, 8, 13, 9, 1, -12},
|
||||
/* 'l' 0x6C */ {947, 2, 13, 4, 1, -12},
|
||||
/* 'm' 0x6D */ {951, 13, 10, 15, 1, -9},
|
||||
/* 'n' 0x6E */ {968, 8, 10, 10, 1, -9},
|
||||
/* 'o' 0x6F */ {978, 8, 10, 10, 1, -9},
|
||||
/* 'p' 0x70 */ {988, 9, 13, 10, 1, -9},
|
||||
/* 'q' 0x71 */ {1003, 8, 13, 10, 1, -9},
|
||||
/* 'r' 0x72 */ {1016, 5, 10, 6, 1, -9},
|
||||
/* 's' 0x73 */ {1023, 8, 10, 9, 1, -9},
|
||||
/* 't' 0x74 */ {1033, 4, 12, 5, 1, -11},
|
||||
/* 'u' 0x75 */ {1039, 8, 10, 10, 1, -9},
|
||||
/* 'v' 0x76 */ {1049, 9, 10, 9, 0, -9},
|
||||
/* 'w' 0x77 */ {1061, 13, 10, 13, 0, -9},
|
||||
/* 'x' 0x78 */ {1078, 7, 10, 9, 1, -9},
|
||||
/* 'y' 0x79 */ {1087, 8, 14, 9, 0, -9},
|
||||
/* 'z' 0x7A */ {1101, 7, 10, 9, 1, -9},
|
||||
/* '{' 0x7B */ {1110, 4, 17, 6, 1, -12},
|
||||
/* '|' 0x7C */ {1119, 2, 17, 4, 2, -12},
|
||||
/* '}' 0x7D */ {1124, 4, 17, 6, 1, -12},
|
||||
/* '~' 0x7E */ {1133, 7, 3, 9, 1, -7},
|
||||
/* 0x7F */ {1136, 13, 14, 15, 1, -12},
|
||||
/* 0x80 */ {1159, 10, 13, 12, 1, -12},
|
||||
/* 0x81 */ {1176, 0, 0, 0, 0, 0},
|
||||
/* 0x82 */ {1176, 2, 3, 5, 1, 0},
|
||||
/* 0x83 */ {1177, 0, 0, 0, 0, 0},
|
||||
/* 0x84 */ {1177, 5, 3, 7, 1, 0},
|
||||
/* 0x85 */ {1179, 10, 1, 12, 1, 0},
|
||||
/* 0x86 */ {1181, 8, 16, 10, 1, -12},
|
||||
/* 0x87 */ {1197, 8, 16, 10, 1, -12},
|
||||
/* 0x88 */ {1213, 0, 0, 0, 0, 0},
|
||||
/* 0x89 */ {1213, 18, 13, 18, 0, -12},
|
||||
/* 0x8A */ {1243, 10, 15, 12, 1, -14},
|
||||
/* 0x8B */ {1262, 2, 4, 4, 1, -6},
|
||||
/* 0x8C */ {1263, 10, 15, 12, 1, -14},
|
||||
/* 0x8D */ {1282, 9, 15, 11, 1, -14},
|
||||
/* 0x8E */ {1299, 10, 15, 11, 1, -14},
|
||||
/* 0x8F */ {1318, 10, 15, 11, 1, -14},
|
||||
/* 0x90 */ {1337, 0, 0, 0, 0, 0},
|
||||
/* 0x91 */ {1337, 2, 4, 4, 2, -12},
|
||||
/* 0x92 */ {1338, 2, 4, 4, 1, -12},
|
||||
/* 0x93 */ {1339, 5, 4, 7, 2, -12},
|
||||
/* 0x94 */ {1342, 5, 4, 7, 1, -12},
|
||||
/* 0x95 */ {1345, 4, 5, 7, 1, -8},
|
||||
/* 0x96 */ {1348, 7, 1, 9, 1, -4},
|
||||
/* 0x97 */ {1349, 16, 1, 18, 1, -4},
|
||||
/* 0x98 */ {1351, 0, 0, 0, 0, 0},
|
||||
/* 0x99 */ {1351, 18, 10, 18, 1, -13},
|
||||
/* 0x9A */ {1374, 8, 13, 9, 1, -12},
|
||||
/* 0x9B */ {1387, 2, 4, 5, 2, -6},
|
||||
/* 0x9C */ {1388, 8, 13, 9, 1, -12},
|
||||
/* 0x9D */ {1401, 6, 13, 8, 1, -12},
|
||||
/* 0x9E */ {1411, 7, 13, 9, 1, -12},
|
||||
/* 0x9F */ {1423, 7, 13, 9, 1, -12},
|
||||
/* 0xA0 */ {1435, 0, 0, 5, 0, 0},
|
||||
/* 0xA1 */ {1435, 5, 3, 6, 0, -12},
|
||||
/* 0xA2 */ {1437, 6, 2, 6, 0, -12},
|
||||
/* 0xA3 */ {1439, 9, 13, 11, 1, -12},
|
||||
/* 0xA4 */ {1454, 7, 6, 10, 2, -8},
|
||||
/* 0xA5 */ {1460, 12, 17, 12, 1, -12},
|
||||
/* 0xA6 */ {1486, 2, 17, 5, 2, -12},
|
||||
/* 0xA7 */ {1491, 9, 17, 10, 1, -12},
|
||||
/* 0xA8 */ {1511, 6, 1, 6, 0, -11},
|
||||
/* 0xA9 */ {1512, 14, 13, 14, 1, -12},
|
||||
/* 0xAA */ {1535, 10, 17, 12, 1, -12},
|
||||
/* 0xAB */ {1557, 7, 6, 9, 1, -7},
|
||||
/* 0xAC */ {1563, 9, 5, 11, 2, -5},
|
||||
/* 0xAD */ {1569, 0, 0, 0, 0, 0},
|
||||
/* 0xAE */ {1569, 14, 13, 14, 1, -12},
|
||||
/* 0xAF */ {1592, 10, 15, 11, 1, -14},
|
||||
/* 0xB0 */ {1611, 5, 5, 11, 3, -11},
|
||||
/* 0xB1 */ {1615, 9, 11, 11, 1, -10},
|
||||
/* 0xB2 */ {1628, 4, 4, 6, 1, 1},
|
||||
/* 0xB3 */ {1630, 4, 13, 5, 1, -12},
|
||||
/* 0xB4 */ {1637, 4, 3, 6, 2, -12},
|
||||
/* 0xB5 */ {1639, 9, 13, 10, 1, -9},
|
||||
/* 0xB6 */ {1654, 8, 16, 10, 2, -12},
|
||||
/* 0xB7 */ {1670, 3, 1, 5, 1, -4},
|
||||
/* 0xB8 */ {1671, 5, 4, 6, 1, 1},
|
||||
/* 0xB9 */ {1674, 10, 14, 10, 1, -9},
|
||||
/* 0xBA */ {1692, 8, 14, 9, 1, -9},
|
||||
/* 0xBB */ {1706, 7, 6, 9, 1, -7},
|
||||
/* 0xBC */ {1712, 8, 13, 10, 1, -12},
|
||||
/* 0xBD */ {1725, 6, 3, 6, 0, -12},
|
||||
/* 0xBE */ {1728, 5, 13, 7, 1, -12},
|
||||
/* 0xBF */ {1737, 7, 12, 9, 1, -11},
|
||||
/* 0xC0 */ {1748, 12, 15, 13, 1, -14},
|
||||
/* 0xC1 */ {1771, 10, 14, 12, 1, -13},
|
||||
/* 0xC2 */ {1789, 10, 14, 12, 1, -13},
|
||||
/* 0xC3 */ {1807, 10, 14, 12, 1, -13},
|
||||
/* 0xC4 */ {1825, 10, 14, 12, 1, -13},
|
||||
/* 0xC5 */ {1843, 8, 14, 10, 1, -13},
|
||||
/* 0xC6 */ {1857, 11, 15, 13, 1, -14},
|
||||
/* 0xC7 */ {1878, 11, 17, 13, 1, -12},
|
||||
/* 0xC8 */ {1902, 11, 15, 13, 1, -14},
|
||||
/* 0xC9 */ {1923, 9, 14, 11, 1, -13},
|
||||
/* 0xCA */ {1939, 11, 17, 12, 1, -12},
|
||||
/* 0xCB */ {1963, 9, 14, 11, 1, -13},
|
||||
/* 0xCC */ {1979, 9, 15, 11, 1, -14},
|
||||
/* 0xCD */ {1996, 3, 14, 5, 1, -13},
|
||||
/* 0xCE */ {2002, 5, 14, 5, 0, -13},
|
||||
/* 0xCF */ {2011, 10, 15, 13, 2, -14},
|
||||
/* 0xD0 */ {2030, 11, 13, 13, 1, -12},
|
||||
/* 0xD1 */ {2048, 11, 14, 13, 1, -13},
|
||||
/* 0xD2 */ {2068, 11, 14, 13, 1, -13},
|
||||
/* 0xD3 */ {2088, 12, 15, 13, 1, -14},
|
||||
/* 0xD4 */ {2111, 12, 15, 13, 1, -14},
|
||||
/* 0xD5 */ {2134, 12, 15, 13, 1, -14},
|
||||
/* 0xD6 */ {2157, 12, 15, 13, 1, -14},
|
||||
/* 0xD7 */ {2180, 7, 7, 11, 2, -7},
|
||||
/* 0xD8 */ {2187, 12, 15, 13, 1, -14},
|
||||
/* 0xD9 */ {2210, 11, 14, 13, 1, -13},
|
||||
/* 0xDA */ {2230, 11, 14, 13, 1, -13},
|
||||
/* 0xDB */ {2250, 11, 14, 13, 1, -13},
|
||||
/* 0xDC */ {2270, 11, 14, 13, 1, -13},
|
||||
/* 0xDD */ {2290, 12, 14, 12, 0, -13},
|
||||
/* 0xDE */ {2311, 9, 17, 11, 1, -12},
|
||||
/* 0xDF */ {2331, 9, 13, 11, 1, -12},
|
||||
/* 0xE0 */ {2346, 5, 13, 6, 1, -12},
|
||||
/* 0xE1 */ {2355, 9, 13, 10, 1, -12},
|
||||
/* 0xE2 */ {2370, 9, 13, 10, 1, -12},
|
||||
/* 0xE3 */ {2385, 9, 13, 10, 1, -12},
|
||||
/* 0xE4 */ {2400, 9, 12, 10, 1, -11},
|
||||
/* 0xE5 */ {2414, 3, 15, 4, 0, -14},
|
||||
/* 0xE6 */ {2420, 8, 13, 9, 1, -12},
|
||||
/* 0xE7 */ {2433, 8, 14, 9, 1, -9},
|
||||
/* 0xE8 */ {2447, 8, 13, 9, 1, -12},
|
||||
/* 0xE9 */ {2460, 8, 13, 10, 1, -12},
|
||||
/* 0xEA */ {2473, 8, 14, 10, 1, -9},
|
||||
/* 0xEB */ {2487, 8, 12, 10, 1, -11},
|
||||
/* 0xEC */ {2499, 8, 13, 10, 1, -12},
|
||||
/* 0xED */ {2512, 3, 13, 4, 1, -12},
|
||||
/* 0xEE */ {2517, 4, 13, 5, 0, -12},
|
||||
/* 0xEF */ {2524, 12, 13, 12, 1, -12},
|
||||
/* 0xF0 */ {2544, 9, 13, 10, 1, -12},
|
||||
/* 0xF1 */ {2559, 8, 13, 10, 1, -12},
|
||||
/* 0xF2 */ {2572, 8, 13, 10, 1, -12},
|
||||
/* 0xF3 */ {2585, 8, 13, 10, 1, -12},
|
||||
/* 0xF4 */ {2598, 8, 13, 10, 1, -12},
|
||||
/* 0xF5 */ {2611, 8, 13, 10, 1, -12},
|
||||
/* 0xF6 */ {2624, 8, 12, 10, 1, -11},
|
||||
/* 0xF7 */ {2636, 9, 8, 11, 1, -7},
|
||||
/* 0xF8 */ {2645, 5, 13, 6, 1, -12},
|
||||
/* 0xF9 */ {2654, 8, 13, 10, 1, -12},
|
||||
/* 0xFA */ {2667, 8, 13, 10, 1, -12},
|
||||
/* 0xFB */ {2680, 8, 13, 10, 1, -12},
|
||||
/* 0xFC */ {2693, 8, 12, 10, 1, -11},
|
||||
/* 0xFD */ {2705, 8, 17, 9, 0, -12},
|
||||
/* 0xFE */ {2722, 5, 16, 5, 1, -11},
|
||||
/* 0xFF */ {2732, 2, 1, 6, 2, -11},
|
||||
};
|
||||
|
||||
const GFXfont FreeSans9pt_Win1250 PROGMEM = {(uint8_t *)FreeSans9pt_Win1250Bitmaps, (GFXglyph *)FreeSans9pt_Win1250Glyphs, 0x20,
|
||||
0xFF, 21};
|
||||
@@ -0,0 +1,493 @@
|
||||
#pragma once
|
||||
const uint8_t FreeSans9pt_Win1251Bitmaps[] PROGMEM = {
|
||||
/* ' ' 0x20 */
|
||||
0xFF, 0xFF, 0xF0, 0xC0, /* '!' 0x21 */
|
||||
0xDE, 0xF7, 0x20, /* '"' 0x22 */
|
||||
0x09, 0x86, 0x41, 0x91, 0xFF, 0x13, 0x04, 0xC3, 0x20, 0xC8, 0xFF, 0x89, 0x82, 0x61, 0x90, /* '#' 0x23 */
|
||||
0x10, 0x1F, 0x14, 0xDA, 0x3D, 0x1E, 0x83, 0x40, 0x78, 0x17, 0x08, 0xF4, 0x7A, 0x35, 0x33, 0xF0, 0x40, 0x20, /* '$' 0x24 */
|
||||
0x38, 0x10, 0xEC, 0x20, 0xC6, 0x20, 0xC6, 0x40, 0xC6, 0x40, 0x6C, 0x80, 0x39, 0x00, 0x01, 0x3C, 0x02, 0x77, 0x02, 0x63, 0x04,
|
||||
0x63, 0x04, 0x77, 0x08, 0x3C, /* '%' 0x25 */
|
||||
0x0E, 0x0C, 0xC3, 0x30, 0xCC, 0x1E, 0x03, 0x03, 0xC1, 0x9B, 0xC2, 0xF0, 0xEC, 0x19, 0x8F, 0x3C, 0x40, /* '&' 0x26 */
|
||||
0xFE, /* ''' 0x27 */
|
||||
0x13, 0x26, 0x6C, 0xCC, 0xCC, 0xC4, 0x66, 0x23, 0x10, /* '(' 0x28 */
|
||||
0x8C, 0x46, 0x63, 0x33, 0x33, 0x32, 0x66, 0x4C, 0x80, /* ')' 0x29 */
|
||||
0x25, 0x7E, 0xA5, 0x00, /* '*' 0x2A */
|
||||
0x30, 0xC3, 0x3F, 0x30, 0xC3, 0x0C, /* '+' 0x2B */
|
||||
0xD6, /* ',' 0x2C */
|
||||
0xF0, /* '-' 0x2D */
|
||||
0xC0, /* '.' 0x2E */
|
||||
0x08, 0x44, 0x21, 0x10, 0x84, 0x42, 0x11, 0x08, 0x00, /* '/' 0x2F */
|
||||
0x3C, 0x66, 0x42, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0x42, 0x66, 0x3C, /* '0' 0x30 */
|
||||
0x11, 0x3F, 0x33, 0x33, 0x33, 0x33, 0x30, /* '1' 0x31 */
|
||||
0x3E, 0x31, 0xB0, 0x78, 0x30, 0x18, 0x1C, 0x1C, 0x1C, 0x18, 0x18, 0x10, 0x08, 0x07, 0xF8, /* '2' 0x32 */
|
||||
0x3C, 0x66, 0xC3, 0xC3, 0x03, 0x06, 0x1C, 0x07, 0x03, 0xC3, 0xC3, 0x66, 0x3C, /* '3' 0x33 */
|
||||
0x0C, 0x18, 0x71, 0x62, 0xC9, 0xA3, 0x46, 0xFE, 0x18, 0x30, 0x60, 0xC0, /* '4' 0x34 */
|
||||
0x7F, 0x20, 0x10, 0x08, 0x08, 0x07, 0xF3, 0x8C, 0x03, 0x01, 0x80, 0xF0, 0x6C, 0x63, 0xE0, /* '5' 0x35 */
|
||||
0x1E, 0x31, 0x98, 0x78, 0x0C, 0x06, 0xF3, 0x8D, 0x83, 0xC1, 0xE0, 0xD0, 0x6C, 0x63, 0xE0, /* '6' 0x36 */
|
||||
0xFF, 0x03, 0x02, 0x06, 0x04, 0x0C, 0x08, 0x18, 0x18, 0x18, 0x10, 0x30, 0x30, /* '7' 0x37 */
|
||||
0x3E, 0x31, 0xB0, 0x78, 0x3C, 0x1B, 0x18, 0xF8, 0xC6, 0xC1, 0xE0, 0xF0, 0x6C, 0x63, 0xE0, /* '8' 0x38 */
|
||||
0x3C, 0x66, 0xC2, 0xC3, 0xC3, 0xC3, 0x67, 0x3B, 0x03, 0x03, 0xC2, 0x66, 0x3C, /* '9' 0x39 */
|
||||
0xC0, 0x00, 0x30, /* ':' 0x3A */
|
||||
0xC0, 0x00, 0x00, 0x64, 0xA0, /* ';' 0x3B */
|
||||
0x00, 0x81, 0xC7, 0x8E, 0x0C, 0x07, 0x80, 0x70, 0x0E, 0x01, 0x80, /* '<' 0x3C */
|
||||
0xFF, 0x80, 0x00, 0x1F, 0xF0, /* '=' 0x3D */
|
||||
0xE0, 0x1C, 0x03, 0x80, 0x30, 0x70, 0xE3, 0x81, 0x00, /* '>' 0x3E */
|
||||
0x3E, 0x31, 0xB0, 0x78, 0x30, 0x18, 0x18, 0x38, 0x18, 0x18, 0x0C, 0x00, 0x00, 0x01, 0x80, /* '?' 0x3F */
|
||||
0x03, 0xF0, 0x06, 0x0E, 0x06, 0x01, 0x86, 0x00, 0x66, 0x1D, 0xBB, 0x31, 0xCF, 0x18, 0xC7, 0x98, 0x63, 0xCC, 0x31, 0xE6, 0x11,
|
||||
0xB3, 0x99, 0xCC, 0xF7, 0x86, 0x00, 0x01, 0x80, 0x00, 0x70, 0x40, 0x0F, 0xE0, /* '@' 0x40 */
|
||||
0x06, 0x00, 0xF0, 0x0F, 0x00, 0x90, 0x19, 0x81, 0x98, 0x10, 0x83, 0x0C, 0x3F, 0xC2, 0x04, 0x60, 0x66, 0x06, 0xC0,
|
||||
0x30, /* 'A' 0x41 */
|
||||
0xFF, 0x18, 0x33, 0x03, 0x60, 0x6C, 0x0D, 0x83, 0x3F, 0xC6, 0x06, 0xC0, 0x78, 0x0F, 0x01, 0xE0, 0x6F, 0xF8, /* 'B' 0x42 */
|
||||
0x1F, 0x86, 0x19, 0x81, 0xA0, 0x3C, 0x01, 0x80, 0x30, 0x06, 0x00, 0xC0, 0x68, 0x0D, 0x83, 0x18, 0x61, 0xF0, /* 'C' 0x43 */
|
||||
0xFF, 0x18, 0x33, 0x03, 0x60, 0x3C, 0x07, 0x80, 0xF0, 0x1E, 0x03, 0xC0, 0x78, 0x0F, 0x03, 0x60, 0xCF, 0xF0, /* 'D' 0x44 */
|
||||
0xFF, 0xE0, 0x30, 0x18, 0x0C, 0x06, 0x03, 0xFD, 0x80, 0xC0, 0x60, 0x30, 0x18, 0x0F, 0xF8, /* 'E' 0x45 */
|
||||
0xFF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xFE, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, /* 'F' 0x46 */
|
||||
0x0F, 0x83, 0x0E, 0x60, 0x66, 0x03, 0xC0, 0x0C, 0x00, 0xC1, 0xFC, 0x03, 0xC0, 0x36, 0x03, 0x60, 0x73, 0x0F, 0x0F,
|
||||
0x10, /* 'G' 0x47 */
|
||||
0xC0, 0x78, 0x0F, 0x01, 0xE0, 0x3C, 0x07, 0x80, 0xFF, 0xFE, 0x03, 0xC0, 0x78, 0x0F, 0x01, 0xE0, 0x3C, 0x06, /* 'H' 0x48 */
|
||||
0xFF, 0xFF, 0xFF, 0xC0, /* 'I' 0x49 */
|
||||
0x06, 0x0C, 0x18, 0x30, 0x60, 0xC1, 0x83, 0x07, 0x8F, 0x1E, 0x27, 0x80, /* 'J' 0x4A */
|
||||
0xC0, 0xF0, 0x6C, 0x33, 0x18, 0xCC, 0x37, 0x0F, 0xC3, 0x98, 0xC3, 0x30, 0xCC, 0x1B, 0x03, 0xC0, 0xC0, /* 'K' 0x4B */
|
||||
0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xFF, /* 'L' 0x4C */
|
||||
0xE0, 0x3F, 0x01, 0xFC, 0x1F, 0xE0, 0xFD, 0x05, 0xEC, 0x6F, 0x63, 0x79, 0x13, 0xCD, 0x9E, 0x6C, 0xF1, 0x47, 0x8E, 0x3C, 0x71,
|
||||
0x80, /* 'M' 0x4D */
|
||||
0xE0, 0x7C, 0x0F, 0xC1, 0xE8, 0x3D, 0x87, 0x98, 0xF1, 0x1E, 0x33, 0xC3, 0x78, 0x6F, 0x07, 0xE0, 0x7C, 0x0E, /* 'N' 0x4E */
|
||||
0x0F, 0x81, 0x83, 0x18, 0x0C, 0xC0, 0x6C, 0x01, 0xE0, 0x0F, 0x00, 0x78, 0x03, 0xC0, 0x1B, 0x01, 0x98, 0x0C, 0x60, 0xC0, 0xF8,
|
||||
0x00, /* 'O' 0x4F */
|
||||
0xFF, 0x30, 0x6C, 0x0F, 0x03, 0xC0, 0xF0, 0x6F, 0xF3, 0x00, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x00, /* 'P' 0x50 */
|
||||
0x0F, 0x81, 0x83, 0x18, 0x0C, 0xC0, 0x6C, 0x01, 0xE0, 0x0F, 0x00, 0x78, 0x03, 0xC0, 0x1B, 0x01, 0x98, 0x6C, 0x60, 0xC0, 0xFB,
|
||||
0x00, 0x08, /* 'Q' 0x51 */
|
||||
0xFF, 0x8C, 0x0E, 0xC0, 0x6C, 0x06, 0xC0, 0x6C, 0x0C, 0xFF, 0x8C, 0x0E, 0xC0, 0x6C, 0x06, 0xC0, 0x6C, 0x06, 0xC0,
|
||||
0x70, /* 'R' 0x52 */
|
||||
0x3F, 0x18, 0x6C, 0x0F, 0x03, 0xC0, 0x1E, 0x01, 0xF0, 0x0E, 0x00, 0xF0, 0x3C, 0x0D, 0x86, 0x3F, 0x00, /* 'S' 0x53 */
|
||||
0xFF, 0x86, 0x03, 0x01, 0x80, 0xC0, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, 0x01, 0x80, 0xC0, /* 'T' 0x54 */
|
||||
0xC0, 0x78, 0x0F, 0x01, 0xE0, 0x3C, 0x07, 0x80, 0xF0, 0x1E, 0x03, 0xC0, 0x78, 0x0F, 0x01, 0xB0, 0x61, 0xF0, /* 'U' 0x55 */
|
||||
0xC0, 0x6C, 0x0D, 0x81, 0x10, 0x63, 0x0C, 0x61, 0x04, 0x60, 0xCC, 0x19, 0x01, 0x60, 0x3C, 0x07, 0x00, 0x60, /* 'V' 0x56 */
|
||||
0xC1, 0x81, 0x61, 0xC3, 0x61, 0xC3, 0x61, 0x43, 0x62, 0x62, 0x22, 0x66, 0x32, 0x26, 0x36, 0x26, 0x14, 0x34, 0x14, 0x34, 0x1C,
|
||||
0x1C, 0x18, 0x1C, 0x08, 0x18, /* 'W' 0x57 */
|
||||
0xC0, 0xD8, 0x66, 0x18, 0xCC, 0x1E, 0x07, 0x00, 0xC0, 0x78, 0x32, 0x0C, 0xC6, 0x1B, 0x07, 0xC0, 0xC0, /* 'X' 0x58 */
|
||||
0xC0, 0x36, 0x06, 0x30, 0xC3, 0x0C, 0x19, 0x81, 0xD8, 0x0F, 0x00, 0x60, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60, 0x06,
|
||||
0x00, /* 'Y' 0x59 */
|
||||
0xFF, 0xC0, 0x60, 0x30, 0x0C, 0x06, 0x03, 0x01, 0xC0, 0x60, 0x30, 0x18, 0x06, 0x03, 0x00, 0xFF, 0xC0, /* 'Z' 0x5A */
|
||||
0xFB, 0x6D, 0xB6, 0xDB, 0x6D, 0xB6, 0xE0, /* '[' 0x5B */
|
||||
0x84, 0x10, 0x84, 0x10, 0x84, 0x10, 0x84, 0x10, 0x80, /* '\' 0x5C */
|
||||
0xED, 0xB6, 0xDB, 0x6D, 0xB6, 0xDB, 0xE0, /* ']' 0x5D */
|
||||
0x30, 0x60, 0xA2, 0x44, 0xD8, 0xA1, 0x80, /* '^' 0x5E */
|
||||
0xFF, 0xC0, /* '_' 0x5F */
|
||||
0xC6, 0x30, /* '`' 0x60 */
|
||||
0x7E, 0x71, 0xB0, 0xC0, 0x60, 0xF3, 0xDB, 0x0D, 0x86, 0xC7, 0x3D, 0xC0, /* 'a' 0x61 */
|
||||
0xC0, 0x60, 0x30, 0x1B, 0xCE, 0x36, 0x0F, 0x07, 0x83, 0xC1, 0xE0, 0xF0, 0x7C, 0x6D, 0xE0, /* 'b' 0x62 */
|
||||
0x3C, 0x66, 0xC3, 0xC0, 0xC0, 0xC0, 0xC0, 0xC3, 0x66, 0x3C, /* 'c' 0x63 */
|
||||
0x03, 0x03, 0x03, 0x3B, 0x67, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0x67, 0x3B, /* 'd' 0x64 */
|
||||
0x3C, 0x66, 0xC3, 0xC3, 0xFF, 0xC0, 0xC0, 0xC3, 0x66, 0x3C, /* 'e' 0x65 */
|
||||
0x36, 0x6F, 0x66, 0x66, 0x66, 0x66, 0x60, /* 'f' 0x66 */
|
||||
0x3B, 0x67, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0x67, 0x3B, 0x03, 0x03, 0xC6, 0x7C, /* 'g' 0x67 */
|
||||
0xC0, 0xC0, 0xC0, 0xDE, 0xE3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, /* 'h' 0x68 */
|
||||
0xC3, 0xFF, 0xFF, 0xC0, /* 'i' 0x69 */
|
||||
0x30, 0x03, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0xE0, /* 'j' 0x6A */
|
||||
0xC0, 0xC0, 0xC0, 0xC2, 0xC4, 0xCC, 0xD8, 0xF8, 0xEC, 0xC4, 0xC6, 0xC3, 0xC3, /* 'k' 0x6B */
|
||||
0xFF, 0xFF, 0xFF, 0xC0, /* 'l' 0x6C */
|
||||
0xDE, 0xF7, 0x1C, 0xF0, 0xC7, 0x86, 0x3C, 0x31, 0xE1, 0x8F, 0x0C, 0x78, 0x63, 0xC3, 0x1E, 0x18, 0xC0, /* 'm' 0x6D */
|
||||
0xDE, 0xE3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, /* 'n' 0x6E */
|
||||
0x3C, 0x66, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0x66, 0x3C, /* 'o' 0x6F */
|
||||
0xDE, 0x71, 0xB0, 0x78, 0x3C, 0x1E, 0x0F, 0x07, 0x83, 0xE3, 0x6F, 0x30, 0x18, 0x0C, 0x00, /* 'p' 0x70 */
|
||||
0x3B, 0x67, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0x67, 0x3B, 0x03, 0x03, 0x03, /* 'q' 0x71 */
|
||||
0xDF, 0x31, 0x8C, 0x63, 0x18, 0xC6, 0x00, /* 'r' 0x72 */
|
||||
0x3E, 0xE3, 0xC0, 0xC0, 0xE0, 0x3C, 0x07, 0xC3, 0xE3, 0x7E, /* 's' 0x73 */
|
||||
0x66, 0xF6, 0x66, 0x66, 0x66, 0x67, /* 't' 0x74 */
|
||||
0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC7, 0x7B, /* 'u' 0x75 */
|
||||
0xC1, 0xA0, 0x98, 0xCC, 0x42, 0x21, 0xB0, 0xD0, 0x28, 0x1C, 0x0C, 0x00, /* 'v' 0x76 */
|
||||
0xC6, 0x1E, 0x38, 0x91, 0xC4, 0xCA, 0x66, 0xD3, 0x16, 0xD0, 0xA6, 0x87, 0x1C, 0x38, 0xC0, 0xC6, 0x00, /* 'w' 0x77 */
|
||||
0x87, 0x89, 0xB1, 0xC3, 0x07, 0x1E, 0x26, 0xC5, 0x0C, /* 'x' 0x78 */
|
||||
0xC1, 0x43, 0x63, 0x62, 0x26, 0x36, 0x34, 0x1C, 0x1C, 0x18, 0x18, 0x18, 0x10, 0x60, /* 'y' 0x79 */
|
||||
0xFE, 0x0C, 0x30, 0xC1, 0x86, 0x18, 0x20, 0xC1, 0xFC, /* 'z' 0x7A */
|
||||
0x36, 0x66, 0x66, 0x6E, 0xCE, 0x66, 0x66, 0x66, 0x30, /* '{' 0x7B */
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xC0, /* '|' 0x7C */
|
||||
0xC6, 0x66, 0x66, 0x67, 0x37, 0x66, 0x66, 0x66, 0xC0, /* '}' 0x7D */
|
||||
0x61, 0x24, 0x38, /* '~' 0x7E */
|
||||
0xFF, 0xFC, 0x00, 0x63, 0xE3, 0x31, 0x99, 0x04, 0xC8, 0x66, 0x06, 0x30, 0x61, 0x83, 0x0C, 0x18, 0x60, 0x03, 0x06, 0x18, 0x00,
|
||||
0xFF, 0xFC, /* 0x7F */
|
||||
0xFF, 0x01, 0x80, 0x18, 0x01, 0x80, 0x18, 0x01, 0xFE, 0x18, 0x31, 0x83, 0x18, 0x31, 0x83, 0x18, 0x31, 0x83, 0x18, 0x30, 0x03,
|
||||
0x00, 0x30, 0x0E, /* 0x80 */
|
||||
0x0C, 0x18, 0x00, 0xFF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, /* 0x81 */
|
||||
0xDC, /* 0x82 */
|
||||
0x18, 0x89, 0xFC, 0x63, 0x18, 0xC6, 0x31, 0x8C, 0x00, /* 0x83 */
|
||||
0xDA, 0x76, /* 0x84 */
|
||||
0xCC, 0xC0, /* 0x85 */
|
||||
0x18, 0x18, 0x18, 0x18, 0xFF, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, /* 0x86 */
|
||||
0x18, 0x18, 0x18, 0x18, 0xFF, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xFF, 0x18, 0x18, 0x18, 0x18, /* 0x87 */
|
||||
0x07, 0xC6, 0x13, 0x00, 0xC0, 0x60, 0x3F, 0xE6, 0x03, 0xFC, 0x60, 0x0C, 0x03, 0x00, 0x61, 0x07, 0xC0, /* 0x88 */
|
||||
0x70, 0x80, 0x22, 0x20, 0x08, 0x90, 0x02, 0x24, 0x00, 0x72, 0x00, 0x00, 0x80, 0x00, 0x40, 0x00, 0x10, 0x00, 0x09, 0xC7, 0x84,
|
||||
0x8B, 0x31, 0x22, 0x84, 0x88, 0xB3, 0x21, 0xC7, 0x80, /* 0x89 */
|
||||
0x3F, 0x80, 0x18, 0xC0, 0x0C, 0x60, 0x06, 0x30, 0x03, 0x18, 0x01, 0x8C, 0x00, 0xC7, 0xF8, 0x63, 0x06, 0x31, 0x81, 0x90, 0xC0,
|
||||
0xD8, 0x60, 0x6C, 0x30, 0x6C, 0x1F, 0xE0, /* 0x8A */
|
||||
0x69, /* 0x8B */
|
||||
0xC0, 0xC0, 0x60, 0x60, 0x30, 0x30, 0x18, 0x18, 0x0C, 0x0C, 0x06, 0x06, 0x03, 0xFF, 0xF9, 0x81, 0x86, 0xC0, 0xC1, 0xE0, 0x60,
|
||||
0xF0, 0x30, 0x78, 0x18, 0x6C, 0x0F, 0xE0, /* 0x8C */
|
||||
0x0C, 0x06, 0x0C, 0x1B, 0x0C, 0xC6, 0x33, 0x0D, 0x83, 0xC0, 0xF0, 0x3E, 0x0D, 0xC3, 0x38, 0xC7, 0x30, 0xEC, 0x1C, /* 0x8D */
|
||||
0xFF, 0x01, 0x80, 0x18, 0x01, 0x80, 0x18, 0x01, 0xFE, 0x18, 0x31, 0x83, 0x18, 0x31, 0x83, 0x18, 0x31, 0x83, 0x18,
|
||||
0x30, /* 0x8E */
|
||||
0xC0, 0x78, 0x0F, 0x01, 0xE0, 0x3C, 0x07, 0x80, 0xF0, 0x1E, 0x03, 0xC0, 0x78, 0x0F, 0x01, 0xE0, 0x3F, 0xFE, 0x0C, 0x01,
|
||||
0x80, /* 0x8F */
|
||||
0x60, 0x7C, 0x18, 0x0D, 0xE7, 0x1B, 0x0D, 0x86, 0xC3, 0x61, 0xB0, 0xD8, 0x6C, 0x36, 0x18, 0x18, 0x08, 0x08, /* 0x90 */
|
||||
0x6B, /* 0x91 */
|
||||
0xD6, /* 0x92 */
|
||||
0x4C, 0xA5, 0xB0, /* 0x93 */
|
||||
0xDA, 0x53, 0x20, /* 0x94 */
|
||||
0x6F, 0xFF, 0x60, /* 0x95 */
|
||||
0xFE, /* 0x96 */
|
||||
0xFF, 0xFF, /* 0x97 */
|
||||
/* 0x98 */
|
||||
0xFC, 0xE1, 0xCC, 0x38, 0x73, 0x0E, 0x1C, 0xC3, 0x8F, 0x30, 0xD2, 0xCC, 0x34, 0xB3, 0x0D, 0x6C, 0xC3, 0x53, 0x30, 0xCC, 0xCC,
|
||||
0x33, 0x30, /* 0x99 */
|
||||
0x7E, 0x03, 0x30, 0x19, 0x80, 0xCC, 0x06, 0x60, 0x33, 0xF9, 0x98, 0x6C, 0xC3, 0x46, 0x1E, 0x3F, 0x80, /* 0x9A */
|
||||
0x96, /* 0x9B */
|
||||
0xC3, 0x03, 0x0C, 0x0C, 0x30, 0x30, 0xC0, 0xC3, 0x03, 0xFF, 0xEC, 0x30, 0xF0, 0xC3, 0xC3, 0x0F, 0x0F, 0xE0, /* 0x9C */
|
||||
0x0C, 0x30, 0x46, 0x3C, 0xDB, 0x34, 0x70, 0xF1, 0xB3, 0x36, 0x3C, 0x20, /* 0x9D */
|
||||
0x60, 0x7C, 0x18, 0x0D, 0xE7, 0x3B, 0x0D, 0x86, 0xC3, 0x61, 0xB0, 0xD8, 0x6C, 0x36, 0x18, /* 0x9E */
|
||||
0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xFF, 0x18, 0x18, /* 0x9F */
|
||||
/* 0xA0 */
|
||||
0x21, 0x07, 0x8C, 0x0F, 0x06, 0x61, 0x98, 0xC3, 0x30, 0xD8, 0x1E, 0x07, 0x00, 0xC0, 0x60, 0x18, 0x0C, 0x03, 0x00, /* 0xA1 */
|
||||
0x66, 0x18, 0xC1, 0x43, 0x63, 0x62, 0x26, 0x36, 0x34, 0x1C, 0x1C, 0x18, 0x18, 0x18, 0x10, 0x60, /* 0xA2 */
|
||||
0x06, 0x0C, 0x18, 0x30, 0x60, 0xC1, 0x83, 0x07, 0x8F, 0x1E, 0x27, 0x80, /* 0xA3 */
|
||||
0xFF, 0xDF, 0x1E, 0x3E, 0xFF, 0xC0, /* 0xA4 */
|
||||
0x00, 0xC0, 0x3F, 0xFF, 0x00, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x30, 0x00, /* 0xA5 */
|
||||
0xFF, 0xFC, 0x0F, 0xFF, 0xC0, /* 0xA6 */
|
||||
0x0C, 0x09, 0x0C, 0xC6, 0x63, 0x81, 0xE3, 0x19, 0x87, 0xE1, 0xB8, 0xC6, 0x41, 0xC0, 0x73, 0x19, 0x8C, 0x66, 0x1E,
|
||||
0x00, /* 0xA7 */
|
||||
0x33, 0x00, 0x3F, 0xF8, 0x0C, 0x06, 0x03, 0x01, 0x80, 0xFF, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, 0xFE, /* 0xA8 */
|
||||
0x0F, 0xC0, 0x61, 0x87, 0x03, 0x9B, 0xC6, 0xD9, 0x8F, 0x60, 0x3D, 0x00, 0xF4, 0x03, 0xD8, 0x0D, 0xE6, 0x67, 0xF3, 0x86, 0x18,
|
||||
0x0F, 0xC0, /* 0xA9 */
|
||||
0x1F, 0x86, 0x19, 0x81, 0xB0, 0x3C, 0x01, 0x80, 0x3F, 0xC6, 0x00, 0xC0, 0x68, 0x0D, 0x83, 0x18, 0x61, 0xF0, /* 0xAA */
|
||||
0x22, 0xCF, 0x26, 0x46, 0x64, 0x40, /* 0xAB */
|
||||
0xFF, 0x80, 0xC0, 0x60, 0x30, 0x18, /* 0xAC */
|
||||
/* 0xAD */
|
||||
0x0F, 0xC0, 0x61, 0x87, 0x03, 0x9F, 0xE6, 0xD0, 0x8F, 0x42, 0x3D, 0xF0, 0xF4, 0x23, 0xD0, 0x8D, 0xC2, 0x67, 0x0B, 0x86, 0x18,
|
||||
0x0F, 0xC0, /* 0xAE */
|
||||
0xCC, 0x03, 0x0C, 0x30, 0xC3, 0x0C, 0x30, 0xC3, 0x0C, 0x30, 0xC3, 0x00, /* 0xAF */
|
||||
0x74, 0x63, 0x17, 0x00, /* 0xB0 */
|
||||
0x0C, 0x06, 0x03, 0x07, 0xE0, 0xC0, 0x60, 0x30, 0x18, 0x00, 0x00, 0x3F, 0xE0, /* 0xB1 */
|
||||
0xFF, 0xFF, 0xFF, 0xC0, /* 0xB2 */
|
||||
0xC3, 0xFF, 0xFF, 0xC0, /* 0xB3 */
|
||||
0x0C, 0x3F, 0xF0, 0xC3, 0x0C, 0x30, 0xC3, 0x0C, 0x30, /* 0xB4 */
|
||||
0xC3, 0x61, 0xB0, 0xD8, 0x6C, 0x36, 0x1B, 0x0D, 0x86, 0xE7, 0x7D, 0xF0, 0x18, 0x0C, 0x00, /* 0xB5 */
|
||||
0x3F, 0x7E, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0x72, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, /* 0xB6 */
|
||||
0xE0, /* 0xB7 */
|
||||
0x66, 0x00, 0x3C, 0x66, 0xC3, 0xC3, 0xFF, 0xC0, 0xC0, 0xC3, 0x66, 0x3C, /* 0xB8 */
|
||||
0xC1, 0x81, 0x83, 0x03, 0x86, 0x05, 0x0C, 0xEB, 0x1A, 0x32, 0x34, 0x66, 0x68, 0xC4, 0xD1, 0x8D, 0xB3, 0x0B, 0x3A, 0x1E, 0x04,
|
||||
0x1C, 0x08, 0x1B, 0xC0, /* 0xB9 */
|
||||
0x3C, 0x46, 0xC3, 0x80, 0xF8, 0x80, 0x80, 0xC3, 0x46, 0x3C, /* 0xBA */
|
||||
0x89, 0x98, 0x99, 0x3C, 0xD1, 0x00, /* 0xBB */
|
||||
0x30, 0x03, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0xE0, /* 0xBC */
|
||||
0x3F, 0x18, 0x6C, 0x0F, 0x03, 0xC0, 0x1E, 0x01, 0xF0, 0x0E, 0x00, 0xF0, 0x3C, 0x0D, 0x86, 0x3F, 0x00, /* 0xBD */
|
||||
0x3E, 0xE3, 0xC0, 0xC0, 0x60, 0x3C, 0x07, 0xC3, 0xE3, 0x7E, /* 0xBE */
|
||||
0xCC, 0x03, 0x0C, 0x30, 0xC3, 0x0C, 0x30, 0xC3, 0x0C, /* 0xBF */
|
||||
0x06, 0x00, 0xF0, 0x0F, 0x00, 0x90, 0x19, 0x81, 0x98, 0x10, 0x83, 0x0C, 0x3F, 0xC2, 0x04, 0x60, 0x66, 0x06, 0xC0,
|
||||
0x30, /* 0xC0 */
|
||||
0xFF, 0x18, 0x03, 0x00, 0x60, 0x0C, 0x01, 0x80, 0x3F, 0xE6, 0x06, 0xC0, 0x78, 0x0F, 0x01, 0xE0, 0x6F, 0xF8, /* 0xC1 */
|
||||
0xFF, 0x18, 0x33, 0x03, 0x60, 0x6C, 0x0D, 0x83, 0x3F, 0xC6, 0x06, 0xC0, 0x78, 0x0F, 0x01, 0xE0, 0x6F, 0xF8, /* 0xC2 */
|
||||
0xFF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, /* 0xC3 */
|
||||
0x1F, 0xF0, 0x60, 0xC1, 0x83, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC1, 0x83, 0x06, 0x0C, 0x18, 0x30, 0x60, 0xC1, 0x03, 0x0C, 0x0C,
|
||||
0xFF, 0xFF, 0x00, 0x3C, 0x00, 0xF0, 0x03, /* 0xC4 */
|
||||
0xFF, 0xE0, 0x30, 0x18, 0x0C, 0x06, 0x03, 0xFD, 0x80, 0xC0, 0x60, 0x30, 0x18, 0x0F, 0xF8, /* 0xC5 */
|
||||
0x61, 0x86, 0x31, 0x8C, 0x19, 0x98, 0x19, 0x98, 0x0D, 0xB0, 0x07, 0xE0, 0x03, 0xC0, 0x07, 0xE0, 0x0D, 0xB0, 0x19, 0x98, 0x31,
|
||||
0x8C, 0x61, 0x86, 0xC1, 0x83, /* 0xC6 */
|
||||
0x3F, 0x18, 0x6C, 0x0F, 0x03, 0x00, 0xC0, 0x60, 0xF0, 0x06, 0x00, 0xF0, 0x3C, 0x0D, 0x86, 0x3F, 0x00, /* 0xC7 */
|
||||
0xC0, 0xF8, 0x1F, 0x07, 0xE0, 0xBC, 0x37, 0x8C, 0xF1, 0x1E, 0x63, 0xD8, 0x7A, 0x0F, 0xC1, 0xF0, 0x3E, 0x06, /* 0xC8 */
|
||||
0x11, 0x03, 0xE0, 0x00, 0x60, 0x7C, 0x0F, 0x83, 0xF0, 0x5E, 0x1B, 0xC6, 0x78, 0x8F, 0x31, 0xEC, 0x3D, 0x07, 0xE0, 0xF8, 0x1F,
|
||||
0x03, /* 0xC9 */
|
||||
0xC1, 0xB0, 0xCC, 0x63, 0x30, 0xD8, 0x3C, 0x0F, 0x03, 0xE0, 0xDC, 0x33, 0x8C, 0x73, 0x0E, 0xC1, 0xC0, /* 0xCA */
|
||||
0x3F, 0xCC, 0x33, 0x0C, 0xC3, 0x30, 0xCC, 0x33, 0x0C, 0xC3, 0x30, 0xC8, 0x36, 0x0D, 0x83, 0xC0, 0xC0, /* 0xCB */
|
||||
0xE0, 0x3F, 0x01, 0xFC, 0x1F, 0xE0, 0xFD, 0x05, 0xEC, 0x6F, 0x63, 0x79, 0x13, 0xCD, 0x9E, 0x6C, 0xF1, 0x47, 0x8E, 0x3C, 0x71,
|
||||
0x80, /* 0xCC */
|
||||
0xC0, 0x78, 0x0F, 0x01, 0xE0, 0x3C, 0x07, 0x80, 0xFF, 0xFE, 0x03, 0xC0, 0x78, 0x0F, 0x01, 0xE0, 0x3C, 0x06, /* 0xCD */
|
||||
0x0F, 0x81, 0x83, 0x18, 0x0C, 0xC0, 0x6C, 0x01, 0xE0, 0x0F, 0x00, 0x78, 0x03, 0xC0, 0x1B, 0x01, 0x98, 0x0C, 0x60, 0xC0, 0xF8,
|
||||
0x00, /* 0xCE */
|
||||
0xFF, 0xF8, 0x0F, 0x01, 0xE0, 0x3C, 0x07, 0x80, 0xF0, 0x1E, 0x03, 0xC0, 0x78, 0x0F, 0x01, 0xE0, 0x3C, 0x06, /* 0xCF */
|
||||
0xFF, 0x30, 0x6C, 0x0F, 0x03, 0xC0, 0xF0, 0x6F, 0xF3, 0x00, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x00, /* 0xD0 */
|
||||
0x1F, 0x86, 0x19, 0x81, 0xA0, 0x3C, 0x01, 0x80, 0x30, 0x06, 0x00, 0xC0, 0x68, 0x0D, 0x83, 0x18, 0x61, 0xF0, /* 0xD1 */
|
||||
0xFF, 0x86, 0x03, 0x01, 0x80, 0xC0, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, 0x01, 0x80, 0xC0, /* 0xD2 */
|
||||
0xC0, 0xF0, 0x66, 0x19, 0x8C, 0x33, 0x0D, 0x81, 0xE0, 0x70, 0x0C, 0x06, 0x01, 0x80, 0xC0, 0x30, 0x00, /* 0xD3 */
|
||||
0x03, 0x00, 0x0C, 0x01, 0xFE, 0x1C, 0xCE, 0xE3, 0x1F, 0x0C, 0x3C, 0x30, 0xF0, 0xC3, 0xE3, 0x1D, 0xCC, 0xE3, 0xFF, 0x00, 0xC0,
|
||||
0x03, 0x00, /* 0xD4 */
|
||||
0xC0, 0xD8, 0x66, 0x18, 0xCC, 0x1E, 0x07, 0x00, 0xC0, 0x78, 0x32, 0x0C, 0xC6, 0x1B, 0x07, 0xC0, 0xC0, /* 0xD5 */
|
||||
0xC0, 0x66, 0x03, 0x30, 0x19, 0x80, 0xCC, 0x06, 0x60, 0x33, 0x01, 0x98, 0x0C, 0xC0, 0x66, 0x03, 0x30, 0x19, 0x80, 0xCF, 0xFF,
|
||||
0x80, 0x0C, 0x00, 0x60, /* 0xD6 */
|
||||
0xC1, 0xE0, 0xF0, 0x78, 0x3C, 0x1E, 0x0F, 0x06, 0xFF, 0x01, 0x80, 0xC0, 0x60, 0x30, 0x18, /* 0xD7 */
|
||||
0xC3, 0x1E, 0x18, 0xF0, 0xC7, 0x86, 0x3C, 0x31, 0xE1, 0x8F, 0x0C, 0x78, 0x63, 0xC3, 0x1E, 0x18, 0xF0, 0xC7, 0x86, 0x3F, 0xFF,
|
||||
0x80, /* 0xD8 */
|
||||
0xC3, 0x19, 0x86, 0x33, 0x0C, 0x66, 0x18, 0xCC, 0x31, 0x98, 0x63, 0x30, 0xC6, 0x61, 0x8C, 0xC3, 0x19, 0x86, 0x33, 0x0C, 0x66,
|
||||
0x18, 0xCF, 0xFF, 0xE0, 0x00, 0xC0, 0x01, 0x80, /* 0xD9 */
|
||||
0xF8, 0x00, 0xC0, 0x06, 0x00, 0x30, 0x01, 0x80, 0x0F, 0xF0, 0x60, 0xC3, 0x03, 0x18, 0x18, 0xC0, 0xC6, 0x06, 0x30, 0x61, 0xFE,
|
||||
0x00, /* 0xDA */
|
||||
0xC0, 0x0F, 0x00, 0x3C, 0x00, 0xF0, 0x03, 0xC0, 0x0F, 0xFE, 0x3C, 0x0C, 0xF0, 0x1B, 0xC0, 0x6F, 0x01, 0xBC, 0x06, 0xF0, 0x33,
|
||||
0xFF, 0x8C, /* 0xDB */
|
||||
0xC0, 0x18, 0x03, 0x00, 0x60, 0x0C, 0x01, 0xFF, 0x30, 0x36, 0x03, 0xC0, 0x78, 0x0F, 0x01, 0xE0, 0x6F, 0xF8, /* 0xDC */
|
||||
0x3F, 0x0C, 0x33, 0x83, 0x60, 0x20, 0x06, 0x00, 0x47, 0xF8, 0x01, 0xC0, 0x78, 0x0D, 0x81, 0x30, 0xC1, 0xF0, /* 0xDD */
|
||||
0xC0, 0xF8, 0x61, 0x83, 0x31, 0x80, 0xD8, 0xC0, 0x6C, 0xC0, 0x1E, 0x60, 0x0F, 0xF0, 0x07, 0x98, 0x03, 0xCC, 0x01, 0xE3, 0x01,
|
||||
0xB1, 0x80, 0xD8, 0x60, 0xCC, 0x0F, 0x80, /* 0xDE */
|
||||
0x3F, 0xD8, 0x3C, 0x0F, 0x03, 0xC0, 0xD8, 0x33, 0xFC, 0x33, 0x18, 0xCC, 0x36, 0x0D, 0x83, 0xC0, 0xC0, /* 0xDF */
|
||||
0x7E, 0x71, 0xB0, 0xC0, 0x60, 0xF3, 0xDB, 0x0D, 0x86, 0xC7, 0x3D, 0xC0, /* 0xE0 */
|
||||
0x03, 0x1F, 0x78, 0x40, 0xFC, 0xE6, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0x66, 0x3C, /* 0xE1 */
|
||||
0xFD, 0x8F, 0x0E, 0x3F, 0xDF, 0xB1, 0xE1, 0xC7, 0xF8, /* 0xE2 */
|
||||
0xFE, 0x31, 0x8C, 0x63, 0x18, 0xC6, 0x00, /* 0xE3 */
|
||||
0x1F, 0x83, 0x30, 0x66, 0x0C, 0xC1, 0x98, 0x33, 0x06, 0x61, 0x8C, 0x31, 0x9F, 0xFF, 0x01, 0xE0, 0x30, /* 0xE4 */
|
||||
0x3C, 0x66, 0xC3, 0xC3, 0xFF, 0xC0, 0xC0, 0xC3, 0x66, 0x3C, /* 0xE5 */
|
||||
0xC6, 0x36, 0x66, 0x36, 0xC1, 0xF8, 0x0F, 0x01, 0xF8, 0x36, 0xC6, 0x66, 0xC6, 0x38, 0x61, /* 0xE6 */
|
||||
0x79, 0x8C, 0x18, 0x30, 0x43, 0x01, 0xE3, 0xC6, 0xF8, /* 0xE7 */
|
||||
0xC7, 0xC7, 0xCF, 0xCB, 0xCB, 0xD3, 0xD3, 0xF3, 0xE3, 0xE3, /* 0xE8 */
|
||||
0x66, 0x18, 0xC7, 0xC7, 0xCF, 0xCB, 0xCB, 0xD3, 0xD3, 0xF3, 0xE3, 0xE3, /* 0xE9 */
|
||||
0xC7, 0x9B, 0x66, 0x8E, 0x1E, 0x36, 0x66, 0xC7, 0x84, /* 0xEA */
|
||||
0x7E, 0xCD, 0x9B, 0x36, 0x6C, 0xD9, 0xA3, 0xC7, 0x0C, /* 0xEB */
|
||||
0xE3, 0xF1, 0xF8, 0xFE, 0xFF, 0x7E, 0xAF, 0x77, 0x93, 0xC9, 0xE0, 0xC0, /* 0xEC */
|
||||
0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xFF, 0xC3, 0xC3, 0xC3, 0xC3, /* 0xED */
|
||||
0x3C, 0x66, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0x66, 0x3C, /* 0xEE */
|
||||
0xFF, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, /* 0xEF */
|
||||
0xDE, 0x71, 0xB0, 0x78, 0x3C, 0x1E, 0x0F, 0x07, 0x83, 0xE3, 0x6F, 0x30, 0x18, 0x0C, 0x00, /* 0xF0 */
|
||||
0x3C, 0x66, 0xC3, 0xC0, 0xC0, 0xC0, 0xC0, 0xC3, 0x66, 0x3C, /* 0xF1 */
|
||||
0xFC, 0xC3, 0x0C, 0x30, 0xC3, 0x0C, 0x30, 0xC0, /* 0xF2 */
|
||||
0xC1, 0x43, 0x63, 0x62, 0x26, 0x36, 0x34, 0x1C, 0x1C, 0x18, 0x18, 0x18, 0x10, 0x60, /* 0xF3 */
|
||||
0x03, 0x00, 0x0C, 0x03, 0xB7, 0x19, 0xE6, 0xC3, 0x0F, 0x0C, 0x3C, 0x30, 0xF0, 0xC3, 0xC3, 0x0F, 0x0C, 0x36, 0x79, 0x8E, 0xDC,
|
||||
0x03, 0x00, 0x0C, 0x00, 0x30, 0x00, /* 0xF4 */
|
||||
0x87, 0x89, 0xB1, 0xC3, 0x07, 0x1E, 0x26, 0xC5, 0x0C, /* 0xF5 */
|
||||
0xC3, 0x30, 0xCC, 0x33, 0x0C, 0xC3, 0x30, 0xCC, 0x33, 0x0C, 0xC3, 0x3F, 0xF0, 0x0C, 0x03, /* 0xF6 */
|
||||
0xC7, 0x8F, 0x1E, 0x3C, 0x6F, 0xC1, 0x83, 0x06, 0x0C, /* 0xF7 */
|
||||
0xCC, 0xF3, 0x3C, 0xCF, 0x33, 0xCC, 0xF3, 0x3C, 0xCF, 0x33, 0xCC, 0xFF, 0xF0, /* 0xF8 */
|
||||
0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCF, 0xFF, 0x00, 0x30, 0x03, /* 0xF9 */
|
||||
0xF0, 0x18, 0x0C, 0x06, 0x03, 0xF1, 0x8C, 0xC6, 0x63, 0x31, 0x9F, 0x80, /* 0xFA */
|
||||
0xC0, 0xF0, 0x3C, 0x0F, 0x03, 0xFE, 0xF0, 0xFC, 0x3F, 0x0F, 0xC3, 0xFF, 0xB0, /* 0xFB */
|
||||
0xC0, 0xC0, 0xC0, 0xC0, 0xFE, 0xC3, 0xC3, 0xC3, 0xC3, 0xFE, /* 0xFC */
|
||||
0x3C, 0x62, 0xC3, 0x01, 0x1F, 0x01, 0x01, 0xC3, 0x62, 0x3C, /* 0xFD */
|
||||
0xC7, 0xCC, 0xC6, 0xD8, 0x3D, 0x83, 0xF8, 0x3D, 0x83, 0xD8, 0x3C, 0xC2, 0xCC, 0x6C, 0x7C, /* 0xFE */
|
||||
0x7F, 0xC3, 0xC3, 0xC3, 0x7F, 0x13, 0x33, 0x63, 0xC3, 0x83, /* 0xFF */
|
||||
};
|
||||
|
||||
const GFXglyph FreeSans9pt_Win1251Glyphs[] PROGMEM = {
|
||||
/* ' ' 0x20 */ {0, 0, 0, 5, 0, 0},
|
||||
/* '!' 0x21 */ {0, 2, 13, 6, 2, -12},
|
||||
/* '"' 0x22 */ {4, 5, 4, 6, 1, -12},
|
||||
/* '#' 0x23 */ {7, 10, 12, 10, 0, -11},
|
||||
/* '$' 0x24 */ {22, 9, 16, 10, 1, -13},
|
||||
/* '%' 0x25 */ {40, 16, 13, 16, 1, -12},
|
||||
/* '&' 0x26 */ {66, 10, 13, 12, 1, -12},
|
||||
/* ''' 0x27 */ {83, 2, 4, 4, 1, -12},
|
||||
/* '(' 0x28 */ {84, 4, 17, 6, 1, -12},
|
||||
/* ')' 0x29 */ {93, 4, 17, 6, 1, -12},
|
||||
/* '*' 0x2A */ {102, 5, 5, 7, 1, -12},
|
||||
/* '+' 0x2B */ {106, 6, 8, 11, 3, -7},
|
||||
/* ',' 0x2C */ {112, 2, 4, 5, 2, 0},
|
||||
/* '-' 0x2D */ {113, 4, 1, 6, 1, -4},
|
||||
/* '.' 0x2E */ {114, 2, 1, 5, 1, 0},
|
||||
/* '/' 0x2F */ {115, 5, 13, 5, 0, -12},
|
||||
/* '0' 0x30 */ {124, 8, 13, 10, 1, -12},
|
||||
/* '1' 0x31 */ {137, 4, 13, 10, 3, -12},
|
||||
/* '2' 0x32 */ {144, 9, 13, 10, 1, -12},
|
||||
/* '3' 0x33 */ {159, 8, 13, 10, 1, -12},
|
||||
/* '4' 0x34 */ {172, 7, 13, 10, 2, -12},
|
||||
/* '5' 0x35 */ {184, 9, 13, 10, 1, -12},
|
||||
/* '6' 0x36 */ {199, 9, 13, 10, 1, -12},
|
||||
/* '7' 0x37 */ {214, 8, 13, 10, 0, -12},
|
||||
/* '8' 0x38 */ {227, 9, 13, 10, 1, -12},
|
||||
/* '9' 0x39 */ {242, 8, 13, 10, 1, -12},
|
||||
/* ':' 0x3A */ {255, 2, 10, 5, 1, -9},
|
||||
/* ';' 0x3B */ {258, 3, 12, 5, 1, -8},
|
||||
/* '<' 0x3C */ {263, 9, 9, 11, 1, -8},
|
||||
/* '=' 0x3D */ {274, 9, 4, 11, 1, -5},
|
||||
/* '>' 0x3E */ {279, 9, 8, 11, 1, -7},
|
||||
/* '?' 0x3F */ {288, 9, 13, 10, 1, -12},
|
||||
/* '@' 0x40 */ {303, 17, 16, 18, 1, -12},
|
||||
/* 'A' 0x41 */ {337, 12, 13, 12, 0, -12},
|
||||
/* 'B' 0x42 */ {357, 11, 13, 12, 1, -12},
|
||||
/* 'C' 0x43 */ {375, 11, 13, 13, 1, -12},
|
||||
/* 'D' 0x44 */ {393, 11, 13, 13, 1, -12},
|
||||
/* 'E' 0x45 */ {411, 9, 13, 11, 1, -12},
|
||||
/* 'F' 0x46 */ {426, 8, 13, 11, 1, -12},
|
||||
/* 'G' 0x47 */ {439, 12, 13, 14, 1, -12},
|
||||
/* 'H' 0x48 */ {459, 11, 13, 13, 1, -12},
|
||||
/* 'I' 0x49 */ {477, 2, 13, 5, 2, -12},
|
||||
/* 'J' 0x4A */ {481, 7, 13, 10, 1, -12},
|
||||
/* 'K' 0x4B */ {493, 10, 13, 12, 1, -12},
|
||||
/* 'L' 0x4C */ {510, 8, 13, 10, 1, -12},
|
||||
/* 'M' 0x4D */ {523, 13, 13, 15, 1, -12},
|
||||
/* 'N' 0x4E */ {545, 11, 13, 13, 1, -12},
|
||||
/* 'O' 0x4F */ {563, 13, 13, 14, 1, -12},
|
||||
/* 'P' 0x50 */ {585, 10, 13, 12, 1, -12},
|
||||
/* 'Q' 0x51 */ {602, 13, 14, 14, 1, -12},
|
||||
/* 'R' 0x52 */ {625, 12, 13, 13, 1, -12},
|
||||
/* 'S' 0x53 */ {645, 10, 13, 12, 1, -12},
|
||||
/* 'T' 0x54 */ {662, 9, 13, 11, 1, -12},
|
||||
/* 'U' 0x55 */ {677, 11, 13, 13, 1, -12},
|
||||
/* 'V' 0x56 */ {695, 11, 13, 11, 0, -12},
|
||||
/* 'W' 0x57 */ {713, 16, 13, 17, 0, -12},
|
||||
/* 'X' 0x58 */ {739, 10, 13, 12, 1, -12},
|
||||
/* 'Y' 0x59 */ {756, 12, 13, 12, 0, -12},
|
||||
/* 'Z' 0x5A */ {776, 10, 13, 11, 1, -12},
|
||||
/* '[' 0x5B */ {793, 3, 17, 5, 1, -12},
|
||||
/* '\' 0x5C */ {800, 5, 13, 5, 0, -12},
|
||||
/* ']' 0x5D */ {809, 3, 17, 5, 0, -12},
|
||||
/* '^' 0x5E */ {816, 7, 7, 8, 1, -12},
|
||||
/* '_' 0x5F */ {823, 10, 1, 10, 0, 3},
|
||||
/* '`' 0x60 */ {825, 4, 3, 5, 0, -12},
|
||||
/* 'a' 0x61 */ {827, 9, 10, 10, 1, -9},
|
||||
/* 'b' 0x62 */ {839, 9, 13, 10, 1, -12},
|
||||
/* 'c' 0x63 */ {854, 8, 10, 9, 1, -9},
|
||||
/* 'd' 0x64 */ {864, 8, 13, 10, 1, -12},
|
||||
/* 'e' 0x65 */ {877, 8, 10, 10, 1, -9},
|
||||
/* 'f' 0x66 */ {887, 4, 13, 5, 1, -12},
|
||||
/* 'g' 0x67 */ {894, 8, 14, 10, 1, -9},
|
||||
/* 'h' 0x68 */ {908, 8, 13, 10, 1, -12},
|
||||
/* 'i' 0x69 */ {921, 2, 13, 4, 1, -12},
|
||||
/* 'j' 0x6A */ {925, 4, 17, 4, 0, -12},
|
||||
/* 'k' 0x6B */ {934, 8, 13, 9, 1, -12},
|
||||
/* 'l' 0x6C */ {947, 2, 13, 4, 1, -12},
|
||||
/* 'm' 0x6D */ {951, 13, 10, 15, 1, -9},
|
||||
/* 'n' 0x6E */ {968, 8, 10, 10, 1, -9},
|
||||
/* 'o' 0x6F */ {978, 8, 10, 10, 1, -9},
|
||||
/* 'p' 0x70 */ {988, 9, 13, 10, 1, -9},
|
||||
/* 'q' 0x71 */ {1003, 8, 13, 10, 1, -9},
|
||||
/* 'r' 0x72 */ {1016, 5, 10, 6, 1, -9},
|
||||
/* 's' 0x73 */ {1023, 8, 10, 9, 1, -9},
|
||||
/* 't' 0x74 */ {1033, 4, 12, 5, 1, -11},
|
||||
/* 'u' 0x75 */ {1039, 8, 10, 10, 1, -9},
|
||||
/* 'v' 0x76 */ {1049, 9, 10, 9, 0, -9},
|
||||
/* 'w' 0x77 */ {1061, 13, 10, 13, 0, -9},
|
||||
/* 'x' 0x78 */ {1078, 7, 10, 9, 1, -9},
|
||||
/* 'y' 0x79 */ {1087, 8, 14, 9, 0, -9},
|
||||
/* 'z' 0x7A */ {1101, 7, 10, 9, 1, -9},
|
||||
/* '{' 0x7B */ {1110, 4, 17, 6, 1, -12},
|
||||
/* '|' 0x7C */ {1119, 2, 17, 4, 2, -12},
|
||||
/* '}' 0x7D */ {1124, 4, 17, 6, 1, -12},
|
||||
/* '~' 0x7E */ {1133, 7, 3, 9, 1, -7},
|
||||
/* 0x7F */ {1136, 13, 14, 15, 1, -12},
|
||||
/* 0x80 */ {1159, 12, 16, 14, 1, -12},
|
||||
/* 0x81 */ {1183, 8, 15, 11, 1, -14},
|
||||
/* 0x82 */ {1198, 2, 3, 5, 1, 0},
|
||||
/* 0x83 */ {1199, 5, 13, 7, 1, -12},
|
||||
/* 0x84 */ {1208, 5, 3, 7, 1, 0},
|
||||
/* 0x85 */ {1210, 10, 1, 12, 1, 0},
|
||||
/* 0x86 */ {1212, 8, 16, 10, 1, -12},
|
||||
/* 0x87 */ {1228, 8, 16, 10, 1, -12},
|
||||
/* 0x88 */ {1244, 10, 13, 12, 1, -12},
|
||||
/* 0x89 */ {1261, 18, 13, 18, 0, -12},
|
||||
/* 0x8A */ {1291, 17, 13, 18, 1, -12},
|
||||
/* 0x8B */ {1319, 2, 4, 4, 1, -6},
|
||||
/* 0x8C */ {1320, 17, 13, 18, 1, -12},
|
||||
/* 0x8D */ {1348, 10, 15, 11, 1, -14},
|
||||
/* 0x8E */ {1367, 12, 13, 14, 1, -12},
|
||||
/* 0x8F */ {1387, 11, 15, 13, 1, -12},
|
||||
/* 0x90 */ {1408, 9, 16, 10, 1, -12},
|
||||
/* 0x91 */ {1426, 2, 4, 4, 2, -12},
|
||||
/* 0x92 */ {1427, 2, 4, 4, 1, -12},
|
||||
/* 0x93 */ {1428, 5, 4, 7, 2, -12},
|
||||
/* 0x94 */ {1431, 5, 4, 7, 1, -12},
|
||||
/* 0x95 */ {1434, 4, 5, 7, 1, -8},
|
||||
/* 0x96 */ {1437, 7, 1, 9, 1, -4},
|
||||
/* 0x97 */ {1438, 16, 1, 18, 1, -4},
|
||||
/* 0x98 */ {1440, 0, 0, 0, 0, 0},
|
||||
/* 0x99 */ {1440, 18, 10, 18, 1, -13},
|
||||
/* 0x9A */ {1463, 13, 10, 14, 1, -9},
|
||||
/* 0x9B */ {1480, 2, 4, 5, 2, -6},
|
||||
/* 0x9C */ {1481, 14, 10, 15, 1, -9},
|
||||
/* 0x9D */ {1499, 7, 13, 9, 1, -12},
|
||||
/* 0x9E */ {1511, 9, 13, 10, 1, -12},
|
||||
/* 0x9F */ {1526, 8, 12, 10, 1, -9},
|
||||
/* 0xA0 */ {1538, 0, 0, 5, 0, 0},
|
||||
/* 0xA1 */ {1538, 10, 15, 11, 1, -14},
|
||||
/* 0xA2 */ {1557, 8, 16, 9, 0, -11},
|
||||
/* 0xA3 */ {1573, 7, 13, 10, 1, -12},
|
||||
/* 0xA4 */ {1585, 7, 6, 10, 2, -8},
|
||||
/* 0xA5 */ {1591, 10, 14, 11, 1, -13},
|
||||
/* 0xA6 */ {1609, 2, 17, 5, 2, -12},
|
||||
/* 0xA7 */ {1614, 9, 17, 10, 1, -12},
|
||||
/* 0xA8 */ {1634, 9, 15, 12, 1, -14},
|
||||
/* 0xA9 */ {1651, 14, 13, 14, 1, -12},
|
||||
/* 0xAA */ {1674, 11, 13, 13, 1, -12},
|
||||
/* 0xAB */ {1692, 7, 6, 9, 1, -7},
|
||||
/* 0xAC */ {1698, 9, 5, 11, 2, -5},
|
||||
/* 0xAD */ {1704, 0, 0, 0, 0, 0},
|
||||
/* 0xAE */ {1704, 14, 13, 14, 1, -12},
|
||||
/* 0xAF */ {1727, 6, 15, 5, 0, -14},
|
||||
/* 0xB0 */ {1739, 5, 5, 11, 3, -11},
|
||||
/* 0xB1 */ {1743, 9, 11, 11, 1, -10},
|
||||
/* 0xB2 */ {1756, 2, 13, 4, 1, -12},
|
||||
/* 0xB3 */ {1760, 2, 13, 4, 1, -12},
|
||||
/* 0xB4 */ {1764, 6, 12, 7, 1, -11},
|
||||
/* 0xB5 */ {1773, 9, 13, 10, 1, -9},
|
||||
/* 0xB6 */ {1788, 8, 16, 10, 2, -12},
|
||||
/* 0xB7 */ {1804, 3, 1, 5, 1, -4},
|
||||
/* 0xB8 */ {1805, 8, 12, 10, 1, -11},
|
||||
/* 0xB9 */ {1817, 15, 13, 17, 1, -12},
|
||||
/* 0xBA */ {1842, 8, 10, 9, 1, -9},
|
||||
/* 0xBB */ {1852, 7, 6, 9, 1, -7},
|
||||
/* 0xBC */ {1858, 4, 17, 4, 0, -12},
|
||||
/* 0xBD */ {1867, 10, 13, 12, 1, -12},
|
||||
/* 0xBE */ {1884, 8, 10, 9, 1, -9},
|
||||
/* 0xBF */ {1894, 6, 12, 5, -1, -11},
|
||||
/* 0xC0 */ {1903, 12, 13, 12, 0, -12},
|
||||
/* 0xC1 */ {1923, 11, 13, 12, 1, -12},
|
||||
/* 0xC2 */ {1941, 11, 13, 12, 1, -12},
|
||||
/* 0xC3 */ {1959, 8, 13, 8, 1, -12},
|
||||
/* 0xC4 */ {1972, 14, 16, 15, 1, -12},
|
||||
/* 0xC5 */ {2000, 9, 13, 12, 1, -12},
|
||||
/* 0xC6 */ {2015, 16, 13, 16, 0, -12},
|
||||
/* 0xC7 */ {2041, 10, 13, 12, 1, -12},
|
||||
/* 0xC8 */ {2058, 11, 13, 13, 1, -12},
|
||||
/* 0xC9 */ {2076, 11, 16, 13, 1, -15},
|
||||
/* 0xCA */ {2098, 10, 13, 11, 1, -12},
|
||||
/* 0xCB */ {2115, 10, 13, 12, 1, -12},
|
||||
/* 0xCC */ {2132, 13, 13, 15, 1, -12},
|
||||
/* 0xCD */ {2154, 11, 13, 13, 1, -12},
|
||||
/* 0xCE */ {2172, 13, 13, 14, 1, -12},
|
||||
/* 0xCF */ {2194, 11, 13, 13, 1, -12},
|
||||
/* 0xD0 */ {2212, 10, 13, 12, 1, -12},
|
||||
/* 0xD1 */ {2229, 11, 13, 13, 1, -12},
|
||||
/* 0xD2 */ {2247, 9, 13, 11, 1, -12},
|
||||
/* 0xD3 */ {2262, 10, 13, 11, 1, -12},
|
||||
/* 0xD4 */ {2279, 14, 13, 15, 1, -12},
|
||||
/* 0xD5 */ {2302, 10, 13, 12, 1, -12},
|
||||
/* 0xD6 */ {2319, 13, 15, 13, 1, -12},
|
||||
/* 0xD7 */ {2344, 9, 13, 11, 1, -12},
|
||||
/* 0xD8 */ {2359, 13, 13, 15, 1, -12},
|
||||
/* 0xD9 */ {2381, 15, 15, 15, 1, -12},
|
||||
/* 0xDA */ {2410, 13, 13, 15, 2, -12},
|
||||
/* 0xDB */ {2432, 14, 13, 16, 1, -12},
|
||||
/* 0xDC */ {2455, 11, 13, 12, 1, -12},
|
||||
/* 0xDD */ {2473, 11, 13, 13, 1, -12},
|
||||
/* 0xDE */ {2491, 17, 13, 18, 1, -12},
|
||||
/* 0xDF */ {2519, 10, 13, 12, 1, -12},
|
||||
/* 0xE0 */ {2536, 9, 10, 10, 1, -9},
|
||||
/* 0xE1 */ {2548, 8, 14, 10, 1, -13},
|
||||
/* 0xE2 */ {2562, 7, 10, 9, 1, -9},
|
||||
/* 0xE3 */ {2571, 5, 10, 7, 1, -9},
|
||||
/* 0xE4 */ {2578, 11, 12, 10, 0, -9},
|
||||
/* 0xE5 */ {2595, 8, 10, 10, 1, -9},
|
||||
/* 0xE6 */ {2605, 12, 10, 14, 1, -9},
|
||||
/* 0xE7 */ {2620, 7, 10, 9, 1, -9},
|
||||
/* 0xE8 */ {2629, 8, 10, 10, 1, -9},
|
||||
/* 0xE9 */ {2639, 8, 12, 10, 1, -11},
|
||||
/* 0xEA */ {2651, 7, 10, 9, 1, -9},
|
||||
/* 0xEB */ {2660, 7, 10, 8, 0, -9},
|
||||
/* 0xEC */ {2669, 9, 10, 11, 1, -9},
|
||||
/* 0xED */ {2681, 8, 10, 10, 1, -9},
|
||||
/* 0xEE */ {2691, 8, 10, 10, 1, -9},
|
||||
/* 0xEF */ {2701, 8, 10, 10, 1, -9},
|
||||
/* 0xF0 */ {2711, 9, 13, 10, 1, -9},
|
||||
/* 0xF1 */ {2726, 8, 10, 9, 1, -9},
|
||||
/* 0xF2 */ {2736, 6, 10, 7, 1, -9},
|
||||
/* 0xF3 */ {2744, 8, 14, 9, 0, -9},
|
||||
/* 0xF4 */ {2758, 14, 15, 15, 1, -11},
|
||||
/* 0xF5 */ {2785, 7, 10, 9, 1, -9},
|
||||
/* 0xF6 */ {2794, 10, 12, 10, 1, -9},
|
||||
/* 0xF7 */ {2809, 7, 10, 9, 1, -9},
|
||||
/* 0xF8 */ {2818, 10, 10, 12, 1, -9},
|
||||
/* 0xF9 */ {2831, 12, 12, 13, 1, -9},
|
||||
/* 0xFA */ {2849, 9, 10, 12, 2, -9},
|
||||
/* 0xFB */ {2861, 10, 10, 12, 1, -9},
|
||||
/* 0xFC */ {2874, 8, 10, 9, 1, -9},
|
||||
/* 0xFD */ {2884, 8, 10, 9, 1, -9},
|
||||
/* 0xFE */ {2894, 12, 10, 13, 1, -9},
|
||||
/* 0xFF */ {2909, 8, 10, 10, 1, -9},
|
||||
};
|
||||
|
||||
const GFXfont FreeSans9pt_Win1251 PROGMEM = {(uint8_t *)FreeSans9pt_Win1251Bitmaps, (GFXglyph *)FreeSans9pt_Win1251Glyphs, 0x20,
|
||||
0xFF, 21};
|
||||
@@ -0,0 +1,494 @@
|
||||
#pragma once
|
||||
const uint8_t FreeSans9pt_Win1252Bitmaps[] PROGMEM = {
|
||||
/* ' ' 0x20 */
|
||||
0xFF, 0xFF, 0xF0, 0xC0, /* '!' 0x21 */
|
||||
0xDE, 0xF7, 0x20, /* '"' 0x22 */
|
||||
0x09, 0x86, 0x41, 0x91, 0xFF, 0x13, 0x04, 0xC3, 0x20, 0xC8, 0xFF, 0x89, 0x82, 0x61, 0x90, /* '#' 0x23 */
|
||||
0x10, 0x1F, 0x14, 0xDA, 0x3D, 0x1E, 0x83, 0x40, 0x78, 0x17, 0x08, 0xF4, 0x7A, 0x35, 0x33, 0xF0, 0x40, 0x20, /* '$' 0x24 */
|
||||
0x38, 0x10, 0xEC, 0x20, 0xC6, 0x20, 0xC6, 0x40, 0xC6, 0x40, 0x6C, 0x80, 0x39, 0x00, 0x01, 0x3C, 0x02, 0x77, 0x02, 0x63, 0x04,
|
||||
0x63, 0x04, 0x77, 0x08, 0x3C, /* '%' 0x25 */
|
||||
0x0E, 0x0C, 0xC3, 0x30, 0xCC, 0x1E, 0x03, 0x03, 0xC1, 0x9B, 0xC2, 0xF0, 0xEC, 0x19, 0x8F, 0x3C, 0x40, /* '&' 0x26 */
|
||||
0xFE, /* ''' 0x27 */
|
||||
0x13, 0x26, 0x6C, 0xCC, 0xCC, 0xC4, 0x66, 0x23, 0x10, /* '(' 0x28 */
|
||||
0x8C, 0x46, 0x63, 0x33, 0x33, 0x32, 0x66, 0x4C, 0x80, /* ')' 0x29 */
|
||||
0x25, 0x7E, 0xA5, 0x00, /* '*' 0x2A */
|
||||
0x30, 0xC3, 0x3F, 0x30, 0xC3, 0x0C, /* '+' 0x2B */
|
||||
0xD6, /* ',' 0x2C */
|
||||
0xF0, /* '-' 0x2D */
|
||||
0xC0, /* '.' 0x2E */
|
||||
0x08, 0x44, 0x21, 0x10, 0x84, 0x42, 0x11, 0x08, 0x00, /* '/' 0x2F */
|
||||
0x3C, 0x66, 0x42, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0x42, 0x66, 0x3C, /* '0' 0x30 */
|
||||
0x11, 0x3F, 0x33, 0x33, 0x33, 0x33, 0x30, /* '1' 0x31 */
|
||||
0x3E, 0x31, 0xB0, 0x78, 0x30, 0x18, 0x1C, 0x1C, 0x1C, 0x18, 0x18, 0x10, 0x08, 0x07, 0xF8, /* '2' 0x32 */
|
||||
0x3C, 0x66, 0xC3, 0xC3, 0x03, 0x06, 0x1C, 0x07, 0x03, 0xC3, 0xC3, 0x66, 0x3C, /* '3' 0x33 */
|
||||
0x0C, 0x18, 0x71, 0x62, 0xC9, 0xA3, 0x46, 0xFE, 0x18, 0x30, 0x60, 0xC0, /* '4' 0x34 */
|
||||
0x7F, 0x20, 0x10, 0x08, 0x08, 0x07, 0xF3, 0x8C, 0x03, 0x01, 0x80, 0xF0, 0x6C, 0x63, 0xE0, /* '5' 0x35 */
|
||||
0x1E, 0x31, 0x98, 0x78, 0x0C, 0x06, 0xF3, 0x8D, 0x83, 0xC1, 0xE0, 0xD0, 0x6C, 0x63, 0xE0, /* '6' 0x36 */
|
||||
0xFF, 0x03, 0x02, 0x06, 0x04, 0x0C, 0x08, 0x18, 0x18, 0x18, 0x10, 0x30, 0x30, /* '7' 0x37 */
|
||||
0x3E, 0x31, 0xB0, 0x78, 0x3C, 0x1B, 0x18, 0xF8, 0xC6, 0xC1, 0xE0, 0xF0, 0x6C, 0x63, 0xE0, /* '8' 0x38 */
|
||||
0x3C, 0x66, 0xC2, 0xC3, 0xC3, 0xC3, 0x67, 0x3B, 0x03, 0x03, 0xC2, 0x66, 0x3C, /* '9' 0x39 */
|
||||
0xC0, 0x00, 0x30, /* ':' 0x3A */
|
||||
0xC0, 0x00, 0x00, 0x64, 0xA0, /* ';' 0x3B */
|
||||
0x00, 0x81, 0xC7, 0x8E, 0x0C, 0x07, 0x80, 0x70, 0x0E, 0x01, 0x80, /* '<' 0x3C */
|
||||
0xFF, 0x80, 0x00, 0x1F, 0xF0, /* '=' 0x3D */
|
||||
0xE0, 0x1C, 0x03, 0x80, 0x30, 0x70, 0xE3, 0x81, 0x00, /* '>' 0x3E */
|
||||
0x3E, 0x31, 0xB0, 0x78, 0x30, 0x18, 0x18, 0x38, 0x18, 0x18, 0x0C, 0x00, 0x00, 0x01, 0x80, /* '?' 0x3F */
|
||||
0x03, 0xF0, 0x06, 0x0E, 0x06, 0x01, 0x86, 0x00, 0x66, 0x1D, 0xBB, 0x31, 0xCF, 0x18, 0xC7, 0x98, 0x63, 0xCC, 0x31, 0xE6, 0x11,
|
||||
0xB3, 0x99, 0xCC, 0xF7, 0x86, 0x00, 0x01, 0x80, 0x00, 0x70, 0x40, 0x0F, 0xE0, /* '@' 0x40 */
|
||||
0x06, 0x00, 0xF0, 0x0F, 0x00, 0x90, 0x19, 0x81, 0x98, 0x10, 0x83, 0x0C, 0x3F, 0xC2, 0x04, 0x60, 0x66, 0x06, 0xC0,
|
||||
0x30, /* 'A' 0x41 */
|
||||
0xFF, 0x18, 0x33, 0x03, 0x60, 0x6C, 0x0D, 0x83, 0x3F, 0xC6, 0x06, 0xC0, 0x78, 0x0F, 0x01, 0xE0, 0x6F, 0xF8, /* 'B' 0x42 */
|
||||
0x1F, 0x86, 0x19, 0x81, 0xA0, 0x3C, 0x01, 0x80, 0x30, 0x06, 0x00, 0xC0, 0x68, 0x0D, 0x83, 0x18, 0x61, 0xF0, /* 'C' 0x43 */
|
||||
0xFF, 0x18, 0x33, 0x03, 0x60, 0x3C, 0x07, 0x80, 0xF0, 0x1E, 0x03, 0xC0, 0x78, 0x0F, 0x03, 0x60, 0xCF, 0xF0, /* 'D' 0x44 */
|
||||
0xFF, 0xE0, 0x30, 0x18, 0x0C, 0x06, 0x03, 0xFD, 0x80, 0xC0, 0x60, 0x30, 0x18, 0x0F, 0xF8, /* 'E' 0x45 */
|
||||
0xFF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xFE, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, /* 'F' 0x46 */
|
||||
0x0F, 0x83, 0x0E, 0x60, 0x66, 0x03, 0xC0, 0x0C, 0x00, 0xC1, 0xFC, 0x03, 0xC0, 0x36, 0x03, 0x60, 0x73, 0x0F, 0x0F,
|
||||
0x10, /* 'G' 0x47 */
|
||||
0xC0, 0x78, 0x0F, 0x01, 0xE0, 0x3C, 0x07, 0x80, 0xFF, 0xFE, 0x03, 0xC0, 0x78, 0x0F, 0x01, 0xE0, 0x3C, 0x06, /* 'H' 0x48 */
|
||||
0xFF, 0xFF, 0xFF, 0xC0, /* 'I' 0x49 */
|
||||
0x06, 0x0C, 0x18, 0x30, 0x60, 0xC1, 0x83, 0x07, 0x8F, 0x1E, 0x27, 0x80, /* 'J' 0x4A */
|
||||
0xC0, 0xF0, 0x6C, 0x33, 0x18, 0xCC, 0x37, 0x0F, 0xC3, 0x98, 0xC3, 0x30, 0xCC, 0x1B, 0x03, 0xC0, 0xC0, /* 'K' 0x4B */
|
||||
0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xFF, /* 'L' 0x4C */
|
||||
0xE0, 0x3F, 0x01, 0xFC, 0x1F, 0xE0, 0xFD, 0x05, 0xEC, 0x6F, 0x63, 0x79, 0x13, 0xCD, 0x9E, 0x6C, 0xF1, 0x47, 0x8E, 0x3C, 0x71,
|
||||
0x80, /* 'M' 0x4D */
|
||||
0xE0, 0x7C, 0x0F, 0xC1, 0xE8, 0x3D, 0x87, 0x98, 0xF1, 0x1E, 0x33, 0xC3, 0x78, 0x6F, 0x07, 0xE0, 0x7C, 0x0E, /* 'N' 0x4E */
|
||||
0x0F, 0x81, 0x83, 0x18, 0x0C, 0xC0, 0x6C, 0x01, 0xE0, 0x0F, 0x00, 0x78, 0x03, 0xC0, 0x1B, 0x01, 0x98, 0x0C, 0x60, 0xC0, 0xF8,
|
||||
0x00, /* 'O' 0x4F */
|
||||
0xFF, 0x30, 0x6C, 0x0F, 0x03, 0xC0, 0xF0, 0x6F, 0xF3, 0x00, 0xC0, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x00, /* 'P' 0x50 */
|
||||
0x0F, 0x81, 0x83, 0x18, 0x0C, 0xC0, 0x6C, 0x01, 0xE0, 0x0F, 0x00, 0x78, 0x03, 0xC0, 0x1B, 0x01, 0x98, 0x6C, 0x60, 0xC0, 0xFB,
|
||||
0x00, 0x08, /* 'Q' 0x51 */
|
||||
0xFF, 0x8C, 0x0E, 0xC0, 0x6C, 0x06, 0xC0, 0x6C, 0x0C, 0xFF, 0x8C, 0x0E, 0xC0, 0x6C, 0x06, 0xC0, 0x6C, 0x06, 0xC0,
|
||||
0x70, /* 'R' 0x52 */
|
||||
0x3F, 0x18, 0x6C, 0x0F, 0x03, 0xC0, 0x1E, 0x01, 0xF0, 0x0E, 0x00, 0xF0, 0x3C, 0x0D, 0x86, 0x3F, 0x00, /* 'S' 0x53 */
|
||||
0xFF, 0x86, 0x03, 0x01, 0x80, 0xC0, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, 0x01, 0x80, 0xC0, /* 'T' 0x54 */
|
||||
0xC0, 0x78, 0x0F, 0x01, 0xE0, 0x3C, 0x07, 0x80, 0xF0, 0x1E, 0x03, 0xC0, 0x78, 0x0F, 0x01, 0xB0, 0x61, 0xF0, /* 'U' 0x55 */
|
||||
0xC0, 0x6C, 0x0D, 0x81, 0x10, 0x63, 0x0C, 0x61, 0x04, 0x60, 0xCC, 0x19, 0x01, 0x60, 0x3C, 0x07, 0x00, 0x60, /* 'V' 0x56 */
|
||||
0xC1, 0x81, 0x61, 0xC3, 0x61, 0xC3, 0x61, 0x43, 0x62, 0x62, 0x22, 0x66, 0x32, 0x26, 0x36, 0x26, 0x14, 0x34, 0x14, 0x34, 0x1C,
|
||||
0x1C, 0x18, 0x1C, 0x08, 0x18, /* 'W' 0x57 */
|
||||
0xC0, 0xD8, 0x66, 0x18, 0xCC, 0x1E, 0x07, 0x00, 0xC0, 0x78, 0x32, 0x0C, 0xC6, 0x1B, 0x07, 0xC0, 0xC0, /* 'X' 0x58 */
|
||||
0xC0, 0x36, 0x06, 0x30, 0xC3, 0x0C, 0x19, 0x81, 0xD8, 0x0F, 0x00, 0x60, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60, 0x06,
|
||||
0x00, /* 'Y' 0x59 */
|
||||
0xFF, 0xC0, 0x60, 0x30, 0x0C, 0x06, 0x03, 0x01, 0xC0, 0x60, 0x30, 0x18, 0x06, 0x03, 0x00, 0xFF, 0xC0, /* 'Z' 0x5A */
|
||||
0xFB, 0x6D, 0xB6, 0xDB, 0x6D, 0xB6, 0xE0, /* '[' 0x5B */
|
||||
0x84, 0x10, 0x84, 0x10, 0x84, 0x10, 0x84, 0x10, 0x80, /* '\' 0x5C */
|
||||
0xED, 0xB6, 0xDB, 0x6D, 0xB6, 0xDB, 0xE0, /* ']' 0x5D */
|
||||
0x30, 0x60, 0xA2, 0x44, 0xD8, 0xA1, 0x80, /* '^' 0x5E */
|
||||
0xFF, 0xC0, /* '_' 0x5F */
|
||||
0xC6, 0x30, /* '`' 0x60 */
|
||||
0x7E, 0x71, 0xB0, 0xC0, 0x60, 0xF3, 0xDB, 0x0D, 0x86, 0xC7, 0x3D, 0xC0, /* 'a' 0x61 */
|
||||
0xC0, 0x60, 0x30, 0x1B, 0xCE, 0x36, 0x0F, 0x07, 0x83, 0xC1, 0xE0, 0xF0, 0x7C, 0x6D, 0xE0, /* 'b' 0x62 */
|
||||
0x3C, 0x66, 0xC3, 0xC0, 0xC0, 0xC0, 0xC0, 0xC3, 0x66, 0x3C, /* 'c' 0x63 */
|
||||
0x03, 0x03, 0x03, 0x3B, 0x67, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0x67, 0x3B, /* 'd' 0x64 */
|
||||
0x3C, 0x66, 0xC3, 0xC3, 0xFF, 0xC0, 0xC0, 0xC3, 0x66, 0x3C, /* 'e' 0x65 */
|
||||
0x36, 0x6F, 0x66, 0x66, 0x66, 0x66, 0x60, /* 'f' 0x66 */
|
||||
0x3B, 0x67, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0x67, 0x3B, 0x03, 0x03, 0xC6, 0x7C, /* 'g' 0x67 */
|
||||
0xC0, 0xC0, 0xC0, 0xDE, 0xE3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, /* 'h' 0x68 */
|
||||
0xC3, 0xFF, 0xFF, 0xC0, /* 'i' 0x69 */
|
||||
0x30, 0x03, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0xE0, /* 'j' 0x6A */
|
||||
0xC0, 0xC0, 0xC0, 0xC2, 0xC4, 0xCC, 0xD8, 0xF8, 0xEC, 0xC4, 0xC6, 0xC3, 0xC3, /* 'k' 0x6B */
|
||||
0xFF, 0xFF, 0xFF, 0xC0, /* 'l' 0x6C */
|
||||
0xDE, 0xF7, 0x1C, 0xF0, 0xC7, 0x86, 0x3C, 0x31, 0xE1, 0x8F, 0x0C, 0x78, 0x63, 0xC3, 0x1E, 0x18, 0xC0, /* 'm' 0x6D */
|
||||
0xDE, 0xE3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, /* 'n' 0x6E */
|
||||
0x3C, 0x66, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0x66, 0x3C, /* 'o' 0x6F */
|
||||
0xDE, 0x71, 0xB0, 0x78, 0x3C, 0x1E, 0x0F, 0x07, 0x83, 0xE3, 0x6F, 0x30, 0x18, 0x0C, 0x00, /* 'p' 0x70 */
|
||||
0x3B, 0x67, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0x67, 0x3B, 0x03, 0x03, 0x03, /* 'q' 0x71 */
|
||||
0xDF, 0x31, 0x8C, 0x63, 0x18, 0xC6, 0x00, /* 'r' 0x72 */
|
||||
0x3E, 0xE3, 0xC0, 0xC0, 0xE0, 0x3C, 0x07, 0xC3, 0xE3, 0x7E, /* 's' 0x73 */
|
||||
0x66, 0xF6, 0x66, 0x66, 0x66, 0x67, /* 't' 0x74 */
|
||||
0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC7, 0x7B, /* 'u' 0x75 */
|
||||
0xC1, 0xA0, 0x98, 0xCC, 0x42, 0x21, 0xB0, 0xD0, 0x28, 0x1C, 0x0C, 0x00, /* 'v' 0x76 */
|
||||
0xC6, 0x1E, 0x38, 0x91, 0xC4, 0xCA, 0x66, 0xD3, 0x16, 0xD0, 0xA6, 0x87, 0x1C, 0x38, 0xC0, 0xC6, 0x00, /* 'w' 0x77 */
|
||||
0x87, 0x89, 0xB1, 0xC3, 0x07, 0x1E, 0x26, 0xC5, 0x0C, /* 'x' 0x78 */
|
||||
0xC1, 0x43, 0x63, 0x62, 0x26, 0x36, 0x34, 0x1C, 0x1C, 0x18, 0x18, 0x18, 0x10, 0x60, /* 'y' 0x79 */
|
||||
0xFE, 0x0C, 0x30, 0xC1, 0x86, 0x18, 0x20, 0xC1, 0xFC, /* 'z' 0x7A */
|
||||
0x36, 0x66, 0x66, 0x6E, 0xCE, 0x66, 0x66, 0x66, 0x30, /* '{' 0x7B */
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xC0, /* '|' 0x7C */
|
||||
0xC6, 0x66, 0x66, 0x67, 0x37, 0x66, 0x66, 0x66, 0xC0, /* '}' 0x7D */
|
||||
0x61, 0x24, 0x38, /* '~' 0x7E */
|
||||
0xFF, 0xFC, 0x00, 0x63, 0xE3, 0x31, 0x99, 0x04, 0xC8, 0x66, 0x06, 0x30, 0x61, 0x83, 0x0C, 0x18, 0x60, 0x03, 0x06, 0x18, 0x00,
|
||||
0xFF, 0xFC, /* 0x7F */
|
||||
0x07, 0xC6, 0x13, 0x00, 0xC0, 0x60, 0x3F, 0xE6, 0x03, 0xFC, 0x60, 0x0C, 0x03, 0x00, 0x61, 0x07, 0xC0, /* 0x80 */
|
||||
/* 0x81 */
|
||||
0xDC, /* 0x82 */
|
||||
0x19, 0x8C, 0xF3, 0x18, 0xC6, 0x31, 0x8C, 0x63, 0x18, 0xC6, 0xE0, /* 0x83 */
|
||||
0xDA, 0x76, /* 0x84 */
|
||||
0xCC, 0xC0, /* 0x85 */
|
||||
0x18, 0x18, 0x18, 0x18, 0xFF, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, /* 0x86 */
|
||||
0x18, 0x18, 0x18, 0x18, 0xFF, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xFF, 0x18, 0x18, 0x18, 0x18, /* 0x87 */
|
||||
0x72, 0xA2, /* 0x88 */
|
||||
0x70, 0x80, 0x22, 0x20, 0x08, 0x90, 0x02, 0x24, 0x00, 0x72, 0x00, 0x00, 0x80, 0x00, 0x40, 0x00, 0x10, 0x00, 0x09, 0xC7, 0x84,
|
||||
0x8B, 0x31, 0x22, 0x84, 0x88, 0xB3, 0x21, 0xC7, 0x80, /* 0x89 */
|
||||
0x1B, 0x03, 0x80, 0x00, 0xFC, 0x61, 0xB0, 0x3C, 0x0F, 0x00, 0x78, 0x07, 0xC0, 0x38, 0x03, 0xC0, 0xF0, 0x36, 0x18,
|
||||
0xFC, /* 0x8A */
|
||||
0x69, /* 0x8B */
|
||||
0x1E, 0xFE, 0x43, 0x81, 0x83, 0x06, 0x06, 0x0C, 0x0C, 0x18, 0x18, 0x30, 0x3F, 0xE0, 0x60, 0xC0, 0xC1, 0x81, 0x81, 0x83, 0x01,
|
||||
0x8E, 0x01, 0xEF, 0xE0, /* 0x8C */
|
||||
/* 0x8D */
|
||||
0x1B, 0x03, 0x80, 0x03, 0xFF, 0x01, 0x80, 0xC0, 0x30, 0x18, 0x0C, 0x07, 0x01, 0x80, 0xC0, 0x60, 0x18, 0x0C, 0x03,
|
||||
0xFF, /* 0x8E */
|
||||
/* 0x8F */
|
||||
/* 0x90 */
|
||||
0x6B, /* 0x91 */
|
||||
0xD6, /* 0x92 */
|
||||
0x4C, 0xA5, 0xB0, /* 0x93 */
|
||||
0xDA, 0x53, 0x20, /* 0x94 */
|
||||
0x6F, 0xFF, 0x60, /* 0x95 */
|
||||
0xFE, /* 0x96 */
|
||||
0xFF, 0xFF, /* 0x97 */
|
||||
0x4D, 0xC0, /* 0x98 */
|
||||
0xFC, 0xE1, 0xCC, 0x38, 0x73, 0x0E, 0x1C, 0xC3, 0x8F, 0x30, 0xD2, 0xCC, 0x34, 0xB3, 0x0D, 0x6C, 0xC3, 0x53, 0x30, 0xCC, 0xCC,
|
||||
0x33, 0x30, /* 0x99 */
|
||||
0x24, 0x3C, 0x18, 0x7E, 0xE3, 0xC0, 0xC0, 0x60, 0x3C, 0x07, 0xC3, 0xE3, 0x7E, /* 0x9A */
|
||||
0x96, /* 0x9B */
|
||||
0x3C, 0xF8, 0xCF, 0x1B, 0x0C, 0x1E, 0x18, 0x3C, 0x3F, 0xF8, 0x60, 0x30, 0xC0, 0x61, 0x83, 0x67, 0x8C, 0x79, 0xF0, /* 0x9C */
|
||||
/* 0x9D */
|
||||
0x48, 0xF0, 0xC7, 0xF0, 0x61, 0x86, 0x0C, 0x30, 0xC1, 0x06, 0x0F, 0xE0, /* 0x9E */
|
||||
0x19, 0x80, 0x00, 0xC0, 0x36, 0x06, 0x30, 0xC3, 0x0C, 0x19, 0x81, 0xD8, 0x0F, 0x00, 0x60, 0x06, 0x00, 0x60, 0x06, 0x00,
|
||||
0x60, /* 0x9F */
|
||||
/* 0xA0 */
|
||||
0xCF, 0xFF, 0xFF, 0xC0, /* 0xA1 */
|
||||
0x08, 0x04, 0x0F, 0x8D, 0x6C, 0x9E, 0x43, 0x21, 0x90, 0xC8, 0x64, 0xDA, 0xC7, 0xC0, 0x80, 0x40, /* 0xA2 */
|
||||
0x1F, 0x0C, 0x66, 0x0D, 0x83, 0x60, 0x0C, 0x0F, 0xC0, 0x60, 0x18, 0x06, 0x03, 0x01, 0xF1, 0x43, 0xC0, /* 0xA3 */
|
||||
0xFF, 0xDF, 0x1E, 0x3E, 0xFF, 0xC0, /* 0xA4 */
|
||||
0xC3, 0x42, 0x42, 0x24, 0x24, 0x3C, 0x18, 0x7E, 0x18, 0x7E, 0x18, 0x18, 0x18, /* 0xA5 */
|
||||
0xFF, 0xFC, 0x0F, 0xFF, 0xC0, /* 0xA6 */
|
||||
0x0C, 0x09, 0x0C, 0xC6, 0x63, 0x81, 0xE3, 0x19, 0x87, 0xE1, 0xB8, 0xC6, 0x41, 0xC0, 0x73, 0x19, 0x8C, 0x66, 0x1E,
|
||||
0x00, /* 0xA7 */
|
||||
0xCC, /* 0xA8 */
|
||||
0x0F, 0xC0, 0x61, 0x87, 0x03, 0x9B, 0xC6, 0xD9, 0x8F, 0x60, 0x3D, 0x00, 0xF4, 0x03, 0xD8, 0x0D, 0xE6, 0x67, 0xF3, 0x86, 0x18,
|
||||
0x0F, 0xC0, /* 0xA9 */
|
||||
0x74, 0x8D, 0xA9, 0x7C, 0x1F, /* 0xAA */
|
||||
0x22, 0xCF, 0x26, 0x46, 0x64, 0x40, /* 0xAB */
|
||||
0xFF, 0x80, 0xC0, 0x60, 0x30, 0x18, /* 0xAC */
|
||||
/* 0xAD */
|
||||
0x0F, 0xC0, 0x61, 0x87, 0x03, 0x9F, 0xE6, 0xD0, 0x8F, 0x42, 0x3D, 0xF0, 0xF4, 0x23, 0xD0, 0x8D, 0xC2, 0x67, 0x0B, 0x86, 0x18,
|
||||
0x0F, 0xC0, /* 0xAE */
|
||||
0xF8, /* 0xAF */
|
||||
0x74, 0x63, 0x17, 0x00, /* 0xB0 */
|
||||
0x0C, 0x06, 0x03, 0x07, 0xE0, 0xC0, 0x60, 0x30, 0x18, 0x00, 0x00, 0x3F, 0xE0, /* 0xB1 */
|
||||
0x7B, 0x30, 0xC3, 0x11, 0x84, 0x3F, /* 0xB2 */
|
||||
0x7D, 0x8C, 0x18, 0xC0, 0x60, 0xF1, 0xBE, /* 0xB3 */
|
||||
0x36, 0xC0, /* 0xB4 */
|
||||
0xC3, 0x61, 0xB0, 0xD8, 0x6C, 0x36, 0x1B, 0x0D, 0x86, 0xE7, 0x7D, 0xF0, 0x18, 0x0C, 0x00, /* 0xB5 */
|
||||
0x3F, 0x7E, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0x72, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, /* 0xB6 */
|
||||
0xE0, /* 0xB7 */
|
||||
0x21, 0xC7, 0xE0, /* 0xB8 */
|
||||
0x3D, 0xB6, 0xD8, /* 0xB9 */
|
||||
0x74, 0x63, 0x18, 0xB8, 0x1F, /* 0xBA */
|
||||
0x89, 0x98, 0x99, 0x3C, 0xD1, 0x00, /* 0xBB */
|
||||
0x20, 0x43, 0x81, 0x06, 0x08, 0x18, 0x20, 0x61, 0x01, 0x84, 0x06, 0x21, 0x80, 0x86, 0x04, 0x78, 0x32, 0x60, 0x87, 0xC4, 0x06,
|
||||
0x10, 0x18, /* 0xBC */
|
||||
0x20, 0x43, 0x81, 0x06, 0x08, 0x18, 0x20, 0x61, 0x01, 0x8D, 0xE6, 0x2C, 0xC1, 0x03, 0x0C, 0x0C, 0x20, 0x41, 0x86, 0x0C, 0x30,
|
||||
0x20, 0xFC, /* 0xBD */
|
||||
0x78, 0x11, 0x98, 0x40, 0x31, 0x00, 0x82, 0x00, 0xC8, 0x01, 0x90, 0x33, 0x43, 0x3D, 0x06, 0x02, 0x3C, 0x08, 0x98, 0x10, 0xF8,
|
||||
0x40, 0x61, 0x00, 0xC0, /* 0xBE */
|
||||
0x0C, 0x00, 0x00, 0x01, 0x80, 0xC0, 0xC0, 0xE0, 0xC0, 0xC0, 0x60, 0xF0, 0x6C, 0x63, 0xE0, /* 0xBF */
|
||||
0x18, 0x03, 0x00, 0x00, 0x30, 0x1E, 0x07, 0x81, 0x20, 0xCC, 0x33, 0x0F, 0xC6, 0x19, 0x86, 0x40, 0xB0, 0x30, /* 0xC0 */
|
||||
0x06, 0x03, 0x00, 0x00, 0x30, 0x1E, 0x07, 0x81, 0x20, 0xCC, 0x33, 0x0F, 0xC6, 0x19, 0x86, 0x40, 0xB0, 0x30, /* 0xC1 */
|
||||
0x0C, 0x04, 0x80, 0x00, 0x30, 0x1E, 0x07, 0x81, 0x20, 0xCC, 0x33, 0x0F, 0xC6, 0x19, 0x86, 0x40, 0xB0, 0x30, /* 0xC2 */
|
||||
0x19, 0x09, 0x80, 0x00, 0x30, 0x1E, 0x07, 0x81, 0x20, 0xCC, 0x33, 0x0F, 0xC6, 0x19, 0x86, 0x40, 0xB0, 0x30, /* 0xC3 */
|
||||
0x33, 0x00, 0x00, 0xC0, 0x78, 0x1E, 0x04, 0x83, 0x30, 0xCC, 0x33, 0x1F, 0xE6, 0x19, 0x02, 0xC0, 0xF0, 0x30, /* 0xC4 */
|
||||
0x0C, 0x04, 0x81, 0x20, 0x30, 0x1E, 0x07, 0x81, 0x20, 0xCC, 0x33, 0x0F, 0xC6, 0x19, 0x86, 0x40, 0xB0, 0x30, /* 0xC5 */
|
||||
0x07, 0xFF, 0x04, 0xC0, 0x0C, 0xC0, 0x08, 0xC0, 0x18, 0xC0, 0x18, 0xC0, 0x30, 0xFF, 0x30, 0xC0, 0x3F, 0xC0, 0x60, 0xC0, 0x60,
|
||||
0xC0, 0xC0, 0xC0, 0xC0, 0xFF, /* 0xC6 */
|
||||
0x1F, 0x06, 0x19, 0x83, 0xA0, 0x3C, 0x01, 0x80, 0x30, 0x06, 0x00, 0xC0, 0x68, 0x0D, 0x83, 0x18, 0xE1, 0xF0, 0x08, 0x01, 0xC0,
|
||||
0x18, 0x0E, 0x00, /* 0xC7 */
|
||||
0x18, 0x06, 0x00, 0x1F, 0xFC, 0x06, 0x03, 0x01, 0x80, 0xFF, 0x60, 0x30, 0x18, 0x0C, 0x07, 0xFC, /* 0xC8 */
|
||||
0x0C, 0x0C, 0x00, 0x1F, 0xFC, 0x06, 0x03, 0x01, 0x80, 0xFF, 0x60, 0x30, 0x18, 0x0C, 0x07, 0xFC, /* 0xC9 */
|
||||
0x1C, 0x1B, 0x00, 0x1F, 0xFC, 0x06, 0x03, 0x01, 0x80, 0xFF, 0x60, 0x30, 0x18, 0x0C, 0x07, 0xFC, /* 0xCA */
|
||||
0x33, 0x00, 0x3F, 0xF8, 0x0C, 0x06, 0x03, 0x01, 0xFE, 0xC0, 0x60, 0x30, 0x18, 0x0C, 0x07, 0xFC, /* 0xCB */
|
||||
0xCC, 0x36, 0xDB, 0x6D, 0xB6, 0xD8, /* 0xCC */
|
||||
0x78, 0x36, 0xDB, 0x6D, 0xB6, 0xC0, /* 0xCD */
|
||||
0x76, 0xC0, 0x63, 0x18, 0xC6, 0x31, 0x8C, 0x63, 0x18, /* 0xCE */
|
||||
0xCC, 0x03, 0x0C, 0x30, 0xC3, 0x0C, 0x30, 0xC3, 0x0C, 0x30, 0xC0, /* 0xCF */
|
||||
0x7F, 0x0C, 0x31, 0x83, 0x30, 0x36, 0x06, 0xC0, 0xFE, 0x1B, 0x03, 0x60, 0x6C, 0x0D, 0x83, 0x30, 0xE7, 0xF0, /* 0xD0 */
|
||||
0x19, 0x02, 0xC3, 0x81, 0xF0, 0x3F, 0x07, 0xA0, 0xF6, 0x1E, 0x63, 0xC4, 0x78, 0xCF, 0x0D, 0xE1, 0xBC, 0x1F, 0x81,
|
||||
0xC0, /* 0xD1 */
|
||||
0x0C, 0x00, 0x60, 0x00, 0x00, 0xF0, 0x39, 0xC6, 0x06, 0x60, 0x6C, 0x03, 0xC0, 0x3C, 0x03, 0xC0, 0x36, 0x06, 0x60, 0x63, 0x9C,
|
||||
0x0F, 0x00, /* 0xD2 */
|
||||
0x03, 0x00, 0x60, 0x00, 0x00, 0xF0, 0x39, 0xC6, 0x06, 0x60, 0x6C, 0x03, 0xC0, 0x3C, 0x03, 0xC0, 0x36, 0x06, 0x60, 0x63, 0x9C,
|
||||
0x0F, 0x00, /* 0xD3 */
|
||||
0x0F, 0x01, 0x98, 0x00, 0x00, 0xF0, 0x39, 0xC6, 0x06, 0x60, 0x6C, 0x03, 0xC0, 0x3C, 0x03, 0xC0, 0x36, 0x06, 0x60, 0x63, 0x9C,
|
||||
0x0F, 0x00, /* 0xD4 */
|
||||
0x1C, 0x81, 0x38, 0x00, 0x00, 0xF0, 0x39, 0xC6, 0x06, 0x60, 0x6C, 0x03, 0xC0, 0x3C, 0x03, 0xC0, 0x36, 0x06, 0x60, 0x63, 0x9C,
|
||||
0x0F, 0x00, /* 0xD5 */
|
||||
0x19, 0x81, 0x98, 0x00, 0x00, 0xF0, 0x39, 0xC6, 0x06, 0x60, 0x6C, 0x03, 0xC0, 0x3C, 0x03, 0xC0, 0x36, 0x06, 0x60, 0x63, 0x9C,
|
||||
0x0F, 0x00, /* 0xD6 */
|
||||
0x83, 0x89, 0xA1, 0x83, 0x89, 0xA1, 0x80, /* 0xD7 */
|
||||
0x0F, 0xD9, 0x83, 0x18, 0x1C, 0xC1, 0xEC, 0x19, 0xE0, 0x8F, 0x08, 0x78, 0x83, 0xC8, 0x1B, 0x81, 0x98, 0x0C, 0xE0, 0xC8, 0xF8,
|
||||
0x00, /* 0xD8 */
|
||||
0x0C, 0x00, 0xC3, 0x01, 0xE0, 0x3C, 0x07, 0x80, 0xF0, 0x1E, 0x03, 0xC0, 0x78, 0x0F, 0x01, 0xE0, 0x36, 0x0C, 0x3E,
|
||||
0x00, /* 0xD9 */
|
||||
0x06, 0x01, 0x83, 0x01, 0xE0, 0x3C, 0x07, 0x80, 0xF0, 0x1E, 0x03, 0xC0, 0x78, 0x0F, 0x01, 0xE0, 0x36, 0x0C, 0x3E,
|
||||
0x00, /* 0xDA */
|
||||
0x0E, 0x03, 0x63, 0x01, 0xE0, 0x3C, 0x07, 0x80, 0xF0, 0x1E, 0x03, 0xC0, 0x78, 0x0F, 0x01, 0xE0, 0x36, 0x0C, 0x3E,
|
||||
0x00, /* 0xDB */
|
||||
0x1B, 0x00, 0x03, 0x01, 0xE0, 0x3C, 0x07, 0x80, 0xF0, 0x1E, 0x03, 0xC0, 0x78, 0x0F, 0x01, 0xE0, 0x36, 0x0C, 0x3E,
|
||||
0x00, /* 0xDC */
|
||||
0x03, 0x0C, 0x63, 0x60, 0x63, 0x0C, 0x30, 0xC1, 0x98, 0x1D, 0x80, 0xF0, 0x06, 0x00, 0x60, 0x06, 0x00, 0x60, 0x06, 0x00,
|
||||
0x60, /* 0xDD */
|
||||
0xC0, 0x30, 0x0F, 0xF3, 0x06, 0xC0, 0xF0, 0x3C, 0x0F, 0x06, 0xFF, 0x30, 0x0C, 0x03, 0x00, 0xC0, 0x00, /* 0xDE */
|
||||
0x3C, 0x33, 0x30, 0xD8, 0x6C, 0x36, 0x33, 0x39, 0x86, 0xC1, 0xE0, 0xF0, 0x78, 0x6D, 0xE0, /* 0xDF */
|
||||
0x60, 0x18, 0x06, 0x0F, 0xCE, 0x36, 0x18, 0x0C, 0x1E, 0x7B, 0x61, 0xB0, 0xD8, 0xE7, 0xB8, /* 0xE0 */
|
||||
0x0C, 0x04, 0x04, 0x0F, 0xCE, 0x36, 0x18, 0x0C, 0x1E, 0x7B, 0x61, 0xB0, 0xD8, 0xE7, 0xB8, /* 0xE1 */
|
||||
0x10, 0x14, 0x1B, 0x0F, 0xCE, 0x36, 0x18, 0x0C, 0x1E, 0x7B, 0x61, 0xB0, 0xD8, 0xE7, 0xB8, /* 0xE2 */
|
||||
0x24, 0x2E, 0x00, 0x0F, 0xCE, 0x36, 0x18, 0x0C, 0x1E, 0x7B, 0x61, 0xB0, 0xD8, 0xE7, 0xB8, /* 0xE3 */
|
||||
0x66, 0x00, 0x1F, 0x9C, 0x6C, 0x30, 0x18, 0x3C, 0xF6, 0xC3, 0x61, 0xB1, 0xCF, 0x70, /* 0xE4 */
|
||||
0x1C, 0x1B, 0x0D, 0x83, 0x87, 0xE7, 0x1B, 0x0C, 0x06, 0x0F, 0x3D, 0xB0, 0xD8, 0x6C, 0x73, 0xDC, /* 0xE5 */
|
||||
0x7E, 0xF9, 0xC7, 0x1B, 0x0C, 0x18, 0x18, 0x33, 0xFF, 0xFC, 0x60, 0x30, 0xC0, 0x61, 0x83, 0xC7, 0x8C, 0xF1, 0xF0, /* 0xE6 */
|
||||
0x3C, 0x66, 0xC3, 0xC0, 0xC0, 0xC0, 0xC0, 0xC3, 0x66, 0x3C, 0x10, 0x1C, 0x0C, 0x38, /* 0xE7 */
|
||||
0x60, 0x30, 0x18, 0x3C, 0x66, 0xC3, 0xC3, 0xFF, 0xC0, 0xC0, 0xC3, 0x66, 0x3C, /* 0xE8 */
|
||||
0x0C, 0x08, 0x18, 0x3C, 0x66, 0xC3, 0xC3, 0xFF, 0xC0, 0xC0, 0xC3, 0x66, 0x3C, /* 0xE9 */
|
||||
0x10, 0x28, 0x6C, 0x3C, 0x66, 0xC3, 0xC3, 0xFF, 0xC0, 0xC0, 0xC3, 0x66, 0x3C, /* 0xEA */
|
||||
0x66, 0x00, 0x3C, 0x66, 0xC3, 0xC3, 0xFF, 0xC0, 0xC0, 0xC3, 0x66, 0x3C, /* 0xEB */
|
||||
0xCC, 0xB6, 0xDB, 0x6D, 0xB6, /* 0xEC */
|
||||
0x7A, 0x6D, 0xB6, 0xDB, 0x6C, /* 0xED */
|
||||
0x6E, 0x96, 0x66, 0x66, 0x66, 0x66, 0x60, /* 0xEE */
|
||||
0xCC, 0x03, 0x0C, 0x30, 0xC3, 0x0C, 0x30, 0xC3, 0x0C, /* 0xEF */
|
||||
0x34, 0x0C, 0x16, 0x03, 0x3F, 0x67, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0x66, 0x3C, /* 0xF0 */
|
||||
0x24, 0x5C, 0x00, 0xDE, 0xE3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, /* 0xF1 */
|
||||
0x30, 0x18, 0x00, 0x3C, 0x66, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0x66, 0x3C, /* 0xF2 */
|
||||
0x0C, 0x18, 0x00, 0x3C, 0x66, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0x66, 0x3C, /* 0xF3 */
|
||||
0x18, 0x24, 0x00, 0x3C, 0x66, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0x66, 0x3C, /* 0xF4 */
|
||||
0x34, 0x2C, 0x00, 0x3C, 0x66, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0x66, 0x3C, /* 0xF5 */
|
||||
0x66, 0x00, 0x3C, 0x66, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0x66, 0x3C, /* 0xF6 */
|
||||
0x18, 0x00, 0x00, 0x1F, 0xF0, 0x00, 0x00, 0x00, 0x30, /* 0xF7 */
|
||||
0x3D, 0x66, 0xC7, 0xCB, 0xCB, 0xD3, 0xD3, 0xE3, 0x66, 0xBC, /* 0xF8 */
|
||||
0x60, 0x30, 0x18, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC7, 0x7B, /* 0xF9 */
|
||||
0x06, 0x0C, 0x18, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC7, 0x7B, /* 0xFA */
|
||||
0x3C, 0x66, 0x00, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC7, 0x7B, /* 0xFB */
|
||||
0x66, 0x00, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC3, 0xC7, 0x7B, /* 0xFC */
|
||||
0x06, 0x04, 0x08, 0xC1, 0x43, 0x63, 0x62, 0x26, 0x36, 0x34, 0x1C, 0x1C, 0x18, 0x18, 0x18, 0x10, 0x60, /* 0xFD */
|
||||
0xC0, 0x60, 0x30, 0x1B, 0xCE, 0x36, 0x0F, 0x07, 0x83, 0xC1, 0xE0, 0xF0, 0x7C, 0x6D, 0xE6, 0x03, 0x01, 0x80, /* 0xFE */
|
||||
0x33, 0x00, 0xC1, 0x43, 0x63, 0x62, 0x26, 0x36, 0x34, 0x1C, 0x1C, 0x18, 0x18, 0x18, 0x10, 0x60, /* 0xFF */
|
||||
};
|
||||
|
||||
const GFXglyph FreeSans9pt_Win1252Glyphs[] PROGMEM = {
|
||||
/* ' ' 0x20 */ {0, 0, 0, 5, 0, 0},
|
||||
/* '!' 0x21 */ {0, 2, 13, 6, 2, -12},
|
||||
/* '"' 0x22 */ {4, 5, 4, 6, 1, -12},
|
||||
/* '#' 0x23 */ {7, 10, 12, 10, 0, -11},
|
||||
/* '$' 0x24 */ {22, 9, 16, 10, 1, -13},
|
||||
/* '%' 0x25 */ {40, 16, 13, 16, 1, -12},
|
||||
/* '&' 0x26 */ {66, 10, 13, 12, 1, -12},
|
||||
/* ''' 0x27 */ {83, 2, 4, 4, 1, -12},
|
||||
/* '(' 0x28 */ {84, 4, 17, 6, 1, -12},
|
||||
/* ')' 0x29 */ {93, 4, 17, 6, 1, -12},
|
||||
/* '*' 0x2A */ {102, 5, 5, 7, 1, -12},
|
||||
/* '+' 0x2B */ {106, 6, 8, 11, 3, -7},
|
||||
/* ',' 0x2C */ {112, 2, 4, 5, 2, 0},
|
||||
/* '-' 0x2D */ {113, 4, 1, 6, 1, -4},
|
||||
/* '.' 0x2E */ {114, 2, 1, 5, 1, 0},
|
||||
/* '/' 0x2F */ {115, 5, 13, 5, 0, -12},
|
||||
/* '0' 0x30 */ {124, 8, 13, 10, 1, -12},
|
||||
/* '1' 0x31 */ {137, 4, 13, 10, 3, -12},
|
||||
/* '2' 0x32 */ {144, 9, 13, 10, 1, -12},
|
||||
/* '3' 0x33 */ {159, 8, 13, 10, 1, -12},
|
||||
/* '4' 0x34 */ {172, 7, 13, 10, 2, -12},
|
||||
/* '5' 0x35 */ {184, 9, 13, 10, 1, -12},
|
||||
/* '6' 0x36 */ {199, 9, 13, 10, 1, -12},
|
||||
/* '7' 0x37 */ {214, 8, 13, 10, 0, -12},
|
||||
/* '8' 0x38 */ {227, 9, 13, 10, 1, -12},
|
||||
/* '9' 0x39 */ {242, 8, 13, 10, 1, -12},
|
||||
/* ':' 0x3A */ {255, 2, 10, 5, 1, -9},
|
||||
/* ';' 0x3B */ {258, 3, 12, 5, 1, -8},
|
||||
/* '<' 0x3C */ {263, 9, 9, 11, 1, -8},
|
||||
/* '=' 0x3D */ {274, 9, 4, 11, 1, -5},
|
||||
/* '>' 0x3E */ {279, 9, 8, 11, 1, -7},
|
||||
/* '?' 0x3F */ {288, 9, 13, 10, 1, -12},
|
||||
/* '@' 0x40 */ {303, 17, 16, 18, 1, -12},
|
||||
/* 'A' 0x41 */ {337, 12, 13, 12, 0, -12},
|
||||
/* 'B' 0x42 */ {357, 11, 13, 12, 1, -12},
|
||||
/* 'C' 0x43 */ {375, 11, 13, 13, 1, -12},
|
||||
/* 'D' 0x44 */ {393, 11, 13, 13, 1, -12},
|
||||
/* 'E' 0x45 */ {411, 9, 13, 11, 1, -12},
|
||||
/* 'F' 0x46 */ {426, 8, 13, 11, 1, -12},
|
||||
/* 'G' 0x47 */ {439, 12, 13, 14, 1, -12},
|
||||
/* 'H' 0x48 */ {459, 11, 13, 13, 1, -12},
|
||||
/* 'I' 0x49 */ {477, 2, 13, 5, 2, -12},
|
||||
/* 'J' 0x4A */ {481, 7, 13, 10, 1, -12},
|
||||
/* 'K' 0x4B */ {493, 10, 13, 12, 1, -12},
|
||||
/* 'L' 0x4C */ {510, 8, 13, 10, 1, -12},
|
||||
/* 'M' 0x4D */ {523, 13, 13, 15, 1, -12},
|
||||
/* 'N' 0x4E */ {545, 11, 13, 13, 1, -12},
|
||||
/* 'O' 0x4F */ {563, 13, 13, 14, 1, -12},
|
||||
/* 'P' 0x50 */ {585, 10, 13, 12, 1, -12},
|
||||
/* 'Q' 0x51 */ {602, 13, 14, 14, 1, -12},
|
||||
/* 'R' 0x52 */ {625, 12, 13, 13, 1, -12},
|
||||
/* 'S' 0x53 */ {645, 10, 13, 12, 1, -12},
|
||||
/* 'T' 0x54 */ {662, 9, 13, 11, 1, -12},
|
||||
/* 'U' 0x55 */ {677, 11, 13, 13, 1, -12},
|
||||
/* 'V' 0x56 */ {695, 11, 13, 11, 0, -12},
|
||||
/* 'W' 0x57 */ {713, 16, 13, 17, 0, -12},
|
||||
/* 'X' 0x58 */ {739, 10, 13, 12, 1, -12},
|
||||
/* 'Y' 0x59 */ {756, 12, 13, 12, 0, -12},
|
||||
/* 'Z' 0x5A */ {776, 10, 13, 11, 1, -12},
|
||||
/* '[' 0x5B */ {793, 3, 17, 5, 1, -12},
|
||||
/* '\' 0x5C */ {800, 5, 13, 5, 0, -12},
|
||||
/* ']' 0x5D */ {809, 3, 17, 5, 0, -12},
|
||||
/* '^' 0x5E */ {816, 7, 7, 8, 1, -12},
|
||||
/* '_' 0x5F */ {823, 10, 1, 10, 0, 3},
|
||||
/* '`' 0x60 */ {825, 4, 3, 5, 0, -12},
|
||||
/* 'a' 0x61 */ {827, 9, 10, 10, 1, -9},
|
||||
/* 'b' 0x62 */ {839, 9, 13, 10, 1, -12},
|
||||
/* 'c' 0x63 */ {854, 8, 10, 9, 1, -9},
|
||||
/* 'd' 0x64 */ {864, 8, 13, 10, 1, -12},
|
||||
/* 'e' 0x65 */ {877, 8, 10, 10, 1, -9},
|
||||
/* 'f' 0x66 */ {887, 4, 13, 5, 1, -12},
|
||||
/* 'g' 0x67 */ {894, 8, 14, 10, 1, -9},
|
||||
/* 'h' 0x68 */ {908, 8, 13, 10, 1, -12},
|
||||
/* 'i' 0x69 */ {921, 2, 13, 4, 1, -12},
|
||||
/* 'j' 0x6A */ {925, 4, 17, 4, 0, -12},
|
||||
/* 'k' 0x6B */ {934, 8, 13, 9, 1, -12},
|
||||
/* 'l' 0x6C */ {947, 2, 13, 4, 1, -12},
|
||||
/* 'm' 0x6D */ {951, 13, 10, 15, 1, -9},
|
||||
/* 'n' 0x6E */ {968, 8, 10, 10, 1, -9},
|
||||
/* 'o' 0x6F */ {978, 8, 10, 10, 1, -9},
|
||||
/* 'p' 0x70 */ {988, 9, 13, 10, 1, -9},
|
||||
/* 'q' 0x71 */ {1003, 8, 13, 10, 1, -9},
|
||||
/* 'r' 0x72 */ {1016, 5, 10, 6, 1, -9},
|
||||
/* 's' 0x73 */ {1023, 8, 10, 9, 1, -9},
|
||||
/* 't' 0x74 */ {1033, 4, 12, 5, 1, -11},
|
||||
/* 'u' 0x75 */ {1039, 8, 10, 10, 1, -9},
|
||||
/* 'v' 0x76 */ {1049, 9, 10, 9, 0, -9},
|
||||
/* 'w' 0x77 */ {1061, 13, 10, 13, 0, -9},
|
||||
/* 'x' 0x78 */ {1078, 7, 10, 9, 1, -9},
|
||||
/* 'y' 0x79 */ {1087, 8, 14, 9, 0, -9},
|
||||
/* 'z' 0x7A */ {1101, 7, 10, 9, 1, -9},
|
||||
/* '{' 0x7B */ {1110, 4, 17, 6, 1, -12},
|
||||
/* '|' 0x7C */ {1119, 2, 17, 4, 2, -12},
|
||||
/* '}' 0x7D */ {1124, 4, 17, 6, 1, -12},
|
||||
/* '~' 0x7E */ {1133, 7, 3, 9, 1, -7},
|
||||
/* 0x7F */ {1136, 13, 14, 15, 1, -12},
|
||||
/* 0x80 */ {1159, 10, 13, 12, 1, -12},
|
||||
/* 0x81 */ {1176, 0, 0, 8, 0, 0},
|
||||
/* 0x82 */ {1176, 2, 3, 5, 1, 0},
|
||||
/* 0x83 */ {1177, 5, 17, 5, 0, -12},
|
||||
/* 0x84 */ {1188, 5, 3, 7, 1, 0},
|
||||
/* 0x85 */ {1190, 10, 1, 12, 1, 0},
|
||||
/* 0x86 */ {1192, 8, 16, 10, 1, -12},
|
||||
/* 0x87 */ {1208, 8, 16, 10, 1, -12},
|
||||
/* 0x88 */ {1224, 5, 3, 6, 0, -12},
|
||||
/* 0x89 */ {1226, 18, 13, 18, 0, -12},
|
||||
/* 0x8A */ {1256, 10, 16, 12, 1, -15},
|
||||
/* 0x8B */ {1276, 2, 4, 4, 1, -6},
|
||||
/* 0x8C */ {1277, 15, 13, 18, 1, -12},
|
||||
/* 0x8D */ {1302, 0, 0, 8, 0, 0},
|
||||
/* 0x8E */ {1302, 10, 16, 11, 1, -15},
|
||||
/* 0x8F */ {1322, 0, 0, 8, 0, 0},
|
||||
/* 0x90 */ {1322, 0, 0, 8, 0, 0},
|
||||
/* 0x91 */ {1322, 2, 4, 4, 2, -12},
|
||||
/* 0x92 */ {1323, 2, 4, 4, 1, -12},
|
||||
/* 0x93 */ {1324, 5, 4, 7, 2, -12},
|
||||
/* 0x94 */ {1327, 5, 4, 7, 1, -12},
|
||||
/* 0x95 */ {1330, 4, 5, 7, 1, -8},
|
||||
/* 0x96 */ {1333, 7, 1, 9, 1, -4},
|
||||
/* 0x97 */ {1334, 16, 1, 18, 1, -4},
|
||||
/* 0x98 */ {1336, 5, 2, 6, 0, -12},
|
||||
/* 0x99 */ {1338, 18, 10, 18, 1, -13},
|
||||
/* 0x9A */ {1361, 8, 13, 9, 1, -12},
|
||||
/* 0x9B */ {1374, 2, 4, 5, 2, -6},
|
||||
/* 0x9C */ {1375, 15, 10, 17, 1, -9},
|
||||
/* 0x9D */ {1394, 0, 0, 8, 0, 0},
|
||||
/* 0x9E */ {1394, 7, 13, 9, 1, -12},
|
||||
/* 0x9F */ {1406, 12, 14, 12, 0, -13},
|
||||
/* 0xA0 */ {1427, 0, 0, 5, 0, 0},
|
||||
/* 0xA1 */ {1427, 2, 13, 6, 2, -8},
|
||||
/* 0xA2 */ {1431, 9, 14, 10, 1, -11},
|
||||
/* 0xA3 */ {1447, 10, 13, 10, 0, -12},
|
||||
/* 0xA4 */ {1464, 7, 6, 10, 2, -8},
|
||||
/* 0xA5 */ {1470, 8, 13, 10, 1, -12},
|
||||
/* 0xA6 */ {1483, 2, 17, 5, 2, -12},
|
||||
/* 0xA7 */ {1488, 9, 17, 10, 1, -12},
|
||||
/* 0xA8 */ {1508, 6, 1, 6, 0, -11},
|
||||
/* 0xA9 */ {1509, 14, 13, 14, 1, -12},
|
||||
/* 0xAA */ {1532, 5, 8, 7, 1, -12},
|
||||
/* 0xAB */ {1537, 7, 6, 9, 1, -7},
|
||||
/* 0xAC */ {1543, 9, 5, 11, 2, -5},
|
||||
/* 0xAD */ {1549, 0, 0, 0, 0, 0},
|
||||
/* 0xAE */ {1549, 14, 13, 14, 1, -12},
|
||||
/* 0xAF */ {1572, 5, 1, 6, 0, -12},
|
||||
/* 0xB0 */ {1573, 5, 5, 11, 3, -11},
|
||||
/* 0xB1 */ {1577, 9, 11, 11, 1, -10},
|
||||
/* 0xB2 */ {1590, 6, 8, 6, 1, -13},
|
||||
/* 0xB3 */ {1596, 7, 8, 6, 0, -13},
|
||||
/* 0xB4 */ {1603, 4, 3, 6, 2, -12},
|
||||
/* 0xB5 */ {1605, 9, 13, 10, 1, -9},
|
||||
/* 0xB6 */ {1620, 8, 16, 10, 2, -12},
|
||||
/* 0xB7 */ {1636, 3, 1, 5, 1, -4},
|
||||
/* 0xB8 */ {1637, 5, 4, 6, 1, 1},
|
||||
/* 0xB9 */ {1640, 3, 7, 6, 2, -13},
|
||||
/* 0xBA */ {1643, 5, 8, 7, 1, -12},
|
||||
/* 0xBB */ {1648, 7, 6, 9, 1, -7},
|
||||
/* 0xBC */ {1654, 14, 13, 16, 2, -12},
|
||||
/* 0xBD */ {1677, 14, 13, 16, 2, -12},
|
||||
/* 0xBE */ {1700, 15, 13, 16, 1, -12},
|
||||
/* 0xBF */ {1725, 9, 13, 10, 1, -8},
|
||||
/* 0xC0 */ {1740, 10, 14, 12, 1, -13},
|
||||
/* 0xC1 */ {1758, 10, 14, 12, 1, -13},
|
||||
/* 0xC2 */ {1776, 10, 14, 12, 1, -13},
|
||||
/* 0xC3 */ {1794, 10, 14, 12, 1, -13},
|
||||
/* 0xC4 */ {1812, 10, 14, 12, 1, -13},
|
||||
/* 0xC5 */ {1830, 10, 14, 12, 1, -13},
|
||||
/* 0xC6 */ {1848, 16, 13, 18, 1, -12},
|
||||
/* 0xC7 */ {1874, 11, 17, 13, 1, -12},
|
||||
/* 0xC8 */ {1898, 9, 14, 11, 1, -13},
|
||||
/* 0xC9 */ {1914, 9, 14, 11, 1, -13},
|
||||
/* 0xCA */ {1930, 9, 14, 11, 1, -13},
|
||||
/* 0xCB */ {1946, 9, 14, 11, 1, -13},
|
||||
/* 0xCC */ {1962, 3, 15, 5, 1, -13},
|
||||
/* 0xCD */ {1968, 3, 14, 5, 1, -13},
|
||||
/* 0xCE */ {1974, 5, 14, 5, 0, -13},
|
||||
/* 0xCF */ {1983, 6, 14, 5, 0, -13},
|
||||
/* 0xD0 */ {1994, 11, 13, 13, 1, -12},
|
||||
/* 0xD1 */ {2012, 11, 14, 13, 1, -13},
|
||||
/* 0xD2 */ {2032, 12, 15, 13, 1, -14},
|
||||
/* 0xD3 */ {2055, 12, 15, 13, 1, -14},
|
||||
/* 0xD4 */ {2078, 12, 15, 13, 1, -14},
|
||||
/* 0xD5 */ {2101, 12, 15, 13, 1, -14},
|
||||
/* 0xD6 */ {2124, 12, 15, 13, 1, -14},
|
||||
/* 0xD7 */ {2147, 7, 7, 11, 2, -7},
|
||||
/* 0xD8 */ {2154, 13, 13, 14, 1, -12},
|
||||
/* 0xD9 */ {2176, 11, 14, 13, 1, -13},
|
||||
/* 0xDA */ {2196, 11, 14, 13, 1, -13},
|
||||
/* 0xDB */ {2216, 11, 14, 13, 1, -13},
|
||||
/* 0xDC */ {2236, 11, 14, 13, 1, -13},
|
||||
/* 0xDD */ {2256, 12, 14, 12, 0, -13},
|
||||
/* 0xDE */ {2277, 10, 13, 12, 1, -12},
|
||||
/* 0xDF */ {2294, 9, 13, 11, 1, -12},
|
||||
/* 0xE0 */ {2309, 9, 13, 10, 1, -12},
|
||||
/* 0xE1 */ {2324, 9, 13, 10, 1, -12},
|
||||
/* 0xE2 */ {2339, 9, 13, 10, 1, -12},
|
||||
/* 0xE3 */ {2354, 9, 13, 10, 1, -12},
|
||||
/* 0xE4 */ {2369, 9, 12, 10, 1, -11},
|
||||
/* 0xE5 */ {2383, 9, 14, 10, 1, -13},
|
||||
/* 0xE6 */ {2399, 15, 10, 16, 1, -9},
|
||||
/* 0xE7 */ {2418, 8, 14, 9, 1, -9},
|
||||
/* 0xE8 */ {2432, 8, 13, 10, 1, -12},
|
||||
/* 0xE9 */ {2445, 8, 13, 10, 1, -12},
|
||||
/* 0xEA */ {2458, 8, 13, 10, 1, -12},
|
||||
/* 0xEB */ {2471, 8, 12, 10, 1, -11},
|
||||
/* 0xEC */ {2483, 3, 13, 4, 0, -12},
|
||||
/* 0xED */ {2488, 3, 13, 4, 1, -12},
|
||||
/* 0xEE */ {2493, 4, 13, 5, 0, -12},
|
||||
/* 0xEF */ {2500, 6, 12, 5, -1, -11},
|
||||
/* 0xF0 */ {2509, 8, 13, 10, 1, -12},
|
||||
/* 0xF1 */ {2522, 8, 13, 10, 1, -12},
|
||||
/* 0xF2 */ {2535, 8, 13, 10, 1, -12},
|
||||
/* 0xF3 */ {2548, 8, 13, 10, 1, -12},
|
||||
/* 0xF4 */ {2561, 8, 13, 10, 1, -12},
|
||||
/* 0xF5 */ {2574, 8, 13, 10, 1, -12},
|
||||
/* 0xF6 */ {2587, 8, 12, 10, 1, -11},
|
||||
/* 0xF7 */ {2599, 9, 8, 11, 1, -7},
|
||||
/* 0xF8 */ {2608, 8, 10, 10, 1, -9},
|
||||
/* 0xF9 */ {2618, 8, 13, 10, 1, -12},
|
||||
/* 0xFA */ {2631, 8, 13, 10, 1, -12},
|
||||
/* 0xFB */ {2644, 8, 13, 10, 1, -12},
|
||||
/* 0xFC */ {2657, 8, 12, 10, 1, -11},
|
||||
/* 0xFD */ {2669, 8, 17, 9, 0, -12},
|
||||
/* 0xFE */ {2686, 9, 16, 10, 1, -12},
|
||||
/* 0xFF */ {2704, 8, 16, 9, 0, -11},
|
||||
};
|
||||
|
||||
const GFXfont FreeSans9pt_Win1252 PROGMEM = {(uint8_t *)FreeSans9pt_Win1252Bitmaps, (GFXglyph *)FreeSans9pt_Win1252Glyphs, 0x20,
|
||||
0xFF, 21};
|
||||
@@ -263,22 +263,10 @@ uint16_t InkHUD::Applet::Y(float f)
|
||||
// Print text, specifying the position of any edge / corner of the textbox
|
||||
void InkHUD::Applet::printAt(int16_t x, int16_t y, const char *text, HorizontalAlignment ha, VerticalAlignment va)
|
||||
{
|
||||
printAt(x, y, std::string(text), ha, va);
|
||||
}
|
||||
|
||||
// Print text, specifying the position of any edge / corner of the textbox
|
||||
void InkHUD::Applet::printAt(int16_t x, int16_t y, std::string text, HorizontalAlignment ha, VerticalAlignment va)
|
||||
{
|
||||
// Custom font
|
||||
// - set with AppletFont::addSubstitution
|
||||
// - find certain UTF8 chars
|
||||
// - replace with glyph from custom font (or suitable ASCII addSubstitution?)
|
||||
getFont().applySubstitutions(&text);
|
||||
|
||||
// We do still have to run getTextBounds to find the width
|
||||
int16_t textOffsetX, textOffsetY;
|
||||
uint16_t textWidth, textHeight;
|
||||
getTextBounds(text.c_str(), 0, 0, &textOffsetX, &textOffsetY, &textWidth, &textHeight);
|
||||
getTextBounds(text, 0, 0, &textOffsetX, &textOffsetY, &textWidth, &textHeight);
|
||||
|
||||
int16_t cursorX = 0;
|
||||
int16_t cursorY = 0;
|
||||
@@ -310,7 +298,13 @@ void InkHUD::Applet::printAt(int16_t x, int16_t y, std::string text, HorizontalA
|
||||
}
|
||||
|
||||
setCursor(cursorX, cursorY);
|
||||
print(text.c_str());
|
||||
print(text);
|
||||
}
|
||||
|
||||
// Print text, specifying the position of any edge / corner of the textbox
|
||||
void InkHUD::Applet::printAt(int16_t x, int16_t y, std::string text, HorizontalAlignment ha, VerticalAlignment va)
|
||||
{
|
||||
printAt(x, y, text.c_str(), ha, va);
|
||||
}
|
||||
|
||||
// Set which font should be used for subsequent drawing
|
||||
@@ -328,11 +322,52 @@ InkHUD::AppletFont InkHUD::Applet::getFont()
|
||||
return currentFont;
|
||||
}
|
||||
|
||||
// Parse any text which might have "special characters"
|
||||
// Re-encodes UTF-8 characters to match our 8-bit encoded fonts
|
||||
std::string InkHUD::Applet::parse(std::string text)
|
||||
{
|
||||
return getFont().decodeUTF8(text);
|
||||
}
|
||||
|
||||
// Get the best version of a node's short name available to us
|
||||
// Parses any non-ascii chars
|
||||
// Swaps for last-four of node-id if the real short name is unknown or can't be rendered (emoji)
|
||||
std::string InkHUD::Applet::parseShortName(meshtastic_NodeInfoLite *node)
|
||||
{
|
||||
assert(node);
|
||||
|
||||
// Use the true shortname if known, and doesn't contain any unprintable characters (emoji, etc.)
|
||||
if (node->has_user) {
|
||||
std::string parsed = parse(node->user.short_name);
|
||||
if (isPrintable(parsed))
|
||||
return parsed;
|
||||
}
|
||||
|
||||
// Otherwise, use the "last 4" of node id
|
||||
// - if short name unknown, or
|
||||
// - if short name is emoji (we can't render this)
|
||||
std::string nodeID = hexifyNodeNum(node->num);
|
||||
return nodeID.substr(nodeID.length() - 4);
|
||||
}
|
||||
|
||||
// Determine if all characters of a string are printable using the current font
|
||||
bool InkHUD::Applet::isPrintable(std::string text)
|
||||
{
|
||||
// Scan for DEL (0x7F), which is the value assigned by AppletFont::applyEncoding if a unicode character is not handled
|
||||
// Todo: move this to from DEL to SUB, once the fonts have been changed for this
|
||||
for (char &c : text) {
|
||||
if (c == '\x7F')
|
||||
return false;
|
||||
}
|
||||
|
||||
// No unprintable characters found
|
||||
return true;
|
||||
}
|
||||
|
||||
// Gets rendered width of a string
|
||||
// Wrapper for getTextBounds
|
||||
uint16_t InkHUD::Applet::getTextWidth(const char *text)
|
||||
{
|
||||
|
||||
// We do still have to run getTextBounds to find the width
|
||||
int16_t textOffsetX, textOffsetY;
|
||||
uint16_t textWidth, textHeight;
|
||||
@@ -345,8 +380,6 @@ uint16_t InkHUD::Applet::getTextWidth(const char *text)
|
||||
// Wrapper for getTextBounds
|
||||
uint16_t InkHUD::Applet::getTextWidth(std::string text)
|
||||
{
|
||||
getFont().applySubstitutions(&text);
|
||||
|
||||
return getTextWidth(text.c_str());
|
||||
}
|
||||
|
||||
@@ -395,12 +428,6 @@ std::string InkHUD::Applet::hexifyNodeNum(NodeNum num)
|
||||
// Avoids splitting words in half, instead moving the entire word to a new line wherever possible
|
||||
void InkHUD::Applet::printWrapped(int16_t left, int16_t top, uint16_t width, std::string text)
|
||||
{
|
||||
// Custom font glyphs
|
||||
// - set with AppletFont::addSubstitution
|
||||
// - find certain UTF8 chars
|
||||
// - replace with glyph from custom font (or suitable ASCII addSubstitution?)
|
||||
getFont().applySubstitutions(&text);
|
||||
|
||||
// Place the AdafruitGFX cursor to suit our "top" coord
|
||||
setCursor(left, top + getFont().heightAboveCursor());
|
||||
|
||||
|
||||
@@ -133,12 +133,15 @@ class Applet : public GFX
|
||||
void drawLogo(int16_t centerX, int16_t centerY, uint16_t width, uint16_t height,
|
||||
Color color = BLACK); // Draw the Meshtastic logo
|
||||
|
||||
std::string hexifyNodeNum(NodeNum num); // Style as !0123abdc
|
||||
SignalStrength getSignalStrength(float snr, float rssi); // Interpret SNR and RSSI, as an easy to understand value
|
||||
std::string getTimeString(uint32_t epochSeconds); // Human readable
|
||||
std::string getTimeString(); // Current time, human readable
|
||||
uint16_t getActiveNodeCount(); // Duration determined by user, in onscreen menu
|
||||
std::string localizeDistance(uint32_t meters); // Human readable distance, imperial or metric
|
||||
std::string hexifyNodeNum(NodeNum num); // Style as !0123abdc
|
||||
SignalStrength getSignalStrength(float snr, float rssi); // Interpret SNR and RSSI, as an easy to understand value
|
||||
std::string getTimeString(uint32_t epochSeconds); // Human readable
|
||||
std::string getTimeString(); // Current time, human readable
|
||||
uint16_t getActiveNodeCount(); // Duration determined by user, in onscreen menu
|
||||
std::string localizeDistance(uint32_t meters); // Human readable distance, imperial or metric
|
||||
std::string parse(std::string text); // Handle text which might contain special chars
|
||||
std::string parseShortName(meshtastic_NodeInfoLite *node); // Get the shortname, or a substitute if has unprintable chars
|
||||
bool isPrintable(std::string); // Check for characters which the font can't print
|
||||
|
||||
// Convenient references
|
||||
|
||||
|
||||
@@ -2,14 +2,17 @@
|
||||
|
||||
#include "./AppletFont.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
using namespace NicheGraphics;
|
||||
|
||||
InkHUD::AppletFont::AppletFont()
|
||||
{
|
||||
// Default constructor uses the in-built AdafruitGFX font
|
||||
// Default constructor uses the in-built AdafruitGFX font (not recommended)
|
||||
}
|
||||
|
||||
InkHUD::AppletFont::AppletFont(const GFXfont &adafruitGFXFont) : gfxFont(&adafruitGFXFont)
|
||||
InkHUD::AppletFont::AppletFont(const GFXfont &adafruitGFXFont, Encoding encoding, int8_t paddingTop, int8_t paddingBottom)
|
||||
: gfxFont(&adafruitGFXFont), encoding(encoding)
|
||||
{
|
||||
// AdafruitGFX fonts are drawn relative to a "cursor line";
|
||||
// they print as if the glyphs are resting on the line of piece of ruled paper.
|
||||
@@ -22,6 +25,10 @@ InkHUD::AppletFont::AppletFont(const GFXfont &adafruitGFXFont) : gfxFont(&adafru
|
||||
// AdafruitGFX fonts do declare a line-height, but this seems to include a certain amount of padding,
|
||||
// which we'd rather not deal with. If we want padding, we'll add it manually.
|
||||
|
||||
this->ascenderHeight = 0;
|
||||
this->descenderHeight = 0;
|
||||
this->height = 0;
|
||||
|
||||
// Scan each glyph in the AdafruitGFX font
|
||||
for (uint16_t i = 0; i <= (gfxFont->last - gfxFont->first); i++) {
|
||||
uint8_t glyphHeight = gfxFont->glyph[i].height; // Height of glyph
|
||||
@@ -33,10 +40,16 @@ InkHUD::AppletFont::AppletFont(const GFXfont &adafruitGFXFont) : gfxFont(&adafru
|
||||
int8_t glyphAscender = 0 - gfxFont->glyph[i].yOffset;
|
||||
if (glyphAscender > 0)
|
||||
this->ascenderHeight = max(this->ascenderHeight, (uint8_t)glyphAscender);
|
||||
|
||||
int8_t glyphDescender = gfxFont->glyph[i].height + gfxFont->glyph[i].yOffset;
|
||||
if (glyphDescender > 0)
|
||||
this->descenderHeight = max(this->descenderHeight, (uint8_t)glyphDescender);
|
||||
}
|
||||
|
||||
// Determine how far characters may hang "below the line"
|
||||
descenderHeight = height - ascenderHeight;
|
||||
// Apply any manual padding to grow or shrink the line size
|
||||
// Helpful if a font has one or two exceptionally large characters, which would make the lines ridiculously tall
|
||||
ascenderHeight += paddingTop;
|
||||
descenderHeight += paddingBottom;
|
||||
|
||||
// Find how far the cursor advances when we "print" a space character
|
||||
spaceCharWidth = gfxFont->glyph[(uint8_t)' ' - gfxFont->first].xAdvance;
|
||||
@@ -83,139 +96,533 @@ uint8_t InkHUD::AppletFont::widthBetweenWords()
|
||||
return this->spaceCharWidth;
|
||||
}
|
||||
|
||||
// Add to the list of substituted glyphs
|
||||
// This "find and replace" operation will be run before text is printed
|
||||
// Used to swap out UTF8 special characters, either with a custom font, or with a suitable ASCII approximation
|
||||
void InkHUD::AppletFont::addSubstitution(const char *from, const char *to)
|
||||
// Convert a unicode char from set of UTF-8 bytes to UTF-32
|
||||
// Used by AppletFont::applyEncoding, which remaps unicode chars for extended ASCII fonts, based on their UTF-32 value
|
||||
uint32_t InkHUD::AppletFont::toUtf32(std::string utf8)
|
||||
{
|
||||
substitutions.push_back({.from = from, .to = to});
|
||||
uint32_t utf32 = 0;
|
||||
|
||||
switch (utf8.length()) {
|
||||
case 2:
|
||||
// 5 bits + 6 bits
|
||||
utf32 |= (utf8.at(0) & 0b00011111) << 6;
|
||||
utf32 |= (utf8.at(1) & 0b00111111);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
// 4 bits + 6 bits + 6 bits
|
||||
utf32 |= (utf8.at(0) & 0b00001111) << (6 + 6);
|
||||
utf32 |= (utf8.at(1) & 0b00111111) << 6;
|
||||
utf32 |= (utf8.at(2) & 0b00111111);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
// 3 bits + 6 bits + 6 bits + 6 bits
|
||||
utf32 |= (utf8.at(0) & 0b00000111) << (6 + 6 + 6);
|
||||
utf32 |= (utf8.at(1) & 0b00111111) << (6 + 6);
|
||||
utf32 |= (utf8.at(2) & 0b00111111) << 6;
|
||||
utf32 |= (utf8.at(3) & 0b00111111);
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
}
|
||||
|
||||
return utf32;
|
||||
}
|
||||
|
||||
// Run all registered substitutions on a string
|
||||
// Used to swap out UTF8 special chars
|
||||
void InkHUD::AppletFont::applySubstitutions(std::string *text)
|
||||
// Process a string, collating UTF-8 bytes, and sending them off for re-encoding to extended ASCII
|
||||
// Not all InkHUD text is passed through here, only text which could potentially contain non-ASCII chars
|
||||
std::string InkHUD::AppletFont::decodeUTF8(std::string encoded)
|
||||
{
|
||||
// For each substitution
|
||||
for (Substitution s : substitutions) {
|
||||
// Final processed output
|
||||
std::string decoded;
|
||||
|
||||
// Find and replace
|
||||
// - search for Substitution::from
|
||||
// - replace with Substitution::to
|
||||
size_t i = text->find(s.from);
|
||||
while (i != std::string::npos) {
|
||||
text->replace(i, strlen(s.from), s.to);
|
||||
i = text->find(s.from, i); // Continue looking from last position
|
||||
// Holds bytes for one UTF-8 char during parsing
|
||||
std::string utf8Char;
|
||||
uint8_t utf8CharSize = 0;
|
||||
|
||||
for (char &c : encoded) {
|
||||
|
||||
// If first byte
|
||||
if (utf8Char.empty()) {
|
||||
// If MSB is unset, byte is an ASCII char
|
||||
// If MSB is set, byte is part of a UTF-8 char. Counting number of higher-order bits tells how many bytes in char
|
||||
if ((c & 0x80)) {
|
||||
char c1 = c;
|
||||
while (c1 & 0x80) {
|
||||
c1 <<= 1;
|
||||
utf8CharSize++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Append the byte to the UTF-8 char we're building
|
||||
utf8Char += c;
|
||||
|
||||
// More bytes left to collect. Iterate.
|
||||
if (utf8Char.length() < utf8CharSize)
|
||||
continue;
|
||||
|
||||
// Now collected all bytes for this char
|
||||
// Remap the value to match the encoding of our 8-bit AppletFont
|
||||
decoded += applyEncoding(utf8Char);
|
||||
|
||||
// Reset, ready to build next UTF-8 char from the encoded bytes
|
||||
utf8Char.clear();
|
||||
utf8CharSize = 0;
|
||||
} // For each char
|
||||
|
||||
// All chars processed, return result
|
||||
return decoded;
|
||||
}
|
||||
|
||||
// Re-encode a single UTF-8 character to extended ASCII
|
||||
// Target encoding depends on the font
|
||||
char InkHUD::AppletFont::applyEncoding(std::string utf8)
|
||||
{
|
||||
// ##################################################### Syntactic Sugar #####################################################
|
||||
#define REMAP(in, out) \
|
||||
case in: \
|
||||
return out;
|
||||
// ###########################################################################################################################
|
||||
|
||||
// Latin - Central Europe
|
||||
// https://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1250.TXT
|
||||
if (encoding == WINDOWS_1250) {
|
||||
// 1-Byte chars: no remapping
|
||||
if (utf8.length() == 1)
|
||||
return utf8.at(0);
|
||||
|
||||
// Multi-byte chars:
|
||||
switch (toUtf32(utf8)) {
|
||||
REMAP(0x20AC, 0x80); // EURO SIGN
|
||||
REMAP(0x201A, 0x82); // SINGLE LOW-9 QUOTATION MARK
|
||||
REMAP(0x201E, 0x84); // DOUBLE LOW-9 QUOTATION MARK
|
||||
REMAP(0x2026, 0x85); // HORIZONTAL ELLIPSIS
|
||||
REMAP(0x2020, 0x86); // DAGGER
|
||||
REMAP(0x2021, 0x87); // DOUBLE DAGGER
|
||||
REMAP(0x2030, 0x89); // PER MILLE SIGN
|
||||
REMAP(0x0160, 0x8A); // LATIN CAPITAL LETTER S WITH CARON
|
||||
REMAP(0x2039, 0x8B); // SINGLE LEFT-POINTING ANGLE QUOTATION MARK
|
||||
REMAP(0x015A, 0x8C); // LATIN CAPITAL LETTER S WITH ACUTE
|
||||
REMAP(0x0164, 0x8D); // LATIN CAPITAL LETTER T WITH CARON
|
||||
REMAP(0x017D, 0x8E); // LATIN CAPITAL LETTER Z WITH CARON
|
||||
REMAP(0x0179, 0x8F); // LATIN CAPITAL LETTER Z WITH ACUTE
|
||||
|
||||
REMAP(0x2018, 0x91); // LEFT SINGLE QUOTATION MARK
|
||||
REMAP(0x2019, 0x92); // RIGHT SINGLE QUOTATION MARK
|
||||
REMAP(0x201C, 0x93); // LEFT DOUBLE QUOTATION MARK
|
||||
REMAP(0x201D, 0x94); // RIGHT DOUBLE QUOTATION MARK
|
||||
REMAP(0x2022, 0x95); // BULLET
|
||||
REMAP(0x2013, 0x96); // EN DASH
|
||||
REMAP(0x2014, 0x97); // EM DASH
|
||||
REMAP(0x2122, 0x99); // TRADE MARK SIGN
|
||||
REMAP(0x0161, 0x9A); // LATIN SMALL LETTER S WITH CARON
|
||||
REMAP(0x203A, 0x9B); // SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
|
||||
REMAP(0x015B, 0x9C); // LATIN SMALL LETTER S WITH ACUTE
|
||||
REMAP(0x0165, 0x9D); // LATIN SMALL LETTER T WITH CARON
|
||||
REMAP(0x017E, 0x9E); // LATIN SMALL LETTER Z WITH CARON
|
||||
REMAP(0x017A, 0x9F); // LATIN SMALL LETTER Z WITH ACUTE
|
||||
|
||||
REMAP(0x00A0, 0xA0); // NO-BREAK SPACE
|
||||
REMAP(0x02C7, 0xA1); // CARON
|
||||
REMAP(0x02D8, 0xA2); // BREVE
|
||||
REMAP(0x0141, 0xA3); // LATIN CAPITAL LETTER L WITH STROKE
|
||||
REMAP(0x00A4, 0xA4); // CURRENCY SIGN
|
||||
REMAP(0x0104, 0xA5); // LATIN CAPITAL LETTER A WITH OGONEK
|
||||
REMAP(0x00A6, 0xA6); // BROKEN BAR
|
||||
REMAP(0x00A7, 0xA7); // SECTION SIGN
|
||||
REMAP(0x00A8, 0xA8); // DIAERESIS
|
||||
REMAP(0x00A9, 0xA9); // COPYRIGHT SIGN
|
||||
REMAP(0x015E, 0xAA); // LATIN CAPITAL LETTER S WITH CEDILLA
|
||||
REMAP(0x00AB, 0xAB); // LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
|
||||
REMAP(0x00AC, 0xAC); // NOT SIGN
|
||||
REMAP(0x00AD, 0xAD); // SOFT HYPHEN
|
||||
REMAP(0x00AE, 0xAE); // REGISTERED SIGN
|
||||
REMAP(0x017B, 0xAF); // LATIN CAPITAL LETTER Z WITH DOT ABOVE
|
||||
|
||||
REMAP(0x00B0, 0xB0); // DEGREE SIGN
|
||||
REMAP(0x00B1, 0xB1); // PLUS-MINUS SIGN
|
||||
REMAP(0x02DB, 0xB2); // OGONEK
|
||||
REMAP(0x0142, 0xB3); // LATIN SMALL LETTER L WITH STROKE
|
||||
REMAP(0x00B4, 0xB4); // ACUTE ACCENT
|
||||
REMAP(0x00B5, 0xB5); // MICRO SIGN
|
||||
REMAP(0x00B6, 0xB6); // PILCROW SIGN
|
||||
REMAP(0x00B7, 0xB7); // MIDDLE DOT
|
||||
REMAP(0x00B8, 0xB8); // CEDILLA
|
||||
REMAP(0x0105, 0xB9); // LATIN SMALL LETTER A WITH OGONEK
|
||||
REMAP(0x015F, 0xBA); // LATIN SMALL LETTER S WITH CEDILLA
|
||||
REMAP(0x00BB, 0xBB); // RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
|
||||
REMAP(0x013D, 0xBC); // LATIN CAPITAL LETTER L WITH CARON
|
||||
REMAP(0x02DD, 0xBD); // DOUBLE ACUTE ACCENT
|
||||
REMAP(0x013E, 0xBE); // LATIN SMALL LETTER L WITH CARON
|
||||
REMAP(0x017C, 0xBF); // LATIN SMALL LETTER Z WITH DOT ABOVE
|
||||
|
||||
REMAP(0x0154, 0xC0); // LATIN CAPITAL LETTER R WITH ACUTE
|
||||
REMAP(0x00C1, 0xC1); // LATIN CAPITAL LETTER A WITH ACUTE
|
||||
REMAP(0x00C2, 0xC2); // LATIN CAPITAL LETTER A WITH CIRCUMFLEX
|
||||
REMAP(0x0102, 0xC3); // LATIN CAPITAL LETTER A WITH BREVE
|
||||
REMAP(0x00C4, 0xC4); // LATIN CAPITAL LETTER A WITH DIAERESIS
|
||||
REMAP(0x0139, 0xC5); // LATIN CAPITAL LETTER L WITH ACUTE
|
||||
REMAP(0x0106, 0xC6); // LATIN CAPITAL LETTER C WITH ACUTE
|
||||
REMAP(0x00C7, 0xC7); // LATIN CAPITAL LETTER C WITH CEDILLA
|
||||
REMAP(0x010C, 0xC8); // LATIN CAPITAL LETTER C WITH CARON
|
||||
REMAP(0x00C9, 0xC9); // LATIN CAPITAL LETTER E WITH ACUTE
|
||||
REMAP(0x0118, 0xCA); // LATIN CAPITAL LETTER E WITH OGONEK
|
||||
REMAP(0x00CB, 0xCB); // LATIN CAPITAL LETTER E WITH DIAERESIS
|
||||
REMAP(0x011A, 0xCC); // LATIN CAPITAL LETTER E WITH CARON
|
||||
REMAP(0x00CD, 0xCD); // LATIN CAPITAL LETTER I WITH ACUTE
|
||||
REMAP(0x00CE, 0xCE); // LATIN CAPITAL LETTER I WITH CIRCUMFLEX
|
||||
REMAP(0x010E, 0xCF); // LATIN CAPITAL LETTER D WITH CARON
|
||||
|
||||
REMAP(0x0110, 0xD0); // LATIN CAPITAL LETTER D WITH STROKE
|
||||
REMAP(0x0143, 0xD1); // LATIN CAPITAL LETTER N WITH ACUTE
|
||||
REMAP(0x0147, 0xD2); // LATIN CAPITAL LETTER N WITH CARON
|
||||
REMAP(0x00D3, 0xD3); // LATIN CAPITAL LETTER O WITH ACUTE
|
||||
REMAP(0x00D4, 0xD4); // LATIN CAPITAL LETTER O WITH CIRCUMFLEX
|
||||
REMAP(0x0150, 0xD5); // LATIN CAPITAL LETTER O WITH DOUBLE ACUTE
|
||||
REMAP(0x00D6, 0xD6); // LATIN CAPITAL LETTER O WITH DIAERESIS
|
||||
REMAP(0x00D7, 0xD7); // MULTIPLICATION SIGN
|
||||
REMAP(0x0158, 0xD8); // LATIN CAPITAL LETTER R WITH CARON
|
||||
REMAP(0x016E, 0xD9); // LATIN CAPITAL LETTER U WITH RING ABOVE
|
||||
REMAP(0x00DA, 0xDA); // LATIN CAPITAL LETTER U WITH ACUTE
|
||||
REMAP(0x0170, 0xDB); // LATIN CAPITAL LETTER U WITH DOUBLE ACUTE
|
||||
REMAP(0x00DC, 0xDC); // LATIN CAPITAL LETTER U WITH DIAERESIS
|
||||
REMAP(0x00DD, 0xDD); // LATIN CAPITAL LETTER Y WITH ACUTE
|
||||
REMAP(0x0162, 0xDE); // LATIN CAPITAL LETTER T WITH CEDILLA
|
||||
REMAP(0x00DF, 0xDF); // LATIN SMALL LETTER SHARP S
|
||||
|
||||
REMAP(0x0155, 0xE0); // LATIN SMALL LETTER R WITH ACUTE
|
||||
REMAP(0x00E1, 0xE1); // LATIN SMALL LETTER A WITH ACUTE
|
||||
REMAP(0x00E2, 0xE2); // LATIN SMALL LETTER A WITH CIRCUMFLEX
|
||||
REMAP(0x0103, 0xE3); // LATIN SMALL LETTER A WITH BREVE
|
||||
REMAP(0x00E4, 0xE4); // LATIN SMALL LETTER A WITH DIAERESIS
|
||||
REMAP(0x013A, 0xE5); // LATIN SMALL LETTER L WITH ACUTE
|
||||
REMAP(0x0107, 0xE6); // LATIN SMALL LETTER C WITH ACUTE
|
||||
REMAP(0x00E7, 0xE7); // LATIN SMALL LETTER C WITH CEDILLA
|
||||
REMAP(0x010D, 0xE8); // LATIN SMALL LETTER C WITH CARON
|
||||
REMAP(0x00E9, 0xE9); // LATIN SMALL LETTER E WITH ACUTE
|
||||
REMAP(0x0119, 0xEA); // LATIN SMALL LETTER E WITH OGONEK
|
||||
REMAP(0x00EB, 0xEB); // LATIN SMALL LETTER E WITH DIAERESIS
|
||||
REMAP(0x011B, 0xEC); // LATIN SMALL LETTER E WITH CARON
|
||||
REMAP(0x00ED, 0xED); // LATIN SMALL LETTER I WITH ACUTE
|
||||
REMAP(0x00EE, 0xEE); // LATIN SMALL LETTER I WITH CIRCUMFLEX
|
||||
REMAP(0x010F, 0xEF); // LATIN SMALL LETTER D WITH CARON
|
||||
|
||||
REMAP(0x0111, 0xF0); // LATIN SMALL LETTER D WITH STROKE
|
||||
REMAP(0x0144, 0xF1); // LATIN SMALL LETTER N WITH ACUTE
|
||||
REMAP(0x0148, 0xF2); // LATIN SMALL LETTER N WITH CARON
|
||||
REMAP(0x00F3, 0xF3); // LATIN SMALL LETTER O WITH ACUTE
|
||||
REMAP(0x00F4, 0xF4); // LATIN SMALL LETTER O WITH CIRCUMFLEX
|
||||
REMAP(0x0151, 0xF5); // LATIN SMALL LETTER O WITH DOUBLE ACUTE
|
||||
REMAP(0x00F6, 0xF6); // LATIN SMALL LETTER O WITH DIAERESIS
|
||||
REMAP(0x00F7, 0xF7); // DIVISION SIGN
|
||||
REMAP(0x0159, 0xF8); // LATIN SMALL LETTER R WITH CARON
|
||||
REMAP(0x016F, 0xF9); // LATIN SMALL LETTER U WITH RING ABOVE
|
||||
REMAP(0x00FA, 0xFA); // LATIN SMALL LETTER U WITH ACUTE
|
||||
REMAP(0x0171, 0xFB); // LATIN SMALL LETTER U WITH DOUBLE ACUTE
|
||||
REMAP(0x00FC, 0xFC); // LATIN SMALL LETTER U WITH DIAERESIS
|
||||
REMAP(0x00FD, 0xFD); // LATIN SMALL LETTER Y WITH ACUTE
|
||||
REMAP(0x0163, 0xFE); // LATIN SMALL LETTER T WITH CEDILLA
|
||||
REMAP(0x02D9, 0xFF); // DOT ABOVE
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Apply a set of substitutions which remap UTF8 for a Windows-1251 font
|
||||
// Windows-1251 is an 8-bit character encoding, suitable for several languages which use the Cyrillic script
|
||||
void InkHUD::AppletFont::addSubstitutionsWin1251()
|
||||
{
|
||||
addSubstitution("Ђ", "\x80");
|
||||
addSubstitution("Ѓ", "\x81");
|
||||
addSubstitution("ѓ", "\x83");
|
||||
addSubstitution("€", "\x88");
|
||||
addSubstitution("Љ", "\x8A");
|
||||
addSubstitution("Њ", "\x8C");
|
||||
addSubstitution("Ќ", "\x8D");
|
||||
addSubstitution("Ћ", "\x8E");
|
||||
addSubstitution("Џ", "\x8F");
|
||||
// Latin - Cyrillic
|
||||
// https://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1251.TXT
|
||||
else if (encoding == WINDOWS_1251) {
|
||||
// 1-Byte chars: no remapping
|
||||
if (utf8.length() == 1)
|
||||
return utf8.at(0);
|
||||
|
||||
addSubstitution("ђ", "\x90");
|
||||
addSubstitution("љ", "\x9A");
|
||||
addSubstitution("њ", "\x9C");
|
||||
addSubstitution("ќ", "\x9D");
|
||||
addSubstitution("ћ", "\x9E");
|
||||
addSubstitution("џ", "\x9F");
|
||||
// Multi-byte chars:
|
||||
switch (toUtf32(utf8)) {
|
||||
REMAP(0x0402, 0x80); // CYRILLIC CAPITAL LETTER DJE
|
||||
REMAP(0x0403, 0x81); // CYRILLIC CAPITAL LETTER GJE
|
||||
REMAP(0x201A, 0x82); // SINGLE LOW-9 QUOTATION MARK
|
||||
REMAP(0x0453, 0x83); // CYRILLIC SMALL LETTER GJE
|
||||
REMAP(0x201E, 0x84); // DOUBLE LOW-9 QUOTATION MARK
|
||||
REMAP(0x2026, 0x85); // HORIZONTAL ELLIPSIS
|
||||
REMAP(0x2020, 0x86); // DAGGER
|
||||
REMAP(0x2021, 0x87); // DOUBLE DAGGER
|
||||
REMAP(0x20AC, 0x88); // EURO SIGN
|
||||
REMAP(0x2030, 0x89); // PER MILLE SIGN
|
||||
REMAP(0x0409, 0x8A); // CYRILLIC CAPITAL LETTER LJE
|
||||
REMAP(0x2039, 0x8B); // SINGLE LEFT-POINTING ANGLE QUOTATION MARK
|
||||
REMAP(0x040A, 0x8C); // CYRILLIC CAPITAL LETTER NJE
|
||||
REMAP(0x040C, 0x8D); // CYRILLIC CAPITAL LETTER KJE
|
||||
REMAP(0x040B, 0x8E); // CYRILLIC CAPITAL LETTER TSHE
|
||||
REMAP(0x040F, 0x8F); // CYRILLIC CAPITAL LETTER DZHE
|
||||
|
||||
addSubstitution("Ў", "\xA1");
|
||||
addSubstitution("ў", "\xA2");
|
||||
addSubstitution("Ј", "\xA3");
|
||||
addSubstitution("Ґ", "\xA5");
|
||||
addSubstitution("Ё", "\xA8");
|
||||
addSubstitution("Є", "\xAA");
|
||||
addSubstitution("Ї", "\xAF");
|
||||
REMAP(0x0452, 0x90); // CYRILLIC SMALL LETTER DJE
|
||||
REMAP(0x2018, 0x91); // LEFT SINGLE QUOTATION MARK
|
||||
REMAP(0x2019, 0x92); // RIGHT SINGLE QUOTATION MARK
|
||||
REMAP(0x201C, 0x93); // LEFT DOUBLE QUOTATION MARK
|
||||
REMAP(0x201D, 0x94); // RIGHT DOUBLE QUOTATION MARK
|
||||
REMAP(0x2022, 0x95); // BULLET
|
||||
REMAP(0x2013, 0x96); // EN DASH
|
||||
REMAP(0x2014, 0x97); // EM DASH
|
||||
REMAP(0x2122, 0x99); // TRADE MARK SIGN
|
||||
REMAP(0x0459, 0x9A); // CYRILLIC SMALL LETTER LJE
|
||||
REMAP(0x203A, 0x9B); // SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
|
||||
REMAP(0x045A, 0x9C); // CYRILLIC SMALL LETTER NJE
|
||||
REMAP(0x045C, 0x9D); // CYRILLIC SMALL LETTER KJE
|
||||
REMAP(0x045B, 0x9E); // CYRILLIC SMALL LETTER TSHE
|
||||
REMAP(0x045F, 0x9F); // CYRILLIC SMALL LETTER DZHE
|
||||
|
||||
addSubstitution("І", "\xB2");
|
||||
addSubstitution("і", "\xB3");
|
||||
addSubstitution("ґ", "\xB4");
|
||||
addSubstitution("ё", "\xB8");
|
||||
addSubstitution("№", "\xB9");
|
||||
addSubstitution("є", "\xBA");
|
||||
addSubstitution("ј", "\xBC");
|
||||
addSubstitution("Ѕ", "\xBD");
|
||||
addSubstitution("ѕ", "\xBE");
|
||||
addSubstitution("ї", "\xBF");
|
||||
REMAP(0x00A0, 0xA0); // NO-BREAK SPACE
|
||||
REMAP(0x040E, 0xA1); // CYRILLIC CAPITAL LETTER SHORT U
|
||||
REMAP(0x045E, 0xA2); // CYRILLIC SMALL LETTER SHORT U
|
||||
REMAP(0x0408, 0xA3); // CYRILLIC CAPITAL LETTER JE
|
||||
REMAP(0x00A4, 0xA4); // CURRENCY SIGN
|
||||
REMAP(0x0490, 0xA5); // CYRILLIC CAPITAL LETTER GHE WITH UPTURN
|
||||
REMAP(0x00A6, 0xA6); // BROKEN BAR
|
||||
REMAP(0x00A7, 0xA7); // SECTION SIGN
|
||||
REMAP(0x0401, 0xA8); // CYRILLIC CAPITAL LETTER IO
|
||||
REMAP(0x00A9, 0xA9); // COPYRIGHT SIGN
|
||||
REMAP(0x0404, 0xAA); // CYRILLIC CAPITAL LETTER UKRAINIAN IE
|
||||
REMAP(0x00AB, 0xAB); // LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
|
||||
REMAP(0x00AC, 0xAC); // NOT SIGN
|
||||
REMAP(0x00AD, 0xAD); // SOFT HYPHEN
|
||||
REMAP(0x00AE, 0xAE); // REGISTERED SIGN
|
||||
REMAP(0x0407, 0xAF); // CYRILLIC CAPITAL LETTER YI
|
||||
|
||||
addSubstitution("А", "\xC0");
|
||||
addSubstitution("Б", "\xC1");
|
||||
addSubstitution("В", "\xC2");
|
||||
addSubstitution("Г", "\xC3");
|
||||
addSubstitution("Д", "\xC4");
|
||||
addSubstitution("Е", "\xC5");
|
||||
addSubstitution("Ж", "\xC6");
|
||||
addSubstitution("З", "\xC7");
|
||||
addSubstitution("И", "\xC8");
|
||||
addSubstitution("Й", "\xC9");
|
||||
addSubstitution("К", "\xCA");
|
||||
addSubstitution("Л", "\xCB");
|
||||
addSubstitution("М", "\xCC");
|
||||
addSubstitution("Н", "\xCD");
|
||||
addSubstitution("О", "\xCE");
|
||||
addSubstitution("П", "\xCF");
|
||||
REMAP(0x00B0, 0xB0); // DEGREE SIGN
|
||||
REMAP(0x00B1, 0xB1); // PLUS-MINUS SIGN
|
||||
REMAP(0x0406, 0xB2); // CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I
|
||||
REMAP(0x0456, 0xB3); // CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I
|
||||
REMAP(0x0491, 0xB4); // CYRILLIC SMALL LETTER GHE WITH UPTURN
|
||||
REMAP(0x00B5, 0xB5); // MICRO SIGN
|
||||
REMAP(0x00B6, 0xB6); // PILCROW SIGN
|
||||
REMAP(0x00B7, 0xB7); // MIDDLE DOT
|
||||
REMAP(0x0451, 0xB8); // CYRILLIC SMALL LETTER IO
|
||||
REMAP(0x2116, 0xB9); // NUMERO SIGN
|
||||
REMAP(0x0454, 0xBA); // CYRILLIC SMALL LETTER UKRAINIAN IE
|
||||
REMAP(0x00BB, 0xBB); // RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
|
||||
REMAP(0x0458, 0xBC); // CYRILLIC SMALL LETTER JE
|
||||
REMAP(0x0405, 0xBD); // CYRILLIC CAPITAL LETTER DZE
|
||||
REMAP(0x0455, 0xBE); // CYRILLIC SMALL LETTER DZE
|
||||
REMAP(0x0457, 0xBF); // CYRILLIC SMALL LETTER YI
|
||||
|
||||
addSubstitution("Р", "\xD0");
|
||||
addSubstitution("С", "\xD1");
|
||||
addSubstitution("Т", "\xD2");
|
||||
addSubstitution("У", "\xD3");
|
||||
addSubstitution("Ф", "\xD4");
|
||||
addSubstitution("Х", "\xD5");
|
||||
addSubstitution("Ц", "\xD6");
|
||||
addSubstitution("Ч", "\xD7");
|
||||
addSubstitution("Ш", "\xD8");
|
||||
addSubstitution("Щ", "\xD9");
|
||||
addSubstitution("Ъ", "\xDA");
|
||||
addSubstitution("Ы", "\xDB");
|
||||
addSubstitution("Ь", "\xDC");
|
||||
addSubstitution("Э", "\xDD");
|
||||
addSubstitution("Ю", "\xDE");
|
||||
addSubstitution("Я", "\xDF");
|
||||
REMAP(0x0410, 0xC0); // CYRILLIC CAPITAL LETTER A
|
||||
REMAP(0x0411, 0xC1); // CYRILLIC CAPITAL LETTER BE
|
||||
REMAP(0x0412, 0xC2); // CYRILLIC CAPITAL LETTER VE
|
||||
REMAP(0x0413, 0xC3); // CYRILLIC CAPITAL LETTER GHE
|
||||
REMAP(0x0414, 0xC4); // CYRILLIC CAPITAL LETTER DE
|
||||
REMAP(0x0415, 0xC5); // CYRILLIC CAPITAL LETTER IE
|
||||
REMAP(0x0416, 0xC6); // CYRILLIC CAPITAL LETTER ZHE
|
||||
REMAP(0x0417, 0xC7); // CYRILLIC CAPITAL LETTER ZE
|
||||
REMAP(0x0418, 0xC8); // CYRILLIC CAPITAL LETTER I
|
||||
REMAP(0x0419, 0xC9); // CYRILLIC CAPITAL LETTER SHORT I
|
||||
REMAP(0x041A, 0xCA); // CYRILLIC CAPITAL LETTER KA
|
||||
REMAP(0x041B, 0xCB); // CYRILLIC CAPITAL LETTER EL
|
||||
REMAP(0x041C, 0xCC); // CYRILLIC CAPITAL LETTER EM
|
||||
REMAP(0x041D, 0xCD); // CYRILLIC CAPITAL LETTER EN
|
||||
REMAP(0x041E, 0xCE); // CYRILLIC CAPITAL LETTER O
|
||||
REMAP(0x041F, 0xCF); // CYRILLIC CAPITAL LETTER PE
|
||||
|
||||
addSubstitution("а", "\xE0");
|
||||
addSubstitution("б", "\xE1");
|
||||
addSubstitution("в", "\xE2");
|
||||
addSubstitution("г", "\xE3");
|
||||
addSubstitution("д", "\xE4");
|
||||
addSubstitution("е", "\xE5");
|
||||
addSubstitution("ж", "\xE6");
|
||||
addSubstitution("з", "\xE7");
|
||||
addSubstitution("и", "\xE8");
|
||||
addSubstitution("й", "\xE9");
|
||||
addSubstitution("к", "\xEA");
|
||||
addSubstitution("л", "\xEB");
|
||||
addSubstitution("м", "\xEC");
|
||||
addSubstitution("н", "\xED");
|
||||
addSubstitution("о", "\xEE");
|
||||
addSubstitution("п", "\xEF");
|
||||
REMAP(0x0420, 0xD0); // CYRILLIC CAPITAL LETTER ER
|
||||
REMAP(0x0421, 0xD1); // CYRILLIC CAPITAL LETTER ES
|
||||
REMAP(0x0422, 0xD2); // CYRILLIC CAPITAL LETTER TE
|
||||
REMAP(0x0423, 0xD3); // CYRILLIC CAPITAL LETTER U
|
||||
REMAP(0x0424, 0xD4); // CYRILLIC CAPITAL LETTER EF
|
||||
REMAP(0x0425, 0xD5); // CYRILLIC CAPITAL LETTER HA
|
||||
REMAP(0x0426, 0xD6); // CYRILLIC CAPITAL LETTER TSE
|
||||
REMAP(0x0427, 0xD7); // CYRILLIC CAPITAL LETTER CHE
|
||||
REMAP(0x0428, 0xD8); // CYRILLIC CAPITAL LETTER SHA
|
||||
REMAP(0x0429, 0xD9); // CYRILLIC CAPITAL LETTER SHCHA
|
||||
REMAP(0x042A, 0xDA); // CYRILLIC CAPITAL LETTER HARD SIGN
|
||||
REMAP(0x042B, 0xDB); // CYRILLIC CAPITAL LETTER YERU
|
||||
REMAP(0x042C, 0xDC); // CYRILLIC CAPITAL LETTER SOFT SIGN
|
||||
REMAP(0x042D, 0xDD); // CYRILLIC CAPITAL LETTER E
|
||||
REMAP(0x042E, 0xDE); // CYRILLIC CAPITAL LETTER YU
|
||||
REMAP(0x042F, 0xDF); // CYRILLIC CAPITAL LETTER YA
|
||||
|
||||
addSubstitution("р", "\xF0");
|
||||
addSubstitution("с", "\xF1");
|
||||
addSubstitution("т", "\xF2");
|
||||
addSubstitution("у", "\xF3");
|
||||
addSubstitution("ф", "\xF4");
|
||||
addSubstitution("х", "\xF5");
|
||||
addSubstitution("ц", "\xF6");
|
||||
addSubstitution("ч", "\xF7");
|
||||
addSubstitution("ш", "\xF8");
|
||||
addSubstitution("щ", "\xF9");
|
||||
addSubstitution("ъ", "\xFA");
|
||||
addSubstitution("ы", "\xFB");
|
||||
addSubstitution("ь", "\xFC");
|
||||
addSubstitution("э", "\xFD");
|
||||
addSubstitution("ю", "\xFE");
|
||||
addSubstitution("я", "\xFF");
|
||||
REMAP(0x0430, 0xE0); // CYRILLIC SMALL LETTER A
|
||||
REMAP(0x0431, 0xE1); // CYRILLIC SMALL LETTER BE
|
||||
REMAP(0x0432, 0xE2); // CYRILLIC SMALL LETTER VE
|
||||
REMAP(0x0433, 0xE3); // CYRILLIC SMALL LETTER GHE
|
||||
REMAP(0x0434, 0xE4); // CYRILLIC SMALL LETTER DE
|
||||
REMAP(0x0435, 0xE5); // CYRILLIC SMALL LETTER IE
|
||||
REMAP(0x0436, 0xE6); // CYRILLIC SMALL LETTER ZHE
|
||||
REMAP(0x0437, 0xE7); // CYRILLIC SMALL LETTER ZE
|
||||
REMAP(0x0438, 0xE8); // CYRILLIC SMALL LETTER I
|
||||
REMAP(0x0439, 0xE9); // CYRILLIC SMALL LETTER SHORT I
|
||||
REMAP(0x043A, 0xEA); // CYRILLIC SMALL LETTER KA
|
||||
REMAP(0x043B, 0xEB); // CYRILLIC SMALL LETTER EL
|
||||
REMAP(0x043C, 0xEC); // CYRILLIC SMALL LETTER EM
|
||||
REMAP(0x043D, 0xED); // CYRILLIC SMALL LETTER EN
|
||||
REMAP(0x043E, 0xEE); // CYRILLIC SMALL LETTER O
|
||||
REMAP(0x043F, 0xEF); // CYRILLIC SMALL LETTER PE
|
||||
|
||||
REMAP(0x0440, 0xF0); // CYRILLIC SMALL LETTER ER
|
||||
REMAP(0x0441, 0xF1); // CYRILLIC SMALL LETTER ES
|
||||
REMAP(0x0442, 0xF2); // CYRILLIC SMALL LETTER TE
|
||||
REMAP(0x0443, 0xF3); // CYRILLIC SMALL LETTER U
|
||||
REMAP(0x0444, 0xF4); // CYRILLIC SMALL LETTER EF
|
||||
REMAP(0x0445, 0xF5); // CYRILLIC SMALL LETTER HA
|
||||
REMAP(0x0446, 0xF6); // CYRILLIC SMALL LETTER TSE
|
||||
REMAP(0x0447, 0xF7); // CYRILLIC SMALL LETTER CHE
|
||||
REMAP(0x0448, 0xF8); // CYRILLIC SMALL LETTER SHA
|
||||
REMAP(0x0449, 0xF9); // CYRILLIC SMALL LETTER SHCHA
|
||||
REMAP(0x044A, 0xFA); // CYRILLIC SMALL LETTER HARD SIGN
|
||||
REMAP(0x044B, 0xFB); // CYRILLIC SMALL LETTER YERU
|
||||
REMAP(0x044C, 0xFC); // CYRILLIC SMALL LETTER SOFT SIGN
|
||||
REMAP(0x044D, 0xFD); // CYRILLIC SMALL LETTER E
|
||||
REMAP(0x044E, 0xFE); // CYRILLIC SMALL LETTER YU
|
||||
REMAP(0x044F, 0xFF); // CYRILLIC SMALL LETTER YA
|
||||
}
|
||||
}
|
||||
|
||||
// Latin - Western Europe
|
||||
// https://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP1252.TXT
|
||||
else if (encoding == WINDOWS_1252) {
|
||||
// 1-Byte chars: no remapping
|
||||
if (utf8.length() == 1)
|
||||
return utf8.at(0);
|
||||
|
||||
// Multi-byte chars:
|
||||
switch (toUtf32(utf8)) {
|
||||
REMAP(0x20AC, 0x80) // EURO SIGN
|
||||
REMAP(0x201A, 0x82) // SINGLE LOW-9 QUOTATION MARK
|
||||
REMAP(0x0192, 0x83) // LATIN SMALL LETTER F WITH HOOK
|
||||
REMAP(0x201E, 0x84) // DOUBLE LOW-9 QUOTATION MARK
|
||||
REMAP(0x2026, 0x85) // HORIZONTAL ELLIPSIS
|
||||
REMAP(0x2020, 0x86) // DAGGER
|
||||
REMAP(0x2021, 0x87) // DOUBLE DAGGER
|
||||
REMAP(0x02C6, 0x88) // MODIFIER LETTER CIRCUMFLEX ACCENT
|
||||
REMAP(0x2030, 0x89) // PER MILLE SIGN
|
||||
REMAP(0x0160, 0x8A) // LATIN CAPITAL LETTER S WITH CARON
|
||||
REMAP(0x2039, 0x8B) // SINGLE LEFT-POINTING ANGLE QUOTATION MARK
|
||||
REMAP(0x0152, 0x8C) // LATIN CAPITAL LIGATURE OE
|
||||
REMAP(0x017D, 0x8E) // LATIN CAPITAL LETTER Z WITH CARON
|
||||
|
||||
REMAP(0x2018, 0x91) // LEFT SINGLE QUOTATION MARK
|
||||
REMAP(0x2019, 0x92) // RIGHT SINGLE QUOTATION MARK
|
||||
REMAP(0x201C, 0x93) // LEFT DOUBLE QUOTATION MARK
|
||||
REMAP(0x201D, 0x94) // RIGHT DOUBLE QUOTATION MARK
|
||||
REMAP(0x2022, 0x95) // BULLET
|
||||
REMAP(0x2013, 0x96) // EN DASH
|
||||
REMAP(0x2014, 0x97) // EM DASH
|
||||
REMAP(0x02DC, 0x98) // SMALL TILDE
|
||||
REMAP(0x2122, 0x99) // TRADE MARK SIGN
|
||||
REMAP(0x0161, 0x9A) // LATIN SMALL LETTER S WITH CARON
|
||||
REMAP(0x203A, 0x9B) // SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
|
||||
REMAP(0x0153, 0x9C) // LATIN SMALL LIGATURE OE
|
||||
REMAP(0x017E, 0x9E) // LATIN SMALL LETTER Z WITH CARON
|
||||
REMAP(0x0178, 0x9F) // LATIN CAPITAL LETTER Y WITH DIAERESIS
|
||||
|
||||
REMAP(0x00A0, 0xA0) // NO-BREAK SPACE
|
||||
REMAP(0x00A1, 0xA1) // INVERTED EXCLAMATION MARK
|
||||
REMAP(0x00A2, 0xA2) // CENT SIGN
|
||||
REMAP(0x00A3, 0xA3) // POUND SIGN
|
||||
REMAP(0x00A4, 0xA4) // CURRENCY SIGN
|
||||
REMAP(0x00A5, 0xA5) // YEN SIGN
|
||||
REMAP(0x00A6, 0xA6) // BROKEN BAR
|
||||
REMAP(0x00A7, 0xA7) // SECTION SIGN
|
||||
REMAP(0x00A8, 0xA8) // DIAERESIS
|
||||
REMAP(0x00A9, 0xA9) // COPYRIGHT SIGN
|
||||
REMAP(0x00AA, 0xAA) // FEMININE ORDINAL INDICATOR
|
||||
REMAP(0x00AB, 0xAB) // LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
|
||||
REMAP(0x00AC, 0xAC) // NOT SIGN
|
||||
REMAP(0x00AD, 0xAD) // SOFT HYPHEN
|
||||
REMAP(0x00AE, 0xAE) // REGISTERED SIGN
|
||||
REMAP(0x00AF, 0xAF) // MACRON
|
||||
|
||||
REMAP(0x00B0, 0xB0) // DEGREE SIGN
|
||||
REMAP(0x00B1, 0xB1) // PLUS-MINUS SIGN
|
||||
REMAP(0x00B2, 0xB2) // SUPERSCRIPT TWO
|
||||
REMAP(0x00B3, 0xB3) // SUPERSCRIPT THREE
|
||||
REMAP(0x00B4, 0xB4) // ACUTE ACCENT
|
||||
REMAP(0x00B5, 0xB5) // MICRO SIGN
|
||||
REMAP(0x00B6, 0xB6) // PILCROW SIGN
|
||||
REMAP(0x00B7, 0xB7) // MIDDLE DOT
|
||||
REMAP(0x00B8, 0xB8) // CEDILLA
|
||||
REMAP(0x00B9, 0xB9) // SUPERSCRIPT ONE
|
||||
REMAP(0x00BA, 0xBA) // MASCULINE ORDINAL INDICATOR
|
||||
REMAP(0x00BB, 0xBB) // RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
|
||||
REMAP(0x00BC, 0xBC) // VULGAR FRACTION ONE QUARTER
|
||||
REMAP(0x00BD, 0xBD) // VULGAR FRACTION ONE HALF
|
||||
REMAP(0x00BE, 0xBE) // VULGAR FRACTION THREE QUARTERS
|
||||
REMAP(0x00BF, 0xBF) // INVERTED QUESTION MARK
|
||||
|
||||
REMAP(0x00C0, 0xC0) // LATIN CAPITAL LETTER A WITH GRAVE
|
||||
REMAP(0x00C1, 0xC1) // LATIN CAPITAL LETTER A WITH ACUTE
|
||||
REMAP(0x00C2, 0xC2) // LATIN CAPITAL LETTER A WITH CIRCUMFLEX
|
||||
REMAP(0x00C3, 0xC3) // LATIN CAPITAL LETTER A WITH TILDE
|
||||
REMAP(0x00C4, 0xC4) // LATIN CAPITAL LETTER A WITH DIAERESIS
|
||||
REMAP(0x00C5, 0xC5) // LATIN CAPITAL LETTER A WITH RING ABOVE
|
||||
REMAP(0x00C6, 0xC6) // LATIN CAPITAL LETTER AE
|
||||
REMAP(0x00C7, 0xC7) // LATIN CAPITAL LETTER C WITH CEDILLA
|
||||
REMAP(0x00C8, 0xC8) // LATIN CAPITAL LETTER E WITH GRAVE
|
||||
REMAP(0x00C9, 0xC9) // LATIN CAPITAL LETTER E WITH ACUTE
|
||||
REMAP(0x00CA, 0xCA) // LATIN CAPITAL LETTER E WITH CIRCUMFLEX
|
||||
REMAP(0x00CB, 0xCB) // LATIN CAPITAL LETTER E WITH DIAERESIS
|
||||
REMAP(0x00CC, 0xCC) // LATIN CAPITAL LETTER I WITH GRAVE
|
||||
REMAP(0x00CD, 0xCD) // LATIN CAPITAL LETTER I WITH ACUTE
|
||||
REMAP(0x00CE, 0xCE) // LATIN CAPITAL LETTER I WITH CIRCUMFLEX
|
||||
REMAP(0x00CF, 0xCF) // LATIN CAPITAL LETTER I WITH DIAERESIS
|
||||
|
||||
REMAP(0x00D0, 0xD0) // LATIN CAPITAL LETTER ETH
|
||||
REMAP(0x00D1, 0xD1) // LATIN CAPITAL LETTER N WITH TILDE
|
||||
REMAP(0x00D2, 0xD2) // LATIN CAPITAL LETTER O WITH GRAVE
|
||||
REMAP(0x00D3, 0xD3) // LATIN CAPITAL LETTER O WITH ACUTE
|
||||
REMAP(0x00D4, 0xD4) // LATIN CAPITAL LETTER O WITH CIRCUMFLEX
|
||||
REMAP(0x00D5, 0xD5) // LATIN CAPITAL LETTER O WITH TILDE
|
||||
REMAP(0x00D6, 0xD6) // LATIN CAPITAL LETTER O WITH DIAERESIS
|
||||
REMAP(0x00D7, 0xD7) // MULTIPLICATION SIGN
|
||||
REMAP(0x00D8, 0xD8) // LATIN CAPITAL LETTER O WITH STROKE
|
||||
REMAP(0x00D9, 0xD9) // LATIN CAPITAL LETTER U WITH GRAVE
|
||||
REMAP(0x00DA, 0xDA) // LATIN CAPITAL LETTER U WITH ACUTE
|
||||
REMAP(0x00DB, 0xDB) // LATIN CAPITAL LETTER U WITH CIRCUMFLEX
|
||||
REMAP(0x00DC, 0xDC) // LATIN CAPITAL LETTER U WITH DIAERESIS
|
||||
REMAP(0x00DD, 0xDD) // LATIN CAPITAL LETTER Y WITH ACUTE
|
||||
REMAP(0x00DE, 0xDE) // LATIN CAPITAL LETTER THORN
|
||||
REMAP(0x00DF, 0xDF) // LATIN SMALL LETTER SHARP S
|
||||
|
||||
REMAP(0x00E0, 0xE0) // LATIN SMALL LETTER A WITH GRAVE
|
||||
REMAP(0x00E1, 0xE1) // LATIN SMALL LETTER A WITH ACUTE
|
||||
REMAP(0x00E2, 0xE2) // LATIN SMALL LETTER A WITH CIRCUMFLEX
|
||||
REMAP(0x00E3, 0xE3) // LATIN SMALL LETTER A WITH TILDE
|
||||
REMAP(0x00E4, 0xE4) // LATIN SMALL LETTER A WITH DIAERESIS
|
||||
REMAP(0x00E5, 0xE5) // LATIN SMALL LETTER A WITH RING ABOVE
|
||||
REMAP(0x00E6, 0xE6) // LATIN SMALL LETTER AE
|
||||
REMAP(0x00E7, 0xE7) // LATIN SMALL LETTER C WITH CEDILLA
|
||||
REMAP(0x00E8, 0xE8) // LATIN SMALL LETTER E WITH GRAVE
|
||||
REMAP(0x00E9, 0xE9) // LATIN SMALL LETTER E WITH ACUTE
|
||||
REMAP(0x00EA, 0xEA) // LATIN SMALL LETTER E WITH CIRCUMFLEX
|
||||
REMAP(0x00EB, 0xEB) // LATIN SMALL LETTER E WITH DIAERESIS
|
||||
REMAP(0x00EC, 0xEC) // LATIN SMALL LETTER I WITH GRAVE
|
||||
REMAP(0x00ED, 0xED) // LATIN SMALL LETTER I WITH ACUTE
|
||||
REMAP(0x00EE, 0xEE) // LATIN SMALL LETTER I WITH CIRCUMFLEX
|
||||
REMAP(0x00EF, 0xEF) // LATIN SMALL LETTER I WITH DIAERESIS
|
||||
|
||||
REMAP(0x00F0, 0xF0) // LATIN SMALL LETTER ETH
|
||||
REMAP(0x00F1, 0xF1) // LATIN SMALL LETTER N WITH TILDE
|
||||
REMAP(0x00F2, 0xF2) // LATIN SMALL LETTER O WITH GRAVE
|
||||
REMAP(0x00F3, 0xF3) // LATIN SMALL LETTER O WITH ACUTE
|
||||
REMAP(0x00F4, 0xF4) // LATIN SMALL LETTER O WITH CIRCUMFLEX
|
||||
REMAP(0x00F5, 0xF5) // LATIN SMALL LETTER O WITH TILDE
|
||||
REMAP(0x00F6, 0xF6) // LATIN SMALL LETTER O WITH DIAERESIS
|
||||
REMAP(0x00F7, 0xF7) // DIVISION SIGN
|
||||
REMAP(0x00F8, 0xF8) // LATIN SMALL LETTER O WITH STROKE
|
||||
REMAP(0x00F9, 0xF9) // LATIN SMALL LETTER U WITH GRAVE
|
||||
REMAP(0x00FA, 0xFA) // LATIN SMALL LETTER U WITH ACUTE
|
||||
REMAP(0x00FB, 0xFB) // LATIN SMALL LETTER U WITH CIRCUMFLEX
|
||||
REMAP(0x00FC, 0xFC) // LATIN SMALL LETTER U WITH DIAERESIS
|
||||
REMAP(0x00FD, 0xFD) // LATIN SMALL LETTER Y WITH ACUTE
|
||||
REMAP(0x00FE, 0xFE) // LATIN SMALL LETTER THORN
|
||||
REMAP(0x00FF, 0xFF) // LATIN SMALL LETTER Y WITH DIAERESIS
|
||||
}
|
||||
}
|
||||
|
||||
// If not handled, return DEL
|
||||
// Todo: swap this to SUB, and modify the fonts
|
||||
return '\x7F';
|
||||
|
||||
// Sweep up the syntactic sugar
|
||||
// Don't want ants in the house
|
||||
#undef REMAP
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -4,10 +4,7 @@
|
||||
|
||||
Wrapper class for an AdafruitGFX font
|
||||
Pre-calculates some font dimension info which InkHUD uses repeatedly
|
||||
|
||||
Also contains an optional set of "substitutions".
|
||||
These can be used to detect special UTF8 chars, and replace occurrences with a remapped char val to suit a custom font
|
||||
These can also be used to swap UTF8 chars for a suitable ASCII substitution (e.g. German ö -> oe, etc)
|
||||
Re-encodes UTF-8 characters to suit extended ASCII AdafruitGFX fonts
|
||||
|
||||
*/
|
||||
|
||||
@@ -24,36 +21,61 @@ namespace NicheGraphics::InkHUD
|
||||
class AppletFont
|
||||
{
|
||||
public:
|
||||
enum Encoding {
|
||||
ASCII,
|
||||
WINDOWS_1250,
|
||||
WINDOWS_1251,
|
||||
WINDOWS_1252,
|
||||
};
|
||||
|
||||
AppletFont();
|
||||
explicit AppletFont(const GFXfont &adafruitGFXFont);
|
||||
AppletFont(const GFXfont &adafruitGFXFont, Encoding encoding = ASCII, int8_t paddingTop = 0, int8_t paddingBottom = 0);
|
||||
|
||||
uint8_t lineHeight();
|
||||
uint8_t heightAboveCursor();
|
||||
uint8_t heightBelowCursor();
|
||||
uint8_t widthBetweenWords(); // Width of the space character
|
||||
|
||||
void applySubstitutions(std::string *text); // Run all char-substitution operations, prior to printing
|
||||
void addSubstitution(const char *from, const char *to); // Register a find-replace action, for remapping UTF8 chars
|
||||
void addSubstitutionsWin1251(); // Cyrillic fonts: remap UTF8 values to their Win-1251 equivalent
|
||||
// Todo: Polish font
|
||||
std::string decodeUTF8(std::string encoded);
|
||||
|
||||
const GFXfont *gfxFont = NULL; // Default value: in-built AdafruitGFX font
|
||||
|
||||
private:
|
||||
uint32_t toUtf32(std::string utf8);
|
||||
char applyEncoding(std::string utf8);
|
||||
|
||||
uint8_t height = 8; // Default value: in-built AdafruitGFX font
|
||||
uint8_t ascenderHeight = 0; // Default value: in-built AdafruitGFX font
|
||||
uint8_t descenderHeight = 8; // Default value: in-built AdafruitGFX font
|
||||
uint8_t spaceCharWidth = 8; // Default value: in-built AdafruitGFX font
|
||||
|
||||
// One pair of find-replace values, for substituting or remapping UTF8 chars
|
||||
struct Substitution {
|
||||
const char *from;
|
||||
const char *to;
|
||||
};
|
||||
|
||||
std::vector<Substitution> substitutions; // List of all character substitutions to run, prior to printing a string
|
||||
Encoding encoding = ASCII;
|
||||
};
|
||||
|
||||
} // namespace NicheGraphics::InkHUD
|
||||
|
||||
// Macros for InkHUD's standard fonts
|
||||
// --------------------------------------
|
||||
|
||||
// Use these once only, passing them to InkHUD::Applet::fontLarge and InkHUD::Applet:fontSmall
|
||||
// Line padding has been adjusted manually, to compensate for a few *extra tall* diacritics
|
||||
|
||||
// Central European
|
||||
#include "graphics/niche/Fonts/FreeSans6pt_Win1250.h"
|
||||
#include "graphics/niche/Fonts/FreeSans9pt_Win1250.h"
|
||||
#define FREESANS_9PT_WIN1250 InkHUD::AppletFont(FreeSans9pt_Win1250, InkHUD::AppletFont::WINDOWS_1250, -1, -1)
|
||||
#define FREESANS_6PT_WIN1250 InkHUD::AppletFont(FreeSans6pt_Win1250, InkHUD::AppletFont::WINDOWS_1250, -1, -2)
|
||||
|
||||
// Cyrillic
|
||||
#include "graphics/niche/Fonts/FreeSans6pt_Win1251.h"
|
||||
#include "graphics/niche/Fonts/FreeSans9pt_Win1251.h"
|
||||
#define FREESANS_9PT_WIN1251 InkHUD::AppletFont(FreeSans9pt_Win1251, InkHUD::AppletFont::WINDOWS_1251, -2, -1)
|
||||
#define FREESANS_6PT_WIN1251 InkHUD::AppletFont(FreeSans6pt_Win1251, InkHUD::AppletFont::WINDOWS_1251, -1, -2)
|
||||
|
||||
// Western European
|
||||
#include "graphics/niche/Fonts/FreeSans6pt_Win1252.h"
|
||||
#include "graphics/niche/Fonts/FreeSans9pt_Win1252.h"
|
||||
#define FREESANS_9PT_WIN1252 InkHUD::AppletFont(FreeSans9pt_Win1252, InkHUD::AppletFont::WINDOWS_1252, -2, -1)
|
||||
#define FREESANS_6PT_WIN1252 InkHUD::AppletFont(FreeSans6pt_Win1252, InkHUD::AppletFont::WINDOWS_1252, -1, -2)
|
||||
|
||||
#endif
|
||||
@@ -286,6 +286,10 @@ void InkHUD::MapApplet::drawLabeledMarker(meshtastic_NodeInfoLite *node)
|
||||
bool isOurNode = node->num == nodeDB->getNodeNum();
|
||||
bool unknownHops = !node->has_hops_away && !isOurNode;
|
||||
|
||||
// Parse any non-ascii chars in the short name,
|
||||
// and use last 4 instead if unknown / can't render
|
||||
std::string shortName = parseShortName(node);
|
||||
|
||||
// We will draw a left or right hand variant, to place text towards screen center
|
||||
// Hopefully avoid text spilling off screen
|
||||
// Most values are the same, regardless of left-right handedness
|
||||
@@ -299,7 +303,7 @@ void InkHUD::MapApplet::drawLabeledMarker(meshtastic_NodeInfoLite *node)
|
||||
markerSize = map(node->hops_away, 0, config.lora.hop_limit, markerSizeMax, markerSizeMin);
|
||||
|
||||
// Common dimensions (left or right variant)
|
||||
textW = getTextWidth(node->user.short_name);
|
||||
textW = getTextWidth(shortName);
|
||||
if (textW == 0)
|
||||
paddingInnerW = 0; // If no text, no padding for text
|
||||
textH = fontSmall.lineHeight();
|
||||
@@ -325,7 +329,7 @@ void InkHUD::MapApplet::drawLabeledMarker(meshtastic_NodeInfoLite *node)
|
||||
drawRect(labelX, labelY, labelW, labelH, BLACK);
|
||||
|
||||
// Short name
|
||||
printAt(textX, textY, node->user.short_name, LEFT, MIDDLE);
|
||||
printAt(textX, textY, shortName, LEFT, MIDDLE);
|
||||
|
||||
// If the label is for our own node,
|
||||
// fade it by overdrawing partially with white
|
||||
|
||||
@@ -142,16 +142,18 @@ void InkHUD::NodeListApplet::onRender()
|
||||
meshtastic_NodeInfoLite *node = nodeDB->getMeshNode(nodeNum);
|
||||
|
||||
// -- Shortname --
|
||||
// use "?" if unknown
|
||||
if (node && node->has_user)
|
||||
shortName = node->user.short_name;
|
||||
// Parse special chars in the short name
|
||||
// Use "?" if unknown
|
||||
if (node)
|
||||
shortName = parseShortName(node);
|
||||
else
|
||||
shortName = "?";
|
||||
|
||||
// -- Longname --
|
||||
// use node id if unknown
|
||||
// Parse special chars in long name
|
||||
// Use node id if unknown
|
||||
if (node && node->has_user)
|
||||
longName = node->user.long_name; // Found in nodeDB
|
||||
longName = parse(node->user.long_name); // Found in nodeDB
|
||||
else {
|
||||
// Not found in nodeDB, show a hex nodeid instead
|
||||
longName = hexifyNodeNum(nodeNum);
|
||||
|
||||
@@ -9,6 +9,12 @@ using namespace NicheGraphics;
|
||||
void InkHUD::BasicExampleApplet::onRender()
|
||||
{
|
||||
printAt(0, 0, "Hello, World!");
|
||||
|
||||
// If text might contain "special characters", is needs parsing first
|
||||
// This applies to data such as text-messages and and node names
|
||||
|
||||
// std::string greeting = parse("Grüezi mitenand!");
|
||||
// printAt(0, 0, greeting);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -5,7 +5,7 @@
|
||||
An example of an InkHUD applet.
|
||||
Tells us when a new text message arrives.
|
||||
|
||||
This applet makes use of the MeshModule API to detect new messages,
|
||||
This applet makes use of the Module API to detect new messages,
|
||||
which is a general part of the Meshtastic firmware, and not part of InkHUD.
|
||||
|
||||
In variants/<your device>/nicheGraphics.h:
|
||||
|
||||
@@ -11,10 +11,19 @@ InkHUD::LogoApplet::LogoApplet() : concurrency::OSThread("LogoApplet")
|
||||
OSThread::setIntervalFromNow(8 * 1000UL);
|
||||
OSThread::enabled = true;
|
||||
|
||||
textLeft = "";
|
||||
textRight = "";
|
||||
textTitle = xstr(APP_VERSION_SHORT);
|
||||
fontTitle = fontSmall;
|
||||
// During onboarding, show the default short name as well as the version string
|
||||
// This behavior assists manufacturers during mass production, and should not be modified without good reason
|
||||
if (!settings->tips.safeShutdownSeen) {
|
||||
fontTitle = fontLarge;
|
||||
textLeft = xstr(APP_VERSION_SHORT);
|
||||
textRight = owner.short_name;
|
||||
textTitle = "Meshtastic";
|
||||
} else {
|
||||
fontTitle = fontSmall;
|
||||
textLeft = "";
|
||||
textRight = "";
|
||||
textTitle = xstr(APP_VERSION_SHORT);
|
||||
}
|
||||
|
||||
bringToForeground();
|
||||
// This is then drawn with a FULL refresh by Renderer::begin
|
||||
@@ -102,9 +111,10 @@ void InkHUD::LogoApplet::onShutdown()
|
||||
|
||||
// Prepare for the powered-off screen now
|
||||
// We can change these values because the initial "shutting down" screen has already rendered at this point
|
||||
meshtastic_NodeInfoLite *ourNode = nodeDB->getMeshNode(nodeDB->getNodeNum());
|
||||
textLeft = "";
|
||||
textRight = "";
|
||||
textTitle = owner.short_name;
|
||||
textTitle = parseShortName(ourNode);
|
||||
fontTitle = fontLarge;
|
||||
|
||||
// This is then drawn by InkHUD::Events::onShutdown, with a blocking FULL update, after InkHUD's flash write is complete
|
||||
|
||||
@@ -244,6 +244,7 @@ void InkHUD::MenuApplet::execute(MenuItem item)
|
||||
void InkHUD::MenuApplet::showPage(MenuPage page)
|
||||
{
|
||||
items.clear();
|
||||
items.shrink_to_fit();
|
||||
|
||||
switch (page) {
|
||||
case ROOT:
|
||||
|
||||
@@ -33,11 +33,6 @@ int InkHUD::NotificationApplet::onReceiveTextMessage(const meshtastic_MeshPacket
|
||||
if (getFrom(p) == nodeDB->getNodeNum())
|
||||
return 0;
|
||||
|
||||
// Abort if message was only an "emoji reaction"
|
||||
// Possibly some implementation of this in future?
|
||||
if (p->decoded.emoji)
|
||||
return 0;
|
||||
|
||||
Notification n;
|
||||
n.timestamp = getValidTime(RTCQuality::RTCQualityDevice, true); // Current RTC time
|
||||
|
||||
@@ -122,7 +117,7 @@ void InkHUD::NotificationApplet::onRender()
|
||||
int16_t textM = divX + padW + (getTextWidth(text) / 2);
|
||||
|
||||
// Restrict area for printing
|
||||
// - don't overlap border, or diveder
|
||||
// - don't overlap border, or divider
|
||||
setCrop(divX + 1, 1, (width() - (divX + 1) - 1), height() - 2);
|
||||
|
||||
// Drop shadow
|
||||
@@ -218,7 +213,7 @@ std::string InkHUD::NotificationApplet::getNotificationText(uint16_t widthAvaila
|
||||
|
||||
// Sender id
|
||||
if (node && node->has_user)
|
||||
text += node->user.short_name;
|
||||
text += parseShortName(node);
|
||||
else
|
||||
text += hexifyNodeNum(message->sender);
|
||||
|
||||
@@ -232,7 +227,7 @@ std::string InkHUD::NotificationApplet::getNotificationText(uint16_t widthAvaila
|
||||
|
||||
// Sender id
|
||||
if (node && node->has_user)
|
||||
text += node->user.short_name;
|
||||
text += parseShortName(node);
|
||||
else
|
||||
text += hexifyNodeNum(message->sender);
|
||||
|
||||
@@ -241,7 +236,8 @@ std::string InkHUD::NotificationApplet::getNotificationText(uint16_t widthAvaila
|
||||
}
|
||||
}
|
||||
|
||||
return text;
|
||||
// Parse any non-ascii characters and return
|
||||
return parse(text);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -23,9 +23,9 @@ void InkHUD::PairingApplet::onRender()
|
||||
|
||||
// Device's bluetooth name, if it will fit
|
||||
setFont(fontSmall);
|
||||
std::string name = "Name: " + std::string(getDeviceName());
|
||||
std::string name = "Name: " + parse(getDeviceName());
|
||||
if (getTextWidth(name) > width()) // Too wide, try without the leading "Name: "
|
||||
name = std::string(getDeviceName());
|
||||
name = parse(getDeviceName());
|
||||
if (getTextWidth(name) < width()) // Does it fit?
|
||||
printAt(X(0.5), Y(0.75), name, CENTER, MIDDLE);
|
||||
}
|
||||
|
||||
@@ -27,11 +27,6 @@ int InkHUD::AllMessageApplet::onReceiveTextMessage(const meshtastic_MeshPacket *
|
||||
if (getFrom(p) == nodeDB->getNodeNum())
|
||||
return 0;
|
||||
|
||||
// Abort if message was only an "emoji reaction"
|
||||
// Possibly some implemetation of this in future?
|
||||
if (p->decoded.emoji)
|
||||
return 0;
|
||||
|
||||
requestAutoshow(); // Want to become foreground, if permitted
|
||||
requestUpdate(); // Want to update display, if applet is foreground
|
||||
|
||||
@@ -72,13 +67,13 @@ void InkHUD::AllMessageApplet::onRender()
|
||||
}
|
||||
|
||||
// Sender's id
|
||||
// - shortname, if available, or
|
||||
// - short name and long name, if available, or
|
||||
// - node id
|
||||
meshtastic_NodeInfoLite *sender = nodeDB->getMeshNode(message->sender);
|
||||
if (sender && sender->has_user) {
|
||||
header += sender->user.short_name;
|
||||
header += parseShortName(sender); // May be last-four of node if unprintable (emoji, etc)
|
||||
header += " (";
|
||||
header += sender->user.long_name;
|
||||
header += parse(sender->user.long_name);
|
||||
header += ")";
|
||||
} else
|
||||
header += hexifyNodeNum(message->sender);
|
||||
@@ -100,19 +95,22 @@ void InkHUD::AllMessageApplet::onRender()
|
||||
// Print message text
|
||||
// ===================
|
||||
|
||||
// Parse any non-ascii chars in the message
|
||||
std::string text = parse(message->text);
|
||||
|
||||
// Extra gap below the header
|
||||
int16_t textTop = headerDivY + padDivH;
|
||||
|
||||
// Determine size if printed large
|
||||
setFont(fontLarge);
|
||||
uint32_t textHeight = getWrappedTextHeight(0, width(), message->text);
|
||||
uint32_t textHeight = getWrappedTextHeight(0, width(), text);
|
||||
|
||||
// If too large, swap to small font
|
||||
if (textHeight + textTop > (uint32_t)height()) // (compare signed and unsigned)
|
||||
setFont(fontSmall);
|
||||
|
||||
// Print text
|
||||
printWrapped(0, textTop, width(), message->text);
|
||||
printWrapped(0, textTop, width(), text);
|
||||
}
|
||||
|
||||
// Don't show notifications for text messages when our applet is displayed
|
||||
|
||||
@@ -23,11 +23,6 @@ int InkHUD::DMApplet::onReceiveTextMessage(const meshtastic_MeshPacket *p)
|
||||
if (!isActive())
|
||||
return 0;
|
||||
|
||||
// Abort if only an "emoji reactions"
|
||||
// Possibly some implemetation of this in future?
|
||||
if (p->decoded.emoji)
|
||||
return 0;
|
||||
|
||||
// If DM (not broadcast)
|
||||
if (!isBroadcast(p->to)) {
|
||||
// Want to update display, if applet is foreground
|
||||
@@ -68,13 +63,13 @@ void InkHUD::DMApplet::onRender()
|
||||
}
|
||||
|
||||
// Sender's id
|
||||
// - shortname, if available, or
|
||||
// - shortname and long name, if available, or
|
||||
// - node id
|
||||
meshtastic_NodeInfoLite *sender = nodeDB->getMeshNode(latestMessage->dm.sender);
|
||||
if (sender && sender->has_user) {
|
||||
header += sender->user.short_name;
|
||||
header += parseShortName(sender); // May be last-four of node if unprintable (emoji, etc)
|
||||
header += " (";
|
||||
header += sender->user.long_name;
|
||||
header += parse(sender->user.long_name);
|
||||
header += ")";
|
||||
} else
|
||||
header += hexifyNodeNum(latestMessage->dm.sender);
|
||||
@@ -96,19 +91,22 @@ void InkHUD::DMApplet::onRender()
|
||||
// Print message text
|
||||
// ===================
|
||||
|
||||
// Parse any non-ascii chars in the message
|
||||
std::string text = parse(latestMessage->dm.text);
|
||||
|
||||
// Extra gap below the header
|
||||
int16_t textTop = headerDivY + padDivH;
|
||||
|
||||
// Determine size if printed large
|
||||
setFont(fontLarge);
|
||||
uint32_t textHeight = getWrappedTextHeight(0, width(), latestMessage->dm.text);
|
||||
uint32_t textHeight = getWrappedTextHeight(0, width(), text);
|
||||
|
||||
// If too large, swap to small font
|
||||
if (textHeight + textTop > (uint32_t)height()) // (compare signed and unsigned)
|
||||
setFont(fontSmall);
|
||||
|
||||
// Print text
|
||||
printWrapped(0, textTop, width(), latestMessage->dm.text);
|
||||
printWrapped(0, textTop, width(), text);
|
||||
}
|
||||
|
||||
// Don't show notifications for direct messages when our applet is displayed
|
||||
|
||||
@@ -16,7 +16,7 @@ void InkHUD::HeardApplet::onActivate()
|
||||
|
||||
void InkHUD::HeardApplet::onDeactivate()
|
||||
{
|
||||
// Avoid an unlikely situation where frquent activation / deactivation populated duplicate info from node DB
|
||||
// Avoid an unlikely situation where frequent activation / deactivation populates duplicate info from node DB
|
||||
cards.clear();
|
||||
}
|
||||
|
||||
@@ -41,6 +41,7 @@ void InkHUD::HeardApplet::handleParsed(CardInfo c)
|
||||
|
||||
cards.push_front(c); // Insert into base class' card collection
|
||||
cards.resize(min(maxCards(), (uint8_t)cards.size())); // Don't keep more cards than we could *ever* fit on screen
|
||||
cards.shrink_to_fit();
|
||||
|
||||
// Our rendered image needs to change if:
|
||||
if (previous.nodeNum != c.nodeNum // Different node
|
||||
@@ -54,7 +55,7 @@ void InkHUD::HeardApplet::handleParsed(CardInfo c)
|
||||
}
|
||||
|
||||
// When applet is activated, pre-fill with stale data from NodeDB
|
||||
// We're sorting using the last_heard value. Succeptible to weirdness if node's RTC changes.
|
||||
// We're sorting using the last_heard value. Susceptible to weirdness if node's RTC changes.
|
||||
// No SNR is available in node db, so we can't calculate signal either
|
||||
// These initial cards from node db will be gradually pushed out by new packets which originate from out base applet instead
|
||||
void InkHUD::HeardApplet::populateFromNodeDB()
|
||||
@@ -72,7 +73,7 @@ void InkHUD::HeardApplet::populateFromNodeDB()
|
||||
return (top->last_heard > bottom->last_heard);
|
||||
});
|
||||
|
||||
// Keep the most recent entries onlyt
|
||||
// Keep the most recent entries only
|
||||
// Just enough to fill the screen
|
||||
if (ordered.size() > maxCards())
|
||||
ordered.resize(maxCards());
|
||||
|
||||
@@ -53,6 +53,7 @@ void InkHUD::RecentsListApplet::handleParsed(CardInfo c)
|
||||
|
||||
cards.push_front(c); // Store this CardInfo
|
||||
cards.resize(min(maxCards(), (uint8_t)cards.size())); // Don't keep more cards than we could *ever* fit on screen
|
||||
cards.shrink_to_fit();
|
||||
|
||||
// Record the time of this observation
|
||||
// Used to count active nodes, and to know when to prune inactive nodes
|
||||
@@ -99,10 +100,12 @@ void InkHUD::RecentsListApplet::prune()
|
||||
if (!isActive(ages.at(i).seenAtMs)) {
|
||||
// Drop this item, and all others behind it
|
||||
ages.resize(i);
|
||||
ages.shrink_to_fit();
|
||||
cards.resize(i);
|
||||
cards.shrink_to_fit();
|
||||
|
||||
// Request an update, if pruning did modify our data
|
||||
// Required if pruning was scheduled. Redundent if pruning was prior to rendering.
|
||||
// Required if pruning was scheduled. Redundant if pruning was prior to rendering.
|
||||
requestAutoshow();
|
||||
requestUpdate();
|
||||
|
||||
|
||||
@@ -71,27 +71,28 @@ void InkHUD::ThreadedMessageApplet::onRender()
|
||||
MessageStore::Message &m = store->messages.at(i);
|
||||
bool outgoing = (m.sender == 0);
|
||||
meshtastic_NodeInfoLite *sender = nodeDB->getMeshNode(m.sender);
|
||||
std::string bodyText = parse(m.text); // Parse any non-ascii chars in the message
|
||||
|
||||
// Cache bottom Y of message text
|
||||
// - Used when drawing vertical line alongside
|
||||
const int16_t dotsB = msgB;
|
||||
|
||||
// Get dimensions for message text
|
||||
uint16_t bodyH = getWrappedTextHeight(msgL, msgW, m.text);
|
||||
uint16_t bodyH = getWrappedTextHeight(msgL, msgW, bodyText);
|
||||
int16_t bodyT = msgB - bodyH;
|
||||
|
||||
// Print message
|
||||
// - if incoming
|
||||
if (!outgoing)
|
||||
printWrapped(msgL, bodyT, msgW, m.text);
|
||||
printWrapped(msgL, bodyT, msgW, bodyText);
|
||||
|
||||
// Print message
|
||||
// - if outgoing
|
||||
else {
|
||||
if (getTextWidth(m.text) < width()) // If short,
|
||||
printAt(msgR, bodyT, m.text, RIGHT); // print right align
|
||||
else // If long,
|
||||
printWrapped(msgL, bodyT, msgW, m.text); // need printWrapped(), which doesn't support right align
|
||||
if (getTextWidth(bodyText) < width()) // If short,
|
||||
printAt(msgR, bodyT, bodyText, RIGHT); // print right align
|
||||
else // If long,
|
||||
printWrapped(msgL, bodyT, msgW, bodyText); // need printWrapped(), which doesn't support right align
|
||||
}
|
||||
|
||||
// Move cursor up
|
||||
@@ -103,12 +104,16 @@ void InkHUD::ThreadedMessageApplet::onRender()
|
||||
// - shortname, if possible, or "me"
|
||||
// - time received, if possible
|
||||
std::string info;
|
||||
if (sender && sender->has_user)
|
||||
info += sender->user.short_name;
|
||||
else if (outgoing)
|
||||
if (outgoing)
|
||||
info += "Me";
|
||||
else
|
||||
info += hexifyNodeNum(m.sender);
|
||||
else {
|
||||
// Check if sender is node db
|
||||
meshtastic_NodeInfoLite *sender = nodeDB->getMeshNode(m.sender);
|
||||
if (sender)
|
||||
info += parseShortName(sender); // Handle any unprintable chars in short name
|
||||
else
|
||||
info += hexifyNodeNum(m.sender); // No node info at all. Print the node num
|
||||
}
|
||||
|
||||
std::string timeString = getTimeString(m.timestamp);
|
||||
if (timeString.length() > 0) {
|
||||
@@ -195,11 +200,6 @@ int InkHUD::ThreadedMessageApplet::onReceiveTextMessage(const meshtastic_MeshPac
|
||||
if (p->to != NODENUM_BROADCAST)
|
||||
return 0;
|
||||
|
||||
// Abort if messages was an "emoji reaction"
|
||||
// Possibly some implemetation of this in future?
|
||||
if (p->decoded.emoji)
|
||||
return 0;
|
||||
|
||||
// Extract info into our slimmed-down "StoredMessage" type
|
||||
MessageStore::Message newMessage;
|
||||
newMessage.timestamp = getValidTime(RTCQuality::RTCQualityDevice, true); // Current RTC time
|
||||
|
||||
@@ -3,11 +3,13 @@
|
||||
#include "./Events.h"
|
||||
|
||||
#include "RTC.h"
|
||||
#include "modules/AdminModule.h"
|
||||
#include "modules/TextMessageModule.h"
|
||||
#include "sleep.h"
|
||||
|
||||
#include "./Applet.h"
|
||||
#include "./SystemApplet.h"
|
||||
#include "graphics/niche/FlashData.h"
|
||||
|
||||
using namespace NicheGraphics;
|
||||
|
||||
@@ -25,6 +27,9 @@ void InkHUD::Events::begin()
|
||||
deepSleepObserver.observe(¬ifyDeepSleep);
|
||||
rebootObserver.observe(¬ifyReboot);
|
||||
textMessageObserver.observe(textMessageModule);
|
||||
#if !MESHTASTIC_EXCLUDE_ADMIN
|
||||
adminMessageObserver.observe(adminModule);
|
||||
#endif
|
||||
#ifdef ARCH_ESP32
|
||||
lightSleepObserver.observe(¬ifyLightSleep);
|
||||
#endif
|
||||
@@ -117,8 +122,13 @@ int InkHUD::Events::beforeReboot(void *unused)
|
||||
sa->onReboot();
|
||||
}
|
||||
|
||||
inkhud->persistence->saveSettings();
|
||||
inkhud->persistence->saveLatestMessage();
|
||||
// Save settings to flash, or erase if factory reset in progress
|
||||
if (!eraseOnReboot) {
|
||||
inkhud->persistence->saveSettings();
|
||||
inkhud->persistence->saveLatestMessage();
|
||||
} else {
|
||||
NicheGraphics::clearFlashData();
|
||||
}
|
||||
|
||||
// Note: no forceUpdate call here
|
||||
// We don't have any final screen to draw, although LogoApplet::onReboot did already display a "rebooting" screen
|
||||
@@ -136,11 +146,6 @@ int InkHUD::Events::onReceiveTextMessage(const meshtastic_MeshPacket *packet)
|
||||
if (getFrom(packet) == nodeDB->getNodeNum())
|
||||
return 0;
|
||||
|
||||
// Short circuit: don't store "emoji reactions"
|
||||
// Possibly some implementation of this in future?
|
||||
if (packet->decoded.emoji)
|
||||
return 0;
|
||||
|
||||
// Determine whether the message is broadcast or a DM
|
||||
// Store this info to prevent confusion after a reboot
|
||||
// Avoids need to compare timestamps, because of situation where "future" messages block newly received, if time not set
|
||||
@@ -171,6 +176,23 @@ int InkHUD::Events::onReceiveTextMessage(const meshtastic_MeshPacket *packet)
|
||||
return 0; // Tell caller to continue notifying other observers. (No reason to abort this event)
|
||||
}
|
||||
|
||||
int InkHUD::Events::onAdminMessage(const meshtastic_AdminMessage *message)
|
||||
{
|
||||
switch (message->which_payload_variant) {
|
||||
// Factory reset
|
||||
// Two possible messages. One preserves BLE bonds, other wipes. Both should clear InkHUD data.
|
||||
case meshtastic_AdminMessage_factory_reset_device_tag:
|
||||
case meshtastic_AdminMessage_factory_reset_config_tag:
|
||||
eraseOnReboot = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0; // Tell caller to continue notifying other observers. (No reason to abort this event)
|
||||
}
|
||||
|
||||
#ifdef ARCH_ESP32
|
||||
// Callback for lightSleepObserver
|
||||
// Make sure the display is not partway through an update when we begin light sleep
|
||||
|
||||
@@ -33,6 +33,7 @@ class Events
|
||||
int beforeDeepSleep(void *unused); // Prepare for shutdown
|
||||
int beforeReboot(void *unused); // Prepare for reboot
|
||||
int onReceiveTextMessage(const meshtastic_MeshPacket *packet); // Store most recent text message
|
||||
int onAdminMessage(const meshtastic_AdminMessage *message); // Handle incoming admin messages
|
||||
#ifdef ARCH_ESP32
|
||||
int beforeLightSleep(void *unused); // Prepare for light sleep
|
||||
#endif
|
||||
@@ -52,10 +53,17 @@ class Events
|
||||
CallbackObserver<Events, const meshtastic_MeshPacket *> textMessageObserver =
|
||||
CallbackObserver<Events, const meshtastic_MeshPacket *>(this, &Events::onReceiveTextMessage);
|
||||
|
||||
// Get notified of incoming admin messages, and handle any which are relevant to InkHUD
|
||||
CallbackObserver<Events, const meshtastic_AdminMessage *> adminMessageObserver =
|
||||
CallbackObserver<Events, const meshtastic_AdminMessage *>(this, &Events::onAdminMessage);
|
||||
|
||||
#ifdef ARCH_ESP32
|
||||
// Get notified when the system is entering light sleep
|
||||
CallbackObserver<Events, void *> lightSleepObserver = CallbackObserver<Events, void *>(this, &Events::beforeLightSleep);
|
||||
#endif
|
||||
|
||||
// If set, InkHUD's data will be erased during onReboot
|
||||
bool eraseOnReboot = false;
|
||||
};
|
||||
|
||||
} // namespace NicheGraphics::InkHUD
|
||||
|
||||
@@ -22,6 +22,8 @@ InkHUD::MessageStore::MessageStore(std::string label)
|
||||
}
|
||||
|
||||
// Write the contents of the MessageStore::messages object to flash
|
||||
// Takes the firmware's SPI lock during FS operations. Implemented for consistency, but only relevant when using SD card.
|
||||
// Need to lock and unlock around specific FS methods, as the SafeFile class takes the lock for itself internally
|
||||
void InkHUD::MessageStore::saveToFlash()
|
||||
{
|
||||
assert(!filename.empty());
|
||||
@@ -29,7 +31,9 @@ void InkHUD::MessageStore::saveToFlash()
|
||||
#ifdef FSCom
|
||||
// Make the directory, if doesn't already exist
|
||||
// This is the same directory accessed by NicheGraphics::FlashData
|
||||
spiLock->lock();
|
||||
FSCom.mkdir("/NicheGraphics");
|
||||
spiLock->unlock();
|
||||
|
||||
// Open or create the file
|
||||
// No "full atomic": don't save then rename
|
||||
@@ -37,6 +41,9 @@ void InkHUD::MessageStore::saveToFlash()
|
||||
|
||||
LOG_INFO("Saving messages in %s", filename.c_str());
|
||||
|
||||
// Take firmware's SPI Lock while writing
|
||||
spiLock->lock();
|
||||
|
||||
// 1st byte: how many messages will be written to store
|
||||
f.write(messages.size());
|
||||
|
||||
@@ -51,6 +58,9 @@ void InkHUD::MessageStore::saveToFlash()
|
||||
LOG_DEBUG("Wrote message %u, length %u, text \"%s\"", (uint32_t)i, min(MAX_MESSAGE_SIZE, m.text.size()), m.text.c_str());
|
||||
}
|
||||
|
||||
// Release firmware's SPI lock, because SafeFile::close needs it
|
||||
spiLock->unlock();
|
||||
|
||||
bool writeSucceeded = f.close();
|
||||
|
||||
if (!writeSucceeded) {
|
||||
@@ -63,6 +73,7 @@ void InkHUD::MessageStore::saveToFlash()
|
||||
|
||||
// Attempt to load the previous contents of the MessageStore:message deque from flash.
|
||||
// Filename is controlled by the "label" parameter
|
||||
// Takes the firmware's SPI lock during FS operations. Implemented for consistency, but only relevant when using SD card.
|
||||
void InkHUD::MessageStore::loadFromFlash()
|
||||
{
|
||||
// Hopefully redundant. Initial intention is to only load / save once per boot.
|
||||
@@ -70,6 +81,9 @@ void InkHUD::MessageStore::loadFromFlash()
|
||||
|
||||
#ifdef FSCom
|
||||
|
||||
// Take the firmware's SPI Lock, in case filesystem is on SD card
|
||||
concurrency::LockGuard guard(spiLock);
|
||||
|
||||
// Check that the file *does* actually exist
|
||||
if (!FSCom.exists(filename.c_str())) {
|
||||
LOG_WARN("'%s' not found. Using default values", filename.c_str());
|
||||
|
||||
@@ -13,7 +13,7 @@ This document is intended as a reference for maintainers. A haphazard collection
|
||||
- [Non-interactive](#non-interactive)
|
||||
- [Customizable](#customizable)
|
||||
- [Event-Driven Rendering](#event-driven-rendering)
|
||||
- [No `#ifdef` spaghetti](#no-ifdef-spaghetti)
|
||||
- [Avoid the Preprocessor](#avoid-the-preprocessor)
|
||||
- [The Implementation](#the-implementation)
|
||||
- [The Rendering Process](#the-rendering-process)
|
||||
- [Concepts](#concepts)
|
||||
@@ -23,6 +23,10 @@ This document is intended as a reference for maintainers. A haphazard collection
|
||||
- [Adding a Variant](#adding-a-variant)
|
||||
- [platformio.ini](#platformioini)
|
||||
- [nicheGraphics.h](#nichegraphicsh)
|
||||
- [Fonts](#fonts)
|
||||
- [Parsing Unicode Text](#parsing-unicode-text)
|
||||
- [Localization](#localization)
|
||||
- [Creating / Modifying](#creating--modifying)
|
||||
- [Class Notes](#class-notes)
|
||||
- [`InkHUD::InkHUD`](#inkhudinkhud)
|
||||
- [`InkHUD::Persistence`](#inkhudpersistence)
|
||||
@@ -73,9 +77,11 @@ The user should be given the choice to decide which information they would like
|
||||
|
||||
The display image does not update "automatically". Individual applets are responsible for deciding when they have new information to show, and then requesting a display update.
|
||||
|
||||
### No `#ifdef` spaghetti
|
||||
### Avoid the Preprocessor
|
||||
|
||||
**Don't** use preprocessor macros for device-specific configuration. This should be achieved with config methods, in [`nicheGraphics.h`](#nichegraphicsh).
|
||||
**Don't** use preprocessor macros to write code which targets individual devices.
|
||||
|
||||
**Do** configure InkHUD to suit each device in [`nicheGraphics.h`](#nichegraphicsh).
|
||||
|
||||
**Do** use preprocessor macros to guard all files
|
||||
|
||||
@@ -103,7 +109,7 @@ The display image does not update "automatically". Individual applets are respon
|
||||
|
||||
(animated diagram)
|
||||
|
||||
<img src="rendering.gif" alt="animated process diagram of InkHUD rendering" height="480"/>
|
||||
<img src="rendering.gif" alt="animated process diagram of InkHUD rendering" height="480" width="auto" />
|
||||
|
||||
An overview:
|
||||
|
||||
@@ -281,11 +287,14 @@ ${esp32s3_base.lib_deps}
|
||||
|
||||
### nicheGraphics.h
|
||||
|
||||
⚠ Wrap this file in `#ifdef MESHTASTIC_INCLUDE_NICHE_GRAPHICS`
|
||||
Should contain a `setupNicheGraphics` method, which creates and configures the various components for InkHUD.
|
||||
|
||||
`nicheGraphics.h` should be placed in the same folder as your variant's `platformio.ini`. If this is not possible, modify `build_src_filter`.
|
||||
For well commented examples, see:
|
||||
|
||||
`nicheGraphics.h` should contain a `setupNicheGraphics` method, which creates and configures the various components for InkHUD.
|
||||
- `/variants/heltec_vision_master_e290/nicheGraphics.h` (ESP32)
|
||||
- `/variants/ELECROW-ThinkNode-M1/nicheGraphics.h` (NRF52)
|
||||
|
||||
As a general overview:
|
||||
|
||||
- Display
|
||||
- Start SPI
|
||||
@@ -301,10 +310,80 @@ ${esp32s3_base.lib_deps}
|
||||
- Setup `TwoButton` driver (user button, optional "auxiliary" button)
|
||||
- Connect to InkHUD handlers (use lambdas)
|
||||
|
||||
For well commented examples, see:
|
||||
## Fonts
|
||||
|
||||
- `variants/heltec_vision_master_e290/nicheGraphics.h` (ESP32)
|
||||
- `variants/t-echo/nicheGraphics.h` (NRF52)
|
||||
InkHUD uses AdafruitGFX fonts. The large and small font which are shared by all applets are set in nicheGraphics.h.
|
||||
|
||||
```cpp
|
||||
// Prepare fonts
|
||||
InkHUD::Applet::fontLarge = FREESANS_9PT_WIN1252;
|
||||
InkHUD::Applet::fontSmall = FREESANS_6PT_WIN1252;
|
||||
|
||||
// Using a generic AdafruitGFX font instead:
|
||||
// InkHUD::Applet::fontLarge = FreeSerif9pt7b;
|
||||
```
|
||||
|
||||
Any generic AdafruitGFX font may be used, but the fonts which are bundled with InkHUD have been customized with extended-ASCII character sets.
|
||||
|
||||
### Parsing Unicode Text
|
||||
|
||||
Text received by the firmware is encoded as UTF-8.
|
||||
|
||||
Applets must manually parse any text which may contain non-ASCII characters. Strings like text-messages and node names should be parsed.
|
||||
|
||||
```cpp
|
||||
std::string greeting = "Góðan daginn!";
|
||||
std::string parsed = parse(greeting);
|
||||
```
|
||||
|
||||
This will re-encode the characters to match whichever extended-ASCII font InkHUD has been built with.
|
||||
|
||||
### Localization
|
||||
|
||||
InkHUD is bundled with extended-ASCII fonts for:
|
||||
|
||||
- Windows-1250 (Central European)
|
||||
- Windows-1251 (Cyrillic)
|
||||
- Windows-1252 (Western European)
|
||||
|
||||
The default builds use Windows-1252 encoding. This can be changed in nicheGraphics.h.
|
||||
|
||||
```cpp
|
||||
InkHUD::Applet::fontLarge = FREESANS_9PT_WIN1250;
|
||||
InkHUD::Applet::fontSmall = FREESANS_6PT_WIN1250;
|
||||
|
||||
InkHUD::Applet::fontLarge = FREESANS_9PT_WIN1251;
|
||||
InkHUD::Applet::fontSmall = FREESANS_6PT_WIN1251;
|
||||
```
|
||||
|
||||
### Creating / Modifying
|
||||
|
||||
For basic conversion and editing, online tools might be sufficient:
|
||||
|
||||
- [https://rop.nl/truetype2gfx/](https://rop.nl/truetype2gfx/) - converting from ttf
|
||||
- [https://tchapi.github.io/Adafruit-GFX-Font-Customiser/](https://tchapi.github.io/Adafruit-GFX-Font-Customiser/) - editing glyphs
|
||||
|
||||
For heavy editing, this offline workflow is suggested:
|
||||
|
||||
- [FontForge](https://fontforge.org/en-US/)
|
||||
- re-ordering glyphs
|
||||
- Encoding > Load Encoding
|
||||
- Encoding > Reencode
|
||||
- .ttf to .bdf conversion
|
||||
- Element > Bitmap Strikes Available..
|
||||
- File > Generate Fonts
|
||||
- [GFXFontEditor](https://github.com/ScottFerg56/GFXFontEditor)
|
||||
- manual glyph correction
|
||||
- .bdf to AdafruitGFX .h conversion
|
||||
- File > Edit Font Properties
|
||||
- right-click glyph list, flatten font
|
||||
- File > Save As
|
||||
- manually edit exported .h
|
||||
- remove `#include <AdafruitGFX.h>`
|
||||
|
||||
If possible, custom Extended-ASCII fonts should use one of the encodings which InkHUD already supports. If this is not possible, a mapping for the new encoding will need to be added.
|
||||
|
||||
See [Encoding](#encoding) for details on using an extended-ASCII font.
|
||||
|
||||
## Class Notes
|
||||
|
||||
@@ -502,6 +581,10 @@ Applets themselves do also listen separately for various events, but for the pur
|
||||
|
||||
Button input is sometimes handled by a system applet. `InkHUD::Events` determines whether the button should be handled by a specific system applet, or should instead trigger a default behavior
|
||||
|
||||
#### Factory Reset
|
||||
|
||||
The Events class handles the admin messages(s) which trigger factory reset. We set `Events::eraseOnReboot = true`, which causes `Events::onReboot` to erase the contents of InkHUD's data directory. We do this because some applets (e.g. ThreadedMessageApplet) save their own data to flash, so if we erased earlier, that data would get re-written during reboot.
|
||||
|
||||
---
|
||||
|
||||
### `InkHUD::Applet`
|
||||
@@ -624,17 +707,30 @@ The default AdafruitGFX text handling places characters "upon a line", as if han
|
||||
|
||||
The height of this box is `AppletFont::lineHeight`, which is the height of the tallest character in the font. This gives us a fixed-height for text, which is much tighter than with AdafruitGFX's default line spacing.
|
||||
|
||||
#### UTF-8 Substitutions
|
||||
#### Encoding
|
||||
|
||||
To enable non-English text, the `AppletFont` class includes a mechanism to detect specific UTF-8 characters, and replace them with alternative glyphs from the AdafruitGFX font. This can be used to remap characters for a custom font, or to offer a suitable ASCII replacement.
|
||||
An AppletFont may be constructed from a standard 7bit ASCII AdafruitGFX font, however InkHUD also supports 8bit extended-ASCII fonts.
|
||||
|
||||
For this, the encoding must be specified when instantiating the AppletFont.
|
||||
|
||||
```cpp
|
||||
// With a custom font
|
||||
// ї is ASCII 0xBF, in Windows-1251 encoding
|
||||
addSubstitution("ї", "\xBF");
|
||||
|
||||
// Substitution (with a default font)
|
||||
addSubstitution("ö", "oe");
|
||||
InkHUD::AppletFont(FreeSans9pt_Win1250, InkHUD::AppletFont::WINDOWS_1250);
|
||||
```
|
||||
|
||||
These substitutions should be performed in a variant's `setupNicheGraphics` method. For convenience, some common ASCII encodings have ready-to-go sets of substitutions you can apply, for example `AppletFont::addSubstitutionsWin1251`
|
||||
Currently supported encodings are:
|
||||
|
||||
- ASCII
|
||||
- Windows-1250 (Central European)
|
||||
- Windows-1251 (Cyrillic)
|
||||
- Windows-1252 (Western European)
|
||||
|
||||
To add support for additional encodings, add to the `AppletFont::Encodings` enum, and then define the mapping from unicode in `AppletFont::applyEncoding`.
|
||||
|
||||
#### Custom Line Height
|
||||
|
||||
Some fonts may have a handful of especially tall characters, especially extended-ASCII fonts with diacritcs. Ideally, the font should be modified to help resolve this, but if the problem remains, manual offsets to the automatically determined line height can be specified in the constructor.
|
||||
|
||||
```cpp
|
||||
// -2 px of padding above, +1 px of padding below
|
||||
InkHUD::AppletFont(FreeSans9pt7b, ASCII, -2, 1);
|
||||
```
|
||||
|
||||
@@ -98,9 +98,8 @@ void TwoButton::setWiring(uint8_t whichButton, uint8_t pin, bool internalPullup)
|
||||
assert(whichButton < 2);
|
||||
buttons[whichButton].pin = pin;
|
||||
buttons[whichButton].activeLogic = LOW; // Unimplemented
|
||||
buttons[whichButton].mode = internalPullup ? INPUT_PULLUP : INPUT;
|
||||
|
||||
pinMode(buttons[whichButton].pin, buttons[whichButton].mode);
|
||||
pinMode(buttons[whichButton].pin, internalPullup ? INPUT_PULLUP : INPUT);
|
||||
}
|
||||
|
||||
void TwoButton::setTiming(uint8_t whichButton, uint32_t debounceMs, uint32_t longpressMs)
|
||||
@@ -182,7 +181,7 @@ void TwoButton::isrSecondary()
|
||||
void TwoButton::startThread()
|
||||
{
|
||||
if (!OSThread::enabled) {
|
||||
OSThread::setInterval(50);
|
||||
OSThread::setInterval(10);
|
||||
OSThread::enabled = true;
|
||||
}
|
||||
}
|
||||
@@ -299,7 +298,9 @@ int TwoButton::afterLightSleep(esp_sleep_wakeup_cause_t cause)
|
||||
// Manually trigger the button-down ISR
|
||||
// - during light sleep, our ISR is disabled
|
||||
// - if light sleep ends by button press, pretend our own ISR caught it
|
||||
if (cause == ESP_SLEEP_WAKEUP_GPIO)
|
||||
// - need to manually confirm by reading pin ourselves, to avoid occasional false positives
|
||||
// (false positive only when using internal pullup resistors?)
|
||||
if (cause == ESP_SLEEP_WAKEUP_GPIO && digitalRead(buttons[0].pin) == buttons[0].activeLogic)
|
||||
isrPrimary();
|
||||
|
||||
return 0; // Indicates success
|
||||
|
||||
@@ -35,7 +35,7 @@ class TwoButton : protected concurrency::OSThread
|
||||
static TwoButton *getInstance(); // Create or get the singleton instance
|
||||
void start(); // Start handling button input
|
||||
void stop(); // Stop handling button input (disconnect ISRs for sleep)
|
||||
void setWiring(uint8_t whichButton, uint8_t pin, bool internalPulldown = false);
|
||||
void setWiring(uint8_t whichButton, uint8_t pin, bool internalPullup = false);
|
||||
void setTiming(uint8_t whichButton, uint32_t debounceMs, uint32_t longpressMs);
|
||||
void setHandlerDown(uint8_t whichButton, Callback onDown);
|
||||
void setHandlerUp(uint8_t whichButton, Callback onUp);
|
||||
@@ -65,7 +65,6 @@ class TwoButton : protected concurrency::OSThread
|
||||
// Per-button config
|
||||
uint8_t pin = 0xFF; // 0xFF: unset
|
||||
bool activeLogic = LOW; // Active LOW by default. Currently unimplemented.
|
||||
uint8_t mode = INPUT; // Whether to use internal pull up / pull down resistors
|
||||
uint32_t debounceLength = 50; // Minimum length for shortpress, in ms
|
||||
uint32_t longpressLength = 500; // How long after button down to fire longpress, in ms
|
||||
volatile State state = State::REST; // Internal state
|
||||
|
||||
+23
-12
@@ -11,6 +11,7 @@
|
||||
|
||||
#ifdef ARCH_PORTDUINO
|
||||
#include "PortduinoGlue.h"
|
||||
#include <thread>
|
||||
#endif
|
||||
|
||||
DeviceScreen *deviceScreen = nullptr;
|
||||
@@ -26,12 +27,10 @@ CallbackObserver<DeviceScreen, esp_sleep_wakeup_cause_t> endSleepObserver =
|
||||
void tft_task_handler(void *param = nullptr)
|
||||
{
|
||||
while (true) {
|
||||
if (deviceScreen) {
|
||||
spiLock->lock();
|
||||
deviceScreen->task_handler();
|
||||
spiLock->unlock();
|
||||
deviceScreen->sleep();
|
||||
}
|
||||
spiLock->lock();
|
||||
deviceScreen->task_handler();
|
||||
spiLock->unlock();
|
||||
deviceScreen->sleep();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,10 +43,10 @@ void tftSetup(void)
|
||||
#else
|
||||
if (settingsMap[displayPanel] != no_screen) {
|
||||
DisplayDriverConfig displayConfig;
|
||||
static char *panels[] = {"NOSCREEN", "X11", "ST7789", "ST7735", "ST7735S", "ST7796",
|
||||
"ILI9341", "ILI9342", "ILI9486", "ILI9488", "HX8357D"};
|
||||
static char *panels[] = {"NOSCREEN", "X11", "FB", "ST7789", "ST7735", "ST7735S",
|
||||
"ST7796", "ILI9341", "ILI9342", "ILI9486", "ILI9488", "HX8357D"};
|
||||
static char *touch[] = {"NOTOUCH", "XPT2046", "STMPE610", "GT911", "FT5x06"};
|
||||
#ifdef USE_X11
|
||||
#if defined(USE_X11)
|
||||
if (settingsMap[displayPanel] == x11) {
|
||||
if (settingsMap[displayWidth] && settingsMap[displayHeight])
|
||||
displayConfig = DisplayDriverConfig(DisplayDriverConfig::device_t::X11, (uint16_t)settingsMap[displayWidth],
|
||||
@@ -55,6 +54,14 @@ void tftSetup(void)
|
||||
else
|
||||
displayConfig.device(DisplayDriverConfig::device_t::X11);
|
||||
} else
|
||||
#elif defined(USE_FRAMEBUFFER)
|
||||
if (settingsMap[displayPanel] == fb) {
|
||||
if (settingsMap[displayWidth] && settingsMap[displayHeight])
|
||||
displayConfig = DisplayDriverConfig(DisplayDriverConfig::device_t::FB, (uint16_t)settingsMap[displayWidth],
|
||||
(uint16_t)settingsMap[displayHeight]);
|
||||
else
|
||||
displayConfig.device(DisplayDriverConfig::device_t::FB);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
displayConfig.device(DisplayDriverConfig::device_t::CUSTOM_TFT)
|
||||
@@ -116,11 +123,15 @@ void tftSetup(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
if (deviceScreen) {
|
||||
#ifdef ARCH_ESP32
|
||||
tftSleepObserver.observe(¬ifyLightSleep);
|
||||
endSleepObserver.observe(¬ifyLightSleepEnd);
|
||||
xTaskCreatePinnedToCore(tft_task_handler, "tft", 10240, NULL, 1, NULL, 0);
|
||||
tftSleepObserver.observe(¬ifyLightSleep);
|
||||
endSleepObserver.observe(¬ifyLightSleepEnd);
|
||||
xTaskCreatePinnedToCore(tft_task_handler, "tft", 10240, NULL, 1, NULL, 0);
|
||||
#elif defined(ARCH_PORTDUINO)
|
||||
std::thread *tft_task = new std::thread([] { tft_task_handler(); });
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
+97
-35
@@ -105,7 +105,7 @@ NRF52Bluetooth *nrf52Bluetooth = nullptr;
|
||||
#include "AmbientLightingThread.h"
|
||||
#include "PowerFSMThread.h"
|
||||
|
||||
#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_I2C
|
||||
#if !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_I2C
|
||||
#include "motion/AccelerometerThread.h"
|
||||
AccelerometerThread *accelerometerThread = nullptr;
|
||||
#endif
|
||||
@@ -115,13 +115,17 @@ AccelerometerThread *accelerometerThread = nullptr;
|
||||
AudioThread *audioThread = nullptr;
|
||||
#endif
|
||||
|
||||
#ifdef USE_PCA9557
|
||||
PCA9557 IOEXP;
|
||||
#endif
|
||||
|
||||
#if HAS_TFT
|
||||
extern void tftSetup(void);
|
||||
#endif
|
||||
|
||||
#ifdef HAS_UDP_MULTICAST
|
||||
#include "mesh/udp/UdpMulticastThread.h"
|
||||
UdpMulticastThread *udpThread = nullptr;
|
||||
#include "mesh/udp/UdpMulticastHandler.h"
|
||||
UdpMulticastHandler *udpHandler = nullptr;
|
||||
#endif
|
||||
|
||||
#if defined(TCXO_OPTIONAL)
|
||||
@@ -133,6 +137,10 @@ void setupNicheGraphics();
|
||||
#include "nicheGraphics.h"
|
||||
#endif
|
||||
|
||||
#if defined(HW_SPI1_DEVICE) && defined(ARCH_ESP32)
|
||||
SPIClass SPI1(HSPI);
|
||||
#endif
|
||||
|
||||
using namespace concurrency;
|
||||
|
||||
volatile static const char slipstreamTZString[] = {USERPREFS_TZ_STRING};
|
||||
@@ -212,6 +220,64 @@ const char *getDeviceName()
|
||||
return name;
|
||||
}
|
||||
|
||||
#if defined(ELECROW_ThinkNode_M1) || defined(ELECROW_ThinkNode_M2)
|
||||
static int32_t ledBlinkCount = 0;
|
||||
|
||||
static int32_t elecrowLedBlinker()
|
||||
{
|
||||
// are we in alert buzzer mode?
|
||||
#if HAS_BUTTON
|
||||
if (buttonThread->isBuzzing()) {
|
||||
// blink LED three times for 3 seconds, then 3 times for a second, with one second pause
|
||||
if (ledBlinkCount % 2) { // odd means LED OFF
|
||||
ledBlink.set(false);
|
||||
ledBlinkCount++;
|
||||
if (ledBlinkCount >= 12)
|
||||
ledBlinkCount = 0;
|
||||
noTone(PIN_BUZZER);
|
||||
return 1000;
|
||||
} else {
|
||||
if (ledBlinkCount < 6) {
|
||||
ledBlink.set(true);
|
||||
tone(PIN_BUZZER, 4000, 3000);
|
||||
ledBlinkCount++;
|
||||
return 3000;
|
||||
} else {
|
||||
ledBlink.set(true);
|
||||
tone(PIN_BUZZER, 4000, 1000);
|
||||
ledBlinkCount++;
|
||||
return 1000;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
#endif
|
||||
ledBlinkCount = 0;
|
||||
if (config.device.led_heartbeat_disabled)
|
||||
return 1000;
|
||||
|
||||
static bool ledOn;
|
||||
// remain on when fully charged or discharging above 10%
|
||||
if ((powerStatus->getIsCharging() && powerStatus->getBatteryChargePercent() >= 100) ||
|
||||
(!powerStatus->getIsCharging() && powerStatus->getBatteryChargePercent() >= 10)) {
|
||||
ledOn = true;
|
||||
} else {
|
||||
ledOn ^= 1;
|
||||
}
|
||||
ledBlink.set(ledOn);
|
||||
// when charging, blink 0.5Hz square wave rate to indicate that
|
||||
if (powerStatus->getIsCharging()) {
|
||||
return 500;
|
||||
}
|
||||
// Blink rapidly when almost empty or if battery is not connected
|
||||
if ((!powerStatus->getIsCharging() && powerStatus->getBatteryChargePercent() < 10) || !powerStatus->getHasBattery()) {
|
||||
return 250;
|
||||
}
|
||||
#if HAS_BUTTON
|
||||
}
|
||||
#endif
|
||||
return 1000;
|
||||
}
|
||||
#else
|
||||
static int32_t ledBlinker()
|
||||
{
|
||||
// Still set up the blinking (heartbeat) interval but skip code path below, so LED will blink if
|
||||
@@ -227,6 +293,7 @@ static int32_t ledBlinker()
|
||||
// have a very sparse duty cycle of LED being on, unless charging, then blink 0.5Hz square wave rate to indicate that
|
||||
return powerStatus->getIsCharging() ? 1000 : (ledOn ? 1 : 1000);
|
||||
}
|
||||
#endif
|
||||
|
||||
uint32_t timeLastPowered = 0;
|
||||
|
||||
@@ -263,11 +330,6 @@ void printInfo()
|
||||
void setup()
|
||||
{
|
||||
|
||||
#ifdef POWER_CHRG
|
||||
pinMode(POWER_CHRG, OUTPUT);
|
||||
digitalWrite(POWER_CHRG, HIGH);
|
||||
#endif
|
||||
|
||||
#if defined(PIN_POWER_EN)
|
||||
pinMode(PIN_POWER_EN, OUTPUT);
|
||||
digitalWrite(PIN_POWER_EN, HIGH);
|
||||
@@ -278,11 +340,6 @@ void setup()
|
||||
digitalWrite(LED_POWER, HIGH);
|
||||
#endif
|
||||
|
||||
#ifdef POWER_LED
|
||||
pinMode(POWER_LED, OUTPUT);
|
||||
digitalWrite(POWER_LED, HIGH);
|
||||
#endif
|
||||
|
||||
#ifdef USER_LED
|
||||
pinMode(USER_LED, OUTPUT);
|
||||
digitalWrite(USER_LED, LOW);
|
||||
@@ -315,9 +372,11 @@ void setup()
|
||||
SPISettings spiSettings(4000000, MSBFIRST, SPI_MODE0);
|
||||
#endif
|
||||
|
||||
#if !HAS_TFT
|
||||
meshtastic_Config_DisplayConfig_OledType screen_model =
|
||||
meshtastic_Config_DisplayConfig_OledType::meshtastic_Config_DisplayConfig_OledType_OLED_AUTO;
|
||||
OLEDDISPLAY_GEOMETRY screen_geometry = GEOMETRY_128_64;
|
||||
#endif
|
||||
|
||||
#ifdef USE_SEGGER
|
||||
auto mode = false ? SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL : SEGGER_RTT_MODE_NO_BLOCK_TRIM;
|
||||
@@ -414,23 +473,15 @@ void setup()
|
||||
|
||||
OSThread::setup();
|
||||
|
||||
#if defined(ELECROW_ThinkNode_M1) || defined(ELECROW_ThinkNode_M2)
|
||||
// The ThinkNodes have their own blink logic
|
||||
ledPeriodic = new Periodic("Blink", elecrowLedBlinker);
|
||||
#else
|
||||
ledPeriodic = new Periodic("Blink", ledBlinker);
|
||||
#endif
|
||||
|
||||
fsInit();
|
||||
|
||||
#if defined(_SEEED_XIAO_NRF52840_SENSE_H_)
|
||||
|
||||
pinMode(CHARGE_LED, INPUT); // sets to detect if charge LED is on or off to see if USB is plugged in
|
||||
|
||||
pinMode(HICHG, OUTPUT);
|
||||
digitalWrite(HICHG, LOW); // 100 mA charging current if set to LOW and 50mA (actually about 20mA) if set to HIGH
|
||||
|
||||
pinMode(BAT_READ, OUTPUT);
|
||||
digitalWrite(BAT_READ, LOW); // This is pin P0_14 = 14 and by pullling low to GND it provices path to read on pin 32 (P0,31)
|
||||
// PIN_VBAT the voltage from divider on XIAO board
|
||||
|
||||
#endif
|
||||
|
||||
#if !MESHTASTIC_EXCLUDE_I2C
|
||||
#if defined(I2C_SDA1) && defined(ARCH_RP2040)
|
||||
Wire1.setSDA(I2C_SDA1);
|
||||
@@ -541,6 +592,7 @@ void setup()
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !HAS_TFT
|
||||
auto screenInfo = i2cScanner->firstScreen();
|
||||
screen_found = screenInfo.type != ScanI2C::DeviceType::NONE ? screenInfo.address : ScanI2C::ADDRESS_NONE;
|
||||
|
||||
@@ -558,6 +610,7 @@ void setup()
|
||||
screen_model = meshtastic_Config_DisplayConfig_OledType::meshtastic_Config_DisplayConfig_OledType_OLED_AUTO;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#define UPDATE_FROM_SCANNER(FIND_FN)
|
||||
|
||||
@@ -626,7 +679,7 @@ void setup()
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL)
|
||||
#if !defined(ARCH_STM32WL)
|
||||
auto acc_info = i2cScanner->firstAccelerometer();
|
||||
accelerometer_found = acc_info.type != ScanI2C::DeviceType::NONE ? acc_info.address : accelerometer_found;
|
||||
LOG_DEBUG("acc_info = %i", acc_info.type);
|
||||
@@ -666,6 +719,7 @@ void setup()
|
||||
scannerToSensorsMap(i2cScanner, ScanI2C::DeviceType::DFROBOT_RAIN, meshtastic_TelemetrySensorType_DFROBOT_RAIN);
|
||||
scannerToSensorsMap(i2cScanner, ScanI2C::DeviceType::LTR390UV, meshtastic_TelemetrySensorType_LTR390UV);
|
||||
scannerToSensorsMap(i2cScanner, ScanI2C::DeviceType::DPS310, meshtastic_TelemetrySensorType_DPS310);
|
||||
scannerToSensorsMap(i2cScanner, ScanI2C::DeviceType::PCT2075, meshtastic_TelemetrySensorType_PCT2075);
|
||||
|
||||
i2cScanner.reset();
|
||||
#endif
|
||||
@@ -725,9 +779,11 @@ void setup()
|
||||
else
|
||||
playStartMelody();
|
||||
|
||||
#if !HAS_TFT
|
||||
// fixed screen override?
|
||||
if (config.display.oled != meshtastic_Config_DisplayConfig_OledType_OLED_AUTO)
|
||||
screen_model = config.display.oled;
|
||||
#endif
|
||||
|
||||
#if defined(USE_SH1107)
|
||||
screen_model = meshtastic_Config_DisplayConfig_OledType_OLED_SH1107; // set dimension of 128x128
|
||||
@@ -739,7 +795,7 @@ void setup()
|
||||
#endif
|
||||
|
||||
#if !MESHTASTIC_EXCLUDE_I2C
|
||||
#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL)
|
||||
#if !defined(ARCH_STM32WL)
|
||||
if (acc_info.type != ScanI2C::DeviceType::NONE) {
|
||||
accelerometerThread = new AccelerometerThread(acc_info.type);
|
||||
}
|
||||
@@ -787,11 +843,16 @@ void setup()
|
||||
#ifdef LORA_TYPE
|
||||
SPI.begin(PIN_EINK_SCLK, 15, PIN_EINK_MOSI, PIN_EINK_CS);
|
||||
LOG_WARN("SPI.begin(SCK=%d, MISO=15, MOSI=%d, NSS=%d)\n", PIN_EINK_SCLK, PIN_EINK_MOSI, PIN_EINK_CS);
|
||||
#elif defined(HW_SPI1_DEVICE)
|
||||
SPI1.begin(LORA_SCK, LORA_MISO, LORA_MOSI, LORA_CS);
|
||||
LOG_DEBUG("SPI1.begin(SCK=%d, MISO=%d, MOSI=%d, NSS=%d)", LORA_SCK, LORA_MISO, LORA_MOSI, LORA_CS);
|
||||
SPI1.setFrequency(4000000);
|
||||
#else
|
||||
SPI.begin(LORA_SCK, LORA_MISO, LORA_MOSI, LORA_CS);
|
||||
LOG_DEBUG("SPI.begin(SCK=%d, MISO=%d, MOSI=%d, NSS=%d)", LORA_SCK, LORA_MISO, LORA_MOSI, LORA_CS);
|
||||
#endif
|
||||
SPI.setFrequency(4000000);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Initialize the screen first so we can show the logo while we start up everything else.
|
||||
@@ -849,12 +910,12 @@ void setup()
|
||||
|
||||
#ifdef HAS_UDP_MULTICAST
|
||||
LOG_DEBUG("Start multicast thread");
|
||||
udpThread = new UdpMulticastThread();
|
||||
udpHandler = new UdpMulticastHandler();
|
||||
#ifdef ARCH_PORTDUINO
|
||||
// FIXME: portduino does not ever call onNetworkConnected so call it here because I don't know what happen if I call
|
||||
// onNetworkConnected there
|
||||
if (config.network.enabled_protocols & meshtastic_Config_NetworkConfig_ProtocolFlags_UDP_BROADCAST) {
|
||||
udpThread->start();
|
||||
udpHandler->start();
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
@@ -885,7 +946,7 @@ void setup()
|
||||
// Don't call screen setup until after nodedb is setup (because we need
|
||||
// the current region name)
|
||||
#if defined(ST7701_CS) || defined(ST7735_CS) || defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ILI9342_DRIVER) || \
|
||||
defined(ST7789_CS) || defined(HX8357_CS) || defined(USE_ST7789)
|
||||
defined(ST7789_CS) || defined(HX8357_CS) || defined(USE_ST7789) || defined(ILI9488_CS)
|
||||
screen->setup();
|
||||
#elif defined(ARCH_PORTDUINO)
|
||||
if (screen_found.port != ScanI2C::I2CPort::NO_I2C || settingsMap[displayPanel]) {
|
||||
@@ -1236,6 +1297,7 @@ void setup()
|
||||
LOG_DEBUG("Free PSRAM : %7d bytes", ESP.getFreePsram());
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
uint32_t rebootAtMsec; // If not zero we will reboot at this time (used to reboot shortly after the update completes)
|
||||
uint32_t shutdownAtMsec; // If not zero we will shutdown at this time (used to shutdown from python or mobile client)
|
||||
@@ -1265,7 +1327,7 @@ extern meshtastic_DeviceMetadata getDeviceMetadata()
|
||||
deviceMetadata.excluded_modules |= meshtastic_ExcludedModules_AUDIO_CONFIG;
|
||||
#endif
|
||||
// Option to explicitly include canned messages for edge cases, e.g. niche graphics
|
||||
#if (!HAS_SCREEN && NO_EXT_GPIO) && !MESHTASTIC_INCLUDE_CANNEDMSG
|
||||
#if (!HAS_SCREEN || NO_EXT_GPIO) || MESHTASTIC_EXCLUDE_CANNEDMESSAGES
|
||||
deviceMetadata.excluded_modules |= meshtastic_ExcludedModules_CANNEDMSG_CONFIG;
|
||||
#endif
|
||||
#if NO_EXT_GPIO
|
||||
@@ -1273,11 +1335,11 @@ extern meshtastic_DeviceMetadata getDeviceMetadata()
|
||||
#endif
|
||||
// Only edge case here is if we apply this a device with built in Accelerometer and want to detect interrupts
|
||||
// We'll have to macro guard against those targets potentially
|
||||
#if NO_EXT_GPIO
|
||||
#if NO_EXT_GPIO || MESHTASTIC_EXCLUDE_DETECTIONSENSOR
|
||||
deviceMetadata.excluded_modules |= meshtastic_ExcludedModules_DETECTIONSENSOR_CONFIG;
|
||||
#endif
|
||||
// If we don't have any GPIO and we don't have GPS, no purpose in having serial config
|
||||
#if NO_EXT_GPIO && NO_GPS
|
||||
// If we don't have any GPIO and we don't have GPS OR we don't want too - no purpose in having serial config
|
||||
#if NO_EXT_GPIO && NO_GPS || MESHTASTIC_EXCLUDE_SERIAL
|
||||
deviceMetadata.excluded_modules |= meshtastic_ExcludedModules_SERIAL_CONFIG;
|
||||
#endif
|
||||
#ifndef ARCH_ESP32
|
||||
|
||||
+3
-3
@@ -51,14 +51,14 @@ extern AudioThread *audioThread;
|
||||
#endif
|
||||
|
||||
#ifdef HAS_UDP_MULTICAST
|
||||
#include "mesh/udp/UdpMulticastThread.h"
|
||||
extern UdpMulticastThread *udpThread;
|
||||
#include "mesh/udp/UdpMulticastHandler.h"
|
||||
extern UdpMulticastHandler *udpHandler;
|
||||
#endif
|
||||
|
||||
// Global Screen singleton.
|
||||
extern graphics::Screen *screen;
|
||||
|
||||
#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_I2C
|
||||
#if !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_I2C
|
||||
#include "motion/AccelerometerThread.h"
|
||||
extern AccelerometerThread *accelerometerThread;
|
||||
#endif
|
||||
|
||||
@@ -345,9 +345,9 @@ void Channels::setChannel(const meshtastic_Channel &c)
|
||||
|
||||
bool Channels::anyMqttEnabled()
|
||||
{
|
||||
#if USERPREFS_EVENT_MODE
|
||||
#if USERPREFS_EVENT_MODE && !MESHTASTIC_EXCLUDE_MQTT
|
||||
// Don't publish messages on the public MQTT broker if we are in event mode
|
||||
if (mqtt && mqtt->isUsingDefaultServer()) {
|
||||
if (mqtt && mqtt->isUsingDefaultServer() && mqtt->isUsingDefaultRootTopic()) {
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -3,12 +3,17 @@
|
||||
#include "architecture.h"
|
||||
|
||||
#if !(MESHTASTIC_EXCLUDE_PKI)
|
||||
#include "NodeDB.h"
|
||||
#include "aes-ccm.h"
|
||||
#include "meshUtils.h"
|
||||
#include <Crypto.h>
|
||||
#include <Curve25519.h>
|
||||
#include <RNG.h>
|
||||
#include <SHA256.h>
|
||||
#if !(MESHTASTIC_EXCLUDE_PKI_KEYGEN)
|
||||
#if !defined(ARCH_STM32WL)
|
||||
#define CryptRNG RNG
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Create a public/private key pair with Curve25519.
|
||||
@@ -18,6 +23,14 @@
|
||||
*/
|
||||
void CryptoEngine::generateKeyPair(uint8_t *pubKey, uint8_t *privKey)
|
||||
{
|
||||
// Mix in any randomness we can, to make key generation stronger.
|
||||
CryptRNG.begin(optstr(APP_VERSION));
|
||||
if (myNodeInfo.device_id.size == 16) {
|
||||
CryptRNG.stir(myNodeInfo.device_id.bytes, myNodeInfo.device_id.size);
|
||||
}
|
||||
auto noise = random();
|
||||
CryptRNG.stir((uint8_t *)&noise, sizeof(noise));
|
||||
|
||||
LOG_DEBUG("Generate Curve25519 keypair");
|
||||
Curve25519::dh1(public_key, private_key);
|
||||
memcpy(pubKey, public_key, sizeof(public_key));
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#define ONE_MINUTE_MS 60 * 1000
|
||||
#define THIRTY_SECONDS_MS 30 * 1000
|
||||
#define FIVE_SECONDS_MS 5 * 1000
|
||||
#define TEN_SECONDS_MS 10 * 1000
|
||||
|
||||
#define min_default_telemetry_interval_secs 30 * 60
|
||||
#define default_gps_update_interval IF_ROUTER(ONE_DAY, 2 * 60)
|
||||
@@ -20,11 +21,14 @@
|
||||
#define default_neighbor_info_broadcast_secs 6 * 60 * 60
|
||||
#define min_node_info_broadcast_secs 60 * 60 // No regular broadcasts of more than once an hour
|
||||
#define min_neighbor_info_broadcast_secs 4 * 60 * 60
|
||||
#define default_map_publish_interval_secs 60 * 60
|
||||
|
||||
#define default_mqtt_address "mqtt.meshtastic.org"
|
||||
#define default_mqtt_username "meshdev"
|
||||
#define default_mqtt_password "large4cats"
|
||||
#define default_mqtt_root "msh"
|
||||
#define default_mqtt_encryption_enabled true
|
||||
#define default_mqtt_tls_enabled false
|
||||
|
||||
#define IF_ROUTER(routerVal, normalVal) \
|
||||
((config.device.role == meshtastic_Config_DeviceConfig_Role_ROUTER) ? (routerVal) : (normalVal))
|
||||
|
||||
@@ -71,6 +71,8 @@ template <typename T> bool LR11x0Interface<T>::init()
|
||||
|
||||
RadioLibInterface::init();
|
||||
|
||||
limitPower();
|
||||
|
||||
if (power > LR1110_MAX_POWER) // Clamp power to maximum defined level
|
||||
power = LR1110_MAX_POWER;
|
||||
|
||||
@@ -80,8 +82,6 @@ template <typename T> bool LR11x0Interface<T>::init()
|
||||
preambleLength = 12; // 12 is the default for operation above 2GHz
|
||||
}
|
||||
|
||||
limitPower();
|
||||
|
||||
#ifdef LR11X0_RF_SWITCH_SUBGHZ
|
||||
pinMode(LR11X0_RF_SWITCH_SUBGHZ, OUTPUT);
|
||||
digitalWrite(LR11X0_RF_SWITCH_SUBGHZ, getFreq() < 1e9 ? HIGH : LOW);
|
||||
@@ -247,8 +247,8 @@ template <typename T> void LR11x0Interface<T>::startReceive()
|
||||
lora.setPreambleLength(preambleLength); // Solve RX ack fail after direct message sent. Not sure why this is needed.
|
||||
|
||||
// We use a 16 bit preamble so this should save some power by letting radio sit in standby mostly.
|
||||
// Furthermore, we need the PREAMBLE_DETECTED and HEADER_VALID IRQ flag to detect whether we are actively receiving
|
||||
int err = lora.startReceive(RADIOLIB_LR11X0_RX_TIMEOUT_INF, RADIOLIB_IRQ_RX_DEFAULT_FLAGS, RADIOLIB_IRQ_RX_DEFAULT_MASK, 0);
|
||||
int err =
|
||||
lora.startReceive(RADIOLIB_LR11X0_RX_TIMEOUT_INF, MESHTASTIC_RADIOLIB_IRQ_RX_FLAGS, RADIOLIB_IRQ_RX_DEFAULT_MASK, 0);
|
||||
assert(err == RADIOLIB_ERR_NONE);
|
||||
|
||||
RadioLibInterface::startReceive();
|
||||
|
||||
@@ -165,10 +165,15 @@ bool NextHopRouter::stopRetransmission(GlobalPacketId key)
|
||||
/* Only when we already transmitted a packet via LoRa, we will cancel the packet in the Tx queue
|
||||
to avoid canceling a transmission if it was ACKed super fast via MQTT */
|
||||
if (old->numRetransmissions < NUM_RELIABLE_RETX - 1) {
|
||||
// remove the 'original' (identified by originator and packet->id) from the txqueue and free it
|
||||
cancelSending(getFrom(p), p->id);
|
||||
// now free the pooled copy for retransmission too
|
||||
packetPool.release(p);
|
||||
// We only cancel it if we are the original sender or if we're not a router(_late)/repeater
|
||||
if (isFromUs(p) || (config.device.role != meshtastic_Config_DeviceConfig_Role_ROUTER &&
|
||||
config.device.role != meshtastic_Config_DeviceConfig_Role_REPEATER &&
|
||||
config.device.role != meshtastic_Config_DeviceConfig_Role_ROUTER_LATE)) {
|
||||
// remove the 'original' (identified by originator and packet->id) from the txqueue and free it
|
||||
cancelSending(getFrom(p), p->id);
|
||||
// now free the pooled copy for retransmission too
|
||||
packetPool.release(p);
|
||||
}
|
||||
}
|
||||
auto numErased = pending.erase(key);
|
||||
assert(numErased == 1);
|
||||
|
||||
+90
-8
@@ -261,7 +261,7 @@ NodeDB::NodeDB()
|
||||
|
||||
#if !(MESHTASTIC_EXCLUDE_PKI_KEYGEN || MESHTASTIC_EXCLUDE_PKI)
|
||||
|
||||
if (!owner.is_licensed) {
|
||||
if (!owner.is_licensed && config.lora.region != meshtastic_Config_LoRaConfig_RegionCode_UNSET) {
|
||||
bool keygenSuccess = false;
|
||||
if (config.security.private_key.size == 32) {
|
||||
if (crypto->regeneratePublicKey(config.security.public_key.bytes, config.security.private_key.bytes)) {
|
||||
@@ -328,6 +328,11 @@ NodeDB::NodeDB()
|
||||
moduleConfig.telemetry.health_update_interval = Default::getConfiguredOrMinimumValue(
|
||||
moduleConfig.telemetry.health_update_interval, min_default_telemetry_interval_secs);
|
||||
}
|
||||
if (moduleConfig.mqtt.has_map_report_settings &&
|
||||
moduleConfig.mqtt.map_report_settings.publish_interval_secs < default_map_publish_interval_secs) {
|
||||
moduleConfig.mqtt.map_report_settings.publish_interval_secs = default_map_publish_interval_secs;
|
||||
}
|
||||
|
||||
// Ensure that the neighbor info update interval is coerced to the minimum
|
||||
moduleConfig.neighbor_info.update_interval =
|
||||
Default::getConfiguredOrMinimumValue(moduleConfig.neighbor_info.update_interval, min_neighbor_info_broadcast_secs);
|
||||
@@ -450,7 +455,6 @@ bool NodeDB::factoryReset(bool eraseBleBonds)
|
||||
nvs_flash_erase();
|
||||
#endif
|
||||
#ifdef ARCH_NRF52
|
||||
Bluefruit.begin();
|
||||
LOG_INFO("Clear bluetooth bonds!");
|
||||
bond_print_list(BLE_GAP_ROLE_PERIPH);
|
||||
bond_print_list(BLE_GAP_ROLE_CENTRAL);
|
||||
@@ -584,7 +588,8 @@ void NodeDB::installDefaultConfig(bool preserveKey = false)
|
||||
resetRadioConfig(true); // This also triggers NodeInfo/Position requests since we're fresh
|
||||
strncpy(config.network.ntp_server, "meshtastic.pool.ntp.org", 32);
|
||||
|
||||
#if (defined(T_DECK) || defined(T_WATCH_S3) || defined(UNPHONE) || defined(PICOMPUTER_S3) || defined(SENSECAP_INDICATOR)) && \
|
||||
#if (defined(T_DECK) || defined(T_WATCH_S3) || defined(UNPHONE) || defined(PICOMPUTER_S3) || defined(SENSECAP_INDICATOR) || \
|
||||
defined(ELECROW_PANEL)) && \
|
||||
HAS_TFT
|
||||
// switch BT off by default; use TFT programming mode or hotkey to enable
|
||||
config.bluetooth.enabled = false;
|
||||
@@ -595,7 +600,7 @@ void NodeDB::installDefaultConfig(bool preserveKey = false)
|
||||
config.bluetooth.fixed_pin = defaultBLEPin;
|
||||
|
||||
#if defined(ST7735_CS) || defined(USE_EINK) || defined(ILI9341_DRIVER) || defined(ILI9342_DRIVER) || defined(ST7789_CS) || \
|
||||
defined(HX8357_CS) || defined(USE_ST7789)
|
||||
defined(HX8357_CS) || defined(USE_ST7789) || defined(ILI9488_CS)
|
||||
bool hasScreen = true;
|
||||
#ifdef HELTEC_MESH_NODE_T114
|
||||
uint32_t st7789_id = get_st7789_id(ST7789_NSS, ST7789_SCK, ST7789_SDA, ST7789_RS, ST7789_RESET);
|
||||
@@ -689,7 +694,7 @@ void NodeDB::initConfigIntervals()
|
||||
|
||||
config.display.screen_on_secs = default_screen_on_secs;
|
||||
|
||||
#if defined(T_WATCH_S3) || defined(T_DECK) || defined(UNPHONE) || defined(MESH_TAB) || defined(RAK14014)
|
||||
#if defined(USE_POWERSAVE)
|
||||
config.power.is_power_saving = true;
|
||||
config.display.screen_on_secs = 30;
|
||||
config.power.wait_bluetooth_secs = 30;
|
||||
@@ -743,6 +748,15 @@ void NodeDB::installDefaultModuleConfig()
|
||||
moduleConfig.external_notification.output_ms = 100;
|
||||
moduleConfig.external_notification.active = true;
|
||||
#endif
|
||||
#ifdef ELECROW_ThinkNode_M1
|
||||
// Default to Elecrow USER_LED (blue)
|
||||
moduleConfig.external_notification.enabled = true;
|
||||
moduleConfig.external_notification.output = USER_LED;
|
||||
moduleConfig.external_notification.active = true;
|
||||
moduleConfig.external_notification.alert_message = true;
|
||||
moduleConfig.external_notification.output_ms = 1000;
|
||||
moduleConfig.external_notification.nag_timeout = 60;
|
||||
#endif
|
||||
#ifdef BUTTON_SECONDARY_CANNEDMESSAGES
|
||||
// Use a board's second built-in button as input source for canned messages
|
||||
moduleConfig.canned_message.enabled = true;
|
||||
@@ -752,11 +766,39 @@ void NodeDB::installDefaultModuleConfig()
|
||||
|
||||
moduleConfig.has_canned_message = true;
|
||||
|
||||
#if USERPREFS_MQTT_ENABLED && !MESHTASTIC_EXCLUDE_MQTT
|
||||
moduleConfig.mqtt.enabled = true;
|
||||
#endif
|
||||
#ifdef USERPREFS_MQTT_ADDRESS
|
||||
strncpy(moduleConfig.mqtt.address, USERPREFS_MQTT_ADDRESS, sizeof(moduleConfig.mqtt.address));
|
||||
#else
|
||||
strncpy(moduleConfig.mqtt.address, default_mqtt_address, sizeof(moduleConfig.mqtt.address));
|
||||
#endif
|
||||
#ifdef USERPREFS_MQTT_USERNAME
|
||||
strncpy(moduleConfig.mqtt.username, USERPREFS_MQTT_USERNAME, sizeof(moduleConfig.mqtt.username));
|
||||
#else
|
||||
strncpy(moduleConfig.mqtt.username, default_mqtt_username, sizeof(moduleConfig.mqtt.username));
|
||||
#endif
|
||||
#ifdef USERPREFS_MQTT_PASSWORD
|
||||
strncpy(moduleConfig.mqtt.password, USERPREFS_MQTT_PASSWORD, sizeof(moduleConfig.mqtt.password));
|
||||
#else
|
||||
strncpy(moduleConfig.mqtt.password, default_mqtt_password, sizeof(moduleConfig.mqtt.password));
|
||||
#endif
|
||||
#ifdef USERPREFS_MQTT_ROOT_TOPIC
|
||||
strncpy(moduleConfig.mqtt.root, USERPREFS_MQTT_ROOT_TOPIC, sizeof(moduleConfig.mqtt.root));
|
||||
#else
|
||||
strncpy(moduleConfig.mqtt.root, default_mqtt_root, sizeof(moduleConfig.mqtt.root));
|
||||
moduleConfig.mqtt.encryption_enabled = true;
|
||||
#endif
|
||||
#ifdef USERPREFS_MQTT_ENCRYPTION_ENABLED
|
||||
moduleConfig.mqtt.encryption_enabled = USERPREFS_MQTT_ENCRYPTION_ENABLED;
|
||||
#else
|
||||
moduleConfig.mqtt.encryption_enabled = default_mqtt_encryption_enabled;
|
||||
#endif
|
||||
#ifdef USERPREFS_MQTT_TLS_ENABLED
|
||||
moduleConfig.mqtt.tls_enabled = USERPREFS_MQTT_TLS_ENABLED;
|
||||
#else
|
||||
moduleConfig.mqtt.tls_enabled = default_mqtt_tls_enabled;
|
||||
#endif
|
||||
|
||||
moduleConfig.has_neighbor_info = true;
|
||||
moduleConfig.neighbor_info.enabled = false;
|
||||
@@ -782,10 +824,19 @@ void NodeDB::installRoleDefaults(meshtastic_Config_DeviceConfig_Role role)
|
||||
initConfigIntervals();
|
||||
initModuleConfigIntervals();
|
||||
config.device.rebroadcast_mode = meshtastic_Config_DeviceConfig_RebroadcastMode_CORE_PORTNUMS_ONLY;
|
||||
owner.has_is_unmessagable = true;
|
||||
owner.is_unmessagable = true;
|
||||
} else if (role == meshtastic_Config_DeviceConfig_Role_ROUTER_LATE) {
|
||||
owner.has_is_unmessagable = true;
|
||||
owner.is_unmessagable = true;
|
||||
} else if (role == meshtastic_Config_DeviceConfig_Role_REPEATER) {
|
||||
owner.has_is_unmessagable = true;
|
||||
owner.is_unmessagable = true;
|
||||
config.display.screen_on_secs = 1;
|
||||
config.device.rebroadcast_mode = meshtastic_Config_DeviceConfig_RebroadcastMode_CORE_PORTNUMS_ONLY;
|
||||
} else if (role == meshtastic_Config_DeviceConfig_Role_SENSOR) {
|
||||
owner.has_is_unmessagable = true;
|
||||
owner.is_unmessagable = true;
|
||||
moduleConfig.telemetry.environment_measurement_enabled = true;
|
||||
moduleConfig.telemetry.environment_update_interval = 300;
|
||||
} else if (role == meshtastic_Config_DeviceConfig_Role_LOST_AND_FOUND) {
|
||||
@@ -800,7 +851,12 @@ void NodeDB::installRoleDefaults(meshtastic_Config_DeviceConfig_Role role)
|
||||
(meshtastic_Config_PositionConfig_PositionFlags_ALTITUDE | meshtastic_Config_PositionConfig_PositionFlags_SPEED |
|
||||
meshtastic_Config_PositionConfig_PositionFlags_HEADING | meshtastic_Config_PositionConfig_PositionFlags_DOP);
|
||||
moduleConfig.telemetry.device_update_interval = ONE_DAY;
|
||||
} else if (role == meshtastic_Config_DeviceConfig_Role_TRACKER) {
|
||||
owner.has_is_unmessagable = true;
|
||||
owner.is_unmessagable = true;
|
||||
} else if (role == meshtastic_Config_DeviceConfig_Role_TAK_TRACKER) {
|
||||
owner.has_is_unmessagable = true;
|
||||
owner.is_unmessagable = true;
|
||||
config.device.node_info_broadcast_secs = ONE_DAY;
|
||||
config.position.position_broadcast_smart_enabled = true;
|
||||
config.position.position_broadcast_secs = 3 * 60; // Every 3 minutes
|
||||
@@ -933,6 +989,8 @@ void NodeDB::installDefaultDeviceState()
|
||||
#endif
|
||||
snprintf(owner.id, sizeof(owner.id), "!%08x", getNodeNum()); // Default node ID now based on nodenum
|
||||
memcpy(owner.macaddr, ourMacAddr, sizeof(owner.macaddr));
|
||||
owner.has_is_unmessagable = true;
|
||||
owner.is_unmessagable = false;
|
||||
}
|
||||
|
||||
// We reserve a few nodenums for future use
|
||||
@@ -1446,6 +1504,28 @@ void NodeDB::updateTelemetry(uint32_t nodeId, const meshtastic_Telemetry &t, RxS
|
||||
notifyObservers(true); // Force an update whether or not our node counts have changed
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the node database with a new contact
|
||||
*/
|
||||
void NodeDB::addFromContact(meshtastic_SharedContact contact)
|
||||
{
|
||||
meshtastic_NodeInfoLite *info = getOrCreateMeshNode(contact.node_num);
|
||||
if (!info) {
|
||||
return;
|
||||
}
|
||||
info->num = contact.node_num;
|
||||
info->last_heard = getValidTime(RTCQualityNTP);
|
||||
info->has_user = true;
|
||||
info->user = TypeConversions::ConvertToUserLite(contact.user);
|
||||
info->is_favorite = true;
|
||||
// Mark the node's key as manually verified to indicate trustworthiness.
|
||||
info->bitfield |= NODEINFO_BITFIELD_IS_KEY_MANUALLY_VERIFIED_MASK;
|
||||
updateGUIforNode = info;
|
||||
powerFSM.trigger(EVENT_NODEDB_UPDATED);
|
||||
notifyObservers(true); // Force an update whether or not our node counts have changed
|
||||
saveNodeDatabaseToDisk();
|
||||
}
|
||||
|
||||
/** Update user info and channel for this node based on received user data
|
||||
*/
|
||||
bool NodeDB::updateUser(uint32_t nodeId, meshtastic_User &p, uint8_t channelIndex)
|
||||
@@ -1575,8 +1655,10 @@ meshtastic_NodeInfoLite *NodeDB::getOrCreateMeshNode(NodeNum n)
|
||||
int oldestIndex = -1;
|
||||
int oldestBoringIndex = -1;
|
||||
for (int i = 1; i < numMeshNodes; i++) {
|
||||
// Simply the oldest non-favorite node
|
||||
if (!meshNodes->at(i).is_favorite && !meshNodes->at(i).is_ignored && meshNodes->at(i).last_heard < oldest) {
|
||||
// Simply the oldest non-favorite, non-ignored, non-verified node
|
||||
if (!meshNodes->at(i).is_favorite && !meshNodes->at(i).is_ignored &&
|
||||
!(meshNodes->at(i).bitfield & NODEINFO_BITFIELD_IS_KEY_MANUALLY_VERIFIED_MASK) &&
|
||||
meshNodes->at(i).last_heard < oldest) {
|
||||
oldest = meshNodes->at(i).last_heard;
|
||||
oldestIndex = i;
|
||||
}
|
||||
|
||||
@@ -110,6 +110,8 @@ class NodeDB
|
||||
/// we updateGUI and updateGUIforNode if we think our this change is big enough for a redraw
|
||||
void updateFrom(const meshtastic_MeshPacket &p);
|
||||
|
||||
void addFromContact(const meshtastic_SharedContact);
|
||||
|
||||
/** Update position info for this node based on received position data
|
||||
*/
|
||||
void updatePosition(uint32_t nodeId, const meshtastic_Position &p, RxSource src = RX_SRC_RADIO);
|
||||
@@ -272,6 +274,8 @@ extern meshtastic_CriticalErrorCode error_code;
|
||||
* A numeric error address (nonzero if available)
|
||||
*/
|
||||
extern uint32_t error_address;
|
||||
#define NODEINFO_BITFIELD_IS_KEY_MANUALLY_VERIFIED_SHIFT 0
|
||||
#define NODEINFO_BITFIELD_IS_KEY_MANUALLY_VERIFIED_MASK (1 << NODEINFO_BITFIELD_IS_KEY_MANUALLY_VERIFIED_SHIFT)
|
||||
|
||||
#define Module_Config_size \
|
||||
(ModuleConfig_CannedMessageConfig_size + ModuleConfig_ExternalNotificationConfig_size + ModuleConfig_MQTTConfig_size + \
|
||||
|
||||
+33
-10
@@ -54,7 +54,13 @@ void PhoneAPI::handleStartConfig()
|
||||
}
|
||||
|
||||
// even if we were already connected - restart our state machine
|
||||
state = STATE_SEND_MY_INFO;
|
||||
if (config_nonce == SPECIAL_NONCE_ONLY_NODES) {
|
||||
// If client only wants node info, jump directly to sending nodes
|
||||
state = STATE_SEND_OWN_NODEINFO;
|
||||
LOG_INFO("Client only wants node info, skipping other config");
|
||||
} else {
|
||||
state = STATE_SEND_MY_INFO;
|
||||
}
|
||||
pauseBluetoothLogging = true;
|
||||
spiLock->lock();
|
||||
filesManifest = getFiles("/", 10);
|
||||
@@ -224,7 +230,12 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf)
|
||||
// Should allow us to resume sending NodeInfo in STATE_SEND_OTHER_NODEINFOS
|
||||
nodeInfoForPhone.num = 0;
|
||||
}
|
||||
state = STATE_SEND_METADATA;
|
||||
if (config_nonce == SPECIAL_NONCE_ONLY_NODES) {
|
||||
// If client only wants node info, jump directly to sending nodes
|
||||
state = STATE_SEND_OTHER_NODEINFOS;
|
||||
} else {
|
||||
state = STATE_SEND_METADATA;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -388,8 +399,14 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf)
|
||||
config_state++;
|
||||
// Advance when we have sent all of our ModuleConfig objects
|
||||
if (config_state > (_meshtastic_AdminMessage_ModuleConfigType_MAX + 1)) {
|
||||
// Clients sending special nonce don't want to see other nodeinfos
|
||||
state = config_nonce == SPECIAL_NONCE ? STATE_SEND_FILEMANIFEST : STATE_SEND_OTHER_NODEINFOS;
|
||||
// Handle special nonce behaviors:
|
||||
// - SPECIAL_NONCE_ONLY_CONFIG: Skip node info, go directly to file manifest
|
||||
// - SPECIAL_NONCE_ONLY_NODES: After sending nodes, skip to complete
|
||||
if (config_nonce == SPECIAL_NONCE_ONLY_CONFIG) {
|
||||
state = STATE_SEND_FILEMANIFEST;
|
||||
} else {
|
||||
state = STATE_SEND_OTHER_NODEINFOS;
|
||||
}
|
||||
config_state = 0;
|
||||
}
|
||||
break;
|
||||
@@ -415,7 +432,8 @@ size_t PhoneAPI::getFromRadio(uint8_t *buf)
|
||||
case STATE_SEND_FILEMANIFEST: {
|
||||
LOG_DEBUG("FromRadio=STATE_SEND_FILEMANIFEST");
|
||||
// last element
|
||||
if (config_state == filesManifest.size()) { // also handles an empty filesManifest
|
||||
if (config_state == filesManifest.size() ||
|
||||
config_nonce == SPECIAL_NONCE_ONLY_NODES) { // also handles an empty filesManifest
|
||||
config_state = 0;
|
||||
filesManifest.clear();
|
||||
// Skip to complete packet
|
||||
@@ -547,9 +565,12 @@ bool PhoneAPI::available()
|
||||
auto nextNode = nodeDB->readNextMeshNode(readIndex);
|
||||
if (nextNode) {
|
||||
nodeInfoForPhone = TypeConversions::ConvertToNodeInfo(nextNode);
|
||||
nodeInfoForPhone.hops_away = nodeInfoForPhone.num == nodeDB->getNodeNum() ? 0 : nodeInfoForPhone.hops_away;
|
||||
nodeInfoForPhone.is_favorite =
|
||||
nodeInfoForPhone.is_favorite || nodeInfoForPhone.num == nodeDB->getNodeNum(); // Our node is always a favorite
|
||||
bool isUs = nodeInfoForPhone.num == nodeDB->getNodeNum();
|
||||
nodeInfoForPhone.hops_away = isUs ? 0 : nodeInfoForPhone.hops_away;
|
||||
nodeInfoForPhone.last_heard = isUs ? getValidTime(RTCQualityFromNet) : nodeInfoForPhone.last_heard;
|
||||
nodeInfoForPhone.snr = isUs ? 0 : nodeInfoForPhone.snr;
|
||||
nodeInfoForPhone.via_mqtt = isUs ? false : nodeInfoForPhone.via_mqtt;
|
||||
nodeInfoForPhone.is_favorite = nodeInfoForPhone.is_favorite || isUs; // Our node is always a favorite
|
||||
}
|
||||
}
|
||||
return true; // Always say we have something, because we might need to advance our state machine
|
||||
@@ -649,8 +670,10 @@ bool PhoneAPI::handleToRadioPacket(meshtastic_MeshPacket &p)
|
||||
meshtastic_QueueStatus qs = router->getQueueStatus();
|
||||
service->sendQueueStatusToPhone(qs, 0, p.id);
|
||||
return false;
|
||||
} else if (p.decoded.portnum == meshtastic_PortNum_POSITION_APP && lastPortNumToRadio[p.decoded.portnum] &&
|
||||
Throttle::isWithinTimespanMs(lastPortNumToRadio[p.decoded.portnum], FIVE_SECONDS_MS)) {
|
||||
} else if (IS_ONE_OF(meshtastic_PortNum_POSITION_APP, meshtastic_PortNum_WAYPOINT_APP, meshtastic_PortNum_ALERT_APP) &&
|
||||
lastPortNumToRadio[p.decoded.portnum] &&
|
||||
Throttle::isWithinTimespanMs(lastPortNumToRadio[p.decoded.portnum], TEN_SECONDS_MS)) {
|
||||
// TODO: [Issue #6700] Make this rate limit throttling scale up / down with the preset
|
||||
LOG_WARN("Rate limit portnum %d", p.decoded.portnum);
|
||||
meshtastic_QueueStatus qs = router->getQueueStatus();
|
||||
service->sendQueueStatusToPhone(qs, 0, p.id);
|
||||
|
||||
+2
-1
@@ -18,7 +18,8 @@
|
||||
#error "meshtastic_ToRadio_size is too large for our BLE packets"
|
||||
#endif
|
||||
|
||||
#define SPECIAL_NONCE 69420
|
||||
#define SPECIAL_NONCE_ONLY_CONFIG 69420
|
||||
#define SPECIAL_NONCE_ONLY_NODES 69421 // ( ͡° ͜ʖ ͡°)
|
||||
|
||||
/**
|
||||
* Provides our protobuf based API which phone/PC clients can use to talk to our device
|
||||
|
||||
@@ -122,11 +122,11 @@ bool RF95Interface::init()
|
||||
power = dacDbValues.db;
|
||||
#endif
|
||||
|
||||
limitPower();
|
||||
|
||||
if (power > RF95_MAX_POWER) // This chip has lower power limits than some
|
||||
power = RF95_MAX_POWER;
|
||||
|
||||
limitPower();
|
||||
|
||||
iface = lora = new RadioLibRF95(&module);
|
||||
|
||||
#ifdef RF95_TCXO
|
||||
|
||||
@@ -528,8 +528,8 @@ void RadioInterface::applyModemConfig()
|
||||
|
||||
power = loraConfig.tx_power;
|
||||
|
||||
if ((power == 0) || ((power + REGULATORY_GAIN_LORA > myRegion->powerLimit) && !devicestate.owner.is_licensed))
|
||||
power = myRegion->powerLimit - REGULATORY_GAIN_LORA;
|
||||
if ((power == 0) || ((power > myRegion->powerLimit) && !devicestate.owner.is_licensed))
|
||||
power = myRegion->powerLimit;
|
||||
|
||||
if (power == 0)
|
||||
power = 17; // Default to this power level if we don't have a valid regional power limit (powerLimit of myRegion defaults
|
||||
@@ -616,7 +616,12 @@ void RadioInterface::limitPower()
|
||||
power = maxPower;
|
||||
}
|
||||
|
||||
LOG_INFO("Set radio: final power level=%d", power);
|
||||
if (TX_GAIN_LORA > 0) {
|
||||
LOG_INFO("Requested Tx power: %d dBm; Device LoRa Tx gain: %d dB", power, TX_GAIN_LORA);
|
||||
power -= TX_GAIN_LORA;
|
||||
}
|
||||
|
||||
LOG_INFO("Final Tx power: %d dBm", power);
|
||||
}
|
||||
|
||||
void RadioInterface::deliverToReceiver(meshtastic_MeshPacket *p)
|
||||
|
||||
@@ -210,6 +210,14 @@ bool RadioLibInterface::canSleep()
|
||||
return res;
|
||||
}
|
||||
|
||||
/** Allow other firmware components to ask whether we are currently sending a packet
|
||||
Initially implemented to protect T-Echo's capacitive touch button from spurious presses during tx
|
||||
*/
|
||||
bool RadioLibInterface::isSending()
|
||||
{
|
||||
return sendingPacket != NULL;
|
||||
}
|
||||
|
||||
/** Attempt to cancel a previously sent packet. Returns true if a packet was found we could cancel */
|
||||
bool RadioLibInterface::cancelSending(NodeNum from, PacketId id)
|
||||
{
|
||||
|
||||
@@ -16,6 +16,9 @@
|
||||
|
||||
#define RADIOLIB_PIN_TYPE uint32_t
|
||||
|
||||
// In addition to the default Rx flags, we need the PREAMBLE_DETECTED flag to detect whether we are actively receiving
|
||||
#define MESHTASTIC_RADIOLIB_IRQ_RX_FLAGS (RADIOLIB_IRQ_RX_DEFAULT_FLAGS | (1 << RADIOLIB_IRQ_PREAMBLE_DETECTED))
|
||||
|
||||
/**
|
||||
* We need to override the RadioLib ArduinoHal class to add mutex protection for SPI bus access
|
||||
*/
|
||||
@@ -132,6 +135,11 @@ class RadioLibInterface : public RadioInterface, protected concurrency::Notified
|
||||
*/
|
||||
virtual bool isActivelyReceiving() = 0;
|
||||
|
||||
/** Are we are currently sending a packet?
|
||||
* This method is public, intending to expose this information to other firmware components
|
||||
*/
|
||||
virtual bool isSending();
|
||||
|
||||
/** Attempt to cancel a previously sent packet. Returns true if a packet was found we could cancel */
|
||||
virtual bool cancelSending(NodeNum from, PacketId id) override;
|
||||
|
||||
|
||||
+6
-5
@@ -283,11 +283,6 @@ ErrorCode Router::send(meshtastic_MeshPacket *p)
|
||||
abortSendAndNak(encodeResult, p);
|
||||
return encodeResult; // FIXME - this isn't a valid ErrorCode
|
||||
}
|
||||
#if HAS_UDP_MULTICAST
|
||||
if (udpThread && config.network.enabled_protocols & meshtastic_Config_NetworkConfig_ProtocolFlags_UDP_BROADCAST) {
|
||||
udpThread->onSend(const_cast<meshtastic_MeshPacket *>(p));
|
||||
}
|
||||
#endif
|
||||
#if !MESHTASTIC_EXCLUDE_MQTT
|
||||
// Only publish to MQTT if we're the original transmitter of the packet
|
||||
if (moduleConfig.mqtt.enabled && isFromUs(p) && mqtt) {
|
||||
@@ -297,6 +292,12 @@ ErrorCode Router::send(meshtastic_MeshPacket *p)
|
||||
packetPool.release(p_decoded);
|
||||
}
|
||||
|
||||
#if HAS_UDP_MULTICAST
|
||||
if (udpHandler && config.network.enabled_protocols & meshtastic_Config_NetworkConfig_ProtocolFlags_UDP_BROADCAST) {
|
||||
udpHandler->onSend(const_cast<meshtastic_MeshPacket *>(p));
|
||||
}
|
||||
#endif
|
||||
|
||||
assert(iface); // This should have been detected already in sendLocal (or we just received a packet from outside)
|
||||
return iface->send(p);
|
||||
}
|
||||
|
||||
@@ -25,11 +25,11 @@ bool STM32WLE5JCInterface::init()
|
||||
|
||||
lora.setRfSwitchTable(rfswitch_pins, rfswitch_table);
|
||||
|
||||
limitPower();
|
||||
|
||||
if (power > STM32WLx_MAX_POWER) // This chip has lower power limits than some
|
||||
power = STM32WLx_MAX_POWER;
|
||||
|
||||
limitPower();
|
||||
|
||||
int res = lora.begin(getFreq(), bw, sf, cr, syncWord, power, preambleLength, tcxoVoltage);
|
||||
|
||||
LOG_INFO("STM32WLx init result %d", res);
|
||||
|
||||
@@ -69,11 +69,11 @@ template <typename T> bool SX126xInterface<T>::init()
|
||||
|
||||
RadioLibInterface::init();
|
||||
|
||||
limitPower();
|
||||
|
||||
if (power > SX126X_MAX_POWER) // Clamp power to maximum defined level
|
||||
power = SX126X_MAX_POWER;
|
||||
|
||||
limitPower();
|
||||
|
||||
int res = lora.begin(getFreq(), bw, sf, cr, syncWord, power, preambleLength, tcxoVoltage, useRegulatorLDO);
|
||||
// \todo Display actual typename of the adapter, not just `SX126x`
|
||||
LOG_INFO("SX126x init result %d", res);
|
||||
@@ -277,8 +277,7 @@ template <typename T> void SX126xInterface<T>::startReceive()
|
||||
setStandby();
|
||||
|
||||
// We use a 16 bit preamble so this should save some power by letting radio sit in standby mostly.
|
||||
// Furthermore, we need the PREAMBLE_DETECTED and HEADER_VALID IRQ flag to detect whether we are actively receiving
|
||||
int err = lora.startReceiveDutyCycleAuto(preambleLength, 8, RADIOLIB_IRQ_RX_DEFAULT_FLAGS | RADIOLIB_IRQ_PREAMBLE_DETECTED);
|
||||
int err = lora.startReceiveDutyCycleAuto(preambleLength, 8, MESHTASTIC_RADIOLIB_IRQ_RX_FLAGS);
|
||||
if (err != RADIOLIB_ERR_NONE)
|
||||
LOG_ERROR("SX126X startReceiveDutyCycleAuto %s%d", radioLibErr, err);
|
||||
assert(err == RADIOLIB_ERR_NONE);
|
||||
|
||||
@@ -62,11 +62,11 @@ template <typename T> bool SX128xInterface<T>::init()
|
||||
|
||||
RadioLibInterface::init();
|
||||
|
||||
limitPower();
|
||||
|
||||
if (power > SX128X_MAX_POWER) // This chip has lower power limits than some
|
||||
power = SX128X_MAX_POWER;
|
||||
|
||||
limitPower();
|
||||
|
||||
preambleLength = 12; // 12 is the default for this chip, 32 does not RX at all
|
||||
|
||||
int res = lora.begin(getFreq(), bw, sf, cr, syncWord, power, preambleLength);
|
||||
@@ -260,8 +260,7 @@ template <typename T> void SX128xInterface<T>::startReceive()
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// We use the PREAMBLE_DETECTED and HEADER_VALID IRQ flag to detect whether we are actively receiving
|
||||
int err = lora.startReceive(RADIOLIB_SX128X_RX_TIMEOUT_INF, RADIOLIB_IRQ_RX_DEFAULT_FLAGS | RADIOLIB_IRQ_PREAMBLE_DETECTED);
|
||||
int err = lora.startReceive(RADIOLIB_SX128X_RX_TIMEOUT_INF, MESHTASTIC_RADIOLIB_IRQ_RX_FLAGS);
|
||||
|
||||
if (err != RADIOLIB_ERR_NONE)
|
||||
LOG_ERROR("SX128X startReceive %s%d", radioLibErr, err);
|
||||
|
||||
@@ -13,6 +13,7 @@ meshtastic_NodeInfo TypeConversions::ConvertToNodeInfo(const meshtastic_NodeInfo
|
||||
info.via_mqtt = lite->via_mqtt;
|
||||
info.is_favorite = lite->is_favorite;
|
||||
info.is_ignored = lite->is_ignored;
|
||||
info.is_key_manually_verified = lite->bitfield & NODEINFO_BITFIELD_IS_KEY_MANUALLY_VERIFIED_MASK;
|
||||
|
||||
if (lite->has_hops_away) {
|
||||
info.has_hops_away = true;
|
||||
@@ -86,6 +87,8 @@ meshtastic_UserLite TypeConversions::ConvertToUserLite(meshtastic_User user)
|
||||
memcpy(lite.macaddr, user.macaddr, sizeof(lite.macaddr));
|
||||
memcpy(lite.public_key.bytes, user.public_key.bytes, sizeof(lite.public_key.bytes));
|
||||
lite.public_key.size = user.public_key.size;
|
||||
lite.has_is_unmessagable = user.has_is_unmessagable;
|
||||
lite.is_unmessagable = user.is_unmessagable;
|
||||
return lite;
|
||||
}
|
||||
|
||||
@@ -102,6 +105,8 @@ meshtastic_User TypeConversions::ConvertToUser(uint32_t nodeNum, meshtastic_User
|
||||
memcpy(user.macaddr, lite.macaddr, sizeof(user.macaddr));
|
||||
memcpy(user.public_key.bytes, lite.public_key.bytes, sizeof(user.public_key.bytes));
|
||||
user.public_key.size = lite.public_key.size;
|
||||
user.has_is_unmessagable = lite.has_is_unmessagable;
|
||||
user.is_unmessagable = lite.is_unmessagable;
|
||||
|
||||
return user;
|
||||
}
|
||||
@@ -43,7 +43,7 @@ template <class T, class U> class APIServerPort : public U, private concurrency:
|
||||
* delegate to the worker. Once coroutines are implemented we can relax this restriction.
|
||||
*/
|
||||
T *openAPI = NULL;
|
||||
#if RAK_4631
|
||||
#if defined(RAK_4631) || defined(RAK11310)
|
||||
// Track wait time for RAK13800 Ethernet requests
|
||||
int32_t waitTime = 100;
|
||||
#endif
|
||||
|
||||
@@ -15,6 +15,14 @@ PB_BIND(meshtastic_HamParameters, meshtastic_HamParameters, AUTO)
|
||||
PB_BIND(meshtastic_NodeRemoteHardwarePinsResponse, meshtastic_NodeRemoteHardwarePinsResponse, 2)
|
||||
|
||||
|
||||
PB_BIND(meshtastic_SharedContact, meshtastic_SharedContact, AUTO)
|
||||
|
||||
|
||||
PB_BIND(meshtastic_KeyVerificationAdmin, meshtastic_KeyVerificationAdmin, AUTO)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -77,6 +77,19 @@ typedef enum _meshtastic_AdminMessage_BackupLocation {
|
||||
meshtastic_AdminMessage_BackupLocation_SD = 1
|
||||
} meshtastic_AdminMessage_BackupLocation;
|
||||
|
||||
/* Three stages of this request. */
|
||||
typedef enum _meshtastic_KeyVerificationAdmin_MessageType {
|
||||
/* This is the first stage, where a client initiates */
|
||||
meshtastic_KeyVerificationAdmin_MessageType_INITIATE_VERIFICATION = 0,
|
||||
/* After the nonce has been returned over the mesh, the client prompts for the security number
|
||||
And uses this message to provide it to the node. */
|
||||
meshtastic_KeyVerificationAdmin_MessageType_PROVIDE_SECURITY_NUMBER = 1,
|
||||
/* Once the user has compared the verification message, this message notifies the node. */
|
||||
meshtastic_KeyVerificationAdmin_MessageType_DO_VERIFY = 2,
|
||||
/* This is the cancel path, can be taken at any point */
|
||||
meshtastic_KeyVerificationAdmin_MessageType_DO_NOT_VERIFY = 3
|
||||
} meshtastic_KeyVerificationAdmin_MessageType;
|
||||
|
||||
/* Struct definitions */
|
||||
/* Parameters for setting up Meshtastic for ameteur radio usage */
|
||||
typedef struct _meshtastic_HamParameters {
|
||||
@@ -99,6 +112,26 @@ typedef struct _meshtastic_NodeRemoteHardwarePinsResponse {
|
||||
meshtastic_NodeRemoteHardwarePin node_remote_hardware_pins[16];
|
||||
} meshtastic_NodeRemoteHardwarePinsResponse;
|
||||
|
||||
typedef struct _meshtastic_SharedContact {
|
||||
/* The node number of the contact */
|
||||
uint32_t node_num;
|
||||
/* The User of the contact */
|
||||
bool has_user;
|
||||
meshtastic_User user;
|
||||
} meshtastic_SharedContact;
|
||||
|
||||
/* This message is used by a client to initiate or complete a key verification */
|
||||
typedef struct _meshtastic_KeyVerificationAdmin {
|
||||
meshtastic_KeyVerificationAdmin_MessageType message_type;
|
||||
/* The nodenum we're requesting */
|
||||
uint32_t remote_nodenum;
|
||||
/* The nonce is used to track the connection */
|
||||
uint64_t nonce;
|
||||
/* The 4 digit code generated by the remote node, and communicated outside the mesh */
|
||||
bool has_security_number;
|
||||
uint32_t security_number;
|
||||
} meshtastic_KeyVerificationAdmin;
|
||||
|
||||
typedef PB_BYTES_ARRAY_T(8) meshtastic_AdminMessage_session_passkey_t;
|
||||
/* This message is handled by the Admin module and is responsible for all settings/channel read/write operations.
|
||||
This message is used to do settings operations to both remote AND local nodes.
|
||||
@@ -202,6 +235,10 @@ typedef struct _meshtastic_AdminMessage {
|
||||
bool begin_edit_settings;
|
||||
/* Commits an open transaction for any edits made to config, module config, owner, and channel settings */
|
||||
bool commit_edit_settings;
|
||||
/* Add a contact (User) to the nodedb */
|
||||
meshtastic_SharedContact add_contact;
|
||||
/* Initiate or respond to a key verification request */
|
||||
meshtastic_KeyVerificationAdmin key_verification;
|
||||
/* Tell the node to factory reset config everything; all device state and configuration will be returned to factory defaults and BLE bonds will be cleared. */
|
||||
int32_t factory_reset_device;
|
||||
/* Tell the node to reboot into the OTA Firmware in this many seconds (or <0 to cancel reboot)
|
||||
@@ -243,6 +280,10 @@ extern "C" {
|
||||
#define _meshtastic_AdminMessage_BackupLocation_MAX meshtastic_AdminMessage_BackupLocation_SD
|
||||
#define _meshtastic_AdminMessage_BackupLocation_ARRAYSIZE ((meshtastic_AdminMessage_BackupLocation)(meshtastic_AdminMessage_BackupLocation_SD+1))
|
||||
|
||||
#define _meshtastic_KeyVerificationAdmin_MessageType_MIN meshtastic_KeyVerificationAdmin_MessageType_INITIATE_VERIFICATION
|
||||
#define _meshtastic_KeyVerificationAdmin_MessageType_MAX meshtastic_KeyVerificationAdmin_MessageType_DO_NOT_VERIFY
|
||||
#define _meshtastic_KeyVerificationAdmin_MessageType_ARRAYSIZE ((meshtastic_KeyVerificationAdmin_MessageType)(meshtastic_KeyVerificationAdmin_MessageType_DO_NOT_VERIFY+1))
|
||||
|
||||
#define meshtastic_AdminMessage_payload_variant_get_config_request_ENUMTYPE meshtastic_AdminMessage_ConfigType
|
||||
#define meshtastic_AdminMessage_payload_variant_get_module_config_request_ENUMTYPE meshtastic_AdminMessage_ModuleConfigType
|
||||
#define meshtastic_AdminMessage_payload_variant_backup_preferences_ENUMTYPE meshtastic_AdminMessage_BackupLocation
|
||||
@@ -252,13 +293,20 @@ extern "C" {
|
||||
|
||||
|
||||
|
||||
#define meshtastic_KeyVerificationAdmin_message_type_ENUMTYPE meshtastic_KeyVerificationAdmin_MessageType
|
||||
|
||||
|
||||
/* Initializer values for message structs */
|
||||
#define meshtastic_AdminMessage_init_default {0, {0}, {0, {0}}}
|
||||
#define meshtastic_HamParameters_init_default {"", 0, 0, ""}
|
||||
#define meshtastic_NodeRemoteHardwarePinsResponse_init_default {0, {meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default}}
|
||||
#define meshtastic_SharedContact_init_default {0, false, meshtastic_User_init_default}
|
||||
#define meshtastic_KeyVerificationAdmin_init_default {_meshtastic_KeyVerificationAdmin_MessageType_MIN, 0, 0, false, 0}
|
||||
#define meshtastic_AdminMessage_init_zero {0, {0}, {0, {0}}}
|
||||
#define meshtastic_HamParameters_init_zero {"", 0, 0, ""}
|
||||
#define meshtastic_NodeRemoteHardwarePinsResponse_init_zero {0, {meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero}}
|
||||
#define meshtastic_SharedContact_init_zero {0, false, meshtastic_User_init_zero}
|
||||
#define meshtastic_KeyVerificationAdmin_init_zero {_meshtastic_KeyVerificationAdmin_MessageType_MIN, 0, 0, false, 0}
|
||||
|
||||
/* Field tags (for use in manual encoding/decoding) */
|
||||
#define meshtastic_HamParameters_call_sign_tag 1
|
||||
@@ -266,6 +314,12 @@ extern "C" {
|
||||
#define meshtastic_HamParameters_frequency_tag 3
|
||||
#define meshtastic_HamParameters_short_name_tag 4
|
||||
#define meshtastic_NodeRemoteHardwarePinsResponse_node_remote_hardware_pins_tag 1
|
||||
#define meshtastic_SharedContact_node_num_tag 1
|
||||
#define meshtastic_SharedContact_user_tag 2
|
||||
#define meshtastic_KeyVerificationAdmin_message_type_tag 1
|
||||
#define meshtastic_KeyVerificationAdmin_remote_nodenum_tag 2
|
||||
#define meshtastic_KeyVerificationAdmin_nonce_tag 3
|
||||
#define meshtastic_KeyVerificationAdmin_security_number_tag 4
|
||||
#define meshtastic_AdminMessage_get_channel_request_tag 1
|
||||
#define meshtastic_AdminMessage_get_channel_response_tag 2
|
||||
#define meshtastic_AdminMessage_get_owner_request_tag 3
|
||||
@@ -310,6 +364,8 @@ extern "C" {
|
||||
#define meshtastic_AdminMessage_remove_ignored_node_tag 48
|
||||
#define meshtastic_AdminMessage_begin_edit_settings_tag 64
|
||||
#define meshtastic_AdminMessage_commit_edit_settings_tag 65
|
||||
#define meshtastic_AdminMessage_add_contact_tag 66
|
||||
#define meshtastic_AdminMessage_key_verification_tag 67
|
||||
#define meshtastic_AdminMessage_factory_reset_device_tag 94
|
||||
#define meshtastic_AdminMessage_reboot_ota_seconds_tag 95
|
||||
#define meshtastic_AdminMessage_exit_simulator_tag 96
|
||||
@@ -365,6 +421,8 @@ X(a, STATIC, ONEOF, UINT32, (payload_variant,set_ignored_node,set_ignored
|
||||
X(a, STATIC, ONEOF, UINT32, (payload_variant,remove_ignored_node,remove_ignored_node), 48) \
|
||||
X(a, STATIC, ONEOF, BOOL, (payload_variant,begin_edit_settings,begin_edit_settings), 64) \
|
||||
X(a, STATIC, ONEOF, BOOL, (payload_variant,commit_edit_settings,commit_edit_settings), 65) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,add_contact,add_contact), 66) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,key_verification,key_verification), 67) \
|
||||
X(a, STATIC, ONEOF, INT32, (payload_variant,factory_reset_device,factory_reset_device), 94) \
|
||||
X(a, STATIC, ONEOF, INT32, (payload_variant,reboot_ota_seconds,reboot_ota_seconds), 95) \
|
||||
X(a, STATIC, ONEOF, BOOL, (payload_variant,exit_simulator,exit_simulator), 96) \
|
||||
@@ -390,6 +448,8 @@ X(a, STATIC, SINGULAR, BYTES, session_passkey, 101)
|
||||
#define meshtastic_AdminMessage_payload_variant_set_fixed_position_MSGTYPE meshtastic_Position
|
||||
#define meshtastic_AdminMessage_payload_variant_get_ui_config_response_MSGTYPE meshtastic_DeviceUIConfig
|
||||
#define meshtastic_AdminMessage_payload_variant_store_ui_config_MSGTYPE meshtastic_DeviceUIConfig
|
||||
#define meshtastic_AdminMessage_payload_variant_add_contact_MSGTYPE meshtastic_SharedContact
|
||||
#define meshtastic_AdminMessage_payload_variant_key_verification_MSGTYPE meshtastic_KeyVerificationAdmin
|
||||
|
||||
#define meshtastic_HamParameters_FIELDLIST(X, a) \
|
||||
X(a, STATIC, SINGULAR, STRING, call_sign, 1) \
|
||||
@@ -405,20 +465,41 @@ X(a, STATIC, REPEATED, MESSAGE, node_remote_hardware_pins, 1)
|
||||
#define meshtastic_NodeRemoteHardwarePinsResponse_DEFAULT NULL
|
||||
#define meshtastic_NodeRemoteHardwarePinsResponse_node_remote_hardware_pins_MSGTYPE meshtastic_NodeRemoteHardwarePin
|
||||
|
||||
#define meshtastic_SharedContact_FIELDLIST(X, a) \
|
||||
X(a, STATIC, SINGULAR, UINT32, node_num, 1) \
|
||||
X(a, STATIC, OPTIONAL, MESSAGE, user, 2)
|
||||
#define meshtastic_SharedContact_CALLBACK NULL
|
||||
#define meshtastic_SharedContact_DEFAULT NULL
|
||||
#define meshtastic_SharedContact_user_MSGTYPE meshtastic_User
|
||||
|
||||
#define meshtastic_KeyVerificationAdmin_FIELDLIST(X, a) \
|
||||
X(a, STATIC, SINGULAR, UENUM, message_type, 1) \
|
||||
X(a, STATIC, SINGULAR, UINT32, remote_nodenum, 2) \
|
||||
X(a, STATIC, SINGULAR, UINT64, nonce, 3) \
|
||||
X(a, STATIC, OPTIONAL, UINT32, security_number, 4)
|
||||
#define meshtastic_KeyVerificationAdmin_CALLBACK NULL
|
||||
#define meshtastic_KeyVerificationAdmin_DEFAULT NULL
|
||||
|
||||
extern const pb_msgdesc_t meshtastic_AdminMessage_msg;
|
||||
extern const pb_msgdesc_t meshtastic_HamParameters_msg;
|
||||
extern const pb_msgdesc_t meshtastic_NodeRemoteHardwarePinsResponse_msg;
|
||||
extern const pb_msgdesc_t meshtastic_SharedContact_msg;
|
||||
extern const pb_msgdesc_t meshtastic_KeyVerificationAdmin_msg;
|
||||
|
||||
/* Defines for backwards compatibility with code written before nanopb-0.4.0 */
|
||||
#define meshtastic_AdminMessage_fields &meshtastic_AdminMessage_msg
|
||||
#define meshtastic_HamParameters_fields &meshtastic_HamParameters_msg
|
||||
#define meshtastic_NodeRemoteHardwarePinsResponse_fields &meshtastic_NodeRemoteHardwarePinsResponse_msg
|
||||
#define meshtastic_SharedContact_fields &meshtastic_SharedContact_msg
|
||||
#define meshtastic_KeyVerificationAdmin_fields &meshtastic_KeyVerificationAdmin_msg
|
||||
|
||||
/* Maximum encoded size of messages (where known) */
|
||||
#define MESHTASTIC_MESHTASTIC_ADMIN_PB_H_MAX_SIZE meshtastic_AdminMessage_size
|
||||
#define meshtastic_AdminMessage_size 511
|
||||
#define meshtastic_HamParameters_size 31
|
||||
#define meshtastic_KeyVerificationAdmin_size 25
|
||||
#define meshtastic_NodeRemoteHardwarePinsResponse_size 496
|
||||
#define meshtastic_SharedContact_size 123
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
|
||||
@@ -180,14 +180,16 @@ typedef enum _meshtastic_Config_DisplayConfig_DisplayUnits {
|
||||
|
||||
/* Override OLED outo detect with this if it fails. */
|
||||
typedef enum _meshtastic_Config_DisplayConfig_OledType {
|
||||
/* Default / Auto */
|
||||
/* Default / Autodetect */
|
||||
meshtastic_Config_DisplayConfig_OledType_OLED_AUTO = 0,
|
||||
/* Default / Auto */
|
||||
/* Default / Autodetect */
|
||||
meshtastic_Config_DisplayConfig_OledType_OLED_SSD1306 = 1,
|
||||
/* Default / Auto */
|
||||
/* Default / Autodetect */
|
||||
meshtastic_Config_DisplayConfig_OledType_OLED_SH1106 = 2,
|
||||
/* Can not be auto detected but set by proto. Used for 128x128 screens */
|
||||
meshtastic_Config_DisplayConfig_OledType_OLED_SH1107 = 3
|
||||
meshtastic_Config_DisplayConfig_OledType_OLED_SH1107 = 3,
|
||||
/* Can not be auto detected but set by proto. Used for 128x64 screens */
|
||||
meshtastic_Config_DisplayConfig_OledType_OLED_SH1107_128_64 = 4
|
||||
} meshtastic_Config_DisplayConfig_OledType;
|
||||
|
||||
typedef enum _meshtastic_Config_DisplayConfig_DisplayMode {
|
||||
@@ -439,6 +441,8 @@ typedef struct _meshtastic_Config_NetworkConfig {
|
||||
char rsyslog_server[33];
|
||||
/* Flags for enabling/disabling network protocols */
|
||||
uint32_t enabled_protocols;
|
||||
/* Enable/Disable ipv6 support */
|
||||
bool ipv6_enabled;
|
||||
} meshtastic_Config_NetworkConfig;
|
||||
|
||||
/* Display Config */
|
||||
@@ -639,8 +643,8 @@ extern "C" {
|
||||
#define _meshtastic_Config_DisplayConfig_DisplayUnits_ARRAYSIZE ((meshtastic_Config_DisplayConfig_DisplayUnits)(meshtastic_Config_DisplayConfig_DisplayUnits_IMPERIAL+1))
|
||||
|
||||
#define _meshtastic_Config_DisplayConfig_OledType_MIN meshtastic_Config_DisplayConfig_OledType_OLED_AUTO
|
||||
#define _meshtastic_Config_DisplayConfig_OledType_MAX meshtastic_Config_DisplayConfig_OledType_OLED_SH1107
|
||||
#define _meshtastic_Config_DisplayConfig_OledType_ARRAYSIZE ((meshtastic_Config_DisplayConfig_OledType)(meshtastic_Config_DisplayConfig_OledType_OLED_SH1107+1))
|
||||
#define _meshtastic_Config_DisplayConfig_OledType_MAX meshtastic_Config_DisplayConfig_OledType_OLED_SH1107_128_64
|
||||
#define _meshtastic_Config_DisplayConfig_OledType_ARRAYSIZE ((meshtastic_Config_DisplayConfig_OledType)(meshtastic_Config_DisplayConfig_OledType_OLED_SH1107_128_64+1))
|
||||
|
||||
#define _meshtastic_Config_DisplayConfig_DisplayMode_MIN meshtastic_Config_DisplayConfig_DisplayMode_DEFAULT
|
||||
#define _meshtastic_Config_DisplayConfig_DisplayMode_MAX meshtastic_Config_DisplayConfig_DisplayMode_COLOR
|
||||
@@ -691,7 +695,7 @@ extern "C" {
|
||||
#define meshtastic_Config_DeviceConfig_init_default {_meshtastic_Config_DeviceConfig_Role_MIN, 0, 0, 0, _meshtastic_Config_DeviceConfig_RebroadcastMode_MIN, 0, 0, 0, 0, "", 0}
|
||||
#define meshtastic_Config_PositionConfig_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _meshtastic_Config_PositionConfig_GpsMode_MIN}
|
||||
#define meshtastic_Config_PowerConfig_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||
#define meshtastic_Config_NetworkConfig_init_default {0, "", "", "", 0, _meshtastic_Config_NetworkConfig_AddressMode_MIN, false, meshtastic_Config_NetworkConfig_IpV4Config_init_default, "", 0}
|
||||
#define meshtastic_Config_NetworkConfig_init_default {0, "", "", "", 0, _meshtastic_Config_NetworkConfig_AddressMode_MIN, false, meshtastic_Config_NetworkConfig_IpV4Config_init_default, "", 0, 0}
|
||||
#define meshtastic_Config_NetworkConfig_IpV4Config_init_default {0, 0, 0, 0}
|
||||
#define meshtastic_Config_DisplayConfig_init_default {0, _meshtastic_Config_DisplayConfig_GpsCoordinateFormat_MIN, 0, 0, 0, _meshtastic_Config_DisplayConfig_DisplayUnits_MIN, _meshtastic_Config_DisplayConfig_OledType_MIN, _meshtastic_Config_DisplayConfig_DisplayMode_MIN, 0, 0, _meshtastic_Config_DisplayConfig_CompassOrientation_MIN, 0}
|
||||
#define meshtastic_Config_LoRaConfig_init_default {0, _meshtastic_Config_LoRaConfig_ModemPreset_MIN, 0, 0, 0, 0, _meshtastic_Config_LoRaConfig_RegionCode_MIN, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0}, 0, 0}
|
||||
@@ -702,7 +706,7 @@ extern "C" {
|
||||
#define meshtastic_Config_DeviceConfig_init_zero {_meshtastic_Config_DeviceConfig_Role_MIN, 0, 0, 0, _meshtastic_Config_DeviceConfig_RebroadcastMode_MIN, 0, 0, 0, 0, "", 0}
|
||||
#define meshtastic_Config_PositionConfig_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, _meshtastic_Config_PositionConfig_GpsMode_MIN}
|
||||
#define meshtastic_Config_PowerConfig_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||
#define meshtastic_Config_NetworkConfig_init_zero {0, "", "", "", 0, _meshtastic_Config_NetworkConfig_AddressMode_MIN, false, meshtastic_Config_NetworkConfig_IpV4Config_init_zero, "", 0}
|
||||
#define meshtastic_Config_NetworkConfig_init_zero {0, "", "", "", 0, _meshtastic_Config_NetworkConfig_AddressMode_MIN, false, meshtastic_Config_NetworkConfig_IpV4Config_init_zero, "", 0, 0}
|
||||
#define meshtastic_Config_NetworkConfig_IpV4Config_init_zero {0, 0, 0, 0}
|
||||
#define meshtastic_Config_DisplayConfig_init_zero {0, _meshtastic_Config_DisplayConfig_GpsCoordinateFormat_MIN, 0, 0, 0, _meshtastic_Config_DisplayConfig_DisplayUnits_MIN, _meshtastic_Config_DisplayConfig_OledType_MIN, _meshtastic_Config_DisplayConfig_DisplayMode_MIN, 0, 0, _meshtastic_Config_DisplayConfig_CompassOrientation_MIN, 0}
|
||||
#define meshtastic_Config_LoRaConfig_init_zero {0, _meshtastic_Config_LoRaConfig_ModemPreset_MIN, 0, 0, 0, 0, _meshtastic_Config_LoRaConfig_RegionCode_MIN, 0, 0, 0, 0, 0, 0, 0, 0, 0, {0, 0, 0}, 0, 0}
|
||||
@@ -757,6 +761,7 @@ extern "C" {
|
||||
#define meshtastic_Config_NetworkConfig_ipv4_config_tag 8
|
||||
#define meshtastic_Config_NetworkConfig_rsyslog_server_tag 9
|
||||
#define meshtastic_Config_NetworkConfig_enabled_protocols_tag 10
|
||||
#define meshtastic_Config_NetworkConfig_ipv6_enabled_tag 11
|
||||
#define meshtastic_Config_DisplayConfig_screen_on_secs_tag 1
|
||||
#define meshtastic_Config_DisplayConfig_gps_format_tag 2
|
||||
#define meshtastic_Config_DisplayConfig_auto_screen_carousel_secs_tag 3
|
||||
@@ -887,7 +892,8 @@ X(a, STATIC, SINGULAR, BOOL, eth_enabled, 6) \
|
||||
X(a, STATIC, SINGULAR, UENUM, address_mode, 7) \
|
||||
X(a, STATIC, OPTIONAL, MESSAGE, ipv4_config, 8) \
|
||||
X(a, STATIC, SINGULAR, STRING, rsyslog_server, 9) \
|
||||
X(a, STATIC, SINGULAR, UINT32, enabled_protocols, 10)
|
||||
X(a, STATIC, SINGULAR, UINT32, enabled_protocols, 10) \
|
||||
X(a, STATIC, SINGULAR, BOOL, ipv6_enabled, 11)
|
||||
#define meshtastic_Config_NetworkConfig_CALLBACK NULL
|
||||
#define meshtastic_Config_NetworkConfig_DEFAULT NULL
|
||||
#define meshtastic_Config_NetworkConfig_ipv4_config_MSGTYPE meshtastic_Config_NetworkConfig_IpV4Config
|
||||
@@ -993,12 +999,12 @@ extern const pb_msgdesc_t meshtastic_Config_SessionkeyConfig_msg;
|
||||
#define meshtastic_Config_DisplayConfig_size 32
|
||||
#define meshtastic_Config_LoRaConfig_size 85
|
||||
#define meshtastic_Config_NetworkConfig_IpV4Config_size 20
|
||||
#define meshtastic_Config_NetworkConfig_size 202
|
||||
#define meshtastic_Config_NetworkConfig_size 204
|
||||
#define meshtastic_Config_PositionConfig_size 62
|
||||
#define meshtastic_Config_PowerConfig_size 52
|
||||
#define meshtastic_Config_SecurityConfig_size 178
|
||||
#define meshtastic_Config_SessionkeyConfig_size 0
|
||||
#define meshtastic_Config_size 205
|
||||
#define meshtastic_Config_size 207
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
|
||||
@@ -58,6 +58,9 @@ typedef struct _meshtastic_UserLite {
|
||||
/* The public key of the user's device.
|
||||
This is sent out to other nodes on the mesh to allow them to compute a shared secret key. */
|
||||
meshtastic_UserLite_public_key_t public_key;
|
||||
/* Whether or not the node can be messaged */
|
||||
bool has_is_unmessagable;
|
||||
bool is_unmessagable;
|
||||
} meshtastic_UserLite;
|
||||
|
||||
typedef struct _meshtastic_NodeInfoLite {
|
||||
@@ -93,6 +96,9 @@ typedef struct _meshtastic_NodeInfoLite {
|
||||
bool is_ignored;
|
||||
/* Last byte of the node number of the node that should be used as the next hop to reach this node. */
|
||||
uint8_t next_hop;
|
||||
/* Bitfield for storing booleans.
|
||||
LSB 0 is_key_manually_verified */
|
||||
uint32_t bitfield;
|
||||
} meshtastic_NodeInfoLite;
|
||||
|
||||
/* This message is never sent over the wire, but it is used for serializing DB
|
||||
@@ -183,15 +189,15 @@ extern "C" {
|
||||
|
||||
/* Initializer values for message structs */
|
||||
#define meshtastic_PositionLite_init_default {0, 0, 0, 0, _meshtastic_Position_LocSource_MIN}
|
||||
#define meshtastic_UserLite_init_default {{0}, "", "", _meshtastic_HardwareModel_MIN, 0, _meshtastic_Config_DeviceConfig_Role_MIN, {0, {0}}}
|
||||
#define meshtastic_NodeInfoLite_init_default {0, false, meshtastic_UserLite_init_default, false, meshtastic_PositionLite_init_default, 0, 0, false, meshtastic_DeviceMetrics_init_default, 0, 0, false, 0, 0, 0, 0}
|
||||
#define meshtastic_UserLite_init_default {{0}, "", "", _meshtastic_HardwareModel_MIN, 0, _meshtastic_Config_DeviceConfig_Role_MIN, {0, {0}}, false, 0}
|
||||
#define meshtastic_NodeInfoLite_init_default {0, false, meshtastic_UserLite_init_default, false, meshtastic_PositionLite_init_default, 0, 0, false, meshtastic_DeviceMetrics_init_default, 0, 0, false, 0, 0, 0, 0, 0}
|
||||
#define meshtastic_DeviceState_init_default {false, meshtastic_MyNodeInfo_init_default, false, meshtastic_User_init_default, 0, {meshtastic_MeshPacket_init_default}, false, meshtastic_MeshPacket_init_default, 0, 0, 0, false, meshtastic_MeshPacket_init_default, 0, {meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default, meshtastic_NodeRemoteHardwarePin_init_default}}
|
||||
#define meshtastic_NodeDatabase_init_default {0, {0}}
|
||||
#define meshtastic_ChannelFile_init_default {0, {meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default, meshtastic_Channel_init_default}, 0}
|
||||
#define meshtastic_BackupPreferences_init_default {0, 0, false, meshtastic_LocalConfig_init_default, false, meshtastic_LocalModuleConfig_init_default, false, meshtastic_ChannelFile_init_default, false, meshtastic_User_init_default}
|
||||
#define meshtastic_PositionLite_init_zero {0, 0, 0, 0, _meshtastic_Position_LocSource_MIN}
|
||||
#define meshtastic_UserLite_init_zero {{0}, "", "", _meshtastic_HardwareModel_MIN, 0, _meshtastic_Config_DeviceConfig_Role_MIN, {0, {0}}}
|
||||
#define meshtastic_NodeInfoLite_init_zero {0, false, meshtastic_UserLite_init_zero, false, meshtastic_PositionLite_init_zero, 0, 0, false, meshtastic_DeviceMetrics_init_zero, 0, 0, false, 0, 0, 0, 0}
|
||||
#define meshtastic_UserLite_init_zero {{0}, "", "", _meshtastic_HardwareModel_MIN, 0, _meshtastic_Config_DeviceConfig_Role_MIN, {0, {0}}, false, 0}
|
||||
#define meshtastic_NodeInfoLite_init_zero {0, false, meshtastic_UserLite_init_zero, false, meshtastic_PositionLite_init_zero, 0, 0, false, meshtastic_DeviceMetrics_init_zero, 0, 0, false, 0, 0, 0, 0, 0}
|
||||
#define meshtastic_DeviceState_init_zero {false, meshtastic_MyNodeInfo_init_zero, false, meshtastic_User_init_zero, 0, {meshtastic_MeshPacket_init_zero}, false, meshtastic_MeshPacket_init_zero, 0, 0, 0, false, meshtastic_MeshPacket_init_zero, 0, {meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero, meshtastic_NodeRemoteHardwarePin_init_zero}}
|
||||
#define meshtastic_NodeDatabase_init_zero {0, {0}}
|
||||
#define meshtastic_ChannelFile_init_zero {0, {meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero, meshtastic_Channel_init_zero}, 0}
|
||||
@@ -210,6 +216,7 @@ extern "C" {
|
||||
#define meshtastic_UserLite_is_licensed_tag 5
|
||||
#define meshtastic_UserLite_role_tag 6
|
||||
#define meshtastic_UserLite_public_key_tag 7
|
||||
#define meshtastic_UserLite_is_unmessagable_tag 9
|
||||
#define meshtastic_NodeInfoLite_num_tag 1
|
||||
#define meshtastic_NodeInfoLite_user_tag 2
|
||||
#define meshtastic_NodeInfoLite_position_tag 3
|
||||
@@ -222,6 +229,7 @@ extern "C" {
|
||||
#define meshtastic_NodeInfoLite_is_favorite_tag 10
|
||||
#define meshtastic_NodeInfoLite_is_ignored_tag 11
|
||||
#define meshtastic_NodeInfoLite_next_hop_tag 12
|
||||
#define meshtastic_NodeInfoLite_bitfield_tag 13
|
||||
#define meshtastic_DeviceState_my_node_tag 2
|
||||
#define meshtastic_DeviceState_owner_tag 3
|
||||
#define meshtastic_DeviceState_receive_queue_tag 5
|
||||
@@ -259,7 +267,8 @@ X(a, STATIC, SINGULAR, STRING, short_name, 3) \
|
||||
X(a, STATIC, SINGULAR, UENUM, hw_model, 4) \
|
||||
X(a, STATIC, SINGULAR, BOOL, is_licensed, 5) \
|
||||
X(a, STATIC, SINGULAR, UENUM, role, 6) \
|
||||
X(a, STATIC, SINGULAR, BYTES, public_key, 7)
|
||||
X(a, STATIC, SINGULAR, BYTES, public_key, 7) \
|
||||
X(a, STATIC, OPTIONAL, BOOL, is_unmessagable, 9)
|
||||
#define meshtastic_UserLite_CALLBACK NULL
|
||||
#define meshtastic_UserLite_DEFAULT NULL
|
||||
|
||||
@@ -275,7 +284,8 @@ X(a, STATIC, SINGULAR, BOOL, via_mqtt, 8) \
|
||||
X(a, STATIC, OPTIONAL, UINT32, hops_away, 9) \
|
||||
X(a, STATIC, SINGULAR, BOOL, is_favorite, 10) \
|
||||
X(a, STATIC, SINGULAR, BOOL, is_ignored, 11) \
|
||||
X(a, STATIC, SINGULAR, UINT32, next_hop, 12)
|
||||
X(a, STATIC, SINGULAR, UINT32, next_hop, 12) \
|
||||
X(a, STATIC, SINGULAR, UINT32, bitfield, 13)
|
||||
#define meshtastic_NodeInfoLite_CALLBACK NULL
|
||||
#define meshtastic_NodeInfoLite_DEFAULT NULL
|
||||
#define meshtastic_NodeInfoLite_user_MSGTYPE meshtastic_UserLite
|
||||
@@ -350,12 +360,12 @@ extern const pb_msgdesc_t meshtastic_BackupPreferences_msg;
|
||||
/* Maximum encoded size of messages (where known) */
|
||||
/* meshtastic_NodeDatabase_size depends on runtime parameters */
|
||||
#define MESHTASTIC_MESHTASTIC_DEVICEONLY_PB_H_MAX_SIZE meshtastic_BackupPreferences_size
|
||||
#define meshtastic_BackupPreferences_size 2263
|
||||
#define meshtastic_BackupPreferences_size 2269
|
||||
#define meshtastic_ChannelFile_size 718
|
||||
#define meshtastic_DeviceState_size 1720
|
||||
#define meshtastic_NodeInfoLite_size 188
|
||||
#define meshtastic_DeviceState_size 1722
|
||||
#define meshtastic_NodeInfoLite_size 196
|
||||
#define meshtastic_PositionLite_size 28
|
||||
#define meshtastic_UserLite_size 96
|
||||
#define meshtastic_UserLite_size 98
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
|
||||
@@ -187,8 +187,8 @@ extern const pb_msgdesc_t meshtastic_LocalModuleConfig_msg;
|
||||
|
||||
/* Maximum encoded size of messages (where known) */
|
||||
#define MESHTASTIC_MESHTASTIC_LOCALONLY_PB_H_MAX_SIZE meshtastic_LocalConfig_size
|
||||
#define meshtastic_LocalConfig_size 743
|
||||
#define meshtastic_LocalModuleConfig_size 667
|
||||
#define meshtastic_LocalConfig_size 745
|
||||
#define meshtastic_LocalModuleConfig_size 669
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
|
||||
@@ -21,6 +21,9 @@ PB_BIND(meshtastic_Routing, meshtastic_Routing, AUTO)
|
||||
PB_BIND(meshtastic_Data, meshtastic_Data, 2)
|
||||
|
||||
|
||||
PB_BIND(meshtastic_KeyVerification, meshtastic_KeyVerification, AUTO)
|
||||
|
||||
|
||||
PB_BIND(meshtastic_Waypoint, meshtastic_Waypoint, AUTO)
|
||||
|
||||
|
||||
@@ -48,6 +51,15 @@ PB_BIND(meshtastic_FromRadio, meshtastic_FromRadio, 2)
|
||||
PB_BIND(meshtastic_ClientNotification, meshtastic_ClientNotification, 2)
|
||||
|
||||
|
||||
PB_BIND(meshtastic_KeyVerificationNumberInform, meshtastic_KeyVerificationNumberInform, AUTO)
|
||||
|
||||
|
||||
PB_BIND(meshtastic_KeyVerificationNumberRequest, meshtastic_KeyVerificationNumberRequest, AUTO)
|
||||
|
||||
|
||||
PB_BIND(meshtastic_KeyVerificationFinal, meshtastic_KeyVerificationFinal, AUTO)
|
||||
|
||||
|
||||
PB_BIND(meshtastic_FileInfo, meshtastic_FileInfo, AUTO)
|
||||
|
||||
|
||||
|
||||
@@ -239,6 +239,25 @@ typedef enum _meshtastic_HardwareModel {
|
||||
meshtastic_HardwareModel_HELTEC_SENSOR_HUB = 92,
|
||||
/* Reserved Fried Chicken ID for future use */
|
||||
meshtastic_HardwareModel_RESERVED_FRIED_CHICKEN = 93,
|
||||
/* Heltec Magnetic Power Bank with Meshtastic compatible */
|
||||
meshtastic_HardwareModel_HELTEC_MESH_POCKET = 94,
|
||||
/* Seeed Solar Node */
|
||||
meshtastic_HardwareModel_SEEED_SOLAR_NODE = 95,
|
||||
/* NomadStar Meteor Pro https://nomadstar.ch/ */
|
||||
meshtastic_HardwareModel_NOMADSTAR_METEOR_PRO = 96,
|
||||
/* Elecrow CrowPanel Advance models, ESP32-S3 and TFT with SX1262 radio plugin */
|
||||
meshtastic_HardwareModel_CROWPANEL = 97,
|
||||
/* *
|
||||
Lilygo LINK32 board with sensors */
|
||||
meshtastic_HardwareModel_LINK_32 = 98,
|
||||
/* *
|
||||
Seeed Tracker L1 */
|
||||
meshtastic_HardwareModel_SEEED_WIO_TRACKER_L1 = 99,
|
||||
/* *
|
||||
Seeed Tracker L1 EINK driver */
|
||||
meshtastic_HardwareModel_SEEED_WIO_TRACKER_L1_EINK = 100,
|
||||
/* Reserved ID for future and past use */
|
||||
meshtastic_HardwareModel_QWANTZ_TINY_ARMS = 101,
|
||||
/* ------------------------------------------------------------------------------------------------------------------------------------------
|
||||
Reserved ID For developing private Ports. These will show up in live traffic sparsely, so we can use a high number. Keep it within 8 bits.
|
||||
------------------------------------------------------------------------------------------------------------------------------------------ */
|
||||
@@ -601,6 +620,9 @@ typedef struct _meshtastic_User {
|
||||
/* The public key of the user's device.
|
||||
This is sent out to other nodes on the mesh to allow them to compute a shared secret key. */
|
||||
meshtastic_User_public_key_t public_key;
|
||||
/* Whether or not the node can be messaged */
|
||||
bool has_is_unmessagable;
|
||||
bool is_unmessagable;
|
||||
} meshtastic_User;
|
||||
|
||||
/* A message used in a traceroute */
|
||||
@@ -669,6 +691,19 @@ typedef struct _meshtastic_Data {
|
||||
uint8_t bitfield;
|
||||
} meshtastic_Data;
|
||||
|
||||
typedef PB_BYTES_ARRAY_T(32) meshtastic_KeyVerification_hash1_t;
|
||||
typedef PB_BYTES_ARRAY_T(32) meshtastic_KeyVerification_hash2_t;
|
||||
/* The actual over-the-mesh message doing KeyVerification */
|
||||
typedef struct _meshtastic_KeyVerification {
|
||||
/* random value Selected by the requesting node */
|
||||
uint64_t nonce;
|
||||
/* The final authoritative hash, only to be sent by NodeA at the end of the handshake */
|
||||
meshtastic_KeyVerification_hash1_t hash1;
|
||||
/* The intermediary hash (actually derived from hash1),
|
||||
sent from NodeB to NodeA in response to the initial message. */
|
||||
meshtastic_KeyVerification_hash2_t hash2;
|
||||
} meshtastic_KeyVerification;
|
||||
|
||||
/* Waypoint message, used to share arbitrary locations across the mesh */
|
||||
typedef struct _meshtastic_Waypoint {
|
||||
/* Id of the waypoint */
|
||||
@@ -843,6 +878,10 @@ typedef struct _meshtastic_NodeInfo {
|
||||
/* True if node is in our ignored list
|
||||
Persists between NodeDB internal clean ups */
|
||||
bool is_ignored;
|
||||
/* True if node public key has been verified.
|
||||
Persists between NodeDB internal clean ups
|
||||
LSB 0 of the bitfield */
|
||||
bool is_key_manually_verified;
|
||||
} meshtastic_NodeInfo;
|
||||
|
||||
typedef PB_BYTES_ARRAY_T(16) meshtastic_MyNodeInfo_device_id_t;
|
||||
@@ -892,6 +931,24 @@ typedef struct _meshtastic_QueueStatus {
|
||||
uint32_t mesh_packet_id;
|
||||
} meshtastic_QueueStatus;
|
||||
|
||||
typedef struct _meshtastic_KeyVerificationNumberInform {
|
||||
uint64_t nonce;
|
||||
char remote_longname[40];
|
||||
uint32_t security_number;
|
||||
} meshtastic_KeyVerificationNumberInform;
|
||||
|
||||
typedef struct _meshtastic_KeyVerificationNumberRequest {
|
||||
uint64_t nonce;
|
||||
char remote_longname[40];
|
||||
} meshtastic_KeyVerificationNumberRequest;
|
||||
|
||||
typedef struct _meshtastic_KeyVerificationFinal {
|
||||
uint64_t nonce;
|
||||
char remote_longname[40];
|
||||
bool isSender;
|
||||
char verification_characters[10];
|
||||
} meshtastic_KeyVerificationFinal;
|
||||
|
||||
/* A notification message from the device to the client
|
||||
To be used for important messages that should to be displayed to the user
|
||||
in the form of push notifications or validation messages when saving
|
||||
@@ -906,6 +963,12 @@ typedef struct _meshtastic_ClientNotification {
|
||||
meshtastic_LogRecord_Level level;
|
||||
/* The message body of the notification */
|
||||
char message[400];
|
||||
pb_size_t which_payload_variant;
|
||||
union {
|
||||
meshtastic_KeyVerificationNumberInform key_verification_number_inform;
|
||||
meshtastic_KeyVerificationNumberRequest key_verification_number_request;
|
||||
meshtastic_KeyVerificationFinal key_verification_final;
|
||||
} payload_variant;
|
||||
} meshtastic_ClientNotification;
|
||||
|
||||
/* Individual File info for the device */
|
||||
@@ -1168,6 +1231,7 @@ extern "C" {
|
||||
|
||||
|
||||
|
||||
|
||||
#define meshtastic_MeshPacket_priority_ENUMTYPE meshtastic_MeshPacket_Priority
|
||||
#define meshtastic_MeshPacket_delayed_ENUMTYPE meshtastic_MeshPacket_Delayed
|
||||
|
||||
@@ -1181,6 +1245,9 @@ extern "C" {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#define meshtastic_Compressed_portnum_ENUMTYPE meshtastic_PortNum
|
||||
|
||||
|
||||
@@ -1196,19 +1263,23 @@ extern "C" {
|
||||
|
||||
/* Initializer values for message structs */
|
||||
#define meshtastic_Position_init_default {false, 0, false, 0, false, 0, 0, _meshtastic_Position_LocSource_MIN, _meshtastic_Position_AltSource_MIN, 0, 0, false, 0, false, 0, 0, 0, 0, 0, false, 0, false, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||
#define meshtastic_User_init_default {"", "", "", {0}, _meshtastic_HardwareModel_MIN, 0, _meshtastic_Config_DeviceConfig_Role_MIN, {0, {0}}}
|
||||
#define meshtastic_User_init_default {"", "", "", {0}, _meshtastic_HardwareModel_MIN, 0, _meshtastic_Config_DeviceConfig_Role_MIN, {0, {0}}, false, 0}
|
||||
#define meshtastic_RouteDiscovery_init_default {0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0, 0, 0, 0}}
|
||||
#define meshtastic_Routing_init_default {0, {meshtastic_RouteDiscovery_init_default}}
|
||||
#define meshtastic_Data_init_default {_meshtastic_PortNum_MIN, {0, {0}}, 0, 0, 0, 0, 0, 0, false, 0}
|
||||
#define meshtastic_KeyVerification_init_default {0, {0, {0}}, {0, {0}}}
|
||||
#define meshtastic_Waypoint_init_default {0, false, 0, false, 0, 0, 0, "", "", 0}
|
||||
#define meshtastic_MqttClientProxyMessage_init_default {"", 0, {{0, {0}}}, 0}
|
||||
#define meshtastic_MeshPacket_init_default {0, 0, 0, 0, {meshtastic_Data_init_default}, 0, 0, 0, 0, 0, _meshtastic_MeshPacket_Priority_MIN, 0, _meshtastic_MeshPacket_Delayed_MIN, 0, 0, {0, {0}}, 0, 0, 0, 0}
|
||||
#define meshtastic_NodeInfo_init_default {0, false, meshtastic_User_init_default, false, meshtastic_Position_init_default, 0, 0, false, meshtastic_DeviceMetrics_init_default, 0, 0, false, 0, 0, 0}
|
||||
#define meshtastic_NodeInfo_init_default {0, false, meshtastic_User_init_default, false, meshtastic_Position_init_default, 0, 0, false, meshtastic_DeviceMetrics_init_default, 0, 0, false, 0, 0, 0, 0}
|
||||
#define meshtastic_MyNodeInfo_init_default {0, 0, 0, {0, {0}}, ""}
|
||||
#define meshtastic_LogRecord_init_default {"", 0, "", _meshtastic_LogRecord_Level_MIN}
|
||||
#define meshtastic_QueueStatus_init_default {0, 0, 0, 0}
|
||||
#define meshtastic_FromRadio_init_default {0, 0, {meshtastic_MeshPacket_init_default}}
|
||||
#define meshtastic_ClientNotification_init_default {false, 0, 0, _meshtastic_LogRecord_Level_MIN, ""}
|
||||
#define meshtastic_ClientNotification_init_default {false, 0, 0, _meshtastic_LogRecord_Level_MIN, "", 0, {meshtastic_KeyVerificationNumberInform_init_default}}
|
||||
#define meshtastic_KeyVerificationNumberInform_init_default {0, "", 0}
|
||||
#define meshtastic_KeyVerificationNumberRequest_init_default {0, ""}
|
||||
#define meshtastic_KeyVerificationFinal_init_default {0, "", 0, ""}
|
||||
#define meshtastic_FileInfo_init_default {"", 0}
|
||||
#define meshtastic_ToRadio_init_default {0, {meshtastic_MeshPacket_init_default}}
|
||||
#define meshtastic_Compressed_init_default {_meshtastic_PortNum_MIN, {0, {0}}}
|
||||
@@ -1221,19 +1292,23 @@ extern "C" {
|
||||
#define meshtastic_resend_chunks_init_default {{{NULL}, NULL}}
|
||||
#define meshtastic_ChunkedPayloadResponse_init_default {0, 0, {0}}
|
||||
#define meshtastic_Position_init_zero {false, 0, false, 0, false, 0, 0, _meshtastic_Position_LocSource_MIN, _meshtastic_Position_AltSource_MIN, 0, 0, false, 0, false, 0, 0, 0, 0, 0, false, 0, false, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||
#define meshtastic_User_init_zero {"", "", "", {0}, _meshtastic_HardwareModel_MIN, 0, _meshtastic_Config_DeviceConfig_Role_MIN, {0, {0}}}
|
||||
#define meshtastic_User_init_zero {"", "", "", {0}, _meshtastic_HardwareModel_MIN, 0, _meshtastic_Config_DeviceConfig_Role_MIN, {0, {0}}, false, 0}
|
||||
#define meshtastic_RouteDiscovery_init_zero {0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0, 0, 0, 0}, 0, {0, 0, 0, 0, 0, 0, 0, 0}}
|
||||
#define meshtastic_Routing_init_zero {0, {meshtastic_RouteDiscovery_init_zero}}
|
||||
#define meshtastic_Data_init_zero {_meshtastic_PortNum_MIN, {0, {0}}, 0, 0, 0, 0, 0, 0, false, 0}
|
||||
#define meshtastic_KeyVerification_init_zero {0, {0, {0}}, {0, {0}}}
|
||||
#define meshtastic_Waypoint_init_zero {0, false, 0, false, 0, 0, 0, "", "", 0}
|
||||
#define meshtastic_MqttClientProxyMessage_init_zero {"", 0, {{0, {0}}}, 0}
|
||||
#define meshtastic_MeshPacket_init_zero {0, 0, 0, 0, {meshtastic_Data_init_zero}, 0, 0, 0, 0, 0, _meshtastic_MeshPacket_Priority_MIN, 0, _meshtastic_MeshPacket_Delayed_MIN, 0, 0, {0, {0}}, 0, 0, 0, 0}
|
||||
#define meshtastic_NodeInfo_init_zero {0, false, meshtastic_User_init_zero, false, meshtastic_Position_init_zero, 0, 0, false, meshtastic_DeviceMetrics_init_zero, 0, 0, false, 0, 0, 0}
|
||||
#define meshtastic_NodeInfo_init_zero {0, false, meshtastic_User_init_zero, false, meshtastic_Position_init_zero, 0, 0, false, meshtastic_DeviceMetrics_init_zero, 0, 0, false, 0, 0, 0, 0}
|
||||
#define meshtastic_MyNodeInfo_init_zero {0, 0, 0, {0, {0}}, ""}
|
||||
#define meshtastic_LogRecord_init_zero {"", 0, "", _meshtastic_LogRecord_Level_MIN}
|
||||
#define meshtastic_QueueStatus_init_zero {0, 0, 0, 0}
|
||||
#define meshtastic_FromRadio_init_zero {0, 0, {meshtastic_MeshPacket_init_zero}}
|
||||
#define meshtastic_ClientNotification_init_zero {false, 0, 0, _meshtastic_LogRecord_Level_MIN, ""}
|
||||
#define meshtastic_ClientNotification_init_zero {false, 0, 0, _meshtastic_LogRecord_Level_MIN, "", 0, {meshtastic_KeyVerificationNumberInform_init_zero}}
|
||||
#define meshtastic_KeyVerificationNumberInform_init_zero {0, "", 0}
|
||||
#define meshtastic_KeyVerificationNumberRequest_init_zero {0, ""}
|
||||
#define meshtastic_KeyVerificationFinal_init_zero {0, "", 0, ""}
|
||||
#define meshtastic_FileInfo_init_zero {"", 0}
|
||||
#define meshtastic_ToRadio_init_zero {0, {meshtastic_MeshPacket_init_zero}}
|
||||
#define meshtastic_Compressed_init_zero {_meshtastic_PortNum_MIN, {0, {0}}}
|
||||
@@ -1278,6 +1353,7 @@ extern "C" {
|
||||
#define meshtastic_User_is_licensed_tag 6
|
||||
#define meshtastic_User_role_tag 7
|
||||
#define meshtastic_User_public_key_tag 8
|
||||
#define meshtastic_User_is_unmessagable_tag 9
|
||||
#define meshtastic_RouteDiscovery_route_tag 1
|
||||
#define meshtastic_RouteDiscovery_snr_towards_tag 2
|
||||
#define meshtastic_RouteDiscovery_route_back_tag 3
|
||||
@@ -1294,6 +1370,9 @@ extern "C" {
|
||||
#define meshtastic_Data_reply_id_tag 7
|
||||
#define meshtastic_Data_emoji_tag 8
|
||||
#define meshtastic_Data_bitfield_tag 9
|
||||
#define meshtastic_KeyVerification_nonce_tag 1
|
||||
#define meshtastic_KeyVerification_hash1_tag 2
|
||||
#define meshtastic_KeyVerification_hash2_tag 3
|
||||
#define meshtastic_Waypoint_id_tag 1
|
||||
#define meshtastic_Waypoint_latitude_i_tag 2
|
||||
#define meshtastic_Waypoint_longitude_i_tag 3
|
||||
@@ -1337,6 +1416,7 @@ extern "C" {
|
||||
#define meshtastic_NodeInfo_hops_away_tag 9
|
||||
#define meshtastic_NodeInfo_is_favorite_tag 10
|
||||
#define meshtastic_NodeInfo_is_ignored_tag 11
|
||||
#define meshtastic_NodeInfo_is_key_manually_verified_tag 12
|
||||
#define meshtastic_MyNodeInfo_my_node_num_tag 1
|
||||
#define meshtastic_MyNodeInfo_reboot_count_tag 8
|
||||
#define meshtastic_MyNodeInfo_min_app_version_tag 11
|
||||
@@ -1350,10 +1430,22 @@ extern "C" {
|
||||
#define meshtastic_QueueStatus_free_tag 2
|
||||
#define meshtastic_QueueStatus_maxlen_tag 3
|
||||
#define meshtastic_QueueStatus_mesh_packet_id_tag 4
|
||||
#define meshtastic_KeyVerificationNumberInform_nonce_tag 1
|
||||
#define meshtastic_KeyVerificationNumberInform_remote_longname_tag 2
|
||||
#define meshtastic_KeyVerificationNumberInform_security_number_tag 3
|
||||
#define meshtastic_KeyVerificationNumberRequest_nonce_tag 1
|
||||
#define meshtastic_KeyVerificationNumberRequest_remote_longname_tag 2
|
||||
#define meshtastic_KeyVerificationFinal_nonce_tag 1
|
||||
#define meshtastic_KeyVerificationFinal_remote_longname_tag 2
|
||||
#define meshtastic_KeyVerificationFinal_isSender_tag 3
|
||||
#define meshtastic_KeyVerificationFinal_verification_characters_tag 4
|
||||
#define meshtastic_ClientNotification_reply_id_tag 1
|
||||
#define meshtastic_ClientNotification_time_tag 2
|
||||
#define meshtastic_ClientNotification_level_tag 3
|
||||
#define meshtastic_ClientNotification_message_tag 4
|
||||
#define meshtastic_ClientNotification_key_verification_number_inform_tag 11
|
||||
#define meshtastic_ClientNotification_key_verification_number_request_tag 12
|
||||
#define meshtastic_ClientNotification_key_verification_final_tag 13
|
||||
#define meshtastic_FileInfo_file_name_tag 1
|
||||
#define meshtastic_FileInfo_size_bytes_tag 2
|
||||
#define meshtastic_Compressed_portnum_tag 1
|
||||
@@ -1449,7 +1541,8 @@ X(a, STATIC, SINGULAR, FIXED_LENGTH_BYTES, macaddr, 4) \
|
||||
X(a, STATIC, SINGULAR, UENUM, hw_model, 5) \
|
||||
X(a, STATIC, SINGULAR, BOOL, is_licensed, 6) \
|
||||
X(a, STATIC, SINGULAR, UENUM, role, 7) \
|
||||
X(a, STATIC, SINGULAR, BYTES, public_key, 8)
|
||||
X(a, STATIC, SINGULAR, BYTES, public_key, 8) \
|
||||
X(a, STATIC, OPTIONAL, BOOL, is_unmessagable, 9)
|
||||
#define meshtastic_User_CALLBACK NULL
|
||||
#define meshtastic_User_DEFAULT NULL
|
||||
|
||||
@@ -1483,6 +1576,13 @@ X(a, STATIC, OPTIONAL, UINT32, bitfield, 9)
|
||||
#define meshtastic_Data_CALLBACK NULL
|
||||
#define meshtastic_Data_DEFAULT NULL
|
||||
|
||||
#define meshtastic_KeyVerification_FIELDLIST(X, a) \
|
||||
X(a, STATIC, SINGULAR, UINT64, nonce, 1) \
|
||||
X(a, STATIC, SINGULAR, BYTES, hash1, 2) \
|
||||
X(a, STATIC, SINGULAR, BYTES, hash2, 3)
|
||||
#define meshtastic_KeyVerification_CALLBACK NULL
|
||||
#define meshtastic_KeyVerification_DEFAULT NULL
|
||||
|
||||
#define meshtastic_Waypoint_FIELDLIST(X, a) \
|
||||
X(a, STATIC, SINGULAR, UINT32, id, 1) \
|
||||
X(a, STATIC, OPTIONAL, SFIXED32, latitude_i, 2) \
|
||||
@@ -1539,7 +1639,8 @@ X(a, STATIC, SINGULAR, UINT32, channel, 7) \
|
||||
X(a, STATIC, SINGULAR, BOOL, via_mqtt, 8) \
|
||||
X(a, STATIC, OPTIONAL, UINT32, hops_away, 9) \
|
||||
X(a, STATIC, SINGULAR, BOOL, is_favorite, 10) \
|
||||
X(a, STATIC, SINGULAR, BOOL, is_ignored, 11)
|
||||
X(a, STATIC, SINGULAR, BOOL, is_ignored, 11) \
|
||||
X(a, STATIC, SINGULAR, BOOL, is_key_manually_verified, 12)
|
||||
#define meshtastic_NodeInfo_CALLBACK NULL
|
||||
#define meshtastic_NodeInfo_DEFAULT NULL
|
||||
#define meshtastic_NodeInfo_user_MSGTYPE meshtastic_User
|
||||
@@ -1610,9 +1711,36 @@ X(a, STATIC, ONEOF, MESSAGE, (payload_variant,deviceuiConfig,deviceuiConfi
|
||||
X(a, STATIC, OPTIONAL, UINT32, reply_id, 1) \
|
||||
X(a, STATIC, SINGULAR, FIXED32, time, 2) \
|
||||
X(a, STATIC, SINGULAR, UENUM, level, 3) \
|
||||
X(a, STATIC, SINGULAR, STRING, message, 4)
|
||||
X(a, STATIC, SINGULAR, STRING, message, 4) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,key_verification_number_inform,payload_variant.key_verification_number_inform), 11) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,key_verification_number_request,payload_variant.key_verification_number_request), 12) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (payload_variant,key_verification_final,payload_variant.key_verification_final), 13)
|
||||
#define meshtastic_ClientNotification_CALLBACK NULL
|
||||
#define meshtastic_ClientNotification_DEFAULT NULL
|
||||
#define meshtastic_ClientNotification_payload_variant_key_verification_number_inform_MSGTYPE meshtastic_KeyVerificationNumberInform
|
||||
#define meshtastic_ClientNotification_payload_variant_key_verification_number_request_MSGTYPE meshtastic_KeyVerificationNumberRequest
|
||||
#define meshtastic_ClientNotification_payload_variant_key_verification_final_MSGTYPE meshtastic_KeyVerificationFinal
|
||||
|
||||
#define meshtastic_KeyVerificationNumberInform_FIELDLIST(X, a) \
|
||||
X(a, STATIC, SINGULAR, UINT64, nonce, 1) \
|
||||
X(a, STATIC, SINGULAR, STRING, remote_longname, 2) \
|
||||
X(a, STATIC, SINGULAR, UINT32, security_number, 3)
|
||||
#define meshtastic_KeyVerificationNumberInform_CALLBACK NULL
|
||||
#define meshtastic_KeyVerificationNumberInform_DEFAULT NULL
|
||||
|
||||
#define meshtastic_KeyVerificationNumberRequest_FIELDLIST(X, a) \
|
||||
X(a, STATIC, SINGULAR, UINT64, nonce, 1) \
|
||||
X(a, STATIC, SINGULAR, STRING, remote_longname, 2)
|
||||
#define meshtastic_KeyVerificationNumberRequest_CALLBACK NULL
|
||||
#define meshtastic_KeyVerificationNumberRequest_DEFAULT NULL
|
||||
|
||||
#define meshtastic_KeyVerificationFinal_FIELDLIST(X, a) \
|
||||
X(a, STATIC, SINGULAR, UINT64, nonce, 1) \
|
||||
X(a, STATIC, SINGULAR, STRING, remote_longname, 2) \
|
||||
X(a, STATIC, SINGULAR, BOOL, isSender, 3) \
|
||||
X(a, STATIC, SINGULAR, STRING, verification_characters, 4)
|
||||
#define meshtastic_KeyVerificationFinal_CALLBACK NULL
|
||||
#define meshtastic_KeyVerificationFinal_DEFAULT NULL
|
||||
|
||||
#define meshtastic_FileInfo_FIELDLIST(X, a) \
|
||||
X(a, STATIC, SINGULAR, STRING, file_name, 1) \
|
||||
@@ -1712,6 +1840,7 @@ extern const pb_msgdesc_t meshtastic_User_msg;
|
||||
extern const pb_msgdesc_t meshtastic_RouteDiscovery_msg;
|
||||
extern const pb_msgdesc_t meshtastic_Routing_msg;
|
||||
extern const pb_msgdesc_t meshtastic_Data_msg;
|
||||
extern const pb_msgdesc_t meshtastic_KeyVerification_msg;
|
||||
extern const pb_msgdesc_t meshtastic_Waypoint_msg;
|
||||
extern const pb_msgdesc_t meshtastic_MqttClientProxyMessage_msg;
|
||||
extern const pb_msgdesc_t meshtastic_MeshPacket_msg;
|
||||
@@ -1721,6 +1850,9 @@ extern const pb_msgdesc_t meshtastic_LogRecord_msg;
|
||||
extern const pb_msgdesc_t meshtastic_QueueStatus_msg;
|
||||
extern const pb_msgdesc_t meshtastic_FromRadio_msg;
|
||||
extern const pb_msgdesc_t meshtastic_ClientNotification_msg;
|
||||
extern const pb_msgdesc_t meshtastic_KeyVerificationNumberInform_msg;
|
||||
extern const pb_msgdesc_t meshtastic_KeyVerificationNumberRequest_msg;
|
||||
extern const pb_msgdesc_t meshtastic_KeyVerificationFinal_msg;
|
||||
extern const pb_msgdesc_t meshtastic_FileInfo_msg;
|
||||
extern const pb_msgdesc_t meshtastic_ToRadio_msg;
|
||||
extern const pb_msgdesc_t meshtastic_Compressed_msg;
|
||||
@@ -1739,6 +1871,7 @@ extern const pb_msgdesc_t meshtastic_ChunkedPayloadResponse_msg;
|
||||
#define meshtastic_RouteDiscovery_fields &meshtastic_RouteDiscovery_msg
|
||||
#define meshtastic_Routing_fields &meshtastic_Routing_msg
|
||||
#define meshtastic_Data_fields &meshtastic_Data_msg
|
||||
#define meshtastic_KeyVerification_fields &meshtastic_KeyVerification_msg
|
||||
#define meshtastic_Waypoint_fields &meshtastic_Waypoint_msg
|
||||
#define meshtastic_MqttClientProxyMessage_fields &meshtastic_MqttClientProxyMessage_msg
|
||||
#define meshtastic_MeshPacket_fields &meshtastic_MeshPacket_msg
|
||||
@@ -1748,6 +1881,9 @@ extern const pb_msgdesc_t meshtastic_ChunkedPayloadResponse_msg;
|
||||
#define meshtastic_QueueStatus_fields &meshtastic_QueueStatus_msg
|
||||
#define meshtastic_FromRadio_fields &meshtastic_FromRadio_msg
|
||||
#define meshtastic_ClientNotification_fields &meshtastic_ClientNotification_msg
|
||||
#define meshtastic_KeyVerificationNumberInform_fields &meshtastic_KeyVerificationNumberInform_msg
|
||||
#define meshtastic_KeyVerificationNumberRequest_fields &meshtastic_KeyVerificationNumberRequest_msg
|
||||
#define meshtastic_KeyVerificationFinal_fields &meshtastic_KeyVerificationFinal_msg
|
||||
#define meshtastic_FileInfo_fields &meshtastic_FileInfo_msg
|
||||
#define meshtastic_ToRadio_fields &meshtastic_ToRadio_msg
|
||||
#define meshtastic_Compressed_fields &meshtastic_Compressed_msg
|
||||
@@ -1765,27 +1901,31 @@ extern const pb_msgdesc_t meshtastic_ChunkedPayloadResponse_msg;
|
||||
/* meshtastic_ChunkedPayloadResponse_size depends on runtime parameters */
|
||||
#define MESHTASTIC_MESHTASTIC_MESH_PB_H_MAX_SIZE meshtastic_FromRadio_size
|
||||
#define meshtastic_ChunkedPayload_size 245
|
||||
#define meshtastic_ClientNotification_size 415
|
||||
#define meshtastic_ClientNotification_size 482
|
||||
#define meshtastic_Compressed_size 239
|
||||
#define meshtastic_Data_size 269
|
||||
#define meshtastic_DeviceMetadata_size 54
|
||||
#define meshtastic_FileInfo_size 236
|
||||
#define meshtastic_FromRadio_size 510
|
||||
#define meshtastic_Heartbeat_size 0
|
||||
#define meshtastic_KeyVerificationFinal_size 65
|
||||
#define meshtastic_KeyVerificationNumberInform_size 58
|
||||
#define meshtastic_KeyVerificationNumberRequest_size 52
|
||||
#define meshtastic_KeyVerification_size 79
|
||||
#define meshtastic_LogRecord_size 426
|
||||
#define meshtastic_MeshPacket_size 378
|
||||
#define meshtastic_MqttClientProxyMessage_size 501
|
||||
#define meshtastic_MyNodeInfo_size 77
|
||||
#define meshtastic_NeighborInfo_size 258
|
||||
#define meshtastic_Neighbor_size 22
|
||||
#define meshtastic_NodeInfo_size 319
|
||||
#define meshtastic_NodeInfo_size 323
|
||||
#define meshtastic_NodeRemoteHardwarePin_size 29
|
||||
#define meshtastic_Position_size 144
|
||||
#define meshtastic_QueueStatus_size 23
|
||||
#define meshtastic_RouteDiscovery_size 256
|
||||
#define meshtastic_Routing_size 259
|
||||
#define meshtastic_ToRadio_size 504
|
||||
#define meshtastic_User_size 113
|
||||
#define meshtastic_User_size 115
|
||||
#define meshtastic_Waypoint_size 165
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -79,7 +79,10 @@ typedef enum _meshtastic_ModuleConfig_SerialConfig_Serial_Mode {
|
||||
/* NMEA messages specifically tailored for CalTopo */
|
||||
meshtastic_ModuleConfig_SerialConfig_Serial_Mode_CALTOPO = 5,
|
||||
/* Ecowitt WS85 weather station */
|
||||
meshtastic_ModuleConfig_SerialConfig_Serial_Mode_WS85 = 6
|
||||
meshtastic_ModuleConfig_SerialConfig_Serial_Mode_WS85 = 6,
|
||||
/* VE.Direct is a serial protocol used by Victron Energy products
|
||||
https://beta.ivc.no/wiki/index.php/Victron_VE_Direct_DIY_Cable */
|
||||
meshtastic_ModuleConfig_SerialConfig_Serial_Mode_VE_DIRECT = 7
|
||||
} meshtastic_ModuleConfig_SerialConfig_Serial_Mode;
|
||||
|
||||
/* TODO: REPLACE */
|
||||
@@ -109,6 +112,8 @@ typedef struct _meshtastic_ModuleConfig_MapReportSettings {
|
||||
uint32_t publish_interval_secs;
|
||||
/* Bits of precision for the location sent (default of 32 is full precision). */
|
||||
uint32_t position_precision;
|
||||
/* Whether we have opted-in to report our location to the map */
|
||||
bool should_report_location;
|
||||
} meshtastic_ModuleConfig_MapReportSettings;
|
||||
|
||||
/* MQTT Client Config */
|
||||
@@ -467,8 +472,8 @@ extern "C" {
|
||||
#define _meshtastic_ModuleConfig_SerialConfig_Serial_Baud_ARRAYSIZE ((meshtastic_ModuleConfig_SerialConfig_Serial_Baud)(meshtastic_ModuleConfig_SerialConfig_Serial_Baud_BAUD_921600+1))
|
||||
|
||||
#define _meshtastic_ModuleConfig_SerialConfig_Serial_Mode_MIN meshtastic_ModuleConfig_SerialConfig_Serial_Mode_DEFAULT
|
||||
#define _meshtastic_ModuleConfig_SerialConfig_Serial_Mode_MAX meshtastic_ModuleConfig_SerialConfig_Serial_Mode_WS85
|
||||
#define _meshtastic_ModuleConfig_SerialConfig_Serial_Mode_ARRAYSIZE ((meshtastic_ModuleConfig_SerialConfig_Serial_Mode)(meshtastic_ModuleConfig_SerialConfig_Serial_Mode_WS85+1))
|
||||
#define _meshtastic_ModuleConfig_SerialConfig_Serial_Mode_MAX meshtastic_ModuleConfig_SerialConfig_Serial_Mode_VE_DIRECT
|
||||
#define _meshtastic_ModuleConfig_SerialConfig_Serial_Mode_ARRAYSIZE ((meshtastic_ModuleConfig_SerialConfig_Serial_Mode)(meshtastic_ModuleConfig_SerialConfig_Serial_Mode_VE_DIRECT+1))
|
||||
|
||||
#define _meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_MIN meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_NONE
|
||||
#define _meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_MAX meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_BACK
|
||||
@@ -502,7 +507,7 @@ extern "C" {
|
||||
/* Initializer values for message structs */
|
||||
#define meshtastic_ModuleConfig_init_default {0, {meshtastic_ModuleConfig_MQTTConfig_init_default}}
|
||||
#define meshtastic_ModuleConfig_MQTTConfig_init_default {0, "", "", "", 0, 0, 0, "", 0, 0, false, meshtastic_ModuleConfig_MapReportSettings_init_default}
|
||||
#define meshtastic_ModuleConfig_MapReportSettings_init_default {0, 0}
|
||||
#define meshtastic_ModuleConfig_MapReportSettings_init_default {0, 0, 0}
|
||||
#define meshtastic_ModuleConfig_RemoteHardwareConfig_init_default {0, 0, 0, {meshtastic_RemoteHardwarePin_init_default, meshtastic_RemoteHardwarePin_init_default, meshtastic_RemoteHardwarePin_init_default, meshtastic_RemoteHardwarePin_init_default}}
|
||||
#define meshtastic_ModuleConfig_NeighborInfoConfig_init_default {0, 0, 0}
|
||||
#define meshtastic_ModuleConfig_DetectionSensorConfig_init_default {0, 0, 0, 0, "", 0, _meshtastic_ModuleConfig_DetectionSensorConfig_TriggerType_MIN, 0}
|
||||
@@ -518,7 +523,7 @@ extern "C" {
|
||||
#define meshtastic_RemoteHardwarePin_init_default {0, "", _meshtastic_RemoteHardwarePinType_MIN}
|
||||
#define meshtastic_ModuleConfig_init_zero {0, {meshtastic_ModuleConfig_MQTTConfig_init_zero}}
|
||||
#define meshtastic_ModuleConfig_MQTTConfig_init_zero {0, "", "", "", 0, 0, 0, "", 0, 0, false, meshtastic_ModuleConfig_MapReportSettings_init_zero}
|
||||
#define meshtastic_ModuleConfig_MapReportSettings_init_zero {0, 0}
|
||||
#define meshtastic_ModuleConfig_MapReportSettings_init_zero {0, 0, 0}
|
||||
#define meshtastic_ModuleConfig_RemoteHardwareConfig_init_zero {0, 0, 0, {meshtastic_RemoteHardwarePin_init_zero, meshtastic_RemoteHardwarePin_init_zero, meshtastic_RemoteHardwarePin_init_zero, meshtastic_RemoteHardwarePin_init_zero}}
|
||||
#define meshtastic_ModuleConfig_NeighborInfoConfig_init_zero {0, 0, 0}
|
||||
#define meshtastic_ModuleConfig_DetectionSensorConfig_init_zero {0, 0, 0, 0, "", 0, _meshtastic_ModuleConfig_DetectionSensorConfig_TriggerType_MIN, 0}
|
||||
@@ -536,6 +541,7 @@ extern "C" {
|
||||
/* Field tags (for use in manual encoding/decoding) */
|
||||
#define meshtastic_ModuleConfig_MapReportSettings_publish_interval_secs_tag 1
|
||||
#define meshtastic_ModuleConfig_MapReportSettings_position_precision_tag 2
|
||||
#define meshtastic_ModuleConfig_MapReportSettings_should_report_location_tag 3
|
||||
#define meshtastic_ModuleConfig_MQTTConfig_enabled_tag 1
|
||||
#define meshtastic_ModuleConfig_MQTTConfig_address_tag 2
|
||||
#define meshtastic_ModuleConfig_MQTTConfig_username_tag 3
|
||||
@@ -699,7 +705,8 @@ X(a, STATIC, OPTIONAL, MESSAGE, map_report_settings, 11)
|
||||
|
||||
#define meshtastic_ModuleConfig_MapReportSettings_FIELDLIST(X, a) \
|
||||
X(a, STATIC, SINGULAR, UINT32, publish_interval_secs, 1) \
|
||||
X(a, STATIC, SINGULAR, UINT32, position_precision, 2)
|
||||
X(a, STATIC, SINGULAR, UINT32, position_precision, 2) \
|
||||
X(a, STATIC, SINGULAR, BOOL, should_report_location, 3)
|
||||
#define meshtastic_ModuleConfig_MapReportSettings_CALLBACK NULL
|
||||
#define meshtastic_ModuleConfig_MapReportSettings_DEFAULT NULL
|
||||
|
||||
@@ -887,8 +894,8 @@ extern const pb_msgdesc_t meshtastic_RemoteHardwarePin_msg;
|
||||
#define meshtastic_ModuleConfig_CannedMessageConfig_size 49
|
||||
#define meshtastic_ModuleConfig_DetectionSensorConfig_size 44
|
||||
#define meshtastic_ModuleConfig_ExternalNotificationConfig_size 42
|
||||
#define meshtastic_ModuleConfig_MQTTConfig_size 222
|
||||
#define meshtastic_ModuleConfig_MapReportSettings_size 12
|
||||
#define meshtastic_ModuleConfig_MQTTConfig_size 224
|
||||
#define meshtastic_ModuleConfig_MapReportSettings_size 14
|
||||
#define meshtastic_ModuleConfig_NeighborInfoConfig_size 10
|
||||
#define meshtastic_ModuleConfig_PaxcounterConfig_size 30
|
||||
#define meshtastic_ModuleConfig_RangeTestConfig_size 10
|
||||
@@ -896,7 +903,7 @@ extern const pb_msgdesc_t meshtastic_RemoteHardwarePin_msg;
|
||||
#define meshtastic_ModuleConfig_SerialConfig_size 28
|
||||
#define meshtastic_ModuleConfig_StoreForwardConfig_size 24
|
||||
#define meshtastic_ModuleConfig_TelemetryConfig_size 46
|
||||
#define meshtastic_ModuleConfig_size 225
|
||||
#define meshtastic_ModuleConfig_size 227
|
||||
#define meshtastic_RemoteHardwarePin_size 21
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -54,6 +54,9 @@ typedef struct _meshtastic_MapReport {
|
||||
uint32_t position_precision;
|
||||
/* Number of online nodes (heard in the last 2 hours) this node has in its list that were received locally (not via MQTT) */
|
||||
uint16_t num_online_local_nodes;
|
||||
/* User has opted in to share their location (map report) with the mqtt server
|
||||
Controlled by map_report.should_report_location */
|
||||
bool has_opted_report_location;
|
||||
} meshtastic_MapReport;
|
||||
|
||||
|
||||
@@ -63,9 +66,9 @@ extern "C" {
|
||||
|
||||
/* Initializer values for message structs */
|
||||
#define meshtastic_ServiceEnvelope_init_default {NULL, NULL, NULL}
|
||||
#define meshtastic_MapReport_init_default {"", "", _meshtastic_Config_DeviceConfig_Role_MIN, _meshtastic_HardwareModel_MIN, "", _meshtastic_Config_LoRaConfig_RegionCode_MIN, _meshtastic_Config_LoRaConfig_ModemPreset_MIN, 0, 0, 0, 0, 0, 0}
|
||||
#define meshtastic_MapReport_init_default {"", "", _meshtastic_Config_DeviceConfig_Role_MIN, _meshtastic_HardwareModel_MIN, "", _meshtastic_Config_LoRaConfig_RegionCode_MIN, _meshtastic_Config_LoRaConfig_ModemPreset_MIN, 0, 0, 0, 0, 0, 0, 0}
|
||||
#define meshtastic_ServiceEnvelope_init_zero {NULL, NULL, NULL}
|
||||
#define meshtastic_MapReport_init_zero {"", "", _meshtastic_Config_DeviceConfig_Role_MIN, _meshtastic_HardwareModel_MIN, "", _meshtastic_Config_LoRaConfig_RegionCode_MIN, _meshtastic_Config_LoRaConfig_ModemPreset_MIN, 0, 0, 0, 0, 0, 0}
|
||||
#define meshtastic_MapReport_init_zero {"", "", _meshtastic_Config_DeviceConfig_Role_MIN, _meshtastic_HardwareModel_MIN, "", _meshtastic_Config_LoRaConfig_RegionCode_MIN, _meshtastic_Config_LoRaConfig_ModemPreset_MIN, 0, 0, 0, 0, 0, 0, 0}
|
||||
|
||||
/* Field tags (for use in manual encoding/decoding) */
|
||||
#define meshtastic_ServiceEnvelope_packet_tag 1
|
||||
@@ -84,6 +87,7 @@ extern "C" {
|
||||
#define meshtastic_MapReport_altitude_tag 11
|
||||
#define meshtastic_MapReport_position_precision_tag 12
|
||||
#define meshtastic_MapReport_num_online_local_nodes_tag 13
|
||||
#define meshtastic_MapReport_has_opted_report_location_tag 14
|
||||
|
||||
/* Struct field encoding specification for nanopb */
|
||||
#define meshtastic_ServiceEnvelope_FIELDLIST(X, a) \
|
||||
@@ -107,7 +111,8 @@ X(a, STATIC, SINGULAR, SFIXED32, latitude_i, 9) \
|
||||
X(a, STATIC, SINGULAR, SFIXED32, longitude_i, 10) \
|
||||
X(a, STATIC, SINGULAR, INT32, altitude, 11) \
|
||||
X(a, STATIC, SINGULAR, UINT32, position_precision, 12) \
|
||||
X(a, STATIC, SINGULAR, UINT32, num_online_local_nodes, 13)
|
||||
X(a, STATIC, SINGULAR, UINT32, num_online_local_nodes, 13) \
|
||||
X(a, STATIC, SINGULAR, BOOL, has_opted_report_location, 14)
|
||||
#define meshtastic_MapReport_CALLBACK NULL
|
||||
#define meshtastic_MapReport_DEFAULT NULL
|
||||
|
||||
@@ -121,7 +126,7 @@ extern const pb_msgdesc_t meshtastic_MapReport_msg;
|
||||
/* Maximum encoded size of messages (where known) */
|
||||
/* meshtastic_ServiceEnvelope_size depends on runtime parameters */
|
||||
#define MESHTASTIC_MESHTASTIC_MQTT_PB_H_MAX_SIZE meshtastic_MapReport_size
|
||||
#define meshtastic_MapReport_size 108
|
||||
#define meshtastic_MapReport_size 110
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
|
||||
@@ -74,6 +74,8 @@ typedef enum _meshtastic_PortNum {
|
||||
meshtastic_PortNum_DETECTION_SENSOR_APP = 10,
|
||||
/* Same as Text Message but used for critical alerts. */
|
||||
meshtastic_PortNum_ALERT_APP = 11,
|
||||
/* Module/port for handling key verification requests. */
|
||||
meshtastic_PortNum_KEY_VERIFICATION_APP = 12,
|
||||
/* Provides a 'ping' service that replies to any packet it receives.
|
||||
Also serves as a small example module.
|
||||
ENCODING: ASCII Plaintext */
|
||||
|
||||
@@ -24,7 +24,10 @@ PB_BIND(meshtastic_LocalStats, meshtastic_LocalStats, AUTO)
|
||||
PB_BIND(meshtastic_HealthMetrics, meshtastic_HealthMetrics, AUTO)
|
||||
|
||||
|
||||
PB_BIND(meshtastic_Telemetry, meshtastic_Telemetry, AUTO)
|
||||
PB_BIND(meshtastic_HostMetrics, meshtastic_HostMetrics, 2)
|
||||
|
||||
|
||||
PB_BIND(meshtastic_Telemetry, meshtastic_Telemetry, 2)
|
||||
|
||||
|
||||
PB_BIND(meshtastic_Nau7802Config, meshtastic_Nau7802Config, AUTO)
|
||||
|
||||
@@ -87,7 +87,11 @@ typedef enum _meshtastic_TelemetrySensorType {
|
||||
/* Infineon DPS310 High accuracy pressure and temperature */
|
||||
meshtastic_TelemetrySensorType_DPS310 = 36,
|
||||
/* RAKWireless RAK12035 Soil Moisture Sensor Module */
|
||||
meshtastic_TelemetrySensorType_RAK12035 = 37
|
||||
meshtastic_TelemetrySensorType_RAK12035 = 37,
|
||||
/* MAX17261 lipo battery gauge */
|
||||
meshtastic_TelemetrySensorType_MAX17261 = 38,
|
||||
/* PCT2075 Temperature Sensor */
|
||||
meshtastic_TelemetrySensorType_PCT2075 = 39
|
||||
} meshtastic_TelemetrySensorType;
|
||||
|
||||
/* Struct definitions */
|
||||
@@ -242,7 +246,7 @@ typedef struct _meshtastic_AirQualityMetrics {
|
||||
/* 10.0um Particle Count */
|
||||
bool has_particles_100um;
|
||||
uint32_t particles_100um;
|
||||
/* 10.0um Particle Count */
|
||||
/* CO2 concentration in ppm */
|
||||
bool has_co2;
|
||||
uint32_t co2;
|
||||
} meshtastic_AirQualityMetrics;
|
||||
@@ -273,6 +277,10 @@ typedef struct _meshtastic_LocalStats {
|
||||
/* Number of times we canceled a packet to be relayed, because someone else did it before us.
|
||||
This will always be zero for ROUTERs/REPEATERs. If this number is high, some other node(s) is/are relaying faster than you. */
|
||||
uint32_t num_tx_relay_canceled;
|
||||
/* Number of bytes used in the heap */
|
||||
uint32_t heap_total_bytes;
|
||||
/* Number of bytes free in the heap */
|
||||
uint32_t heap_free_bytes;
|
||||
} meshtastic_LocalStats;
|
||||
|
||||
/* Health telemetry metrics */
|
||||
@@ -288,6 +296,32 @@ typedef struct _meshtastic_HealthMetrics {
|
||||
float temperature;
|
||||
} meshtastic_HealthMetrics;
|
||||
|
||||
/* Linux host metrics */
|
||||
typedef struct _meshtastic_HostMetrics {
|
||||
/* Host system uptime */
|
||||
uint32_t uptime_seconds;
|
||||
/* Host system free memory */
|
||||
uint64_t freemem_bytes;
|
||||
/* Host system disk space free for / */
|
||||
uint64_t diskfree1_bytes;
|
||||
/* Secondary system disk space free */
|
||||
bool has_diskfree2_bytes;
|
||||
uint64_t diskfree2_bytes;
|
||||
/* Tertiary disk space free */
|
||||
bool has_diskfree3_bytes;
|
||||
uint64_t diskfree3_bytes;
|
||||
/* Host system one minute load in 1/100ths */
|
||||
uint16_t load1;
|
||||
/* Host system five minute load in 1/100ths */
|
||||
uint16_t load5;
|
||||
/* Host system fifteen minute load in 1/100ths */
|
||||
uint16_t load15;
|
||||
/* Optional User-provided string for arbitrary host system information
|
||||
that doesn't make sense as a dedicated entry. */
|
||||
bool has_user_string;
|
||||
char user_string[200];
|
||||
} meshtastic_HostMetrics;
|
||||
|
||||
/* Types of Measurements the telemetry module is equipped to handle */
|
||||
typedef struct _meshtastic_Telemetry {
|
||||
/* Seconds since 1970 - or 0 for unknown/unset */
|
||||
@@ -306,6 +340,8 @@ typedef struct _meshtastic_Telemetry {
|
||||
meshtastic_LocalStats local_stats;
|
||||
/* Health telemetry metrics */
|
||||
meshtastic_HealthMetrics health_metrics;
|
||||
/* Linux host metrics */
|
||||
meshtastic_HostMetrics host_metrics;
|
||||
} variant;
|
||||
} meshtastic_Telemetry;
|
||||
|
||||
@@ -324,8 +360,9 @@ extern "C" {
|
||||
|
||||
/* Helper constants for enums */
|
||||
#define _meshtastic_TelemetrySensorType_MIN meshtastic_TelemetrySensorType_SENSOR_UNSET
|
||||
#define _meshtastic_TelemetrySensorType_MAX meshtastic_TelemetrySensorType_RAK12035
|
||||
#define _meshtastic_TelemetrySensorType_ARRAYSIZE ((meshtastic_TelemetrySensorType)(meshtastic_TelemetrySensorType_RAK12035+1))
|
||||
#define _meshtastic_TelemetrySensorType_MAX meshtastic_TelemetrySensorType_PCT2075
|
||||
#define _meshtastic_TelemetrySensorType_ARRAYSIZE ((meshtastic_TelemetrySensorType)(meshtastic_TelemetrySensorType_PCT2075+1))
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -341,16 +378,18 @@ extern "C" {
|
||||
#define meshtastic_EnvironmentMetrics_init_default {false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0}
|
||||
#define meshtastic_PowerMetrics_init_default {false, 0, false, 0, false, 0, false, 0, false, 0, false, 0}
|
||||
#define meshtastic_AirQualityMetrics_init_default {false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0}
|
||||
#define meshtastic_LocalStats_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||
#define meshtastic_LocalStats_init_default {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||
#define meshtastic_HealthMetrics_init_default {false, 0, false, 0, false, 0}
|
||||
#define meshtastic_HostMetrics_init_default {0, 0, 0, false, 0, false, 0, 0, 0, 0, false, ""}
|
||||
#define meshtastic_Telemetry_init_default {0, 0, {meshtastic_DeviceMetrics_init_default}}
|
||||
#define meshtastic_Nau7802Config_init_default {0, 0}
|
||||
#define meshtastic_DeviceMetrics_init_zero {false, 0, false, 0, false, 0, false, 0, false, 0}
|
||||
#define meshtastic_EnvironmentMetrics_init_zero {false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0}
|
||||
#define meshtastic_PowerMetrics_init_zero {false, 0, false, 0, false, 0, false, 0, false, 0, false, 0}
|
||||
#define meshtastic_AirQualityMetrics_init_zero {false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0, false, 0}
|
||||
#define meshtastic_LocalStats_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||
#define meshtastic_LocalStats_init_zero {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||
#define meshtastic_HealthMetrics_init_zero {false, 0, false, 0, false, 0}
|
||||
#define meshtastic_HostMetrics_init_zero {0, 0, 0, false, 0, false, 0, 0, 0, 0, false, ""}
|
||||
#define meshtastic_Telemetry_init_zero {0, 0, {meshtastic_DeviceMetrics_init_zero}}
|
||||
#define meshtastic_Nau7802Config_init_zero {0, 0}
|
||||
|
||||
@@ -412,9 +451,20 @@ extern "C" {
|
||||
#define meshtastic_LocalStats_num_rx_dupe_tag 9
|
||||
#define meshtastic_LocalStats_num_tx_relay_tag 10
|
||||
#define meshtastic_LocalStats_num_tx_relay_canceled_tag 11
|
||||
#define meshtastic_LocalStats_heap_total_bytes_tag 12
|
||||
#define meshtastic_LocalStats_heap_free_bytes_tag 13
|
||||
#define meshtastic_HealthMetrics_heart_bpm_tag 1
|
||||
#define meshtastic_HealthMetrics_spO2_tag 2
|
||||
#define meshtastic_HealthMetrics_temperature_tag 3
|
||||
#define meshtastic_HostMetrics_uptime_seconds_tag 1
|
||||
#define meshtastic_HostMetrics_freemem_bytes_tag 2
|
||||
#define meshtastic_HostMetrics_diskfree1_bytes_tag 3
|
||||
#define meshtastic_HostMetrics_diskfree2_bytes_tag 4
|
||||
#define meshtastic_HostMetrics_diskfree3_bytes_tag 5
|
||||
#define meshtastic_HostMetrics_load1_tag 6
|
||||
#define meshtastic_HostMetrics_load5_tag 7
|
||||
#define meshtastic_HostMetrics_load15_tag 8
|
||||
#define meshtastic_HostMetrics_user_string_tag 9
|
||||
#define meshtastic_Telemetry_time_tag 1
|
||||
#define meshtastic_Telemetry_device_metrics_tag 2
|
||||
#define meshtastic_Telemetry_environment_metrics_tag 3
|
||||
@@ -422,6 +472,7 @@ extern "C" {
|
||||
#define meshtastic_Telemetry_power_metrics_tag 5
|
||||
#define meshtastic_Telemetry_local_stats_tag 6
|
||||
#define meshtastic_Telemetry_health_metrics_tag 7
|
||||
#define meshtastic_Telemetry_host_metrics_tag 8
|
||||
#define meshtastic_Nau7802Config_zeroOffset_tag 1
|
||||
#define meshtastic_Nau7802Config_calibrationFactor_tag 2
|
||||
|
||||
@@ -499,7 +550,9 @@ X(a, STATIC, SINGULAR, UINT32, num_online_nodes, 7) \
|
||||
X(a, STATIC, SINGULAR, UINT32, num_total_nodes, 8) \
|
||||
X(a, STATIC, SINGULAR, UINT32, num_rx_dupe, 9) \
|
||||
X(a, STATIC, SINGULAR, UINT32, num_tx_relay, 10) \
|
||||
X(a, STATIC, SINGULAR, UINT32, num_tx_relay_canceled, 11)
|
||||
X(a, STATIC, SINGULAR, UINT32, num_tx_relay_canceled, 11) \
|
||||
X(a, STATIC, SINGULAR, UINT32, heap_total_bytes, 12) \
|
||||
X(a, STATIC, SINGULAR, UINT32, heap_free_bytes, 13)
|
||||
#define meshtastic_LocalStats_CALLBACK NULL
|
||||
#define meshtastic_LocalStats_DEFAULT NULL
|
||||
|
||||
@@ -510,6 +563,19 @@ X(a, STATIC, OPTIONAL, FLOAT, temperature, 3)
|
||||
#define meshtastic_HealthMetrics_CALLBACK NULL
|
||||
#define meshtastic_HealthMetrics_DEFAULT NULL
|
||||
|
||||
#define meshtastic_HostMetrics_FIELDLIST(X, a) \
|
||||
X(a, STATIC, SINGULAR, UINT32, uptime_seconds, 1) \
|
||||
X(a, STATIC, SINGULAR, UINT64, freemem_bytes, 2) \
|
||||
X(a, STATIC, SINGULAR, UINT64, diskfree1_bytes, 3) \
|
||||
X(a, STATIC, OPTIONAL, UINT64, diskfree2_bytes, 4) \
|
||||
X(a, STATIC, OPTIONAL, UINT64, diskfree3_bytes, 5) \
|
||||
X(a, STATIC, SINGULAR, UINT32, load1, 6) \
|
||||
X(a, STATIC, SINGULAR, UINT32, load5, 7) \
|
||||
X(a, STATIC, SINGULAR, UINT32, load15, 8) \
|
||||
X(a, STATIC, OPTIONAL, STRING, user_string, 9)
|
||||
#define meshtastic_HostMetrics_CALLBACK NULL
|
||||
#define meshtastic_HostMetrics_DEFAULT NULL
|
||||
|
||||
#define meshtastic_Telemetry_FIELDLIST(X, a) \
|
||||
X(a, STATIC, SINGULAR, FIXED32, time, 1) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (variant,device_metrics,variant.device_metrics), 2) \
|
||||
@@ -517,7 +583,8 @@ X(a, STATIC, ONEOF, MESSAGE, (variant,environment_metrics,variant.environm
|
||||
X(a, STATIC, ONEOF, MESSAGE, (variant,air_quality_metrics,variant.air_quality_metrics), 4) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (variant,power_metrics,variant.power_metrics), 5) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (variant,local_stats,variant.local_stats), 6) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (variant,health_metrics,variant.health_metrics), 7)
|
||||
X(a, STATIC, ONEOF, MESSAGE, (variant,health_metrics,variant.health_metrics), 7) \
|
||||
X(a, STATIC, ONEOF, MESSAGE, (variant,host_metrics,variant.host_metrics), 8)
|
||||
#define meshtastic_Telemetry_CALLBACK NULL
|
||||
#define meshtastic_Telemetry_DEFAULT NULL
|
||||
#define meshtastic_Telemetry_variant_device_metrics_MSGTYPE meshtastic_DeviceMetrics
|
||||
@@ -526,6 +593,7 @@ X(a, STATIC, ONEOF, MESSAGE, (variant,health_metrics,variant.health_metric
|
||||
#define meshtastic_Telemetry_variant_power_metrics_MSGTYPE meshtastic_PowerMetrics
|
||||
#define meshtastic_Telemetry_variant_local_stats_MSGTYPE meshtastic_LocalStats
|
||||
#define meshtastic_Telemetry_variant_health_metrics_MSGTYPE meshtastic_HealthMetrics
|
||||
#define meshtastic_Telemetry_variant_host_metrics_MSGTYPE meshtastic_HostMetrics
|
||||
|
||||
#define meshtastic_Nau7802Config_FIELDLIST(X, a) \
|
||||
X(a, STATIC, SINGULAR, INT32, zeroOffset, 1) \
|
||||
@@ -539,6 +607,7 @@ extern const pb_msgdesc_t meshtastic_PowerMetrics_msg;
|
||||
extern const pb_msgdesc_t meshtastic_AirQualityMetrics_msg;
|
||||
extern const pb_msgdesc_t meshtastic_LocalStats_msg;
|
||||
extern const pb_msgdesc_t meshtastic_HealthMetrics_msg;
|
||||
extern const pb_msgdesc_t meshtastic_HostMetrics_msg;
|
||||
extern const pb_msgdesc_t meshtastic_Telemetry_msg;
|
||||
extern const pb_msgdesc_t meshtastic_Nau7802Config_msg;
|
||||
|
||||
@@ -549,6 +618,7 @@ extern const pb_msgdesc_t meshtastic_Nau7802Config_msg;
|
||||
#define meshtastic_AirQualityMetrics_fields &meshtastic_AirQualityMetrics_msg
|
||||
#define meshtastic_LocalStats_fields &meshtastic_LocalStats_msg
|
||||
#define meshtastic_HealthMetrics_fields &meshtastic_HealthMetrics_msg
|
||||
#define meshtastic_HostMetrics_fields &meshtastic_HostMetrics_msg
|
||||
#define meshtastic_Telemetry_fields &meshtastic_Telemetry_msg
|
||||
#define meshtastic_Nau7802Config_fields &meshtastic_Nau7802Config_msg
|
||||
|
||||
@@ -558,10 +628,11 @@ extern const pb_msgdesc_t meshtastic_Nau7802Config_msg;
|
||||
#define meshtastic_DeviceMetrics_size 27
|
||||
#define meshtastic_EnvironmentMetrics_size 113
|
||||
#define meshtastic_HealthMetrics_size 11
|
||||
#define meshtastic_LocalStats_size 60
|
||||
#define meshtastic_HostMetrics_size 264
|
||||
#define meshtastic_LocalStats_size 72
|
||||
#define meshtastic_Nau7802Config_size 16
|
||||
#define meshtastic_PowerMetrics_size 30
|
||||
#define meshtastic_Telemetry_size 120
|
||||
#define meshtastic_Telemetry_size 272
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
/// Verify baseline assumption of node size. If it increases, we need to reevaluate
|
||||
/// the impact of its memory footprint, notably on MAX_NUM_NODES.
|
||||
static_assert(sizeof(meshtastic_NodeInfoLite) <= 192, "NodeInfoLite size increased. Reconsider impact on MAX_NUM_NODES.");
|
||||
static_assert(sizeof(meshtastic_NodeInfoLite) <= 200, "NodeInfoLite size increased. Reconsider impact on MAX_NUM_NODES.");
|
||||
|
||||
/// max number of nodes allowed in the nodeDB
|
||||
#ifndef MAX_NUM_NODES
|
||||
|
||||
@@ -462,8 +462,8 @@ PiWebServerThread::PiWebServerThread()
|
||||
webservport = settingsMap[webserverport];
|
||||
LOG_INFO("Use webserver port from yaml config %i ", webservport);
|
||||
} else {
|
||||
LOG_INFO("Webserver port in yaml config set to 0, defaulting to port 443");
|
||||
webservport = 443;
|
||||
LOG_INFO("Webserver port in yaml config set to 0, defaulting to port 9443");
|
||||
webservport = 9443;
|
||||
}
|
||||
|
||||
// Web Content Service Instance
|
||||
|
||||
@@ -13,12 +13,11 @@
|
||||
#endif // HAS_ETHERNET
|
||||
|
||||
#define UDP_MULTICAST_DEFAUL_PORT 4403 // Default port for UDP multicast is same as TCP api server
|
||||
#define UDP_MULTICAST_THREAD_INTERVAL_MS 15000
|
||||
|
||||
class UdpMulticastThread : public concurrency::OSThread
|
||||
class UdpMulticastHandler final
|
||||
{
|
||||
public:
|
||||
UdpMulticastThread() : OSThread("UdpMulticast") { udpIpAddress = IPAddress(224, 0, 0, 69); }
|
||||
UdpMulticastHandler() { udpIpAddress = IPAddress(224, 0, 0, 69); }
|
||||
|
||||
void start()
|
||||
{
|
||||
@@ -71,14 +70,6 @@ class UdpMulticastThread : public concurrency::OSThread
|
||||
return true;
|
||||
}
|
||||
|
||||
protected:
|
||||
int32_t runOnce() override
|
||||
{
|
||||
canSleep = true;
|
||||
// TODO: Implement nodeinfo broadcast
|
||||
return UDP_MULTICAST_THREAD_INTERVAL_MS;
|
||||
}
|
||||
|
||||
private:
|
||||
IPAddress udpIpAddress;
|
||||
AsyncUDP udp;
|
||||
@@ -133,8 +133,8 @@ static void onNetworkConnected()
|
||||
}
|
||||
|
||||
#if HAS_UDP_MULTICAST
|
||||
if (udpThread && config.network.enabled_protocols & meshtastic_Config_NetworkConfig_ProtocolFlags_UDP_BROADCAST) {
|
||||
udpThread->start();
|
||||
if (udpHandler && config.network.enabled_protocols & meshtastic_Config_NetworkConfig_ProtocolFlags_UDP_BROADCAST) {
|
||||
udpHandler->start();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
#include "modules/PositionModule.h"
|
||||
#endif
|
||||
|
||||
#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_I2C
|
||||
#if !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_I2C
|
||||
#include "motion/AccelerometerThread.h"
|
||||
#endif
|
||||
|
||||
@@ -284,7 +284,11 @@ bool AdminModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshta
|
||||
case meshtastic_AdminMessage_remove_by_nodenum_tag: {
|
||||
LOG_INFO("Client received remove_nodenum command");
|
||||
nodeDB->removeNodeByNum(r->remove_by_nodenum);
|
||||
this->notifyObservers(r); // Observed by screen
|
||||
break;
|
||||
}
|
||||
case meshtastic_AdminMessage_add_contact_tag: {
|
||||
LOG_INFO("Client received add_contact command");
|
||||
nodeDB->addFromContact(r->add_contact);
|
||||
break;
|
||||
}
|
||||
case meshtastic_AdminMessage_set_favorite_node_tag: {
|
||||
@@ -444,6 +448,9 @@ bool AdminModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshta
|
||||
myReply = allocErrorResponse(meshtastic_Routing_Error_NONE, &mp);
|
||||
}
|
||||
|
||||
// Allow any observers (e.g. the UI) to respond to this event
|
||||
notifyObservers(r);
|
||||
|
||||
return handled;
|
||||
}
|
||||
|
||||
@@ -497,6 +504,12 @@ void AdminModule::handleSetOwner(const meshtastic_User &o)
|
||||
sendWarning(licensedModeMessage);
|
||||
}
|
||||
}
|
||||
if (owner.has_is_unmessagable != o.has_is_unmessagable ||
|
||||
(o.has_is_unmessagable && owner.is_unmessagable != o.is_unmessagable)) {
|
||||
changed = 1;
|
||||
owner.has_is_unmessagable = o.has_is_unmessagable || o.has_is_unmessagable;
|
||||
owner.is_unmessagable = o.is_unmessagable;
|
||||
}
|
||||
|
||||
if (changed) { // If nothing really changed, don't broadcast on the network or write to flash
|
||||
service->reloadOwner(!hasOpenEditTransaction);
|
||||
@@ -546,8 +559,10 @@ void AdminModule::handleSetConfig(const meshtastic_Config &c)
|
||||
sendWarning(warning);
|
||||
}
|
||||
// If we're setting router role for the first time, install its intervals
|
||||
if (existingRole != c.payload_variant.device.role)
|
||||
if (existingRole != c.payload_variant.device.role) {
|
||||
nodeDB->installRoleDefaults(c.payload_variant.device.role);
|
||||
changes |= SEGMENT_NODEDATABASE | SEGMENT_DEVICESTATE; // Some role defaults affect owner
|
||||
}
|
||||
if (config.device.node_info_broadcast_secs < min_node_info_broadcast_secs) {
|
||||
LOG_DEBUG("Tried to set node_info_broadcast_secs too low, setting to %d", min_node_info_broadcast_secs);
|
||||
config.device.node_info_broadcast_secs = min_node_info_broadcast_secs;
|
||||
@@ -646,6 +661,24 @@ void AdminModule::handleSetConfig(const meshtastic_Config &c)
|
||||
config.lora = c.payload_variant.lora;
|
||||
// If we're setting region for the first time, init the region
|
||||
if (isRegionUnset && config.lora.region > meshtastic_Config_LoRaConfig_RegionCode_UNSET) {
|
||||
if (!owner.is_licensed) {
|
||||
bool keygenSuccess = false;
|
||||
if (config.security.private_key.size == 32) {
|
||||
if (crypto->regeneratePublicKey(config.security.public_key.bytes, config.security.private_key.bytes)) {
|
||||
keygenSuccess = true;
|
||||
}
|
||||
} else {
|
||||
LOG_INFO("Generate new PKI keys");
|
||||
crypto->generateKeyPair(config.security.public_key.bytes, config.security.private_key.bytes);
|
||||
keygenSuccess = true;
|
||||
}
|
||||
if (keygenSuccess) {
|
||||
config.security.public_key.size = 32;
|
||||
config.security.private_key.size = 32;
|
||||
owner.public_key.size = 32;
|
||||
memcpy(owner.public_key.bytes, config.security.public_key.bytes, 32);
|
||||
}
|
||||
}
|
||||
config.lora.tx_enabled = true;
|
||||
initRegion();
|
||||
if (myRegion->dutyCycle < 100) {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user