/*
 * Copyright 2018 - 2019 NXP
 * All rights reserved.
 *
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include "fsl_device_registers.h"
#include "fsl_gpio.h"
#include "gpio.h"

/*******************************************************************************
 * Definitions
 ******************************************************************************/

/*! @brief The pin config struct of gpio adapter. */
typedef struct _hal_gpio_pin
{
    uint16_t port : 3U;
    uint16_t pin : 5U;
    uint16_t direction : 1U;
    uint16_t trigger : 3U;
    uint16_t reserved : 4U;
} hal_gpio_pin_t;

typedef struct _hal_gpio_state
{
    struct _hal_gpio_state *next;
    hal_gpio_callback_t callback;
    void *callbackParam;
    hal_gpio_pin_t pin;
} hal_gpio_state_t;

/*******************************************************************************
 * Prototypes
 ******************************************************************************/

static void HAL_GpioInterruptHandle(uint8_t port);

/*******************************************************************************
 * Variables
 ******************************************************************************/

static hal_gpio_state_t *s_GpioHead;

/*******************************************************************************
 * Code
 ******************************************************************************/

static void HAL_GpioInterruptHandle(uint8_t port)
{
    hal_gpio_state_t *head = s_GpioHead;
    GPIO_Type *gpioList[]  = GPIO_BASE_PTRS;
    uint32_t intFlag;

    /* Get and clear gpio pin interrupt Flag */
    intFlag = GPIO_PortGetInterruptFlags(gpioList[port]);
    GPIO_PortClearInterruptFlags(gpioList[port], intFlag);

    while (NULL != head)
    {
        /* Check which triger is ON! */
        if (kHAL_GpioInterruptDisable != (hal_gpio_interrupt_trigger_t)head->pin.trigger)
        {
            if ((port == head->pin.port) && (0U != (intFlag & (1U << head->pin.pin))))
            {
                if ((NULL != head->callback))
                {
                    head->callback(head->callbackParam);
                }
            }
        }

        head = head->next;
    }
}
/* IRQHandler for GPIO1 */
#if defined(GPIO1) && (FSL_FEATURE_SOC_IGPIO_COUNT > 0U)
void GPIO1_Combined_0_15_IRQHandler(void);
void GPIO1_Combined_0_15_IRQHandler(void)
{
    HAL_GpioInterruptHandle(1);

#if defined __CORTEX_M && (__CORTEX_M == 4U)
    __DSB();
#endif
}
void GPIO1_Combined_16_31_IRQHandler(void);
void GPIO1_Combined_16_31_IRQHandler(void)
{
    HAL_GpioInterruptHandle(1);

#if defined __CORTEX_M && (__CORTEX_M == 4U)
    __DSB();
#endif
}
#endif
/* IRQHandler for GPIO2 */
#if defined(GPIO2) && (FSL_FEATURE_SOC_IGPIO_COUNT > 0U)
void GPIO2_Combined_0_15_IRQHandler(void);
void GPIO2_Combined_0_15_IRQHandler(void)
{
    HAL_GpioInterruptHandle(2);

#if defined __CORTEX_M && (__CORTEX_M == 4U)
    __DSB();
#endif
}
void GPIO2_Combined_16_31_IRQHandler(void);
void GPIO2_Combined_16_31_IRQHandler(void)
{
    HAL_GpioInterruptHandle(2);

#if defined __CORTEX_M && (__CORTEX_M == 4U)
    __DSB();
#endif
}
#endif
/* IRQHandler for GPIO3 */
#if defined(GPIO3) && (FSL_FEATURE_SOC_IGPIO_COUNT > 0U)
void GPIO3_Combined_0_15_IRQHandler(void);
void GPIO3_Combined_0_15_IRQHandler(void)
{
    HAL_GpioInterruptHandle(3);

#if defined __CORTEX_M && (__CORTEX_M == 4U)
    __DSB();
#endif
}
void GPIO3_Combined_16_31_IRQHandler(void);
void GPIO3_Combined_16_31_IRQHandler(void)
{
    HAL_GpioInterruptHandle(3);

#if defined __CORTEX_M && (__CORTEX_M == 4U)
    __DSB();
#endif
}
#endif
/* IRQHandler for GPIO4 */
#if defined(GPIO4) && (FSL_FEATURE_SOC_IGPIO_COUNT > 0U)
void GPIO4_Combined_0_15_IRQHandler(void);
void GPIO4_Combined_0_15_IRQHandler(void)
{
    HAL_GpioInterruptHandle(4);

#if defined __CORTEX_M && (__CORTEX_M == 4U)
    __DSB();
#endif
}
void GPIO4_Combined_16_31_IRQHandler(void);
void GPIO4_Combined_16_31_IRQHandler(void)
{
    HAL_GpioInterruptHandle(4);

#if defined __CORTEX_M && (__CORTEX_M == 4U)
    __DSB();
#endif
}
#endif
/* IRQHandler for GPIO5 */
#if defined(GPIO5) && (FSL_FEATURE_SOC_IGPIO_COUNT > 0U)
void GPIO5_Combined_0_15_IRQHandler(void);
void GPIO5_Combined_0_15_IRQHandler(void)
{
    HAL_GpioInterruptHandle(5);

#if defined __CORTEX_M && (__CORTEX_M == 4U)
    __DSB();
#endif
}
void GPIO5_Combined_16_31_IRQHandler(void);
void GPIO5_Combined_16_31_IRQHandler(void)
{
    HAL_GpioInterruptHandle(5);

#if defined __CORTEX_M && (__CORTEX_M == 4U)
    __DSB();
#endif
}
#endif
/* IRQHandler for GPIO6 GPIO7 GPIO8 GPIO9 */
#if defined(GPIO6) && defined(GPIO7) && defined(GPIO8) && defined(GPIO9) && (FSL_FEATURE_SOC_IGPIO_COUNT > 8U)
void GPIO6_7_8_9_IRQHandler(void);
void GPIO6_7_8_9_IRQHandler(void)
{
    HAL_GpioInterruptHandle(6);
    HAL_GpioInterruptHandle(7);
    HAL_GpioInterruptHandle(8);
    HAL_GpioInterruptHandle(9);

#if defined __CORTEX_M && (__CORTEX_M == 4U)
    __DSB();
#endif
}
#endif

