/************************************************************************************************/
/**
* @file               std_gpio.c
* @author             MCU Ecosystem Development Team
* @brief              GPIO STD库驱动。
*                     实现GPIO初始化、去初始化等API。
*
*
**************************************************************************************************
* @attention
* Copyright (c) CEC Huada Electronic Design Co.,Ltd. All rights reserved.
*
**************************************************************************************************
*/

/************************************************************************************************/
/**
* @addtogroup STD_Driver
* @{
*/

/**
* @addtogroup GPIO
* @{
*
*/
/************************************************************************************************/


/*------------------------------------------includes--------------------------------------------*/
#include "std.h"

#ifdef STD_GPIO_PERIPHERAL_USED

/*-------------------------------------------functions------------------------------------------*/

/************************************************************************************************/
/**
* @addtogroup GPIO_External_Functions 
* @{
*
*/
/************************************************************************************************/ 

/**
* @brief  GPIO初始化
* @param  gpiox GPIO外设
*             @arg GPIOA
*             @arg GPIOB
*             @arg GPIOF
* @param  gpio_init_param GPIO初始化参数结构体
* @retval 无
*/
void std_gpio_init(GPIO_t* gpiox, std_gpio_init_t* gpio_init_param)
{
    uint32_t offset = 0;
    uint32_t current_pin = 0;

    /* 遍历配置GPIO引脚 */
    for (; ((gpio_init_param->pin) >> offset) != 0x00U; offset++)
    {
        /* 获取当前所遍历引脚 */
        current_pin = (gpio_init_param->pin) & (0x00000001UL << offset);

        if (current_pin != 0x00U)
        {
            /* 配置模式 */
            std_gpio_set_pin_mode(gpiox, current_pin, gpio_init_param->mode);

            /* 配置上下拉 */
            std_gpio_set_pin_pull(gpiox, current_pin, gpio_init_param->pull);
                
            if (gpio_init_param->mode == GPIO_MODE_ALTERNATE)
            {
                /* 配置复用功能 */
                if (current_pin < GPIO_PIN_8)
                {
                    /* 设置GPIO引脚（0~7）复用功能 */
                    std_gpio_set_afpin_0_7 (gpiox, current_pin, gpio_init_param->alternate);
                }
                else
                {
                    /* 设置GPIO引脚（8~15）复用功能 */
                    std_gpio_set_afpin_8_15(gpiox, current_pin, gpio_init_param->alternate);
                }
            }
        }
    }

    if ((gpio_init_param->mode == GPIO_MODE_OUTPUT) || (gpio_init_param->mode == GPIO_MODE_ALTERNATE))
    {
        /* 配置输出类型 */
        std_gpio_set_pin_output_type(gpiox, gpio_init_param->pin, gpio_init_param->output_type);
    }
}

/**
* @brief  GPIO去初始化
* @param  gpiox GPIO外设
*             @arg GPIOA
*             @arg GPIOB
*             @arg GPIOF
* @param  pin_mask GPIO引脚组合
*             @arg GPIO_PIN_0
*             @arg GPIO_PIN_1
*             @arg ...
*             @arg GPIO_PIN_ALL
* @retval 无
*/
void std_gpio_deinit(GPIO_t* gpiox, uint32_t pin_mask)
{
    uint32_t offset = 0;
    uint32_t current_pin = 0;

    /* 恢复寄存器值为默认值 */
    for (; ((pin_mask) >>offset) != 0x00000000U; offset++)
    {
        /* 获取当前所遍历引脚 */
        current_pin = (pin_mask) & (0x00000001U << offset);
        if (current_pin)
        {
            /* 配置模式 */
            std_gpio_set_pin_mode(gpiox, current_pin, GPIO_MODE_ANALOG);

            /* 配置上下拉 */
            std_gpio_set_pin_pull(gpiox, current_pin, GPIO_NOPULL);
            
            /* 配置复用功能 */
            if (current_pin < GPIO_PIN_8)
            {
                /* 设置GPIO引脚（0~7）复用功能 */
                std_gpio_set_afpin_0_7 (gpiox, current_pin, 0U);
            }
            else
            {
                /* 设置GPIO引脚（8~15）复用功能 */
                std_gpio_set_afpin_8_15(gpiox, current_pin, 0U);
            }
        }
    }
    
    /* 配置输出类型 */
    std_gpio_set_pin_output_type(gpiox, pin_mask, GPIO_OUTPUT_PUSHPULL);
}

