/**
 ******************************************************************************
 * @file    kpm32xx_ddl_gpio.h
 * @author  Kiwi Software Team
 * @brief   Header file of GPIO DDL module.
 * @note
 *		   V1.0.0, 2024/12/20.
 *
  * Copyright (c) 2024, Kiwi Instruments Co,. Ltd.
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 *	1. Redistributions of source code must retain the above copyright notice,
 *	   this list of conditions and the following disclaimer.
 *
 *	2. Redistributions in binary form must reproduce the above copyright notice,
 *	   this list of conditions and the following disclaimer in the documentation
 *	   and/or other materials provided with the distribution.
 *
 *	3. Neither the name of the copyright holder nor the names of its contributors
 *	   may be used to endorse or promote products derived from this software without
 *	   specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
 * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 ******************************************************************************
 */


#ifndef __KPM32xx_DDL_GPIO_H
#define __KPM32xx_DDL_GPIO_H

#ifdef __cplusplus
extern "C" {
#endif

#include "kpm32xx_ddl_def.h"

typedef struct
{
	uint32_t pin;
	uint32_t initValue;    /* The initial value before GPIO outputs */
	uint32_t mode;
	uint32_t pull;
	uint32_t alternate;
	uint32_t drvCapacity;   /* IO driving capacity */
	uint32_t openDrain;     /* OpenDrain*/
} GPIO_Init_T;

typedef enum
{
	GPIO_PIN_RESET = 0U,
	GPIO_PIN_SET
} GPIO_PinState_T;

typedef enum
{
    PIN_AS_OUTPUT = 0,
    PIN_AS_INPUT,
} GPIO_PinDir_T;

typedef struct
{
    uint8_t enable;    /* GPIO port x noise filter enable */
    uint8_t clock;     /* GPIO port x noise filter clock */
} GPIO_InputNF_T;

typedef enum
{
	PIN_NFLT_DISABLE = 0U,
	PIN_NFLT_ENABLE  = 1U
} GPIO_NFBPState;


typedef enum
{
	EVTACK_OP_LOW       = 0x00UL << GPIO_EVT_ACK_Pos,
	EVTACK_OP_HIGH      = 0x01UL << GPIO_EVT_ACK_Pos,
	EVTACK_OP_TOGGLE    = 0x02UL << GPIO_EVT_ACK_Pos,
} GPIO_EvtAckState;

typedef struct
{
	uint32_t pin;
	uint32_t evtChn;  /* event channel */
	uint32_t evtAck;  /* Output Low, High or Toggle */
}GPIO_Evt_T;

/* For GPIO pin Set */
#define GPIO_PIN_0                  ((uint16_t)0x0001)  /* pin 0 selected    */
#define GPIO_PIN_1                  ((uint16_t)0x0002)  /* pin 1 selected    */
#define GPIO_PIN_2                  ((uint16_t)0x0004)  /* pin 2 selected    */
#define GPIO_PIN_3                  ((uint16_t)0x0008)  /* pin 3 selected    */
#define GPIO_PIN_4                  ((uint16_t)0x0010)  /* pin 4 selected    */
#define GPIO_PIN_5                  ((uint16_t)0x0020)  /* pin 5 selected    */
#define GPIO_PIN_6                  ((uint16_t)0x0040)  /* pin 6 selected    */
#define GPIO_PIN_7                  ((uint16_t)0x0080)  /* pin 7 selected    */
#define GPIO_PIN_8                  ((uint16_t)0x0100)  /* pin 8 selected    */
#define GPIO_PIN_9                  ((uint16_t)0x0200)  /* pin 9 selected    */
#define GPIO_PIN_10                 ((uint16_t)0x0400)  /* pin 10 selected   */
#define GPIO_PIN_11                 ((uint16_t)0x0800)  /* pin 11 selected   */
#define GPIO_PIN_12                 ((uint16_t)0x1000)  /* pin 12 selected   */
#define GPIO_PIN_13                 ((uint16_t)0x2000)  /* pin 13 selected   */
#define GPIO_PIN_14                 ((uint16_t)0x4000)  /* pin 14 selected   */
#define GPIO_PIN_15                 ((uint16_t)0x8000)  /* pin 15 selected   */
#define GPIO_PIN_All                ((uint16_t)0xFFFF)  /* All pins selected */
#define GPIO_PIN_MASK               (0x0000FFFFU)       /* PIN mask for assert test */

/* For GPIO mode Set */
#define  GPIO_MODE_INPUT            ((uint32_t)0x00000001U)   /* Input floating mode     */
#define  GPIO_MODE_OUTPUT           ((uint32_t)0x00000002U)   /* Output push pull mode   */
#define  GPIO_MODE_AF               ((uint32_t)0x00000004U)   /* alternate function mode */
#define  GPIO_MODE_ANALOG           ((uint32_t)0x00000008U)   /* Analog mode */
#define  GPIO_MODE                  ((uint32_t)0x0000000FU)


/* GPIO pull or nopull set */
#define GPIO_NOPULL                 ((uint32_t)0x00000000U)    /* No pull-up activation  */
#define GPIO_PULLUP                 ((uint32_t)0x00000001U)    /* pull-up activation     */
/* GPIO pulldown set */
#define GPIO_PULLDOWN               ((uint32_t)0x00000002U)    /* pull-down activation   */
/* GPIO pull mask set */
#define GPIO_PULL_MASK              ((uint32_t)0x00000003U)

/* GPIO Clock Filter */
#define GPIO_NFCLK_CLK0             ((uint32_t)0x00000000U)
#define GPIO_NFCLK_CLK1             ((uint32_t)0x00000001U)
#define GPIO_NFCLK_CLK2             ((uint32_t)0x00000002U)
#define GPIO_NFCLK_LIRC             ((uint32_t)0x00000003U)


#define IS_GPIO_PIN(__PIN__)        ((((uint32_t)(__PIN__) & GPIO_PIN_MASK) != 0x00u) &&\
                                     (((uint32_t)(__PIN__) & ~GPIO_PIN_MASK) == 0x00u))

