Skip to content

Commit 8ccc14d

Browse files
committed
feat(app/hmi-generic): Add new HMI application
HMI generic application implements some basic functionality of a HMI device, specifically: - drawing on a display/framebuffer device - managing keypad and buttons - sensing proximity of the user - outputting sound using a speaker - communicating over a suitable interface/bus It should be fully configurable using Kconfig (not yet the case).
1 parent 744700e commit 8ccc14d

File tree

4 files changed

+148
-0
lines changed

4 files changed

+148
-0
lines changed

applications/hmi-generic/Kconfig

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
config APP_HMI_GENERIC
2+
bool "A generic HMI application with LCD, presence detection, speaker, keyboard"
3+
4+
menu "Generic HMI application config"
5+
depends on APP_HMI_GENERIC
6+
7+
config APP_NAME
8+
string
9+
default "hmi-generic"
10+
11+
endmenu

applications/hmi-generic/SConscript

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
Import("env")
2+
Import("conf")
3+
Import("objs")
4+
5+
objs.append(env.Object(source = [
6+
File("app.c"),
7+
]))
8+
env.Append(CPPPATH = [Dir(".")])
9+

applications/hmi-generic/app.c

+96
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
/* SPDX-License-Identifier: GPL-3.0-or-later
2+
*
3+
* Generic HMI implementation
4+
*
5+
* Copyright (c) 2025, Marek Koza (qyx@krtko.org)
6+
* All rights reserved.
7+
*/
8+
9+
#include <main.h>
10+
#include "app.h"
11+
12+
#define MODULE_NAME "hmi"
13+
14+
15+
static void com_task(void *p) {
16+
App *self = p;
17+
18+
struct nbus_socket *socket = nbus_socket_allocate(&nbus);
19+
while (true) {
20+
uint8_t local_id[] = {0x00, 0x00, 0x00, 0x10};
21+
nbus_socket_bind(socket, local_id, 1);
22+
23+
struct datagram_msg rxmsg = {0};
24+
static uint8_t packet_buffer[1024];
25+
size_t len = sizeof(packet_buffer);
26+
27+
if (socket->datagram.vmt->read(&socket->datagram, packet_buffer, &len, &rxmsg) == DATAGRAM_RET_OK) {
28+
uint32_t offset = packet_buffer[0] << 24 | packet_buffer[1] << 16 | packet_buffer[2] << 8 | packet_buffer[3];
29+
len -= 4;
30+
31+
if ((offset + len) > 9600) {
32+
continue;
33+
}
34+
self->fb->vmt->write(self->fb, offset, packet_buffer + 4, len, FB_MODE_G2);
35+
36+
if ((offset + len) == 9600) {
37+
self->fb->vmt->flush(self->fb);
38+
}
39+
}
40+
41+
}
42+
nbus_socket_release(&nbus, socket);
43+
vTaskDelete(NULL);
44+
}
45+
46+
47+
static void input_task(void *p) {
48+
App *self = p;
49+
50+
51+
while (true) {
52+
53+
vTaskDelay(1000);
54+
}
55+
vTaskDelete(NULL);
56+
}
57+
58+
59+
app_ret_t app_init(App *self) {
60+
memset(self, 0, sizeof(App));
61+
62+
self->fb = NULL;
63+
if (iservicelocator_query_type_id(locator, ISERVICELOCATOR_TYPE_FB, 0, (Interface **)&self->fb) != ISERVICELOCATOR_RET_OK) {
64+
u_log(system_log, LOG_TYPE_ERROR, U_LOG_MODULE_PREFIX("no framebuffer device found"));
65+
return APP_RET_FAILED;
66+
}
67+
68+
/* Get any i2c available. Allow configuration in the future (along with input devices). */
69+
self->i2c = NULL;
70+
if (iservicelocator_query_type_id(locator, ISERVICELOCATOR_TYPE_I2C, 0, (Interface **)&self->i2c) != ISERVICELOCATOR_RET_OK) {
71+
u_log(system_log, LOG_TYPE_ERROR, U_LOG_MODULE_PREFIX("no suitable i2c device found"));
72+
return APP_RET_FAILED;
73+
}
74+
75+
xTaskCreate(com_task, "hmi-com", configMINIMAL_STACK_SIZE + 256, (void *)self, 1, &(self->com_task));
76+
if (self->com_task == NULL) {
77+
u_log(system_log, LOG_TYPE_ERROR, U_LOG_MODULE_PREFIX("cannot create application com task"));
78+
goto err;
79+
}
80+
81+
xTaskCreate(input_task, "hmi-input", configMINIMAL_STACK_SIZE + 128, (void *)self, 1, &(self->input_task));
82+
if (self->input_task == NULL) {
83+
u_log(system_log, LOG_TYPE_ERROR, U_LOG_MODULE_PREFIX("cannot create application input task"));
84+
goto err;
85+
}
86+
87+
88+
return APP_RET_OK;
89+
err:
90+
return APP_RET_FAILED;
91+
}
92+
93+
94+
app_ret_t app_free(App *self) {
95+
return APP_RET_OK;
96+
}

applications/hmi-generic/app.h

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/* SPDX-License-Identifier: GPL-3.0-or-later
2+
*
3+
* Generic HMI implementation
4+
*
5+
* Copyright (c) 2025, Marek Koza (qyx@krtko.org)
6+
* All rights reserved.
7+
*/
8+
9+
#pragma once
10+
11+
#include <interfaces/datagram.h>
12+
#include <interfaces/fb.h>
13+
#include <interfaces/i2c-bus.h>
14+
#include <services/nbus2/nbus2.h>
15+
16+
17+
typedef enum {
18+
APP_RET_OK = 0,
19+
APP_RET_FAILED,
20+
} app_ret_t;
21+
22+
typedef struct {
23+
TaskHandle_t com_task;
24+
TaskHandle_t input_task;
25+
Fb *fb;
26+
I2cBus *i2c;
27+
} App;
28+
29+
30+
app_ret_t app_init(App *self);
31+
app_ret_t app_free(App *self);
32+

0 commit comments

Comments
 (0)