/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : bsp_init.c
  * @brief          : 板级支持包初始化源文件
  ******************************************************************************
  */
/* USER CODE END Header */

#include "bsp_init.h"
#include "bsp_board.h"
#include "bsp_board_manager.h"
#include "hal.h"
#include "hal_gpio.h"
#include "hal_uart.h"

/**
 * @brief 初始化板级支持包
 * @retval HAL 状态码
 */
hal_ret_t bsp_init(void) {
    /* Get board configuration */
    const bsp_board_config_t* board_config = bsp_board_get_config();
    hal_ret_t status = HAL_RET_OK;
    uint8_t i;
    
    /* Initialize HAL layer */
    status = hal_init();
    if (status != HAL_RET_OK) {
        return status;
    }
    
    /* Initialize peripherals based on configuration */
    
    /* Initialize LEDs */
    if (board_config->leds.enable) {
        for (i = 0; i < board_config->leds.count; i++) {
            if (board_config->init_funcs.led_init != NULL) {
                status = board_config->init_funcs.led_init(&board_config->leds.leds[i]);
                if (status != HAL_RET_OK) {
                    return status;
                }
            } else {
                /* Use default initialization if no function provided */
                hal_gpio_config_t gpio_config = {
                    .port = board_config->leds.leds[i].port,
                    .pin = board_config->leds.leds[i].pin,
                    .mode = board_config->leds.leds[i].mode,
                    .speed = board_config->leds.leds[i].speed,
                    .pull = board_config->leds.leds[i].pull
                };
                status = hal_gpio_configure_pin(&gpio_config);
                if (status != HAL_RET_OK) {
                    return status;
                }
            }
        }
    }
    
    /* Initialize Buttons */
    if (board_config->buttons.enable && board_config->init_funcs.button_init != NULL) {
        status = board_config->init_funcs.button_init(&board_config->buttons);
        if (status != HAL_RET_OK) {
            return status;
        }
    }
    
    /* Initialize UARTs */
    if (board_config->init_funcs.uart_init != NULL) {
        for (i = 0; i < board_config->periphs.uart_count; i++) {
            if (board_config->periphs.uarts[i].enable) {
                status = board_config->init_funcs.uart_init(&board_config->periphs.uarts[i]);
                if (status != HAL_RET_OK) {
                    return status;
                }
            }
        }
    }
    
    /* Initialize SPIs */
    if (board_config->init_funcs.spi_init != NULL) {
        for (i = 0; i < board_config->periphs.spi_count; i++) {
            if (board_config->periphs.spis[i].enable) {
                status = board_config->init_funcs.spi_init(&board_config->periphs.spis[i]);
                if (status != HAL_RET_OK) {
                    return status;
                }
            }
        }
    }
    
    /* Initialize I2Cs */
    if (board_config->init_funcs.i2c_init != NULL) {
        for (i = 0; i < board_config->periphs.i2c_count; i++) {
            if (board_config->periphs.i2cs[i].enable) {
                status = board_config->init_funcs.i2c_init(&board_config->periphs.i2cs[i]);
                if (status != HAL_RET_OK) {
                    return status;
                }
            }
        }
    }
    
    /* Initialize CANs */
    if (board_config->init_funcs.can_init != NULL) {
        for (i = 0; i < board_config->periphs.can_count; i++) {
            if (board_config->periphs.cans[i].enable) {
                status = board_config->init_funcs.can_init(&board_config->periphs.cans[i]);
                if (status != HAL_RET_OK) {
                    return status;
                }
            }
        }
    }
    
    /* Initialize ADCs */
    if (board_config->init_funcs.adc_init != NULL) {
        for (i = 0; i < board_config->periphs.adc_count; i++) {
            if (board_config->periphs.adcs[i].enable) {
                status = board_config->init_funcs.adc_init(&board_config->periphs.adcs[i]);
                if (status != HAL_RET_OK) {
                    return status;
                }
            }
        }
    }
    
    /* Initialize W25QXX if available and enabled */
    if (board_config->w25qxx.enable && board_config->init_funcs.w25qxx_init != NULL) {
        status = board_config->init_funcs.w25qxx_init(&board_config->w25qxx);
        if (status != HAL_RET_OK) {
            return status;
        }
    }
    
    return status;
}

/**
 * @brief 使用配置初始化板卡 GPIO
 * @retval HAL 状态码
 */
