/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : bsp_board.h
  * @brief          : Board support package board abstraction header file
  ******************************************************************************
  */
/* USER CODE END Header */

#ifndef BSP_BOARD_H
#define BSP_BOARD_H

#include <stdint.h>
#include "hal.h"
#include "hal_gpio.h"
#include "hal_uart.h"
#include "hal_spi.h"
#include "hal_i2c.h"
#include "hal_can.h"
#include "hal_adc.h"

/**
 * @brief BSP configuration version
 */
#define BSP_CONFIG_VERSION_MAJOR 1
#define BSP_CONFIG_VERSION_MINOR 0
#define BSP_CONFIG_VERSION_PATCH 0
#define BSP_CONFIG_VERSION (BSP_CONFIG_VERSION_MAJOR << 16 | BSP_CONFIG_VERSION_MINOR << 8 | BSP_CONFIG_VERSION_PATCH)

/**
 * @brief Board LED configuration structure
 */
typedef struct {
    uint8_t enable;                 /*!< LED enable flag */
    hal_gpio_port_t port;           /*!< LED GPIO port */
    hal_gpio_pin_t pin;             /*!< LED GPIO pin */
    hal_gpio_mode_t mode;           /*!< LED GPIO mode */
    hal_gpio_speed_t speed;         /*!< LED GPIO speed */
    hal_gpio_pull_t pull;           /*!< LED GPIO pull configuration */
} bsp_led_config_t;

/**
 * @brief Board button configuration structure
 */
typedef struct {
    hal_gpio_port_t port;           /*!< Button GPIO port */
    hal_gpio_pin_t pin;             /*!< Button GPIO pin */
    hal_gpio_mode_t mode;           /*!< Button GPIO mode */
    hal_gpio_speed_t speed;         /*!< Button GPIO speed */
    hal_gpio_pull_t pull;           /*!< Button GPIO pull configuration */
    uint8_t active_high;            /*!< Button active high flag */
} bsp_button_config_t;

/**
 * @brief Board buttons configuration structure
 */
typedef struct {
    uint8_t enable;                 /*!< Buttons enable flag */
    uint8_t count;                  /*!< Number of buttons */
    const bsp_button_config_t* buttons; /*!< Pointer to buttons configuration array */
} bsp_buttons_config_t;

/**
 * @brief UART instance identifier definitions
 */
typedef enum {
    BSP_UART_INSTANCE_1 = 0,
    BSP_UART_INSTANCE_2,
    BSP_UART_INSTANCE_3,
    BSP_UART_INSTANCE_4,
    BSP_UART_INSTANCE_5,
    BSP_UART_INSTANCE_6,
    BSP_UART_INSTANCE_MAX
} bsp_uart_instance_t;

/**
 * @brief Board UART configuration structure
 */
typedef struct {
    uint8_t enable;                 /*!< UART enable flag */
    bsp_uart_instance_t instance;   /*!< UART instance */
    uint32_t baudrate;              /*!< UART baudrate */
    hal_uart_parity_t parity;       /*!< UART parity */
    hal_uart_stopbits_t stopbits;   /*!< UART stop bits */
    hal_uart_databits_t databits;   /*!< UART data bits */
    hal_gpio_port_t tx_port;        /*!< UART TX port */
    hal_gpio_pin_t tx_pin;          /*!< UART TX pin */
    hal_gpio_port_t rx_port;        /*!< UART RX port */
    hal_gpio_pin_t rx_pin;          /*!< UART RX pin */
} bsp_uart_config_t;

/**
 * @brief Board SPI configuration structure
 */
typedef struct {
    uint8_t enable;                 /*!< SPI enable flag */
    hal_spi_instance_t instance;    /*!< SPI instance */
    hal_spi_mode_t mode;            /*!< SPI mode */
    uint32_t baudrate;              /*!< SPI baudrate */
    hal_spi_polarity_t polarity;    /*!< SPI clock polarity */
    hal_spi_phase_t phase;          /*!< SPI clock phase */
    hal_spi_databits_t databits;    /*!< SPI data bits */
    hal_gpio_port_t sck_port;       /*!< SPI SCK port */
    hal_gpio_pin_t sck_pin;         /*!< SPI SCK pin */
    hal_gpio_port_t miso_port;      /*!< SPI MISO port */
    hal_gpio_pin_t miso_pin;        /*!< SPI MISO pin */
    hal_gpio_port_t mosi_port;      /*!< SPI MOSI port */
    hal_gpio_pin_t mosi_pin;        /*!< SPI MOSI pin */
} bsp_spi_config_t;

/**
 * @brief Board I2C configuration structure
 */
