/************************************************************************************************/
/**
* @file               std_lpuart.c
* @author             MCU Ecosystem Development Team
* @brief              LPUART STD库驱动。
*                     实现LPUART配置等API。
*
**************************************************************************************************
* @attention
* Copyright (c) CEC Huada Electronic Design Co.,Ltd. All rights reserved.
*
**************************************************************************************************
*/


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

/**
* @addtogroup LPUART 
* @{
*
*/
/************************************************************************************************/


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

#ifdef STD_LPUART_PERIPHERAL_USED
/*-------------------------------------------functions------------------------------------------*/

/************************************************************************************************/
/**
* @addtogroup LPUART_External_Functions 
* @{
*
*/
/************************************************************************************************/ 

/**
* @brief  LPUART 初始化
* @param  lpuartx LPUART外设
* @param  lpuart_init_param 初始化结构体
* @retval std_status_t 返回API执行结果
*/
std_status_t std_lpuart_init(LPUART_t *lpuartx, std_lpuart_init_t *lpuart_init_param)
{
    uint32_t direction = 0U;    
    /* 禁用LPUART */
    std_lpuart_disable(lpuartx);
    
    /* 配置停止位 */
    std_lpuart_set_stopbits(lpuartx,lpuart_init_param->stopbits);
    /* 配置预分频 */
    std_lpuart_set_kclk_prescaler(lpuartx,lpuart_init_param->prescaler);
    /* 配置硬件流控 */
    std_lpuart_set_hardflow_control(lpuartx,lpuart_init_param->hardware_flow);
    /* 配置通信波特率 */
    if (STD_OK != (std_lpuart_set_baudrate(lpuartx,lpuart_init_param->baudrate)))
    {
        return STD_ERR;
    }
    
    /* 设置 LPUART 字长 、收发模式、校验*/
    MODIFY_REG(lpuartx->CR1,
              (UART_CR1_WL | UART_CR1_TE | UART_CR1_RE | UART_CR1_PTS | UART_CR1_PEN),
              (lpuart_init_param->wordlength | lpuart_init_param->direction | lpuart_init_param->parity));
    
    direction = std_lpuart_get_transfer_direction(lpuartx);
    
    /* 使能LPUART */
    std_lpuart_enable(lpuartx);
    
    /* 在使能发送器后，需等待TEACK标志置1 */
    if (LPUART_DIRECTION_SEND == (direction & LPUART_DIRECTION_SEND))
    {
        while (!std_lpuart_get_flag(lpuartx, LPUART_FLAG_TEACK))
        {
        }
    }
    /* 在使能接收器后，需等待REACK标志置1 */
    if (LPUART_DIRECTION_RECEIVE == (direction & LPUART_DIRECTION_RECEIVE))
    {
        while (!std_lpuart_get_flag(lpuartx, LPUART_FLAG_REACK))
        {
        }
    }     

    return  STD_OK;
}


/**
* @brief  LPUART 去初始化
* @param  lpuartx LPUART外设
* @retval 无
*/
void std_lpuart_deinit(LPUART_t *lpuartx)
{
    /* 复位LPUART1 */
    std_rcc_apb1_reset(RCC_PERIPH_RESET_LPUART1);
    /* 关闭LPUART1时钟 */
    std_rcc_apb1_clk_disable(RCC_PERIPH_CLK_LPUART1);
}

/**
* @brief  LPUART 波特率计算及BRR寄存器配置
* @param  lpuartx LPUART外设 
* @param  baudrate LPUART波特率
* @retval std_status_t 返回API执行结果
*/
std_status_t std_lpuart_set_baudrate(LPUART_t *lpuartx, uint32_t baudrate)
{    
    uint32_t kclk_frequency = 0;
    uint32_t prescaler_temp = 0;
    uint32_t brr_temp = 0;

    /* 获取LPUART当前的时钟源频率 */ 
    kclk_frequency = std_rcc_get_lpuart1freq();
    
    /* 获取LPUART 预分频器的分频值 */
    prescaler_temp = std_lpuart_get_kclk_prescaler(lpuartx);
    /* 计算LPUART BRR配置 */
    brr_temp = (uint32_t)((((uint64_t)(kclk_frequency / prescaler_temp) << 8) + (baudrate >> 1)) / (baudrate));
    /* 判断BRR配置在有效范围内 */
    if ((brr_temp >= LPUART_BRR_MIN) && (brr_temp <= LPUART_BRR_MAX))
    {
        MODIFY_REG(lpuartx->BRR,UART_BRR_LPUART, brr_temp);
        return STD_OK;
    }
    else
    {
        return STD_ERR;
    } 
}

/**
* @brief  LPUART 结构体初始化
* @param  lpuart_init_struct LPUART初始化结构体指针
* @retval 无
*/
void std_lpuart_struct_init(std_lpuart_init_t *lpuart_init_struct)
{
    lpuart_init_struct->prescaler = LPUART_PRESCALER_DIV1;
    lpuart_init_struct->baudrate = 9600;
    lpuart_init_struct->wordlength = LPUART_WORDLENGTH_8BITS;
    lpuart_init_struct->hardware_flow = LPUART_FLOWCONTROL_NONE;
    lpuart_init_struct->parity = LPUART_PARITY_NONE;
    lpuart_init_struct->stopbits = LPUART_STOPBITS_1;
    lpuart_init_struct->direction =LPUART_DIRECTION_SEND_RECEIVE;
}    

/** 
* @} 
*/

#endif /* STD_LPUART_PERIPHERAL_USED */
/** 
* @} 
*/

/** 
* @} 
*/