hal_ret_t bsp_gpio_init(void) {
    /* Get board configuration */
    const bsp_board_config_t* board_config = bsp_board_get_config();
    hal_ret_t status = HAL_RET_OK;
    uint8_t i;
    
    /* Initialize LED GPIOs */
    if (board_config->leds.enable) {
        for (i = 0; i < board_config->leds.count; i++) {
            hal_gpio_config_t gpio_config = {
                .port = board_config->leds.leds[i].port,
                .pin = board_config->leds.leds[i].pin,
                .mode = board_config->leds.leds[i].mode,
                .speed = board_config->leds.leds[i].speed,
                .pull = board_config->leds.leds[i].pull
            };
            status = hal_gpio_configure_pin(&gpio_config);
            if (status != HAL_RET_OK) {
                return status;
            }
        }
    }
    
    /* Initialize Buttons GPIO */
    if (board_config->buttons.enable) {
        for (i = 0; i < board_config->buttons.count; i++) {
            const bsp_button_config_t* button = &board_config->buttons.buttons[i];
            hal_gpio_config_t gpio_config = {
                .port = button->port,
                .pin = button->pin,
                .mode = button->mode,
                .speed = button->speed,
                .pull = button->pull
            };
            status = hal_gpio_configure_pin(&gpio_config);
            if (status != HAL_RET_OK) {
                return status;
            }
        }
    }
    
    /* Initialize UART GPIOs */
    for (i = 0; i < board_config->periphs.uart_count; i++) {
        if (board_config->periphs.uarts[i].enable) {
            /* Initialize TX pin */
            hal_gpio_config_t gpio_config = {
                .port = board_config->periphs.uarts[i].tx_port,
                .pin = board_config->periphs.uarts[i].tx_pin,
                .mode = HAL_GPIO_MODE_AF_PP,
                .speed = HAL_GPIO_SPEED_HIGH,
                .pull = HAL_GPIO_PULL_NO
            };
            status = hal_gpio_configure_pin(&gpio_config);
            if (status != HAL_RET_OK) {
                return status;
            }
            
            /* Initialize RX pin */
            gpio_config.port = board_config->periphs.uarts[i].rx_port;
            gpio_config.pin = board_config->periphs.uarts[i].rx_pin;
            gpio_config.mode = HAL_GPIO_MODE_AF_PP;
            gpio_config.speed = HAL_GPIO_SPEED_HIGH;
            gpio_config.pull = HAL_GPIO_PULL_UP;
            status = hal_gpio_configure_pin(&gpio_config);
            if (status != HAL_RET_OK) {
                return status;
            }
        }
    }
    
    /* Initialize SPI GPIOs */
    for (i = 0; i < board_config->periphs.spi_count; i++) {
        if (board_config->periphs.spis[i].enable) {
            /* Initialize SCK pin */
            hal_gpio_config_t gpio_config = {
                .port = board_config->periphs.spis[i].sck_port,
                .pin = board_config->periphs.spis[i].sck_pin,
                .mode = HAL_GPIO_MODE_AF_PP,
                .speed = HAL_GPIO_SPEED_HIGH,
                .pull = HAL_GPIO_PULL_NO
            };
            status = hal_gpio_configure_pin(&gpio_config);
            if (status != HAL_RET_OK) {
                return status;
            }
            
            /* Initialize MISO pin */
            gpio_config.port = board_config->periphs.spis[i].miso_port;
            gpio_config.pin = board_config->periphs.spis[i].miso_pin;
            gpio_config.mode = HAL_GPIO_MODE_AF_PP;
            gpio_config.speed = HAL_GPIO_SPEED_HIGH;
            gpio_config.pull = HAL_GPIO_PULL_UP;
            status = hal_gpio_configure_pin(&gpio_config);
            if (status != HAL_RET_OK) {
                return status;
            }
            
            /* Initialize MOSI pin */
            gpio_config.port = board_config->periphs.spis[i].mosi_port;
            gpio_config.pin = board_config->periphs.spis[i].mosi_pin;
            gpio_config.mode = HAL_GPIO_MODE_AF_PP;
            gpio_config.speed = HAL_GPIO_SPEED_HIGH;
            gpio_config.pull = HAL_GPIO_PULL_NO;
            status = hal_gpio_configure_pin(&gpio_config);
            if (status != HAL_RET_OK) {
                return status;
            }
        }
    }
    
    return status;
}

/**
 * @brief 获取板卡名称
 * @retval 板卡名称字符串
 */
const char* bsp_get_board_name(void) {
    return bsp_board_get_name();
}

/**
 * @brief 获取当前板卡配置
 * @retval 指向板卡配置结构体的指针
 */
const bsp_board_config_t* bsp_get_board_config(void) {
    return bsp_board_get_config();
}
