~aleteoryx/muditaos

6d1ec66cb4ffcc0f16c0791b5abdb8ceb0e6958f — Lucjan Bryndza 4 years ago 1156320
[BH-510] Knob driver

Add knob driver for the rotary encoder.

Signed-off-by: Lucjan Bryndza <lucjan.bryndza@mudita.com>
M module-bsp/board/linux/CMakeLists.txt => module-bsp/board/linux/CMakeLists.txt +1 -0
@@ 25,6 25,7 @@ target_sources(module-bsp
                hal/battery_charger/BatteryCharger.cpp
                hal/key_input/KeyInput.cpp
                bell_temp_sensor/bell_temp_sensor.cpp
                rotary_encoder/rotary_encoder.cpp

                ${CMAKE_CURRENT_BINARY_DIR}/eink-config.h
)

A module-bsp/board/linux/rotary_encoder/rotary_encoder.cpp => module-bsp/board/linux/rotary_encoder/rotary_encoder.cpp +20 -0
@@ 0,0 1,20 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include <bsp/rotary_encoder/rotary_encoder.hpp>

namespace bsp::rotary_encoder
{
    int init(xQueueHandle qHandle)
    {
        return 1;
    }
    void deinit()
    {}

    std::optional<type> WorkerEventHandler()
    {
        return std::nullopt;
    }

} // namespace bsp::rotary_encoder

