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