Due to a change in the Espressif Arduino core, the TX timeout for the HW CDC (used in the ESP32-S3, for example) must not be set to 0, as otherwise, an integer underflow occurs. Removing the TX timeout is not necessary anymore anyways, because it is now detected when CDC is not active, and attempts to write will return immediately until the host read something again. Only when the transmit buffer becomes full initially, the default timeout of just 100ms takes effect once. For USB CDC (used with the ESP32-S2, for example), the timeout is not relevant either.
172 lines
5.0 KiB
C++
172 lines
5.0 KiB
C++
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
/*
|
|
* Copyright (C) 2022-2024 Thomas Basler and others
|
|
*/
|
|
#include "Configuration.h"
|
|
#include "Datastore.h"
|
|
#include "Display_Graphic.h"
|
|
#include "InverterSettings.h"
|
|
#include "Led_Single.h"
|
|
#include "MessageOutput.h"
|
|
#include "MqttHandleDtu.h"
|
|
#include "MqttHandleHass.h"
|
|
#include "MqttHandleInverter.h"
|
|
#include "MqttHandleInverterTotal.h"
|
|
#include "MqttSettings.h"
|
|
#include "NetworkSettings.h"
|
|
#include "NtpSettings.h"
|
|
#include "PinMapping.h"
|
|
#include "RestartHelper.h"
|
|
#include "Scheduler.h"
|
|
#include "SunPosition.h"
|
|
#include "Utils.h"
|
|
#include "WebApi.h"
|
|
#include "defaults.h"
|
|
#include <Arduino.h>
|
|
#include <LittleFS.h>
|
|
#include <TaskScheduler.h>
|
|
#include <esp_heap_caps.h>
|
|
#include <SpiManager.h>
|
|
|
|
#include <driver/uart.h>
|
|
|
|
void setup()
|
|
{
|
|
// Move all dynamic allocations >512byte to psram (if available)
|
|
heap_caps_malloc_extmem_enable(512);
|
|
|
|
// Initialize SpiManager
|
|
SpiManagerInst.register_bus(SPI2_HOST);
|
|
#if SOC_SPI_PERIPH_NUM > 2
|
|
SpiManagerInst.register_bus(SPI3_HOST);
|
|
#endif
|
|
|
|
// Initialize serial output
|
|
Serial.begin(SERIAL_BAUDRATE);
|
|
#if !ARDUINO_USB_CDC_ON_BOOT
|
|
// Only wait for serial interface to be set up when not using CDC
|
|
while (!Serial)
|
|
yield();
|
|
#endif
|
|
MessageOutput.init(scheduler);
|
|
MessageOutput.println();
|
|
MessageOutput.println("Starting OpenDTU");
|
|
|
|
// Initialize file system
|
|
MessageOutput.print("Initialize FS... ");
|
|
if (!LittleFS.begin(false)) { // Do not format if mount failed
|
|
MessageOutput.print("failed... trying to format...");
|
|
if (!LittleFS.begin(true)) {
|
|
MessageOutput.print("success");
|
|
} else {
|
|
MessageOutput.print("failed");
|
|
}
|
|
} else {
|
|
MessageOutput.println("done");
|
|
}
|
|
|
|
// Read configuration values
|
|
MessageOutput.print("Reading configuration... ");
|
|
if (!Configuration.read()) {
|
|
MessageOutput.print("initializing... ");
|
|
Configuration.init();
|
|
if (Configuration.write()) {
|
|
MessageOutput.print("written... ");
|
|
} else {
|
|
MessageOutput.print("failed... ");
|
|
}
|
|
}
|
|
if (Configuration.get().Cfg.Version != CONFIG_VERSION) {
|
|
MessageOutput.print("migrated... ");
|
|
Configuration.migrate();
|
|
}
|
|
auto& config = Configuration.get();
|
|
MessageOutput.println("done");
|
|
|
|
// Load PinMapping
|
|
MessageOutput.print("Reading PinMapping... ");
|
|
if (PinMapping.init(String(Configuration.get().Dev_PinMapping))) {
|
|
MessageOutput.print("found valid mapping ");
|
|
} else {
|
|
MessageOutput.print("using default config ");
|
|
}
|
|
const auto& pin = PinMapping.get();
|
|
MessageOutput.println("done");
|
|
|
|
// Initialize WiFi
|
|
MessageOutput.print("Initialize Network... ");
|
|
NetworkSettings.init(scheduler);
|
|
MessageOutput.println("done");
|
|
NetworkSettings.applyConfig();
|
|
|
|
// Initialize NTP
|
|
MessageOutput.print("Initialize NTP... ");
|
|
NtpSettings.init();
|
|
MessageOutput.println("done");
|
|
|
|
// Initialize SunPosition
|
|
MessageOutput.print("Initialize SunPosition... ");
|
|
SunPosition.init(scheduler);
|
|
MessageOutput.println("done");
|
|
|
|
// Initialize MqTT
|
|
MessageOutput.print("Initialize MqTT... ");
|
|
MqttSettings.init();
|
|
MqttHandleDtu.init(scheduler);
|
|
MqttHandleInverter.init(scheduler);
|
|
MqttHandleInverterTotal.init(scheduler);
|
|
MqttHandleHass.init(scheduler);
|
|
MessageOutput.println("done");
|
|
|
|
// Initialize WebApi
|
|
MessageOutput.print("Initialize WebApi... ");
|
|
WebApi.init(scheduler);
|
|
MessageOutput.println("done");
|
|
|
|
// Initialize Display
|
|
MessageOutput.print("Initialize Display... ");
|
|
Display.init(
|
|
scheduler,
|
|
static_cast<DisplayType_t>(pin.display_type),
|
|
pin.display_data,
|
|
pin.display_clk,
|
|
pin.display_cs,
|
|
pin.display_reset);
|
|
Display.setDiagramMode(static_cast<DiagramMode_t>(config.Display.Diagram.Mode));
|
|
Display.setOrientation(config.Display.Rotation);
|
|
Display.enablePowerSafe = config.Display.PowerSafe;
|
|
Display.enableScreensaver = config.Display.ScreenSaver;
|
|
Display.setContrast(config.Display.Contrast);
|
|
Display.setLanguage(config.Display.Language);
|
|
Display.setStartupDisplay();
|
|
MessageOutput.println("done");
|
|
|
|
// Initialize Single LEDs
|
|
MessageOutput.print("Initialize LEDs... ");
|
|
LedSingle.init(scheduler);
|
|
MessageOutput.println("done");
|
|
|
|
// Check for default DTU serial
|
|
MessageOutput.print("Check for default DTU serial... ");
|
|
if (config.Dtu.Serial == DTU_SERIAL) {
|
|
MessageOutput.print("generate serial based on ESP chip id: ");
|
|
const uint64_t dtuId = Utils::generateDtuSerial();
|
|
MessageOutput.printf("%0" PRIx32 "%08" PRIx32 "... ",
|
|
((uint32_t)((dtuId >> 32) & 0xFFFFFFFF)),
|
|
((uint32_t)(dtuId & 0xFFFFFFFF)));
|
|
config.Dtu.Serial = dtuId;
|
|
Configuration.write();
|
|
}
|
|
MessageOutput.println("done");
|
|
|
|
InverterSettings.init(scheduler);
|
|
|
|
Datastore.init(scheduler);
|
|
RestartHelper.init(scheduler);
|
|
}
|
|
|
|
void loop()
|
|
{
|
|
scheduler.execute();
|
|
}
|