static hal_gpio_status_t HAL_GpioConflictSearch(hal_gpio_state_t *head, uint8_t port, uint8_t pin)
{
    while (head)
    {
        if ((head->pin.port == port) && (head->pin.pin == pin))
        {
            return kStatus_HAL_GpioPinConflict;
        }
        head = head->next;
    }
    return kStatus_HAL_GpioSuccess;
}

static hal_gpio_status_t HAL_GpioAddItem(hal_gpio_state_t **head, hal_gpio_state_t *node)
{
    hal_gpio_state_t *p = *head;
    uint32_t regPrimask;

    regPrimask = DisableGlobalIRQ();

    if (NULL == p)
    {
        *head = node;
    }
    else
    {
        while (p->next)
        {
            if (p == node)
            {
                EnableGlobalIRQ(regPrimask);
                return kStatus_HAL_GpioPinConflict;
            }
            p = p->next;
        }

        p->next = node;
    }
    node->next = NULL;
    EnableGlobalIRQ(regPrimask);
    return kStatus_HAL_GpioSuccess;
}

static hal_gpio_status_t HAL_GpioRemoveItem(hal_gpio_state_t **head, hal_gpio_state_t *node)
{
    hal_gpio_state_t *p = *head;
    hal_gpio_state_t *q = NULL;
    uint32_t regPrimask;

    regPrimask = DisableGlobalIRQ();
    while (p)
    {
        if (p == node)
        {
            if (NULL == q)
            {
                *head = p->next;
            }
            else
            {
                q->next = p->next;
            }
            break;
        }
        else
        {
            q = p;
            p = p->next;
        }
    }
    EnableGlobalIRQ(regPrimask);
    return kStatus_HAL_GpioSuccess;
}

