1 /**
2  * @file lv_pxp_osa.c
3  *
4  */
5 
6 /**
7  * Copyright 2020, 2022-2023 NXP
8  *
9  * SPDX-License-Identifier: MIT
10  */
11 
12 /*********************
13  *      INCLUDES
14  *********************/
15 
16 #include "lv_pxp_osa.h"
17 
18 #if LV_USE_PXP
19 #if LV_USE_DRAW_PXP || LV_USE_ROTATE_PXP
20 #include "lv_pxp_utils.h"
21 #include "../../../misc/lv_log.h"
22 #include "../../../osal/lv_os.h"
23 #include "fsl_pxp.h"
24 
25 #if defined(SDK_OS_FREE_RTOS)
26     #include "FreeRTOS.h"
27 #endif
28 
29 #if defined(__ZEPHYR__)
30     #include <zephyr/kernel.h>
31     #include <zephyr/irq.h>
32 #endif
33 
34 /*********************
35  *      DEFINES
36  *********************/
37 
38 /**********************
39  *      TYPEDEFS
40  **********************/
41 
42 /**********************
43  *  STATIC PROTOTYPES
44  **********************/
45 
46 /**
47  * PXP interrupt initialization.
48  */
49 static void _pxp_interrupt_init(void);
50 
51 /**
52  * PXP interrupt de-initialization.
53  */
54 static void _pxp_interrupt_deinit(void);
55 
56 /**
57  * Start the PXP job.
58  */
59 static void _pxp_run(void);
60 
61 /**
62  * Wait for PXP completion.
63  */
64 static void _pxp_wait(void);
65 
66 #if defined(__ZEPHYR__)
67     /**
68     * Interrupt handler for Zephyr IRQ
69     */
70     static void _pxp_zephyr_irq_handler(void *);
71 #endif
72 
73 /**********************
74  *  STATIC VARIABLES
75  **********************/
76 
77 #if LV_USE_OS
78     static lv_thread_sync_t pxp_sync;
79 #endif
80 static volatile bool ucPXPIdle;
81 
82 static pxp_cfg_t _pxp_default_cfg = {
83     .pxp_interrupt_init = _pxp_interrupt_init,
84     .pxp_interrupt_deinit = _pxp_interrupt_deinit,
85     .pxp_run = _pxp_run,
86     .pxp_wait = _pxp_wait,
87 };
88 
89 /**********************
90  *      MACROS
91  **********************/
92 
93 /**********************
94  *   GLOBAL FUNCTIONS
95  **********************/
96 
PXP_IRQHandler(void)97 void PXP_IRQHandler(void)
98 {
99     if(kPXP_CompleteFlag & PXP_GetStatusFlags(PXP_ID)) {
100         PXP_ClearStatusFlags(PXP_ID, kPXP_CompleteFlag);
101 #if LV_USE_OS
102         lv_thread_sync_signal_isr(&pxp_sync);
103 #else
104         ucPXPIdle = true;
105 #endif
106     }
107 }
108 
pxp_get_default_cfg(void)109 pxp_cfg_t * pxp_get_default_cfg(void)
110 {
111     return &_pxp_default_cfg;
112 }
113 
114 /**********************
115  *   STATIC FUNCTIONS
116  **********************/
117 
118 #if defined(__ZEPHYR__)
_pxp_zephyr_irq_handler(void *)119 static void _pxp_zephyr_irq_handler(void *)
120 {
121     PXP_IRQHandler();
122 }
123 #endif
124 
_pxp_interrupt_init(void)125 static void _pxp_interrupt_init(void)
126 {
127 #if LV_USE_OS
128     if(lv_thread_sync_init(&pxp_sync) != LV_RESULT_OK) {
129         PXP_ASSERT_MSG(false, "Failed to init thread_sync.");
130     }
131 #endif
132 
133 #if defined(__ZEPHYR__)
134     IRQ_CONNECT(DT_IRQN(DT_NODELABEL(pxp)), CONFIG_LV_Z_PXP_INTERRUPT_PRIORITY, _pxp_zephyr_irq_handler, NULL, 0);
135     irq_enable(DT_IRQN(DT_NODELABEL(pxp)));
136 #elif defined(SDK_OS_FREE_RTOS)
137     NVIC_SetPriority(PXP_IRQ_ID, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY + 1);
138 #endif
139 
140 #if !defined(__ZEPHYR__)
141     NVIC_EnableIRQ(PXP_IRQ_ID);
142 #endif
143 
144     ucPXPIdle = true;
145 }
146 
_pxp_interrupt_deinit(void)147 static void _pxp_interrupt_deinit(void)
148 {
149 #if defined(__ZEPHYR__)
150     irq_disable(DT_IRQN(DT_NODELABEL(pxp)));
151 #else
152     NVIC_DisableIRQ(PXP_IRQ_ID);
153 #endif
154 
155 #if LV_USE_OS
156     lv_thread_sync_delete(&pxp_sync);
157 #endif
158 }
159 
160 /**
161  * Function to start PXP job.
162  */
_pxp_run(void)163 static void _pxp_run(void)
164 {
165     ucPXPIdle = false;
166 
167     PXP_EnableInterrupts(PXP_ID, kPXP_CompleteInterruptEnable);
168     PXP_Start(PXP_ID);
169 }
170 
171 /**
172  * Function to wait for PXP completion.
173  */
_pxp_wait(void)174 static void _pxp_wait(void)
175 {
176     if(ucPXPIdle == true)
177         return;
178 #if LV_USE_OS
179     if(lv_thread_sync_wait(&pxp_sync) == LV_RESULT_OK)
180         ucPXPIdle = true;
181 #else
182     while(ucPXPIdle == false) {
183     }
184 #endif
185 }
186 
187 #endif /*LV_USE_DRAW_PXP || LV_USE_ROTATE_PXP*/
188 #endif /*LV_USE_PXP*/
189