/** * @file lv_gpu_nxp_pxp_osa.c * */ /** * MIT License * * Copyright 2020, 2022, 2023 NXP * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights to * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of * the Software, and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice (including the next paragraph) * shall be included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * */ /********************* * INCLUDES *********************/ #include "lv_gpu_nxp_pxp_osa.h" #if LV_USE_GPU_NXP_PXP && LV_USE_GPU_NXP_PXP_AUTO_INIT #include "../../../misc/lv_log.h" #include "fsl_pxp.h" #if defined(SDK_OS_FREE_RTOS) #include "FreeRTOS.h" #include "semphr.h" #endif #if defined(__ZEPHYR__) #include #endif /********************* * DEFINES *********************/ /********************** * TYPEDEFS **********************/ /********************** * STATIC PROTOTYPES **********************/ /** * PXP interrupt initialization. */ static lv_res_t _lv_gpu_nxp_pxp_interrupt_init(void); /** * PXP interrupt de-initialization. */ static void _lv_gpu_nxp_pxp_interrupt_deinit(void); /** * Start the PXP job. */ static void _lv_gpu_nxp_pxp_run(void); /** * Wait for PXP completion. */ static void _lv_gpu_nxp_pxp_wait(void); /********************** * STATIC VARIABLES **********************/ #if defined(SDK_OS_FREE_RTOS) static SemaphoreHandle_t s_pxpIdleSem; #endif #if defined(__ZEPHYR__) static K_SEM_DEFINE(s_pxpIdleSem, 0, 1); #endif static volatile bool s_pxpIdle; static lv_nxp_pxp_cfg_t pxp_default_cfg = { .pxp_interrupt_init = _lv_gpu_nxp_pxp_interrupt_init, .pxp_interrupt_deinit = _lv_gpu_nxp_pxp_interrupt_deinit, .pxp_run = _lv_gpu_nxp_pxp_run, .pxp_wait = _lv_gpu_nxp_pxp_wait, }; /********************** * MACROS **********************/ /********************** * GLOBAL FUNCTIONS **********************/ void PXP_IRQHandler(void) { #if defined(SDK_OS_FREE_RTOS) BaseType_t taskAwake = pdFALSE; #endif if(kPXP_CompleteFlag & PXP_GetStatusFlags(LV_GPU_NXP_PXP_ID)) { PXP_ClearStatusFlags(LV_GPU_NXP_PXP_ID, kPXP_CompleteFlag); #if defined(SDK_OS_FREE_RTOS) xSemaphoreGiveFromISR(s_pxpIdleSem, &taskAwake); portYIELD_FROM_ISR(taskAwake); #elif defined(__ZEPHYR__) k_sem_give(&s_pxpIdleSem); #else s_pxpIdle = true; #endif } } lv_nxp_pxp_cfg_t * lv_gpu_nxp_pxp_get_cfg(void) { return &pxp_default_cfg; } /********************** * STATIC FUNCTIONS **********************/ static lv_res_t _lv_gpu_nxp_pxp_interrupt_init(void) { #if defined(SDK_OS_FREE_RTOS) s_pxpIdleSem = xSemaphoreCreateBinary(); if(s_pxpIdleSem == NULL) return LV_RES_INV; NVIC_SetPriority(LV_GPU_NXP_PXP_IRQ_ID, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY + 1); #endif s_pxpIdle = true; NVIC_EnableIRQ(LV_GPU_NXP_PXP_IRQ_ID); return LV_RES_OK; } static void _lv_gpu_nxp_pxp_interrupt_deinit(void) { NVIC_DisableIRQ(LV_GPU_NXP_PXP_IRQ_ID); #if defined(SDK_OS_FREE_RTOS) vSemaphoreDelete(s_pxpIdleSem); #elif defined(__ZEPHYR__) k_sem_reset(&s_pxpIdleSem); #endif } /** * Function to start PXP job. */ static void _lv_gpu_nxp_pxp_run(void) { s_pxpIdle = false; PXP_EnableInterrupts(LV_GPU_NXP_PXP_ID, kPXP_CompleteInterruptEnable); PXP_Start(LV_GPU_NXP_PXP_ID); } /** * Function to wait for PXP completion. */ static void _lv_gpu_nxp_pxp_wait(void) { #if defined(SDK_OS_FREE_RTOS) || defined(__ZEPHYR__) /* Return if PXP was never started, otherwise the semaphore will lock forever. */ if(s_pxpIdle == true) return; #endif #if defined (SDK_OS_FREE_RTOS) if(xSemaphoreTake(s_pxpIdleSem, portMAX_DELAY) == pdTRUE) s_pxpIdle = true; #elif defined(__ZEPHYR__) if(k_sem_take(&s_pxpIdleSem, K_FOREVER) == 0) s_pxpIdle = true; #else while(s_pxpIdle == false) { } #endif } #endif /*LV_USE_GPU_NXP_PXP && LV_USE_GPU_NXP_PXP_AUTO_INIT*/