~aleteoryx/muditaos

ed3dab784cc57fb1c47580da5843a73da921ee78 — Wojtek Rzepecki 4 years ago 857b1fb
[EGD-7388] Fix unresponsive keyboard

Fix teh keyboard driver to process all
incoming key events
M module-bsp/board/linux/keyboard/keyboard.cpp => module-bsp/board/linux/keyboard/keyboard.cpp +9 -7
@@ 25,7 25,7 @@

#include "bsp/keyboard/keyboard.hpp"

namespace bsp
namespace bsp::keyboard
{
    namespace
    {


@@ 96,13 96,15 @@ namespace bsp
        }
    } // namespace

    void keyboard_get_data(const uint8_t &notification, uint8_t &event, uint8_t &code)
    std::vector<KeyEvent> getKeyEvents(std::uint8_t notification)
    {
        event = kevent;
        code  = kcode;
        KeyEvent keyEvent;
        keyEvent.code  = static_cast<KeyCodes>(kcode);
        keyEvent.event = static_cast<KeyEvents>(kevent);
        return std::vector<KeyEvent>{keyEvent};
    }

    int32_t keyboard_Init(xQueueHandle qHandle)
    std::int32_t init(xQueueHandle qHandle)
    {

        if (xTaskCreate(linux_keyboard_worker, "keyboard", 512, qHandle, 0, &linux_keyboard_worker_handle) != pdPASS) {


@@ 111,11 113,11 @@ namespace bsp
        return 0;
    }

    int32_t keyboard_Deinit(void)
    std::int32_t deinit()
    {
        vTaskDelete(linux_keyboard_worker_handle);
        close(fd);
        return 0;
    }

} // namespace bsp
} // namespace bsp::keyboard

R module-bsp/board/rt1051/bsp/keyboard/TCA8418.h => module-bsp/board/rt1051/bsp/keyboard/TCA8418.hpp +0 -0
M module-bsp/board/rt1051/bsp/keyboard/keyboard.cpp => module-bsp/board/rt1051/bsp/keyboard/keyboard.cpp +149 -152
@@ 1,45 1,85 @@
// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "TCA8418.hpp"

#include <FreeRTOS.h>
#include <queue.h>
#include <task.h>
#include <timers.h>
#include <bsp/keyboard/keyboard.hpp>
#include <bsp/BoardDefinitions.hpp>
#include <board.h>
#include <fsl_common.h>

#include <stdio.h>
#include <stdint.h>
#include <assert.h>

#include "FreeRTOS.h"
#include "queue.h"
#include "task.h"
#include "timers.h"

#include "../board.h"
#include "fsl_common.h"
#include "TCA8418.h"
#include "bsp/common.hpp"
#include "bsp/keyboard/key_codes.hpp"

#include "bsp/BoardDefinitions.hpp"
#include "drivers/i2c/DriverI2C.hpp"
#include "drivers/gpio/DriverGPIO.hpp"

namespace bsp
namespace bsp::keyboard
{
    namespace
    {
        using namespace drivers;

        enum class NotificationSource
        {
            regularKey     = 0x01,
            rightFnPress   = 0x02,
            rightFnRelease = 0x04,
        };

        constexpr auto keyboardContactOscillationTimeoutMS = 20;

        std::shared_ptr<DriverI2C> i2c;
        I2CAddress i2cAddr = {
            .deviceAddress = TCA8418_I2C_ADDRESS, .subAddress = 0, .subAddressSize = TCA8418_I2C_ADDRESS_SIZE};
        std::shared_ptr<DriverGPIO> gpio;

        xQueueHandle qHandleIrq                 = nullptr;
        TimerHandle_t rightFunctionalCheckTimer = nullptr;
        std::uint8_t rigthFunctionalLastState   = 0;

        constexpr std::uint8_t keyCountRegisterMask  = 0x0F;
        constexpr std::uint8_t keyCodeRegisterMask   = 0x7F;
        constexpr std::uint8_t eventTypeRegisterMask = 0x80;

