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