/* Copyright Statement:
 *
 * This software/firmware and related documentation ("AutoChips Software") are
 * protected under relevant copyright laws. The information contained herein is
 * confidential and proprietary to AutoChips Inc. and/or its licensors. Without
 * the prior written permission of AutoChips inc. and/or its licensors, any
 * reproduction, modification, use or disclosure of AutoChips Software, and
 * information contained herein, in whole or in part, shall be strictly
 * prohibited.
 *
 * AutoChips Inc. (C) 2022. All rights reserved.
 *
 * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
 * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("AUTOCHIPS SOFTWARE")
 * RECEIVED FROM AUTOCHIPS AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER
 * ON AN "AS-IS" BASIS ONLY. AUTOCHIPS EXPRESSLY DISCLAIMS ANY AND ALL
 * WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
 * NONINFRINGEMENT. NEITHER DOES AUTOCHIPS PROVIDE ANY WARRANTY WHATSOEVER WITH
 * RESPECT TO THE SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY,
 * INCORPORATED IN, OR SUPPLIED WITH THE AUTOCHIPS SOFTWARE, AND RECEIVER AGREES
 * TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO.
 * RECEIVER EXPRESSLY ACKNOWLEDGES THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO
 * OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES CONTAINED IN AUTOCHIPS
 * SOFTWARE. AUTOCHIPS SHALL ALSO NOT BE RESPONSIBLE FOR ANY AUTOCHIPS SOFTWARE
 * RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
 * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND AUTOCHIPS'S
 * ENTIRE AND CUMULATIVE LIABILITY WITH RESPECT TO THE AUTOCHIPS SOFTWARE
 * RELEASED HEREUNDER WILL BE, AT AUTOCHIPS'S OPTION, TO REVISE OR REPLACE THE
 * AUTOCHIPS SOFTWARE AT ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE
 * CHARGE PAID BY RECEIVER TO AUTOCHIPS FOR SUCH AUTOCHIPS SOFTWARE AT ISSUE.
 */

#ifndef _AC780X_GPIO_H
#define _AC780X_GPIO_H
/*!
 * @file ac780x_gpio.h
 *
 * @brief This file provides gpio integration functions interface.
 *
 */
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

/* ===========================================  Includes  =========================================== */
#include "ac7802x.h"

/* ============================================  Define  ============================================ */
/*!
* @brief GPIO instance index macro, GPIOx should be GPIOA/GPIOB
*/
#define GPIO_INDEX(GPIOx)    ((GPIO_IndexType)(((uint32_t)(GPIOx) - GPIOA_BASE) / 0x30))

/*!< GPIO pin max number: 0~27 */
#define GPIO_PIN_MAX_NUM     (27UL)

/*!< GPIO base addr parameter check */
#define IS_GPIO_PERIPH(GPIOx) (((GPIOx) == GPIOA) || ((GPIOx) == GPIOB))

/*!< GPIO pin bit action check, should be 0 or 1 */
#define IS_GPIO_BIT_ACTION(action) (((action) == ENABLE)  || ((action) == DISABLE))

/* ===========================================  Typedef  ============================================ */
/*!< GPIO module index enumeration. */
typedef enum
{
    GPIOA_INDEX = 0,       /*!< 0: GPIOA index */
    GPIOB_INDEX,           /*!< 1: GPIOB index */
    GPIO_INDEX_MAX
}GPIO_IndexType;

typedef enum{
    GPIO_PIN0_MASK = (uint32_t)0x1,
    GPIO_PIN1_MASK = (uint32_t)0x2,
    GPIO_PIN2_MASK = (uint32_t)0x4,
    GPIO_PIN3_MASK = (uint32_t)0x8,
    GPIO_PIN4_MASK = (uint32_t)0x10,
    GPIO_PIN5_MASK = (uint32_t)0x20,
    GPIO_PIN6_MASK = (uint32_t)0x40,
    GPIO_PIN7_MASK = (uint32_t)0x80,
    GPIO_PIN8_MASK = (uint32_t)0x100,
    GPIO_PIN9_MASK = (uint32_t)0x200,
    GPIO_PIN10_MASK = (uint32_t)0x400,
    GPIO_PIN11_MASK = (uint32_t)0x800,
    GPIO_PIN12_MASK = (uint32_t)0x1000,
    GPIO_PIN13_MASK = (uint32_t)0x2000,
    GPIO_PIN14_MASK = (uint32_t)0x4000,
    GPIO_PIN15_MASK = (uint32_t)0x8000,
    GPIO_PIN_ALL_MASK = (uint32_t)0xFFFF,
}GPIO_PinMaskType;

