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 /*********************
46 * DEFINES
47 *********************/
48
49 /**********************
50 * TYPEDEFS
51 **********************/
52
53 /**********************
54 * STATIC PROTOTYPES
55 **********************/
56
57 /**
58 * PXP interrupt initialization.
59 */
60 static lv_res_t _lv_gpu_nxp_pxp_interrupt_init(void);
61
62 /**
63 * PXP interrupt de-initialization.
64 */
65 static void _lv_gpu_nxp_pxp_interrupt_deinit(void);
66
67 /**
68 * Start the PXP job.
69 */
70 static void _lv_gpu_nxp_pxp_run(void);
71
72 /**
73 * Wait for PXP completion.
74 */
75 static void _lv_gpu_nxp_pxp_wait(void);
76
77 /**********************
78 * STATIC VARIABLES
79 **********************/
80
81 #if defined(SDK_OS_FREE_RTOS)
82 static SemaphoreHandle_t s_pxpIdleSem;
83 #endif
84 static volatile bool s_pxpIdle;
85
86 static lv_nxp_pxp_cfg_t pxp_default_cfg = {
87 .pxp_interrupt_init = _lv_gpu_nxp_pxp_interrupt_init,
88 .pxp_interrupt_deinit = _lv_gpu_nxp_pxp_interrupt_deinit,
89 .pxp_run = _lv_gpu_nxp_pxp_run,
90 .pxp_wait = _lv_gpu_nxp_pxp_wait,
91 };
92
93 /**********************
94 * MACROS
95 **********************/
96
97 /**********************
98 * GLOBAL FUNCTIONS
99 **********************/
100
PXP_IRQHandler(void)101 void PXP_IRQHandler(void)
102 {
103 #if defined(SDK_OS_FREE_RTOS)
104 BaseType_t taskAwake = pdFALSE;
105 #endif
106
107 if(kPXP_CompleteFlag & PXP_GetStatusFlags(LV_GPU_NXP_PXP_ID)) {
108 PXP_ClearStatusFlags(LV_GPU_NXP_PXP_ID, kPXP_CompleteFlag);
109 #if defined(SDK_OS_FREE_RTOS)
110 xSemaphoreGiveFromISR(s_pxpIdleSem, &taskAwake);
111 portYIELD_FROM_ISR(taskAwake);
112 #else
113 s_pxpIdle = true;
114 #endif
115 }
116 }
117
lv_gpu_nxp_pxp_get_cfg(void)118 lv_nxp_pxp_cfg_t * lv_gpu_nxp_pxp_get_cfg(void)
119 {
120 return &pxp_default_cfg;
121 }
122
123 /**********************
124 * STATIC FUNCTIONS
125 **********************/
126
_lv_gpu_nxp_pxp_interrupt_init(void)127 static lv_res_t _lv_gpu_nxp_pxp_interrupt_init(void)
128 {
129 #if defined(SDK_OS_FREE_RTOS)
130 s_pxpIdleSem = xSemaphoreCreateBinary();
131 if(s_pxpIdleSem == NULL)
132 return LV_RES_INV;
133
134 NVIC_SetPriority(LV_GPU_NXP_PXP_IRQ_ID, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY + 1);
135 #endif
136 s_pxpIdle = true;
137
138 NVIC_EnableIRQ(LV_GPU_NXP_PXP_IRQ_ID);
139
140 return LV_RES_OK;
141 }
142
_lv_gpu_nxp_pxp_interrupt_deinit(void)143 static void _lv_gpu_nxp_pxp_interrupt_deinit(void)
144 {
145 NVIC_DisableIRQ(LV_GPU_NXP_PXP_IRQ_ID);
146 #if defined(SDK_OS_FREE_RTOS)
147 vSemaphoreDelete(s_pxpIdleSem);
148 #endif
149 }
150
151 /**
152 * Function to start PXP job.
153 */
_lv_gpu_nxp_pxp_run(void)154 static void _lv_gpu_nxp_pxp_run(void)
155 {
156 s_pxpIdle = false;
157
158 PXP_EnableInterrupts(LV_GPU_NXP_PXP_ID, kPXP_CompleteInterruptEnable);
159 PXP_Start(LV_GPU_NXP_PXP_ID);
160 }
161
162 /**
163 * Function to wait for PXP completion.
164 */
_lv_gpu_nxp_pxp_wait(void)165 static void _lv_gpu_nxp_pxp_wait(void)
166 {
167 #if defined(SDK_OS_FREE_RTOS)
168 /* Return if PXP was never started, otherwise the semaphore will lock forever. */
169 if(s_pxpIdle == true)
170 return;
171
172 if(xSemaphoreTake(s_pxpIdleSem, portMAX_DELAY) == pdTRUE)
173 s_pxpIdle = true;
174 #else
175 while(s_pxpIdle == false) {
176 }
177 #endif
178 }
179
180 #endif /*LV_USE_GPU_NXP_PXP && LV_USE_GPU_NXP_PXP_AUTO_INIT*/
181