/**
* @brief  GPIO初始化结构体初始化
* @param  gpio_init_struct GPIO初始化参数结构体
* @retval 无
*/
void std_gpio_struct_init(std_gpio_init_t* gpio_init_struct)
{
    gpio_init_struct->pin = GPIO_PIN_0;
    gpio_init_struct->mode = GPIO_MODE_ANALOG;
    gpio_init_struct->pull = GPIO_NOPULL;
    gpio_init_struct->output_type = GPIO_OUTPUT_PUSHPULL;
    gpio_init_struct->alternate = 0U;
}

/**
* @brief  GPIO灌电流配置
* @param  gpiox GPIO外设
*             @arg GPIOA
*             @arg GPIOB
*             @arg GPIOF
* @param  pin_mask GPIO引脚
*             @arg GPIO_PIN_3
*             @arg ...
*             @arg GPIO_PIN_15
* @param  drive_level GPIO引脚灌电流驱动档位
*             @arg GPIO_SINK_CURRENT_LOW_DRIVE   低驱
*             @arg GPIO_SINK_CURRENT_HIGH_DRIVE  高驱
* @note   PORTA端口PA3-PA7、PA15, PORTB端口PB3-PB8, PORTF端口PF4支持驱动能力配置
* @retval 无
*/
void std_gpio_sink_drive_config(GPIO_t* gpiox, uint32_t pin_mask, uint32_t drive_level)
{
    uint32_t offset = 0;
    uint32_t current_pin = 0;

    /* 遍历配置GPIO引脚 */
    for (; ((pin_mask) >>offset) != 0x00000000U; offset++)
    {
        /* 获取当前所遍历引脚 */
        current_pin = (pin_mask) & (0x00000001U << offset);
        if (current_pin)
        {
            /* 配置灌电流 */
            std_gpio_set_pin_sink_current(gpiox, current_pin, drive_level);
        }
    }
}

/**
* @brief  GPIO拉电流配置
* @param  gpiox GPIO外设
*             @arg GPIOA
*             @arg GPIOB
*             @arg GPIOF
* @param  pin_mask GPIO引脚
*             @arg GPIO_PIN_3
*             @arg ...
*             @arg GPIO_PIN_15
* @param  drive_level GPIO引脚拉电流驱动档位
*             @arg GPIO_SOURCE_CURRENT_LOW_DRIVE        低驱
*             @arg GPIO_SOURCE_CURRENT_MEDIUMLOW_DRIVE  中低驱
*             @arg GPIO_SOURCE_CURRENT_MEDIUMHIGH_DRIVE 中高驱
*             @arg GPIO_SOURCE_CURRENT_HIGH_DRIVE       高驱
* @note   PORTA端口PA3-PA7、PA15, PORTB端口PB3-PB8, PORTF端口PF4支持驱动能力配置
* @retval 无
*/
void std_gpio_source_drive_config(GPIO_t* gpiox, uint32_t pin_mask, uint32_t drive_level)
{
    uint32_t offset = 0;
    uint32_t current_pin = 0;

    /* 遍历配置GPIO引脚 */
    for (; ((pin_mask) >>offset) != 0x00000000U; offset++)
    {
        /* 获取当前所遍历引脚 */
        current_pin = (pin_mask) & (0x00000001U << offset);
        if (current_pin)
        {
            /* 配置拉电流 */
            std_gpio_set_pin_source_current(gpiox, current_pin, drive_level);
        }
    }
}

/** 
* @} 
*/

#endif /* STD_GPIO_PERIPHERAL_USED */

/** 
* @} 
*/

/** 
* @} 
*/
