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,const char * const name,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, const char *const name, lv_thread_prio_t prio,
17 void (*callback)(void *), 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 k_thread_name_set(thread->tid, name);
33
34 return LV_RESULT_OK;
35 }
36
lv_thread_delete(lv_thread_t * thread)37 lv_result_t lv_thread_delete(lv_thread_t *thread)
38 {
39 int ret;
40
41 k_thread_abort(thread->tid);
42 ret = k_thread_stack_free(thread->stack);
43 if (ret < 0) {
44 LOG_ERR("Failled to delete thread: %d", ret);
45 return LV_RESULT_INVALID;
46 }
47
48 return LV_RESULT_OK;
49 }
50
lv_mutex_init(lv_mutex_t * mutex)51 lv_result_t lv_mutex_init(lv_mutex_t *mutex)
52 {
53 k_mutex_init(mutex);
54 return LV_RESULT_OK;
55 }
56
lv_mutex_lock(lv_mutex_t * mutex)57 lv_result_t lv_mutex_lock(lv_mutex_t *mutex)
58 {
59 int ret;
60
61 ret = k_mutex_lock(mutex, K_FOREVER);
62 if (ret != 0) {
63 LOG_ERR("Failed to lock mutex: %d", ret);
64 return LV_RESULT_INVALID;
65 }
66
67 return LV_RESULT_OK;
68 }
69
lv_mutex_lock_isr(lv_mutex_t * mutex)70 lv_result_t lv_mutex_lock_isr(lv_mutex_t *mutex)
71 {
72 int ret;
73
74 ret = k_mutex_lock(mutex, K_NO_WAIT);
75 if (ret != 0) {
76 LOG_ERR("Failed to lock mutex: %d", ret);
77 return LV_RESULT_INVALID;
78 }
79
80 return LV_RESULT_OK;
81 }
82
lv_mutex_unlock(lv_mutex_t * mutex)83 lv_result_t lv_mutex_unlock(lv_mutex_t *mutex)
84 {
85 int ret;
86
87 ret = k_mutex_unlock(mutex);
88 if (ret != 0) {
89 LOG_ERR("Failed to unlock mutex: %d", ret);
90 return LV_RESULT_INVALID;
91 }
92
93 return LV_RESULT_OK;
94 }
95
lv_mutex_delete(lv_mutex_t * mutex)96 lv_result_t lv_mutex_delete(lv_mutex_t *mutex)
97 {
98 ARG_UNUSED(mutex);
99 return LV_RESULT_OK;
100 }
101
lv_thread_sync_init(lv_thread_sync_t * sync)102 lv_result_t lv_thread_sync_init(lv_thread_sync_t *sync)
103 {
104 int ret;
105
106 ret = k_sem_init(sync, 0, 1);
107 if (ret != 0) {
108 LOG_ERR("Failed to init thread sync: %d", ret);
109 return LV_RESULT_INVALID;
110 }
111
112 return LV_RESULT_OK;
113 }
114
lv_thread_sync_wait(lv_thread_sync_t * sync)115 lv_result_t lv_thread_sync_wait(lv_thread_sync_t *sync)
116 {
117 int ret;
118
119 ret = k_sem_take(sync, K_FOREVER);
120 if (ret < 0) {
121 LOG_ERR("Error waiting on thread sync: %d", ret);
122 return LV_RESULT_INVALID;
123 }
124
125 return LV_RESULT_OK;
126 }
127
lv_thread_sync_signal(lv_thread_sync_t * sync)128 lv_result_t lv_thread_sync_signal(lv_thread_sync_t *sync)
129 {
130 k_sem_give(sync);
131 return LV_RESULT_OK;
132 }
133
lv_thread_sync_signal_isr(lv_thread_sync_t * sync)134 lv_result_t lv_thread_sync_signal_isr(lv_thread_sync_t *sync)
135 {
136 k_sem_give(sync);
137 return LV_RESULT_OK;
138 }
139
lv_thread_sync_delete(lv_thread_sync_t * sync)140 lv_result_t lv_thread_sync_delete(lv_thread_sync_t *sync)
141 {
142 ARG_UNUSED(sync);
143 return LV_RESULT_OK;
144 }
145
thread_entry(void * thread,void * cb,void * user_data)146 void thread_entry(void *thread, void *cb, void *user_data)
147 {
148 __ASSERT_NO_MSG(cb != NULL);
149 lv_thread_entry entry_cb = (lv_thread_entry)cb;
150
151 entry_cb(user_data);
152 lv_thread_delete((lv_thread_t *)thread);
153 }
154