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