/******************************************************************************
**
** Copyright (C) 2021 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Quick Ultralite module.
**
** $QT_BEGIN_LICENSE:COMM$
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see http://www.qt.io/terms-conditions. For further
** information use the contact form at http://www.qt.io/contact-us.
**
** $QT_END_LICENSE$
**
******************************************************************************/
#include "nxp_os.h"
#include "power.h"

#include <FreeRTOS.h>
#include <semphr.h>
#include <task.h>
#include <portmacro.h>
#include "FreeRTOSConfig.h"

#include <stdint.h>

static SemaphoreHandle_t mainloopSemaphore = NULL;
static SemaphoreHandle_t lcdPxpSemaphore = NULL;

void nxp_initSuspension()
{
    mainloopSemaphore = xSemaphoreCreateBinary();
    lcdPxpSemaphore = xSemaphoreCreateBinary();
}

void nxp_suspend(SemaphoreType semaphoreType, int timeout)
{
    SemaphoreHandle_t semaphore;
    switch (semaphoreType) {
    case MAINLOOP_SEMAPHORE:
        semaphore = mainloopSemaphore;
        break;
    case LCD_PXP_SEMAPHORE:
        semaphore = lcdPxpSemaphore;
        break;
    default:
        semaphore = NULL;
    }

    TickType_t timeoutTicks = 0;
    if (timeout < 0)
        timeoutTicks = portMAX_DELAY;
    else
        timeoutTicks = timeout / portTICK_PERIOD_MS;

    if (semaphore)
        xSemaphoreTake(semaphore, timeoutTicks);
}

void nxp_resume(SemaphoreType semaphoreType)
{
    SemaphoreHandle_t semaphore;
    switch (semaphoreType) {
    case MAINLOOP_SEMAPHORE:
        semaphore = mainloopSemaphore;
        break;
    case LCD_PXP_SEMAPHORE:
        semaphore = lcdPxpSemaphore;
        break;
    default:
        semaphore = NULL;
    }

    if (semaphore) {
        if (xPortIsInsideInterrupt() == pdTRUE)
            xSemaphoreGiveFromISR(semaphore, NULL);
        else
            xSemaphoreGive(semaphore);
    }
}

void vApplicationIdleHook()
{
    enterSleepMode();
}

extern void xPortSysTickHandler();
void nxp_systick(void)
{
#if (INCLUDE_xTaskGetSchedulerState == 1)
    if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) {
#endif /* INCLUDE_xTaskGetSchedulerState */
        xPortSysTickHandler();
#if (INCLUDE_xTaskGetSchedulerState == 1)
    }
#endif /* INCLUDE_xTaskGetSchedulerState */
}
