C
Qt Quick Ultralite Automotive Cluster Demo
// Copyright (C) 2024 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial
#include "hmi_input.h"
#include "r_typedefs.h"
#include "r_gpio_api.h"
#include "r_bsp_hmi_knob.h"
#include "r_bsp_hmi_api.h"
template<HMIInputEvent::Type type, HMIInputEvent::Key keyCode>
static void keyEventHandler()
{
HMIInput::instance().postEvent(HMIInputEvent(keyCode, type));
}
static void qulButtonLeftAction(void)
{
uint8_t level = R_GPIO_ReadIntPin(BSP_BTN_LEFT_INTP);
// The buttons are low-active
if (level == 0u) {
R_BSP_BtnAction(BSP_BTN_LEFT_PRESS);
} else {
R_BSP_BtnAction(BSP_BTN_LEFT_RELEASE);
}
}
static void qulButtonUpAction(void)
{
uint8_t level = R_GPIO_ReadIntPin(BSP_BTN_UP_INTP);
if (level == 0u) {
R_BSP_BtnAction(BSP_BTN_UP_PRESS);
} else {
R_BSP_BtnAction(BSP_BTN_UP_RELEASE);
}
}
#if USE_FOUT_INSTEAD_BSP_BTN_DOWN != 1
static void qulButtonDownAction(void)
{
uint8_t level = R_GPIO_ReadIntPin(BSP_BTN_DOWN_INTP);
if (level == 0u) {
R_BSP_BtnAction(BSP_BTN_DOWN_PRESS);
} else {
R_BSP_BtnAction(BSP_BTN_DOWN_RELEASE);
}
}
#endif // USE_FOUT_INSTEAD_BSP_BTN_DOWN
static void qulButtonRightAction(void)
{
uint8_t level = R_GPIO_ReadIntPin(BSP_BTN_RIGHT_INTP);
if (level == 0u) {
R_BSP_BtnAction(BSP_BTN_RIGHT_PRESS);
} else {
R_BSP_BtnAction(BSP_BTN_RIGHT_RELEASE);
}
}
static void qulButtonCenterAction(void)
{
uint8_t level = R_GPIO_ReadIntPin(BSP_BTN_CENTER_INTP);
if (level == 0u) {
R_BSP_BtnAction(BSP_BTN_CENTER_PRESS);
} else {
R_BSP_BtnAction(BSP_BTN_CENTER_RELEASE);
}
}
static void overrideButtonActions()
{
//Disable interrupts
R_GPIO_DeInitInt(BSP_BTN_LEFT_INTP);
R_GPIO_DeInitInt(BSP_BTN_UP_INTP);
#if USE_FOUT_INSTEAD_BSP_BTN_DOWN != 1
R_GPIO_DeInitInt(BSP_BTN_DOWN_INTP);
#endif /* USE_FOUT_INSTEAD_BSP_BTN_DOWN */
R_GPIO_DeInitInt(BSP_BTN_RIGHT_INTP);
R_GPIO_DeInitInt(BSP_BTN_CENTER_INTP);
//Assign custom buttons actions
r_gpio_IntConfig_t cfg;
cfg.Port = BSP_BTN_LEFT_PORT;
cfg.Pin = BSP_BTN_LEFT_PIN;
cfg.Trigger = R_GPIO_INT_BOTH_EDGES;
cfg.Callback = &qulButtonLeftAction;
R_GPIO_InitInt(BSP_BTN_LEFT_INTP, &cfg);
cfg.Port = BSP_BTN_UP_PORT;
cfg.Pin = BSP_BTN_UP_PIN;
cfg.Trigger = R_GPIO_INT_BOTH_EDGES;
cfg.Callback = &qulButtonUpAction;
R_GPIO_InitInt(BSP_BTN_UP_INTP, &cfg);
#if USE_FOUT_INSTEAD_BSP_BTN_DOWN != 1
cfg.Port = BSP_BTN_DOWN_PORT;
cfg.Pin = BSP_BTN_DOWN_PIN;
cfg.Trigger = R_GPIO_INT_BOTH_EDGES;
cfg.Callback = &qulButtonDownAction;
R_GPIO_InitInt(BSP_BTN_DOWN_INTP, &cfg);
#endif /* USE_FOUT_INSTEAD_BSP_BTN_DOWN */
cfg.Port = BSP_BTN_RIGHT_PORT;
cfg.Pin = BSP_BTN_RIGHT_PIN;
cfg.Trigger = R_GPIO_INT_BOTH_EDGES;
cfg.Callback = &qulButtonRightAction;
R_GPIO_InitInt(BSP_BTN_RIGHT_INTP, &cfg);
cfg.Port = BSP_BTN_CENTER_PORT;
cfg.Pin = BSP_BTN_CENTER_PIN;
cfg.Trigger = R_GPIO_INT_BOTH_EDGES;
cfg.Callback = &qulButtonCenterAction;
R_GPIO_InitInt(BSP_BTN_CENTER_INTP, &cfg);
//Enable interrupts
R_GPIO_EnableInt(BSP_BTN_LEFT_INTP);
R_GPIO_EnableInt(BSP_BTN_UP_INTP);
#if USE_FOUT_INSTEAD_BSP_BTN_DOWN != 1
R_GPIO_EnableInt(BSP_BTN_DOWN_INTP);
#endif /* USE_FOUT_INSTEAD_BSP_BTN_DOWN */
R_GPIO_EnableInt(BSP_BTN_RIGHT_INTP);
R_GPIO_EnableInt(BSP_BTN_CENTER_INTP);
}
static void hmiInputInit()
{
R_BSP_HMI_Init();
overrideButtonActions();
R_BSP_SetButtonCallback(BSP_BTN_UP_PRESS, keyEventHandler<HMIInputEvent::KeyPress, HMIInputEvent::HMI_BTN_UP>);
R_BSP_SetButtonCallback(BSP_BTN_UP_RELEASE, keyEventHandler<HMIInputEvent::KeyRelease, HMIInputEvent::HMI_BTN_UP>);
R_BSP_SetButtonCallback(BSP_BTN_DOWN_PRESS, keyEventHandler<HMIInputEvent::KeyPress, HMIInputEvent::HMI_BTN_DOWN>);
R_BSP_SetButtonCallback(BSP_BTN_DOWN_RELEASE,
keyEventHandler<HMIInputEvent::KeyRelease, HMIInputEvent::HMI_BTN_DOWN>);
R_BSP_SetButtonCallback(BSP_BTN_LEFT_PRESS, keyEventHandler<HMIInputEvent::KeyPress, HMIInputEvent::HMI_BTN_LEFT>);
R_BSP_SetButtonCallback(BSP_BTN_LEFT_RELEASE,
keyEventHandler<HMIInputEvent::KeyRelease, HMIInputEvent::HMI_BTN_LEFT>);
R_BSP_SetButtonCallback(BSP_BTN_RIGHT_PRESS, keyEventHandler<HMIInputEvent::KeyPress, HMIInputEvent::HMI_BTN_RIGHT>);
R_BSP_SetButtonCallback(BSP_BTN_RIGHT_RELEASE,
keyEventHandler<HMIInputEvent::KeyRelease, HMIInputEvent::HMI_BTN_RIGHT>);
R_BSP_SetButtonCallback(BSP_BTN_CENTER_PRESS,
keyEventHandler<HMIInputEvent::KeyPress, HMIInputEvent::HMI_BTN_CENTER>);
R_BSP_SetButtonCallback(BSP_BTN_CENTER_RELEASE,
keyEventHandler<HMIInputEvent::KeyRelease, HMIInputEvent::HMI_BTN_CENTER>);
// The knob alternates between sending left and right turn events
// no matter which way you turn it, so let's just send BTN_LEFT_TURN events
// to make it sort of useful.
R_BSP_SetButtonCallback(BSP_BTN_LEFT_TURN,
keyEventHandler<HMIInputEvent::KeyRelease, HMIInputEvent::HMI_KNOB_TURN_RIGHT>);
R_BSP_SetButtonCallback(BSP_BTN_RIGHT_TURN,
keyEventHandler<HMIInputEvent::KeyRelease, HMIInputEvent::HMI_KNOB_TURN_RIGHT>);
R_BSP_SetButtonCallback(BSP_BTN_OK_PRESS, keyEventHandler<HMIInputEvent::KeyPress, HMIInputEvent::HMI_KNOB_CENTER>);
R_BSP_SetButtonCallback(BSP_BTN_OK_RELEASE,
keyEventHandler<HMIInputEvent::KeyRelease, HMIInputEvent::HMI_KNOB_CENTER>);
}
extern void (*hmiInputInitRoutine)();
static struct Init
{
Init() { hmiInputInitRoutine = hmiInputInit; }
} init;