#define IS_GPIO_MODE(__MODE__)      (((__MODE__) == GPIO_MODE_INPUT)         ||\
                                     ((__MODE__) == GPIO_MODE_OUTPUT)        ||\
                                     ((__MODE__) == GPIO_MODE_AF)            ||\
                                     ((__MODE__) == GPIO_MODE_ANALOG))

#define IS_GPIO_PULL(__PULL__)      (((__PULL__) == GPIO_NOPULL)             ||\
                                     ((__PULL__) == GPIO_PULLUP)             ||\
                                     ((__PULL__) == GPIO_PULLDOWN))

/**
  * @brief  Make GPIO peripheral active.
  * @param  None.
  *
  * @retval None.
  */
void DDL_GPIO_Instance_Active(void);

/**
  * @brief  Configure GPIO as Input mode.
  * @param  GPIOx  pointer to a GPIO_Type structure.
  * @param  gpioPin GPIO pin.
  * @param  pullMsk GPIO pull up/down or none-pull.
  *
  * @retval None.
  */
void DDL_GPIO_Config2Input(GPIO_Type *GPIOx, uint32_t gpioPin, uint32_t pullMsk);

/**
  * @brief  Configure the drive capacity of one GPIO pin.
  * @param  GPIOx  pointer to a GPIO_Type structure.
  * @param  gpioPin GPIO pin.
  * @param  drvCapacity GPIO IO driving capacity.
  *
  * @retval None.
  */
void DDL_GPIO_DrvCapcityConfig(GPIO_Type *GPIOx, uint32_t gpioPin, uint32_t drvCapacity);

/**
  * @brief  Configure open drain feature of one GPIO pin.
  * @param  GPIOx  pointer to a GPIO_Type structure.
  * @param  gpioPin GPIO pin.
  * @param  openDrain GPIO IO open drain.
  *
  * @retval None.
  */
void DDL_GPIO_OpenDrainConfig(GPIO_Type *GPIOx, uint32_t gpioPin, uint32_t openDrain);

/**
  * @brief  Configure GPIO as Output mode.
  * @param  GPIOx  pointer to a GPIO_Type structure.
  * @param  gpioPin GPIO pin.
  * @param  initValue GPIO initial value before output.
  * @param  pullMsk GPIO pull up/down or none-pull.
  *
  * @retval None.  
  */