        void rightFunctionalCheckTimerCallback(TimerHandle_t timer)
        {
            std::uint8_t right_functional_current_state =
                GPIO_PinRead(BOARD_KEYBOARD_RF_BUTTON_PORT, BOARD_KEYBOARD_RF_BUTTON_PIN);
            BaseType_t xHigherPriorityTaskWoken = pdFALSE;
            xTimerStop(timer, 0);

            // If user pressed button and it is not just the contact oscillation
            if (right_functional_current_state == rigthFunctionalLastState) {
                if (right_functional_current_state == 0) {
                    if (qHandleIrq != nullptr) {
                        std::uint8_t val = static_cast<std::uint8_t>(NotificationSource::rightFnPress);
                        xQueueSendFromISR(qHandleIrq, &val, &xHigherPriorityTaskWoken);
                    }
                }
                else {
                    if (qHandleIrq != nullptr) {
                        std::uint8_t val = static_cast<std::uint8_t>(NotificationSource::rightFnRelease);
                        xQueueSendFromISR(qHandleIrq, &val, &xHigherPriorityTaskWoken);
                    }
                }
            }

    using namespace drivers;

    static std::shared_ptr<drivers::DriverI2C> i2c;
    static drivers::I2CAddress i2cAddr = {
        .deviceAddress = TCA8418_I2C_ADDRESS, .subAddress = 0, .subAddressSize = TCA8418_I2C_ADDRESS_SIZE};
    static std::shared_ptr<DriverGPIO> gpio;

#define KEYBOARD_CONTACT_OSCILLATION_TIMEOUT_MS 20

    static TimerHandle_t s_right_functional_check_timer   = NULL;
    static volatile uint8_t s_rigth_functional_last_state = 0;
            gpio->EnableInterrupt(1U << static_cast<uint32_t>(BoardDefinitions::KEYBOARD_RF_BUTTON));
        }

    static void s_bsp_keyboard_right_functional_check_timer_cb(TimerHandle_t timer);
        void clearAllIRQs()
        {
            std::uint8_t clearIRQs = 0xFF;
            i2cAddr.subAddress     = REG_INT_STAT;
            i2c->Write(i2cAddr, reinterpret_cast<std::uint8_t *>(&clearIRQs), 1);
        }

    static xQueueHandle qHandleIrq = NULL;
    } // anonymous namespace

    status_t keyboard_Init(xQueueHandle qHandle)
    std::int32_t init(xQueueHandle qHandle)
    {

        i2c = DriverI2C::Create(


@@ 65,37 105,37 @@ namespace bsp
                                          .defLogic = 0,
                                          .pin      = static_cast<uint32_t>(BoardDefinitions::KEYBOARD_IRQ_PIN)});

        uint32_t reg   = 0;
        std::uint32_t reg = 0;
        status_t error = 0;

        gpio->WritePin(static_cast<uint32_t>(BoardDefinitions::KEYBOARD_RESET_PIN), 0);
        gpio->WritePin(static_cast<std::uint32_t>(BoardDefinitions::KEYBOARD_RESET_PIN), 0);
        vTaskDelay(1);
        gpio->WritePin(static_cast<uint32_t>(BoardDefinitions::KEYBOARD_RESET_PIN), 1);
        gpio->WritePin(static_cast<std::uint32_t>(BoardDefinitions::KEYBOARD_RESET_PIN), 1);
        vTaskDelay(10);

        /* Assemble a mask for row and column registers */
        reg = ~(uint32_t(~0) << TCA8418_ROWS_COUNT);
        reg += (~(uint32_t(~0) << TCA8418_COL_COUNT)) << 8;
        reg = ~(std::uint32_t(~0) << TCA8418_ROWS_COUNT);
        reg += (~(std::uint32_t(~0) << TCA8418_COL_COUNT)) << 8;

        /* Set registers to keypad mode */
        i2cAddr.subAddress = REG_KP_GPIO1;
        i2c->Write(i2cAddr, (uint8_t *)&reg, 1);
        i2c->Write(i2cAddr, reinterpret_cast<std::uint8_t *>(&reg), 1);
        reg                = reg >> 8;
        i2cAddr.subAddress = REG_KP_GPIO2;
        i2c->Write(i2cAddr, (uint8_t *)&reg, 1);
        i2c->Write(i2cAddr, reinterpret_cast<std::uint8_t *>(&reg), 1);
        reg                = reg >> 16;
        i2cAddr.subAddress = REG_KP_GPIO3;
        i2c->Write(i2cAddr, (uint8_t *)&reg, 1);
        i2c->Write(i2cAddr, reinterpret_cast<std::uint8_t *>(&reg), 1);