hal_gpio_status_t HAL_GpioInit(hal_gpio_handle_t gpioHandle, hal_gpio_pin_config_t *pinConfig)
{
    hal_gpio_state_t *gpioState;
    GPIO_Type *gpioList[]           = GPIO_BASE_PTRS;
    hal_gpio_status_t status        = kStatus_HAL_GpioSuccess;
    gpio_pin_config_t gpioPinconfig = {
        kGPIO_DigitalInput,
        0,
        kGPIO_NoIntmode,
    };

    assert(gpioHandle);
    assert(pinConfig);

    if (HAL_GPIO_HANDLE_SIZE < sizeof(hal_gpio_state_t))
    {
        return kStatus_HAL_GpioError;
    }

    gpioState = (hal_gpio_state_t *)gpioHandle;

    /* Check if the port is vaild */
    if (NULL == gpioList[pinConfig->port])
    {
        return kStatus_HAL_GpioError;
    }

    if ((NULL != s_GpioHead) &&
        (kStatus_HAL_GpioSuccess != HAL_GpioConflictSearch(s_GpioHead, pinConfig->port, pinConfig->pin)))
    {
        return kStatus_HAL_GpioPinConflict;
    }

    status = HAL_GpioAddItem(&s_GpioHead, gpioState);
    if (kStatus_HAL_GpioSuccess != status)
    {
        return status;
    }

    gpioState->pin.pin       = pinConfig->pin;
    gpioState->pin.port      = pinConfig->port;
    gpioState->pin.direction = (uint16_t)pinConfig->direction;
    gpioState->pin.trigger   = (uint16_t)kHAL_GpioInterruptDisable;

    if (kHAL_GpioDirectionOut == (hal_gpio_direction_t)pinConfig->direction)
    {
        gpioPinconfig.direction = kGPIO_DigitalOutput;
    }
    else
    {
        gpioPinconfig.direction = kGPIO_DigitalInput;
    }
    gpioPinconfig.outputLogic = pinConfig->level;
    GPIO_PinInit(gpioList[gpioState->pin.port], gpioState->pin.pin, &gpioPinconfig);
    return kStatus_HAL_GpioSuccess;
}

hal_gpio_status_t HAL_GpioDeinit(hal_gpio_handle_t gpioHandle)
{
    hal_gpio_state_t *gpioState;
    GPIO_Type *gpioList[] = GPIO_BASE_PTRS;

    assert(gpioHandle);

    gpioState = (hal_gpio_state_t *)gpioHandle;

    if ((uint16_t)kHAL_GpioDirectionIn == gpioState->pin.direction)
    {
        GPIO_PortDisableInterrupts(gpioList[gpioState->pin.port], (uint32_t)(1U << gpioState->pin.pin));
    }

    HAL_GpioRemoveItem(&s_GpioHead, gpioState);
    return kStatus_HAL_GpioSuccess;
}

hal_gpio_status_t HAL_GpioGetInput(hal_gpio_handle_t gpioHandle, uint8_t *pinState)
{
    hal_gpio_state_t *gpioStateHandle;
    GPIO_Type *gpioList[] = GPIO_BASE_PTRS;

    assert(gpioHandle);

    gpioStateHandle = (hal_gpio_state_t *)gpioHandle;

    *pinState = ((GPIO_PinRead(gpioList[gpioStateHandle->pin.port], gpioStateHandle->pin.pin)) ? 1 : 0);
    return kStatus_HAL_GpioSuccess;
}

hal_gpio_status_t HAL_GpioSetOutput(hal_gpio_handle_t gpioHandle, uint8_t pinState)
{
    hal_gpio_state_t *gpioStateHandle;
    GPIO_Type *gpioList[] = GPIO_BASE_PTRS;

    assert(gpioHandle);

    gpioStateHandle = (hal_gpio_state_t *)gpioHandle;

    GPIO_PinWrite(gpioList[gpioStateHandle->pin.port], gpioStateHandle->pin.pin, (pinState) ? 1 : 0);
    return kStatus_HAL_GpioSuccess;
}

hal_gpio_status_t HAL_GpioInstallCallback(hal_gpio_handle_t gpioHandle,
                                          hal_gpio_callback_t callback,
                                          void *callbackParam)
{
    hal_gpio_state_t *gpioStateHandle;

    assert(gpioHandle);

    gpioStateHandle = (hal_gpio_state_t *)gpioHandle;

    gpioStateHandle->callbackParam = callbackParam;
    gpioStateHandle->callback      = callback;

    return kStatus_HAL_GpioSuccess;
}

hal_gpio_status_t HAL_GpioGetTriggerMode(hal_gpio_handle_t gpioHandle, hal_gpio_interrupt_trigger_t *gpioTrigger)
{
    hal_gpio_state_t *gpioStateHandle;

    assert(gpioHandle);

    gpioStateHandle = (hal_gpio_state_t *)gpioHandle;

    if (kHAL_GpioDirectionOut == (hal_gpio_direction_t)gpioStateHandle->pin.direction)
    {
        return kStatus_HAL_GpioError;
    }

    *gpioTrigger = (hal_gpio_interrupt_trigger_t)gpioStateHandle->pin.trigger;
    return kStatus_HAL_GpioSuccess;
}