typedef struct {
    uint8_t enable;                 /*!< I2C enable flag */
    hal_i2c_instance_t instance;    /*!< I2C instance */
    hal_i2c_speed_t speed;          /*!< I2C speed */
    hal_i2c_address_mode_t address_mode; /*!< I2C address mode */
    hal_i2c_dutycycle_t dutycycle;  /*!< I2C duty cycle */
    uint16_t own_address1;          /*!< I2C own address 1 */
    hal_gpio_port_t scl_port;       /*!< I2C SCL port */
    hal_gpio_pin_t scl_pin;         /*!< I2C SCL pin */
    hal_gpio_port_t sda_port;       /*!< I2C SDA port */
    hal_gpio_pin_t sda_pin;         /*!< I2C SDA pin */
} bsp_i2c_config_t;

/**
 * @brief Board CAN configuration structure
 */
typedef struct {
    uint8_t enable;                 /*!< CAN enable flag */
    hal_can_instance_t instance;    /*!< CAN instance */
    hal_can_mode_t mode;            /*!< CAN mode */
    uint32_t prescaler;             /*!< CAN prescaler */
    uint8_t sync_jump_width;        /*!< CAN sync jump width */
    uint8_t time_segment1;          /*!< CAN time segment 1 */
    uint8_t time_segment2;          /*!< CAN time segment 2 */
    hal_gpio_port_t rx_port;        /*!< CAN RX port */
    hal_gpio_pin_t rx_pin;          /*!< CAN RX pin */
    hal_gpio_port_t tx_port;        /*!< CAN TX port */
    hal_gpio_pin_t tx_pin;          /*!< CAN TX pin */
} bsp_can_config_t;

/**
 * @brief Board ADC channel configuration structure
 */
typedef struct {
    uint8_t enable;                 /*!< ADC channel enable flag */
    hal_adc_channel_t channel;      /*!< ADC channel */
    hal_adc_sampletime_t sampletime; /*!< ADC sample time */
    uint8_t rank;                   /*!< ADC channel rank */
} bsp_adc_channel_config_t;

/**
 * @brief Board ADC configuration structure
 */
typedef struct {
    uint8_t enable;                 /*!< ADC enable flag */
    hal_adc_instance_t instance;    /*!< ADC instance */
    hal_adc_resolution_t resolution; /*!< ADC resolution */
    uint8_t scan_conversion_mode;   /*!< ADC scan conversion mode */
    uint8_t continuous_conversion_mode; /*!< ADC continuous conversion mode */
    uint8_t channel_count;          /*!< Number of ADC channels */
    const bsp_adc_channel_config_t* channels; /*!< Pointer to ADC channels configuration array */
} bsp_adc_config_t;

/**
 * @brief Board W25QXX configuration structure
 */
typedef struct {
    uint8_t enable;                 /*!< W25QXX enable flag */
    hal_gpio_port_t cs_port;        /*!< W25QXX CS port */
    hal_gpio_pin_t cs_pin;          /*!< W25QXX CS pin */
    uint8_t spi_instance;           /*!< SPI instance used by W25QXX */
} bsp_w25qxx_config_t;

/**
 * @brief Board peripheral initialization function type
 */
typedef hal_ret_t (*bsp_periph_init_func_t)(const void* config);

/**
 * @brief Board ID structure
 */
typedef struct {
    uint16_t vendor_id;             /*!< Board vendor ID */
    uint16_t product_id;            /*!< Board product ID */
    uint32_t serial_number;         /*!< Board serial number */
} bsp_board_id_t;

/**
 * @brief Board feature flags
 */
typedef enum {
    BSP_BOARD_FEATURE_LED         = (1 << 0),  /*!< Board has LED support */
    BSP_BOARD_FEATURE_BUTTON      = (1 << 1),  /*!< Board has button support */
    BSP_BOARD_FEATURE_UART        = (1 << 2),  /*!< Board has UART support */
    BSP_BOARD_FEATURE_SPI         = (1 << 3),  /*!< Board has SPI support */
    BSP_BOARD_FEATURE_I2C         = (1 << 4),  /*!< Board has I2C support */
    BSP_BOARD_FEATURE_CAN         = (1 << 5),  /*!< Board has CAN support */
    BSP_BOARD_FEATURE_ADC         = (1 << 6),  /*!< Board has ADC support */
    BSP_BOARD_FEATURE_DAC         = (1 << 7),  /*!< Board has DAC support */
    BSP_BOARD_FEATURE_TIMER       = (1 << 8),  /*!< Board has TIMER support */
    BSP_BOARD_FEATURE_RTC         = (1 << 9),  /*!< Board has RTC support */
    BSP_BOARD_FEATURE_W25QXX      = (1 << 10), /*!< Board has W25QXX support */
    BSP_BOARD_FEATURE_DMA         = (1 << 11), /*!< Board has DMA support */
    BSP_BOARD_FEATURE_ETH         = (1 << 12), /*!< Board has ETH support */
    BSP_BOARD_FEATURE_USB         = (1 << 13), /*!< Board has USB support */
    BSP_BOARD_FEATURE_SDIO        = (1 << 14), /*!< Board has SDIO support */
    BSP_BOARD_FEATURE_FSMC        = (1 << 15), /*!< Board has FSMC support */
} bsp_board_feature_t;

