#include "SystemStartup.h" #include #include #ifndef OLED_SDA #define OLED_SDA 17 #endif #ifndef OLED_SCL #define OLED_SCL 18 #endif #ifndef OLED_ADDR #define OLED_ADDR 0x3C #endif static const bool kEnableOled = true; static U8G2_SH1106_128X64_NONAME_F_HW_I2C g_oled(U8G2_R0, /* reset=*/U8X8_PIN_NONE); static SystemStartup* g_activeSystemStartup = nullptr; static void forceSpiDeselectedEarly() { pinMode(tbeam_supreme::sdCs(), OUTPUT); digitalWrite(tbeam_supreme::sdCs(), HIGH); pinMode(tbeam_supreme::imuCs(), OUTPUT); digitalWrite(tbeam_supreme::imuCs(), HIGH); } SystemStartup::SystemStartup(Print& serial) : serial_(serial), sd_(serial) {} bool SystemStartup::begin(const SystemStartupConfig& cfg, SystemEventCallback callback) { cfg_ = cfg; callback_ = callback; g_activeSystemStartup = this; // Match Exercise 05 behavior: deselect SPI devices immediately at startup. forceSpiDeselectedEarly(); if (kEnableOled) { Wire.begin(OLED_SDA, OLED_SCL); g_oled.setI2CAddress(OLED_ADDR << 1); g_oled.begin(); } emit(SystemEvent::BOOTING, "System startup booting"); oledShow3("System Startup", "Booting..."); serial_.printf("Sleeping for %lu ms to allow Serial Monitor connection...\r\n", (unsigned long)cfg_.serialDelayMs); delay(cfg_.serialDelayMs); return sd_.begin(cfg_.sd, &SystemStartup::onSdEventThunk); } void SystemStartup::update() { sd_.update(); } void SystemStartup::onSdEventThunk(SdEvent event, const char* message) { if (g_activeSystemStartup != nullptr) { g_activeSystemStartup->onSdEvent(event, message); } } void SystemStartup::onSdEvent(SdEvent event, const char* message) { if (event == SdEvent::NO_CARD) { oledShow3("SD missing or", "invalid FAT16/32", "Insert/format card"); emit(SystemEvent::SD_MISSING, message); } else if (event == SdEvent::CARD_MOUNTED) { oledShow3("SD card ready", "Mounted OK"); emit(SystemEvent::SD_READY, message); } else if (event == SdEvent::CARD_REMOVED) { oledShow3("SD card removed", "Please re-insert"); emit(SystemEvent::SD_REMOVED, message); } } void SystemStartup::emit(SystemEvent event, const char* message) { serial_.printf("[SYSTEM] %s\r\n", message); if (callback_ != nullptr) { callback_(event, message); } } void SystemStartup::oledShow3(const char* l1, const char* l2, const char* l3) { if (!kEnableOled) { return; } g_oled.clearBuffer(); g_oled.setFont(u8g2_font_6x10_tf); if (l1) g_oled.drawUTF8(0, 16, l1); if (l2) g_oled.drawUTF8(0, 32, l2); if (l3) g_oled.drawUTF8(0, 48, l3); g_oled.sendBuffer(); }