typedef enum{
    GPIO_PIN0 = 0,
    GPIO_PIN1,
    GPIO_PIN2,
    GPIO_PIN3,
    GPIO_PIN4,
    GPIO_PIN5,
    GPIO_PIN6,
    GPIO_PIN7,
    GPIO_PIN8,
    GPIO_PIN9,
    GPIO_PIN10,
    GPIO_PIN11,
    GPIO_PIN12,
    GPIO_PIN13,
    GPIO_PIN14,
    GPIO_PIN15,
    GPIO_PIN_MAX_ONE_GROUP,
}GPIO_PinType;
 /*!< GPIO pin check, should be 0~15 */
#define IS_GPIO_PIN(PINx) ((PINx) <= GPIO_PIN15)

/*!< GPIO pin level enumeration */
typedef enum
{
    GPIO_LEVEL_LOW = 0,
    GPIO_LEVEL_HIGH
}GPIO_LevelType;

typedef enum
{
    GPIO_IN = 0,
    GPIO_OUT
}GPIO_DirType;
/*!< GPIO pin direction check, should be 0 or 1 */
#define IS_GPIO_DIR(dir) (((dir) == GPIO_IN)  || ((dir) == GPIO_OUT))

typedef enum
{
    GPIO_FLOATING = 0,
    GPIO_PU,
    GPIO_PD
}GPIO_PuPdType;

typedef enum
{
    GPIO_FUN0 = 0,
    GPIO_FUN1,
    GPIO_FUN2,
    GPIO_FUN3
}GPIO_FunType;
 /*!< GPIO PINMUX function check, should be 0~3 */
#define IS_GPIO_PINMUX(func) (((func) == GPIO_FUN0)  || ((func) == GPIO_FUN1) || \
                              ((func) == GPIO_FUN2) || ((func) == GPIO_FUN3))

typedef enum
{
    GPIO_DRIVING_4MA = 0,
    GPIO_DRIVING_8MA,
    GPIO_DRIVING_12MA,
    GPIO_DRIVING_16MA
}GPIO_DrivingType;

typedef struct
{
    GPIO_DirType GPIO_Dir;
    GPIO_PuPdType GPIO_PuPd;
    GPIO_FunType GPIO_Fun;
}GPIO_ModeType;

typedef struct
{
    GPIO_PinType GPIO_Pin;             /*!< pin: 0~15 */
    GPIO_ModeType GPIO_Mode;
    GPIO_DrivingType GPIO_Driving;
}GPIO_ConfigType;

typedef enum
{
    EXTI_TRIGGER_FALLING=0,
    EXTI_TRIGGER_RISING,
    EXTI_TRIGGER_RISING_FALLING,
}EXTI_TriggerType;
/*!< GPIO exti trigger check, should be 0~2 */
#define IS_EXTI_TRIGGER(trigger) (((trigger) == EXTI_TRIGGER_FALLING) || \
                                  ((trigger) == EXTI_TRIGGER_RISING) ||  \
                                  ((trigger) == EXTI_TRIGGER_RISING_FALLING))
typedef struct
{
    uint32_t *PMUXx;                 /*!< PMUX index, can be configured by GPIO_GetPMUXConfig() */
    uint32_t PMUXx_PFSEL;            /*!< PFSEL index, can be configured by GPIO_GetPMUXConfig() */
}GPIO_ConfigPmuxType;

/* ==========================================  Variables  =========================================== */

/* ====================================  Functions declaration  ===================================== */
/*!
* @brief Set several GPIO pins' Pmux and pin function
*
* @param[in] GPIOx: GPIO type structure pointer:
*                   -GPIOA
*                   -GPIOB
* @param[in] config: GPIO_Config type structure pointer
* @return none
*/
void GPIO_Init(GPIO_Type *GPIOx, const GPIO_ConfigType *config);

/*!
* @brief reset all GPIO: disable interrupt and disable clock
*
* @param[in] none
* @return none
*/
void GPIO_DeInit(void);

