// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved. // For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md #include "service-evtmgr/EVMessages.hpp" #include "service-evtmgr/KbdMessage.hpp" #include "service-evtmgr/Constants.hpp" #include "service-evtmgr/WorkerEventCommon.hpp" #include "battery/BatteryController.hpp" #include #include #include #include #include #include #include #include #include #include "FreeRTOS.h" #include "projdefs.h" #include "queue.h" #include "task.h" #include #include #include WorkerEventCommon::WorkerEventCommon(sys::Service *service) : sys::Worker(service, stackDepthBytes), service(service), keyInput{hal::key_input::AbstractKeyInput::Factory::create()} {} bool WorkerEventCommon::handleMessage(uint32_t queueID) { auto &queue = queues[queueID]; // service queue if (queueID == static_cast(WorkerEventQueues::queueService)) { sys::WorkerCommand wcmd; if (!queue->Dequeue(&wcmd, 0)) { return false; } wcmd.command = 1; // place some code here to handle messages from service } if (queueID == static_cast(WorkerEventQueues::queueKeyboardIRQ)) { uint8_t notification; if (!queue->Dequeue(¬ification, 0)) { return false; } for (const auto &key : keyInput->getKeyEvents(notification)) { processKeyEvent(key.event, key.code); } } if (queueID == static_cast(WorkerEventQueues::queueBatteryController)) { sevm::battery::BatteryController::Events event; if (!queue->Dequeue(&event, 0)) { return false; } batteryController->handleNotification(event); } if (queueID == static_cast(WorkerEventQueues::queueRTC)) { uint8_t notification; if (!queue->Dequeue(¬ification, 0)) { return false; } time_t timestamp; bsp::rtc::getCurrentTimestamp(×tamp); bsp::rtc::setMinuteAlarm(timestamp); /// Poll battery controller to recalculate state and possibly send update requests to /// appmgr/sysmgr batteryController->poll(); auto message = std::make_shared(MessageType::EVMMinuteUpdated); message->timestamp = timestamp; service->bus.sendUnicast(message, service::name::evt_manager); } return true; } void WorkerEventCommon::addProductQueues(std::list &queueList) {} void WorkerEventCommon::initProductHardware() {} void WorkerEventCommon::deinitProductHardware() {} bool WorkerEventCommon::initEventQueues() { constexpr auto elementSize = sizeof(std::uint8_t); std::list queuesList; queuesList.emplace_back(keyboardQueueName, elementSize, keyboardQueueSize); queuesList.emplace_back(batteryQueueName, elementSize, batteryQueueSize); queuesList.emplace_back(rtcQueueName, elementSize, rtcQueueSize); addProductQueues(queuesList); return Worker::init(queuesList); } bool WorkerEventCommon::initCommonHardwareComponents() { keyInput->init(queues[static_cast(WorkerEventQueues::queueKeyboardIRQ)]->GetQueueHandle()); auto queueBatteryHandle = queues[static_cast(WorkerEventQueues::queueBatteryController)]->GetQueueHandle(); batteryController = std::make_shared(service, queueBatteryHandle); bsp::rtc::init(queues[static_cast(WorkerEventQueues::queueRTC)]->GetQueueHandle()); time_t timestamp; bsp::rtc::getCurrentTimestamp(×tamp); bsp::rtc::setMinuteAlarm(timestamp); cpuSentinel = std::make_shared("WorkerEvent", service, [this](bsp::CpuFrequencyHz newFrequency) { updateResourcesAfterCpuFrequencyChange(newFrequency); }); auto sentinelRegistrationMsg = std::make_shared(cpuSentinel); service->bus.sendUnicast(std::move(sentinelRegistrationMsg), service::name::system_manager); initProductHardware(); return true; } void WorkerEventCommon::init(std::shared_ptr settings) { initEventQueues(); initCommonHardwareComponents(); } bool WorkerEventCommon::deinit(void) { Worker::deinit(); deinitProductHardware(); keyInput->deinit(); return true; } void WorkerEventCommon::processKeyEvent(bsp::KeyEvents event, bsp::KeyCodes code) { auto message = std::make_shared(); message->key.keyCode = code; switch (event) { case bsp::KeyEvents::Pressed: if (lastState == bsp::KeyEvents::Pressed) { return; } message->key.state = RawKey::State::Pressed; message->key.timePress = xTaskGetTickCount(); lastPressed = code; lastState = event; break; case bsp::KeyEvents::Released: if (lastState != bsp::KeyEvents::Pressed) { return; } if (lastPressed != code) { return; } lastState = bsp::KeyEvents::Released; { message->key.state = RawKey::State::Released; message->key.timeRelease = xTaskGetTickCount(); } break; case bsp::KeyEvents::Moved: message->key.state = RawKey::State::Moved; break; } service->bus.sendUnicast(message, service::name::evt_manager); } void WorkerEventCommon::updateResourcesAfterCpuFrequencyChange(bsp::CpuFrequencyHz newFrequency) { bsp::eink_frontlight::updateClockFrequency(newFrequency); bsp::vibrator::updateClockFrequency(newFrequency); }