1 /*
2 * Copyright (c) 2024 Fabian Blatz <fabianblatz@gmail.com>
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include "lvgl_zephyr_osal.h"
8 #include <lvgl.h>
9
10 #include <zephyr/logging/log.h>
11 LOG_MODULE_DECLARE(lvgl, CONFIG_LV_Z_LOG_LEVEL);
12
13 typedef void (*lv_thread_entry)(void *);
14 static void thread_entry(void *thread, void *cb, void *user_data);
15
lv_thread_init(lv_thread_t * thread,lv_thread_prio_t prio,void (* callback)(void *),size_t stack_size,void * user_data)16 lv_result_t lv_thread_init(lv_thread_t *thread, lv_thread_prio_t prio, void (*callback)(void *),
17 size_t stack_size, void *user_data)
18 {
19 int thread_priority;
20
21 thread->stack = k_thread_stack_alloc(stack_size, 0);
22 if (thread->stack == NULL) {
23 return LV_RESULT_INVALID;
24 }
25
26 thread_priority = (CONFIG_NUM_PREEMPT_PRIORITIES - 1) -
27 ((prio * (CONFIG_NUM_PREEMPT_PRIORITIES - 1)) / LV_THREAD_PRIO_HIGHEST);
28
29 thread->tid = k_thread_create(&thread->thread, thread->stack, stack_size, thread_entry,
30 thread, callback, user_data, thread_priority, 0, K_NO_WAIT);
31
32 return LV_RESULT_OK;
33 }
34
lv_thread_delete(lv_thread_t * thread)35 lv_result_t lv_thread_delete(lv_thread_t *thread)
36 {
37 int ret;
38
39 k_thread_abort(thread->tid);
40 ret = k_thread_stack_free(thread->stack);
41 if (ret < 0) {
42 LOG_ERR("Failled to delete thread: %d", ret);
43 return LV_RESULT_INVALID;
44 }
45
46 return LV_RESULT_OK;
47 }
48
lv_mutex_init(lv_mutex_t * mutex)49 lv_result_t lv_mutex_init(lv_mutex_t *mutex)
50 {
51 k_mutex_init(mutex);
52 return LV_RESULT_OK;
53 }
54
lv_mutex_lock(lv_mutex_t * mutex)55 lv_result_t lv_mutex_lock(lv_mutex_t *mutex)
56 {
57 int ret;
58
59 ret = k_mutex_lock(mutex, K_FOREVER);
60 if (ret != 0) {
61 LOG_ERR("Failed to lock mutex: %d", ret);
62 return LV_RESULT_INVALID;
63 }
64
65 return LV_RESULT_OK;
66 }
67
lv_mutex_lock_isr(lv_mutex_t * mutex)68 lv_result_t lv_mutex_lock_isr(lv_mutex_t *mutex)
69 {
70 int ret;
71
72 ret = k_mutex_lock(mutex, K_NO_WAIT);
73 if (ret != 0) {
74 LOG_ERR("Failed to lock mutex: %d", ret);
75 return LV_RESULT_INVALID;
76 }
77
78 return LV_RESULT_OK;
79 }
80
lv_mutex_unlock(lv_mutex_t * mutex)81 lv_result_t lv_mutex_unlock(lv_mutex_t *mutex)
82 {
83 int ret;
84
85 ret = k_mutex_unlock(mutex);
86 if (ret != 0) {
87 LOG_ERR("Failed to unlock mutex: %d", ret);
88 return LV_RESULT_INVALID;
89 }
90
91 return LV_RESULT_OK;
92 }
93
lv_mutex_delete(lv_mutex_t * mutex)94 lv_result_t lv_mutex_delete(lv_mutex_t *mutex)
95 {
96 ARG_UNUSED(mutex);
97 return LV_RESULT_OK;
98 }
99
lv_thread_sync_init(lv_thread_sync_t * sync)100 lv_result_t lv_thread_sync_init(lv_thread_sync_t *sync)
101 {
102 int ret;
103
104 ret = k_sem_init(sync, 0, 1);
105 if (ret != 0) {
106 LOG_ERR("Failed to init thread sync: %d", ret);
107 return LV_RESULT_INVALID;
108 }
109
110 return LV_RESULT_OK;
111 }
112
lv_thread_sync_wait(lv_thread_sync_t * sync)113 lv_result_t lv_thread_sync_wait(lv_thread_sync_t *sync)
114 {
115 int ret;
116
117 ret = k_sem_take(sync, K_FOREVER);
118 if (ret < 0) {
119 LOG_ERR("Error waiting on thread sync: %d", ret);
120 return LV_RESULT_INVALID;
121 }
122
123 return LV_RESULT_OK;
124 }
125
lv_thread_sync_signal(lv_thread_sync_t * sync)126 lv_result_t lv_thread_sync_signal(lv_thread_sync_t *sync)
127 {
128 k_sem_give(sync);
129 return LV_RESULT_OK;
130 }
131
lv_thread_sync_signal_isr(lv_thread_sync_t * sync)132 lv_result_t lv_thread_sync_signal_isr(lv_thread_sync_t *sync)
133 {
134 k_sem_give(sync);
135 return LV_RESULT_OK;
136 }
137
lv_thread_sync_delete(lv_thread_sync_t * sync)138 lv_result_t lv_thread_sync_delete(lv_thread_sync_t *sync)
139 {
140 ARG_UNUSED(sync);
141 return LV_RESULT_OK;
142 }
143
thread_entry(void * thread,void * cb,void * user_data)144 void thread_entry(void *thread, void *cb, void *user_data)
145 {
146 __ASSERT_NO_MSG(cb != NULL);
147 lv_thread_entry entry_cb = (lv_thread_entry)cb;
148
149 entry_cb(user_data);
150 lv_thread_delete((lv_thread_t *)thread);
151 }
152