/*!
* @brief Set GPIO pin level by GPIO_ODR register
*
* @param[in] GPIOx: GPIO type structure pointer:
*                   -GPIOA
*                   -GPIOB
* @param[in] GPIO_Pin: GPIO_Pin type num:
*                   -GPIO_PIN0
*                   -GPIO_PIN1
*                   -GPIO_PIN2
*                   - ...
*                   -GPIO_PIN15
* @param[in] pinVal: Pin level
*                   -GPIO_LEVEL_LOW
*                   -GPIO_LEVEL_HIGH
* @return none
*/
void GPIO_SetPinLevel(GPIO_Type *GPIOx, GPIO_PinType GPIO_Pin, GPIO_LevelType pinLevel);

/*!
* @brief Get GPIO pin level by GPIO_IDR register
*
* @param[in] GPIOx: GPIO type structure pointer:
*                   -GPIOA
*                   -GPIOB
* @param[in] GPIO_Pin: GPIO_Pin type num:
*                   -GPIO_PIN0
*                   -GPIO_PIN1
*                   -GPIO_PIN2
*                   - ...
*                   -GPIO_PIN15
* @return pinVal: Pin level
*                   -GPIO_LEVEL_LOW
*                   -GPIO_LEVEL_HIGH
*/
GPIO_LevelType GPIO_GetPinLevel(GPIO_Type *GPIOx, GPIO_PinType GPIO_Pin);

/*!
* @brief  Set Select GPIO pin by GPIO_BSRR register
*
* @param[in] GPIOx: GPIO type structure pointer:
*                   -GPIOA
*                   -GPIOB
* @param[in] GPIO_Pin: GPIO_Pin type num:
*                   -GPIO_PIN0
*                   -GPIO_PIN1
*                   -GPIO_PIN2
*                   - ...
*                   -GPIO_PIN15
* @return     none
*/
void GPIO_SetPinBit(GPIO_Type *GPIOx, GPIO_PinType GPIO_Pin);

/*!
* @brief Reset Select GPIO pin
*
* @param[in] GPIOx: GPIO type structure pointer:
*                   -GPIOA
*                   -GPIOB
* @param[in] GPIO_Pin: GPIO_Pin type num:
*                   -GPIO_PIN0
*                   -GPIO_PIN1
*                   -GPIO_PIN2
*                   - ...
*                   -GPIO_PIN15
* @return none
*/
void GPIO_ResetPinBit(GPIO_Type *GPIOx, GPIO_PinType GPIO_Pin);

/*!
* @brief Set GPIO port value by GPIO_ODR register
*
* @param[in] GPIOx: GPIO type structure pointer:
*                   -GPIOA
*                   -GPIOB
* @param[in] portLevel: GPIOx_ODR register value, it can be 0~0xFFFF
* @return none
*/
void GPIO_SetPortLevel(GPIO_Type *GPIOx, uint16_t portLevel);

/*!
* @brief Get GPIO port value by GPIO_IDR register
*
* @param[in] GPIOx: GPIO type structure pointer:
*                   -GPIOA
*                   -GPIOB
* @return portLevel: GPIOx_IDR register value, it can be 0~0xFFFF
*/
uint16_t GPIO_GetPortLevel(GPIO_Type *GPIOx);

/*!
* @brief  Set a GPIO pin's Pmux and pin function
*
* @param[in] GPIOx: GPIO type structure pointer:
*                   -GPIOA
*                   -GPIOB
* @param[in] GPIO_Pin: GPIO_Pin type num:
*                   -GPIO_PIN0
*                   -GPIO_PIN1
*                   -GPIO_PIN2
*                   - ...
*                   -GPIO_PIN15
* @param[in] functionx: GPIO function
*                   -GPIO_FUN0
*                   -GPIO_FUN1
*                   -GPIO_FUN2
*                   -GPIO_FUN3
* @return none
*/
void GPIO_SetFunc(GPIO_Type *GPIOx, GPIO_PinType GPIO_Pin, GPIO_FunType functionx);