void DDL_GPIO_Config2Output(GPIO_Type *GPIOx, uint32_t gpioPin, uint32_t initValue, uint32_t pullMsk);

/**
  * @brief  Configure GPIO as Alternative Mode.
  * @param  GPIOx  pointer to a GPIO_Type structure.
  * @param  gpioPin GPIO pin.
  * @param  alternate GPIO alternative function.
  *
  * @retval None.
  */
void DDL_GPIO_Config2AltFunc(GPIO_Type *GPIOx, uint32_t gpioPin, uint32_t alternate);

/**
  * @brief  Configure GPIO as Analog Mode.
  * @param  GPIOx  pointer to a GPIO_Type structure.
  * @param  gpioPin GPIO pin.
  *
  * @retval None.
  */
void DDL_GPIO_Config2Analog(GPIO_Type *GPIOx, uint32_t gpioPin);

/**
  * @brief  Read out the state of one GPIO Pin with the indication of high or low level.
  * @param  GPIOx     pointer to a GPIO_Type structure.
  *         gpioPin   GPIO pin in one GPIO port. Refer to GPIO_PIN_0 ~ GPIO_PIN_15.
  *
  * @retval GPIO Pin State.
  */
GPIO_PinState_T DDL_GPIO_ReadPin(GPIO_Type *GPIOx, uint16_t gpioPin);

/**
  * @brief  Configure one GPIO Pin as high or low level.
  * @param  GPIOx     pointer to a GPIO_Type structure.
  *         gpioPin   GPIO pin in one GPIO port. Refer to GPIO_PIN_0 ~ GPIO_PIN_15.
  *         pinState  the expected high or low level state.
  *
  * @retval None.
  */
void DDL_GPIO_WritePin(GPIO_Type *GPIOx, uint16_t gpioPin, GPIO_PinState_T pinState);

/**
  * @brief  Toggle one GPIO Pin from high to low or vice versa.
  * @param  GPIOx     pointer to a GPIO_Type structure.
  *         gpioPin   GPIO pin in one GPIO port. Refer to GPIO_PIN_0 ~ GPIO_PIN_15.
  *
  * @retval None.
  */
void DDL_GPIO_TogglePin(GPIO_Type *GPIOx, uint16_t gpioPin);

/**
  * @brief  Configure GPIO as Input mode.
  * @param  GPIOx  pointer to a GPIO_Type structure.
  * @param  gpioPin GPIO pin.
  *
  * @retval None.
  */
void DDL_GPIO_PinInputDirectionConfig(GPIO_Type *GPIOx, uint16_t gpioPin);

/**
  * @brief  EBUS event triggers GPIO. GPIO could output as High, Low state or
  *         switch between High and Low states.
  *
  *         Caution:  Only one GPIO Pin can be triggered by EBUS event
  *                   in each GPIO Port.
  *
  * @param  GPIOx     pointer to a GPIO_Type structure.
  *         gpioEvt   pointer to a GPIO_Evt_T structure that contains
  *                   configuration information for the given GPIO Pin.
  *  
  * @retval None.
  */
void  DDL_GPIO_EBus_Start(GPIO_Type *GPIOx, GPIO_Evt_T *gpioEvt);

/**
  * @brief  Configure GPIO as Output mode.
  * @param  GPIOx  pointer to a GPIO_Type structure.
  * @param  gpioPin GPIO pin.
  *
  * @retval None.  
  */
void DDL_GPIO_PinOutputDirectionConfig(GPIO_Type *GPIOx, uint16_t gpioPin);

/**
  * @brief  Configure GPIO filters
  *
  * @param  GPIOx     pointer to a GPIO_Type structure.
  *         gpioPin   GPIO pin in one GPIO port. Refer to GPIO_PIN_0 ~ GPIO_PIN_15.
  *         pFilter   pointer to a GPIO_InputNF_T structure that contains
  *                   configuration information for the given GPIO Pin.
  *
  * @retval DDL Status.
  */
DDL_Status_T DDL_GPIO_PinNoiseFilterConfig(GPIO_Type *GPIOx, uint16_t gpioPin, GPIO_InputNF_T *pFilter);



#ifdef __cplusplus
}
#endif

#endif /* __KPM32xx_DDL_GPIO_H */
