1 /**
2 * @file lv_gpu_nxp_pxp_osa.c
3 *
4 */
5
6 /**
7 * MIT License
8 *
9 * Copyright 2020, 2022, 2023 NXP
10 *
11 * Permission is hereby granted, free of charge, to any person obtaining a copy
12 * of this software and associated documentation files (the "Software"), to deal
13 * in the Software without restriction, including without limitation the rights to
14 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
15 * the Software, and to permit persons to whom the Software is furnished to do so,
16 * subject to the following conditions:
17 *
18 * The above copyright notice and this permission notice (including the next paragraph)
19 * shall be included in all copies or substantial portions of the Software.
20 *
21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
22 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
23 * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
24 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
25 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
26 * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 *
28 */
29
30 /*********************
31 * INCLUDES
32 *********************/
33
34 #include "lv_gpu_nxp_pxp_osa.h"
35
36 #if LV_USE_GPU_NXP_PXP && LV_USE_GPU_NXP_PXP_AUTO_INIT
37 #include "../../../misc/lv_log.h"
38 #include "fsl_pxp.h"
39
40 #if defined(SDK_OS_FREE_RTOS)
41 #include "FreeRTOS.h"
42 #include "semphr.h"
43 #endif
44
45 #if defined(__ZEPHYR__)
46 #include <zephyr/kernel.h>
47 #endif
48
49 /*********************
50 * DEFINES
51 *********************/
52
53 /**********************
54 * TYPEDEFS
55 **********************/
56
57 /**********************
58 * STATIC PROTOTYPES
59 **********************/
60
61 /**
62 * PXP interrupt initialization.
63 */
64 static lv_res_t _lv_gpu_nxp_pxp_interrupt_init(void);
65
66 /**
67 * PXP interrupt de-initialization.
68 */
69 static void _lv_gpu_nxp_pxp_interrupt_deinit(void);
70
71 /**
72 * Start the PXP job.
73 */
74 static void _lv_gpu_nxp_pxp_run(void);
75
76 /**
77 * Wait for PXP completion.
78 */
79 static void _lv_gpu_nxp_pxp_wait(void);
80
81 /**********************
82 * STATIC VARIABLES
83 **********************/
84
85 #if defined(SDK_OS_FREE_RTOS)
86 static SemaphoreHandle_t s_pxpIdleSem;
87 #endif
88 #if defined(__ZEPHYR__)
89 static K_SEM_DEFINE(s_pxpIdleSem, 0, 1);
90 #endif
91 static volatile bool s_pxpIdle;
92
93 static lv_nxp_pxp_cfg_t pxp_default_cfg = {
94 .pxp_interrupt_init = _lv_gpu_nxp_pxp_interrupt_init,
95 .pxp_interrupt_deinit = _lv_gpu_nxp_pxp_interrupt_deinit,
96 .pxp_run = _lv_gpu_nxp_pxp_run,
97 .pxp_wait = _lv_gpu_nxp_pxp_wait,
98 };
99
100 /**********************
101 * MACROS
102 **********************/
103
104 /**********************
105 * GLOBAL FUNCTIONS
106 **********************/
107
PXP_IRQHandler(void)108 void PXP_IRQHandler(void)
109 {
110 #if defined(SDK_OS_FREE_RTOS)
111 BaseType_t taskAwake = pdFALSE;
112 #endif
113
114 if(kPXP_CompleteFlag & PXP_GetStatusFlags(LV_GPU_NXP_PXP_ID)) {
115 PXP_ClearStatusFlags(LV_GPU_NXP_PXP_ID, kPXP_CompleteFlag);
116 #if defined(SDK_OS_FREE_RTOS)
117 xSemaphoreGiveFromISR(s_pxpIdleSem, &taskAwake);
118 portYIELD_FROM_ISR(taskAwake);
119 #elif defined(__ZEPHYR__)
120 k_sem_give(&s_pxpIdleSem);
121 #else
122 s_pxpIdle = true;
123 #endif
124 }
125 }
126
lv_gpu_nxp_pxp_get_cfg(void)127 lv_nxp_pxp_cfg_t * lv_gpu_nxp_pxp_get_cfg(void)
128 {
129 return &pxp_default_cfg;
130 }
131
132 /**********************
133 * STATIC FUNCTIONS
134 **********************/
135
_lv_gpu_nxp_pxp_interrupt_init(void)136 static lv_res_t _lv_gpu_nxp_pxp_interrupt_init(void)
137 {
138 #if defined(SDK_OS_FREE_RTOS)
139 s_pxpIdleSem = xSemaphoreCreateBinary();
140 if(s_pxpIdleSem == NULL)
141 return LV_RES_INV;
142
143 NVIC_SetPriority(LV_GPU_NXP_PXP_IRQ_ID, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY + 1);
144 #endif
145 s_pxpIdle = true;
146
147 NVIC_EnableIRQ(LV_GPU_NXP_PXP_IRQ_ID);
148
149 return LV_RES_OK;
150 }
151
_lv_gpu_nxp_pxp_interrupt_deinit(void)152 static void _lv_gpu_nxp_pxp_interrupt_deinit(void)
153 {
154 NVIC_DisableIRQ(LV_GPU_NXP_PXP_IRQ_ID);
155 #if defined(SDK_OS_FREE_RTOS)
156 vSemaphoreDelete(s_pxpIdleSem);
157 #elif defined(__ZEPHYR__)
158 k_sem_reset(&s_pxpIdleSem);
159 #endif
160 }
161
162 /**
163 * Function to start PXP job.
164 */
_lv_gpu_nxp_pxp_run(void)165 static void _lv_gpu_nxp_pxp_run(void)
166 {
167 s_pxpIdle = false;
168
169 PXP_EnableInterrupts(LV_GPU_NXP_PXP_ID, kPXP_CompleteInterruptEnable);
170 PXP_Start(LV_GPU_NXP_PXP_ID);
171 }
172
173 /**
174 * Function to wait for PXP completion.
175 */
_lv_gpu_nxp_pxp_wait(void)176 static void _lv_gpu_nxp_pxp_wait(void)
177 {
178 #if defined(SDK_OS_FREE_RTOS) || defined(__ZEPHYR__)
179 /* Return if PXP was never started, otherwise the semaphore will lock forever. */
180 if(s_pxpIdle == true)
181 return;
182 #endif
183 #if defined (SDK_OS_FREE_RTOS)
184 if(xSemaphoreTake(s_pxpIdleSem, portMAX_DELAY) == pdTRUE)
185 s_pxpIdle = true;
186 #elif defined(__ZEPHYR__)
187 if(k_sem_take(&s_pxpIdleSem, K_FOREVER) == 0)
188 s_pxpIdle = true;
189 #else
190 while(s_pxpIdle == false) {
191 }
192 #endif
193 }
194
195 #endif /*LV_USE_GPU_NXP_PXP && LV_USE_GPU_NXP_PXP_AUTO_INIT*/
196