/*!
* @brief Get a GPIO pin's Pmux function
*
* @param[in] GPIOx: GPIO type structure pointer:
*                   -GPIOA
*                   -GPIOB
* @param[in] GPIO_Pin: GPIO_Pin type num:
*                   -GPIO_PIN0
*                   -GPIO_PIN1
*                   -GPIO_PIN2
*                   - ...
*                   -GPIO_PIN15
* @return GPIO pin Pmux function
*/
GPIO_FunType GPIO_GetPinFunc(GPIO_Type *GPIOx, GPIO_PinType GPIO_Pin);

/*!
* @brief Set several GPIO pins' Pmux( pin function )
*
* @param[in] GPIOx: GPIO type structure pointer:
*                   -GPIOA
*                   -GPIOB
* @param[in] pinMask: GPIO pin mask value indicate which GPIO need to be modifyed
* @param[in] functionx: GPIO function
*                   -GPIO_FUN0
*                   -GPIO_FUN1
*                   -GPIO_FUN2
*                   -GPIO_FUN3
* @return none
*/
void GPIO_SetFuncGroup(GPIO_Type *GPIOx, uint16_t pinMask, GPIO_FunType functionx);

/*!
* @brief Set GPIO pin's mode, input or output
*
* @param[in] GPIOx: GPIO type structure pointer:
*                   -GPIOA
*                   -GPIOB
* @param[in] GPIO_Pin: GPIO_Pin type num:
*                   -GPIO_PIN0
*                   -GPIO_PIN1
*                   -GPIO_PIN2
*                   - ...
*                   -GPIO_PIN15
* @param[in] pinDir: GPIO direction, input or output
*                   -GPIO_IN
*                   -GPIO_OUT
* @return none
*/
void GPIO_SetDir(GPIO_Type *GPIOx, GPIO_PinType GPIO_Pin, GPIO_DirType pinMode);

/*!
* @brief Get a GPIO pin's direction, input or output
*
* @param[in] GPIOx: GPIO type structure pointer:
*                   -GPIOA
*                   -GPIOB
* @param[in] GPIO_Pin: GPIO_Pin type num:
*                   -GPIO_PIN0
*                   -GPIO_PIN1
*                   -GPIO_PIN2
*                   - ...
*                   -GPIO_PIN15
* @return GPIO pin's direction
*                   -GPIO_IN
*                   -GPIO_OUT
*/
GPIO_DirType GPIO_GetDir(GPIO_Type *GPIOx, GPIO_PinType GPIO_Pin);

/*!
* @brief Set several GPIO pins' pin mode
*
* @param[in] GPIOx: GPIO type structure pointer:
*                   -GPIOA
*                   -GPIOB
* @param[in] pinMask: GPIO pin mask value indicate which gpios need to be modifyed
* @param[in] pinDir: GPIO direction, input or output
*                   -GPIO_IN
*                   -GPIO_OUT
* @return none
*/
void GPIO_SetDirGroup(GPIO_Type *GPIOx, uint16_t pinMask, GPIO_DirType pinDir);

/*!
* @brief Set GPIO pin's pull-up resistor
*
* @param[in] GPIOx: GPIO type structure pointer:
*                   -GPIOA
*                   -GPIOB
* @param[in] GPIO_Pin: GPIO_Pin type num:
*                   -GPIO_PIN0
*                   -GPIO_PIN1
*                   -GPIO_PIN2
*                   - ...
*                   -GPIO_PIN15
* @param[in] enable: enable or disable pull-up resistor
*                   -ENABLE
*                   -DISABLE
* @return none
*/
void GPIO_SetPullup(GPIO_Type *GPIOx, GPIO_PinType GPIO_Pin, ACTION_Type enable);

/*!
* @brief Set GPIO pin's pull-down resistor
*
* @param[in] GPIOx: GPIO type structure pointer:
*                   -GPIOA
*                   -GPIOB
* @param[in] GPIO_Pin: GPIO_Pin type num:
*                   -GPIO_PIN0
*                   -GPIO_PIN1
*                   -GPIO_PIN2
*                   - ...
*                   -GPIO_PIN15
* @param[in] enable: enable or disable pull-down resistor
*                   -ENABLE
*                   -DISABLE
* @return none
*/
void GPIO_SetPulldown(GPIO_Type *GPIOx, GPIO_PinType GPIO_Pin, ACTION_Type enable);

