250 lines
5.0 KiB
C++
250 lines
5.0 KiB
C++
#include "Platform.h"
|
|
#include <ArduinoLog.h>
|
|
#include "Static.h"
|
|
#include <time.h>
|
|
|
|
#ifdef PLATFORM_PHOTON
|
|
STARTUP(BootOptions::initPins());
|
|
#else
|
|
#include "inputs/Serial.h"
|
|
#include "platform/arduino/MQTTTelemetry.h"
|
|
void printNewline(Print* logOutput, int logLevel)
|
|
{
|
|
(void)logLevel; // unused
|
|
logOutput->print("\n");
|
|
}
|
|
#endif
|
|
|
|
int Platform::s_timezone = 0;
|
|
Platform::TaskRegistration* Platform::firstTask = NULL;
|
|
Platform::TaskRegistration* Platform::lastTask = NULL;
|
|
|
|
const char*
|
|
Platform::name()
|
|
{
|
|
return PlatformImpl<>::name();
|
|
#ifdef PLATFORM_PHOTON
|
|
return "Photon";
|
|
#endif
|
|
}
|
|
|
|
const char*
|
|
Platform::version()
|
|
{
|
|
return PlatformImpl<>::version();
|
|
#ifdef PLATFORM_PHOTON
|
|
return System.version().c_str();
|
|
#else
|
|
return "Unknown!";
|
|
#endif
|
|
}
|
|
|
|
int
|
|
Platform::freeRam()
|
|
{
|
|
return PlatformImpl<>::freeRam();
|
|
}
|
|
|
|
void
|
|
Platform::preSetup()
|
|
{
|
|
Serial.begin(115200);
|
|
#ifdef PLATFORM_PHOTON
|
|
System.enableFeature(FEATURE_RETAINED_MEMORY);
|
|
if (bootopts.isFlash) {
|
|
System.dfu();
|
|
}
|
|
if (bootopts.isSerial) {
|
|
bootopts.waitForRelease();
|
|
while(!Serial.isConnected()) {
|
|
Particle.process();
|
|
}
|
|
Log.notice("\xf0\x9f\x94\x8c Serial connected");
|
|
}
|
|
#else
|
|
Log.begin(LOG_LEVEL_TRACE, Static<MQTTTelemetry>::instance()->logPrinter());
|
|
Static<MQTTTelemetry>::instance()->setSequencer(Static<Sequencer>::instance());
|
|
Log.setSuffix(printNewline);
|
|
#endif
|
|
|
|
#ifdef BOARD_ESP8266
|
|
if (!ESP.checkFlashCRC()) {
|
|
Log.fatal("Firmware failed CRC check!!!");
|
|
}
|
|
#endif
|
|
PlatformImpl<>::startWatchdog();
|
|
}
|
|
|
|
void
|
|
Platform::setup()
|
|
{
|
|
#ifdef PLATFORM_PHOTON
|
|
Time.zone(Static<Platform>::instance()->getTimezone());
|
|
#endif
|
|
PlatformImpl<>::startNTP();
|
|
}
|
|
|
|
void
|
|
Platform::bootSplash()
|
|
{
|
|
PlatformImpl<>::bootSplash();
|
|
|
|
#ifdef PLATFORM_PHOTON
|
|
Log.notice(u8" Boot pin configuration:");
|
|
Log.notice(u8" 2: Setup - %d", bootopts.isSetup);
|
|
Log.notice(u8" 3: Serial - %d", bootopts.isSerial);
|
|
Log.notice(u8" 4: Flash - %d", bootopts.isFlash);
|
|
#endif
|
|
|
|
if (bootopts.crashCount > 0) {
|
|
Log.warning(u8"Previous crash detected!!!! We're on attempt %d", bootopts.crashCount);
|
|
char lastTaskBuf[16];
|
|
strncpy(lastTaskBuf, MainLoop::lastTaskName(), sizeof(lastTaskBuf));
|
|
lastTaskBuf[15] = 0;
|
|
Log.error(u8"Crash occurred in task %s", lastTaskBuf);
|
|
|
|
PlatformImpl<>::printCrashInfo();
|
|
|
|
strncpy(lastTaskBuf, Renderer::lastFigmentName(), sizeof(lastTaskBuf));
|
|
lastTaskBuf[15] = 0;
|
|
Log.error(u8"Last Figment was %s", lastTaskBuf);
|
|
}
|
|
|
|
Log.trace("Registered tasks:");
|
|
auto it = beginTasks();
|
|
while (it != endTasks()) {
|
|
if (!(*it)->isFigment()) {
|
|
Log.trace(" %s", (*it)->name);
|
|
}
|
|
++it;
|
|
}
|
|
Log.trace("Registered Figments:");
|
|
it = beginTasks();
|
|
while (it != endTasks()) {
|
|
if ((*it)->isFigment()) {
|
|
Log.trace(" %s", (*it)->name);
|
|
}
|
|
++it;
|
|
}
|
|
}
|
|
|
|
void
|
|
Platform::loop()
|
|
{
|
|
PlatformImpl<>::loop();
|
|
}
|
|
|
|
bool
|
|
Platform::getLocalTime(struct tm* timedata)
|
|
{
|
|
#ifdef PLATFORM_PHOTON
|
|
if (Time.isValid()) {
|
|
timedata->tm_hour = Time.hour();
|
|
timedata->tm_min = Time.minute();
|
|
return true;
|
|
}
|
|
return false;
|
|
#endif
|
|
return PlatformImpl<>::getLocalTime(timedata, s_timezone);
|
|
}
|
|
|
|
const char*
|
|
Platform::deviceID()
|
|
{
|
|
return PlatformImpl<>::deviceID();
|
|
}
|
|
|
|
void
|
|
Platform::addLEDs(CRGB* leds, uint16_t ledCount) {
|
|
FastLED.addLeds<NEOPIXEL, RENDERBUG_LED_PIN>(leds, ledCount);
|
|
}
|
|
|
|
const String
|
|
Platform::model()
|
|
{
|
|
static String modelName = String("Renderbug " ) + Platform::name();
|
|
return modelName;
|
|
}
|
|
|
|
void
|
|
Platform::restart() {
|
|
PlatformImpl<>::restart();
|
|
}
|
|
|
|
|
|
void
|
|
Platform::doReboot(Args& args, Print& out)
|
|
{
|
|
out.println("Rebooting");
|
|
restart();
|
|
}
|
|
|
|
void
|
|
Platform::doSafeMode(Args& args, Print& out)
|
|
{
|
|
out.println("Rebooting into safe mode");
|
|
PlatformImpl<>::forceSafeMode();
|
|
restart();
|
|
}
|
|
|
|
String s;
|
|
|
|
void
|
|
Platform::doTaskStart(Args& args, Print& out)
|
|
{
|
|
s = args[1];
|
|
MainLoop::instance()->dispatch(InputEvent{InputEvent::StartThing, s.c_str()});
|
|
}
|
|
|
|
void
|
|
Platform::doTaskStop(Args& args, Print& out)
|
|
{
|
|
s = args[1];
|
|
MainLoop::instance()->dispatch(InputEvent{InputEvent::StopThing, s.c_str()});
|
|
}
|
|
|
|
void
|
|
Platform::doTaskList(Args& args, Print& out)
|
|
{
|
|
auto sched = MainLoop::instance()->scheduler;
|
|
auto printer = Static<SerialInput>::instance()->printer();
|
|
out.println("Tasks:");
|
|
for(auto task : sched.tasks) {
|
|
bool isFigment = task->isFigment();
|
|
if (task->state == Task::Running) {
|
|
out.print("+");
|
|
} else {
|
|
out.print("-");
|
|
}
|
|
if (isFigment) {
|
|
out.print("F ");
|
|
} else {
|
|
out.print("T ");
|
|
}
|
|
out.println(task->name);
|
|
}
|
|
}
|
|
|
|
|
|
const std::vector<Command>&
|
|
Platform::commands() const
|
|
{
|
|
static const std::vector<Command> _commands = {
|
|
{"tasks", &Platform::doTaskList},
|
|
{"safe-mode", &Platform::doSafeMode},
|
|
{"reboot", &Platform::doReboot},
|
|
{"stop", &Platform::doTaskStop},
|
|
{"start", &Platform::doTaskStart}
|
|
};
|
|
return _commands;
|
|
}
|
|
|
|
BootOptions
|
|
Platform::bootopts;
|
|
|
|
char
|
|
Platform::s_deviceID[15];
|
|
|
|
STATIC_ALLOC(Platform);
|
|
STATIC_TASK(Platform);
|