M module-bsp/CMakeLists.txt => module-bsp/CMakeLists.txt +1 -0
@@ 74,6 74,7 @@ target_link_libraries(${PROJECT_NAME}
eventstore
module-os
service-bluetooth
+ magic_enum
${TARGET_LIBRARIES}
PRIVATE
time-constants
M module-bsp/board/linux/hal/key_input/KeyInput.cpp => module-bsp/board/linux/hal/key_input/KeyInput.cpp +1 -1
@@ 84,7 84,7 @@ namespace hal::key_input
close(fd);
}
- std::vector<bsp::KeyEvent> LinuxKeyInput::getKeyEvents(std::uint8_t)
+ std::vector<bsp::KeyEvent> LinuxKeyInput::getKeyEvents(KeyNotificationSource)
{
using namespace bsp;
KeyEvent keyEvent;
M module-bsp/board/linux/hal/key_input/KeyInput.hpp => module-bsp/board/linux/hal/key_input/KeyInput.hpp +1 -1
@@ 12,6 12,6 @@ namespace hal::key_input
public:
void init(xQueueHandle qHandle) final;
void deinit() final;
- std::vector<bsp::KeyEvent> getKeyEvents(std::uint8_t) final;
+ std::vector<bsp::KeyEvent> getKeyEvents(KeyNotificationSource) final;
};
} // namespace hal::key_input
M module-bsp/board/rt1051/bellpx/CMakeLists.txt => module-bsp/board/rt1051/bellpx/CMakeLists.txt +3 -2
@@ 12,8 12,9 @@ target_sources(
PRIVATE
hal/temperature_source/TemperatureSource.cpp
hal/battery_charger/BatteryCharger.cpp
- hal/key_input/KeyInput.cpp
- bsp/eink/eink_pin_config.cpp
+ hal/key_input/KeyInput.cpp
+ bsp/eink/eink_pin_config.cpp
+ bsp/switches/switches.cpp
bsp/rotary_encoder/rotary_encoder.cpp
bsp/bell_temp_sensor/bell_temp_sensor.cpp
pin_mux.c
M module-bsp/board/rt1051/bellpx/board/BoardDefinitions.hpp => module-bsp/board/rt1051/bellpx/board/BoardDefinitions.hpp +10 -0
@@ 143,4 143,14 @@ enum class BoardDefinitions
BELL_TEMP_SENSOR_I2C = static_cast<int>(drivers::I2CInstances ::I2C4),
BELL_TEMP_SENSOR_I2C_BAUDRATE = I2C_STD_BAUDRATE,
+
+ BELL_SWITCHES_GPIO = static_cast<int>(drivers::GPIOInstances ::GPIO_2),
+ BELL_SWITCHES_CENTER = 16, // GPIO_B1_00
+ BELL_SWITCHES_LEFT = 24, // GPIO_B1_08
+ BELL_SWITCHES_RIGHT = 25, // GPIO_B1_09
+ BELL_SWITCHES_LATCH = 26, // GPIO_B1_10
+ BELL_SWITCHES_DOME = 27, // GPIO_B1_11
+
+ BELL_WAKEUP_GPIO = static_cast<int>(drivers::GPIOInstances ::GPIO_5),
+ BELL_WAKEUP = 0, // SNVS_WAKEUP_GPIO5_IO00
};
M module-bsp/board/rt1051/bellpx/board/pin_mux.h => module-bsp/board/rt1051/bellpx/board/pin_mux.h +8 -2
@@ 158,10 158,16 @@ extern "C"
/**
* BELL DOME SWITCH
*/
-#define PINMUX_DOME_SWITCH IOMUXC_GPIO_B0_11_GPIO2_IO11
+#define PINMUX_DOME_SWITCH IOMUXC_GPIO_B1_11_GPIO2_IO27
void PINMUX_DomeSwitch(void);
/**
+ * BELL WAKEUP
+ */
+#define PINMUX_WAKEUP IOMUXC_SNVS_WAKEUP_GPIO5_IO00
+ void PINMUX_Wakeup(void);
+
+/**
* BELL WDOG_B
*/
#define PINMUX_WDOG_B IOMUXC_GPIO_B1_13_GPIO2_IO29
@@ 186,4 192,4 @@ extern "C"
/***********************************************************************************************************************
* EOF
- **********************************************************************************************************************/>
\ No newline at end of file
+ **********************************************************************************************************************/
A module-bsp/board/rt1051/bellpx/bsp/switches/switches.cpp => module-bsp/board/rt1051/bellpx/bsp/switches/switches.cpp +412 -0
@@ 0,0 1,412 @@
+// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#include <module-utils/Utils.hpp> // for byte conversion functions. it is included first because of magic enum define
+
+#include <FreeRTOS.h>
+#include <mutex.hpp>
+#include <queue.h>
+#include <task.h>
+#include <timers.h>
+#include <bsp/switches/switches.hpp>
+#include <board/BoardDefinitions.hpp>
+#include <board.h>
+#include <fsl_common.h>
+
+#include <chrono>
+#include <stdio.h>
+#include <stdint.h>
+#include <assert.h>
+#include <map>
+#include <vector>
+#include <magic_enum.hpp>
+
+using namespace drivers;
+using namespace utils;
+
+namespace bsp::bell_switches
+{
+ using namespace std::chrono_literals;
+
+ using TimerCallback = void (*)(TimerHandle_t timerHandle);
+
+ constexpr std::chrono::milliseconds contactOscillationTimeout{30ms};
+ constexpr std::chrono::milliseconds centerKeyPressValidationTimeout{100ms};
+
+ enum class DebounceTimerId : unsigned int
+ {
+ leftSideSwitch = 0,
+ rightSideSwitch,
+ lightCenterSwitch,
+ latchSwitch,
+ wakeup,
+ Invalid
+ };
+
+ enum class NotificationSource : uint16_t
+ {
+ leftSideKeyPress = 0x0001,
+ leftSideKeyRelease = 0x0002,
+ rightSideKeyPress = 0x0004,
+ rightSideKeyRelease = 0x0008,
+ lightCenterKeyPress = 0x0010,
+ lightCenterKeyRelease = 0x0020,
+ latchKeyPress = 0x0040,
+ latchKeyRelease = 0x0080,
+ wakeupEvent = 0x0400,
+ wakeupEventRelease = 0x0800,
+ Invalid = 0xFFFF
+ };
+
+ void debounceTimerCallback(TimerHandle_t timerHandle);
+
+ struct DebounceTimerState
+ {
+ const DebounceTimerId id{DebounceTimerId::Invalid};
+ const NotificationSource notificationSource{NotificationSource::Invalid};
+ const std::shared_ptr<drivers::DriverGPIO> gpio;
+ const BoardDefinitions pin{-1};
+ KeyEvents lastState{KeyEvents::Pressed};
+ TimerHandle_t timer{nullptr};
+
+ void createTimer(TimerCallback callback, const std::chrono::milliseconds timeout)
+ {
+ timer =
+ xTimerCreate(magic_enum::enum_name(id).data(), pdMS_TO_TICKS(timeout.count()), false, this, callback);
+ }
+ };
+
+ static struct LatchEventFlag
+ {
+ private:
+ static constexpr std::chrono::milliseconds latchPressEventTimeout = 1000ms;
+ cpp_freertos::MutexStandard latchFlagMutex;
+ std::chrono::time_point<std::chrono::system_clock> timeOfLastLatchEvent = std::chrono::system_clock::now();
+ bool pressed = false;
+
+ public:
+ void setPressed()
+ {
+ cpp_freertos::LockGuard lock(latchFlagMutex);
+ pressed = true;
+ timeOfLastLatchEvent = std::chrono::system_clock::now();
+ }
+
+ void setReleased()
+ {
+ cpp_freertos::LockGuard lock(latchFlagMutex);
+ pressed = false;
+ timeOfLastLatchEvent = std::chrono::system_clock::now();
+ }
+
+ bool isPressed()
+ {
+ cpp_freertos::LockGuard lock(latchFlagMutex);
+ return pressed;
+ }
+
+ bool wasJustPressed()
+ {
+ cpp_freertos::LockGuard lock(latchFlagMutex);
+ auto ret = ((std::chrono::duration_cast<std::chrono::milliseconds>(
+ std::chrono::system_clock::now() - timeOfLastLatchEvent)) <= latchPressEventTimeout);
+ return ret;
+ }
+
+ } latchEventFlag;
+
+ static std::map<DebounceTimerId, DebounceTimerState> debounceTimers;
+
+ static xQueueHandle qHandleIrq{};
+ std::shared_ptr<DriverGPIO> gpio_sw;
+ std::shared_ptr<DriverGPIO> gpio_wakeup;
+
+ void debounceTimerCallback(TimerHandle_t timerHandle)
+ {
+ auto timerState = static_cast<DebounceTimerState *>(pvTimerGetTimerID(timerHandle));
+ BaseType_t xHigherPriorityTaskWoken = pdFALSE;
+ xTimerStop(timerState->timer, 0);
+
+ auto currentState = timerState->gpio->ReadPin(static_cast<uint32_t>(timerState->pin)) ? KeyEvents::Released
+ : KeyEvents::Pressed;
+
+ if (currentState == timerState->lastState && qHandleIrq != nullptr) {
+ if (currentState == KeyEvents::Pressed) {
+ if (timerState->notificationSource == NotificationSource::latchKeyPress) {
+ latchEventFlag.setPressed();
+ }
+ auto val = static_cast<std::uint16_t>(timerState->notificationSource);
+ xQueueSendFromISR(qHandleIrq, &val, &xHigherPriorityTaskWoken);
+ timerState->lastState = KeyEvents::Released;
+ }
+ else {
+ if (timerState->notificationSource == NotificationSource::latchKeyPress) {
+ latchEventFlag.setReleased();
+ }
+ // Using responding release notification source, which is one bit shifted
+ auto val = (static_cast<std::uint16_t>(timerState->notificationSource) << 1);
+ xQueueSendFromISR(qHandleIrq, &val, &xHigherPriorityTaskWoken);
+ timerState->lastState = KeyEvents::Pressed;
+ }
+ }
+
+ timerState->gpio->EnableInterrupt(1U << static_cast<uint32_t>(timerState->pin));
+ }
+
+ void debounceTimerCenterClickCallback(TimerHandle_t timerHandle)
+ {
+ auto timerState = static_cast<DebounceTimerState *>(pvTimerGetTimerID(timerHandle));
+ BaseType_t xHigherPriorityTaskWoken = pdFALSE;
+ xTimerStop(timerState->timer, 0);
+
+ if (!latchEventFlag.wasJustPressed() && qHandleIrq != nullptr) {
+ const auto currentState = timerState->gpio->ReadPin(static_cast<uint32_t>(timerState->pin))
+ ? KeyEvents::Released
+ : KeyEvents::Pressed;
+ if (currentState != timerState->lastState) {
+ auto val = static_cast<std::uint16_t>(timerState->notificationSource);
+ xQueueSendFromISR(qHandleIrq, &val, &xHigherPriorityTaskWoken);
+ }
+ }
+
+ timerState->gpio->EnableInterrupt(1U << static_cast<uint32_t>(timerState->pin));
+ }
+
+ void addDebounceTimer(DebounceTimerState timerState)
+ {
+ debounceTimers.insert({timerState.id, timerState});
+ DebounceTimerState &state = debounceTimers.find(timerState.id)->second;
+
+ if (timerState.notificationSource == NotificationSource::lightCenterKeyPress) {
+ state.createTimer(debounceTimerCenterClickCallback, centerKeyPressValidationTimeout);
+ }
+ else {
+ state.createTimer(debounceTimerCallback, contactOscillationTimeout);
+ }
+ }
+
+ void configureSwitch(BoardDefinitions boardSwitch, DriverGPIOPinParams::InterruptMode mode)
+ {
+
+ gpio_sw->ClearPortInterrupts(1 << magic_enum::enum_integer(boardSwitch));
+ gpio_sw->ConfPin(DriverGPIOPinParams{.dir = DriverGPIOPinParams::Direction::Input,
+ .irqMode = mode,
+ .defLogic = 1,
+ .pin = static_cast<uint32_t>(boardSwitch)});
+ }
+
+ int32_t init(xQueueHandle qHandle)
+ {
+ qHandleIrq = qHandle;
+
+ // Switches
+ gpio_sw =
+ DriverGPIO::Create(static_cast<GPIOInstances>(BoardDefinitions::BELL_SWITCHES_GPIO), DriverGPIOParams{});
+ // wakeup
+ gpio_wakeup =
+ DriverGPIO::Create(static_cast<GPIOInstances>(BoardDefinitions::BELL_WAKEUP_GPIO), DriverGPIOParams{});
+
+ configureSwitch(BoardDefinitions::BELL_SWITCHES_LATCH,
+ DriverGPIOPinParams::InterruptMode::IntRisingOrFallingEdge);
+ configureSwitch(BoardDefinitions::BELL_SWITCHES_LEFT,
+ DriverGPIOPinParams::InterruptMode::IntRisingOrFallingEdge);
+ configureSwitch(BoardDefinitions::BELL_SWITCHES_RIGHT,
+ DriverGPIOPinParams::InterruptMode::IntRisingOrFallingEdge);
+ configureSwitch(BoardDefinitions::BELL_SWITCHES_CENTER, DriverGPIOPinParams::InterruptMode::IntRisingEdge);
+ configureSwitch(BoardDefinitions::BELL_WAKEUP, DriverGPIOPinParams::InterruptMode::IntFallingEdge);
+
+ addDebounceTimer(DebounceTimerState{DebounceTimerId::leftSideSwitch,
+ NotificationSource::leftSideKeyPress,
+ gpio_sw,
+ BoardDefinitions::BELL_SWITCHES_LEFT});
+ addDebounceTimer(DebounceTimerState{DebounceTimerId::rightSideSwitch,
+ NotificationSource::rightSideKeyPress,
+ gpio_sw,
+ BoardDefinitions::BELL_SWITCHES_RIGHT});
+ addDebounceTimer(DebounceTimerState{DebounceTimerId::lightCenterSwitch,
+ NotificationSource::lightCenterKeyPress,
+ gpio_sw,
+ BoardDefinitions::BELL_SWITCHES_CENTER});
+ addDebounceTimer(DebounceTimerState{DebounceTimerId::latchSwitch,
+ NotificationSource::latchKeyPress,
+ gpio_sw,
+ BoardDefinitions::BELL_SWITCHES_LATCH,
+ KeyEvents::Released});
+ addDebounceTimer(DebounceTimerState{
+ DebounceTimerId::wakeup, NotificationSource::wakeupEvent, gpio_wakeup, BoardDefinitions::BELL_WAKEUP});
+
+ enableIRQ();
+
+ return kStatus_Success;
+ }
+
+ std::int32_t deinit()
+ {
+ qHandleIrq = nullptr;
+ disableIRQ();
+
+ for (const auto &el : debounceTimers) {
+ xTimerDelete(el.second.timer, 50);
+ }
+ debounceTimers.clear();
+
+ gpio_sw.reset();
+ gpio_wakeup.reset();
+
+ return kStatus_Success;
+ }
+
+ void getDebounceTimer(BaseType_t xHigherPriorityTaskWoken, DebounceTimerId timerId)
+ {
+ if (debounceTimers.find(timerId) == debounceTimers.end()) {
+ LOG_ERROR("Could not find debouncer timer for: %s", magic_enum::enum_name(timerId).data());
+ return;
+ }
+ auto debounceTimerState = debounceTimers.at(timerId);
+ debounceTimerState.gpio->DisableInterrupt(1U << static_cast<uint32_t>(debounceTimerState.pin));
+ debounceTimerState.lastState = debounceTimerState.gpio->ReadPin(static_cast<uint32_t>(debounceTimerState.pin))
+ ? KeyEvents::Released
+ : KeyEvents::Pressed;
+ if (debounceTimerState.timer != nullptr) {
+ xTimerResetFromISR(debounceTimerState.timer, &xHigherPriorityTaskWoken);
+ }
+ }
+
+ BaseType_t IRQHandler(uint32_t mask)
+ {
+ BaseType_t xHigherPriorityTaskWoken = pdFALSE;
+ auto timerId = DebounceTimerId::Invalid;
+
+ gpio_sw->ClearPortInterrupts(1U << mask);
+
+ if (mask & (1 << magic_enum::enum_integer(BoardDefinitions::BELL_SWITCHES_LEFT))) {
+ timerId = DebounceTimerId::leftSideSwitch;
+ }
+ else if (mask & (1 << magic_enum::enum_integer(BoardDefinitions::BELL_SWITCHES_RIGHT))) {
+ timerId = DebounceTimerId::rightSideSwitch;
+ }
+ else if (mask & (1 << magic_enum::enum_integer(BoardDefinitions::BELL_SWITCHES_CENTER))) {
+ timerId = DebounceTimerId::lightCenterSwitch;
+ }
+ else if (mask & (1 << magic_enum::enum_integer(BoardDefinitions::BELL_SWITCHES_LATCH))) {
+ timerId = DebounceTimerId::latchSwitch;
+ }
+
+ getDebounceTimer(xHigherPriorityTaskWoken, timerId);
+
+ return xHigherPriorityTaskWoken;
+ }
+
+ BaseType_t wakeupIRQHandler()
+ {
+ BaseType_t xHigherPriorityTaskWoken = pdFALSE;
+ gpio_wakeup->ClearPortInterrupts(1U << static_cast<uint32_t>(BoardDefinitions::BELL_WAKEUP));
+
+ getDebounceTimer(xHigherPriorityTaskWoken, DebounceTimerId::wakeup);
+
+ return xHigherPriorityTaskWoken;
+ }
+
+ void enableIRQ()
+ {
+ gpio_sw->EnableInterrupt(1 << static_cast<uint32_t>(BoardDefinitions::BELL_SWITCHES_CENTER));
+ gpio_sw->EnableInterrupt(1 << static_cast<uint32_t>(BoardDefinitions::BELL_SWITCHES_LEFT));
+ gpio_sw->EnableInterrupt(1 << static_cast<uint32_t>(BoardDefinitions::BELL_SWITCHES_RIGHT));
+ gpio_sw->EnableInterrupt(1 << static_cast<uint32_t>(BoardDefinitions::BELL_SWITCHES_LATCH));
+ }
+
+ void enableWakeupIRQ()
+ {
+ gpio_wakeup->EnableInterrupt(1 << static_cast<uint32_t>(BoardDefinitions::BELL_WAKEUP));
+ }
+
+ void disableIRQ()
+ {
+ gpio_sw->DisableInterrupt(1 << static_cast<uint32_t>(BoardDefinitions::BELL_SWITCHES_CENTER));
+ gpio_sw->DisableInterrupt(1 << static_cast<uint32_t>(BoardDefinitions::BELL_SWITCHES_LEFT));
+ gpio_sw->DisableInterrupt(1 << static_cast<uint32_t>(BoardDefinitions::BELL_SWITCHES_RIGHT));
+ gpio_sw->DisableInterrupt(1 << static_cast<uint32_t>(BoardDefinitions::BELL_SWITCHES_LATCH));
+ }
+
+ void disableWakeupIRQ()
+ {
+ gpio_wakeup->DisableInterrupt(1 << static_cast<uint32_t>(BoardDefinitions::BELL_WAKEUP));
+ }
+
+ std::vector<KeyEvent> getKeyEvents(KeyNotificationSource notification)
+ {
+ std::vector<KeyEvent> out;
+
+ if (notification & static_cast<uint16_t>(NotificationSource::leftSideKeyPress)) {
+ LOG_DEBUG("leftSideKeyPress");
+ KeyEvent keyEvent{KeyCodes::FnLeft, KeyEvents::Pressed};
+ out.push_back(keyEvent);
+ }
+
+ if (notification & static_cast<uint16_t>(NotificationSource::leftSideKeyRelease)) {
+ LOG_DEBUG("leftSideKeyRelease");
+ KeyEvent keyEvent{KeyCodes::FnLeft, KeyEvents::Released};
+ out.push_back(keyEvent);
+ }
+
+ if (notification & static_cast<uint16_t>(NotificationSource::rightSideKeyPress)) {
+ LOG_DEBUG("rightSideKeyPress");
+ KeyEvent keyEvent{KeyCodes::FnRight, KeyEvents::Pressed};
+ out.push_back(keyEvent);
+ }
+
+ if (notification & static_cast<uint8_t>(NotificationSource::rightSideKeyRelease)) {
+ LOG_DEBUG("rightSideKeyRelease");
+ KeyEvent keyEvent{KeyCodes::FnRight, KeyEvents::Released};
+ out.push_back(keyEvent);
+ }
+
+ if (notification & static_cast<uint16_t>(NotificationSource::lightCenterKeyPress)) {
+ LOG_DEBUG("lightCenterKeyPress");
+ KeyEvent keyEvent{KeyCodes::JoystickEnter, KeyEvents::Pressed};
+ out.push_back(keyEvent);
+ // workaround for current GUI event processing
+ keyEvent = {KeyCodes::JoystickEnter, KeyEvents::Released};
+ out.push_back(keyEvent);
+ }
+
+ if (notification & static_cast<uint16_t>(NotificationSource::lightCenterKeyRelease)) {
+ LOG_DEBUG("lightCenterKeyRelease");
+ KeyEvent keyEvent{KeyCodes::JoystickEnter, KeyEvents::Pressed};
+ out.push_back(keyEvent);
+ // workaround for current GUI event processing
+ keyEvent = {KeyCodes::JoystickEnter, KeyEvents::Released};
+ out.push_back(keyEvent);
+ }
+
+ if (notification & static_cast<uint16_t>(NotificationSource::latchKeyPress)) {
+ LOG_DEBUG("latchKeyPress");
+ KeyEvent keyEvent{KeyCodes::JoystickRight, KeyEvents::Pressed};
+ out.push_back(keyEvent);
+ // workaround for current GUI event processing
+ keyEvent = {KeyCodes::JoystickRight, KeyEvents::Released};
+ out.push_back(keyEvent);
+ }
+
+ if (notification & static_cast<uint16_t>(NotificationSource::latchKeyRelease)) {
+ LOG_DEBUG("latchKeyRelease");
+ KeyEvent keyEvent{KeyCodes::JoystickLeft, KeyEvents::Pressed};
+ out.push_back(keyEvent);
+ // workaround for current GUI event processing
+ keyEvent = {KeyCodes::JoystickLeft, KeyEvents::Released};
+ out.push_back(keyEvent);
+ }
+
+ if (notification & static_cast<uint16_t>(NotificationSource::wakeupEvent)) {
+ /* Implement wakeup event */
+ }
+
+ if (notification & static_cast<uint16_t>(NotificationSource::wakeupEventRelease)) {
+ KeyEvent keyEvent;
+ /* Implement wakeup event */
+ }
+
+ return out;
+ }
+
+} // namespace bsp::bell_switches
A module-bsp/board/rt1051/bellpx/bsp/switches/switches.hpp => module-bsp/board/rt1051/bellpx/bsp/switches/switches.hpp +26 -0
@@ 0,0 1,26 @@
+// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#pragma once
+
+#include <hal/key_input/KeyEventDefinitions.hpp>
+
+#include <cstdint>
+#include <vector>
+
+namespace bsp::bell_switches
+{
+ std::vector<KeyEvent> getKeyEvents(KeyNotificationSource notification);
+
+ std::int32_t init(xQueueHandle qHandle);
+
+ std::int32_t deinit();
+
+ void enableIRQ();
+
+ void disableIRQ();
+
+ BaseType_t IRQHandler(uint32_t mask);
+
+ BaseType_t wakeupIRQHandler();
+} // namespace bsp::bell_switches
M module-bsp/board/rt1051/bellpx/hal/key_input/KeyInput.cpp => module-bsp/board/rt1051/bellpx/hal/key_input/KeyInput.cpp +15 -10
@@ 4,6 4,8 @@
#include "KeyInput.hpp"
#include <hal/GenericFactory.hpp>
+#include <bsp/switches/switches.hpp>
+#include <board/BoardDefinitions.hpp>
namespace hal::key_input
{
@@ 12,25 14,28 @@ namespace hal::key_input
return hal::impl::factory<KeyInput, AbstractKeyInput>();
}
- void KeyInput::init(xQueueHandle)
- {}
+ void KeyInput::init(xQueueHandle queueHandle)
+ {
+ bsp::bell_switches::init(queueHandle);
+ }
void KeyInput::deinit()
- {}
-
- std::vector<bsp::KeyEvent> KeyInput::getKeyEvents(std::uint8_t)
{
- return std::vector<bsp::KeyEvent>{};
+ bsp::bell_switches::deinit();
}
- BaseType_t generalIRQHandler()
+ std::vector<bsp::KeyEvent> KeyInput::getKeyEvents(KeyNotificationSource notification)
{
- return 0;
+ return bsp::bell_switches::getKeyEvents(notification);
}
- BaseType_t rightFunctionalIRQHandler()
+ BaseType_t generalIRQHandler(std::uint32_t irqMask)
{
- return 0;
+ return bsp::bell_switches::IRQHandler(irqMask);
}
+ BaseType_t wakeupIRQHandler()
+ {
+ return bsp::bell_switches::wakeupIRQHandler();
+ }
} // namespace hal::key_input
M module-bsp/board/rt1051/bellpx/hal/key_input/KeyInput.hpp => module-bsp/board/rt1051/bellpx/hal/key_input/KeyInput.hpp +3 -1
@@ 12,6 12,8 @@ namespace hal::key_input
public:
void init(xQueueHandle) final;
void deinit() final;
- std::vector<bsp::KeyEvent> getKeyEvents(std::uint8_t) final;
+ std::vector<bsp::KeyEvent> getKeyEvents(KeyNotificationSource) final;
+
+ BaseType_t wakeupIRQHandler();
};
} // namespace hal::key_input
M module-bsp/board/rt1051/bellpx/irq_gpio.cpp => module-bsp/board/rt1051/bellpx/irq_gpio.cpp +30 -7
@@ 2,6 2,7 @@
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include "board/irq_gpio.hpp"
+#include <module-utils/Utils.hpp>
#include "board.h"
#include "FreeRTOS.h"
@@ 10,7 11,7 @@
#include "board/rt1051/bsp/eink/bsp_eink.h"
#include <hal/battery_charger/AbstractBatteryCharger.hpp>
-#include <hal/key_input/AbstractKeyInput.hpp>
+#include <hal/key_input/KeyInput.hpp>
#include "board/BoardDefinitions.hpp"
#include "bsp/light_sensor/light_sensor.hpp"
@@ 24,15 25,18 @@ namespace bsp
DisableIRQ(GPIO2_Combined_0_15_IRQn);
DisableIRQ(GPIO2_Combined_16_31_IRQn);
DisableIRQ(GPIO3_Combined_16_31_IRQn);
+ DisableIRQ(GPIO5_Combined_0_15_IRQn);
GPIO_PortDisableInterrupts(GPIO1, UINT32_MAX);
GPIO_PortDisableInterrupts(GPIO2, UINT32_MAX);
GPIO_PortDisableInterrupts(GPIO3, UINT32_MAX);
+ GPIO_PortClearInterruptFlags(GPIO5, UINT32_MAX);
// Clear all IRQs
GPIO_PortClearInterruptFlags(GPIO1, UINT32_MAX);
GPIO_PortClearInterruptFlags(GPIO2, UINT32_MAX);
GPIO_PortClearInterruptFlags(GPIO3, UINT32_MAX);
+ GPIO_PortClearInterruptFlags(GPIO5, UINT32_MAX);
EnableIRQ(GPIO1_Combined_0_15_IRQn);
NVIC_SetPriority(GPIO1_Combined_0_15_IRQn, configLIBRARY_LOWEST_INTERRUPT_PRIORITY);
@@ 48,6 52,9 @@ namespace bsp
EnableIRQ(GPIO3_Combined_16_31_IRQn);
NVIC_SetPriority(GPIO3_Combined_16_31_IRQn, configLIBRARY_LOWEST_INTERRUPT_PRIORITY);
+
+ EnableIRQ(GPIO5_Combined_0_15_IRQn);
+ NVIC_SetPriority(GPIO5_Combined_0_15_IRQn, configLIBRARY_LOWEST_INTERRUPT_PRIORITY);
}
extern "C"
@@ 90,10 97,6 @@ namespace bsp
xHigherPriorityTaskWoken |= hal::battery::IRQHandler();
}
- if (irq_mask & (1 << static_cast<uint32_t>(BoardDefinitions::LIGHT_SENSOR_IRQ))) {
- xHigherPriorityTaskWoken |= bsp::light_sensor::IRQHandler();
- }
-
// Clear all IRQs
GPIO_PortClearInterruptFlags(GPIO2, irq_mask);
@@ 106,8 109,11 @@ namespace bsp
BaseType_t xHigherPriorityTaskWoken = 0;
uint32_t irq_mask = GPIO_GetPinsInterruptFlags(GPIO2);
- if (irq_mask & (1 << BOARD_KEYBOARD_IRQ_GPIO_PIN)) {
- xHigherPriorityTaskWoken |= hal::key_input::generalIRQHandler();
+ if (irq_mask & ((1 << static_cast<uint32_t>(BoardDefinitions::BELL_SWITCHES_CENTER)) |
+ (1 << static_cast<uint32_t>(BoardDefinitions::BELL_SWITCHES_RIGHT)) |
+ (1 << static_cast<uint32_t>(BoardDefinitions::BELL_SWITCHES_LEFT)) |
+ (1 << static_cast<uint32_t>(BoardDefinitions::BELL_SWITCHES_LATCH)))) {
+ xHigherPriorityTaskWoken |= hal::key_input::generalIRQHandler(irq_mask);
}
// Clear all IRQs
@@ 133,5 139,22 @@ namespace bsp
// Switch context if necessary
portEND_SWITCHING_ISR(xHigherPriorityTaskWoken);
}
+
+ void GPIO5_Combined_0_15_IRQHandler(void)
+ {
+ BaseType_t xHigherPriorityTaskWoken = 0;
+ uint32_t irq_mask = GPIO_GetPinsInterruptFlags(GPIO5);
+
+ if (irq_mask & (1 << static_cast<uint32_t>(BoardDefinitions::BELL_WAKEUP))) {
+
+ xHigherPriorityTaskWoken |= hal::key_input::wakeupIRQHandler();
+ }
+
+ // Clear all IRQs on the GPIO5 port
+ GPIO_PortClearInterruptFlags(GPIO5, irq_mask);
+
+ // Switch context if necessary
+ portEND_SWITCHING_ISR(xHigherPriorityTaskWoken);
+ }
}
} // namespace bsp
M module-bsp/board/rt1051/bellpx/pin_mux.c => module-bsp/board/rt1051/bellpx/pin_mux.c +22 -9
@@ 304,6 304,7 @@ void PINMUX_InitBootPins(void)
PINMUX_InitButtons();
PINMUX_InitRotaryEncoder();
PINMUX_DomeSwitch();
+ PINMUX_Wakeup();
PINMUX_WDOG_B_Init();
PINMUX_InitI2C4();
}
@@ 1125,6 1126,8 @@ void PINMUX_InitEinkFrontlight(void)
void PINMUX_InitButtons(void)
{
+ CLOCK_EnableClock(kCLOCK_Iomuxc);
+
IOMUXC_SetPinMux(PINMUX_BUTTON_SW1, 0U); /* Software Input On Field: Input Path is determined by functionality */
IOMUXC_SetPinMux(PINMUX_BUTTON_SW2, 0U); /* Software Input On Field: Input Path is determined by functionality */
@@ 1135,24 1138,22 @@ void PINMUX_InitButtons(void)
0U); /* Software Input On Field: Input Path is determined by functionality */
IOMUXC_SetPinConfig(PINMUX_BUTTON_SW1,
-
PAD_CONFIG_SLEW_RATE_SLOW | PAD_CONFIG_DRIVER_DISABLED | PAD_CONFIG_SPEED_SLOW_50MHz |
- PAD_CONFIG_PULL_KEEPER_DISABLED | PAD_CONFIG_SELECT_PULL | PAD_CONFIG_PULL_UP_100kOhm);
+ PAD_CONFIG_PULL_KEEPER_DISABLED | PAD_CONFIG_SELECT_PULL | PAD_CONFIG_PULL_UP_22kOhm);
IOMUXC_SetPinConfig(PINMUX_BUTTON_SW2,
-
PAD_CONFIG_SLEW_RATE_SLOW | PAD_CONFIG_DRIVER_DISABLED | PAD_CONFIG_SPEED_SLOW_50MHz |
- PAD_CONFIG_PULL_KEEPER_DISABLED | PAD_CONFIG_SELECT_PULL | PAD_CONFIG_PULL_UP_100kOhm);
+ PAD_CONFIG_PULL_KEEPER_DISABLED | PAD_CONFIG_SELECT_PULL | PAD_CONFIG_PULL_UP_22kOhm);
IOMUXC_SetPinConfig(PINMUX_BUTTON_SW_ENC,
-
PAD_CONFIG_SLEW_RATE_SLOW | PAD_CONFIG_DRIVER_DISABLED | PAD_CONFIG_SPEED_SLOW_50MHz |
- PAD_CONFIG_PULL_KEEPER_DISABLED | PAD_CONFIG_SELECT_PULL | PAD_CONFIG_PULL_UP_100kOhm);
+ PAD_CONFIG_DRIVER_STRENGTH_LVL_6 | PAD_CONFIG_PULL_KEEPER_ENABLED | PAD_CONFIG_SELECT_PULL |
+ PAD_CONFIG_PULL_UP_100kOhm);
IOMUXC_SetPinConfig(PINMUX_BUTTON_SW_PUSH,
-
PAD_CONFIG_SLEW_RATE_SLOW | PAD_CONFIG_DRIVER_DISABLED | PAD_CONFIG_SPEED_SLOW_50MHz |
- PAD_CONFIG_PULL_KEEPER_DISABLED | PAD_CONFIG_SELECT_PULL | PAD_CONFIG_PULL_UP_100kOhm);
+ PAD_CONFIG_PULL_KEEPER_ENABLED | PAD_CONFIG_SELECT_PULL | PAD_CONFIG_PULL_UP_22kOhm |
+ PAD_CONFIG_HYSTERESIS_ENABLED);
}
void PINMUX_InitRotaryEncoder(void)
@@ 1174,7 1175,7 @@ void PINMUX_InitRotaryEncoder(void)
void PINMUX_DomeSwitch(void)
{
- IOMUXC_SetPinMux(PINMUX_DOME_SWITCH, 0U); /* Software Input On Field: Input Path is determined by functionality */
+ IOMUXC_SetPinMux(PINMUX_DOME_SWITCH, 1U); /* Software Input On Field: Input Path is determined by functionality */
IOMUXC_SetPinConfig(PINMUX_DOME_SWITCH,
@@ 1225,6 1226,18 @@ void PINMUX_InitI2C4(void)
PAD_CONFIG_SELECT_KEEPER | PAD_CONFIG_PULL_UP_22kOhm);
}
+void PINMUX_Wakeup(void)
+{
+ CLOCK_EnableClock(kCLOCK_IomuxcSnvs);
+
+ IOMUXC_SetPinMux(PINMUX_WAKEUP, 1U); /* Software Input On Field: Input Path is determined by functionality */
+
+ IOMUXC_SetPinConfig(PINMUX_WAKEUP,
+
+ PAD_CONFIG_SLEW_RATE_SLOW | PAD_CONFIG_DRIVER_DISABLED | PAD_CONFIG_SPEED_SLOW_50MHz |
+ PAD_CONFIG_PULL_KEEPER_DISABLED | PAD_CONFIG_SELECT_PULL | PAD_CONFIG_PULL_UP_100kOhm);
+}
+
/***********************************************************************************************************************
* EOF
**********************************************************************************************************************/
M module-bsp/board/rt1051/puretx/CMakeLists.txt => module-bsp/board/rt1051/puretx/CMakeLists.txt +1 -1
@@ 11,7 11,7 @@ target_sources(
PRIVATE
hal/battery_charger/BatteryCharger.cpp
- hal/key_input/KeyInput.cpp
+ hal/key_input/KeyInput.cpp
bsp/battery_charger/battery_charger.cpp
bsp/eink/eink_pin_config.cpp
bsp/keyboard/keyboard.cpp
M module-bsp/board/rt1051/puretx/bsp/keyboard/keyboard.cpp => module-bsp/board/rt1051/puretx/bsp/keyboard/keyboard.cpp +1 -1
@@ 203,7 203,7 @@ namespace bsp::keyboard
return kStatus_Success;
}
- std::vector<KeyEvent> getKeyEvents(std::uint8_t notification)
+ std::vector<KeyEvent> getKeyEvents(KeyNotificationSource notification)
{
std::vector<KeyEvent> out;
if (notification & static_cast<std::uint8_t>(NotificationSource::regularKey)) {
M module-bsp/board/rt1051/puretx/bsp/keyboard/keyboard.hpp => module-bsp/board/rt1051/puretx/bsp/keyboard/keyboard.hpp +1 -1
@@ 10,7 10,7 @@
namespace bsp::keyboard
{
- std::vector<KeyEvent> getKeyEvents(std::uint8_t notification);
+ std::vector<KeyEvent> getKeyEvents(KeyNotificationSource notification);
std::int32_t init(xQueueHandle qHandle);
M module-bsp/board/rt1051/puretx/hal/key_input/KeyInput.cpp => module-bsp/board/rt1051/puretx/hal/key_input/KeyInput.cpp +2 -2
@@ 23,12 23,12 @@ namespace hal::key_input
bsp::keyboard::deinit();
}
- std::vector<bsp::KeyEvent> KeyInput::getKeyEvents(std::uint8_t notification)
+ std::vector<bsp::KeyEvent> KeyInput::getKeyEvents(KeyNotificationSource notification)
{
return bsp::keyboard::getKeyEvents(notification);
}
- BaseType_t generalIRQHandler()
+ BaseType_t generalIRQHandler(std::uint32_t irqMask)
{
return bsp::keyboard::IRQHandler();
}
M module-bsp/board/rt1051/puretx/hal/key_input/KeyInput.hpp => module-bsp/board/rt1051/puretx/hal/key_input/KeyInput.hpp +1 -1
@@ 12,6 12,6 @@ namespace hal::key_input
public:
void init(xQueueHandle queueHandle) final;
void deinit() final;
- std::vector<bsp::KeyEvent> getKeyEvents(std::uint8_t) final;
+ std::vector<bsp::KeyEvent> getKeyEvents(KeyNotificationSource) final;
};
} // namespace hal::key_input
M module-bsp/board/rt1051/puretx/irq_gpio.cpp => module-bsp/board/rt1051/puretx/irq_gpio.cpp +2 -2
@@ 10,7 10,7 @@
#include "board/rt1051/bsp/eink/bsp_eink.h"
#include <hal/battery_charger/AbstractBatteryCharger.hpp>
-#include <hal/key_input/AbstractKeyInput.hpp>
+#include <hal/key_input/KeyInput.hpp>
#include "bsp/cellular/bsp_cellular.hpp"
#include "bsp/headset/headset.hpp"
#include "board/BoardDefinitions.hpp"
@@ 142,7 142,7 @@ namespace bsp
uint32_t irq_mask = GPIO_GetPinsInterruptFlags(GPIO2);
if (irq_mask & (1 << BOARD_KEYBOARD_IRQ_GPIO_PIN)) {
- xHigherPriorityTaskWoken |= hal::key_input::generalIRQHandler();
+ xHigherPriorityTaskWoken |= hal::key_input::generalIRQHandler(irq_mask);
}
if (irq_mask & (1 << BOARD_USBC_NINT_PIN)) {
M module-bsp/hal/key_input/AbstractKeyInput.hpp => module-bsp/hal/key_input/AbstractKeyInput.hpp +6 -5
@@ 4,6 4,7 @@
#pragma once
#include "KeyEventDefinitions.hpp"
+
#include <FreeRTOS.h>
#include <queue.h>
@@ 22,12 23,12 @@ namespace hal::key_input
virtual ~AbstractKeyInput() = default;
- virtual void init(xQueueHandle) = 0;
- virtual void deinit() = 0;
- virtual std::vector<bsp::KeyEvent> getKeyEvents(std::uint8_t) = 0;
+ virtual void init(xQueueHandle) = 0;
+ virtual void deinit() = 0;
+ virtual std::vector<bsp::KeyEvent> getKeyEvents(KeyNotificationSource) = 0;
};
- BaseType_t generalIRQHandler();
+ BaseType_t generalIRQHandler(std::uint32_t irqMask);
BaseType_t rightFunctionalIRQHandler();
-
+ BaseType_t wakeupIRQHandler();
} // namespace hal::key_input
M module-bsp/hal/key_input/KeyEventDefinitions.hpp => module-bsp/hal/key_input/KeyEventDefinitions.hpp +3 -2
@@ 5,9 5,10 @@
#include <magic_enum.hpp>
+using KeyNotificationSource = uint16_t;
+
namespace bsp
{
-
enum class KeyCodes
{
Undefined = 0,
@@ 44,7 45,7 @@ namespace bsp
HeadsetOk = 71,
HeadsetVolUp = 72,
- HeadsetVolDown = 73
+ HeadsetVolDown = 73,
};
enum class KeyEvents
M products/BellHybrid/keymap/include/keymap/KeyMap.hpp => products/BellHybrid/keymap/include/keymap/KeyMap.hpp +1 -0
@@ 9,6 9,7 @@
/// GUI design
enum class KeyMap
{
+ Frontlight = static_cast<int>(gui::KeyCode::KEY_LF),
Back = static_cast<int>(gui::KeyCode::KEY_RF),
LightPress = static_cast<int>(gui::KeyCode::KEY_ENTER),
RotateLeft = static_cast<int>(gui::KeyCode::KEY_DOWN),