M module-bsp/board/rt1051/CMakeLists.txt => module-bsp/board/rt1051/CMakeLists.txt +1 -0
@@ 63,6 63,7 @@ target_sources(module-bsp
		common/fsl_drivers/fsl_src.c
		common/fsl_drivers/fsl_usdhc.c
		common/fsl_drivers/fsl_wdog.c
		common/fsl_drivers/fsl_qtmr.c
		common/startup_mimxrt1052.cpp
		common/system_MIMXRT1051.c
		drivers/RT1051DriverDMA.cpp

M module-bsp/board/rt1051/bellpx/CMakeLists.txt => module-bsp/board/rt1051/bellpx/CMakeLists.txt +1 -0
@@ 14,6 14,7 @@ target_sources(
        hal/battery_charger/BatteryCharger.cpp
	    hal/key_input/KeyInput.cpp
	    bsp/eink/eink_pin_config.cpp
        bsp/rotary_encoder/rotary_encoder.cpp
        bsp/bell_temp_sensor/bell_temp_sensor.cpp
        pin_mux.c
        clock_config.cpp

A module-bsp/board/rt1051/bellpx/bsp/rotary_encoder/rotary_encoder.cpp => module-bsp/board/rt1051/bellpx/bsp/rotary_encoder/rotary_encoder.cpp +92 -0
@@ 0,0 1,92 @@
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include <bsp/rotary_encoder/rotary_encoder.hpp>
#include <board/BoardDefinitions.hpp>
#include <timers.h>
#include <fsl_common.h>
#include <fsl_qtmr.h>

/* Hardware PINS
 * TMR3_CH0-----GPIO_B0_06-----
 * TMR3_CH1-----GPIO_B0_07-----
 */
namespace bsp::rotary_encoder
{
    namespace
    {
        constexpr auto POLL_INTERVAL_MS       = 100U;
        constexpr uint16_t MAX_PER_100MS      = 100U;
        constexpr auto PRIMARY_SOURCE         = kQTMR_ClockCounter0InputPin;
        constexpr auto BOARD_QTMR_ENC_CHANNEL = kQTMR_Channel_0;
        constexpr auto SECONDARY_SOURCE       = kQTMR_Counter1InputPin;
        auto BOARD_QTMR_ID                    = TMR3;
        xQueueHandle gHandleIrq;
        TimerHandle_t gTimerHandle;
        uint32_t encCounter;
    } // namespace

    int init(xQueueHandle qHandle)
    {
        gHandleIrq = qHandle;
        qtmr_config_t timerCfg;
        QTMR_GetDefaultConfig(&timerCfg);
        timerCfg.primarySource   = PRIMARY_SOURCE;
        timerCfg.secondarySource = SECONDARY_SOURCE;
        QTMR_Init(BOARD_QTMR_ID, BOARD_QTMR_ENC_CHANNEL, &timerCfg);
        QTMR_StartTimer(BOARD_QTMR_ID, BOARD_QTMR_ENC_CHANNEL, kQTMR_QuadCountMode);
        if (!gTimerHandle) {
            gTimerHandle =
                xTimerCreate("RotEncTimer", pdMS_TO_TICKS(POLL_INTERVAL_MS), true, nullptr, [](TimerHandle_t) {
                    if (gHandleIrq) {
                        uint8_t val{0x01};
                        xQueueSend(gHandleIrq, &val, 0);
                    }
                });
        }
        LOG_DEBUG("Init rotary encoder driver");
        const auto ret = (gTimerHandle && gHandleIrq) ? (kStatus_Success) : (kStatus_Fail);
        LOG_DEBUG("Init rotary encoder driver status %i", ret);
        return ret;
    }

    void deinit()
    {
        xTimerDelete(gTimerHandle, 50);
        gTimerHandle = nullptr;
        gHandleIrq   = nullptr;
        QTMR_Deinit(BOARD_QTMR_ID, BOARD_QTMR_ENC_CHANNEL);
    }

    std::optional<type> WorkerEventHandler()
    {
        uint16_t tmp = QTMR_GetCurrentTimerCount(BOARD_QTMR_ID, BOARD_QTMR_ENC_CHANNEL);
        std::optional<type> ret;

        if (tmp != encCounter && encCounter >= 0xFFFFU - MAX_PER_100MS && encCounter <= 0xFFFFU) {
            if (tmp <= MAX_PER_100MS || tmp > encCounter) {
                ret = type::forward;
            }
            else {
                ret = type::backward;
            }
        }
        else if (tmp != encCounter && encCounter <= MAX_PER_100MS) {
            if ((tmp >= 0xFFFFU - MAX_PER_100MS) || tmp < encCounter) {
                ret = type::backward;
            }
            else {
                ret = type::forward;
            }
        }
        else if (tmp < encCounter) {
            ret = type::backward;
        }
        else if (tmp > encCounter) {
            ret = type::forward;
        }
        encCounter = tmp;
        return ret;
    }

} // namespace bsp::rotary_encoder

A module-bsp/board/rt1051/common/fsl_drivers/fsl_qtmr.c => module-bsp/board/rt1051/common/fsl_drivers/fsl_qtmr.c +612 -0
@@ 0,0 1,612 @@
/*
 * Copyright 2017-2020 NXP
 * All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include "fsl_qtmr.h"

/* Component ID definition, used by tools. */
#ifndef FSL_COMPONENT_ID
#define FSL_COMPONENT_ID "platform.drivers.qtmr"
#endif

/*******************************************************************************
 * Prototypes
 ******************************************************************************/
/*!
 * @brief Gets the instance from the base address to be used to gate or ungate the module clock
 *
 * @param base Quad Timer peripheral base address
 *
 * @return The Quad Timer instance
 */
static uint32_t QTMR_GetInstance(TMR_Type *base);

/*******************************************************************************
 * Variables
 ******************************************************************************/
/*! @brief Pointers to Quad Timer bases for each instance. */
static TMR_Type *const s_qtmrBases[] = TMR_BASE_PTRS;

#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
/*! @brief Pointers to Quad Timer clocks for each instance. */
static const clock_ip_name_t s_qtmrClocks[] = TMR_CLOCKS;
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */

/*******************************************************************************
 * Code
 ******************************************************************************/
static uint32_t QTMR_GetInstance(TMR_Type *base)
{
    uint32_t instance;

    /* Find the instance index from base address mappings. */
    for (instance = 0; instance < ARRAY_SIZE(s_qtmrBases); instance++)
    {
        if (s_qtmrBases[instance] == base)
        {
            break;
        }
    }

    assert(instance < ARRAY_SIZE(s_qtmrBases));

    return instance;
}

/*!
 * brief Ungates the Quad Timer clock and configures the peripheral for basic operation.
 *
 * note This API should be called at the beginning of the application using the Quad Timer driver.
 *
 * param base     Quad Timer peripheral base address
 * param channel  Quad Timer channel number
 * param config   Pointer to user's Quad Timer config structure
 */
void QTMR_Init(TMR_Type *base, qtmr_channel_selection_t channel, const qtmr_config_t *config)
{
    assert(NULL != config);

#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
    /* Enable the module clock */
    CLOCK_EnableClock(s_qtmrClocks[QTMR_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */

    /* Setup the counter sources */
    base->CHANNEL[channel].CTRL = (TMR_CTRL_PCS(config->primarySource) | TMR_CTRL_SCS(config->secondarySource));

    /* Setup the master mode operation */
    base->CHANNEL[channel].SCTRL =
        (TMR_SCTRL_EEOF(config->enableExternalForce) | TMR_SCTRL_MSTR(config->enableMasterMode));

    /* Setup debug mode */
    base->CHANNEL[channel].CSCTRL = TMR_CSCTRL_DBG_EN(config->debugMode);

    base->CHANNEL[channel].FILT &= (uint16_t)(~(TMR_FILT_FILT_CNT_MASK | TMR_FILT_FILT_PER_MASK));
    /* Setup input filter */
    base->CHANNEL[channel].FILT =
        (TMR_FILT_FILT_CNT(config->faultFilterCount) | TMR_FILT_FILT_PER(config->faultFilterPeriod));
}

/*!
 * brief Stops the counter and gates the Quad Timer clock
 *
 * param base     Quad Timer peripheral base address
 * param channel  Quad Timer channel number
 */
void QTMR_Deinit(TMR_Type *base, qtmr_channel_selection_t channel)
{
    /* Stop the counter */
    base->CHANNEL[channel].CTRL &= (uint16_t)(~TMR_CTRL_CM_MASK);

#if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
    /* Disable the module clock */
    CLOCK_DisableClock(s_qtmrClocks[QTMR_GetInstance(base)]);
#endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
}

/*!
 * brief  Fill in the Quad Timer config struct with the default settings
 *
 * The default values are:
 * code
 *    config->debugMode = kQTMR_RunNormalInDebug;
 *    config->enableExternalForce = false;
 *    config->enableMasterMode = false;
 *    config->faultFilterCount = 0;
 *    config->faultFilterPeriod = 0;
 *    config->primarySource = kQTMR_ClockDivide_2;
 *    config->secondarySource = kQTMR_Counter0InputPin;
 * endcode
 * param config Pointer to user's Quad Timer config structure.
 */
void QTMR_GetDefaultConfig(qtmr_config_t *config)
{
    assert(NULL != config);

    /* Initializes the configure structure to zero. */
    (void)memset(config, 0, sizeof(*config));

    /* Halt counter during debug mode */
    config->debugMode = kQTMR_RunNormalInDebug;
    /* Another counter cannot force state of OFLAG signal */
    config->enableExternalForce = false;
    /* Compare function's output from this counter is not broadcast to other counters */
    config->enableMasterMode = false;
    /* Fault filter count is set to 0 */
    config->faultFilterCount = 0;
    /* Fault filter period is set to 0 which disables the fault filter */
    config->faultFilterPeriod = 0;
    /* Primary count source is IP bus clock divide by 2 */
    config->primarySource = kQTMR_ClockDivide_2;
    /* Secondary count source is counter 0 input pin */
    config->secondarySource = kQTMR_Counter0InputPin;
}

/*!
 * brief Sets up Quad timer module for PWM signal output.
 *
 * The function initializes the timer module according to the parameters passed in by the user. The
 * function also sets up the value compare registers to match the PWM signal requirements.
 *
 * param base             Quad Timer peripheral base address
 * param channel          Quad Timer channel number
 * param pwmFreqHz        PWM signal frequency in Hz
 * param dutyCyclePercent PWM pulse width, value should be between 0 to 100
 *                         0=inactive signal(0% duty cycle)...
 *                         100=active signal (100% duty cycle)
 * param outputPolarity   true: invert polarity of the output signal, false: no inversion
 * param srcClock_Hz      Main counter clock in Hz.
 *
 * return Returns an error if there was error setting up the signal.
 */
status_t QTMR_SetupPwm(TMR_Type *base,
                       qtmr_channel_selection_t channel,
                       uint32_t pwmFreqHz,
                       uint8_t dutyCyclePercent,
                       bool outputPolarity,
                       uint32_t srcClock_Hz)
{
    uint32_t periodCount, highCount, lowCount;
    uint16_t reg;
    status_t status;

    if (dutyCyclePercent <= 100U)
    {
        /* Set OFLAG pin for output mode and force out a low on the pin */
        base->CHANNEL[channel].SCTRL |= (TMR_SCTRL_FORCE_MASK | TMR_SCTRL_OEN_MASK);

        /* Counter values to generate a PWM signal */
        periodCount = srcClock_Hz / pwmFreqHz;
        highCount   = periodCount * dutyCyclePercent / 100U;
        lowCount    = periodCount - highCount;

        if (highCount > 0U)
        {
            highCount -= 1U;
        }
        if (lowCount > 0U)
        {
            lowCount -= 1U;
        }

        /* This should not be a 16-bit overflow value. If it is, change to a larger divider for clock source. */
        assert(highCount <= 0xFFFFU);
        assert(lowCount <= 0xFFFFU);

        /* Setup the compare registers for PWM output */
        base->CHANNEL[channel].COMP1 = (uint16_t)lowCount;
        base->CHANNEL[channel].COMP2 = (uint16_t)highCount;

        /* Setup the pre-load registers for PWM output */
        base->CHANNEL[channel].CMPLD1 = (uint16_t)lowCount;
        base->CHANNEL[channel].CMPLD2 = (uint16_t)highCount;

        reg = base->CHANNEL[channel].CSCTRL;
        /* Setup the compare load control for COMP1 and COMP2.
         * Load COMP1 when CSCTRL[TCF2] is asserted, load COMP2 when CSCTRL[TCF1] is asserted
         */
        reg &= (uint16_t)(~(TMR_CSCTRL_CL1_MASK | TMR_CSCTRL_CL2_MASK));
        reg |= (TMR_CSCTRL_CL1(kQTMR_LoadOnComp2) | TMR_CSCTRL_CL2(kQTMR_LoadOnComp1));
        base->CHANNEL[channel].CSCTRL = reg;

        if (outputPolarity)
        {
            /* Invert the polarity */
            base->CHANNEL[channel].SCTRL |= TMR_SCTRL_OPS_MASK;
        }
        else
        {
            /* True polarity, no inversion */
            base->CHANNEL[channel].SCTRL &= ~(uint16_t)TMR_SCTRL_OPS_MASK;
        }

        reg = base->CHANNEL[channel].CTRL;
        reg &= ~(uint16_t)TMR_CTRL_OUTMODE_MASK;
        /* Count until compare value is  reached and re-initialize the counter, toggle OFLAG output
         * using alternating compare register
         */
        reg |= (TMR_CTRL_LENGTH_MASK | TMR_CTRL_OUTMODE(kQTMR_ToggleOnAltCompareReg));
        base->CHANNEL[channel].CTRL = reg;

        status = kStatus_Success;
    }
    else
    {
        /* Invalid dutycycle */
        status = kStatus_Fail;
    }

    return status;
}

/*!
 * brief Allows the user to count the source clock cycles until a capture event arrives.
 *
 * The count is stored in the capture register.
 *
 * param base            Quad Timer peripheral base address
 * param channel         Quad Timer channel number
 * param capturePin      Pin through which we receive the input signal to trigger the capture
 * param inputPolarity   true: invert polarity of the input signal, false: no inversion
 * param reloadOnCapture true: reload the counter when an input capture occurs, false: no reload
 * param captureMode     Specifies which edge of the input signal  triggers a capture
 */
void QTMR_SetupInputCapture(TMR_Type *base,
                            qtmr_channel_selection_t channel,
                            qtmr_input_source_t capturePin,
                            bool inputPolarity,
                            bool reloadOnCapture,
                            qtmr_input_capture_edge_t captureMode)
{
    uint16_t reg;

    /* Clear the prior value for the input source for capture */
    reg = base->CHANNEL[channel].CTRL & (uint16_t)(~TMR_CTRL_SCS_MASK);

    /* Set the new input source */
    reg |= TMR_CTRL_SCS(capturePin);
    base->CHANNEL[channel].CTRL = reg;

    /* Clear the prior values for input polarity, capture mode. Set the external pin as input */
    reg = base->CHANNEL[channel].SCTRL &
          (uint16_t)(~(TMR_SCTRL_IPS_MASK | TMR_SCTRL_CAPTURE_MODE_MASK | TMR_SCTRL_OEN_MASK));
    /* Set the new values */
    reg |= (TMR_SCTRL_IPS(inputPolarity) | TMR_SCTRL_CAPTURE_MODE(captureMode));
    base->CHANNEL[channel].SCTRL = reg;

    /* Setup if counter should reload when a capture occurs */
    if (reloadOnCapture)
    {
        base->CHANNEL[channel].CSCTRL |= TMR_CSCTRL_ROC_MASK;
    }
    else
    {
        base->CHANNEL[channel].CSCTRL &= (uint16_t)(~TMR_CSCTRL_ROC_MASK);
    }
}

/*!
 * brief Enables the selected Quad Timer interrupts
 *
 * param base      Quad Timer peripheral base address
 * param channel   Quad Timer channel number
 * param mask      The interrupts to enable. This is a logical OR of members of the
 *                  enumeration ::qtmr_interrupt_enable_t
 */
void QTMR_EnableInterrupts(TMR_Type *base, qtmr_channel_selection_t channel, uint32_t mask)
{
    uint16_t reg;

    reg = base->CHANNEL[channel].SCTRL;
    /* Compare interrupt */
    if ((mask & (uint16_t)kQTMR_CompareInterruptEnable) != 0UL)
    {
        reg |= TMR_SCTRL_TCFIE_MASK;
    }
    /* Overflow interrupt */
    if ((mask & (uint16_t)kQTMR_OverflowInterruptEnable) != 0UL)
    {
        reg |= TMR_SCTRL_TOFIE_MASK;
    }
    /* Input edge interrupt */
    if ((mask & (uint16_t)kQTMR_EdgeInterruptEnable) != 0UL)
    {
        /* Restriction: Do not set both SCTRL[IEFIE] and DMA[IEFDE] */
        base->CHANNEL[channel].DMA &= ~(uint16_t)TMR_DMA_IEFDE_MASK;
        reg |= TMR_SCTRL_IEFIE_MASK;
    }
    base->CHANNEL[channel].SCTRL = reg;

    reg = base->CHANNEL[channel].CSCTRL;
    /* Compare 1 interrupt */
    if ((mask & (uint16_t)kQTMR_Compare1InterruptEnable) != 0UL)
    {
        reg |= TMR_CSCTRL_TCF1EN_MASK;
    }
    /* Compare 2 interrupt */
    if ((mask & (uint16_t)kQTMR_Compare2InterruptEnable) != 0UL)
    {
        reg |= TMR_CSCTRL_TCF2EN_MASK;
    }
    base->CHANNEL[channel].CSCTRL = reg;
}

/*!
 * brief Disables the selected Quad Timer interrupts
 *
 * param base     Quad Timer peripheral base addres
 * param channel  Quad Timer channel number
 * param mask The interrupts to enable. This is a logical OR of members of the
 *             enumeration ::qtmr_interrupt_enable_t
 */
void QTMR_DisableInterrupts(TMR_Type *base, qtmr_channel_selection_t channel, uint32_t mask)
{
    uint16_t reg;

    reg = base->CHANNEL[channel].SCTRL;
    /* Compare interrupt */
    if ((mask & (uint16_t)kQTMR_CompareInterruptEnable) != 0UL)
    {
        reg &= (uint16_t)(~TMR_SCTRL_TCFIE_MASK);
    }
    /* Overflow interrupt */
    if ((mask & (uint16_t)kQTMR_OverflowInterruptEnable) != 0UL)
    {
        reg &= (uint16_t)(~TMR_SCTRL_TOFIE_MASK);
    }
    /* Input edge interrupt */
    if ((mask & (uint16_t)kQTMR_EdgeInterruptEnable) != 0UL)
    {
        reg &= (uint16_t)(~TMR_SCTRL_IEFIE_MASK);
    }
    base->CHANNEL[channel].SCTRL = reg;

    reg = base->CHANNEL[channel].CSCTRL;
    /* Compare 1 interrupt */
    if ((mask & (uint16_t)kQTMR_Compare1InterruptEnable) != 0UL)
    {
        reg &= ~(uint16_t)TMR_CSCTRL_TCF1EN_MASK;
    }
    /* Compare 2 interrupt */
    if ((mask & (uint16_t)kQTMR_Compare2InterruptEnable) != 0UL)
    {
        reg &= ~(uint16_t)TMR_CSCTRL_TCF2EN_MASK;
    }
    base->CHANNEL[channel].CSCTRL = reg;
}

/*!
 * brief Gets the enabled Quad Timer interrupts
 *
 * param base    Quad Timer peripheral base address
 * param channel Quad Timer channel number
 *
 * return The enabled interrupts. This is the logical OR of members of the
 *         enumeration ::qtmr_interrupt_enable_t
 */
uint32_t QTMR_GetEnabledInterrupts(TMR_Type *base, qtmr_channel_selection_t channel)
{
    uint32_t enabledInterrupts = 0;
    uint16_t reg;

    reg = base->CHANNEL[channel].SCTRL;
    /* Compare interrupt */
    if ((reg & TMR_SCTRL_TCFIE_MASK) != 0U)
    {
        enabledInterrupts |= (uint32_t)kQTMR_CompareFlag;
    }
    /* Overflow interrupt */
    if ((reg & TMR_SCTRL_TOFIE_MASK) != 0U)
    {
        enabledInterrupts |= (uint32_t)kQTMR_OverflowInterruptEnable;
    }
    /* Input edge interrupt */
    if ((reg & TMR_SCTRL_IEFIE_MASK) != 0U)
    {
        enabledInterrupts |= (uint32_t)kQTMR_EdgeInterruptEnable;
    }

    reg = base->CHANNEL[channel].CSCTRL;
    /* Compare 1 interrupt */
    if ((reg & TMR_CSCTRL_TCF1EN_MASK) != 0U)
    {
        enabledInterrupts |= (uint32_t)kQTMR_Compare1InterruptEnable;
    }
    /* Compare 2 interrupt */
    if ((reg & TMR_CSCTRL_TCF2EN_MASK) != 0U)
    {
        enabledInterrupts |= (uint32_t)kQTMR_Compare2InterruptEnable;
    }

    return enabledInterrupts;
}

/*!
 * brief Gets the Quad Timer status flags
 *
 * param base     Quad Timer peripheral base address
 * param channel  Quad Timer channel number
 *
 * return The status flags. This is the logical OR of members of the
 *         enumeration ::qtmr_status_flags_t
 */
uint32_t QTMR_GetStatus(TMR_Type *base, qtmr_channel_selection_t channel)
{
    uint32_t statusFlags = 0;
    uint16_t reg;

    reg = base->CHANNEL[channel].SCTRL;
    /* Timer compare flag */
    if ((reg & TMR_SCTRL_TCF_MASK) != 0U)
    {
        statusFlags |= (uint32_t)kQTMR_CompareFlag;
    }
    /* Timer overflow flag */
    if ((reg & TMR_SCTRL_TOF_MASK) != 0U)
    {
        statusFlags |= (uint32_t)kQTMR_OverflowFlag;
    }
    /* Input edge flag */
    if ((reg & TMR_SCTRL_IEF_MASK) != 0U)
    {
        statusFlags |= (uint32_t)kQTMR_EdgeFlag;
    }

    reg = base->CHANNEL[channel].CSCTRL;
    /* Compare 1 flag */
    if ((reg & TMR_CSCTRL_TCF1_MASK) != 0U)
    {
        statusFlags |= (uint32_t)kQTMR_Compare1Flag;
    }
    /* Compare 2 flag */
    if ((reg & TMR_CSCTRL_TCF2_MASK) != 0U)
    {
        statusFlags |= (uint32_t)kQTMR_Compare2Flag;
    }

    return statusFlags;
}

/*!
 * brief Clears the Quad Timer status flags.
 *
 * param base     Quad Timer peripheral base address
 * param channel  Quad Timer channel number
 * param mask The status flags to clear. This is a logical OR of members of the
 *             enumeration ::qtmr_status_flags_t
 */
void QTMR_ClearStatusFlags(TMR_Type *base, qtmr_channel_selection_t channel, uint32_t mask)
{
    uint16_t reg;

    reg = base->CHANNEL[channel].SCTRL;
    /* Timer compare flag */
    if ((mask & (uint32_t)kQTMR_CompareFlag) != 0U)
    {
        reg &= (uint16_t)(~TMR_SCTRL_TCF_MASK);
    }
    /* Timer overflow flag */
    if ((mask & (uint32_t)kQTMR_OverflowFlag) != 0U)
    {
        reg &= (uint16_t)(~TMR_SCTRL_TOF_MASK);
    }
    /* Input edge flag */
    if ((mask & (uint32_t)kQTMR_EdgeFlag) != 0U)
    {
        reg &= (uint16_t)(~TMR_SCTRL_IEF_MASK);
    }
    base->CHANNEL[channel].SCTRL = reg;

    reg = base->CHANNEL[channel].CSCTRL;
    /* Compare 1 flag */
    if ((mask & (uint32_t)kQTMR_Compare1Flag) != 0U)
    {
        reg &= ~(uint16_t)TMR_CSCTRL_TCF1_MASK;
    }
    /* Compare 2 flag */
    if ((mask & (uint32_t)kQTMR_Compare2Flag) != 0U)
    {
        reg &= ~(uint16_t)TMR_CSCTRL_TCF2_MASK;
    }
    base->CHANNEL[channel].CSCTRL = reg;
}

/*!
 * brief Sets the timer period in ticks.
 *
 * Timers counts from initial value till it equals the count value set here. The counter
 * will then reinitialize to the value specified in the Load register.
 *
 * note
 * 1. This function will write the time period in ticks to COMP1 or COMP2 register
 *    depending on the count direction
 * 2. User can call the utility macros provided in fsl_common.h to convert to ticks
 * 3. This function supports cases, providing only primary source clock without secondary source clock.
 *
 * param base     Quad Timer peripheral base address
 * param channel  Quad Timer channel number
 * param ticks Timer period in units of ticks
 */
void QTMR_SetTimerPeriod(TMR_Type *base, qtmr_channel_selection_t channel, uint16_t ticks)
{
    /* Set the length bit to reinitialize the counters on a match */
    base->CHANNEL[channel].CTRL |= TMR_CTRL_LENGTH_MASK;

    if ((base->CHANNEL[channel].CTRL & TMR_CTRL_DIR_MASK) != 0U)
    {
        /* Counting down */
        base->CHANNEL[channel].COMP2 = ticks;
    }
    else
    {
        /* Counting up */
        base->CHANNEL[channel].COMP1 = ticks;
    }
}

/*!
 * brief Enable the Quad Timer DMA.
 *
 * param base     Quad Timer peripheral base address
 * param channel  Quad Timer channel number
 * param mask     The DMA to enable. This is a logical OR of members of the
 *                  enumeration ::qtmr_dma_enable_t
 */
void QTMR_EnableDma(TMR_Type *base, qtmr_channel_selection_t channel, uint32_t mask)
{
    uint16_t reg;

    reg = base->CHANNEL[channel].DMA;
    /* Input Edge Flag DMA Enable */
    if ((mask & (uint32_t)kQTMR_InputEdgeFlagDmaEnable) != 0U)
    {
        /* Restriction: Do not set both DMA[IEFDE] and SCTRL[IEFIE] */
        base->CHANNEL[channel].SCTRL &= (uint16_t)(~TMR_SCTRL_IEFIE_MASK);
        reg |= TMR_DMA_IEFDE_MASK;
    }
    /* Comparator Preload Register 1 DMA Enable */
    if ((mask & (uint32_t)kQTMR_ComparatorPreload1DmaEnable) != 0U)
    {
        reg |= TMR_DMA_CMPLD1DE_MASK;
    }
    /* Comparator Preload Register 2 DMA Enable */
    if ((mask & (uint32_t)kQTMR_ComparatorPreload2DmaEnable) != 0U)
    {
        reg |= TMR_DMA_CMPLD2DE_MASK;
    }
    base->CHANNEL[channel].DMA = reg;
}

/*!
 * brief Disable the Quad Timer DMA.
 *
 * param base     Quad Timer peripheral base address
 * param channel  Quad Timer channel number
 * param mask     The DMA to enable. This is a logical OR of members of the
 *                  enumeration ::qtmr_dma_enable_t
 */
void QTMR_DisableDma(TMR_Type *base, qtmr_channel_selection_t channel, uint32_t mask)
{
    uint16_t reg;

    reg = base->CHANNEL[channel].DMA;
    /* Input Edge Flag DMA Enable */
    if ((mask & (uint32_t)kQTMR_InputEdgeFlagDmaEnable) != 0U)
    {
        reg &= ~(uint16_t)TMR_DMA_IEFDE_MASK;
    }
    /* Comparator Preload Register 1 DMA Enable */
    if ((mask & (uint32_t)kQTMR_ComparatorPreload1DmaEnable) != 0U)
    {
        reg &= ~(uint16_t)TMR_DMA_CMPLD1DE_MASK;
    }
    /* Comparator Preload Register 2 DMA Enable */
    if ((mask & (uint32_t)kQTMR_ComparatorPreload2DmaEnable) != 0U)
    {
        reg &= ~(uint16_t)TMR_DMA_CMPLD2DE_MASK;
    }
    base->CHANNEL[channel].DMA = reg;
}

A module-bsp/board/rt1051/common/fsl_drivers/fsl_qtmr.h => module-bsp/board/rt1051/common/fsl_drivers/fsl_qtmr.h +439 -0
@@ 0,0 1,439 @@
/*
 * Copyright 2017-2020 NXP
 * All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */
#ifndef _FSL_QTMR_H_
#define _FSL_QTMR_H_

#include "fsl_common.h"

/*!
 * @addtogroup qtmr
 * @{
 */

/*******************************************************************************
 * Definitions
 ******************************************************************************/

/*! @name Driver version */
/*@{*/
#define FSL_QTMR_DRIVER_VERSION (MAKE_VERSION(2, 0, 2)) /*!< Version */
/*@}*/

/*! @brief Quad Timer primary clock source selection*/
typedef enum _qtmr_primary_count_source
{
    kQTMR_ClockCounter0InputPin = 0, /*!< Use counter 0 input pin */
    kQTMR_ClockCounter1InputPin,     /*!< Use counter 1 input pin */
    kQTMR_ClockCounter2InputPin,     /*!< Use counter 2 input pin */
    kQTMR_ClockCounter3InputPin,     /*!< Use counter 3 input pin */
    kQTMR_ClockCounter0Output,       /*!< Use counter 0 output */
    kQTMR_ClockCounter1Output,       /*!< Use counter 1 output */
    kQTMR_ClockCounter2Output,       /*!< Use counter 2 output */
    kQTMR_ClockCounter3Output,       /*!< Use counter 3 output */
    kQTMR_ClockDivide_1,             /*!< IP bus clock divide by 1 prescaler */
    kQTMR_ClockDivide_2,             /*!< IP bus clock divide by 2 prescaler */
    kQTMR_ClockDivide_4,             /*!< IP bus clock divide by 4 prescaler */
    kQTMR_ClockDivide_8,             /*!< IP bus clock divide by 8 prescaler */
    kQTMR_ClockDivide_16,            /*!< IP bus clock divide by 16 prescaler */
    kQTMR_ClockDivide_32,            /*!< IP bus clock divide by 32 prescaler */
    kQTMR_ClockDivide_64,            /*!< IP bus clock divide by 64 prescaler */
    kQTMR_ClockDivide_128            /*!< IP bus clock divide by 128 prescaler */
} qtmr_primary_count_source_t;

/*! @brief Quad Timer input sources selection*/
typedef enum _qtmr_input_source
{
    kQTMR_Counter0InputPin = 0, /*!< Use counter 0 input pin */
    kQTMR_Counter1InputPin,     /*!< Use counter 1 input pin */
    kQTMR_Counter2InputPin,     /*!< Use counter 2 input pin */
    kQTMR_Counter3InputPin      /*!< Use counter 3 input pin */
} qtmr_input_source_t;

/*! @brief Quad Timer counting mode selection */
typedef enum _qtmr_counting_mode
{
    kQTMR_NoOperation = 0,          /*!< No operation */
    kQTMR_PriSrcRiseEdge,           /*!< Count rising edges or primary source */
    kQTMR_PriSrcRiseAndFallEdge,    /*!< Count rising and falling edges of primary source */
    kQTMR_PriSrcRiseEdgeSecInpHigh, /*!< Count rise edges of pri SRC while sec inp high active */
    kQTMR_QuadCountMode,            /*!< Quadrature count mode, uses pri and sec sources */
    kQTMR_PriSrcRiseEdgeSecDir,     /*!< Count rising edges of pri SRC; sec SRC specifies dir */
    kQTMR_SecSrcTrigPriCnt,         /*!< Edge of sec SRC trigger primary count until compare*/
    kQTMR_CascadeCount              /*!< Cascaded count mode (up/down) */
} qtmr_counting_mode_t;

/*! @brief Quad Timer output mode selection*/
typedef enum _qtmr_output_mode
{
    kQTMR_AssertWhenCountActive = 0,    /*!< Assert OFLAG while counter is active*/
    kQTMR_ClearOnCompare,               /*!< Clear OFLAG on successful compare */
    kQTMR_SetOnCompare,                 /*!< Set OFLAG on successful compare */
    kQTMR_ToggleOnCompare,              /*!< Toggle OFLAG on successful compare */
    kQTMR_ToggleOnAltCompareReg,        /*!< Toggle OFLAG using alternating compare registers */
    kQTMR_SetOnCompareClearOnSecSrcInp, /*!< Set OFLAG on compare, clear on sec SRC input edge */
    kQTMR_SetOnCompareClearOnCountRoll, /*!< Set OFLAG on compare, clear on counter rollover */
    kQTMR_EnableGateClock               /*!< Enable gated clock output while count is active */
} qtmr_output_mode_t;

/*! @brief Quad Timer input capture edge mode, rising edge, or falling edge */
typedef enum _qtmr_input_capture_edge
{
    kQTMR_NoCapture = 0,       /*!< Capture is disabled */
    kQTMR_RisingEdge,          /*!< Capture on rising edge (IPS=0) or falling edge (IPS=1)*/
    kQTMR_FallingEdge,         /*!< Capture on falling edge (IPS=0) or rising edge (IPS=1)*/
    kQTMR_RisingAndFallingEdge /*!< Capture on both edges */
} qtmr_input_capture_edge_t;

/*! @brief Quad Timer input capture edge mode, rising edge, or falling edge */
typedef enum _qtmr_preload_control
{
    kQTMR_NoPreload = 0, /*!< Never preload */
    kQTMR_LoadOnComp1,   /*!< Load upon successful compare with value in COMP1 */
    kQTMR_LoadOnComp2    /*!< Load upon successful compare with value in COMP2*/
} qtmr_preload_control_t;

/*! @brief List of Quad Timer run options when in Debug mode */
typedef enum _qtmr_debug_action
{
    kQTMR_RunNormalInDebug = 0U, /*!< Continue with normal operation */
    kQTMR_HaltCounter,           /*!< Halt counter */
    kQTMR_ForceOutToZero,        /*!< Force output to logic 0 */
    kQTMR_HaltCountForceOutZero  /*!< Halt counter and force output to logic 0 */
} qtmr_debug_action_t;

/*! @brief List of Quad Timer interrupts */
// typedef enum _qtmr_interrupt_enable
typedef enum _qtmr_interrupt_enable
{
    kQTMR_CompareInterruptEnable  = (1U << 0), /*!< Compare interrupt.*/
    kQTMR_Compare1InterruptEnable = (1U << 1), /*!< Compare 1 interrupt.*/
    kQTMR_Compare2InterruptEnable = (1U << 2), /*!< Compare 2 interrupt.*/
    kQTMR_OverflowInterruptEnable = (1U << 3), /*!< Timer overflow interrupt.*/
    kQTMR_EdgeInterruptEnable     = (1U << 4)  /*!< Input edge interrupt.*/
} qtmr_interrupt_enable_t;

/*! @brief List of Quad Timer flags */
typedef enum _qtmr_status_flags
{
    kQTMR_CompareFlag  = (1U << 0), /*!< Compare flag */
    kQTMR_Compare1Flag = (1U << 1), /*!< Compare 1 flag */
    kQTMR_Compare2Flag = (1U << 2), /*!< Compare 2 flag */
    kQTMR_OverflowFlag = (1U << 3), /*!< Timer overflow flag */
    kQTMR_EdgeFlag     = (1U << 4)  /*!< Input edge flag */
} qtmr_status_flags_t;

/*! @brief List of channel selection */
typedef enum _qtmr_channel_selection
{
    kQTMR_Channel_0 = 0U, /*!< TMR Channel 0 */
    kQTMR_Channel_1,      /*!< TMR Channel 1 */
    kQTMR_Channel_2,      /*!< TMR Channel 2 */
    kQTMR_Channel_3,      /*!< TMR Channel 3 */
} qtmr_channel_selection_t;

/*! @brief List of Quad Timer DMA enable */
typedef enum _qtmr_dma_enable
{
    kQTMR_InputEdgeFlagDmaEnable      = (1U << 0), /*!< Input Edge Flag DMA Enable.*/
    kQTMR_ComparatorPreload1DmaEnable = (1U << 1), /*!< Comparator Preload Register 1 DMA Enable.*/
    kQTMR_ComparatorPreload2DmaEnable = (1U << 2), /*!< Comparator Preload Register 2 DMA Enable.*/
} qtmr_dma_enable_t;

/*!
 * @brief Quad Timer config structure
 *
 * This structure holds the configuration settings for the Quad Timer peripheral. To initialize this
 * structure to reasonable defaults, call the QTMR_GetDefaultConfig() function and pass a
 * pointer to your config structure instance.
 *
 * The config struct can be made const so it resides in flash
 */
typedef struct _qtmr_config
{
    qtmr_primary_count_source_t primarySource; /*!< Specify the primary count source */
    qtmr_input_source_t secondarySource;       /*!< Specify the secondary count source */
    bool enableMasterMode;                     /*!< true: Broadcast compare function output to other counters;
                                                    false no broadcast */
    bool enableExternalForce;                  /*!< true: Compare from another counter force state of OFLAG signal
                                                    false: OFLAG controlled by local counter */
    uint8_t faultFilterCount;                  /*!< Fault filter count */
    uint8_t faultFilterPeriod;                 /*!< Fault filter period;value of 0 will bypass the filter */
    qtmr_debug_action_t debugMode;             /*!< Operation in Debug mode */
} qtmr_config_t;

/*******************************************************************************
 * API
 ******************************************************************************/

#if defined(__cplusplus)
extern "C" {
#endif

/*!
 * @name Initialization and deinitialization
 * @{
 */

/*!
 * @brief Ungates the Quad Timer clock and configures the peripheral for basic operation.
 *
 * @note This API should be called at the beginning of the application using the Quad Timer driver.
 *
 * @param base     Quad Timer peripheral base address
 * @param channel  Quad Timer channel number
 * @param config   Pointer to user's Quad Timer config structure
 */
void QTMR_Init(TMR_Type *base, qtmr_channel_selection_t channel, const qtmr_config_t *config);

/*!
 * @brief Stops the counter and gates the Quad Timer clock
 *
 * @param base     Quad Timer peripheral base address
 * @param channel  Quad Timer channel number
 */
void QTMR_Deinit(TMR_Type *base, qtmr_channel_selection_t channel);

/*!
 * @brief  Fill in the Quad Timer config struct with the default settings
 *
 * The default values are:
 * @code
 *    config->debugMode = kQTMR_RunNormalInDebug;
 *    config->enableExternalForce = false;
 *    config->enableMasterMode = false;
 *    config->faultFilterCount = 0;
 *    config->faultFilterPeriod = 0;
 *    config->primarySource = kQTMR_ClockDivide_2;
 *    config->secondarySource = kQTMR_Counter0InputPin;
 * @endcode
 * @param config Pointer to user's Quad Timer config structure.
 */
void QTMR_GetDefaultConfig(qtmr_config_t *config);

/*! @}*/

/*!
 * @brief Sets up Quad timer module for PWM signal output.
 *
 * The function initializes the timer module according to the parameters passed in by the user. The
 * function also sets up the value compare registers to match the PWM signal requirements.
 *
 * @param base             Quad Timer peripheral base address
 * @param channel          Quad Timer channel number
 * @param pwmFreqHz        PWM signal frequency in Hz
 * @param dutyCyclePercent PWM pulse width, value should be between 0 to 100
 *                         0=inactive signal(0% duty cycle)...
 *                         100=active signal (100% duty cycle)
 * @param outputPolarity   true: invert polarity of the output signal, false: no inversion
 * @param srcClock_Hz      Main counter clock in Hz.
 *
 * @return Returns an error if there was error setting up the signal.
 */
status_t QTMR_SetupPwm(TMR_Type *base,
                       qtmr_channel_selection_t channel,
                       uint32_t pwmFreqHz,
                       uint8_t dutyCyclePercent,
                       bool outputPolarity,
                       uint32_t srcClock_Hz);

/*!
 * @brief Allows the user to count the source clock cycles until a capture event arrives.
 *
 * The count is stored in the capture register.
 *
 * @param base            Quad Timer peripheral base address
 * @param channel         Quad Timer channel number
 * @param capturePin      Pin through which we receive the input signal to trigger the capture
 * @param inputPolarity   true: invert polarity of the input signal, false: no inversion
 * @param reloadOnCapture true: reload the counter when an input capture occurs, false: no reload
 * @param captureMode     Specifies which edge of the input signal  triggers a capture
 */
void QTMR_SetupInputCapture(TMR_Type *base,
                            qtmr_channel_selection_t channel,
                            qtmr_input_source_t capturePin,
                            bool inputPolarity,
                            bool reloadOnCapture,
                            qtmr_input_capture_edge_t captureMode);

/*!
 * @name Interrupt Interface
 * @{
 */

/*!
 * @brief Enables the selected Quad Timer interrupts
 *
 * @param base      Quad Timer peripheral base address
 * @param channel   Quad Timer channel number
 * @param mask      The interrupts to enable. This is a logical OR of members of the
 *                  enumeration ::qtmr_interrupt_enable_t
 */
void QTMR_EnableInterrupts(TMR_Type *base, qtmr_channel_selection_t channel, uint32_t mask);

/*!
 * @brief Disables the selected Quad Timer interrupts
 *
 * @param base     Quad Timer peripheral base addres
 * @param channel  Quad Timer channel number
 * @param mask The interrupts to enable. This is a logical OR of members of the
 *             enumeration ::qtmr_interrupt_enable_t
 */
void QTMR_DisableInterrupts(TMR_Type *base, qtmr_channel_selection_t channel, uint32_t mask);

/*!
 * @brief Gets the enabled Quad Timer interrupts
 *
 * @param base    Quad Timer peripheral base address
 * @param channel Quad Timer channel number
 *
 * @return The enabled interrupts. This is the logical OR of members of the
 *         enumeration ::qtmr_interrupt_enable_t
 */
uint32_t QTMR_GetEnabledInterrupts(TMR_Type *base, qtmr_channel_selection_t channel);

/*! @}*/

/*!
 * @name Status Interface
 * @{
 */

/*!
 * @brief Gets the Quad Timer status flags
 *
 * @param base     Quad Timer peripheral base address
 * @param channel  Quad Timer channel number
 *
 * @return The status flags. This is the logical OR of members of the
 *         enumeration ::qtmr_status_flags_t
 */
uint32_t QTMR_GetStatus(TMR_Type *base, qtmr_channel_selection_t channel);

/*!
 * @brief Clears the Quad Timer status flags.
 *
 * @param base     Quad Timer peripheral base address
 * @param channel  Quad Timer channel number
 * @param mask The status flags to clear. This is a logical OR of members of the
 *             enumeration ::qtmr_status_flags_t
 */
void QTMR_ClearStatusFlags(TMR_Type *base, qtmr_channel_selection_t channel, uint32_t mask);

/*! @}*/

/*!
 * @name Read and Write the timer period
 * @{
 */

/*!
 * @brief Sets the timer period in ticks.
 *
 * Timers counts from initial value till it equals the count value set here. The counter
 * will then reinitialize to the value specified in the Load register.
 *
 * @note
 * 1. This function will write the time period in ticks to COMP1 or COMP2 register
 *    depending on the count direction
 * 2. User can call the utility macros provided in fsl_common.h to convert to ticks
 * 3. This function supports cases, providing only primary source clock without secondary source clock.
 *
 * @param base     Quad Timer peripheral base address
 * @param channel  Quad Timer channel number
 * @param ticks Timer period in units of ticks
 */
void QTMR_SetTimerPeriod(TMR_Type *base, qtmr_channel_selection_t channel, uint16_t ticks);

/*!
 * @brief Reads the current timer counting value.
 *
 * This function returns the real-time timer counting value, in a range from 0 to a
 * timer period.
 *
 * @note User can call the utility macros provided in fsl_common.h to convert ticks to usec or msec
 *
 * @param base     Quad Timer peripheral base address
 * @param channel  Quad Timer channel number
 *
 * @return Current counter value in ticks
 */
static inline uint16_t QTMR_GetCurrentTimerCount(TMR_Type *base, qtmr_channel_selection_t channel)
{
    return base->CHANNEL[channel].CNTR;
}

/*! @}*/

/*!
 * @name Timer Start and Stop
 * @{
 */

/*!
 * @brief Starts the Quad Timer counter.
 *
 *
 * @param base        Quad Timer peripheral base address
 * @param channel     Quad Timer channel number
 * @param clockSource Quad Timer clock source
 */
static inline void QTMR_StartTimer(TMR_Type *base, qtmr_channel_selection_t channel, qtmr_counting_mode_t clockSource)
{
    uint16_t reg = base->CHANNEL[channel].CTRL;

    reg &= (uint16_t)(~(TMR_CTRL_CM_MASK));
    reg |= TMR_CTRL_CM(clockSource);
    base->CHANNEL[channel].CTRL = reg;
}

/*!
 * @brief Stops the Quad Timer counter.
 *
 * @param base     Quad Timer peripheral base address
 * @param channel  Quad Timer channel number
 */
static inline void QTMR_StopTimer(TMR_Type *base, qtmr_channel_selection_t channel)
{
    base->CHANNEL[channel].CTRL &= (uint16_t)(~TMR_CTRL_CM_MASK);
}

/*! @}*/

/*!
 * @name Enable and Disable the Quad Timer DMA
 * @{
 */

/*!
 * @brief Enable the Quad Timer DMA.
 *
 * @param base     Quad Timer peripheral base address
 * @param channel  Quad Timer channel number
 * @param mask     The DMA to enable. This is a logical OR of members of the
 *                  enumeration ::qtmr_dma_enable_t
 */
void QTMR_EnableDma(TMR_Type *base, qtmr_channel_selection_t channel, uint32_t mask);

/*!
 * @brief Disable the Quad Timer DMA.
 *
 * @param base     Quad Timer peripheral base address
 * @param channel  Quad Timer channel number
 * @param mask     The DMA to enable. This is a logical OR of members of the
 *                  enumeration ::qtmr_dma_enable_t
 */
void QTMR_DisableDma(TMR_Type *base, qtmr_channel_selection_t channel, uint32_t mask);

/*! @}*/

#if defined(__cplusplus)
}
#endif

/*! @}*/

#endif /* _FSL_QTMR_H_ */

A module-bsp/bsp/rotary_encoder/rotary_encoder.hpp => module-bsp/bsp/rotary_encoder/rotary_encoder.hpp +23 -0
@@ 0,0 1,23 @@
#pragma once

#include <cstdint>
#include <optional>

#include "../common.hpp"
#include <queue.hpp>

namespace bsp
{
    namespace rotary_encoder
    {
        enum class type
        {
            forward  = 0x01,
            backward = 0x02
        };
        int init(xQueueHandle qHandle);
        void deinit();
        std::optional<type> WorkerEventHandler();
    } // namespace rotary_encoder

} // namespace bsp

M products/BellHybrid/services/evtmgr/WorkerEvent.cpp => products/BellHybrid/services/evtmgr/WorkerEvent.cpp +22 -2
@@ 6,6 6,7 @@
#include <bsp/eink_frontlight/eink_frontlight.hpp>
#include <service-audio/AudioMessage.hpp>
#include <service-evtmgr/EVMessages.hpp>
#include <bsp/rotary_encoder/rotary_encoder.hpp>

namespace bell
{


@@ 14,21 15,40 @@ namespace bell
    {}

    void WorkerEvent::addProductQueues(std::list<sys::WorkerQueueInfo> &queuesList)
    {}
    {
        constexpr auto elementSize = sizeof(std::uint8_t);
        queuesList.emplace_back(rotaryEncoderQueueName, elementSize, rotaryEncoderQueueSize);
    }

    void WorkerEvent::initProductHardware()
    {
        bsp::eink_frontlight::init();
        bsp::rotary_encoder::init(queues[static_cast<int32_t>(EventQueues::queueRotaryEncoder)]->GetQueueHandle());
    }

    bool WorkerEvent::handleMessage(std::uint32_t queueID)
    {

        auto &queue = queues[queueID];
        if (queueID == static_cast<uint32_t>(EventQueues::queueRotaryEncoder)) {
            uint8_t notification;
            if (!queue->Dequeue(&notification, 0)) {
                return false;
            }
            handleRotaryEncoderEvent();
        }
        return WorkerEventCommon::handleMessage(queueID);
    }

    void WorkerEvent::deinitProductHardware()
    {
        bsp::eink_frontlight::deinit();
        bsp::rotary_encoder::deinit();
    }

    void WorkerEvent::handleRotaryEncoderEvent()
    {
        if (const auto &key = bsp::rotary_encoder::WorkerEventHandler(); key.has_value()) {
            LOG_DEBUG("Rotary encoder handler %i", int(key.value()));
        }
    }
} // namespace bell

M products/BellHybrid/services/evtmgr/WorkerEvent.hpp => products/BellHybrid/services/evtmgr/WorkerEvent.hpp +8 -0
@@ 17,5 17,13 @@ namespace bell
        void initProductHardware() final;
        void deinitProductHardware() final;
        bool handleMessage(std::uint32_t queueID) override;
        void handleRotaryEncoderEvent();
        enum class EventQueues
        {
            queueHeadsetIRQ = static_cast<int>(WorkerEventQueues::queueRTC) + 1,
            queueRotaryEncoder,
        };
        static constexpr auto rotaryEncoderQueueSize = 64U;
        static constexpr auto rotaryEncoderQueueName = "qRotaryEncoder";
    };
} // namespace bell