diff --git a/src/draw/nxp/pxp/lv_pxp_osa.c b/src/draw/nxp/pxp/lv_pxp_osa.c index 539cefe503..b573b212b6 100644 --- a/src/draw/nxp/pxp/lv_pxp_osa.c +++ b/src/draw/nxp/pxp/lv_pxp_osa.c @@ -18,11 +18,16 @@ #if LV_USE_DRAW_PXP #include "lv_pxp_utils.h" #include "../../../misc/lv_log.h" +#include "../../../osal/lv_os.h" #include "fsl_pxp.h" #if defined(SDK_OS_FREE_RTOS) #include "FreeRTOS.h" - #include "semphr.h" +#endif + +#if defined(__ZEPHYR__) + #include + #include #endif /********************* @@ -57,12 +62,19 @@ static void _pxp_run(void); */ static void _pxp_wait(void); +#if defined(__ZEPHYR__) + /** + * Interrupt handler for Zephyr IRQ + */ + static void _pxp_zephyr_irq_handler(void *); +#endif + /********************** * STATIC VARIABLES **********************/ -#if defined(SDK_OS_FREE_RTOS) - static SemaphoreHandle_t xPXPIdleSemaphore; +#if LV_USE_OS + static lv_thread_sync_t pxp_sync; #endif static volatile bool ucPXPIdle; @@ -83,20 +95,10 @@ static pxp_cfg_t _pxp_default_cfg = { void PXP_IRQHandler(void) { -#if defined(SDK_OS_FREE_RTOS) - BaseType_t xHigherPriorityTaskWoken = pdFALSE; -#endif - if(kPXP_CompleteFlag & PXP_GetStatusFlags(PXP_ID)) { PXP_ClearStatusFlags(PXP_ID, kPXP_CompleteFlag); -#if defined(SDK_OS_FREE_RTOS) - xSemaphoreGiveFromISR(xPXPIdleSemaphore, &xHigherPriorityTaskWoken); - - /* If xHigherPriorityTaskWoken is now set to pdTRUE then a context switch - should be performed to ensure the interrupt returns directly to the highest - priority task. The macro used for this purpose is dependent on the port in - use and may be called portEND_SWITCHING_ISR(). */ - portYIELD_FROM_ISR(xHigherPriorityTaskWoken); +#if LV_USE_OS + lv_thread_sync_signal_isr(&pxp_sync); #else ucPXPIdle = true; #endif @@ -112,24 +114,45 @@ pxp_cfg_t * pxp_get_default_cfg(void) * STATIC FUNCTIONS **********************/ +#if defined(__ZEPHYR__) +static void _pxp_zephyr_irq_handler(void *) +{ + PXP_IRQHandler(); +} +#endif + static void _pxp_interrupt_init(void) { -#if defined(SDK_OS_FREE_RTOS) - xPXPIdleSemaphore = xSemaphoreCreateBinary(); - PXP_ASSERT_MSG(xPXPIdleSemaphore, "xSemaphoreCreateBinary failed!"); +#if LV_USE_OS + if(lv_thread_sync_init(&pxp_sync) != LV_RESULT_OK) { + PXP_ASSERT_MSG(false, "Failed to init thread_sync."); + } +#endif +#if defined(__ZEPHYR__) + IRQ_CONNECT(DT_IRQN(DT_NODELABEL(pxp)), CONFIG_LV_Z_PXP_INTERRUPT_PRIORITY, _pxp_zephyr_irq_handler, NULL, 0); + irq_enable(DT_IRQN(DT_NODELABEL(pxp))); +#elif defined(SDK_OS_FREE_RTOS) NVIC_SetPriority(PXP_IRQ_ID, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY + 1); #endif - ucPXPIdle = true; +#if !defined(__ZEPHYR__) NVIC_EnableIRQ(PXP_IRQ_ID); +#endif + + ucPXPIdle = true; } static void _pxp_interrupt_deinit(void) { +#if defined(__ZEPHYR__) + irq_disable(DT_IRQN(DT_NODELABEL(pxp))); +#else NVIC_DisableIRQ(PXP_IRQ_ID); -#if defined(SDK_OS_FREE_RTOS) - vSemaphoreDelete(xPXPIdleSemaphore); +#endif + +#if LV_USE_OS + lv_thread_sync_delete(&pxp_sync); #endif } @@ -149,12 +172,10 @@ static void _pxp_run(void) */ static void _pxp_wait(void) { -#if defined(SDK_OS_FREE_RTOS) - /* Return if PXP was never started, otherwise the semaphore will lock forever. */ if(ucPXPIdle == true) return; - - if(xSemaphoreTake(xPXPIdleSemaphore, portMAX_DELAY) == pdTRUE) +#if LV_USE_OS + if(lv_thread_sync_wait(&pxp_sync) == LV_RESULT_OK) ucPXPIdle = true; #else while(ucPXPIdle == false) { diff --git a/src/osal/lv_cmsis_rtos2.c b/src/osal/lv_cmsis_rtos2.c index 028520f180..ed414c8dab 100644 --- a/src/osal/lv_cmsis_rtos2.c +++ b/src/osal/lv_cmsis_rtos2.c @@ -172,6 +172,11 @@ lv_result_t lv_thread_sync_signal(lv_thread_sync_t * sync) return LV_RESULT_OK; } +lv_result_t lv_thread_sync_signal_isr(lv_thread_sync_t * sync) +{ + return lv_thread_sync_signal(sync); +} + lv_result_t lv_thread_sync_delete(lv_thread_sync_t * sync) { osStatus_t status = osEventFlagsDelete(*sync); diff --git a/src/osal/lv_freertos.c b/src/osal/lv_freertos.c index 0f7f678bca..2dfd323bdd 100644 --- a/src/osal/lv_freertos.c +++ b/src/osal/lv_freertos.c @@ -318,6 +318,36 @@ lv_result_t lv_thread_sync_delete(lv_thread_sync_t * pxCond) return LV_RESULT_OK; } +lv_result_t lv_thread_sync_signal_isr(lv_thread_sync_t * pxCond) +{ + BaseType_t xHigherPriorityTaskWoken = pdFALSE; +#if USE_FREERTOS_TASK_NOTIFY + /* Send a notification to the task waiting. */ + vTaskNotifyGiveFromISR(pxCond->xTaskToNotify, &xHigherPriorityTaskWoken); + portYIELD_FROM_ISR(xHigherPriorityTaskWoken); +#else + /* If the cond is uninitialized, perform initialization. */ + prvCheckCondInit(pxCond); + + /* Enter critical section to prevent preemption. */ + _enter_critical(); + + pxCond->xSyncSignal = pdTRUE; + BaseType_t xAnyHigherPriorityTaskWoken = pdFALSE; + + /* Unblock all. */ + for(uint32_t i = 0; i < pxCond->ulWaitingThreads; i++) { + xSemaphoreGiveFromISR(pxCond->xCondWaitSemaphore, &xAnyHigherPriorityTaskWoken); + xHigherPriorityTaskWoken |= xAnyHigherPriorityTaskWoken; + } + + _exit_critical(); + portYIELD_FROM_ISR(xHigherPriorityTaskWoken); +#endif + + return LV_RESULT_OK; +} + /********************** * STATIC FUNCTIONS **********************/ diff --git a/src/osal/lv_mqx.c b/src/osal/lv_mqx.c index 7e15f812e9..fed82f4289 100644 --- a/src/osal/lv_mqx.c +++ b/src/osal/lv_mqx.c @@ -156,6 +156,12 @@ lv_result_t lv_thread_sync_delete(lv_thread_sync_t * sync) return LV_RESULT_OK; } +lv_result_t lv_thread_sync_signal_isr(lv_thread_sync_t * sync) +{ + LV_UNUSED(sync); + return LV_RESULT_INVALID; +} + /********************** * STATIC FUNCTIONS **********************/ diff --git a/src/osal/lv_os.h b/src/osal/lv_os.h index e9d745d87a..d0a4e02f5c 100644 --- a/src/osal/lv_os.h +++ b/src/osal/lv_os.h @@ -138,6 +138,13 @@ lv_result_t lv_thread_sync_wait(lv_thread_sync_t * sync); */ lv_result_t lv_thread_sync_signal(lv_thread_sync_t * sync); +/** + * Send a wake-up signal to a sync object from interrupt + * @param sync a sync object + * @return LV_RESULT_OK: success; LV_RESULT_INVALID: failure + */ +lv_result_t lv_thread_sync_signal_isr(lv_thread_sync_t * sync); + /** * Delete a sync object * @param sync a sync object to delete diff --git a/src/osal/lv_os_none.c b/src/osal/lv_os_none.c index 4e044d0578..547810db73 100644 --- a/src/osal/lv_os_none.c +++ b/src/osal/lv_os_none.c @@ -106,6 +106,13 @@ lv_result_t lv_thread_sync_signal(lv_thread_sync_t * sync) return LV_RESULT_INVALID; } +lv_result_t lv_thread_sync_signal_isr(lv_thread_sync_t * sync) +{ + LV_UNUSED(sync); + LV_ASSERT(0); + return LV_RESULT_INVALID; +} + lv_result_t lv_thread_sync_delete(lv_thread_sync_t * sync) { LV_UNUSED(sync); diff --git a/src/osal/lv_pthread.c b/src/osal/lv_pthread.c index a2244220b1..3fde246380 100644 --- a/src/osal/lv_pthread.c +++ b/src/osal/lv_pthread.c @@ -152,6 +152,12 @@ lv_result_t lv_thread_sync_delete(lv_thread_sync_t * sync) return LV_RESULT_OK; } +lv_result_t lv_thread_sync_signal_isr(lv_thread_sync_t * sync) +{ + LV_UNUSED(sync); + return LV_RESULT_INVALID; +} + /********************** * STATIC FUNCTIONS **********************/ diff --git a/src/osal/lv_rtthread.c b/src/osal/lv_rtthread.c index 39f78d7848..e781634e16 100644 --- a/src/osal/lv_rtthread.c +++ b/src/osal/lv_rtthread.c @@ -177,6 +177,12 @@ lv_result_t lv_thread_sync_delete(lv_thread_sync_t * sync) } } +lv_result_t lv_thread_sync_signal_isr(lv_thread_sync_t * sync) +{ + LV_UNUSED(sync); + return LV_RESULT_INVALID; +} + /********************** * STATIC FUNCTIONS **********************/ diff --git a/src/osal/lv_windows.c b/src/osal/lv_windows.c index 0d6a33d663..386f9aef88 100644 --- a/src/osal/lv_windows.c +++ b/src/osal/lv_windows.c @@ -197,6 +197,12 @@ lv_result_t lv_thread_sync_delete(lv_thread_sync_t * sync) return LV_RESULT_OK; } +lv_result_t lv_thread_sync_signal_isr(lv_thread_sync_t * sync) +{ + LV_UNUSED(sync); + return LV_RESULT_INVALID; +} + /********************** * STATIC FUNCTIONS **********************/