        /* Enable column debouncing */
        i2cAddr.subAddress = REG_DEBOUNCE_DIS1;
        i2c->Write(i2cAddr, (uint8_t *)&reg, 1);
        i2c->Write(i2cAddr, reinterpret_cast<std::uint8_t *>(&reg), 1);
        reg                = reg >> 8;
        i2cAddr.subAddress = REG_DEBOUNCE_DIS2;
        i2c->Write(i2cAddr, (uint8_t *)&reg, 1);
        i2c->Write(i2cAddr, reinterpret_cast<std::uint8_t *>(&reg), 1);
        reg                = reg >> 16;
        i2cAddr.subAddress = REG_DEBOUNCE_DIS3;
        i2c->Write(i2cAddr, (uint8_t *)&reg, 1);
        i2c->Write(i2cAddr, reinterpret_cast<std::uint8_t *>(&reg), 1);

        if (error != kStatus_Success) {
            return error;


@@ 104,71 144,58 @@ namespace bsp
        reg = CFG_INT_CFG | CFG_OVR_FLOW_IEN | CFG_KE_IEN;
        // Enable interrupts
        i2cAddr.subAddress = REG_CFG;
        i2c->Write(i2cAddr, (uint8_t *)&reg, 1);

        // Clear keys FIFO, IRQs
        uint8_t val = 0;
        uint8_t i   = 0;
        i2c->Write(i2cAddr, reinterpret_cast<std::uint8_t *>(&reg), 1);

        // Get key pressed/released count
        std::uint8_t val   = 0;
        i2cAddr.subAddress = REG_KEY_LCK_EC;
        i2c->Read(i2cAddr, (uint8_t *)&val, 1);
        i2c->Read(i2cAddr, reinterpret_cast<std::uint8_t *>(&val), 1);

        uint8_t key_count = val & 0xF;
        for (i = 0; i < key_count; i++) {
        std::uint8_t keyCount = val & keyCountRegisterMask;
        for (std::uint8_t i = 0; i < keyCount; i++) {
            i2cAddr.subAddress = REG_KEY_EVENT_A;
            i2c->Read(i2cAddr, (uint8_t *)&val, 1);
            i2c->Read(i2cAddr, reinterpret_cast<std::uint8_t *>(&val), 1);
        }

        // Clear all interrupts
        uint8_t dummy = 0xff;

        i2cAddr.subAddress = REG_INT_STAT;
        i2c->Read(i2cAddr, (uint8_t *)&dummy, 1);

        // Clear all interrupts, even IRQs we didn't check (GPI, CAD, LCK)
        reg                = 0xff;
        // Dummy read before clear IRQs
        std::uint8_t dummy = 0xFF;
        i2cAddr.subAddress = REG_INT_STAT;
        i2c->Write(i2cAddr, (uint8_t *)&reg, 1);

        if (s_right_functional_check_timer == NULL) {
            s_right_functional_check_timer = xTimerCreate("RfKeyTim",
                                                          pdMS_TO_TICKS(KEYBOARD_CONTACT_OSCILLATION_TIMEOUT_MS),
                                                          false,
                                                          NULL,
                                                          s_bsp_keyboard_right_functional_check_timer_cb);
            if (s_right_functional_check_timer == NULL) {
        i2c->Read(i2cAddr, reinterpret_cast<std::uint8_t *>(&dummy), 1);
        clearAllIRQs();

        if (rightFunctionalCheckTimer == nullptr) {
            rightFunctionalCheckTimer = xTimerCreate("RfKeyTim",
                                                     pdMS_TO_TICKS(keyboardContactOscillationTimeoutMS),
                                                     false,
                                                     NULL,
                                                     rightFunctionalCheckTimerCallback);
            if (rightFunctionalCheckTimer == nullptr) {
                return kStatus_Fail;
            }
        }

        /* Enable GPIO pin interrupt */
        gpio->EnableInterrupt(1U << static_cast<uint32_t>(BoardDefinitions::KEYBOARD_RF_BUTTON));
        gpio->EnableInterrupt(1U << static_cast<uint32_t>(BoardDefinitions::KEYBOARD_IRQ_PIN));
        gpio->EnableInterrupt(1U << static_cast<std::uint32_t>(BoardDefinitions::KEYBOARD_RF_BUTTON));
        gpio->EnableInterrupt(1U << static_cast<std::uint32_t>(BoardDefinitions::KEYBOARD_IRQ_PIN));

        return kStatus_Success;
    }

    status_t keyboard_Deinit(void)
    std::int32_t deinit()
    {

        /* Disable GPIO pin interrupt */
        gpio->DisableInterrupt(1U << static_cast<uint32_t>(BoardDefinitions::KEYBOARD_RF_BUTTON));
        gpio->DisableInterrupt(1U << static_cast<uint32_t>(BoardDefinitions::KEYBOARD_IRQ_PIN));
        gpio->DisableInterrupt(1U << static_cast<std::uint32_t>(BoardDefinitions::KEYBOARD_RF_BUTTON));
        gpio->DisableInterrupt(1U << static_cast<std::uint32_t>(BoardDefinitions::KEYBOARD_IRQ_PIN));

        gpio->ClearPortInterrupts(1U << static_cast<uint32_t>(BoardDefinitions::KEYBOARD_RF_BUTTON));
        gpio->ClearPortInterrupts(1U << static_cast<uint32_t>(BoardDefinitions::KEYBOARD_IRQ_PIN));
        gpio->ClearPortInterrupts(1U << static_cast<std::uint32_t>(BoardDefinitions::KEYBOARD_RF_BUTTON));
        gpio->ClearPortInterrupts(1U << static_cast<std::uint32_t>(BoardDefinitions::KEYBOARD_IRQ_PIN));

        // Clear all interrupts, even IRQs we didn't check (GPI, CAD, LCK)
        uint8_t reg        = 0xff;
        i2cAddr.subAddress = REG_INT_STAT;
        i2c->Write(i2cAddr, (uint8_t *)&reg, 1);
        clearAllIRQs();

        xTimerDelete(s_right_functional_check_timer, 50);
        s_right_functional_check_timer = nullptr;
        xTimerDelete(rightFunctionalCheckTimer, 50);
        rightFunctionalCheckTimer = nullptr;

        // Clear IRQ queue handle
        qHandleIrq = NULL;
        qHandleIrq = nullptr;

        i2c.reset();
        gpio.reset();


@@ 176,111 203,81 @@ namespace bsp
        return kStatus_Success;
    }

    void keyboard_get_data(const uint8_t &notification, uint8_t &event, uint8_t &code)
    std::vector<KeyEvent> getKeyEvents(std::uint8_t notification)
    {
        if (notification & 0x01) {
        std::vector<KeyEvent> out;
        if (notification & static_cast<std::uint8_t>(NotificationSource::regularKey)) {
            uint8_t retval = 0;
            // Read how many key events has been registered
            i2cAddr.subAddress = REG_KEY_LCK_EC;
            i2c->Read(i2cAddr, (uint8_t *)&retval, 1);
            i2c->Read(i2cAddr, reinterpret_cast<std::uint8_t *>(&retval), 1);

            uint8_t events_count = retval & 0xF;
            uint8_t i            = 0;
            // Iterate over and parse each event
            for (i = 0; i < events_count; i++) {
                uint8_t key      = 0;
                uint8_t rel_pres = 0;
            std::uint8_t eventsCount = retval & keyCountRegisterMask;
            for (std::uint8_t i = 0; i < eventsCount; i++) {
                std::uint8_t key      = 0;
                std::uint8_t rel_pres = 0;

                i2cAddr.subAddress = REG_KEY_EVENT_A;
                i2c->Read(i2cAddr, (uint8_t *)&retval, 1);
                i2c->Read(i2cAddr, reinterpret_cast<std::uint8_t *>(&retval), 1);

                key = retval & 0x7F;
                // rel_pres: 0 - key release, 1 - key press
                rel_pres = (retval & 0x80) >> 7; // key release/pressed is stored on the last bit
                key = retval & keyCodeRegisterMask;
                // key release/pressed is stored on the last bit
                rel_pres = (retval & eventTypeRegisterMask) >> 7;

                if (rel_pres == 0) {}
                else {
                }
                code  = key;
                event = rel_pres;
                KeyEvent keyEvent;
                keyEvent.code  = static_cast<KeyCodes>(key);
                keyEvent.event = static_cast<KeyEvents>(rel_pres);
                out.push_back(keyEvent);
            }

            // Clear all interrupts
            uint8_t reg = 0xff;

            i2cAddr.subAddress = REG_INT_STAT;
            i2c->Write(i2cAddr, (uint8_t *)&reg, 1);
            clearAllIRQs();
        }

        if (notification & 0x02) {

            code  = static_cast<uint8_t>(bsp::KeyCodes::FnRight);
            event = static_cast<uint8_t>(KeyEvents::Pressed);
        if (notification & static_cast<std::uint8_t>(NotificationSource::rightFnPress)) {
            KeyEvent keyEvent;
            keyEvent.code  = KeyCodes::FnRight;
            keyEvent.event = KeyEvents::Pressed;
            out.push_back(keyEvent);
        }

        if (notification & 0x04) {

            code  = static_cast<uint8_t>(KeyCodes::FnRight);
            event = static_cast<uint8_t>(KeyEvents::Released);
        if (notification & static_cast<std::uint8_t>(NotificationSource::rightFnRelease)) {
            KeyEvent keyEvent;
            keyEvent.code  = KeyCodes::FnRight;
            keyEvent.event = KeyEvents::Released;
            out.push_back(keyEvent);
        }

        return out;
    }

    BaseType_t keyboard_right_functional_IRQHandler(void)
    BaseType_t rightFunctionalIRQHandler()
    {
        BaseType_t xHigherPriorityTaskWoken = pdFALSE;
        gpio->ClearPortInterrupts(1U << static_cast<uint32_t>(BoardDefinitions::KEYBOARD_RF_BUTTON));

        if (s_right_functional_check_timer != NULL) {
        if (rightFunctionalCheckTimer != NULL) {
            gpio->DisableInterrupt(1U << static_cast<uint32_t>(BoardDefinitions::KEYBOARD_RF_BUTTON));

            if (gpio->ReadPin(static_cast<uint32_t>(BoardDefinitions::KEYBOARD_RF_BUTTON)) == 0) {
                s_rigth_functional_last_state = 0;
                rigthFunctionalLastState = 0;
            }
            else {
                s_rigth_functional_last_state = 1;
                rigthFunctionalLastState = 1;
            }

            xTimerResetFromISR(s_right_functional_check_timer, &xHigherPriorityTaskWoken);
            xTimerResetFromISR(rightFunctionalCheckTimer, &xHigherPriorityTaskWoken);
        }

        return xHigherPriorityTaskWoken;
    }

    BaseType_t keyboard_IRQHandler(void)
    BaseType_t IRQHandler()
    {
        BaseType_t xHigherPriorityTaskWoken = pdFALSE;
        if (qHandleIrq != NULL) {
            uint8_t val = 0x01;
        if (qHandleIrq != nullptr) {
            std::uint8_t val = static_cast<std::uint8_t>(NotificationSource::regularKey);
            xQueueSendFromISR(qHandleIrq, &val, &xHigherPriorityTaskWoken);
        }
        return xHigherPriorityTaskWoken;
    }

    static void s_bsp_keyboard_right_functional_check_timer_cb(TimerHandle_t timer)
    {
        uint8_t right_functional_current_state =
            GPIO_PinRead(BOARD_KEYBOARD_RF_BUTTON_PORT, BOARD_KEYBOARD_RF_BUTTON_PIN);
        BaseType_t xHigherPriorityTaskWoken = pdFALSE;
        xTimerStop(timer, 0);

        // If user pressed button and it is not just the contact oscillation
        if (right_functional_current_state == s_rigth_functional_last_state) {
            if (right_functional_current_state == 0) {
                // RIGHT FUNCTIONAL PRESSED
                if (qHandleIrq != NULL) {
                    uint8_t val = 0x02;
                    xQueueSendFromISR(qHandleIrq, &val, &xHigherPriorityTaskWoken);
                }
            }
            else {
                // RIGHT FUNCTIONAL RELEASED
                if (qHandleIrq != NULL) {
                    uint8_t val = 0x04;
                    xQueueSendFromISR(qHandleIrq, &val, &xHigherPriorityTaskWoken);
                }
            }
        }

        gpio->EnableInterrupt(1U << static_cast<uint32_t>(BoardDefinitions::KEYBOARD_RF_BUTTON));
    }
} // namespace bsp
} // namespace bsp::keyboard

M module-bsp/board/rt1051/common/irq/irq_gpio.cpp => module-bsp/board/rt1051/common/irq/irq_gpio.cpp +2 -2
@@ 110,7 110,7 @@ namespace bsp
            uint32_t irq_mask                   = GPIO_GetPinsInterruptFlags(GPIO2);

            if (irq_mask & (1 << BOARD_KEYBOARD_RF_BUTTON_PIN)) {
                xHigherPriorityTaskWoken |= keyboard_right_functional_IRQHandler();
                xHigherPriorityTaskWoken |= bsp::keyboard::rightFunctionalIRQHandler();
            }

            if (irq_mask & (1 << BOARD_BATTERY_CHARGER_INOKB_PIN)) {


@@ 144,7 144,7 @@ namespace bsp
            uint32_t irq_mask                   = GPIO_GetPinsInterruptFlags(GPIO2);

            if (irq_mask & (1 << BOARD_KEYBOARD_IRQ_GPIO_PIN)) {
                xHigherPriorityTaskWoken |= keyboard_IRQHandler();
                xHigherPriorityTaskWoken |= bsp::keyboard::IRQHandler();
            }

            if (irq_mask & (1 << BOARD_USBC_NINT_PIN)) {

M module-bsp/bsp/keyboard/keyboard.hpp => module-bsp/bsp/keyboard/keyboard.hpp +21 -12
@@ 1,23 1,32 @@
#ifndef PUREPHONE_KEYBOARD_HPP
#define PUREPHONE_KEYBOARD_HPP
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include <stdint.h>
#pragma once

#include "bsp/common.hpp"
#include "key_codes.hpp"

namespace bsp {
#include <bsp/common.hpp>

	void keyboard_get_data(const uint8_t& notification, uint8_t& event, uint8_t& code);
#include <cstdint>
#include <vector>

	int32_t keyboard_Init(xQueueHandle qHandle);
namespace bsp::keyboard 
{
	struct KeyEvent
	{
		KeyCodes code;
		KeyEvents event;
	};

	int32_t keyboard_Deinit(void);
	std::vector<KeyEvent> getKeyEvents(std::uint8_t notification);

	BaseType_t keyboard_IRQHandler(void);
	std::int32_t init(xQueueHandle qHandle);

	BaseType_t keyboard_right_functional_IRQHandler(void);
}
	std::int32_t deinit();

	BaseType_t IRQHandler();

	BaseType_t rightFunctionalIRQHandler();
} // namespace bsp::keyboard


#endif //PUREPHONE_KEYBOARD_HPP

M module-services/service-evtmgr/WorkerEvent.cpp => module-services/service-evtmgr/WorkerEvent.cpp +5 -6
@@ 78,10 78,9 @@ bool WorkerEvent::handleMessage(uint32_t queueID)
        if (!queue->Dequeue(&notification, 0)) {
            return false;
        }
        uint8_t state, code;
        bsp::keyboard_get_data(notification, state, code);

        processKeyEvent(static_cast<bsp::KeyEvents>(state), static_cast<bsp::KeyCodes>(code));
        for (const auto &key : bsp::keyboard::getKeyEvents(notification)) {
            processKeyEvent(key.event, key.code);
        }
    }

    if (queueID == static_cast<uint32_t>(WorkerEventQueues::queueHeadsetIRQ)) {


@@ 203,7 202,7 @@ bool WorkerEvent::init(std::list<sys::WorkerQueueInfo> queuesList)
{
    Worker::init(queuesList);
    bsp::vibrator::init();
    bsp::keyboard_Init(queues[static_cast<int32_t>(WorkerEventQueues::queueKeyboardIRQ)]->GetQueueHandle());
    bsp::keyboard::init(queues[static_cast<int32_t>(WorkerEventQueues::queueKeyboardIRQ)]->GetQueueHandle());
    bsp::headset::Init(queues[static_cast<int32_t>(WorkerEventQueues::queueHeadsetIRQ)]->GetQueueHandle());
    auto queueBatteryHandle = queues[static_cast<int32_t>(WorkerEventQueues::queueBattery)]->GetQueueHandle();
    auto queueChargerDetect = queues[static_cast<int32_t>(WorkerEventQueues::queueChargerDetect)]->GetQueueHandle();


@@ 240,7 239,7 @@ void WorkerEvent::init(std::list<sys::WorkerQueueInfo> queuesList, std::shared_p
bool WorkerEvent::deinit(void)
{
    Worker::deinit();
    bsp::keyboard_Deinit();
    bsp::keyboard::deinit();
    bsp::headset::Deinit();
    bsp::battery_charger::deinit();
    bsp::torch::deinit();