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