#include "./Config.h" #include "./Static.h" #include #include constexpr uint16_t HardwareConfig::MAX_LED_NUM; HardwareConfig HardwareConfig::load() { HardwareConfig ret; EEPROM.begin(sizeof(ret)); EEPROM.get(0, ret); EEPROM.end(); Log.notice("Loaded config version %d, CRC %d", ret.version, ret.checksum); return ret; } void HardwareConfig::save() { HardwareConfig dataCopy{*this}; dataCopy.checksum = getCRC(); EEPROM.begin(sizeof(dataCopy)); EEPROM.put(0, dataCopy); EEPROM.commit(); EEPROM.end(); } LinearCoordinateMapping HardwareConfig::toCoordMap() const { auto pixelCount = min(HardwareConfig::MAX_LED_NUM, std::max((uint16_t)1, data.pixelCount)); auto startPixel = min(pixelCount, std::max((uint16_t)1, data.startPixel)); return LinearCoordinateMapping{pixelCount, startPixel}; } bool HardwareConfig::isValid() const { return version == 2 && checksum == getCRC() && data.pixelCount <= MAX_LED_NUM; } uint8_t HardwareConfig::getCRC() const { const unsigned char* message = reinterpret_cast(&data); constexpr uint8_t length = sizeof(data); unsigned char i, j, crc = 0; for(i = 0; i < length; i++) { crc ^= message[i]; for(j = 0; j < 8; j++) { if (crc & 1) { crc ^= CRC7_POLY; } crc >>= 1; } } return crc; } void ConfigService::onStart() { Log.notice("Starting configuration service..."); m_config = HardwareConfig::load(); if (m_config.isValid()) { Log.notice("Configuration found!"); } else { Log.notice("No configuration found. Writing defaults..."); m_config = HardwareConfig{}; m_config.save(); } m_coordMap = m_config.toCoordMap(); Log.notice("Configured to use %d pixels, starting at %d", m_config.data.pixelCount, m_config.data.startPixel); /*Log.notice("Loading task states..."); for(int i = 0; i < 32; i++) { auto svc = m_config.data.serviceStates[i]; if (strnlen(svc.name, 16) > 0) { Log.notice("* %s: %s", svc.name, svc.isDisabled? "DISABLED" : "ENABLED"); } }*/ } void ConfigService::loop() { } void ConfigService::handleEvent(const InputEvent &evt) { switch(evt.intent) { case InputEvent::SetDisplayLength: //Log.info("Updating pixel count from %d to %d", m_coordMap.pixelCount, evt.asInt()); m_config.data.pixelCount = evt.asInt(); m_coordMap = m_config.toCoordMap(); //Log.info("Count is now %d", m_coordMap.pixelCount); break; case InputEvent::SetDisplayOffset: //Log.info("Updating pixel offset from %d to %d", m_coordMap.startPixel, evt.asInt()); m_config.data.startPixel = evt.asInt(); m_coordMap = m_config.toCoordMap(); //Log.info("Offset is now %d", m_coordMap.startPixel); break; case InputEvent::SaveConfigurationRequest: //Log.info("Saving configuration"); m_config.save(); break; default: break; } } STATIC_ALLOC(ConfigService);