/*!
* @brief Set a GPIO pin's driving ability
*
* @param[in] GPIOx: GPIO type structure pointer:
*                   -GPIOA
*                   -GPIOB
* @param[in] GPIO_Pin: GPIO_Pin type num:
*                   -GPIO_PIN0
*                   -GPIO_PIN1
*                   -GPIO_PIN2
*                   - ...
*                   -GPIO_PIN15
* @param[in] E4E2Value: Driving current select
*                   -GPIO_DRIVING_4MA
*                   -GPIO_DRIVING_8MA
*                   -GPIO_DRIVING_12MA
*                   -GPIO_DRIVING_16MA
* @return none
*/
void GPIO_SetDrivingAbility(GPIO_Type *GPIOx, GPIO_PinType GPIO_Pin, GPIO_DrivingType E4E2Value);

/*!
* @brief Set GPIO as high-Z state or floating input state.
*
* @param[in] GPIOx: GPIO type structure pointer:
*                   -GPIOA
*                   -GPIOB
* @param[in] GPIO_Pin: GPIO_Pin type num:
*                   -GPIO_PIN0
*                   -GPIO_PIN1
*                   -GPIO_PIN2
*                   - ...
*                   -GPIO_PIN15
* @param[in] enable: enable or disable high-z state. If disable high-z, IO will be set to floating input.
*                   -ENABLE
*                   -DISABLE
* @return none
*/
void GPIO_SetHighZ(GPIO_Type *GPIOx, GPIO_PinType GPIO_Pin, ACTION_Type enable);

/*!
* @brief Enable a GPIO pin's external interrupt and trigger condition
*
* @param[in] GPIOx: GPIO type structure pointer:
*                   -GPIOA
*                   -GPIOB
* @param[in] GPIO_Pin: GPIO_Pin type num:
*                   -GPIO_PIN0
*                   -GPIO_PIN1
*                   -GPIO_PIN2
*                   - ...
*                   -GPIO_PIN15
* @param[in] risingFallingEdge: GPIO's external interrupt set,value can be
*                   -EXTI_TRIGGER_FALLING
*                   -EXTI_TRIGGER_RISING
*                   -EXTI_TRIGGER_RISING_FALLING
* @return none
*/
void GPIO_EnableExtInterrupt(GPIO_Type *GPIOx, GPIO_PinType GPIO_Pin, EXTI_TriggerType risingFallingEdge);

/*!
* @brief Disable a GPIO pin's external interrupt and trigger condition
*
* @param[in] GPIO_Pin: GPIO_Pin type num:
*                   -GPIO_PIN0
*                   -GPIO_PIN1
*                   -GPIO_PIN2
*                   - ...
*                   -GPIO_PIN15
* @return  none
*/
void GPIO_DisableExtInterrupt(GPIO_PinType GPIO_Pin);

/*!
* @brief Get a GPIO pin's pending external interrupt IRQ number, a 16bit mask which represents the GPIO's group internal position
*
* @param[in] none
* @return GPIO's Pending external interrupt 16 bits mask
*/
uint16_t GPIO_GetPendingExtInterrupt(void);

/*!
* @brief Clear a GPIO pin's external interrupt pending flag
*
* @param[in] GPIO_Pin: GPIO_Pin type num:
*                   -GPIO_PIN0
*                   -GPIO_PIN1
*                   -GPIO_PIN2
*                   - ...
*                   -GPIO_PIN15
* @return none
*/
void GPIO_ClearPendingExtInterrupt(GPIO_PinType GPIO_Pin);

/*!
* @brief Set GPIO interrupt callback function, Pin0~2 has the independent interrupt vector,
*         Pin3~8 share the same interrupt vector, and Pin9~15 share the same interrupt vector.
*
* @param[in] GPIO_Pin: GPIO_Pin type num:
*                   -GPIO_PIN0
*                   -GPIO_PIN1
*                   -GPIO_PIN2
*                   - ...
*                   -GPIO_PIN15
* @param[in] callback: GPIO interrupt callback function, which will be called in EXTIx_IRQHandler()
* @return none
*/
void GPIO_SetCallback(GPIO_PinType GPIO_Pin, const DeviceCallback_Type callback);

#ifdef __cplusplus
}
#endif /* __cplusplus */

#endif /* _AC780X_GPIO_H */

/* =============================================  EOF  ============================================== */