/**
 * @brief Board hardware information structure
 */
typedef struct {
    uint32_t clock_speed;           /*!< Board clock speed */
    uint32_t flash_size;            /*!< Flash size in bytes */
    uint32_t ram_size;              /*!< RAM size in bytes */
    uint32_t eeprom_size;           /*!< EEPROM size in bytes */
    uint32_t sram_size;             /*!< SRAM size in bytes */
    uint8_t  cpu_core;              /*!< CPU core type */
    uint8_t  cpu_bits;              /*!< CPU bits (32 or 64) */
} bsp_board_hw_info_t;

/**
 * @brief Board peripheral configuration structure
 */
typedef struct {
    /* UART configurations */
    uint8_t uart_count;             /*!< Number of UARTs */
    const bsp_uart_config_t* uarts; /*!< Pointer to UARTs configuration array */
    
    /* SPI configurations */
    uint8_t spi_count;              /*!< Number of SPIs */
    const bsp_spi_config_t* spis;   /*!< Pointer to SPIs configuration array */
    
    /* I2C configurations */
    uint8_t i2c_count;              /*!< Number of I2Cs */
    const bsp_i2c_config_t* i2cs;   /*!< Pointer to I2Cs configuration array */
    
    /* CAN configurations */
    uint8_t can_count;              /*!< Number of CANs */
    const bsp_can_config_t* cans;   /*!< Pointer to CANs configuration array */
    
    /* ADC configurations */
    uint8_t adc_count;              /*!< Number of ADCs */
    const bsp_adc_config_t* adcs;   /*!< Pointer to ADCs configuration array */
} bsp_board_periph_config_t;

/**
 * @brief Board initialization function pointers structure
 */
typedef struct {
    bsp_periph_init_func_t led_init;        /*!< LED initialization function */
    bsp_periph_init_func_t button_init;     /*!< Button initialization function */
    bsp_periph_init_func_t uart_init;       /*!< UART initialization function */
    bsp_periph_init_func_t spi_init;        /*!< SPI initialization function */
    bsp_periph_init_func_t i2c_init;        /*!< I2C initialization function */
    bsp_periph_init_func_t can_init;        /*!< CAN initialization function */
    bsp_periph_init_func_t adc_init;        /*!< ADC initialization function */
    bsp_periph_init_func_t w25qxx_init;     /*!< W25QXX initialization function */
} bsp_board_init_funcs_t;

/**
 * @brief Board configuration structure
 */
typedef struct {
    uint32_t version;               /*!< Configuration version */
    const char* name;               /*!< Board name */
    const char* description;        /*!< Board description */
    bsp_board_id_t id;              /*!< Board ID information */
    
    /* Board features */
    uint32_t features;              /*!< Board feature flags */
    
    /* Hardware information */
    bsp_board_hw_info_t hw_info;    /*!< Hardware information */
    
    /* Peripheral configurations */
    bsp_led_config_t led;           /*!< LED configuration */
    bsp_buttons_config_t buttons;   /*!< Buttons configuration */
    bsp_w25qxx_config_t w25qxx;     /*!< W25QXX configuration */
    
    /* Peripheral arrays */
    bsp_board_periph_config_t periphs; /*!< Peripheral configurations */
    
    /* Initialization functions */
    bsp_board_init_funcs_t init_funcs; /*!< Initialization function pointers */
    
    /* Additional board-specific configuration */
    void* custom_config;            /*!< Custom board configuration pointer */
    size_t custom_config_size;      /*!< Custom board configuration size */
    
    /* Board revision information */
    uint8_t major_rev;              /*!< Major revision */
    uint8_t minor_rev;              /*!< Minor revision */
    uint8_t patch_rev;              /*!< Patch revision */
    const char* revision_desc;      /*!< Revision description */
} bsp_board_config_t;

/**
 * @brief STM32F407VET6 board configuration extern declaration
 */
extern const bsp_board_config_t stm32f407vet6_board_config;

/**
 * @brief Board hardware initialization
 * @retval HAL status code
 */
hal_ret_t bsp_board_init(void);

/**
 * @brief Get board name
 * @retval Board name string
 */
const char* bsp_board_get_name(void);

/**
 * @brief Get board configuration
 * @retval Pointer to board configuration structure
 */
const bsp_board_config_t* bsp_board_get_config(void);

#endif /* BSP_BOARD_H */
