Compare commits
2 Commits
39d2962258
...
2f6126da96
| Author | SHA1 | Date | |
|---|---|---|---|
| 2f6126da96 | |||
| 76adb3584c |
@@ -17,9 +17,11 @@ target_sources(app PRIVATE
|
|||||||
src/ble_adv_uuid16.c
|
src/ble_adv_uuid16.c
|
||||||
src/ble_bas_module.c
|
src/ble_bas_module.c
|
||||||
src/ble_hid_module.c
|
src/ble_hid_module.c
|
||||||
|
src/display_module.c
|
||||||
src/encoder_module.c
|
src/encoder_module.c
|
||||||
src/hid_flowctrl_module.c
|
src/hid_flowctrl_module.c
|
||||||
src/keyboard_core_module.c
|
src/keyboard_core_module.c
|
||||||
|
src/ui/ui_main.c
|
||||||
src/usb_hid_module.c
|
src/usb_hid_module.c
|
||||||
src/events/bat_state_event.c
|
src/events/bat_state_event.c
|
||||||
src/events/encoder_event.c
|
src/events/encoder_event.c
|
||||||
|
|||||||
@@ -30,4 +30,32 @@
|
|||||||
bias-pull-up;
|
bias-pull-up;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
spi3_default: spi3_default {
|
||||||
|
group1 {
|
||||||
|
psels = <NRF_PSEL(SPIM_SCK, 1, 13)>,
|
||||||
|
<NRF_PSEL(SPIM_MOSI, 0, 28)>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
spi3_sleep: spi3_sleep {
|
||||||
|
group1 {
|
||||||
|
psels = <NRF_PSEL(SPIM_SCK, 1, 13)>,
|
||||||
|
<NRF_PSEL(SPIM_MOSI, 0, 28)>;
|
||||||
|
low-power-enable;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
pwm0_default: pwm0_default {
|
||||||
|
group1 {
|
||||||
|
psels = <NRF_PSEL(PWM_OUT0, 1, 11)>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
pwm0_sleep: pwm0_sleep {
|
||||||
|
group1 {
|
||||||
|
psels = <NRF_PSEL(PWM_OUT0, 1, 11)>;
|
||||||
|
low-power-enable;
|
||||||
|
};
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
#include <nordic/nrf52840_qiaa.dtsi>
|
#include <nordic/nrf52840_qiaa.dtsi>
|
||||||
#include "mini_keyboard-pinctrl.dtsi"
|
#include "mini_keyboard-pinctrl.dtsi"
|
||||||
#include <zephyr/dt-bindings/adc/adc.h>
|
#include <zephyr/dt-bindings/adc/adc.h>
|
||||||
|
#include <zephyr/dt-bindings/mipi_dbi/mipi_dbi.h>
|
||||||
|
#include <zephyr/dt-bindings/pwm/pwm.h>
|
||||||
|
|
||||||
/ {
|
/ {
|
||||||
model = "Mini keyboard";
|
model = "Mini keyboard";
|
||||||
@@ -11,11 +13,13 @@
|
|||||||
zephyr,sram = &sram0;
|
zephyr,sram = &sram0;
|
||||||
zephyr,flash = &flash0;
|
zephyr,flash = &flash0;
|
||||||
zephyr,code-partition = &slot0_partition;
|
zephyr,code-partition = &slot0_partition;
|
||||||
|
zephyr,display = &screen_lcd;
|
||||||
};
|
};
|
||||||
|
|
||||||
aliases {
|
aliases {
|
||||||
led0 = &myled0;
|
led0 = &myled0;
|
||||||
qdec0 = &qdec;
|
qdec0 = &qdec;
|
||||||
|
backlight = &backlight;
|
||||||
};
|
};
|
||||||
|
|
||||||
hid_kbd: hid_kbd {
|
hid_kbd: hid_kbd {
|
||||||
@@ -36,12 +40,57 @@
|
|||||||
in-polling-period-us = <1000>;
|
in-polling-period-us = <1000>;
|
||||||
};
|
};
|
||||||
|
|
||||||
leds {
|
leds {
|
||||||
compatible = "gpio-leds";
|
compatible = "gpio-leds";
|
||||||
myled0: led_0 {
|
myled0: led_0 {
|
||||||
gpios = <&gpio1 2 GPIO_ACTIVE_LOW>;
|
gpios = <&gpio1 2 GPIO_ACTIVE_LOW>;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pwm_leds {
|
||||||
|
compatible = "pwm-leds";
|
||||||
|
status = "okay";
|
||||||
|
|
||||||
|
backlight: pwm_led_0 {
|
||||||
|
pwms = <&pwm0 0 PWM_MSEC(10) PWM_POLARITY_INVERTED>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
mipi_dbi_screen: mipi_dbi_screen {
|
||||||
|
compatible = "zephyr,mipi-dbi-spi";
|
||||||
|
spi-dev = <&spi3>;
|
||||||
|
dc-gpios = <&gpio0 3 GPIO_ACTIVE_HIGH>;
|
||||||
|
reset-gpios = <&gpio1 10 GPIO_ACTIVE_LOW>;
|
||||||
|
write-only;
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <0>;
|
||||||
|
|
||||||
|
screen_lcd: st7789v@0 {
|
||||||
|
compatible = "sitronix,st7789v";
|
||||||
|
status = "okay";
|
||||||
|
reg = <0>;
|
||||||
|
mipi-max-frequency = <32000000>;
|
||||||
|
width = <320>;
|
||||||
|
height = <172>;
|
||||||
|
x-offset = <0>;
|
||||||
|
y-offset = <34>;
|
||||||
|
vcom = <0x34>;
|
||||||
|
gctrl = <0x00>;
|
||||||
|
mdac = <0xA0>;
|
||||||
|
gamma = <0x01>;
|
||||||
|
colmod = <0x05>;
|
||||||
|
lcm = <0x2c>;
|
||||||
|
porch-param = [ 0c 0c 00 33 33 ];
|
||||||
|
cmd2en-param = [ 5a 69 02 01 ];
|
||||||
|
pwctrl1-param = [ a4 a1 ];
|
||||||
|
pvgam-param = [ f0 04 08 0a 0a 05 25 33 3c 24 0e 0f 27 2f ];
|
||||||
|
nvgam-param = [ f0 02 06 06 04 22 25 32 3b 3a 15 17 2d 37 ];
|
||||||
|
ram-param = [ 00 f0 ];
|
||||||
|
rgb-param = [ cd 08 14 ];
|
||||||
|
ready-time-ms = <120>;
|
||||||
|
mipi-mode = "MIPI_DBI_MODE_SPI_4WIRE";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
vbatt: vbatt {
|
vbatt: vbatt {
|
||||||
compatible = "voltage-divider";
|
compatible = "voltage-divider";
|
||||||
@@ -90,6 +139,7 @@
|
|||||||
|
|
||||||
&uicr {
|
&uicr {
|
||||||
nfct-pins-as-gpios;
|
nfct-pins-as-gpios;
|
||||||
|
gpio-as-nreset;
|
||||||
};
|
};
|
||||||
|
|
||||||
&adc {
|
&adc {
|
||||||
@@ -148,6 +198,21 @@
|
|||||||
status = "okay";
|
status = "okay";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
&spi3 {
|
||||||
|
status = "okay";
|
||||||
|
pinctrl-0 = <&spi3_default>;
|
||||||
|
pinctrl-1 = <&spi3_sleep>;
|
||||||
|
pinctrl-names = "default", "sleep";
|
||||||
|
cs-gpios = <&gpio0 2 GPIO_ACTIVE_LOW>;
|
||||||
|
};
|
||||||
|
|
||||||
|
&pwm0 {
|
||||||
|
status = "okay";
|
||||||
|
pinctrl-0 = <&pwm0_default>;
|
||||||
|
pinctrl-1 = <&pwm0_sleep>;
|
||||||
|
pinctrl-names = "default", "sleep";
|
||||||
|
};
|
||||||
|
|
||||||
&qdec {
|
&qdec {
|
||||||
status = "okay";
|
status = "okay";
|
||||||
pinctrl-0 = <&encoder_default>;
|
pinctrl-0 = <&encoder_default>;
|
||||||
|
|||||||
15
inc/click_detector_def.h
Normal file
15
inc/click_detector_def.h
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
/*
|
||||||
|
* This configuration file is included only once from the CAF click detector
|
||||||
|
* module and defines the keys that should produce click events.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <caf/click_detector.h>
|
||||||
|
|
||||||
|
const struct {} click_detector_def_include_once;
|
||||||
|
|
||||||
|
static const struct click_detector_config click_detector_config[] = {
|
||||||
|
{
|
||||||
|
.key_id = 0x180,
|
||||||
|
.consume_button_event = true,
|
||||||
|
},
|
||||||
|
};
|
||||||
27
prj.conf
27
prj.conf
@@ -1,8 +1,13 @@
|
|||||||
CONFIG_CAF=y
|
CONFIG_CAF=y
|
||||||
CONFIG_CAF_BUTTONS=y
|
CONFIG_CAF_BUTTONS=y
|
||||||
CONFIG_CAF_BUTTONS_DEF_PATH="buttons_def.h"
|
CONFIG_CAF_BUTTONS_DEF_PATH="buttons_def.h"
|
||||||
|
CONFIG_CAF_CLICK_DETECTOR=y
|
||||||
|
CONFIG_CAF_CLICK_DETECTOR_DEF_PATH="click_detector_def.h"
|
||||||
CONFIG_GPIO=y
|
CONFIG_GPIO=y
|
||||||
CONFIG_I2C=y
|
CONFIG_I2C=y
|
||||||
|
CONFIG_LED=y
|
||||||
|
CONFIG_PWM=y
|
||||||
|
CONFIG_SPI=y
|
||||||
CONFIG_NRFX_RTC2=y
|
CONFIG_NRFX_RTC2=y
|
||||||
CONFIG_NRFX_GPPI=y
|
CONFIG_NRFX_GPPI=y
|
||||||
CONFIG_NRFX_QDEC=y
|
CONFIG_NRFX_QDEC=y
|
||||||
@@ -10,6 +15,9 @@ CONFIG_PINCTRL_DYNAMIC=y
|
|||||||
CONFIG_REBOOT=y
|
CONFIG_REBOOT=y
|
||||||
CONFIG_SENSOR=y
|
CONFIG_SENSOR=y
|
||||||
CONFIG_ADC=y
|
CONFIG_ADC=y
|
||||||
|
CONFIG_DISPLAY=y
|
||||||
|
CONFIG_DISPLAY_LOG_LEVEL_ERR=y
|
||||||
|
CONFIG_MIPI_DBI_LOG_LEVEL_ERR=y
|
||||||
CONFIG_SETTINGS=y
|
CONFIG_SETTINGS=y
|
||||||
CONFIG_SETTINGS_NVS=y
|
CONFIG_SETTINGS_NVS=y
|
||||||
CONFIG_FLASH=y
|
CONFIG_FLASH=y
|
||||||
@@ -78,8 +86,27 @@ CONFIG_CAF_BLE_ADV_FAST_ADV=y
|
|||||||
CONFIG_CAF_BLE_ADV_FILTER_ACCEPT_LIST=y
|
CONFIG_CAF_BLE_ADV_FILTER_ACCEPT_LIST=y
|
||||||
CONFIG_CAF_BLE_ADV_MODULE_SUSPEND_EVENTS=y
|
CONFIG_CAF_BLE_ADV_MODULE_SUSPEND_EVENTS=y
|
||||||
CONFIG_CAF_BLE_BOND=y
|
CONFIG_CAF_BLE_BOND=y
|
||||||
|
CONFIG_CAF_BLE_BOND_PEER_ERASE_CLICK=y
|
||||||
|
CONFIG_CAF_BLE_BOND_PEER_ERASE_CLICK_KEY_ID=0x180
|
||||||
|
CONFIG_CAF_BLE_BOND_PEER_ERASE_CLICK_LONG=y
|
||||||
|
CONFIG_CAF_BLE_BOND_PEER_ERASE_CLICK_TIMEOUT=-1
|
||||||
CONFIG_CAF_MODULE_SUSPEND_EVENTS=y
|
CONFIG_CAF_MODULE_SUSPEND_EVENTS=y
|
||||||
CONFIG_BT_ADV_PROV_FLAGS=y
|
CONFIG_BT_ADV_PROV_FLAGS=y
|
||||||
CONFIG_BT_ADV_PROV_GAP_APPEARANCE=y
|
CONFIG_BT_ADV_PROV_GAP_APPEARANCE=y
|
||||||
CONFIG_BT_ADV_PROV_DEVICE_NAME=y
|
CONFIG_BT_ADV_PROV_DEVICE_NAME=y
|
||||||
CONFIG_BT_ADV_PROV_DEVICE_NAME_SD=y
|
CONFIG_BT_ADV_PROV_DEVICE_NAME_SD=y
|
||||||
|
|
||||||
|
# LVGL
|
||||||
|
CONFIG_LVGL=y
|
||||||
|
CONFIG_LV_Z_AUTO_INIT=n
|
||||||
|
CONFIG_LV_Z_RUN_LVGL_ON_WORKQUEUE=y
|
||||||
|
CONFIG_LV_Z_LVGL_MUTEX=y
|
||||||
|
CONFIG_LV_COLOR_DEPTH_16=y
|
||||||
|
CONFIG_LV_COLOR_16_SWAP=y
|
||||||
|
CONFIG_LV_Z_BITS_PER_PIXEL=16
|
||||||
|
CONFIG_LV_Z_VDB_SIZE=25
|
||||||
|
CONFIG_LV_Z_DOUBLE_VDB=y
|
||||||
|
CONFIG_LV_Z_MEM_POOL_SIZE=16384
|
||||||
|
CONFIG_LV_USE_LABEL=y
|
||||||
|
CONFIG_LV_FONT_MONTSERRAT_14=y
|
||||||
|
CONFIG_MAIN_STACK_SIZE=4096
|
||||||
|
|||||||
177
src/display_module.c
Normal file
177
src/display_module.c
Normal file
@@ -0,0 +1,177 @@
|
|||||||
|
#include <errno.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#include <app_event_manager.h>
|
||||||
|
|
||||||
|
#define MODULE display_module
|
||||||
|
#include <caf/events/module_state_event.h>
|
||||||
|
#include <caf/events/power_event.h>
|
||||||
|
|
||||||
|
#include <lvgl_zephyr.h>
|
||||||
|
#include <zephyr/device.h>
|
||||||
|
#include <zephyr/drivers/display.h>
|
||||||
|
#include <zephyr/drivers/led.h>
|
||||||
|
#include <zephyr/logging/log.h>
|
||||||
|
|
||||||
|
#include "ui/ui_main.h"
|
||||||
|
|
||||||
|
LOG_MODULE_REGISTER(MODULE, LOG_LEVEL_INF);
|
||||||
|
|
||||||
|
BUILD_ASSERT(DT_HAS_CHOSEN(zephyr_display), "Missing zephyr,display chosen node");
|
||||||
|
BUILD_ASSERT(DT_NODE_HAS_STATUS(DT_ALIAS(backlight), okay),
|
||||||
|
"Missing backlight alias");
|
||||||
|
|
||||||
|
static const struct device *const display_dev =
|
||||||
|
DEVICE_DT_GET(DT_CHOSEN(zephyr_display));
|
||||||
|
static const struct device *const backlight_dev =
|
||||||
|
DEVICE_DT_GET(DT_PARENT(DT_ALIAS(backlight)));
|
||||||
|
static const uint32_t backlight_idx = DT_NODE_CHILD_IDX(DT_ALIAS(backlight));
|
||||||
|
static bool initialized;
|
||||||
|
static bool running;
|
||||||
|
static bool lvgl_initialized;
|
||||||
|
|
||||||
|
static int backlight_set(bool on)
|
||||||
|
{
|
||||||
|
if (on) {
|
||||||
|
return led_on(backlight_dev, backlight_idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
return led_off(backlight_dev, backlight_idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int module_init(void)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
|
||||||
|
LOG_INF("Display init on %s", display_dev->name);
|
||||||
|
|
||||||
|
if (!device_is_ready(display_dev)) {
|
||||||
|
LOG_ERR("Display device %s not ready", display_dev->name);
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!device_is_ready(backlight_dev)) {
|
||||||
|
LOG_ERR("Backlight device %s not ready", backlight_dev->name);
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = backlight_set(false);
|
||||||
|
if (err) {
|
||||||
|
LOG_ERR("Backlight off failed (%d)", err);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int module_start(void)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
|
||||||
|
if (running) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!lvgl_initialized) {
|
||||||
|
err = lvgl_init();
|
||||||
|
if (err) {
|
||||||
|
LOG_ERR("lvgl_init failed (%d)", err);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
lvgl_initialized = true;
|
||||||
|
|
||||||
|
lvgl_lock();
|
||||||
|
ui_main_init();
|
||||||
|
lvgl_unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
err = backlight_set(true);
|
||||||
|
if (err) {
|
||||||
|
LOG_ERR("Backlight enable failed (%d)", err);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = display_blanking_off(display_dev);
|
||||||
|
if (err) {
|
||||||
|
LOG_ERR("display_blanking_off failed (%d)", err);
|
||||||
|
(void)backlight_set(false);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
running = true;
|
||||||
|
LOG_INF("LVGL display started");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void module_pause(void)
|
||||||
|
{
|
||||||
|
if (!running) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
(void)display_blanking_on(display_dev);
|
||||||
|
(void)backlight_set(false);
|
||||||
|
running = false;
|
||||||
|
LOG_INF("LVGL display paused");
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool app_event_handler(const struct app_event_header *aeh)
|
||||||
|
{
|
||||||
|
if (is_module_state_event(aeh)) {
|
||||||
|
const struct module_state_event *event = cast_module_state_event(aeh);
|
||||||
|
int err;
|
||||||
|
|
||||||
|
if (check_state(event, MODULE_ID(main), MODULE_STATE_READY)) {
|
||||||
|
if (!initialized) {
|
||||||
|
err = module_init();
|
||||||
|
if (err) {
|
||||||
|
module_set_state(MODULE_STATE_ERROR);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
initialized = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = module_start();
|
||||||
|
if (err) {
|
||||||
|
module_set_state(MODULE_STATE_ERROR);
|
||||||
|
} else {
|
||||||
|
module_set_state(MODULE_STATE_READY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_power_down_event(aeh)) {
|
||||||
|
if (initialized) {
|
||||||
|
module_pause();
|
||||||
|
module_set_state(MODULE_STATE_STANDBY);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_wake_up_event(aeh)) {
|
||||||
|
if (initialized) {
|
||||||
|
int err = module_start();
|
||||||
|
|
||||||
|
if (err) {
|
||||||
|
module_set_state(MODULE_STATE_ERROR);
|
||||||
|
} else {
|
||||||
|
module_set_state(MODULE_STATE_READY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
APP_EVENT_LISTENER(MODULE, app_event_handler);
|
||||||
|
APP_EVENT_SUBSCRIBE(MODULE, module_state_event);
|
||||||
|
APP_EVENT_SUBSCRIBE_EARLY(MODULE, power_down_event);
|
||||||
|
APP_EVENT_SUBSCRIBE(MODULE, wake_up_event);
|
||||||
34
src/ui/ui_main.c
Normal file
34
src/ui/ui_main.c
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#include <lvgl.h>
|
||||||
|
|
||||||
|
#include "ui_main.h"
|
||||||
|
|
||||||
|
static bool ui_initialized;
|
||||||
|
|
||||||
|
void ui_main_init(void)
|
||||||
|
{
|
||||||
|
lv_obj_t *screen;
|
||||||
|
lv_obj_t *title;
|
||||||
|
lv_obj_t *subtitle;
|
||||||
|
|
||||||
|
if (ui_initialized) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
screen = lv_screen_active();
|
||||||
|
lv_obj_set_style_bg_color(screen, lv_color_hex(0x101418), 0);
|
||||||
|
lv_obj_set_style_text_color(screen, lv_color_hex(0xF5F7FA), 0);
|
||||||
|
|
||||||
|
title = lv_label_create(screen);
|
||||||
|
lv_label_set_text(title, "Hello World");
|
||||||
|
lv_obj_set_style_text_font(title, &lv_font_montserrat_14, 0);
|
||||||
|
lv_obj_align(title, LV_ALIGN_CENTER, 0, -10);
|
||||||
|
|
||||||
|
subtitle = lv_label_create(screen);
|
||||||
|
lv_label_set_text(subtitle, "WH Mini Keyboard");
|
||||||
|
lv_obj_set_style_text_opa(subtitle, LV_OPA_70, 0);
|
||||||
|
lv_obj_align(subtitle, LV_ALIGN_CENTER, 0, 14);
|
||||||
|
|
||||||
|
ui_initialized = true;
|
||||||
|
}
|
||||||
14
src/ui/ui_main.h
Normal file
14
src/ui/ui_main.h
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
#ifndef BLINKY_UI_MAIN_H_
|
||||||
|
#define BLINKY_UI_MAIN_H_
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void ui_main_init(void);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* BLINKY_UI_MAIN_H_ */
|
||||||
Reference in New Issue
Block a user