优化调试新增按键驱动

This commit is contained in:
冯佳
2026-01-23 13:03:40 +08:00
parent 0a30f956b4
commit 988cc7ad4a
66 changed files with 878713 additions and 1274 deletions

View File

@ -41,15 +41,20 @@ void bsp_init(void) {
hal_gpio_configure_pin(&gpio_config);
}
/* Initialize Button */
/* Initialize Buttons */
if (board_config->button_init != NULL) {
board_config->button_init(&board_config->button);
board_config->button_init(&board_config->buttons);
}
/* Initialize UART */
if (board_config->uart_init != NULL) {
board_config->uart_init(&board_config->uart);
}
/* Initialize W25QXX if available */
if (board_config->w25qxx_init != NULL) {
board_config->w25qxx_init(&board_config->w25qxx);
}
}
/**
@ -58,6 +63,7 @@ void bsp_init(void) {
void bsp_gpio_init(void) {
/* Get board configuration */
const bsp_board_config_t* board_config = bsp_board_get_config();
uint8_t i;
/* Initialize LED GPIO */
hal_gpio_config_t gpio_config = {
@ -69,13 +75,14 @@ void bsp_gpio_init(void) {
};
hal_gpio_configure_pin(&gpio_config);
/* Initialize Button GPIO if configured */
if (board_config->button.port != 0 && board_config->button.pin != 0) {
gpio_config.port = board_config->button.port;
gpio_config.pin = board_config->button.pin;
gpio_config.mode = board_config->button.mode;
gpio_config.speed = board_config->button.speed;
gpio_config.pull = board_config->button.pull;
/* 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);
}
}

351
BSP/Src/bsp_key.c Normal file
View File

@ -0,0 +1,351 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : bsp_key.c
* @brief : Board support package key driver implementation
******************************************************************************
*/
/* USER CODE END Header */
#include "bsp_key.h"
#include "bsp_config.h"
#include "hal_gpio.h"
#include "bsp_board.h"
#include "bsp_board_manager.h"
#include "hal_delay.h"
/**
* @brief Key debounce configuration
*/
#define KEY_DEBOUNCE_COUNT 5 /* Debounce count (each update is ~10ms, so 50ms debounce) */
#define KEY_LONG_PRESS_TIME 1000 /* Long press time in ms */
#define KEY_REPEAT_INTERVAL 200 /* Repeat interval in ms */
#define KEY_SHORT_PRESS_TIME 200 /* Short press time in ms */
#define KEY_UPDATE_INTERVAL 10 /* Update interval in ms */
/**
* @brief Key configuration structure
*/
typedef struct {
hal_gpio_port_t port;
hal_gpio_pin_t pin;
uint8_t active_high;
} bsp_key_config_t;
/**
* @brief Key state structure for debouncing and event detection
*/
typedef struct {
/* Debounce state */
bsp_key_state_t current_state; /* Current debounced state */
bsp_key_state_t previous_state; /* Previous debounced state */
uint8_t debounce_counter; /* Debounce counter */
/* Event flags */
uint8_t press_event; /* Press event flag */
uint8_t release_event; /* Release event flag */
uint8_t long_press_event; /* Long press event flag */
uint8_t repeat_event; /* Repeat event flag */
uint8_t short_press_event; /* Short press event flag */
/* Timing variables */
uint32_t press_start_time; /* Press start time in ms */
uint32_t last_repeat_time; /* Last repeat event time in ms */
uint32_t current_time; /* Current time in ms */
/* Configuration */
uint16_t long_press_time; /* Long press time in ms */
uint16_t repeat_interval; /* Repeat interval in ms */
uint16_t short_press_time; /* Short press time in ms */
/* Key configuration */
const bsp_button_config_t* button_config;
} bsp_key_internal_state_t;
/**
* @brief Key state table for debouncing and event detection
*/
static bsp_key_internal_state_t key_state_table[BSP_KEY_ID_MAX] = {0};
/**
* @brief Get current board button configuration
*/
static const bsp_button_config_t* bsp_key_get_button_config(bsp_key_id_t key_id) {
const bsp_board_config_t* board_config = bsp_board_get_config();
if (board_config && key_id < board_config->buttons.count) {
return &board_config->buttons.buttons[key_id];
}
return NULL;
}
/**
* @brief Read raw key state (without debounce)
* @param key_id: Key ID
* @retval Raw key state
*/
static bsp_key_state_t bsp_key_read_raw(bsp_key_id_t key_id) {
bsp_key_state_t state;
const bsp_button_config_t* button_config = bsp_key_get_button_config(key_id);
if (button_config) {
hal_gpio_pin_state_t gpio_state;
/* Read GPIO pin state */
gpio_state = hal_gpio_read_pin(button_config->port, button_config->pin);
/* Convert to key state based on active level */
if (button_config->active_high) {
state = (gpio_state == HAL_GPIO_PIN_SET) ? BSP_KEY_STATE_PRESSED : BSP_KEY_STATE_RELEASED;
} else {
state = (gpio_state == HAL_GPIO_PIN_RESET) ? BSP_KEY_STATE_PRESSED : BSP_KEY_STATE_RELEASED;
}
} else {
state = BSP_KEY_STATE_RELEASED;
}
return state;
}
/**
* @brief Get current system time in milliseconds
* @retval Current time in ms
*/
static uint32_t bsp_key_get_time_ms(void) {
/* Use HAL tick function */
return hal_get_tick();
}
/**
* @brief Initialize all keys
*/
void bsp_key_init(void) {
uint8_t i;
/* Get current board configuration */
const bsp_board_config_t* board_config = bsp_board_get_config();
/* Initialize key state table */
for (i = 0; i < BSP_KEY_ID_MAX; i++) {
/* Get button configuration for this key */
const bsp_button_config_t* button_config = bsp_key_get_button_config((bsp_key_id_t)i);
/* Initialize with current state */
key_state_table[i].current_state = bsp_key_read_raw((bsp_key_id_t)i);
key_state_table[i].previous_state = key_state_table[i].current_state;
key_state_table[i].debounce_counter = 0;
/* Clear event flags */
key_state_table[i].press_event = 0;
key_state_table[i].release_event = 0;
key_state_table[i].long_press_event = 0;
key_state_table[i].repeat_event = 0;
key_state_table[i].short_press_event = 0;
/* Initialize timing variables */
key_state_table[i].press_start_time = 0;
key_state_table[i].last_repeat_time = 0;
key_state_table[i].current_time = 0;
/* Set default configuration */
key_state_table[i].long_press_time = KEY_LONG_PRESS_TIME;
key_state_table[i].repeat_interval = KEY_REPEAT_INTERVAL;
key_state_table[i].short_press_time = KEY_SHORT_PRESS_TIME;
/* Store button configuration */
key_state_table[i].button_config = button_config;
}
/* Call board-specific button initialization if available */
if (board_config && board_config->button_init) {
board_config->button_init(&board_config->buttons);
}
}
/**
* @brief Update key state (call this function periodically, e.g. every 10ms)
*/
void bsp_key_update(void) {
uint8_t i;
uint32_t current_time = bsp_key_get_time_ms();
for (i = 0; i < BSP_KEY_ID_MAX; i++) {
/* Skip if button configuration is not available */
if (!key_state_table[i].button_config) {
continue;
}
bsp_key_state_t raw_state = bsp_key_read_raw((bsp_key_id_t)i);
bsp_key_internal_state_t* key_state = &key_state_table[i];
/* Update current time */
key_state->current_time = current_time;
/* Debounce logic - optimized version */
if (raw_state != key_state->current_state) {
/* State is changing, increment counter */
if (++key_state->debounce_counter >= KEY_DEBOUNCE_COUNT) {
/* Debounce count reached, update state */
key_state->previous_state = key_state->current_state;
key_state->current_state = raw_state;
key_state->debounce_counter = 0;
if (raw_state == BSP_KEY_STATE_PRESSED) {
/* Key pressed event */
key_state->press_event = 1;
key_state->release_event = 0;
key_state->short_press_event = 0;
/* Reset timing variables */
key_state->press_start_time = current_time;
key_state->last_repeat_time = current_time;
key_state->long_press_event = 0;
key_state->repeat_event = 0;
} else {
/* Key released event */
key_state->release_event = 1;
key_state->press_event = 0;
/* Check for short press event */
uint32_t press_duration = current_time - key_state->press_start_time;
if (press_duration < key_state->long_press_time) {
key_state->short_press_event = 1;
}
/* Reset long press and repeat flags */
key_state->long_press_event = 0;
key_state->repeat_event = 0;
}
}
} else {
/* State is stable, reset counter */
key_state->debounce_counter = 0;
/* Handle timing-based events if key is pressed */
if (raw_state == BSP_KEY_STATE_PRESSED) {
uint32_t press_duration = current_time - key_state->press_start_time;
/* Check for long press event - only set once */
if (press_duration >= key_state->long_press_time && !key_state->long_press_event) {
key_state->long_press_event = 1;
}
/* Check for repeat event - only after long press */
if (key_state->long_press_event &&
(current_time - key_state->last_repeat_time >= key_state->repeat_interval)) {
key_state->repeat_event = 1;
key_state->last_repeat_time = current_time;
}
}
}
}
}
/**
* @brief Read debounced key state
* @param key_id: Key ID
* @retval Key state
*/
bsp_key_state_t bsp_key_read(bsp_key_id_t key_id) {
if (key_id < BSP_KEY_ID_MAX) {
return key_state_table[key_id].current_state;
}
return BSP_KEY_STATE_RELEASED;
}
/**
* @brief Check if key is pressed
* @param key_id: Key ID
* @retval 1 if pressed, 0 otherwise
*/
uint8_t bsp_key_is_pressed(bsp_key_id_t key_id) {
return (bsp_key_read(key_id) == BSP_KEY_STATE_PRESSED) ? 1 : 0;
}
/**
* @brief Check if key is released
* @param key_id: Key ID
* @retval 1 if released, 0 otherwise
*/
uint8_t bsp_key_is_released(bsp_key_id_t key_id) {
return (bsp_key_read(key_id) == BSP_KEY_STATE_RELEASED) ? 1 : 0;
}
/**
* @brief Check for key press event (edge detection)
* @param key_id: Key ID
* @retval 1 if key was pressed, 0 otherwise
*/
uint8_t bsp_key_get_press_event(bsp_key_id_t key_id) {
uint8_t event = 0;
if (key_id < BSP_KEY_ID_MAX) {
event = key_state_table[key_id].press_event;
key_state_table[key_id].press_event = 0; /* Clear event flag */
}
return event;
}
/**
* @brief Check for key release event (edge detection)
* @param key_id: Key ID
* @retval 1 if key was released, 0 otherwise
*/
uint8_t bsp_key_get_release_event(bsp_key_id_t key_id) {
uint8_t event = 0;
if (key_id < BSP_KEY_ID_MAX) {
event = key_state_table[key_id].release_event;
key_state_table[key_id].release_event = 0; /* Clear event flag */
}
return event;
}
/**
* @brief Check for key long pressed event
* @param key_id: Key ID
* @retval 1 if key was long pressed, 0 otherwise
*/
uint8_t bsp_key_get_long_press_event(bsp_key_id_t key_id) {
uint8_t event = 0;
if (key_id < BSP_KEY_ID_MAX) {
event = key_state_table[key_id].long_press_event;
/* Long press event is only reported once */
}
return event;
}
/**
* @brief Check for key repeat event
* @param key_id: Key ID
* @retval 1 if key repeat event occurred, 0 otherwise
*/
uint8_t bsp_key_get_repeat_event(bsp_key_id_t key_id) {
uint8_t event = 0;
if (key_id < BSP_KEY_ID_MAX) {
event = key_state_table[key_id].repeat_event;
key_state_table[key_id].repeat_event = 0; /* Clear event flag */
}
return event;
}
/**
* @brief Check for key short pressed event
* @param key_id: Key ID
* @retval 1 if key was short pressed, 0 otherwise
*/
uint8_t bsp_key_get_short_press_event(bsp_key_id_t key_id) {
uint8_t event = 0;
if (key_id < BSP_KEY_ID_MAX) {
event = key_state_table[key_id].short_press_event;
key_state_table[key_id].short_press_event = 0; /* Clear event flag */
}
return event;
}

View File

@ -11,6 +11,7 @@
#include "bsp_config.h"
#include "hal_gpio.h"
#include "hal_uart.h"
#include "hal_spi.h"
/**
* @brief Default LED initialization function
@ -28,20 +29,66 @@ static void default_led_init(const void* config) {
hal_gpio_configure_pin(&gpio_config);
}
/**
* @brief STM32F407VET6 board button configurations
*/
static const bsp_button_config_t stm32f407vet6_buttons[] = {
/* KEY0 - PE4, active low */
{
.port = BSP_KEY0_PORT,
.pin = BSP_KEY0_PIN,
.mode = HAL_GPIO_MODE_INPUT,
.speed = HAL_GPIO_SPEED_LOW,
.pull = HAL_GPIO_PULL_UP,
.active_high = 0
},
/* KEY1 - PE3, active low */
{
.port = BSP_KEY1_PORT,
.pin = BSP_KEY1_PIN,
.mode = HAL_GPIO_MODE_INPUT,
.speed = HAL_GPIO_SPEED_LOW,
.pull = HAL_GPIO_PULL_UP,
.active_high = 0
},
/* WKUP - PA0, active high */
{
.port = BSP_WKUP_PORT,
.pin = BSP_WKUP_PIN,
.mode = HAL_GPIO_MODE_INPUT,
.speed = HAL_GPIO_SPEED_LOW,
.pull = HAL_GPIO_PULL_DOWN,
.active_high = 1
}
};
/**
* @brief STM32F407VET6 buttons configuration
*/
static const bsp_buttons_config_t stm32f407vet6_buttons_config = {
.count = sizeof(stm32f407vet6_buttons) / sizeof(bsp_button_config_t),
.buttons = stm32f407vet6_buttons
};
/**
* @brief Default button initialization function
* @param config: Button configuration structure
*/
static void default_button_init(const void* config) {
const bsp_button_config_t* button_config = (const bsp_button_config_t*)config;
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);
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);
}
}
/**
@ -60,6 +107,38 @@ static void default_uart_init(const void* config) {
hal_uart_config(&uart_cfg);
}
/**
* @brief Default W25QXX initialization function
* @param config: W25QXX configuration structure
*/
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);
}
/**
* @brief STM32F407VET6 board configuration
*/
@ -72,13 +151,7 @@ const bsp_board_config_t stm32f407vet6_board_config = {
.speed = HAL_GPIO_SPEED_MEDIUM,
.pull = HAL_GPIO_PULL_NO
},
.button = {
.port = 0, /* Not used */
.pin = 0, /* Not used */
.mode = HAL_GPIO_MODE_INPUT,
.speed = HAL_GPIO_SPEED_LOW,
.pull = HAL_GPIO_PULL_NO
},
.buttons = stm32f407vet6_buttons_config,
.uart = {
.instance = BSP_UART_INSTANCE,
.baudrate = BSP_UART_BAUDRATE,
@ -90,9 +163,22 @@ const bsp_board_config_t stm32f407vet6_board_config = {
.rx_port = HAL_GPIO_PORT_A, /* USART1_RX - PA10 */
.rx_pin = HAL_GPIO_PIN_10
},
.w25qxx = {
.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
}
},
.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
};