hal_gpio_status_t HAL_GpioSetTriggerMode(hal_gpio_handle_t gpioHandle, hal_gpio_interrupt_trigger_t gpioTrigger)
{
    hal_gpio_state_t *gpioStateHandle;
    GPIO_Type *gpioList[] = GPIO_BASE_PTRS;
    uint32_t regPrimask;
    IRQn_Type gpioLowIRQsList[]  = GPIO_COMBINED_LOW_IRQS;
    IRQn_Type gpioHighIRQsList[] = GPIO_COMBINED_HIGH_IRQS;
    gpio_interrupt_mode_t triggerType;

    assert(gpioHandle);

    gpioStateHandle = (hal_gpio_state_t *)gpioHandle;

    if (kHAL_GpioDirectionOut == (hal_gpio_direction_t)gpioStateHandle->pin.direction)
    {
        return kStatus_HAL_GpioError;
    }

    switch (gpioTrigger)
    {
        case kHAL_GpioInterruptLogicZero:
            triggerType = kGPIO_IntLowLevel;
            break;
        case kHAL_GpioInterruptLogicOne:
            triggerType = kGPIO_IntHighLevel;
            break;
        case kHAL_GpioInterruptRisingEdge:
            triggerType = kGPIO_IntRisingEdge;
            break;
        case kHAL_GpioInterruptFallingEdge:
            triggerType = kGPIO_IntFallingEdge;
            break;
        case kHAL_GpioInterruptEitherEdge:
            triggerType = kGPIO_IntRisingOrFallingEdge;
            break;
        default:
            triggerType = kGPIO_NoIntmode;
            break;
    }

    gpioStateHandle->pin.trigger = (uint16_t)gpioTrigger;

    /* Disbale Global Interrupt */
    regPrimask = DisableGlobalIRQ();

    /* initialize gpio interrupt */
    GPIO_PinSetInterruptConfig(gpioList[gpioStateHandle->pin.port], gpioStateHandle->pin.pin, triggerType);

    /* Enable IRQ */
    if (triggerType != kGPIO_NoIntmode)
    {
        GPIO_PortEnableInterrupts(gpioList[gpioStateHandle->pin.port], (1U << gpioStateHandle->pin.pin));
        if (gpioStateHandle->pin.pin <= 15)
        {
            NVIC_SetPriority(gpioLowIRQsList[gpioStateHandle->pin.port], HAL_GPIO_ISR_PRIORITY);
            (void)EnableIRQ(gpioLowIRQsList[gpioStateHandle->pin.port]);
        }
        else
        {
            NVIC_SetPriority(gpioHighIRQsList[gpioStateHandle->pin.port], HAL_GPIO_ISR_PRIORITY);
            (void)EnableIRQ(gpioHighIRQsList[gpioStateHandle->pin.port]);
        }
    }
    else
    {
        GPIO_PortDisableInterrupts(gpioList[gpioStateHandle->pin.port], (uint32_t)(1 << gpioStateHandle->pin.pin));
    }

    /* Enable Global Interrupt */
    EnableGlobalIRQ(regPrimask);

    return kStatus_HAL_GpioSuccess;
}

hal_gpio_status_t HAL_GpioWakeUpSetting(hal_gpio_handle_t gpioHandle, uint8_t enable)
{
    hal_gpio_state_t *gpioStateHandle;
    assert(gpioHandle);

    gpioStateHandle = (hal_gpio_state_t *)gpioHandle;

    if (kHAL_GpioDirectionOut == (hal_gpio_direction_t)gpioStateHandle->pin.direction)
    {
        return kStatus_HAL_GpioError;
    }

    return kStatus_HAL_GpioSuccess;
}

hal_gpio_status_t HAL_GpioEnterLowpower(hal_gpio_handle_t gpioHandle)
{
    assert(gpioHandle);

    return kStatus_HAL_GpioSuccess;
}

hal_gpio_status_t HAL_GpioExitLowpower(hal_gpio_handle_t gpioHandle)
{
    assert(gpioHandle);

    return kStatus_HAL_GpioSuccess;
}
