/*
 * STM32F4串口硬件抽象层实现
 * 功能：实现STM32F4平台的串口硬件抽象层
 * 依赖硬件：STM32F407VE
 * 跨平台适配点：通过硬件抽象层接口适配不同平台
 */

#include "hal.h"
#include "stm32f4xx_hal.h"

/* 串口句柄 */
static UART_HandleTypeDef huart1;

/**
 * @brief  串口初始化
 * @param  baudrate: 波特率
 * @return hal_status_t: 操作结果
 * @note   初始化串口硬件
 */
static hal_status_t stm32f4_uart_init(hal_uart_baudrate_t baudrate)
{
    huart1.Instance = USART1;
    huart1.Init.BaudRate = baudrate;
    huart1.Init.WordLength = UART_WORDLENGTH_8B;
    huart1.Init.StopBits = UART_STOPBITS_1;
    huart1.Init.Parity = UART_PARITY_NONE;
    huart1.Init.Mode = UART_MODE_TX_RX;
    huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
    huart1.Init.OverSampling = UART_OVERSAMPLING_16;
    
    if (HAL_UART_Init(&huart1) != HAL_OK) {
        return HAL_STATUS_ERROR;
    }
    
    return HAL_STATUS_OK;
}

/**
 * @brief  串口反初始化
 * @return hal_status_t: 操作结果
 * @note   反初始化串口硬件
 */
static hal_status_t stm32f4_uart_deinit(void)
{
    if (HAL_UART_DeInit(&huart1) != HAL_OK) {
        return HAL_STATUS_ERROR;
    }
    
    return HAL_STATUS_OK;
}

/**
 * @brief  串口发送数据
 * @param  data: 数据指针
 * @param  len: 数据长度
 * @return hal_status_t: 操作结果
 * @note   发送数据，使用阻塞方式
 */
static hal_status_t stm32f4_uart_send(const uint8_t *data, uint32_t len)
{
    if (HAL_UART_Transmit(&huart1, (uint8_t *)data, len, 1000) != HAL_OK) {
        return HAL_STATUS_ERROR;
    }
    
    return HAL_STATUS_OK;
}

/**
 * @brief  串口接收数据
 * @param  data: 数据指针
 * @param  len: 数据长度
 * @param  timeout: 超时时间
 * @return hal_status_t: 操作结果
 * @note   接收数据，使用阻塞方式
 */
static hal_status_t stm32f4_uart_recv(uint8_t *data, uint32_t len, uint32_t timeout)
{
    if (HAL_UART_Receive(&huart1, data, len, timeout) != HAL_OK) {
        return HAL_STATUS_ERROR;
    }
    
    return HAL_STATUS_OK;
}

/* 串口硬件抽象层操作结构体 */
const hal_uart_ops_t stm32f4_uart_ops = {
    .init = stm32f4_uart_init,
    .deinit = stm32f4_uart_deinit,
    .send = stm32f4_uart_send,
    .recv = stm32f4_uart_recv
};

/**
 * @brief  UART MSP初始化
 * @param  uartHandle: UART句柄
 * @return 无
 * @note   初始化UART的MSP
 */
void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};
    if(uartHandle->Instance==USART1)
    {
        /* USART1 clock enable */
        __HAL_RCC_USART1_CLK_ENABLE();
        __HAL_RCC_GPIOA_CLK_ENABLE();

        /**USART1 GPIO Configuration
        PA9     ------> USART1_TX
        PA10     ------> USART1_RX
        */
        GPIO_InitStruct.Pin = GPIO_PIN_9|GPIO_PIN_10;
        GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
        GPIO_InitStruct.Pull = GPIO_PULLUP;
        GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
        GPIO_InitStruct.Alternate = GPIO_AF7_USART1;
        HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
    }
}

/**
 * @brief  UART MSP反初始化
 * @param  uartHandle: UART句柄
 * @return 无
 * @note   反初始化UART的MSP
 */
void HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle)
{
    if(uartHandle->Instance==USART1)
    {
        /* Peripheral clock disable */
        __HAL_RCC_USART1_CLK_DISABLE();

        /**USART1 GPIO Configuration
        PA9     ------> USART1_TX
        PA10     ------> USART1_RX
        */
        HAL_GPIO_DeInit(GPIOA, GPIO_PIN_9|GPIO_PIN_10);
    }
}