进一步迭代优化统一管理
This commit is contained in:
@ -11,39 +11,53 @@
|
||||
#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 {
|
||||
hal_gpio_port_t port;
|
||||
hal_gpio_pin_t pin;
|
||||
hal_gpio_mode_t mode;
|
||||
hal_gpio_speed_t speed;
|
||||
hal_gpio_pull_t pull;
|
||||
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;
|
||||
hal_gpio_pin_t pin;
|
||||
hal_gpio_mode_t mode;
|
||||
hal_gpio_speed_t speed;
|
||||
hal_gpio_pull_t pull;
|
||||
uint8_t active_high;
|
||||
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 count;
|
||||
const bsp_button_config_t* buttons;
|
||||
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;
|
||||
|
||||
/**
|
||||
@ -63,62 +77,226 @@ typedef enum {
|
||||
* @brief Board UART configuration structure
|
||||
*/
|
||||
typedef struct {
|
||||
bsp_uart_instance_t instance;
|
||||
uint32_t baudrate;
|
||||
hal_uart_parity_t parity;
|
||||
hal_uart_stopbits_t stopbits;
|
||||
hal_uart_databits_t databits;
|
||||
hal_gpio_port_t tx_port;
|
||||
hal_gpio_pin_t tx_pin;
|
||||
hal_gpio_port_t rx_port;
|
||||
hal_gpio_pin_t rx_pin;
|
||||
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 {
|
||||
hal_spi_instance_t instance;
|
||||
hal_spi_mode_t mode;
|
||||
uint32_t baudrate;
|
||||
hal_spi_polarity_t polarity;
|
||||
hal_spi_phase_t phase;
|
||||
hal_spi_databits_t databits;
|
||||
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 {
|
||||
hal_gpio_port_t cs_port;
|
||||
hal_gpio_pin_t cs_pin;
|
||||
bsp_spi_config_t spi_config;
|
||||
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 void (*bsp_periph_init_func_t)(const void* config);
|
||||
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 {
|
||||
const char* name;
|
||||
bsp_led_config_t led;
|
||||
bsp_buttons_config_t buttons;
|
||||
bsp_uart_config_t uart;
|
||||
bsp_w25qxx_config_t w25qxx;
|
||||
uint32_t version; /*!< Configuration version */
|
||||
const char* name; /*!< Board name */
|
||||
const char* description; /*!< Board description */
|
||||
bsp_board_id_t id; /*!< Board ID information */
|
||||
|
||||
/* Initialization function pointers */
|
||||
bsp_periph_init_func_t led_init;
|
||||
bsp_periph_init_func_t button_init;
|
||||
bsp_periph_init_func_t uart_init;
|
||||
bsp_periph_init_func_t w25qxx_init;
|
||||
/* 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 */
|
||||
uint32_t clock_speed;
|
||||
uint8_t uart_count;
|
||||
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;
|
||||
|
||||
/**
|
||||
@ -128,8 +306,9 @@ extern const bsp_board_config_t stm32f407vet6_board_config;
|
||||
|
||||
/**
|
||||
* @brief Board hardware initialization
|
||||
* @retval HAL status code
|
||||
*/
|
||||
void bsp_board_init(void);
|
||||
hal_ret_t bsp_board_init(void);
|
||||
|
||||
/**
|
||||
* @brief Get board name
|
||||
@ -137,4 +316,10 @@ void bsp_board_init(void);
|
||||
*/
|
||||
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 */
|
||||
|
||||
@ -37,16 +37,16 @@ const bsp_board_config_t* bsp_board_get_by_name(const char* name);
|
||||
/**
|
||||
* @brief Set current board configuration by index
|
||||
* @param index: Board configuration index
|
||||
* @retval 0 if successful, -1 if invalid index
|
||||
* @retval HAL status code
|
||||
*/
|
||||
int8_t bsp_board_set_by_index(uint8_t index);
|
||||
hal_ret_t bsp_board_set_by_index(uint8_t index);
|
||||
|
||||
/**
|
||||
* @brief Set current board configuration by name
|
||||
* @param name: Board name string
|
||||
* @retval 0 if successful, -1 if not found
|
||||
* @retval HAL status code
|
||||
*/
|
||||
int8_t bsp_board_set_by_name(const char* name);
|
||||
hal_ret_t bsp_board_set_by_name(const char* name);
|
||||
|
||||
/**
|
||||
* @brief Get current board configuration
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file : bsp_config.h
|
||||
* @brief : Board support package configuration file
|
||||
* @brief : Board support package configuration file header
|
||||
******************************************************************************
|
||||
*/
|
||||
/* USER CODE END Header */
|
||||
@ -10,42 +10,175 @@
|
||||
#ifndef BSP_CONFIG_H
|
||||
#define BSP_CONFIG_H
|
||||
|
||||
#include "hal_gpio.h"
|
||||
#include "hal_uart.h"
|
||||
#include <stdio.h>
|
||||
#include "bsp_module.h"
|
||||
#include "bsp_board.h"
|
||||
#include "hal.h"
|
||||
|
||||
/**
|
||||
* @brief Board name definition
|
||||
* @brief BSP configuration file format definitions
|
||||
*/
|
||||
#define BOARD_NAME "STM32F407VET6"
|
||||
#define BSP_CONFIG_FILE_VERSION "1.0.0"
|
||||
#define BSP_CONFIG_MAX_LINE_LENGTH 256
|
||||
#define BSP_CONFIG_MAX_SECTION_NAME_LENGTH 32
|
||||
#define BSP_CONFIG_MAX_KEY_NAME_LENGTH 32
|
||||
#define BSP_CONFIG_MAX_VALUE_LENGTH 128
|
||||
|
||||
/**
|
||||
* @brief LED hardware configuration
|
||||
* @brief BSP configuration section type
|
||||
*/
|
||||
#define BSP_LED_PORT HAL_GPIO_PORT_A
|
||||
#define BSP_LED_PIN HAL_GPIO_PIN_6
|
||||
typedef enum {
|
||||
BSP_CONFIG_SECTION_NONE = 0,
|
||||
BSP_CONFIG_SECTION_BOARD,
|
||||
BSP_CONFIG_SECTION_MODULE,
|
||||
BSP_CONFIG_SECTION_PERIPH,
|
||||
BSP_CONFIG_SECTION_MAX
|
||||
} bsp_config_section_t;
|
||||
|
||||
/**
|
||||
* @brief Button hardware configuration
|
||||
* @brief BSP configuration entry
|
||||
*/
|
||||
/* KEY0 - PE4, active low */
|
||||
#define BSP_KEY0_PORT HAL_GPIO_PORT_E
|
||||
#define BSP_KEY0_PIN HAL_GPIO_PIN_4
|
||||
|
||||
/* KEY1 - PE3, active low */
|
||||
#define BSP_KEY1_PORT HAL_GPIO_PORT_E
|
||||
#define BSP_KEY1_PIN HAL_GPIO_PIN_3
|
||||
|
||||
/* WK_UP - PA0, active high */
|
||||
#define BSP_WKUP_PORT HAL_GPIO_PORT_A
|
||||
#define BSP_WKUP_PIN HAL_GPIO_PIN_0
|
||||
typedef struct {
|
||||
const char* section;
|
||||
const char* key;
|
||||
const char* value;
|
||||
} bsp_config_entry_t;
|
||||
|
||||
/**
|
||||
* @brief UART hardware configuration
|
||||
* @brief BSP configuration parser context
|
||||
*/
|
||||
#define BSP_UART_INSTANCE BSP_UART_INSTANCE_1
|
||||
#define BSP_UART_BAUDRATE 115200
|
||||
#define BSP_UART_PARITY HAL_UART_PARITY_NONE
|
||||
#define BSP_UART_STOPBITS HAL_UART_STOPBITS_1
|
||||
#define BSP_UART_DATABITS HAL_UART_DATABITS_8
|
||||
typedef struct {
|
||||
FILE* file;
|
||||
char current_section[BSP_CONFIG_MAX_SECTION_NAME_LENGTH];
|
||||
char buffer[BSP_CONFIG_MAX_LINE_LENGTH];
|
||||
uint32_t line_number;
|
||||
uint8_t initialized;
|
||||
} bsp_config_parser_t;
|
||||
|
||||
/**
|
||||
* @brief BSP configuration file operations
|
||||
*/
|
||||
typedef struct {
|
||||
hal_ret_t (*open)(const char* filename, bsp_config_parser_t* parser);
|
||||
hal_ret_t (*close)(bsp_config_parser_t* parser);
|
||||
hal_ret_t (*read_entry)(bsp_config_parser_t* parser, bsp_config_entry_t* entry);
|
||||
hal_ret_t (*parse_int)(const char* value, int* result);
|
||||
hal_ret_t (*parse_uint)(const char* value, uint32_t* result);
|
||||
hal_ret_t (*parse_bool)(const char* value, uint8_t* result);
|
||||
hal_ret_t (*parse_string)(const char* value, char* result, size_t max_length);
|
||||
} bsp_config_ops_t;
|
||||
|
||||
/**
|
||||
* @brief Initialize BSP configuration system
|
||||
* @retval HAL status code
|
||||
*/
|
||||
hal_ret_t bsp_config_init(void);
|
||||
|
||||
/**
|
||||
* @brief Deinitialize BSP configuration system
|
||||
* @retval HAL status code
|
||||
*/
|
||||
hal_ret_t bsp_config_deinit(void);
|
||||
|
||||
/**
|
||||
* @brief Load BSP configuration from file
|
||||
* @param filename: Configuration file name
|
||||
* @retval HAL status code
|
||||
*/
|
||||
hal_ret_t bsp_config_load(const char* filename);
|
||||
|
||||
/**
|
||||
* @brief Save BSP configuration to file
|
||||
* @param filename: Configuration file name
|
||||
* @retval HAL status code
|
||||
*/
|
||||
hal_ret_t bsp_config_save(const char* filename);
|
||||
|
||||
/**
|
||||
* @brief Get configuration value
|
||||
* @param section: Configuration section name
|
||||
* @param key: Configuration key name
|
||||
* @param value: Pointer to store value
|
||||
* @param max_length: Maximum length of value buffer
|
||||
* @retval HAL status code
|
||||
*/
|
||||
hal_ret_t bsp_config_get_value(const char* section, const char* key, char* value, size_t max_length);
|
||||
|
||||
/**
|
||||
* @brief Set configuration value
|
||||
* @param section: Configuration section name
|
||||
* @param key: Configuration key name
|
||||
* @param value: Configuration value
|
||||
* @retval HAL status code
|
||||
*/
|
||||
hal_ret_t bsp_config_set_value(const char* section, const char* key, const char* value);
|
||||
|
||||
/**
|
||||
* @brief Get configuration value as integer
|
||||
* @param section: Configuration section name
|
||||
* @param key: Configuration key name
|
||||
* @param value: Pointer to store integer value
|
||||
* @retval HAL status code
|
||||
*/
|
||||
hal_ret_t bsp_config_get_int(const char* section, const char* key, int* value);
|
||||
|
||||
/**
|
||||
* @brief Set configuration value as integer
|
||||
* @param section: Configuration section name
|
||||
* @param key: Configuration key name
|
||||
* @param value: Integer value
|
||||
* @retval HAL status code
|
||||
*/
|
||||
hal_ret_t bsp_config_set_int(const char* section, const char* key, int value);
|
||||
|
||||
/**
|
||||
* @brief Get configuration value as unsigned integer
|
||||
* @param section: Configuration section name
|
||||
* @param key: Configuration key name
|
||||
* @param value: Pointer to store unsigned integer value
|
||||
* @retval HAL status code
|
||||
*/
|
||||
hal_ret_t bsp_config_get_uint(const char* section, const char* key, uint32_t* value);
|
||||
|
||||
/**
|
||||
* @brief Set configuration value as unsigned integer
|
||||
* @param section: Configuration section name
|
||||
* @param key: Configuration key name
|
||||
* @param value: Unsigned integer value
|
||||
* @retval HAL status code
|
||||
*/
|
||||
hal_ret_t bsp_config_set_uint(const char* section, const char* key, uint32_t value);
|
||||
|
||||
/**
|
||||
* @brief Get configuration value as boolean
|
||||
* @param section: Configuration section name
|
||||
* @param key: Configuration key name
|
||||
* @param value: Pointer to store boolean value
|
||||
* @retval HAL status code
|
||||
*/
|
||||
hal_ret_t bsp_config_get_bool(const char* section, const char* key, uint8_t* value);
|
||||
|
||||
/**
|
||||
* @brief Set configuration value as boolean
|
||||
* @param section: Configuration section name
|
||||
* @param key: Configuration key name
|
||||
* @param value: Boolean value
|
||||
* @retval HAL status code
|
||||
*/
|
||||
hal_ret_t bsp_config_set_bool(const char* section, const char* key, uint8_t value);
|
||||
|
||||
/**
|
||||
* @brief Parse BSP modules from configuration
|
||||
* @param config: Pointer to BSP board configuration structure to fill
|
||||
* @retval HAL status code
|
||||
*/
|
||||
hal_ret_t bsp_config_parse_modules(bsp_board_config_t* config);
|
||||
|
||||
/**
|
||||
* @brief Initialize BSP from configuration file
|
||||
* @param filename: Configuration file name
|
||||
* @retval HAL status code
|
||||
*/
|
||||
hal_ret_t bsp_init_from_config(const char* filename);
|
||||
|
||||
#endif /* BSP_CONFIG_H */
|
||||
|
||||
@ -14,13 +14,15 @@
|
||||
|
||||
/**
|
||||
* @brief Initialize board support package
|
||||
* @retval HAL status code
|
||||
*/
|
||||
void bsp_init(void);
|
||||
hal_ret_t bsp_init(void);
|
||||
|
||||
/**
|
||||
* @brief Initialize board GPIO
|
||||
* @retval HAL status code
|
||||
*/
|
||||
void bsp_gpio_init(void);
|
||||
hal_ret_t bsp_gpio_init(void);
|
||||
|
||||
/**
|
||||
* @brief Get board name
|
||||
|
||||
401
BSP/Inc/bsp_module.h
Normal file
401
BSP/Inc/bsp_module.h
Normal file
@ -0,0 +1,401 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file : bsp_module.h
|
||||
* @brief : Board support package module management header file
|
||||
******************************************************************************
|
||||
*/
|
||||
/* USER CODE END Header */
|
||||
|
||||
#ifndef BSP_MODULE_H
|
||||
#define BSP_MODULE_H
|
||||
|
||||
#include "hal.h"
|
||||
|
||||
/**
|
||||
* @brief BSP module type definitions
|
||||
*/
|
||||
typedef enum {
|
||||
BSP_MODULE_TYPE_LED = 0,
|
||||
BSP_MODULE_TYPE_BUTTON,
|
||||
BSP_MODULE_TYPE_UART,
|
||||
BSP_MODULE_TYPE_SPI,
|
||||
BSP_MODULE_TYPE_I2C,
|
||||
BSP_MODULE_TYPE_CAN,
|
||||
BSP_MODULE_TYPE_ADC,
|
||||
BSP_MODULE_TYPE_DAC,
|
||||
BSP_MODULE_TYPE_TIMER,
|
||||
BSP_MODULE_TYPE_RTC,
|
||||
BSP_MODULE_TYPE_W25QXX,
|
||||
BSP_MODULE_TYPE_MAX
|
||||
} bsp_module_type_t;
|
||||
|
||||
/**
|
||||
* @brief BSP module state definitions
|
||||
*/
|
||||
typedef enum {
|
||||
BSP_MODULE_STATE_UNINIT = 0,
|
||||
BSP_MODULE_STATE_INIT,
|
||||
BSP_MODULE_STATE_CONFIGURED,
|
||||
BSP_MODULE_STATE_RUNNING,
|
||||
BSP_MODULE_STATE_ERROR
|
||||
} bsp_module_state_t;
|
||||
|
||||
/**
|
||||
* @brief BSP module priority definitions
|
||||
*/
|
||||
typedef enum {
|
||||
BSP_MODULE_PRIORITY_HIGHEST = 0,
|
||||
BSP_MODULE_PRIORITY_HIGH,
|
||||
BSP_MODULE_PRIORITY_MEDIUM,
|
||||
BSP_MODULE_PRIORITY_LOW,
|
||||
BSP_MODULE_PRIORITY_LOWEST
|
||||
} bsp_module_priority_t;
|
||||
|
||||
/**
|
||||
* @brief BSP module configuration structure
|
||||
*/
|
||||
typedef struct bsp_module_config {
|
||||
bsp_module_type_t type; /*!< Module type */
|
||||
const char* name; /*!< Module name */
|
||||
bsp_module_priority_t priority; /*!< Module priority */
|
||||
uint32_t version; /*!< Module version */
|
||||
uint8_t instance; /*!< Module instance */
|
||||
uint8_t enable; /*!< Module enable flag */
|
||||
void* config_data; /*!< Module configuration data */
|
||||
size_t config_size; /*!< Module configuration size */
|
||||
uint32_t dependencies; /*!< Module dependencies bitmask */
|
||||
} bsp_module_config_t;
|
||||
|
||||
/**
|
||||
* @brief BSP module operations structure
|
||||
*/
|
||||
typedef struct {
|
||||
hal_ret_t (*init)(void* config); /*!< Module initialization function */
|
||||
hal_ret_t (*deinit)(void); /*!< Module deinitialization function */
|
||||
hal_ret_t (*configure)(void* config); /*!< Module configuration function */
|
||||
hal_ret_t (*start)(void); /*!< Module start function */
|
||||
hal_ret_t (*stop)(void); /*!< Module stop function */
|
||||
hal_ret_t (*reset)(void); /*!< Module reset function */
|
||||
bsp_module_state_t (*get_state)(void); /*!< Module get state function */
|
||||
hal_ret_t (*control)(uint32_t cmd, void* param); /*!< Module control function */
|
||||
} bsp_module_ops_t;
|
||||
|
||||
/**
|
||||
* @brief BSP module version structure
|
||||
*/
|
||||
typedef struct {
|
||||
uint8_t major;
|
||||
uint8_t minor;
|
||||
uint8_t patch;
|
||||
} bsp_module_version_t;
|
||||
|
||||
/**
|
||||
* @brief Forward declaration of bsp_module_t
|
||||
*/
|
||||
typedef struct bsp_module bsp_module_t;
|
||||
|
||||
/**
|
||||
* @brief BSP module event callback type
|
||||
*/
|
||||
typedef hal_ret_t (*bsp_module_event_callback_t)(const bsp_module_t* sender, uint32_t event, void* data);
|
||||
|
||||
/**
|
||||
* @brief BSP module structure
|
||||
*/
|
||||
typedef struct bsp_module {
|
||||
bsp_module_config_t config; /*!< Module configuration */
|
||||
bsp_module_ops_t ops; /*!< Module operations */
|
||||
bsp_module_state_t state; /*!< Module state */
|
||||
bsp_module_version_t version; /*!< Module version */
|
||||
struct bsp_module* next; /*!< Pointer to next module in the list */
|
||||
struct bsp_module* prev; /*!< Pointer to previous module in the list */
|
||||
void* private_data; /*!< Module private data */
|
||||
bsp_module_event_callback_t event_callback; /*!< Event callback */
|
||||
} bsp_module_t;
|
||||
|
||||
/**
|
||||
* @brief BSP module event definitions
|
||||
*/
|
||||
#define BSP_MODULE_EVENT_INIT (1 << 0) /*!< Module initialized */
|
||||
#define BSP_MODULE_EVENT_DEINIT (1 << 1) /*!< Module deinitialized */
|
||||
#define BSP_MODULE_EVENT_START (1 << 2) /*!< Module started */
|
||||
#define BSP_MODULE_EVENT_STOP (1 << 3) /*!< Module stopped */
|
||||
#define BSP_MODULE_EVENT_ERROR (1 << 4) /*!< Module error */
|
||||
#define BSP_MODULE_EVENT_CONFIG (1 << 5) /*!< Module configured */
|
||||
#define BSP_MODULE_EVENT_CUSTOM (1 << 8) /*!< Custom module event base */
|
||||
|
||||
/**
|
||||
* @brief BSP module auto-registration macros
|
||||
*/
|
||||
#define BSP_MODULE_REGISTER(module) \
|
||||
static const bsp_module_config_t __bsp_module_##module##_config = { \
|
||||
.type = BSP_MODULE_TYPE_##module, \
|
||||
.name = #module, \
|
||||
.priority = BSP_MODULE_PRIORITY_MEDIUM, \
|
||||
.version = 1, \
|
||||
.instance = 0, \
|
||||
.enable = 1, \
|
||||
.config_data = NULL, \
|
||||
.config_size = 0, \
|
||||
.dependencies = 0 \
|
||||
}; \
|
||||
static bsp_module_t __bsp_module_##module = { \
|
||||
.config = __bsp_module_##module##_config, \
|
||||
.state = BSP_MODULE_STATE_UNINIT, \
|
||||
.version = {1, 0, 0}, \
|
||||
.event_callback = NULL \
|
||||
};
|
||||
|
||||
#define BSP_MODULE_REGISTER_FULL(module, type, priority, instance, deps) \
|
||||
static const bsp_module_config_t __bsp_module_##module##_config = { \
|
||||
.type = (type), \
|
||||
.name = #module, \
|
||||
.priority = (priority), \
|
||||
.version = 1, \
|
||||
.instance = (instance), \
|
||||
.enable = 1, \
|
||||
.config_data = NULL, \
|
||||
.config_size = 0, \
|
||||
.dependencies = (deps) \
|
||||
}; \
|
||||
static bsp_module_t __bsp_module_##module = { \
|
||||
.config = __bsp_module_##module##_config, \
|
||||
.state = BSP_MODULE_STATE_UNINIT, \
|
||||
.version = {1, 0, 0}, \
|
||||
.event_callback = NULL \
|
||||
};
|
||||
|
||||
#define BSP_MODULE_REGISTER_AT_STARTUP(module) \
|
||||
BSP_MODULE_REGISTER(module) \
|
||||
__attribute__((constructor)) static void __bsp_register_##module##_at_startup(void) { \
|
||||
bsp_module_register(&__bsp_module_##module); \
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief BSP module manager structure
|
||||
*/
|
||||
typedef struct {
|
||||
bsp_module_t* modules[BSP_MODULE_TYPE_MAX]; /*!< Modules by type */
|
||||
bsp_module_t* module_list; /*!< Linked list of all modules */
|
||||
uint32_t module_count; /*!< Total number of modules */
|
||||
} bsp_module_manager_t;
|
||||
|
||||
/**
|
||||
* @brief Initialize BSP module manager
|
||||
* @retval HAL status code
|
||||
*/
|
||||
hal_ret_t bsp_module_manager_init(void);
|
||||
|
||||
/**
|
||||
* @brief Register a BSP module
|
||||
* @param module: Pointer to module structure
|
||||
* @retval HAL status code
|
||||
*/
|
||||
hal_ret_t bsp_module_register(bsp_module_t* module);
|
||||
|
||||
/**
|
||||
* @brief Unregister a BSP module
|
||||
* @param module: Pointer to module structure
|
||||
* @retval HAL status code
|
||||
*/
|
||||
hal_ret_t bsp_module_unregister(bsp_module_t* module);
|
||||
|
||||
/**
|
||||
* @brief Initialize all registered BSP modules
|
||||
* @retval HAL status code
|
||||
*/
|
||||
hal_ret_t bsp_module_init_all(void);
|
||||
|
||||
/**
|
||||
* @brief Deinitialize all registered BSP modules
|
||||
* @retval HAL status code
|
||||
*/
|
||||
hal_ret_t bsp_module_deinit_all(void);
|
||||
|
||||
/**
|
||||
* @brief Start all registered BSP modules
|
||||
* @retval HAL status code
|
||||
*/
|
||||
hal_ret_t bsp_module_start_all(void);
|
||||
|
||||
/**
|
||||
* @brief Stop all registered BSP modules
|
||||
* @retval HAL status code
|
||||
*/
|
||||
hal_ret_t bsp_module_stop_all(void);
|
||||
|
||||
/**
|
||||
* @brief Initialize a specific BSP module
|
||||
* @param type: Module type
|
||||
* @param instance: Module instance
|
||||
* @retval HAL status code
|
||||
*/
|
||||
hal_ret_t bsp_module_init(bsp_module_type_t type, uint8_t instance);
|
||||
|
||||
/**
|
||||
* @brief Deinitialize a specific BSP module
|
||||
* @param type: Module type
|
||||
* @param instance: Module instance
|
||||
* @retval HAL status code
|
||||
*/
|
||||
hal_ret_t bsp_module_deinit(bsp_module_type_t type, uint8_t instance);
|
||||
|
||||
/**
|
||||
* @brief Configure a specific BSP module
|
||||
* @param type: Module type
|
||||
* @param instance: Module instance
|
||||
* @param config: Module configuration data
|
||||
* @param size: Module configuration size
|
||||
* @retval HAL status code
|
||||
*/
|
||||
hal_ret_t bsp_module_configure(bsp_module_type_t type, uint8_t instance, void* config, size_t size);
|
||||
|
||||
/**
|
||||
* @brief Start a specific BSP module
|
||||
* @param type: Module type
|
||||
* @param instance: Module instance
|
||||
* @retval HAL status code
|
||||
*/
|
||||
hal_ret_t bsp_module_start(bsp_module_type_t type, uint8_t instance);
|
||||
|
||||
/**
|
||||
* @brief Stop a specific BSP module
|
||||
* @param type: Module type
|
||||
* @param instance: Module instance
|
||||
* @retval HAL status code
|
||||
*/
|
||||
hal_ret_t bsp_module_stop(bsp_module_type_t type, uint8_t instance);
|
||||
|
||||
/**
|
||||
* @brief Reset a specific BSP module
|
||||
* @param type: Module type
|
||||
* @param instance: Module instance
|
||||
* @retval HAL status code
|
||||
*/
|
||||
hal_ret_t bsp_module_reset(bsp_module_type_t type, uint8_t instance);
|
||||
|
||||
/**
|
||||
* @brief Get state of a specific BSP module
|
||||
* @param type: Module type
|
||||
* @param instance: Module instance
|
||||
* @param state: Pointer to store module state
|
||||
* @retval HAL status code
|
||||
*/
|
||||
hal_ret_t bsp_module_get_state(bsp_module_type_t type, uint8_t instance, bsp_module_state_t* state);
|
||||
|
||||
/**
|
||||
* @brief Control a specific BSP module
|
||||
* @param type: Module type
|
||||
* @param instance: Module instance
|
||||
* @param cmd: Control command
|
||||
* @param param: Control parameter
|
||||
* @retval HAL status code
|
||||
*/
|
||||
hal_ret_t bsp_module_control(bsp_module_type_t type, uint8_t instance, uint32_t cmd, void* param);
|
||||
|
||||
/**
|
||||
* @brief Get a specific BSP module
|
||||
* @param type: Module type
|
||||
* @param instance: Module instance
|
||||
* @retval Pointer to module structure, or NULL if not found
|
||||
*/
|
||||
bsp_module_t* bsp_module_get(bsp_module_type_t type, uint8_t instance);
|
||||
|
||||
/**
|
||||
* @brief Get all modules of a specific type
|
||||
* @param type: Module type
|
||||
* @retval Pointer to module list, or NULL if no modules found
|
||||
*/
|
||||
bsp_module_t* bsp_module_get_by_type(bsp_module_type_t type);
|
||||
|
||||
/**
|
||||
* @brief Get module by name
|
||||
* @param name: Module name
|
||||
* @retval Pointer to module structure, or NULL if not found
|
||||
*/
|
||||
bsp_module_t* bsp_module_get_by_name(const char* name);
|
||||
|
||||
/**
|
||||
* @brief Get total number of registered modules
|
||||
* @retval Number of registered modules
|
||||
*/
|
||||
uint32_t bsp_module_get_count(void);
|
||||
|
||||
/**
|
||||
* @brief Check if all dependencies of a module are satisfied
|
||||
* @param module: Pointer to module structure
|
||||
* @retval HAL status code
|
||||
*/
|
||||
hal_ret_t bsp_module_check_dependencies(const bsp_module_t* module);
|
||||
|
||||
/**
|
||||
* @brief Get module manager instance
|
||||
* @retval Pointer to module manager structure
|
||||
*/
|
||||
bsp_module_manager_t* bsp_module_get_manager(void);
|
||||
|
||||
/**
|
||||
* @brief Register a module event callback
|
||||
* @param type: Module type
|
||||
* @param instance: Module instance
|
||||
* @param callback: Event callback function
|
||||
* @retval HAL status code
|
||||
*/
|
||||
hal_ret_t bsp_module_register_event_callback(bsp_module_type_t type, uint8_t instance, bsp_module_event_callback_t callback);
|
||||
|
||||
/**
|
||||
* @brief Trigger a module event
|
||||
* @param module: Pointer to module structure
|
||||
* @param event: Event to trigger
|
||||
* @param data: Event data
|
||||
* @retval HAL status code
|
||||
*/
|
||||
hal_ret_t bsp_module_trigger_event(const bsp_module_t* module, uint32_t event, void* data);
|
||||
|
||||
/**
|
||||
* @brief Find modules by priority range
|
||||
* @param min_priority: Minimum priority
|
||||
* @param max_priority: Maximum priority
|
||||
* @param count: Pointer to store number of modules found
|
||||
* @retval Pointer to array of module pointers, or NULL if no modules found
|
||||
*/
|
||||
bsp_module_t** bsp_module_find_by_priority_range(bsp_module_priority_t min_priority, bsp_module_priority_t max_priority, uint32_t* count);
|
||||
|
||||
/**
|
||||
* @brief Set module enable/disable state
|
||||
* @param type: Module type
|
||||
* @param instance: Module instance
|
||||
* @param enable: Enable flag
|
||||
* @retval HAL status code
|
||||
*/
|
||||
hal_ret_t bsp_module_set_enable(bsp_module_type_t type, uint8_t instance, uint8_t enable);
|
||||
|
||||
/**
|
||||
* @brief Check if module is enabled
|
||||
* @param type: Module type
|
||||
* @param instance: Module instance
|
||||
* @param enable: Pointer to store enable state
|
||||
* @retval HAL status code
|
||||
*/
|
||||
hal_ret_t bsp_module_is_enabled(bsp_module_type_t type, uint8_t instance, uint8_t* enable);
|
||||
|
||||
/**
|
||||
* @brief Set module priority
|
||||
* @param type: Module type
|
||||
* @param instance: Module instance
|
||||
* @param priority: New priority
|
||||
* @retval HAL status code
|
||||
*/
|
||||
hal_ret_t bsp_module_set_priority(bsp_module_type_t type, uint8_t instance, bsp_module_priority_t priority);
|
||||
|
||||
/**
|
||||
* @brief Get module priority
|
||||
* @param type: Module type
|
||||
* @param instance: Module instance
|
||||
* @param priority: Pointer to store priority
|
||||
* @retval HAL return code
|
||||
*/
|
||||
hal_ret_t bsp_module_get_priority(bsp_module_type_t type, uint8_t instance, bsp_module_priority_t* priority);
|
||||
|
||||
#endif /* BSP_MODULE_H */
|
||||
@ -64,30 +64,34 @@ const bsp_board_config_t* bsp_board_get_by_name(const char* name) {
|
||||
/**
|
||||
* @brief Set current board configuration by index
|
||||
* @param index: Board configuration index
|
||||
* @retval 0 if successful, -1 if invalid index
|
||||
* @retval HAL status code
|
||||
*/
|
||||
int8_t bsp_board_set_by_index(uint8_t index) {
|
||||
hal_ret_t bsp_board_set_by_index(uint8_t index) {
|
||||
if (index < bsp_board_get_count()) {
|
||||
current_board_index = index;
|
||||
return 0;
|
||||
return HAL_RET_OK;
|
||||
}
|
||||
return -1;
|
||||
return HAL_RET_INVALID_PARAM;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set current board configuration by name
|
||||
* @param name: Board name string
|
||||
* @retval 0 if successful, -1 if not found
|
||||
* @retval HAL status code
|
||||
*/
|
||||
int8_t bsp_board_set_by_name(const char* name) {
|
||||
hal_ret_t bsp_board_set_by_name(const char* name) {
|
||||
if (name == NULL) {
|
||||
return HAL_RET_INVALID_PARAM;
|
||||
}
|
||||
|
||||
for (uint8_t i = 0; i < bsp_board_get_count(); i++) {
|
||||
if (supported_boards[i]->name != NULL &&
|
||||
strcmp(supported_boards[i]->name, name) == 0) {
|
||||
current_board_index = i;
|
||||
return 0;
|
||||
return HAL_RET_OK;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
return HAL_RET_ERROR;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
653
BSP/Src/bsp_config.c
Normal file
653
BSP/Src/bsp_config.c
Normal file
@ -0,0 +1,653 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file : bsp_config.c
|
||||
* @brief : Board support package configuration file source
|
||||
******************************************************************************
|
||||
*/
|
||||
/* USER CODE END Header */
|
||||
|
||||
#include "bsp_config.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
/**
|
||||
* @brief Configuration storage entry
|
||||
*/
|
||||
typedef struct bsp_config_storage_entry {
|
||||
char section[BSP_CONFIG_MAX_SECTION_NAME_LENGTH];
|
||||
char key[BSP_CONFIG_MAX_KEY_NAME_LENGTH];
|
||||
char value[BSP_CONFIG_MAX_VALUE_LENGTH];
|
||||
struct bsp_config_storage_entry* next;
|
||||
} bsp_config_storage_entry_t;
|
||||
|
||||
/**
|
||||
* @brief Configuration storage
|
||||
*/
|
||||
typedef struct {
|
||||
bsp_config_storage_entry_t* entries;
|
||||
uint32_t entry_count;
|
||||
uint8_t initialized;
|
||||
} bsp_config_storage_t;
|
||||
|
||||
/**
|
||||
* @brief Configuration storage instance
|
||||
*/
|
||||
static bsp_config_storage_t bsp_config_storage = {
|
||||
.entries = NULL,
|
||||
.entry_count = 0,
|
||||
.initialized = 0
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Trim whitespace from a string
|
||||
* @param str: String to trim
|
||||
* @return Trimmed string
|
||||
*/
|
||||
static char* bsp_config_trim(char* str) {
|
||||
char* end;
|
||||
|
||||
// Trim leading whitespace
|
||||
while (isspace((unsigned char)*str)) {
|
||||
str++;
|
||||
}
|
||||
|
||||
if (*str == 0) {
|
||||
return str;
|
||||
}
|
||||
|
||||
// Trim trailing whitespace
|
||||
end = str + strlen(str) - 1;
|
||||
while (end > str && isspace((unsigned char)*end)) {
|
||||
end--;
|
||||
}
|
||||
|
||||
// Null terminate
|
||||
*(end + 1) = 0;
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Open configuration file
|
||||
* @param filename: Configuration file name
|
||||
* @param parser: Parser context
|
||||
* @retval HAL status code
|
||||
*/
|
||||
static hal_ret_t bsp_config_file_open(const char* filename, bsp_config_parser_t* parser) {
|
||||
if (filename == NULL || parser == NULL) {
|
||||
return HAL_INVALID_PARAM;
|
||||
}
|
||||
|
||||
parser->file = fopen(filename, "r");
|
||||
if (parser->file == NULL) {
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
memset(parser->current_section, 0, sizeof(parser->current_section));
|
||||
memset(parser->buffer, 0, sizeof(parser->buffer));
|
||||
parser->line_number = 0;
|
||||
parser->initialized = 1;
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Close configuration file
|
||||
* @param parser: Parser context
|
||||
* @retval HAL status code
|
||||
*/
|
||||
static hal_ret_t bsp_config_file_close(bsp_config_parser_t* parser) {
|
||||
if (parser == NULL || !parser->initialized) {
|
||||
return HAL_INVALID_PARAM;
|
||||
}
|
||||
|
||||
if (parser->file != NULL) {
|
||||
fclose(parser->file);
|
||||
parser->file = NULL;
|
||||
}
|
||||
|
||||
parser->initialized = 0;
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Read a configuration entry from file
|
||||
* @param parser: Parser context
|
||||
* @param entry: Configuration entry
|
||||
* @retval HAL status code
|
||||
*/
|
||||
static hal_ret_t bsp_config_file_read_entry(bsp_config_parser_t* parser, bsp_config_entry_t* entry) {
|
||||
if (parser == NULL || entry == NULL || !parser->initialized) {
|
||||
return HAL_INVALID_PARAM;
|
||||
}
|
||||
|
||||
if (parser->file == NULL) {
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
while (fgets(parser->buffer, sizeof(parser->buffer), parser->file) != NULL) {
|
||||
parser->line_number++;
|
||||
|
||||
char* line = bsp_config_trim(parser->buffer);
|
||||
size_t len = strlen(line);
|
||||
|
||||
// Skip empty lines and comments
|
||||
if (len == 0 || line[0] == '#') {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check for section header
|
||||
if (line[0] == '[' && line[len - 1] == ']') {
|
||||
// Extract section name
|
||||
memset(parser->current_section, 0, sizeof(parser->current_section));
|
||||
strncpy(parser->current_section, line + 1, len - 2);
|
||||
parser->current_section[len - 2] = '\0';
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check for key-value pair
|
||||
char* equals = strchr(line, '=');
|
||||
if (equals != NULL) {
|
||||
// Extract key and value
|
||||
*equals = '\0';
|
||||
char* key = bsp_config_trim(line);
|
||||
char* value = bsp_config_trim(equals + 1);
|
||||
|
||||
entry->section = parser->current_section;
|
||||
entry->key = key;
|
||||
entry->value = value;
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
}
|
||||
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Parse integer value
|
||||
* @param value: String value to parse
|
||||
* @param result: Pointer to store result
|
||||
* @retval HAL status code
|
||||
*/
|
||||
static hal_ret_t bsp_config_parse_int(const char* value, int* result) {
|
||||
if (value == NULL || result == NULL) {
|
||||
return HAL_INVALID_PARAM;
|
||||
}
|
||||
|
||||
char* endptr;
|
||||
long val = strtol(value, &endptr, 0);
|
||||
|
||||
if (*endptr != '\0') {
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
*result = (int)val;
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Parse unsigned integer value
|
||||
* @param value: String value to parse
|
||||
* @param result: Pointer to store result
|
||||
* @retval HAL status code
|
||||
*/
|
||||
static hal_ret_t bsp_config_parse_uint(const char* value, uint32_t* result) {
|
||||
if (value == NULL || result == NULL) {
|
||||
return HAL_INVALID_PARAM;
|
||||
}
|
||||
|
||||
char* endptr;
|
||||
unsigned long val = strtoul(value, &endptr, 0);
|
||||
|
||||
if (*endptr != '\0') {
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
*result = (uint32_t)val;
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Parse boolean value
|
||||
* @param value: String value to parse
|
||||
* @param result: Pointer to store result
|
||||
* @retval HAL status code
|
||||
*/
|
||||
static hal_ret_t bsp_config_parse_bool(const char* value, uint8_t* result) {
|
||||
if (value == NULL || result == NULL) {
|
||||
return HAL_INVALID_PARAM;
|
||||
}
|
||||
|
||||
if (strcmp(value, "true") == 0 || strcmp(value, "TRUE") == 0 ||
|
||||
strcmp(value, "1") == 0 || strcmp(value, "yes") == 0 ||
|
||||
strcmp(value, "YES") == 0) {
|
||||
*result = 1;
|
||||
return HAL_OK;
|
||||
} else if (strcmp(value, "false") == 0 || strcmp(value, "FALSE") == 0 ||
|
||||
strcmp(value, "0") == 0 || strcmp(value, "no") == 0 ||
|
||||
strcmp(value, "NO") == 0) {
|
||||
*result = 0;
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Parse string value
|
||||
* @param value: String value to parse
|
||||
* @param result: Pointer to store result
|
||||
* @param max_length: Maximum length of result buffer
|
||||
* @retval HAL status code
|
||||
*/
|
||||
static hal_ret_t bsp_config_parse_string(const char* value, char* result, size_t max_length) {
|
||||
if (value == NULL || result == NULL) {
|
||||
return HAL_INVALID_PARAM;
|
||||
}
|
||||
|
||||
strncpy(result, value, max_length - 1);
|
||||
result[max_length - 1] = '\0';
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Add a configuration entry to storage
|
||||
* @param section: Section name
|
||||
* @param key: Key name
|
||||
* @param value: Value
|
||||
* @retval HAL status code
|
||||
*/
|
||||
static hal_ret_t bsp_config_storage_add(const char* section, const char* key, const char* value) {
|
||||
// Check if entry already exists
|
||||
bsp_config_storage_entry_t* entry = bsp_config_storage.entries;
|
||||
while (entry != NULL) {
|
||||
if (strcmp(entry->section, section) == 0 && strcmp(entry->key, key) == 0) {
|
||||
// Update existing entry
|
||||
strncpy(entry->value, value, sizeof(entry->value) - 1);
|
||||
entry->value[sizeof(entry->value) - 1] = '\0';
|
||||
return HAL_OK;
|
||||
}
|
||||
entry = entry->next;
|
||||
}
|
||||
|
||||
// Create new entry
|
||||
bsp_config_storage_entry_t* new_entry = malloc(sizeof(bsp_config_storage_entry_t));
|
||||
if (new_entry == NULL) {
|
||||
return HAL_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
strncpy(new_entry->section, section, sizeof(new_entry->section) - 1);
|
||||
strncpy(new_entry->key, key, sizeof(new_entry->key) - 1);
|
||||
strncpy(new_entry->value, value, sizeof(new_entry->value) - 1);
|
||||
new_entry->section[sizeof(new_entry->section) - 1] = '\0';
|
||||
new_entry->key[sizeof(new_entry->key) - 1] = '\0';
|
||||
new_entry->value[sizeof(new_entry->value) - 1] = '\0';
|
||||
new_entry->next = NULL;
|
||||
|
||||
// Add to list
|
||||
if (bsp_config_storage.entries == NULL) {
|
||||
bsp_config_storage.entries = new_entry;
|
||||
} else {
|
||||
entry = bsp_config_storage.entries;
|
||||
while (entry->next != NULL) {
|
||||
entry = entry->next;
|
||||
}
|
||||
entry->next = new_entry;
|
||||
}
|
||||
|
||||
bsp_config_storage.entry_count++;
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clear configuration storage
|
||||
*/
|
||||
static void bsp_config_storage_clear(void) {
|
||||
bsp_config_storage_entry_t* entry = bsp_config_storage.entries;
|
||||
while (entry != NULL) {
|
||||
bsp_config_storage_entry_t* next = entry->next;
|
||||
free(entry);
|
||||
entry = next;
|
||||
}
|
||||
|
||||
bsp_config_storage.entries = NULL;
|
||||
bsp_config_storage.entry_count = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initialize BSP configuration system
|
||||
* @retval HAL status code
|
||||
*/
|
||||
hal_ret_t bsp_config_init(void) {
|
||||
if (bsp_config_storage.initialized) {
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
bsp_config_storage_clear();
|
||||
bsp_config_storage.initialized = 1;
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Deinitialize BSP configuration system
|
||||
* @retval HAL status code
|
||||
*/
|
||||
hal_ret_t bsp_config_deinit(void) {
|
||||
if (!bsp_config_storage.initialized) {
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
bsp_config_storage_clear();
|
||||
bsp_config_storage.initialized = 0;
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Load BSP configuration from file
|
||||
* @param filename: Configuration file name
|
||||
* @retval HAL status code
|
||||
*/
|
||||
hal_ret_t bsp_config_load(const char* filename) {
|
||||
if (!bsp_config_storage.initialized) {
|
||||
hal_ret_t status = bsp_config_init();
|
||||
if (status != HAL_OK) {
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
bsp_config_parser_t parser;
|
||||
hal_ret_t status = bsp_config_file_open(filename, &parser);
|
||||
if (status != HAL_OK) {
|
||||
return status;
|
||||
}
|
||||
|
||||
bsp_config_entry_t entry;
|
||||
while ((status = bsp_config_file_read_entry(&parser, &entry)) == HAL_OK) {
|
||||
status = bsp_config_storage_add(entry.section, entry.key, entry.value);
|
||||
if (status != HAL_OK) {
|
||||
bsp_config_file_close(&parser);
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
if (status != HAL_TIMEOUT) {
|
||||
bsp_config_file_close(&parser);
|
||||
return status;
|
||||
}
|
||||
|
||||
status = bsp_config_file_close(&parser);
|
||||
if (status != HAL_OK) {
|
||||
return status;
|
||||
}
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Save BSP configuration to file
|
||||
* @param filename: Configuration file name
|
||||
* @retval HAL status code
|
||||
*/
|
||||
hal_ret_t bsp_config_save(const char* filename) {
|
||||
if (!bsp_config_storage.initialized || bsp_config_storage.entry_count == 0) {
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
FILE* file = fopen(filename, "w");
|
||||
if (file == NULL) {
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
fprintf(file, "# BSP Configuration File\n");
|
||||
fprintf(file, "# Version: %s\n\n", BSP_CONFIG_FILE_VERSION);
|
||||
|
||||
char current_section[BSP_CONFIG_MAX_SECTION_NAME_LENGTH] = "";
|
||||
bsp_config_storage_entry_t* entry = bsp_config_storage.entries;
|
||||
|
||||
while (entry != NULL) {
|
||||
if (strcmp(entry->section, current_section) != 0) {
|
||||
// New section
|
||||
strncpy(current_section, entry->section, sizeof(current_section) - 1);
|
||||
fprintf(file, "[%s]\n", current_section);
|
||||
}
|
||||
|
||||
fprintf(file, "%s=%s\n", entry->key, entry->value);
|
||||
entry = entry->next;
|
||||
}
|
||||
|
||||
fclose(file);
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get configuration value
|
||||
* @param section: Configuration section name
|
||||
* @param key: Configuration key name
|
||||
* @param value: Pointer to store value
|
||||
* @param max_length: Maximum length of value buffer
|
||||
* @retval HAL status code
|
||||
*/
|
||||
hal_ret_t bsp_config_get_value(const char* section, const char* key, char* value, size_t max_length) {
|
||||
if (!bsp_config_storage.initialized || section == NULL || key == NULL || value == NULL) {
|
||||
return HAL_INVALID_PARAM;
|
||||
}
|
||||
|
||||
bsp_config_storage_entry_t* entry = bsp_config_storage.entries;
|
||||
while (entry != NULL) {
|
||||
if (strcmp(entry->section, section) == 0 && strcmp(entry->key, key) == 0) {
|
||||
strncpy(value, entry->value, max_length - 1);
|
||||
value[max_length - 1] = '\0';
|
||||
return HAL_OK;
|
||||
}
|
||||
entry = entry->next;
|
||||
}
|
||||
|
||||
return HAL_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set configuration value
|
||||
* @param section: Configuration section name
|
||||
* @param key: Configuration key name
|
||||
* @param value: Configuration value
|
||||
* @retval HAL status code
|
||||
*/
|
||||
hal_ret_t bsp_config_set_value(const char* section, const char* key, const char* value) {
|
||||
if (!bsp_config_storage.initialized || section == NULL || key == NULL || value == NULL) {
|
||||
return HAL_INVALID_PARAM;
|
||||
}
|
||||
|
||||
return bsp_config_storage_add(section, key, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get configuration value as integer
|
||||
* @param section: Configuration section name
|
||||
* @param key: Configuration key name
|
||||
* @param value: Pointer to store integer value
|
||||
* @retval HAL status code
|
||||
*/
|
||||
hal_ret_t bsp_config_get_int(const char* section, const char* key, int* value) {
|
||||
char str_value[BSP_CONFIG_MAX_VALUE_LENGTH];
|
||||
hal_ret_t status = bsp_config_get_value(section, key, str_value, sizeof(str_value));
|
||||
if (status != HAL_OK) {
|
||||
return status;
|
||||
}
|
||||
|
||||
return bsp_config_parse_int(str_value, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set configuration value as integer
|
||||
* @param section: Configuration section name
|
||||
* @param key: Configuration key name
|
||||
* @param value: Integer value
|
||||
* @retval HAL status code
|
||||
*/
|
||||
hal_ret_t bsp_config_set_int(const char* section, const char* key, int value) {
|
||||
char str_value[BSP_CONFIG_MAX_VALUE_LENGTH];
|
||||
snprintf(str_value, sizeof(str_value), "%d", value);
|
||||
return bsp_config_set_value(section, key, str_value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get configuration value as unsigned integer
|
||||
* @param section: Configuration section name
|
||||
* @param key: Configuration key name
|
||||
* @param value: Pointer to store unsigned integer value
|
||||
* @retval HAL status code
|
||||
*/
|
||||
hal_ret_t bsp_config_get_uint(const char* section, const char* key, uint32_t* value) {
|
||||
char str_value[BSP_CONFIG_MAX_VALUE_LENGTH];
|
||||
hal_status_t status = bsp_config_get_value(section, key, str_value, sizeof(str_value));
|
||||
if (status != HAL_OK) {
|
||||
return status;
|
||||
}
|
||||
|
||||
return bsp_config_parse_uint(str_value, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set configuration value as unsigned integer
|
||||
* @param section: Configuration section name
|
||||
* @param key: Configuration key name
|
||||
* @param value: Unsigned integer value
|
||||
* @retval HAL status code
|
||||
*/
|
||||
hal_ret_t bsp_config_set_uint(const char* section, const char* key, uint32_t value) {
|
||||
char str_value[BSP_CONFIG_MAX_VALUE_LENGTH];
|
||||
snprintf(str_value, sizeof(str_value), "%lu", (unsigned long)value);
|
||||
return bsp_config_set_value(section, key, str_value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get configuration value as boolean
|
||||
* @param section: Configuration section name
|
||||
* @param key: Configuration key name
|
||||
* @param value: Pointer to store boolean value
|
||||
* @retval HAL status code
|
||||
*/
|
||||
hal_ret_t bsp_config_get_bool(const char* section, const char* key, uint8_t* value) {
|
||||
char str_value[BSP_CONFIG_MAX_VALUE_LENGTH];
|
||||
hal_status_t status = bsp_config_get_value(section, key, str_value, sizeof(str_value));
|
||||
if (status != HAL_OK) {
|
||||
return status;
|
||||
}
|
||||
|
||||
return bsp_config_parse_bool(str_value, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set configuration value as boolean
|
||||
* @param section: Configuration section name
|
||||
* @param key: Configuration key name
|
||||
* @param value: Boolean value
|
||||
* @retval HAL status code
|
||||
*/
|
||||
hal_ret_t bsp_config_set_bool(const char* section, const char* key, uint8_t value) {
|
||||
return bsp_config_set_value(section, key, value ? "true" : "false");
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Parse BSP modules from configuration
|
||||
* @param config: Pointer to BSP board configuration structure to fill
|
||||
* @retval HAL status code
|
||||
*/
|
||||
hal_ret_t bsp_config_parse_modules(bsp_board_config_t* config) {
|
||||
if (config == NULL) {
|
||||
return HAL_INVALID_PARAM;
|
||||
}
|
||||
|
||||
// TODO: Implement module parsing logic
|
||||
// This will depend on the specific configuration file format
|
||||
// and how modules are defined in the configuration
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initialize BSP from configuration file
|
||||
* @param filename: Configuration file name
|
||||
* @retval HAL status code
|
||||
*/
|
||||
hal_ret_t bsp_init_from_config(const char* filename) {
|
||||
// Load configuration file
|
||||
hal_ret_t status = bsp_config_load(filename);
|
||||
if (status != HAL_OK) {
|
||||
return status;
|
||||
}
|
||||
|
||||
// Initialize HAL layer
|
||||
status = hal_init();
|
||||
if (status != HAL_OK) {
|
||||
return status;
|
||||
}
|
||||
|
||||
// Initialize BSP module manager
|
||||
status = bsp_module_manager_init();
|
||||
if (status != HAL_OK) {
|
||||
return status;
|
||||
}
|
||||
|
||||
// Create board configuration from file
|
||||
bsp_board_config_t board_config;
|
||||
memset(&board_config, 0, sizeof(board_config));
|
||||
|
||||
// Parse board information
|
||||
char board_name[64];
|
||||
status = bsp_config_get_value("board", "name", board_name, sizeof(board_name));
|
||||
if (status == HAL_OK) {
|
||||
board_config.name = strdup(board_name);
|
||||
} else {
|
||||
board_config.name = "Unknown";
|
||||
}
|
||||
|
||||
uint32_t version = BSP_CONFIG_VERSION;
|
||||
status = bsp_config_get_uint("board", "version", &version);
|
||||
if (status == HAL_OK) {
|
||||
board_config.version = version;
|
||||
} else {
|
||||
board_config.version = BSP_CONFIG_VERSION;
|
||||
}
|
||||
|
||||
// Parse modules from configuration
|
||||
status = bsp_config_parse_modules(&board_config);
|
||||
if (status != HAL_OK) {
|
||||
return status;
|
||||
}
|
||||
|
||||
// Initialize board
|
||||
status = bsp_board_init();
|
||||
if (status != HAL_OK) {
|
||||
return status;
|
||||
}
|
||||
|
||||
// Initialize all modules
|
||||
status = bsp_module_init_all();
|
||||
if (status != HAL_OK) {
|
||||
return status;
|
||||
}
|
||||
|
||||
// Configure all modules
|
||||
// TODO: Implement module configuration from file
|
||||
|
||||
// Start all modules
|
||||
status = bsp_module_start_all();
|
||||
if (status != HAL_OK) {
|
||||
return status;
|
||||
}
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
@ -16,20 +16,29 @@
|
||||
|
||||
/**
|
||||
* @brief Initialize board support package
|
||||
* @retval HAL status code
|
||||
*/
|
||||
void bsp_init(void) {
|
||||
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 */
|
||||
hal_init();
|
||||
status = hal_init();
|
||||
if (status != HAL_RET_OK) {
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Initialize peripherals based on configuration */
|
||||
|
||||
/* Initialize LED */
|
||||
if (board_config->led_init != NULL) {
|
||||
board_config->led_init(&board_config->led);
|
||||
} else {
|
||||
if (board_config->led.enable && board_config->init_funcs.led_init != NULL) {
|
||||
status = board_config->init_funcs.led_init(&board_config->led);
|
||||
if (status != HAL_RET_OK) {
|
||||
return status;
|
||||
}
|
||||
} else if (board_config->led.enable) {
|
||||
/* Use default initialization if no function provided */
|
||||
hal_gpio_config_t gpio_config = {
|
||||
.port = board_config->led.port,
|
||||
@ -38,53 +47,204 @@ void bsp_init(void) {
|
||||
.speed = board_config->led.speed,
|
||||
.pull = board_config->led.pull
|
||||
};
|
||||
hal_gpio_configure_pin(&gpio_config);
|
||||
status = hal_gpio_configure_pin(&gpio_config);
|
||||
if (status != HAL_RET_OK) {
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
/* Initialize Buttons */
|
||||
if (board_config->button_init != NULL) {
|
||||
board_config->button_init(&board_config->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 UART */
|
||||
if (board_config->uart_init != NULL) {
|
||||
board_config->uart_init(&board_config->uart);
|
||||
/* 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 W25QXX if available */
|
||||
if (board_config->w25qxx_init != NULL) {
|
||||
board_config->w25qxx_init(&board_config->w25qxx);
|
||||
/* 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 Initialize board GPIO using configuration
|
||||
* @retval HAL status code
|
||||
*/
|
||||
void bsp_gpio_init(void) {
|
||||
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 GPIO */
|
||||
hal_gpio_config_t gpio_config = {
|
||||
.port = board_config->led.port,
|
||||
.pin = board_config->led.pin,
|
||||
.mode = board_config->led.mode,
|
||||
.speed = board_config->led.speed,
|
||||
.pull = board_config->led.pull
|
||||
};
|
||||
hal_gpio_configure_pin(&gpio_config);
|
||||
if (board_config->led.enable) {
|
||||
hal_gpio_config_t gpio_config = {
|
||||
.port = board_config->led.port,
|
||||
.pin = board_config->led.pin,
|
||||
.mode = board_config->led.mode,
|
||||
.speed = board_config->led.speed,
|
||||
.pull = board_config->led.pull
|
||||
};
|
||||
status = hal_gpio_configure_pin(&gpio_config);
|
||||
if (status != HAL_RET_OK) {
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
/* Initialize Buttons GPIO */
|
||||
for (i = 0; i < board_config->buttons.count; i++) {
|
||||
const bsp_button_config_t* button = &board_config->buttons.buttons[i];
|
||||
gpio_config.port = button->port;
|
||||
gpio_config.pin = button->pin;
|
||||
gpio_config.mode = button->mode;
|
||||
gpio_config.speed = button->speed;
|
||||
gpio_config.pull = button->pull;
|
||||
hal_gpio_configure_pin(&gpio_config);
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -156,8 +156,8 @@ void bsp_key_init(void) {
|
||||
}
|
||||
|
||||
/* Call board-specific button initialization if available */
|
||||
if (board_config && board_config->button_init) {
|
||||
board_config->button_init(&board_config->buttons);
|
||||
if (board_config && board_config->init_funcs.button_init) {
|
||||
board_config->init_funcs.button_init(&board_config->buttons);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
795
BSP/Src/bsp_module.c
Normal file
795
BSP/Src/bsp_module.c
Normal file
@ -0,0 +1,795 @@
|
||||
/* USER CODE BEGIN Header */
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file : bsp_module.c
|
||||
* @brief : Board support package module management source file
|
||||
******************************************************************************
|
||||
*/
|
||||
/* USER CODE END Header */
|
||||
|
||||
#include "bsp_module.h"
|
||||
#include <string.h>
|
||||
|
||||
/**
|
||||
* @brief Module manager instance
|
||||
*/
|
||||
static bsp_module_manager_t bsp_module_manager;
|
||||
|
||||
/**
|
||||
* @brief Initialize BSP module manager
|
||||
* @retval HAL status code
|
||||
*/
|
||||
hal_ret_t bsp_module_manager_init(void) {
|
||||
/* Clear module manager */
|
||||
memset(&bsp_module_manager, 0, sizeof(bsp_module_manager));
|
||||
|
||||
/* Initialize module arrays */
|
||||
for (uint8_t i = 0; i < BSP_MODULE_TYPE_MAX; i++) {
|
||||
bsp_module_manager.modules[i] = NULL;
|
||||
}
|
||||
|
||||
bsp_module_manager.module_list = NULL;
|
||||
bsp_module_manager.module_count = 0;
|
||||
|
||||
return HAL_RET_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Register a BSP module
|
||||
* @param module: Pointer to module structure
|
||||
* @retval HAL status code
|
||||
*/
|
||||
hal_ret_t bsp_module_register(bsp_module_t* module) {
|
||||
if (module == NULL) {
|
||||
return HAL_RET_INVALID_PARAM;
|
||||
}
|
||||
|
||||
if (module->config.type >= BSP_MODULE_TYPE_MAX) {
|
||||
return HAL_INVALID_PARAM;
|
||||
}
|
||||
|
||||
/* Check if module already exists */
|
||||
if (bsp_module_get(module->config.type, module->config.instance) != NULL) {
|
||||
return HAL_RESOURCE_LOCKED;
|
||||
}
|
||||
|
||||
/* Initialize module state */
|
||||
module->state = BSP_MODULE_STATE_UNINIT;
|
||||
module->next = NULL;
|
||||
module->prev = NULL;
|
||||
|
||||
/* Add module to the linked list */
|
||||
if (bsp_module_manager.module_list == NULL) {
|
||||
bsp_module_manager.module_list = module;
|
||||
} else {
|
||||
/* Insert module at the end of the list */
|
||||
bsp_module_t* current = bsp_module_manager.module_list;
|
||||
while (current->next != NULL) {
|
||||
current = current->next;
|
||||
}
|
||||
current->next = module;
|
||||
module->prev = current;
|
||||
}
|
||||
|
||||
/* Add module to the type-specific list */
|
||||
if (bsp_module_manager.modules[module->config.type] == NULL) {
|
||||
bsp_module_manager.modules[module->config.type] = module;
|
||||
} else {
|
||||
/* Insert module at the end of the type-specific list */
|
||||
bsp_module_t* current = bsp_module_manager.modules[module->config.type];
|
||||
while (current->next != NULL && current->config.type == module->config.type) {
|
||||
current = current->next;
|
||||
}
|
||||
if (current->config.type == module->config.type) {
|
||||
current->next = module;
|
||||
module->prev = current;
|
||||
} else {
|
||||
/* Insert between current->prev and current */
|
||||
if (current->prev != NULL) {
|
||||
current->prev->next = module;
|
||||
} else {
|
||||
bsp_module_manager.modules[module->config.type] = module;
|
||||
}
|
||||
module->prev = current->prev;
|
||||
module->next = current;
|
||||
current->prev = module;
|
||||
}
|
||||
}
|
||||
|
||||
bsp_module_manager.module_count++;
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Unregister a BSP module
|
||||
* @param module: Pointer to module structure
|
||||
* @retval HAL status code
|
||||
*/
|
||||
hal_ret_t bsp_module_unregister(bsp_module_t* module) {
|
||||
if (module == NULL) {
|
||||
return HAL_INVALID_PARAM;
|
||||
}
|
||||
|
||||
/* Deinitialize module if it's initialized */
|
||||
if (module->state != BSP_MODULE_STATE_UNINIT) {
|
||||
if (module->ops.deinit != NULL) {
|
||||
module->ops.deinit();
|
||||
}
|
||||
module->state = BSP_MODULE_STATE_UNINIT;
|
||||
}
|
||||
|
||||
/* Remove module from linked list */
|
||||
if (module->prev != NULL) {
|
||||
module->prev->next = module->next;
|
||||
} else {
|
||||
/* Module is first in the list */
|
||||
bsp_module_manager.module_list = module->next;
|
||||
}
|
||||
|
||||
if (module->next != NULL) {
|
||||
module->next->prev = module->prev;
|
||||
}
|
||||
|
||||
/* Remove module from type-specific list */
|
||||
if (bsp_module_manager.modules[module->config.type] == module) {
|
||||
bsp_module_manager.modules[module->config.type] = module->next;
|
||||
}
|
||||
|
||||
/* Reset module pointers */
|
||||
module->next = NULL;
|
||||
module->prev = NULL;
|
||||
|
||||
bsp_module_manager.module_count--;
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get a specific BSP module
|
||||
* @param type: Module type
|
||||
* @param instance: Module instance
|
||||
* @retval Pointer to module structure, or NULL if not found
|
||||
*/
|
||||
bsp_module_t* bsp_module_get(bsp_module_type_t type, uint8_t instance) {
|
||||
if (type >= BSP_MODULE_TYPE_MAX) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bsp_module_t* current = bsp_module_manager.modules[type];
|
||||
while (current != NULL && current->config.type == type) {
|
||||
if (current->config.instance == instance) {
|
||||
return current;
|
||||
}
|
||||
current = current->next;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get all modules of a specific type
|
||||
* @param type: Module type
|
||||
* @retval Pointer to module list, or NULL if no modules found
|
||||
*/
|
||||
bsp_module_t* bsp_module_get_by_type(bsp_module_type_t type) {
|
||||
if (type >= BSP_MODULE_TYPE_MAX) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return bsp_module_manager.modules[type];
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get module by name
|
||||
* @param name: Module name
|
||||
* @retval Pointer to module structure, or NULL if not found
|
||||
*/
|
||||
bsp_module_t* bsp_module_get_by_name(const char* name) {
|
||||
if (name == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bsp_module_t* current = bsp_module_manager.module_list;
|
||||
while (current != NULL) {
|
||||
if (current->config.name != NULL && strcmp(current->config.name, name) == 0) {
|
||||
return current;
|
||||
}
|
||||
current = current->next;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if all dependencies of a module are satisfied
|
||||
* @param module: Pointer to module structure
|
||||
* @retval HAL status code
|
||||
*/
|
||||
hal_ret_t bsp_module_check_dependencies(const bsp_module_t* module) {
|
||||
if (module == NULL) {
|
||||
return HAL_INVALID_PARAM;
|
||||
}
|
||||
|
||||
/* Check if dependencies are satisfied */
|
||||
if (module->config.dependencies == 0) {
|
||||
/* No dependencies */
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/* Check each dependency bit */
|
||||
for (uint8_t i = 0; i < BSP_MODULE_TYPE_MAX; i++) {
|
||||
if (module->config.dependencies & (1 << i)) {
|
||||
/* Check if dependency module exists and is initialized */
|
||||
bsp_module_t* dep_module = bsp_module_manager.modules[i];
|
||||
if (dep_module == NULL) {
|
||||
return HAL_RET_ERROR;
|
||||
}
|
||||
|
||||
/* Check if at least one instance is initialized */
|
||||
bsp_module_t* current = dep_module;
|
||||
uint8_t dep_found = 0;
|
||||
while (current != NULL && current->config.type == i) {
|
||||
if (current->state >= BSP_MODULE_STATE_INIT) {
|
||||
dep_found = 1;
|
||||
break;
|
||||
}
|
||||
current = current->next;
|
||||
}
|
||||
|
||||
if (!dep_found) {
|
||||
return HAL_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initialize a specific BSP module
|
||||
* @param type: Module type
|
||||
* @param instance: Module instance
|
||||
* @retval HAL status code
|
||||
*/
|
||||
hal_ret_t bsp_module_init(bsp_module_type_t type, uint8_t instance) {
|
||||
/* Get module */
|
||||
bsp_module_t* module = bsp_module_get(type, instance);
|
||||
if (module == NULL) {
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Check if module is already initialized */
|
||||
if (module->state != BSP_MODULE_STATE_UNINIT) {
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/* Check dependencies */
|
||||
hal_ret_t status = bsp_module_check_dependencies(module);
|
||||
if (status != HAL_OK) {
|
||||
module->state = BSP_MODULE_STATE_ERROR;
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Initialize module */
|
||||
if (module->ops.init != NULL) {
|
||||
status = module->ops.init(module->config.config_data);
|
||||
if (status != HAL_OK) {
|
||||
module->state = BSP_MODULE_STATE_ERROR;
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
module->state = BSP_MODULE_STATE_INIT;
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Deinitialize a specific BSP module
|
||||
* @param type: Module type
|
||||
* @param instance: Module instance
|
||||
* @retval HAL status code
|
||||
*/
|
||||
hal_ret_t bsp_module_deinit(bsp_module_type_t type, uint8_t instance) {
|
||||
/* Get module */
|
||||
bsp_module_t* module = bsp_module_get(type, instance);
|
||||
if (module == NULL) {
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Check if module is already uninitialized */
|
||||
if (module->state == BSP_MODULE_STATE_UNINIT) {
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/* Stop module if it's running */
|
||||
if (module->state == BSP_MODULE_STATE_RUNNING && module->ops.stop != NULL) {
|
||||
module->ops.stop();
|
||||
}
|
||||
|
||||
/* Deinitialize module */
|
||||
if (module->ops.deinit != NULL) {
|
||||
hal_ret_t status = module->ops.deinit();
|
||||
if (status != HAL_OK) {
|
||||
module->state = BSP_MODULE_STATE_ERROR;
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
module->state = BSP_MODULE_STATE_UNINIT;
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Configure a specific BSP module
|
||||
* @param type: Module type
|
||||
* @param instance: Module instance
|
||||
* @param config: Module configuration data
|
||||
* @param size: Module configuration size
|
||||
* @retval HAL status code
|
||||
*/
|
||||
hal_ret_t bsp_module_configure(bsp_module_type_t type, uint8_t instance, void* config, size_t size) {
|
||||
/* Get module */
|
||||
bsp_module_t* module = bsp_module_get(type, instance);
|
||||
if (module == NULL) {
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Check if module is initialized */
|
||||
if (module->state < BSP_MODULE_STATE_INIT) {
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Configure module */
|
||||
if (module->ops.configure != NULL) {
|
||||
hal_ret_t status = module->ops.configure(config);
|
||||
if (status != HAL_OK) {
|
||||
module->state = BSP_MODULE_STATE_ERROR;
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
module->state = BSP_MODULE_STATE_CONFIGURED;
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Start a specific BSP module
|
||||
* @param type: Module type
|
||||
* @param instance: Module instance
|
||||
* @retval HAL status code
|
||||
*/
|
||||
hal_ret_t bsp_module_start(bsp_module_type_t type, uint8_t instance) {
|
||||
/* Get module */
|
||||
bsp_module_t* module = bsp_module_get(type, instance);
|
||||
if (module == NULL) {
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Check if module is configured */
|
||||
if (module->state < BSP_MODULE_STATE_CONFIGURED) {
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Start module */
|
||||
if (module->ops.start != NULL) {
|
||||
hal_ret_t status = module->ops.start();
|
||||
if (status != HAL_OK) {
|
||||
module->state = BSP_MODULE_STATE_ERROR;
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
module->state = BSP_MODULE_STATE_RUNNING;
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Stop a specific BSP module
|
||||
* @param type: Module type
|
||||
* @param instance: Module instance
|
||||
* @retval HAL status code
|
||||
*/
|
||||
hal_ret_t bsp_module_stop(bsp_module_type_t type, uint8_t instance) {
|
||||
/* Get module */
|
||||
bsp_module_t* module = bsp_module_get(type, instance);
|
||||
if (module == NULL) {
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Check if module is running */
|
||||
if (module->state != BSP_MODULE_STATE_RUNNING) {
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/* Stop module */
|
||||
if (module->ops.stop != NULL) {
|
||||
hal_ret_t status = module->ops.stop();
|
||||
if (status != HAL_OK) {
|
||||
module->state = BSP_MODULE_STATE_ERROR;
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
module->state = BSP_MODULE_STATE_CONFIGURED;
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reset a specific BSP module
|
||||
* @param type: Module type
|
||||
* @param instance: Module instance
|
||||
* @retval HAL status code
|
||||
*/
|
||||
hal_ret_t bsp_module_reset(bsp_module_type_t type, uint8_t instance) {
|
||||
/* Get module */
|
||||
bsp_module_t* module = bsp_module_get(type, instance);
|
||||
if (module == NULL) {
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Stop module if it's running */
|
||||
hal_ret_t status = bsp_module_stop(type, instance);
|
||||
if (status != HAL_OK) {
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Deinitialize module */
|
||||
status = bsp_module_deinit(type, instance);
|
||||
if (status != HAL_OK) {
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Reinitialize module */
|
||||
status = bsp_module_init(type, instance);
|
||||
if (status != HAL_OK) {
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Configure module */
|
||||
if (module->config.config_data != NULL) {
|
||||
status = bsp_module_configure(type, instance, module->config.config_data, module->config.config_size);
|
||||
if (status != HAL_OK) {
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
/* Start module */
|
||||
status = bsp_module_start(type, instance);
|
||||
if (status != HAL_OK) {
|
||||
return status;
|
||||
}
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get state of a specific BSP module
|
||||
* @param type: Module type
|
||||
* @param instance: Module instance
|
||||
* @param state: Pointer to store module state
|
||||
* @retval HAL status code
|
||||
*/
|
||||
hal_ret_t bsp_module_get_state(bsp_module_type_t type, uint8_t instance, bsp_module_state_t* state) {
|
||||
if (state == NULL) {
|
||||
return HAL_INVALID_PARAM;
|
||||
}
|
||||
|
||||
/* Get module */
|
||||
bsp_module_t* module = bsp_module_get(type, instance);
|
||||
if (module == NULL) {
|
||||
*state = BSP_MODULE_STATE_UNINIT;
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
*state = module->state;
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Control a specific BSP module
|
||||
* @param type: Module type
|
||||
* @param instance: Module instance
|
||||
* @param cmd: Control command
|
||||
* @param param: Control parameter
|
||||
* @retval HAL status code
|
||||
*/
|
||||
hal_ret_t bsp_module_control(bsp_module_type_t type, uint8_t instance, uint32_t cmd, void* param) {
|
||||
/* Get module */
|
||||
bsp_module_t* module = bsp_module_get(type, instance);
|
||||
if (module == NULL) {
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Check if module is initialized */
|
||||
if (module->state < BSP_MODULE_STATE_INIT) {
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
/* Control module */
|
||||
if (module->ops.control != NULL) {
|
||||
return module->ops.control(cmd, param);
|
||||
}
|
||||
|
||||
return HAL_RET_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initialize all registered BSP modules in priority order
|
||||
* @retval HAL status code
|
||||
*/
|
||||
hal_ret_t bsp_module_init_all(void) {
|
||||
hal_ret_t status = HAL_RET_OK;
|
||||
|
||||
/* Initialize modules by priority */
|
||||
for (uint8_t priority = BSP_MODULE_PRIORITY_HIGHEST; priority <= BSP_MODULE_PRIORITY_LOWEST; priority++) {
|
||||
bsp_module_t* current = bsp_module_manager.module_list;
|
||||
while (current != NULL) {
|
||||
if (current->config.priority == priority) {
|
||||
status = bsp_module_init(current->config.type, current->config.instance);
|
||||
if (status != HAL_OK) {
|
||||
return status;
|
||||
}
|
||||
}
|
||||
current = current->next;
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Deinitialize all registered BSP modules in reverse priority order
|
||||
* @retval HAL status code
|
||||
*/
|
||||
hal_ret_t bsp_module_deinit_all(void) {
|
||||
hal_status_t status = HAL_OK;
|
||||
|
||||
/* Deinitialize modules by reverse priority */
|
||||
for (int8_t priority = BSP_MODULE_PRIORITY_LOWEST; priority >= BSP_MODULE_PRIORITY_HIGHEST; priority--) {
|
||||
bsp_module_t* current = bsp_module_manager.module_list;
|
||||
while (current != NULL) {
|
||||
if (current->config.priority == priority) {
|
||||
status = bsp_module_deinit(current->config.type, current->config.instance);
|
||||
if (status != HAL_OK) {
|
||||
return status;
|
||||
}
|
||||
}
|
||||
current = current->next;
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Start all registered BSP modules in priority order
|
||||
* @retval HAL status code
|
||||
*/
|
||||
hal_ret_t bsp_module_start_all(void) {
|
||||
hal_status_t status = HAL_OK;
|
||||
|
||||
/* Start modules by priority */
|
||||
for (uint8_t priority = BSP_MODULE_PRIORITY_HIGHEST; priority <= BSP_MODULE_PRIORITY_LOWEST; priority++) {
|
||||
bsp_module_t* current = bsp_module_manager.module_list;
|
||||
while (current != NULL) {
|
||||
if (current->config.priority == priority && current->state >= BSP_MODULE_STATE_CONFIGURED) {
|
||||
status = bsp_module_start(current->config.type, current->config.instance);
|
||||
if (status != HAL_OK) {
|
||||
return status;
|
||||
}
|
||||
}
|
||||
current = current->next;
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Stop all registered BSP modules in reverse priority order
|
||||
* @retval HAL status code
|
||||
*/
|
||||
hal_ret_t bsp_module_stop_all(void) {
|
||||
hal_status_t status = HAL_OK;
|
||||
|
||||
/* Stop modules by reverse priority */
|
||||
for (int8_t priority = BSP_MODULE_PRIORITY_LOWEST; priority >= BSP_MODULE_PRIORITY_HIGHEST; priority--) {
|
||||
bsp_module_t* current = bsp_module_manager.module_list;
|
||||
while (current != NULL) {
|
||||
if (current->config.priority == priority && current->state == BSP_MODULE_STATE_RUNNING) {
|
||||
status = bsp_module_stop(current->config.type, current->config.instance);
|
||||
if (status != HAL_OK) {
|
||||
return status;
|
||||
}
|
||||
}
|
||||
current = current->next;
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get total number of registered modules
|
||||
* @retval Number of registered modules
|
||||
*/
|
||||
uint32_t bsp_module_get_count(void) {
|
||||
return bsp_module_manager.module_count;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get module manager instance
|
||||
* @retval Pointer to module manager structure
|
||||
*/
|
||||
bsp_module_manager_t* bsp_module_get_manager(void) {
|
||||
return &bsp_module_manager;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Register a module event callback
|
||||
* @param type: Module type
|
||||
* @param instance: Module instance
|
||||
* @param callback: Event callback function
|
||||
* @retval HAL status code
|
||||
*/
|
||||
hal_ret_t bsp_module_register_event_callback(bsp_module_type_t type, uint8_t instance, bsp_module_event_callback_t callback) {
|
||||
bsp_module_t* module = bsp_module_get(type, instance);
|
||||
if (module == NULL) {
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
module->event_callback = callback;
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Trigger a module event
|
||||
* @param module: Pointer to module structure
|
||||
* @param event: Event to trigger
|
||||
* @param data: Event data
|
||||
* @retval HAL status code
|
||||
*/
|
||||
hal_ret_t bsp_module_trigger_event(const bsp_module_t* module, uint32_t event, void* data) {
|
||||
if (module == NULL) {
|
||||
return HAL_INVALID_PARAM;
|
||||
}
|
||||
|
||||
// Check if module has an event callback registered
|
||||
if (module->event_callback != NULL) {
|
||||
return module->event_callback(module, event, data);
|
||||
}
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Find modules by priority range
|
||||
* @param min_priority: Minimum priority
|
||||
* @param max_priority: Maximum priority
|
||||
* @param count: Pointer to store number of modules found
|
||||
* @retval Pointer to array of module pointers, or NULL if no modules found
|
||||
*/
|
||||
bsp_module_t** bsp_module_find_by_priority_range(bsp_module_priority_t min_priority, bsp_module_priority_t max_priority, uint32_t* count) {
|
||||
if (count == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// First pass: count matching modules
|
||||
uint32_t module_count = 0;
|
||||
bsp_module_t* current = bsp_module_manager.module_list;
|
||||
while (current != NULL) {
|
||||
if (current->config.priority >= min_priority && current->config.priority <= max_priority) {
|
||||
module_count++;
|
||||
}
|
||||
current = current->next;
|
||||
}
|
||||
|
||||
if (module_count == 0) {
|
||||
*count = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Second pass: allocate and fill array
|
||||
bsp_module_t** modules = (bsp_module_t**)malloc(module_count * sizeof(bsp_module_t*));
|
||||
if (modules == NULL) {
|
||||
*count = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uint32_t index = 0;
|
||||
current = bsp_module_manager.module_list;
|
||||
while (current != NULL && index < module_count) {
|
||||
if (current->config.priority >= min_priority && current->config.priority <= max_priority) {
|
||||
modules[index++] = current;
|
||||
}
|
||||
current = current->next;
|
||||
}
|
||||
|
||||
*count = module_count;
|
||||
return modules;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set module enable/disable state
|
||||
* @param type: Module type
|
||||
* @param instance: Module instance
|
||||
* @param enable: Enable flag
|
||||
* @retval HAL status code
|
||||
*/
|
||||
hal_ret_t bsp_module_set_enable(bsp_module_type_t type, uint8_t instance, uint8_t enable) {
|
||||
bsp_module_t* module = bsp_module_get(type, instance);
|
||||
if (module == NULL) {
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
module->config.enable = enable;
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check if module is enabled
|
||||
* @param type: Module type
|
||||
* @param instance: Module instance
|
||||
* @param enable: Pointer to store enable state
|
||||
* @retval HAL status code
|
||||
*/
|
||||
hal_ret_t bsp_module_is_enabled(bsp_module_type_t type, uint8_t instance, uint8_t* enable) {
|
||||
if (enable == NULL) {
|
||||
return HAL_INVALID_PARAM;
|
||||
}
|
||||
|
||||
bsp_module_t* module = bsp_module_get(type, instance);
|
||||
if (module == NULL) {
|
||||
*enable = 0;
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
*enable = module->config.enable;
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set module priority
|
||||
* @param type: Module type
|
||||
* @param instance: Module instance
|
||||
* @param priority: New priority
|
||||
* @retval HAL status code
|
||||
*/
|
||||
hal_ret_t bsp_module_set_priority(bsp_module_type_t type, uint8_t instance, bsp_module_priority_t priority) {
|
||||
bsp_module_t* module = bsp_module_get(type, instance);
|
||||
if (module == NULL) {
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
module->config.priority = priority;
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get module priority
|
||||
* @param type: Module type
|
||||
* @param instance: Module instance
|
||||
* @param priority: Pointer to store priority
|
||||
* @retval HAL status code
|
||||
*/
|
||||
hal_ret_t bsp_module_get_priority(bsp_module_type_t type, uint8_t instance, bsp_module_priority_t* priority) {
|
||||
if (priority == NULL) {
|
||||
return HAL_INVALID_PARAM;
|
||||
}
|
||||
|
||||
bsp_module_t* module = bsp_module_get(type, instance);
|
||||
if (module == NULL) {
|
||||
*priority = BSP_MODULE_PRIORITY_MEDIUM;
|
||||
return HAL_ERROR;
|
||||
}
|
||||
|
||||
*priority = module->config.priority;
|
||||
return HAL_OK;
|
||||
}
|
||||
@ -17,7 +17,7 @@
|
||||
* @return true if successful, false otherwise
|
||||
*/
|
||||
static bool w25qxx_spi_send(const uint8_t *data, uint16_t size) {
|
||||
return hal_spi_transmit(W25QXX_SPI_INSTANCE, data, size);
|
||||
return hal_spi_transmit(W25QXX_SPI_INSTANCE, data, size) == HAL_RET_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -27,7 +27,7 @@ static bool w25qxx_spi_send(const uint8_t *data, uint16_t size) {
|
||||
* @return true if successful, false otherwise
|
||||
*/
|
||||
static bool w25qxx_spi_receive(uint8_t *data, uint16_t size) {
|
||||
return hal_spi_receive(W25QXX_SPI_INSTANCE, data, size);
|
||||
return hal_spi_receive(W25QXX_SPI_INSTANCE, data, size) == HAL_RET_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -38,7 +38,7 @@ static bool w25qxx_spi_receive(uint8_t *data, uint16_t size) {
|
||||
* @return true if successful, false otherwise
|
||||
*/
|
||||
static bool w25qxx_spi_transceive(const uint8_t *tx_data, uint8_t *rx_data, uint16_t size) {
|
||||
return hal_spi_transmit_receive(W25QXX_SPI_INSTANCE, tx_data, rx_data, size);
|
||||
return hal_spi_transmit_receive(W25QXX_SPI_INSTANCE, tx_data, rx_data, size) == HAL_RET_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -96,7 +96,7 @@ bool bsp_w25qxx_init(void) {
|
||||
.databits = HAL_SPI_DATABITS_8
|
||||
};
|
||||
|
||||
if (!hal_spi_init(W25QXX_SPI_INSTANCE, &spi_config)) {
|
||||
if (hal_spi_init(W25QXX_SPI_INSTANCE, &spi_config) != HAL_RET_OK) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@ -16,8 +16,9 @@
|
||||
/**
|
||||
* @brief Default LED initialization function
|
||||
* @param config: LED configuration structure
|
||||
* @retval HAL status code
|
||||
*/
|
||||
static void default_led_init(const void* config) {
|
||||
static hal_ret_t default_led_init(const void* config) {
|
||||
const bsp_led_config_t* led_config = (const bsp_led_config_t*)config;
|
||||
hal_gpio_config_t gpio_config = {
|
||||
.port = led_config->port,
|
||||
@ -26,7 +27,132 @@ static void default_led_init(const void* config) {
|
||||
.speed = led_config->speed,
|
||||
.pull = led_config->pull
|
||||
};
|
||||
hal_gpio_configure_pin(&gpio_config);
|
||||
return hal_gpio_configure_pin(&gpio_config);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Default button initialization function
|
||||
* @param config: Button configuration structure
|
||||
* @retval HAL status code
|
||||
*/
|
||||
static hal_ret_t default_button_init(const void* config) {
|
||||
const bsp_buttons_config_t* buttons_config = (const bsp_buttons_config_t*)config;
|
||||
uint8_t i;
|
||||
hal_ret_t status = HAL_RET_OK;
|
||||
|
||||
for (i = 0; i < buttons_config->count; i++) {
|
||||
const bsp_button_config_t* button_config = &buttons_config->buttons[i];
|
||||
hal_gpio_config_t gpio_config = {
|
||||
.port = button_config->port,
|
||||
.pin = button_config->pin,
|
||||
.mode = button_config->mode,
|
||||
.speed = button_config->speed,
|
||||
.pull = button_config->pull
|
||||
};
|
||||
status = hal_gpio_configure_pin(&gpio_config);
|
||||
if (status != HAL_RET_OK) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Default UART initialization function
|
||||
* @param config: UART configuration structure
|
||||
* @retval HAL status code
|
||||
*/
|
||||
static hal_ret_t default_uart_init(const void* config) {
|
||||
const bsp_uart_config_t* uart_config = (const bsp_uart_config_t*)config;
|
||||
hal_uart_config_t uart_cfg = {
|
||||
.instance = (hal_uart_instance_t)uart_config->instance,
|
||||
.baudrate = uart_config->baudrate,
|
||||
.parity = uart_config->parity,
|
||||
.stopbits = uart_config->stopbits,
|
||||
.databits = uart_config->databits
|
||||
};
|
||||
return hal_uart_config(&uart_cfg);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Default SPI initialization function
|
||||
* @param config: SPI configuration structure
|
||||
* @retval HAL status code
|
||||
*/
|
||||
static hal_ret_t default_spi_init(const void* config) {
|
||||
const bsp_spi_config_t* spi_config = (const bsp_spi_config_t*)config;
|
||||
hal_spi_config_t spi_cfg = {
|
||||
.instance = spi_config->instance,
|
||||
.mode = spi_config->mode,
|
||||
.baudrate = spi_config->baudrate,
|
||||
.polarity = spi_config->polarity,
|
||||
.phase = spi_config->phase,
|
||||
.databits = spi_config->databits
|
||||
};
|
||||
return hal_spi_init(spi_config->instance, &spi_cfg);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Default I2C initialization function
|
||||
* @param config: I2C configuration structure
|
||||
* @retval HAL status code
|
||||
*/
|
||||
static hal_ret_t default_i2c_init(const void* config) {
|
||||
/* TODO: Implement default I2C initialization */
|
||||
return HAL_RET_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Default CAN initialization function
|
||||
* @param config: CAN configuration structure
|
||||
* @retval HAL status code
|
||||
*/
|
||||
static hal_ret_t default_can_init(const void* config) {
|
||||
/* TODO: Implement default CAN initialization */
|
||||
return HAL_RET_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Default ADC initialization function
|
||||
* @param config: ADC configuration structure
|
||||
* @retval HAL status code
|
||||
*/
|
||||
static hal_ret_t default_adc_init(const void* config) {
|
||||
/* TODO: Implement default ADC initialization */
|
||||
return HAL_RET_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Default W25QXX initialization function
|
||||
* @param config: W25QXX configuration structure
|
||||
* @retval HAL status code
|
||||
*/
|
||||
static hal_ret_t default_w25qxx_init(const void* config) {
|
||||
const bsp_w25qxx_config_t* w25qxx_config = (const bsp_w25qxx_config_t*)config;
|
||||
hal_ret_t status = HAL_RET_OK;
|
||||
|
||||
/* Initialize CS pin */
|
||||
hal_gpio_config_t gpio_config = {
|
||||
.port = w25qxx_config->cs_port,
|
||||
.pin = w25qxx_config->cs_pin,
|
||||
.mode = HAL_GPIO_MODE_OUTPUT_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;
|
||||
}
|
||||
|
||||
/* Deselect chip initially */
|
||||
status = hal_gpio_write_pin(w25qxx_config->cs_port, w25qxx_config->cs_pin, HAL_GPIO_PIN_SET);
|
||||
if (status != HAL_RET_OK) {
|
||||
return status;
|
||||
}
|
||||
|
||||
/* SPI instance is now just an index, actual SPI initialization is handled separately */
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -35,8 +161,8 @@ static void default_led_init(const void* config) {
|
||||
static const bsp_button_config_t stm32f407vet6_buttons[] = {
|
||||
/* KEY0 - PE4, active low */
|
||||
{
|
||||
.port = BSP_KEY0_PORT,
|
||||
.pin = BSP_KEY0_PIN,
|
||||
.port = HAL_GPIO_PORT_E,
|
||||
.pin = HAL_GPIO_PIN_4,
|
||||
.mode = HAL_GPIO_MODE_INPUT,
|
||||
.speed = HAL_GPIO_SPEED_LOW,
|
||||
.pull = HAL_GPIO_PULL_UP,
|
||||
@ -44,8 +170,8 @@ static const bsp_button_config_t stm32f407vet6_buttons[] = {
|
||||
},
|
||||
/* KEY1 - PE3, active low */
|
||||
{
|
||||
.port = BSP_KEY1_PORT,
|
||||
.pin = BSP_KEY1_PIN,
|
||||
.port = HAL_GPIO_PORT_E,
|
||||
.pin = HAL_GPIO_PIN_3,
|
||||
.mode = HAL_GPIO_MODE_INPUT,
|
||||
.speed = HAL_GPIO_SPEED_LOW,
|
||||
.pull = HAL_GPIO_PULL_UP,
|
||||
@ -53,8 +179,8 @@ static const bsp_button_config_t stm32f407vet6_buttons[] = {
|
||||
},
|
||||
/* WKUP - PA0, active high */
|
||||
{
|
||||
.port = BSP_WKUP_PORT,
|
||||
.pin = BSP_WKUP_PIN,
|
||||
.port = HAL_GPIO_PORT_A,
|
||||
.pin = HAL_GPIO_PIN_0,
|
||||
.mode = HAL_GPIO_MODE_INPUT,
|
||||
.speed = HAL_GPIO_SPEED_LOW,
|
||||
.pull = HAL_GPIO_PULL_DOWN,
|
||||
@ -66,121 +192,217 @@ static const bsp_button_config_t stm32f407vet6_buttons[] = {
|
||||
* @brief STM32F407VET6 buttons configuration
|
||||
*/
|
||||
static const bsp_buttons_config_t stm32f407vet6_buttons_config = {
|
||||
.enable = 1,
|
||||
.count = sizeof(stm32f407vet6_buttons) / sizeof(bsp_button_config_t),
|
||||
.buttons = stm32f407vet6_buttons
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Default button initialization function
|
||||
* @param config: Button configuration structure
|
||||
* @brief STM32F407VET6 board UART configurations
|
||||
*/
|
||||
static void default_button_init(const void* config) {
|
||||
const bsp_buttons_config_t* buttons_config = (const bsp_buttons_config_t*)config;
|
||||
uint8_t i;
|
||||
|
||||
for (i = 0; i < buttons_config->count; i++) {
|
||||
const bsp_button_config_t* button_config = &buttons_config->buttons[i];
|
||||
hal_gpio_config_t gpio_config = {
|
||||
.port = button_config->port,
|
||||
.pin = button_config->pin,
|
||||
.mode = button_config->mode,
|
||||
.speed = button_config->speed,
|
||||
.pull = button_config->pull
|
||||
};
|
||||
hal_gpio_configure_pin(&gpio_config);
|
||||
static const bsp_uart_config_t stm32f407vet6_uarts[] = {
|
||||
/* USART1 - PA9(TX), PA10(RX) */
|
||||
{
|
||||
.enable = 1,
|
||||
.instance = BSP_UART_INSTANCE_1,
|
||||
.baudrate = 115200,
|
||||
.parity = HAL_UART_PARITY_NONE,
|
||||
.stopbits = HAL_UART_STOPBITS_1,
|
||||
.databits = HAL_UART_DATABITS_8,
|
||||
.tx_port = HAL_GPIO_PORT_A, /* USART1_TX - PA9 */
|
||||
.tx_pin = HAL_GPIO_PIN_9,
|
||||
.rx_port = HAL_GPIO_PORT_A, /* USART1_RX - PA10 */
|
||||
.rx_pin = HAL_GPIO_PIN_10
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Default UART initialization function
|
||||
* @param config: UART configuration structure
|
||||
* @brief STM32F407VET6 board SPI configurations
|
||||
*/
|
||||
static void default_uart_init(const void* config) {
|
||||
const bsp_uart_config_t* uart_config = (const bsp_uart_config_t*)config;
|
||||
hal_uart_config_t uart_cfg = {
|
||||
.instance = (hal_uart_instance_t)uart_config->instance,
|
||||
.baudrate = uart_config->baudrate,
|
||||
.parity = uart_config->parity,
|
||||
.stopbits = uart_config->stopbits,
|
||||
.databits = uart_config->databits
|
||||
};
|
||||
hal_uart_config(&uart_cfg);
|
||||
}
|
||||
static const bsp_spi_config_t stm32f407vet6_spis[] = {
|
||||
/* SPI1 - PA5(SCK), PA6(MISO), PA7(MOSI) */
|
||||
{
|
||||
.enable = 1,
|
||||
.instance = HAL_SPI_INSTANCE_1,
|
||||
.mode = HAL_SPI_MODE_MASTER,
|
||||
.baudrate = 1000000, /* 1 MHz */
|
||||
.polarity = HAL_SPI_POLARITY_LOW,
|
||||
.phase = HAL_SPI_PHASE_1EDGE,
|
||||
.databits = HAL_SPI_DATABITS_8,
|
||||
.sck_port = HAL_GPIO_PORT_A,
|
||||
.sck_pin = HAL_GPIO_PIN_5,
|
||||
.miso_port = HAL_GPIO_PORT_A,
|
||||
.miso_pin = HAL_GPIO_PIN_6,
|
||||
.mosi_port = HAL_GPIO_PORT_A,
|
||||
.mosi_pin = HAL_GPIO_PIN_7
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Default W25QXX initialization function
|
||||
* @param config: W25QXX configuration structure
|
||||
* @brief STM32F407VET6 board I2C configurations
|
||||
*/
|
||||
static void default_w25qxx_init(const void* config) {
|
||||
const bsp_w25qxx_config_t* w25qxx_config = (const bsp_w25qxx_config_t*)config;
|
||||
|
||||
/* Initialize CS pin */
|
||||
hal_gpio_config_t gpio_config = {
|
||||
.port = w25qxx_config->cs_port,
|
||||
.pin = w25qxx_config->cs_pin,
|
||||
.mode = HAL_GPIO_MODE_OUTPUT_PP,
|
||||
.speed = HAL_GPIO_SPEED_HIGH,
|
||||
.pull = HAL_GPIO_PULL_NO
|
||||
};
|
||||
hal_gpio_configure_pin(&gpio_config);
|
||||
|
||||
/* Deselect chip initially */
|
||||
hal_gpio_write_pin(w25qxx_config->cs_port, w25qxx_config->cs_pin, HAL_GPIO_PIN_SET);
|
||||
|
||||
/* Initialize SPI */
|
||||
hal_spi_config_t spi_config = {
|
||||
.instance = w25qxx_config->spi_config.instance,
|
||||
.mode = w25qxx_config->spi_config.mode,
|
||||
.baudrate = w25qxx_config->spi_config.baudrate,
|
||||
.polarity = w25qxx_config->spi_config.polarity,
|
||||
.phase = w25qxx_config->spi_config.phase,
|
||||
.databits = w25qxx_config->spi_config.databits
|
||||
};
|
||||
hal_spi_init(w25qxx_config->spi_config.instance, &spi_config);
|
||||
}
|
||||
static const bsp_i2c_config_t stm32f407vet6_i2cs[] = {
|
||||
/* I2C1 - PB6(SCL), PB7(SDA) */
|
||||
{
|
||||
.enable = 0, /* Disabled by default */
|
||||
.instance = HAL_I2C_INSTANCE_1,
|
||||
.speed = HAL_I2C_SPEED_STANDARD,
|
||||
.address_mode = HAL_I2C_ADDRESS_7BIT,
|
||||
.dutycycle = HAL_I2C_DUTYCYCLE_2,
|
||||
.own_address1 = 0x00,
|
||||
.scl_port = HAL_GPIO_PORT_B,
|
||||
.scl_pin = HAL_GPIO_PIN_6,
|
||||
.sda_port = HAL_GPIO_PORT_B,
|
||||
.sda_pin = HAL_GPIO_PIN_7
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief STM32F407VET6 board CAN configurations
|
||||
*/
|
||||
static const bsp_can_config_t stm32f407vet6_cans[] = {
|
||||
/* CAN1 - PA11(RX), PA12(TX) */
|
||||
{
|
||||
.enable = 0, /* Disabled by default */
|
||||
.instance = HAL_CAN_INSTANCE_1,
|
||||
.mode = HAL_CAN_MODE_NORMAL,
|
||||
.prescaler = 6, /* 168MHz / 6 = 28MHz */
|
||||
.sync_jump_width = 1,
|
||||
.time_segment1 = 13,
|
||||
.time_segment2 = 2,
|
||||
.rx_port = HAL_GPIO_PORT_A,
|
||||
.rx_pin = HAL_GPIO_PIN_11,
|
||||
.tx_port = HAL_GPIO_PORT_A,
|
||||
.tx_pin = HAL_GPIO_PIN_12
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief STM32F407VET6 board ADC channel configurations
|
||||
*/
|
||||
static const bsp_adc_channel_config_t stm32f407vet6_adc_channels[] = {
|
||||
/* ADC1 Channel 0 - PA0 */
|
||||
{
|
||||
.enable = 0, /* Disabled by default */
|
||||
.channel = HAL_ADC_CHANNEL_0,
|
||||
.sampletime = HAL_ADC_SAMPLETIME_56CYCLES,
|
||||
.rank = 1
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief STM32F407VET6 board ADC configurations
|
||||
*/
|
||||
static const bsp_adc_config_t stm32f407vet6_adcs[] = {
|
||||
/* ADC1 */
|
||||
{
|
||||
.enable = 0, /* Disabled by default */
|
||||
.instance = HAL_ADC_INSTANCE_1,
|
||||
.resolution = HAL_ADC_RESOLUTION_12B,
|
||||
.scan_conversion_mode = 0,
|
||||
.continuous_conversion_mode = 0,
|
||||
.channel_count = sizeof(stm32f407vet6_adc_channels) / sizeof(bsp_adc_channel_config_t),
|
||||
.channels = stm32f407vet6_adc_channels
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief STM32F407VET6 board configuration
|
||||
*/
|
||||
const bsp_board_config_t stm32f407vet6_board_config = {
|
||||
.name = BOARD_NAME,
|
||||
.version = BSP_CONFIG_VERSION,
|
||||
.name = "STM32F407VET6",
|
||||
.description = "STM32F407VET6 Development Board",
|
||||
.id = {
|
||||
.vendor_id = 0x0483, /* STMicroelectronics */
|
||||
.product_id = 0x374B, /* STM32F4 Series */
|
||||
.serial_number = 0x00000001 /* Default serial number */
|
||||
},
|
||||
|
||||
/* Board features */
|
||||
.features = (
|
||||
BSP_BOARD_FEATURE_LED |
|
||||
BSP_BOARD_FEATURE_BUTTON |
|
||||
BSP_BOARD_FEATURE_UART |
|
||||
BSP_BOARD_FEATURE_SPI |
|
||||
BSP_BOARD_FEATURE_I2C |
|
||||
BSP_BOARD_FEATURE_CAN |
|
||||
BSP_BOARD_FEATURE_ADC |
|
||||
BSP_BOARD_FEATURE_W25QXX
|
||||
),
|
||||
|
||||
/* Hardware information */
|
||||
.hw_info = {
|
||||
.clock_speed = 168000000, /* 168 MHz */
|
||||
.flash_size = 512 * 1024, /* 512 KB */
|
||||
.ram_size = 192 * 1024, /* 192 KB */
|
||||
.eeprom_size = 0, /* No internal EEPROM */
|
||||
.sram_size = 64 * 1024, /* 64 KB SRAM */
|
||||
.cpu_core = 0x0F, /* Cortex-M4 */
|
||||
.cpu_bits = 32 /* 32-bit CPU */
|
||||
},
|
||||
|
||||
/* Peripheral configurations */
|
||||
.led = {
|
||||
.port = BSP_LED_PORT,
|
||||
.pin = BSP_LED_PIN,
|
||||
.enable = 1,
|
||||
.port = HAL_GPIO_PORT_E,
|
||||
.pin = HAL_GPIO_PIN_5,
|
||||
.mode = HAL_GPIO_MODE_OUTPUT_PP,
|
||||
.speed = HAL_GPIO_SPEED_MEDIUM,
|
||||
.pull = HAL_GPIO_PULL_NO
|
||||
},
|
||||
.buttons = stm32f407vet6_buttons_config,
|
||||
.uart = {
|
||||
.instance = BSP_UART_INSTANCE,
|
||||
.baudrate = BSP_UART_BAUDRATE,
|
||||
.parity = BSP_UART_PARITY,
|
||||
.stopbits = BSP_UART_STOPBITS,
|
||||
.databits = BSP_UART_DATABITS,
|
||||
.tx_port = HAL_GPIO_PORT_A, /* USART1_TX - PA9 */
|
||||
.tx_pin = HAL_GPIO_PIN_9,
|
||||
.rx_port = HAL_GPIO_PORT_A, /* USART1_RX - PA10 */
|
||||
.rx_pin = HAL_GPIO_PIN_10
|
||||
},
|
||||
.w25qxx = {
|
||||
.enable = 1,
|
||||
.cs_port = HAL_GPIO_PORT_B,
|
||||
.cs_pin = HAL_GPIO_PIN_0,
|
||||
.spi_config = {
|
||||
.instance = HAL_SPI_INSTANCE_1,
|
||||
.mode = HAL_SPI_MODE_MASTER,
|
||||
.baudrate = 1000000, /* 1 MHz */
|
||||
.polarity = HAL_SPI_POLARITY_LOW,
|
||||
.phase = HAL_SPI_PHASE_1EDGE,
|
||||
.databits = HAL_SPI_DATABITS_8
|
||||
}
|
||||
.spi_instance = 0 /* Use SPI instance 0 */
|
||||
},
|
||||
.led_init = default_led_init,
|
||||
.button_init = default_button_init,
|
||||
.uart_init = default_uart_init,
|
||||
.w25qxx_init = default_w25qxx_init,
|
||||
.clock_speed = 168000000, /* 168 MHz */
|
||||
.uart_count = 6
|
||||
|
||||
/* Peripheral arrays */
|
||||
.periphs = {
|
||||
/* UART configurations */
|
||||
.uart_count = 1,
|
||||
.uarts = stm32f407vet6_uarts,
|
||||
|
||||
/* SPI configurations */
|
||||
.spi_count = 1,
|
||||
.spis = stm32f407vet6_spis,
|
||||
|
||||
/* I2C configurations */
|
||||
.i2c_count = 1,
|
||||
.i2cs = stm32f407vet6_i2cs,
|
||||
|
||||
/* CAN configurations */
|
||||
.can_count = 1,
|
||||
.cans = stm32f407vet6_cans,
|
||||
|
||||
/* ADC configurations */
|
||||
.adc_count = 1,
|
||||
.adcs = stm32f407vet6_adcs
|
||||
},
|
||||
|
||||
/* Initialization function pointers */
|
||||
.init_funcs = {
|
||||
.led_init = default_led_init,
|
||||
.button_init = default_button_init,
|
||||
.uart_init = default_uart_init,
|
||||
.spi_init = default_spi_init,
|
||||
.i2c_init = default_i2c_init,
|
||||
.can_init = default_can_init,
|
||||
.adc_init = default_adc_init,
|
||||
.w25qxx_init = default_w25qxx_init
|
||||
},
|
||||
|
||||
/* Additional board-specific configuration */
|
||||
.custom_config = NULL,
|
||||
.custom_config_size = 0,
|
||||
|
||||
/* Board revision information */
|
||||
.major_rev = 1,
|
||||
.minor_rev = 0,
|
||||
.patch_rev = 0,
|
||||
.revision_desc = "Original release"
|
||||
};
|
||||
|
||||
/**
|
||||
@ -190,3 +412,11 @@ const bsp_board_config_t stm32f407vet6_board_config = {
|
||||
const char* bsp_board_get_name(void) {
|
||||
return stm32f407vet6_board_config.name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get board configuration
|
||||
* @retval Pointer to board configuration structure
|
||||
*/
|
||||
const bsp_board_config_t* bsp_board_get_config(void) {
|
||||
return &stm32f407vet6_board_config;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user