优化实现串口驱动,SPI驱动 W25QXX还需要初始化验证修复

This commit is contained in:
冯佳
2026-01-23 09:59:43 +08:00
parent 51e8d79f78
commit b166bee1a9
69 changed files with 6253 additions and 1178 deletions

View File

@ -5,14 +5,23 @@ add_library(hal STATIC)
# Add HAL sources
target_sources(hal PRIVATE
Src/hal.c
Src/hal_gpio.c
Src/hal_delay.c
Src/hal_uart.c
Src/hal_spi.c
# STM32F4 specific sources
Src/arch/stm32f4/hal_stm32f4.c
Src/arch/stm32f4/hal_stm32f4_gpio.c
Src/arch/stm32f4/hal_stm32f4_uart.c
Src/arch/stm32f4/hal_stm32f4_delay.c
Src/arch/stm32f4/hal_stm32f4_spi.c
)
# Add HAL include directories
target_include_directories(hal PUBLIC
Inc
Inc/arch/stm32f4
)
# Link HAL dependencies

View File

@ -0,0 +1,26 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : hal_stm32f4.h
* @brief : STM32F4 architecture specific HAL header file
******************************************************************************
*/
/* USER CODE END Header */
#ifndef HAL_STM32F4_H
#define HAL_STM32F4_H
/* Include STM32F4 HAL headers */
#include "stm32f4xx_hal.h"
/* Include common HAL headers */
#include "../../hal_gpio.h"
#include "../../hal_uart.h"
#include "../../hal_delay.h"
/**
* @brief STM32F4 specific initialization
*/
void hal_stm32f4_init(void);
#endif /* HAL_STM32F4_H */

View File

@ -0,0 +1,59 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : hal_stm32f4_spi.h
* @brief : STM32F4 specific SPI HAL header file
******************************************************************************
*/
/* USER CODE END Header */
#ifndef __HAL_STM32F4_SPI_H__
#define __HAL_STM32F4_SPI_H__
#include "hal.h"
#include "hal_spi.h"
/**
* @brief STM32F4 specific SPI initialization
* @param instance SPI instance identifier
* @param config SPI configuration structure
* @return true if initialization is successful, false otherwise
*/
bool hal_stm32f4_spi_init(hal_spi_instance_t instance, const hal_spi_config_t *config);
/**
* @brief STM32F4 specific SPI deinitialization
* @param instance SPI instance identifier
* @return true if deinitialization is successful, false otherwise
*/
bool hal_stm32f4_spi_deinit(hal_spi_instance_t instance);
/**
* @brief STM32F4 specific SPI transmit implementation
* @param instance SPI instance identifier
* @param p_data Pointer to data buffer to transmit
* @param size Size of data to transmit
* @return true if transmission is successful, false otherwise
*/
bool hal_stm32f4_spi_transmit(hal_spi_instance_t instance, const uint8_t *p_data, uint16_t size);
/**
* @brief STM32F4 specific SPI receive implementation
* @param instance SPI instance identifier
* @param p_data Pointer to data buffer to receive
* @param size Size of data to receive
* @return true if reception is successful, false otherwise
*/
bool hal_stm32f4_spi_receive(hal_spi_instance_t instance, uint8_t *p_data, uint16_t size);
/**
* @brief STM32F4 specific SPI transmit and receive implementation
* @param instance SPI instance identifier
* @param p_tx_data Pointer to data buffer to transmit
* @param p_rx_data Pointer to data buffer to receive
* @param size Size of data to transmit/receive
* @return true if transmission and reception are successful, false otherwise
*/
bool hal_stm32f4_spi_transmit_receive(hal_spi_instance_t instance, const uint8_t *p_tx_data, uint8_t *p_rx_data, uint16_t size);
#endif /* __HAL_STM32F4_SPI_H__ */

47
HAL/Inc/hal.h Normal file
View File

@ -0,0 +1,47 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : hal.h
* @brief : Hardware Abstraction Layer common header file
******************************************************************************
*/
/* USER CODE END Header */
#ifndef HAL_H
#define HAL_H
/* Define supported architectures */
#define HAL_ARCH_STM32F1 0
#define HAL_ARCH_STM32F4 1
#define HAL_ARCH_STM32F7 2
#define HAL_ARCH_STM32L4 3
/* Select target architecture */
#ifndef HAL_TARGET_ARCH
#define HAL_TARGET_ARCH HAL_ARCH_STM32F4
#endif
/* Include architecture specific headers */
#if HAL_TARGET_ARCH == HAL_ARCH_STM32F1
#include "arch/stm32f1/hal_stm32f1.h"
#elif HAL_TARGET_ARCH == HAL_ARCH_STM32F4
#include "arch/stm32f4/hal_stm32f4.h"
#elif HAL_TARGET_ARCH == HAL_ARCH_STM32F7
#include "arch/stm32f7/hal_stm32f7.h"
#elif HAL_TARGET_ARCH == HAL_ARCH_STM32L4
#include "arch/stm32l4/hal_stm32l4.h"
#else
#error "Unsupported HAL architecture: " #HAL_TARGET_ARCH
#endif
/* Architecture compatibility check */
#if HAL_TARGET_ARCH < HAL_ARCH_STM32F1 || HAL_TARGET_ARCH > HAL_ARCH_STM32L4
#error "Invalid HAL architecture selection"
#endif
/**
* @brief HAL module initialization
*/
void hal_init(void);
#endif /* HAL_H */

View File

@ -58,12 +58,49 @@ typedef enum {
HAL_GPIO_PORT_K = 10U
} hal_gpio_port_t;
/**
* @brief GPIO mode definitions
*/
typedef enum {
HAL_GPIO_MODE_INPUT = 0U,
HAL_GPIO_MODE_OUTPUT_PP = 1U,
HAL_GPIO_MODE_OUTPUT_OD = 2U,
HAL_GPIO_MODE_AF_PP = 3U,
HAL_GPIO_MODE_AF_OD = 4U,
HAL_GPIO_MODE_ANALOG = 5U,
HAL_GPIO_MODE_IT_RISING = 6U,
HAL_GPIO_MODE_IT_FALLING = 7U,
HAL_GPIO_MODE_IT_RISING_FALLING = 8U
} hal_gpio_mode_t;
/**
* @brief GPIO speed definitions
*/
typedef enum {
HAL_GPIO_SPEED_LOW = 0U,
HAL_GPIO_SPEED_MEDIUM = 1U,
HAL_GPIO_SPEED_HIGH = 2U,
HAL_GPIO_SPEED_VERY_HIGH = 3U
} hal_gpio_speed_t;
/**
* @brief GPIO pull-up/pull-down definitions
*/
typedef enum {
HAL_GPIO_PULL_NO = 0U,
HAL_GPIO_PULL_UP = 1U,
HAL_GPIO_PULL_DOWN = 2U
} hal_gpio_pull_t;
/**
* @brief GPIO 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;
} hal_gpio_config_t;
/**
@ -71,6 +108,12 @@ typedef struct {
*/
void hal_gpio_init(void);
/**
* @brief Configure GPIO pin
* @param config: GPIO configuration structure
*/
void hal_gpio_configure_pin(const hal_gpio_config_t *config);
/**
* @brief Write GPIO pin state
* @param port: GPIO port

117
HAL/Inc/hal_spi.h Normal file
View File

@ -0,0 +1,117 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : hal_spi.h
* @brief : SPI hardware abstraction layer header file
******************************************************************************
*/
/* USER CODE END Header */
#ifndef HAL_SPI_H
#define HAL_SPI_H
#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>
/**
* @brief SPI instance identifier definitions
*/
typedef enum {
HAL_SPI_INSTANCE_1 = 0,
HAL_SPI_INSTANCE_2,
HAL_SPI_INSTANCE_3,
HAL_SPI_INSTANCE_4,
HAL_SPI_INSTANCE_5,
HAL_SPI_INSTANCE_6,
HAL_SPI_INSTANCE_MAX
} hal_spi_instance_t;
/**
* @brief SPI mode definitions
*/
typedef enum {
HAL_SPI_MODE_MASTER = 0,
HAL_SPI_MODE_SLAVE
} hal_spi_mode_t;
/**
* @brief SPI clock polarity definitions
*/
typedef enum {
HAL_SPI_POLARITY_LOW = 0,
HAL_SPI_POLARITY_HIGH
} hal_spi_polarity_t;
/**
* @brief SPI clock phase definitions
*/
typedef enum {
HAL_SPI_PHASE_1EDGE = 0,
HAL_SPI_PHASE_2EDGE
} hal_spi_phase_t;
/**
* @brief SPI data bits definitions
*/
typedef enum {
HAL_SPI_DATABITS_8 = 0,
HAL_SPI_DATABITS_16
} hal_spi_databits_t;
/**
* @brief 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;
} hal_spi_config_t;
/**
* @brief Initialize SPI hardware
* @param instance SPI instance identifier
* @param config SPI configuration structure
* @return true if initialization is successful, false otherwise
*/
bool hal_spi_init(hal_spi_instance_t instance, const hal_spi_config_t *config);
/**
* @brief Deinitialize SPI hardware
* @param instance SPI instance identifier
* @return true if deinitialization is successful, false otherwise
*/
bool hal_spi_deinit(hal_spi_instance_t instance);
/**
* @brief Transmit data over specific SPI instance
* @param instance: SPI instance identifier
* @param data: Pointer to data buffer
* @param size: Data length in bytes
* @return true if transmission is successful, false otherwise
*/
bool hal_spi_transmit(hal_spi_instance_t instance, const uint8_t *data, uint16_t size);
/**
* @brief Receive data from specific SPI instance
* @param instance: SPI instance identifier
* @param data: Pointer to data buffer
* @param size: Data length to receive in bytes
* @return true if reception is successful, false otherwise
*/
bool hal_spi_receive(hal_spi_instance_t instance, uint8_t *data, uint16_t size);
/**
* @brief Transmit and receive data simultaneously over specific SPI instance
* @param instance: SPI instance identifier
* @param tx_data: Pointer to transmit data buffer
* @param rx_data: Pointer to receive data buffer
* @param size: Data length in bytes
* @return true if transmission and reception are successful, false otherwise
*/
bool hal_spi_transmit_receive(hal_spi_instance_t instance, const uint8_t *tx_data, uint8_t *rx_data, uint16_t size);
#endif /* HAL_SPI_H */

View File

@ -38,10 +38,24 @@ typedef enum {
HAL_UART_DATABITS_9 = 1U
} hal_uart_databits_t;
/**
* @brief UART instance identifier definitions
*/
typedef enum {
HAL_UART_INSTANCE_1 = 0U,
HAL_UART_INSTANCE_2,
HAL_UART_INSTANCE_3,
HAL_UART_INSTANCE_4,
HAL_UART_INSTANCE_5,
HAL_UART_INSTANCE_6,
HAL_UART_INSTANCE_MAX
} hal_uart_instance_t;
/**
* @brief UART configuration structure
*/
typedef struct {
hal_uart_instance_t instance;
uint32_t baudrate;
hal_uart_parity_t parity;
hal_uart_stopbits_t stopbits;
@ -54,36 +68,40 @@ typedef struct {
void hal_uart_init(void);
/**
* @brief Configure UART parameters
* @brief Configure UART parameters for specific instance
* @param config: UART configuration structure
*/
void hal_uart_config(const hal_uart_config_t *config);
/**
* @brief Send data over UART
* @brief Send data over specific UART instance
* @param instance: UART instance identifier
* @param data: Pointer to data buffer
* @param length: Data length in bytes
*/
void hal_uart_send(const uint8_t *data, size_t length);
void hal_uart_send(hal_uart_instance_t instance, const uint8_t *data, size_t length);
/**
* @brief Receive data over UART
* @brief Receive data from specific UART instance
* @param instance: UART instance identifier
* @param data: Pointer to data buffer
* @param length: Data length to receive in bytes
* @retval Number of bytes received
*/
size_t hal_uart_receive(uint8_t *data, size_t length);
size_t hal_uart_receive(hal_uart_instance_t instance, uint8_t *data, size_t length);
/**
* @brief Check if UART is ready to send
* @brief Check if specific UART instance is ready to send
* @param instance: UART instance identifier
* @retval 1 if ready, 0 otherwise
*/
uint8_t hal_uart_is_tx_ready(void);
uint8_t hal_uart_is_tx_ready(hal_uart_instance_t instance);
/**
* @brief Check if UART has data to receive
* @brief Check if specific UART instance has data to receive
* @param instance: UART instance identifier
* @retval 1 if data available, 0 otherwise
*/
uint8_t hal_uart_is_rx_ready(void);
uint8_t hal_uart_is_rx_ready(hal_uart_instance_t instance);
#endif /* HAL_UART_H */

View File

@ -0,0 +1,20 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : hal_stm32f4.c
* @brief : STM32F4 architecture specific HAL initialization
******************************************************************************
*/
/* USER CODE END Header */
#include "hal.h"
/**
* @brief STM32F4 specific initialization
*/
void hal_stm32f4_init(void) {
/* Initialize STM32F4 specific peripherals */
hal_stm32f4_gpio_init();
hal_stm32f4_uart_init();
hal_stm32f4_delay_init();
}

View File

@ -0,0 +1,44 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : hal_stm32f4_delay.c
* @brief : STM32F4 specific Delay HAL implementation
******************************************************************************
*/
/* USER CODE END Header */
#include "hal.h"
#include "hal_delay.h"
#include "stm32f4xx_hal.h"
/**
* @brief STM32F4 specific delay initialization
*/
void hal_stm32f4_delay_init(void) {
/* Delay initialization is handled by HAL_Init() */
}
/**
* @brief STM32F4 specific delay in milliseconds
* @param ms: Delay time in milliseconds
*/
void hal_stm32f4_delay_ms(uint32_t ms) {
HAL_Delay(ms);
}
/**
* @brief STM32F4 specific delay in microseconds
* @param us: Delay time in microseconds
*/
void hal_stm32f4_delay_us(uint32_t us) {
uint32_t ticks = 0;
uint32_t start_tick = 0;
uint32_t tick_freq = HAL_RCC_GetHCLKFreq() / 1000000;
ticks = us * tick_freq;
start_tick = HAL_GetTick() * tick_freq;
while ((HAL_GetTick() * tick_freq - start_tick) < ticks) {
/* Busy wait */
}
}

View File

@ -0,0 +1,164 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : hal_stm32f4_gpio.c
* @brief : STM32F4 specific GPIO HAL implementation
******************************************************************************
*/
/* USER CODE END Header */
#include "hal.h"
#include "hal_gpio.h"
#include "stm32f4xx_hal.h"
/**
* @brief Convert HAL GPIO port to STM32 GPIO port
* @param port: HAL GPIO port
* @retval STM32 GPIO port
*/
static GPIO_TypeDef* hal_gpio_port_to_stm32(hal_gpio_port_t port) {
switch (port) {
case HAL_GPIO_PORT_A: return GPIOA;
case HAL_GPIO_PORT_B: return GPIOB;
case HAL_GPIO_PORT_C: return GPIOC;
case HAL_GPIO_PORT_D: return GPIOD;
case HAL_GPIO_PORT_E: return GPIOE;
case HAL_GPIO_PORT_F: return GPIOF;
case HAL_GPIO_PORT_G: return GPIOG;
case HAL_GPIO_PORT_H: return GPIOH;
case HAL_GPIO_PORT_I: return GPIOI;
// case HAL_GPIO_PORT_J: return GPIOJ;
// case HAL_GPIO_PORT_K: return GPIOK;
default: return NULL;
}
}
/**
* @brief Convert HAL GPIO pin to STM32 GPIO pin
* @param pin: HAL GPIO pin
* @retval STM32 GPIO pin
*/
static uint16_t hal_gpio_pin_to_stm32(hal_gpio_pin_t pin) {
return (1U << pin);
}
/**
* @brief Convert HAL GPIO state to STM32 GPIO state
* @param state: HAL GPIO state
* @retval STM32 GPIO state
*/
static GPIO_PinState hal_gpio_state_to_stm32(hal_gpio_pin_state_t state) {
return (state == HAL_GPIO_PIN_SET) ? GPIO_PIN_SET : GPIO_PIN_RESET;
}
/**
* @brief STM32F4 specific GPIO initialization
*/
void hal_stm32f4_gpio_init(void) {
/* GPIO initialization is handled by BSP layer */
}
/**
* @brief STM32F4 specific GPIO write pin implementation
*/
void hal_stm32f4_gpio_write_pin(hal_gpio_port_t port, hal_gpio_pin_t pin, hal_gpio_pin_state_t state) {
GPIO_TypeDef* stm32_port = hal_gpio_port_to_stm32(port);
if (stm32_port == NULL) {
return;
}
uint16_t stm32_pin = hal_gpio_pin_to_stm32(pin);
GPIO_PinState stm32_state = hal_gpio_state_to_stm32(state);
HAL_GPIO_WritePin(stm32_port, stm32_pin, stm32_state);
}
/**
* @brief STM32F4 specific GPIO toggle pin implementation
*/
void hal_stm32f4_gpio_toggle_pin(hal_gpio_port_t port, hal_gpio_pin_t pin) {
GPIO_TypeDef* stm32_port = hal_gpio_port_to_stm32(port);
if (stm32_port == NULL) {
return;
}
uint16_t stm32_pin = hal_gpio_pin_to_stm32(pin);
HAL_GPIO_TogglePin(stm32_port, stm32_pin);
}
/**
* @brief STM32F4 specific GPIO read pin implementation
*/
hal_gpio_pin_state_t hal_stm32f4_gpio_read_pin(hal_gpio_port_t port, hal_gpio_pin_t pin) {
GPIO_TypeDef* stm32_port = hal_gpio_port_to_stm32(port);
if (stm32_port == NULL) {
return HAL_GPIO_PIN_RESET;
}
uint16_t stm32_pin = hal_gpio_pin_to_stm32(pin);
GPIO_PinState stm32_state = HAL_GPIO_ReadPin(stm32_port, stm32_pin);
return (stm32_state == GPIO_PIN_SET) ? HAL_GPIO_PIN_SET : HAL_GPIO_PIN_RESET;
}
/**
* @brief STM32F4 specific GPIO configure pin implementation
*/
void hal_stm32f4_gpio_configure_pin(const hal_gpio_config_t *config) {
if (config == NULL) {
return;
}
GPIO_TypeDef* stm32_port = hal_gpio_port_to_stm32(config->port);
if (stm32_port == NULL) {
return;
}
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* Enable GPIO clock */
switch (config->port) {
case HAL_GPIO_PORT_A: __HAL_RCC_GPIOA_CLK_ENABLE(); break;
case HAL_GPIO_PORT_B: __HAL_RCC_GPIOB_CLK_ENABLE(); break;
case HAL_GPIO_PORT_C: __HAL_RCC_GPIOC_CLK_ENABLE(); break;
case HAL_GPIO_PORT_D: __HAL_RCC_GPIOD_CLK_ENABLE(); break;
case HAL_GPIO_PORT_E: __HAL_RCC_GPIOE_CLK_ENABLE(); break;
case HAL_GPIO_PORT_F: __HAL_RCC_GPIOF_CLK_ENABLE(); break;
case HAL_GPIO_PORT_G: __HAL_RCC_GPIOG_CLK_ENABLE(); break;
case HAL_GPIO_PORT_H: __HAL_RCC_GPIOH_CLK_ENABLE(); break;
case HAL_GPIO_PORT_I: __HAL_RCC_GPIOI_CLK_ENABLE(); break;
default: break;
}
/* Configure GPIO parameters */
GPIO_InitStruct.Pin = hal_gpio_pin_to_stm32(config->pin);
/* Convert HAL GPIO mode to STM32 GPIO mode */
switch (config->mode) {
case HAL_GPIO_MODE_INPUT: GPIO_InitStruct.Mode = GPIO_MODE_INPUT; break;
case HAL_GPIO_MODE_OUTPUT_PP: GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; break;
case HAL_GPIO_MODE_OUTPUT_OD: GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD; break;
case HAL_GPIO_MODE_AF_PP: GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; break;
case HAL_GPIO_MODE_AF_OD: GPIO_InitStruct.Mode = GPIO_MODE_AF_OD; break;
case HAL_GPIO_MODE_ANALOG: GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; break;
case HAL_GPIO_MODE_IT_RISING: GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING; break;
case HAL_GPIO_MODE_IT_FALLING: GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING; break;
case HAL_GPIO_MODE_IT_RISING_FALLING: GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING; break;
default: GPIO_InitStruct.Mode = GPIO_MODE_INPUT; break;
}
/* Convert HAL GPIO pull to STM32 GPIO pull */
switch (config->pull) {
case HAL_GPIO_PULL_NO: GPIO_InitStruct.Pull = GPIO_NOPULL; break;
case HAL_GPIO_PULL_UP: GPIO_InitStruct.Pull = GPIO_PULLUP; break;
case HAL_GPIO_PULL_DOWN: GPIO_InitStruct.Pull = GPIO_PULLDOWN; break;
default: GPIO_InitStruct.Pull = GPIO_NOPULL; break;
}
/* Convert HAL GPIO speed to STM32 GPIO speed */
switch (config->speed) {
case HAL_GPIO_SPEED_LOW: GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; break;
case HAL_GPIO_SPEED_MEDIUM: GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM; break;
case HAL_GPIO_SPEED_HIGH: GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; break;
case HAL_GPIO_SPEED_VERY_HIGH: GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; break;
default: GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; break;
}
/* Initialize GPIO */
HAL_GPIO_Init(stm32_port, &GPIO_InitStruct);
}

View File

@ -0,0 +1,254 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : hal_stm32f4_spi.c
* @brief : STM32F4 specific SPI HAL implementation
******************************************************************************
*/
/* USER CODE END Header */
#include "hal.h"
#include "hal_spi.h"
#include "hal_stm32f4_spi.h"
#include "stm32f4xx_hal.h"
#include "stm32f4xx_hal_spi.h"
#include <stdbool.h>
/* SPI handles */
static SPI_HandleTypeDef hspi1;
static SPI_HandleTypeDef hspi2;
static SPI_HandleTypeDef hspi3;
static SPI_HandleTypeDef hspi4;
static SPI_HandleTypeDef hspi5;
static SPI_HandleTypeDef hspi6;
/**
* @brief Get SPI handle based on instance
* @param instance SPI instance identifier
* @return Pointer to SPI handle
*/
static SPI_HandleTypeDef* get_spi_handle(hal_spi_instance_t instance) {
switch (instance) {
case HAL_SPI_INSTANCE_1:
return &hspi1;
case HAL_SPI_INSTANCE_2:
return &hspi2;
case HAL_SPI_INSTANCE_3:
return &hspi3;
case HAL_SPI_INSTANCE_4:
return &hspi4;
case HAL_SPI_INSTANCE_5:
return &hspi5;
case HAL_SPI_INSTANCE_6:
return &hspi6;
default:
return NULL;
}
}
/**
* @brief STM32F4 specific SPI initialization
* @param instance SPI instance identifier
* @param config SPI configuration structure
* @return true if initialization is successful, false otherwise
*/
bool hal_stm32f4_spi_init(hal_spi_instance_t instance, const hal_spi_config_t *config) {
if (config == NULL) {
return false;
}
SPI_HandleTypeDef* hspi = get_spi_handle(instance);
if (hspi == NULL) {
return false;
}
/* Configure SPI parameters */
hspi->Instance = NULL;
hspi->Init.Mode = (config->mode == HAL_SPI_MODE_MASTER) ? SPI_MODE_MASTER : SPI_MODE_SLAVE;
hspi->Init.DataSize = (config->databits == HAL_SPI_DATABITS_8) ? SPI_DATASIZE_8BIT : SPI_DATASIZE_16BIT;
hspi->Init.CLKPolarity = (config->polarity == HAL_SPI_POLARITY_LOW) ? SPI_POLARITY_LOW : SPI_POLARITY_HIGH;
hspi->Init.CLKPhase = (config->phase == HAL_SPI_PHASE_1EDGE) ? SPI_PHASE_1EDGE : SPI_PHASE_2EDGE;
hspi->Init.NSS = SPI_NSS_SOFT; /* Use software NSS */
/* Calculate baud rate prescaler based on desired baud rate */
uint32_t apb_clock = HAL_RCC_GetPCLK2Freq(); /* Assume SPI1 is on APB2 */
uint32_t prescaler = 0;
uint32_t temp_prescaler = 2;
while (apb_clock / temp_prescaler > config->baudrate) {
temp_prescaler <<= 1;
prescaler++;
}
hspi->Init.BaudRatePrescaler = (uint32_t)temp_prescaler;
hspi->Init.FirstBit = SPI_FIRSTBIT_MSB; /* Default to MSB first */
hspi->Init.TIMode = SPI_TIMODE_DISABLE;
hspi->Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi->Init.CRCPolynomial = 10;
/* Configure GPIO and enable clocks based on instance */
GPIO_InitTypeDef GPIO_InitStruct = {0};
switch (instance) {
case HAL_SPI_INSTANCE_1:
/* Enable SPI1 clock */
__HAL_RCC_SPI1_CLK_ENABLE();
/* Enable GPIOB clock */
__HAL_RCC_GPIOB_CLK_ENABLE();
/* Configure SPI1 GPIO pins: SCK(PB3), MISO(PB4), MOSI(PB5) */
GPIO_InitStruct.Pin = GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF5_SPI1;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
hspi->Instance = SPI1;
break;
case HAL_SPI_INSTANCE_2:
/* Enable SPI2 clock */
__HAL_RCC_SPI2_CLK_ENABLE();
/* Enable GPIOB clock */
__HAL_RCC_GPIOB_CLK_ENABLE();
/* Configure SPI2 GPIO pins: SCK(PB13), MISO(PB14), MOSI(PB15) */
GPIO_InitStruct.Pin = GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF5_SPI2;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
hspi->Instance = SPI2;
break;
case HAL_SPI_INSTANCE_3:
/* Enable SPI3 clock */
__HAL_RCC_SPI3_CLK_ENABLE();
/* Enable GPIOC clock */
__HAL_RCC_GPIOC_CLK_ENABLE();
/* Configure SPI3 GPIO pins: SCK(PC10), MISO(PC11), MOSI(PC12) */
GPIO_InitStruct.Pin = GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF6_SPI3;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
hspi->Instance = SPI3;
break;
default:
return false;
}
/* Initialize SPI */
if (HAL_SPI_Init(hspi) != HAL_OK) {
return false;
}
return true;
}
/**
* @brief STM32F4 specific SPI deinitialization
* @param instance SPI instance identifier
* @return true if deinitialization is successful, false otherwise
*/
bool hal_stm32f4_spi_deinit(hal_spi_instance_t instance) {
SPI_HandleTypeDef* hspi = get_spi_handle(instance);
if (hspi == NULL || hspi->Instance == NULL) {
return false;
}
if (HAL_SPI_DeInit(hspi) != HAL_OK) {
return false;
}
/* Disable SPI clock */
switch (instance) {
case HAL_SPI_INSTANCE_1:
__HAL_RCC_SPI1_CLK_DISABLE();
break;
case HAL_SPI_INSTANCE_2:
__HAL_RCC_SPI2_CLK_DISABLE();
break;
case HAL_SPI_INSTANCE_3:
__HAL_RCC_SPI3_CLK_DISABLE();
break;
default:
return false;
}
return true;
}
/**
* @brief STM32F4 specific SPI transmit implementation
* @param instance SPI instance identifier
* @param p_data Pointer to data buffer to transmit
* @param size Size of data to transmit
* @return true if transmission is successful, false otherwise
*/
bool hal_stm32f4_spi_transmit(hal_spi_instance_t instance, const uint8_t *p_data, uint16_t size) {
if (p_data == NULL || size == 0) {
return false;
}
SPI_HandleTypeDef* hspi = get_spi_handle(instance);
if (hspi == NULL || hspi->Instance == NULL) {
return false;
}
HAL_StatusTypeDef status = HAL_SPI_Transmit(hspi, (uint8_t*)p_data, size, HAL_MAX_DELAY);
return (status == HAL_OK);
}
/**
* @brief STM32F4 specific SPI receive implementation
* @param instance SPI instance identifier
* @param p_data Pointer to data buffer to receive
* @param size Size of data to receive
* @return true if reception is successful, false otherwise
*/
bool hal_stm32f4_spi_receive(hal_spi_instance_t instance, uint8_t *p_data, uint16_t size) {
if (p_data == NULL || size == 0) {
return false;
}
SPI_HandleTypeDef* hspi = get_spi_handle(instance);
if (hspi == NULL || hspi->Instance == NULL) {
return false;
}
HAL_StatusTypeDef status = HAL_SPI_Receive(hspi, p_data, size, HAL_MAX_DELAY);
return (status == HAL_OK);
}
/**
* @brief STM32F4 specific SPI transmit and receive implementation
* @param instance SPI instance identifier
* @param p_tx_data Pointer to data buffer to transmit
* @param p_rx_data Pointer to data buffer to receive
* @param size Size of data to transmit/receive
* @return true if transmission and reception are successful, false otherwise
*/
bool hal_stm32f4_spi_transmit_receive(hal_spi_instance_t instance, const uint8_t *p_tx_data, uint8_t *p_rx_data, uint16_t size) {
if (p_tx_data == NULL || p_rx_data == NULL || size == 0) {
return false;
}
SPI_HandleTypeDef* hspi = get_spi_handle(instance);
if (hspi == NULL || hspi->Instance == NULL) {
return false;
}
HAL_StatusTypeDef status = HAL_SPI_TransmitReceive(hspi, (uint8_t*)p_tx_data, p_rx_data, size, HAL_MAX_DELAY);
return (status == HAL_OK);
}

View File

@ -0,0 +1,161 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : hal_stm32f4_uart.c
* @brief : STM32F4 specific UART HAL implementation
******************************************************************************
*/
/* USER CODE END Header */
#include "hal.h"
#include "hal_uart.h"
#include "stm32f4xx_hal.h"
#include "stm32f4xx_hal_uart.h"
/* UART handle */
static UART_HandleTypeDef huart1;
/**
* @brief STM32F4 specific UART initialization
*/
void hal_stm32f4_uart_init(void) {
/* UART initialization is handled by HAL_Init() */
/* Configure UART GPIO pins */
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* Enable UART clock */
__HAL_RCC_USART1_CLK_ENABLE();
/* Enable GPIO clocks */
__HAL_RCC_GPIOA_CLK_ENABLE();
/* Configure USART1 Tx (PA9) as alternate function push-pull */
GPIO_InitStruct.Pin = GPIO_PIN_9;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF7_USART1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* Configure USART1 Rx (PA10) as alternate function push-pull */
GPIO_InitStruct.Pin = GPIO_PIN_10;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF7_USART1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* Initialize UART */
huart1.Instance = USART1;
huart1.Init.BaudRate = 115200;
huart1.Init.WordLength = UART_WORDLENGTH_8B;
huart1.Init.StopBits = UART_STOPBITS_1;
huart1.Init.Parity = UART_PARITY_NONE;
huart1.Init.Mode = UART_MODE_TX_RX;
huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart1.Init.OverSampling = UART_OVERSAMPLING_16;
if (HAL_UART_Init(&huart1) != HAL_OK) {
/* Initialization Error */
while (1);
}
}
/**
* @brief STM32F4 specific UART configuration
*/
void hal_stm32f4_uart_config(const hal_uart_config_t *config) {
if (config == NULL) {
return;
}
/* Update UART configuration */
huart1.Init.BaudRate = config->baudrate;
/* Convert parity */
switch (config->parity) {
case HAL_UART_PARITY_NONE:
huart1.Init.Parity = UART_PARITY_NONE;
break;
case HAL_UART_PARITY_ODD:
huart1.Init.Parity = UART_PARITY_ODD;
break;
case HAL_UART_PARITY_EVEN:
huart1.Init.Parity = UART_PARITY_EVEN;
break;
default:
huart1.Init.Parity = UART_PARITY_NONE;
break;
}
/* Convert stop bits */
huart1.Init.StopBits = (config->stopbits == HAL_UART_STOPBITS_1) ?
UART_STOPBITS_1 : UART_STOPBITS_2;
/* Convert data bits */
huart1.Init.WordLength = (config->databits == HAL_UART_DATABITS_8) ?
UART_WORDLENGTH_8B : UART_WORDLENGTH_9B;
/* Re-initialize UART */
if (HAL_UART_Init(&huart1) != HAL_OK) {
/* Initialization Error */
while (1);
}
}
/**
* @brief STM32F4 specific UART send implementation
*/
void hal_stm32f4_uart_send(hal_uart_instance_t instance, const uint8_t *data, size_t length) {
if (data == NULL || length == 0) {
return;
}
/* Currently only supports USART1 */
if (instance == HAL_UART_INSTANCE_1) {
HAL_UART_Transmit(&huart1, (uint8_t *)data, length, HAL_MAX_DELAY);
}
}
/**
* @brief STM32F4 specific UART receive implementation
*/
size_t hal_stm32f4_uart_receive(hal_uart_instance_t instance, uint8_t *data, size_t length) {
if (data == NULL || length == 0) {
return 0;
}
/* Currently only supports USART1 */
if (instance == HAL_UART_INSTANCE_1) {
HAL_StatusTypeDef status = HAL_UART_Receive(&huart1, data, length, HAL_MAX_DELAY);
if (status == HAL_OK) {
return length;
}
}
return 0;
}
/**
* @brief STM32F4 specific UART TX ready check
*/
uint8_t hal_stm32f4_uart_is_tx_ready(hal_uart_instance_t instance) {
/* Currently only supports USART1 */
if (instance == HAL_UART_INSTANCE_1) {
return (HAL_UART_GetState(&huart1) == HAL_UART_STATE_READY) ? 1 : 0;
}
return 0;
}
/**
* @brief STM32F4 specific UART RX ready check
*/
uint8_t hal_stm32f4_uart_is_rx_ready(hal_uart_instance_t instance) {
/* Currently only supports USART1 */
if (instance == HAL_UART_INSTANCE_1) {
return (HAL_UART_GetState(&huart1) == HAL_UART_STATE_READY) ? 1 : 0;
}
return 0;
}

22
HAL/Src/hal.c Normal file
View File

@ -0,0 +1,22 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : hal.c
* @brief : Hardware Abstraction Layer main source file
******************************************************************************
*/
/* USER CODE END Header */
#include "hal.h"
/**
* @brief HAL module initialization
*/
void hal_init(void) {
/* Call architecture specific initialization */
#if HAL_TARGET_ARCH == HAL_ARCH_STM32F4
hal_stm32f4_init();
#else
#error "Unsupported HAL architecture"
#endif
}

View File

@ -7,14 +7,19 @@
*/
/* USER CODE END Header */
#include "hal.h"
#include "hal_delay.h"
#include "stm32f4xx_hal.h"
/**
* @brief Initialize delay module
*/
void hal_delay_init(void) {
/* Delay initialization is handled by HAL_Init() */
/* Call architecture specific delay initialization */
#if HAL_TARGET_ARCH == HAL_ARCH_STM32F4
hal_stm32f4_delay_init();
#else
#error "Unsupported HAL architecture"
#endif
}
/**
@ -22,7 +27,12 @@ void hal_delay_init(void) {
* @param ms: Delay time in milliseconds
*/
void hal_delay_ms(uint32_t ms) {
HAL_Delay(ms);
/* Call architecture specific delay implementation */
#if HAL_TARGET_ARCH == HAL_ARCH_STM32F4
hal_stm32f4_delay_ms(ms);
#else
#error "Unsupported HAL architecture"
#endif
}
/**
@ -30,14 +40,10 @@ void hal_delay_ms(uint32_t ms) {
* @param us: Delay time in microseconds
*/
void hal_delay_us(uint32_t us) {
uint32_t ticks = 0;
uint32_t start_tick = 0;
uint32_t tick_freq = HAL_RCC_GetHCLKFreq() / 1000000;
ticks = us * tick_freq;
start_tick = HAL_GetTick() * tick_freq;
while ((HAL_GetTick() * tick_freq - start_tick) < ticks) {
/* Busy wait */
}
/* Call architecture specific delay implementation */
#if HAL_TARGET_ARCH == HAL_ARCH_STM32F4
hal_stm32f4_delay_us(us);
#else
#error "Unsupported HAL architecture"
#endif
}

View File

@ -7,54 +7,44 @@
*/
/* USER CODE END Header */
#include "hal.h"
#include "hal_gpio.h"
#include "stm32f4xx_hal.h"
/**
* @brief Convert HAL GPIO port to STM32 GPIO port
* @param port: HAL GPIO port
* @retval STM32 GPIO port
*/
static GPIO_TypeDef* hal_gpio_port_to_stm32(hal_gpio_port_t port) {
switch (port) {
case HAL_GPIO_PORT_A: return GPIOA;
case HAL_GPIO_PORT_B: return GPIOB;
case HAL_GPIO_PORT_C: return GPIOC;
case HAL_GPIO_PORT_D: return GPIOD;
case HAL_GPIO_PORT_E: return GPIOE;
case HAL_GPIO_PORT_F: return GPIOF;
case HAL_GPIO_PORT_G: return GPIOG;
case HAL_GPIO_PORT_H: return GPIOH;
case HAL_GPIO_PORT_I: return GPIOI;
// case HAL_GPIO_PORT_J: return GPIOJ;
// case HAL_GPIO_PORT_K: return GPIOK;
default: return NULL;
}
}
/**
* @brief Convert HAL GPIO pin to STM32 GPIO pin
* @param pin: HAL GPIO pin
* @retval STM32 GPIO pin
*/
static uint16_t hal_gpio_pin_to_stm32(hal_gpio_pin_t pin) {
return (1U << pin);
}
/**
* @brief Convert HAL GPIO state to STM32 GPIO state
* @param state: HAL GPIO state
* @retval STM32 GPIO state
*/
static GPIO_PinState hal_gpio_state_to_stm32(hal_gpio_pin_state_t state) {
return (state == HAL_GPIO_PIN_SET) ? GPIO_PIN_SET : GPIO_PIN_RESET;
}
/**
* @brief Initialize GPIO hardware
*/
void hal_gpio_init(void) {
/* GPIO initialization is handled by BSP layer */
/* Call architecture specific GPIO initialization */
#if HAL_TARGET_ARCH == HAL_ARCH_STM32F1
hal_stm32f1_gpio_init();
#elif HAL_TARGET_ARCH == HAL_ARCH_STM32F4
hal_stm32f4_gpio_init();
#elif HAL_TARGET_ARCH == HAL_ARCH_STM32F7
hal_stm32f7_gpio_init();
#elif HAL_TARGET_ARCH == HAL_ARCH_STM32L4
hal_stm32l4_gpio_init();
#else
#error "Unsupported HAL architecture"
#endif
}
/**
* @brief Configure GPIO pin
* @param config: GPIO configuration structure
*/
void hal_gpio_configure_pin(const hal_gpio_config_t *config) {
/* Call architecture specific GPIO configuration */
#if HAL_TARGET_ARCH == HAL_ARCH_STM32F1
hal_stm32f1_gpio_configure_pin(config);
#elif HAL_TARGET_ARCH == HAL_ARCH_STM32F4
hal_stm32f4_gpio_configure_pin(config);
#elif HAL_TARGET_ARCH == HAL_ARCH_STM32F7
hal_stm32f7_gpio_configure_pin(config);
#elif HAL_TARGET_ARCH == HAL_ARCH_STM32L4
hal_stm32l4_gpio_configure_pin(config);
#else
#error "Unsupported HAL architecture"
#endif
}
/**
@ -64,13 +54,18 @@ void hal_gpio_init(void) {
* @param state: GPIO pin state
*/
void hal_gpio_write_pin(hal_gpio_port_t port, hal_gpio_pin_t pin, hal_gpio_pin_state_t state) {
GPIO_TypeDef* stm32_port = hal_gpio_port_to_stm32(port);
if (stm32_port == NULL) {
return;
}
uint16_t stm32_pin = hal_gpio_pin_to_stm32(pin);
GPIO_PinState stm32_state = hal_gpio_state_to_stm32(state);
HAL_GPIO_WritePin(stm32_port, stm32_pin, stm32_state);
/* Call architecture specific GPIO write implementation */
#if HAL_TARGET_ARCH == HAL_ARCH_STM32F1
hal_stm32f1_gpio_write_pin(port, pin, state);
#elif HAL_TARGET_ARCH == HAL_ARCH_STM32F4
hal_stm32f4_gpio_write_pin(port, pin, state);
#elif HAL_TARGET_ARCH == HAL_ARCH_STM32F7
hal_stm32f7_gpio_write_pin(port, pin, state);
#elif HAL_TARGET_ARCH == HAL_ARCH_STM32L4
hal_stm32l4_gpio_write_pin(port, pin, state);
#else
#error "Unsupported HAL architecture"
#endif
}
/**
@ -79,12 +74,18 @@ void hal_gpio_write_pin(hal_gpio_port_t port, hal_gpio_pin_t pin, hal_gpio_pin_s
* @param pin: GPIO pin
*/
void hal_gpio_toggle_pin(hal_gpio_port_t port, hal_gpio_pin_t pin) {
GPIO_TypeDef* stm32_port = hal_gpio_port_to_stm32(port);
if (stm32_port == NULL) {
return;
}
uint16_t stm32_pin = hal_gpio_pin_to_stm32(pin);
HAL_GPIO_TogglePin(stm32_port, stm32_pin);
/* Call architecture specific GPIO toggle implementation */
#if HAL_TARGET_ARCH == HAL_ARCH_STM32F1
hal_stm32f1_gpio_toggle_pin(port, pin);
#elif HAL_TARGET_ARCH == HAL_ARCH_STM32F4
hal_stm32f4_gpio_toggle_pin(port, pin);
#elif HAL_TARGET_ARCH == HAL_ARCH_STM32F7
hal_stm32f7_gpio_toggle_pin(port, pin);
#elif HAL_TARGET_ARCH == HAL_ARCH_STM32L4
hal_stm32l4_gpio_toggle_pin(port, pin);
#else
#error "Unsupported HAL architecture"
#endif
}
/**
@ -94,11 +95,17 @@ void hal_gpio_toggle_pin(hal_gpio_port_t port, hal_gpio_pin_t pin) {
* @retval GPIO pin state
*/
hal_gpio_pin_state_t hal_gpio_read_pin(hal_gpio_port_t port, hal_gpio_pin_t pin) {
GPIO_TypeDef* stm32_port = hal_gpio_port_to_stm32(port);
if (stm32_port == NULL) {
return HAL_GPIO_PIN_RESET;
}
uint16_t stm32_pin = hal_gpio_pin_to_stm32(pin);
GPIO_PinState stm32_state = HAL_GPIO_ReadPin(stm32_port, stm32_pin);
return (stm32_state == GPIO_PIN_SET) ? HAL_GPIO_PIN_SET : HAL_GPIO_PIN_RESET;
/* Call architecture specific GPIO read implementation */
#if HAL_TARGET_ARCH == HAL_ARCH_STM32F1
return hal_stm32f1_gpio_read_pin(port, pin);
#elif HAL_TARGET_ARCH == HAL_ARCH_STM32F4
return hal_stm32f4_gpio_read_pin(port, pin);
#elif HAL_TARGET_ARCH == HAL_ARCH_STM32F7
return hal_stm32f7_gpio_read_pin(port, pin);
#elif HAL_TARGET_ARCH == HAL_ARCH_STM32L4
return hal_stm32l4_gpio_read_pin(port, pin);
#else
#error "Unsupported HAL architecture"
return HAL_GPIO_PIN_RESET;
#endif
}

125
HAL/Src/hal_spi.c Normal file
View File

@ -0,0 +1,125 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : hal_spi.c
* @brief : SPI hardware abstraction layer source file
******************************************************************************
*/
/* USER CODE END Header */
#include "hal.h"
#include "hal_spi.h"
#include "hal_stm32f4_spi.h"
/**
* @brief Initialize SPI hardware
* @param instance SPI instance identifier
* @param config SPI configuration structure
* @return true if initialization is successful, false otherwise
*/
bool hal_spi_init(hal_spi_instance_t instance, const hal_spi_config_t *config) {
/* Call architecture specific SPI initialization */
#if HAL_TARGET_ARCH == HAL_ARCH_STM32F1
return hal_stm32f1_spi_init(instance, config);
#elif HAL_TARGET_ARCH == HAL_ARCH_STM32F4
return hal_stm32f4_spi_init(instance, config);
#elif HAL_TARGET_ARCH == HAL_ARCH_STM32F7
return hal_stm32f7_spi_init(instance, config);
#elif HAL_TARGET_ARCH == HAL_ARCH_STM32L4
return hal_stm32l4_spi_init(instance, config);
#else
#error "Unsupported HAL architecture"
return false;
#endif
}
/**
* @brief Deinitialize SPI hardware
* @param instance SPI instance identifier
* @return true if deinitialization is successful, false otherwise
*/
bool hal_spi_deinit(hal_spi_instance_t instance) {
/* Call architecture specific SPI deinitialization */
#if HAL_TARGET_ARCH == HAL_ARCH_STM32F1
return hal_stm32f1_spi_deinit(instance);
#elif HAL_TARGET_ARCH == HAL_ARCH_STM32F4
return hal_stm32f4_spi_deinit(instance);
#elif HAL_TARGET_ARCH == HAL_ARCH_STM32F7
return hal_stm32f7_spi_deinit(instance);
#elif HAL_TARGET_ARCH == HAL_ARCH_STM32L4
return hal_stm32l4_spi_deinit(instance);
#else
#error "Unsupported HAL architecture"
return false;
#endif
}
/**
* @brief SPI transmit function
* @param instance SPI instance identifier
* @param p_data Pointer to data buffer to transmit
* @param size Size of data to transmit
* @return true if transmission is successful, false otherwise
*/
bool hal_spi_transmit(hal_spi_instance_t instance, const uint8_t *p_data, uint16_t size) {
/* Call architecture specific SPI transmit implementation */
#if HAL_TARGET_ARCH == HAL_ARCH_STM32F1
return hal_stm32f1_spi_transmit(instance, p_data, size);
#elif HAL_TARGET_ARCH == HAL_ARCH_STM32F4
return hal_stm32f4_spi_transmit(instance, p_data, size);
#elif HAL_TARGET_ARCH == HAL_ARCH_STM32F7
return hal_stm32f7_spi_transmit(instance, p_data, size);
#elif HAL_TARGET_ARCH == HAL_ARCH_STM32L4
return hal_stm32l4_spi_transmit(instance, p_data, size);
#else
#error "Unsupported HAL architecture"
return false;
#endif
}
/**
* @brief SPI receive function
* @param instance SPI instance identifier
* @param p_data Pointer to data buffer to receive
* @param size Size of data to receive
* @return true if reception is successful, false otherwise
*/
bool hal_spi_receive(hal_spi_instance_t instance, uint8_t *p_data, uint16_t size) {
/* Call architecture specific SPI receive implementation */
#if HAL_TARGET_ARCH == HAL_ARCH_STM32F1
return hal_stm32f1_spi_receive(instance, p_data, size);
#elif HAL_TARGET_ARCH == HAL_ARCH_STM32F4
return hal_stm32f4_spi_receive(instance, p_data, size);
#elif HAL_TARGET_ARCH == HAL_ARCH_STM32F7
return hal_stm32f7_spi_receive(instance, p_data, size);
#elif HAL_TARGET_ARCH == HAL_ARCH_STM32L4
return hal_stm32l4_spi_receive(instance, p_data, size);
#else
#error "Unsupported HAL architecture"
return false;
#endif
}
/**
* @brief SPI transmit and receive function
* @param instance SPI instance identifier
* @param p_tx_data Pointer to data buffer to transmit
* @param p_rx_data Pointer to data buffer to receive
* @param size Size of data to transmit/receive
* @return true if transmission and reception are successful, false otherwise
*/
bool hal_spi_transmit_receive(hal_spi_instance_t instance, const uint8_t *p_tx_data, uint8_t *p_rx_data, uint16_t size) {
/* Call architecture specific SPI transmit and receive implementation */
#if HAL_TARGET_ARCH == HAL_ARCH_STM32F1
return hal_stm32f1_spi_transmit_receive(instance, p_tx_data, p_rx_data, size);
#elif HAL_TARGET_ARCH == HAL_ARCH_STM32F4
return hal_stm32f4_spi_transmit_receive(instance, p_tx_data, p_rx_data, size);
#elif HAL_TARGET_ARCH == HAL_ARCH_STM32F7
return hal_stm32f7_spi_transmit_receive(instance, p_tx_data, p_rx_data, size);
#elif HAL_TARGET_ARCH == HAL_ARCH_STM32L4
return hal_stm32l4_spi_transmit_receive(instance, p_tx_data, p_rx_data, size);
#else
#error "Unsupported HAL architecture"
return false;
#endif
}

View File

@ -7,148 +7,128 @@
*/
/* USER CODE END Header */
#include "hal.h"
#include "hal_uart.h"
#include "stm32f4xx_hal.h"
#include "stm32f4xx_hal_uart.h"
/* UART handle */
static UART_HandleTypeDef huart1;
/**
* @brief Initialize UART hardware
*/
void hal_uart_init(void) {
/* UART initialization is handled by HAL_Init() */
/* Configure UART GPIO pins */
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* Enable UART clock */
__HAL_RCC_USART1_CLK_ENABLE();
/* Enable GPIO clocks */
__HAL_RCC_GPIOA_CLK_ENABLE();
/* Configure USART1 Tx (PA9) as alternate function push-pull */
GPIO_InitStruct.Pin = GPIO_PIN_9;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF7_USART1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* Configure USART1 Rx (PA10) as alternate function push-pull */
GPIO_InitStruct.Pin = GPIO_PIN_10;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF7_USART1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* Initialize UART */
huart1.Instance = USART1;
huart1.Init.BaudRate = 115200;
huart1.Init.WordLength = UART_WORDLENGTH_8B;
huart1.Init.StopBits = UART_STOPBITS_1;
huart1.Init.Parity = UART_PARITY_NONE;
huart1.Init.Mode = UART_MODE_TX_RX;
huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart1.Init.OverSampling = UART_OVERSAMPLING_16;
if (HAL_UART_Init(&huart1) != HAL_OK) {
/* Initialization Error */
while (1);
}
/* Call architecture specific UART initialization */
#if HAL_TARGET_ARCH == HAL_ARCH_STM32F1
hal_stm32f1_uart_init();
#elif HAL_TARGET_ARCH == HAL_ARCH_STM32F4
hal_stm32f4_uart_init();
#elif HAL_TARGET_ARCH == HAL_ARCH_STM32F7
hal_stm32f7_uart_init();
#elif HAL_TARGET_ARCH == HAL_ARCH_STM32L4
hal_stm32l4_uart_init();
#else
#error "Unsupported HAL architecture"
#endif
}
/**
* @brief Configure UART parameters
* @brief Configure UART parameters for specific instance
* @param config: UART configuration structure
*/
void hal_uart_config(const hal_uart_config_t *config) {
if (config == NULL) {
return;
}
/* Update UART configuration */
huart1.Init.BaudRate = config->baudrate;
/* Convert parity */
switch (config->parity) {
case HAL_UART_PARITY_NONE:
huart1.Init.Parity = UART_PARITY_NONE;
break;
case HAL_UART_PARITY_ODD:
huart1.Init.Parity = UART_PARITY_ODD;
break;
case HAL_UART_PARITY_EVEN:
huart1.Init.Parity = UART_PARITY_EVEN;
break;
default:
huart1.Init.Parity = UART_PARITY_NONE;
break;
}
/* Convert stop bits */
huart1.Init.StopBits = (config->stopbits == HAL_UART_STOPBITS_1) ?
UART_STOPBITS_1 : UART_STOPBITS_2;
/* Convert data bits */
huart1.Init.WordLength = (config->databits == HAL_UART_DATABITS_8) ?
UART_WORDLENGTH_8B : UART_WORDLENGTH_9B;
/* Re-initialize UART */
if (HAL_UART_Init(&huart1) != HAL_OK) {
/* Initialization Error */
while (1);
}
/* Call architecture specific UART configuration */
#if HAL_TARGET_ARCH == HAL_ARCH_STM32F1
hal_stm32f1_uart_config(config);
#elif HAL_TARGET_ARCH == HAL_ARCH_STM32F4
hal_stm32f4_uart_config(config);
#elif HAL_TARGET_ARCH == HAL_ARCH_STM32F7
hal_stm32f7_uart_config(config);
#elif HAL_TARGET_ARCH == HAL_ARCH_STM32L4
hal_stm32l4_uart_config(config);
#else
#error "Unsupported HAL architecture"
#endif
}
/**
* @brief Send data over UART
* @brief Send data over specific UART instance
* @param instance: UART instance identifier
* @param data: Pointer to data buffer
* @param length: Data length in bytes
*/
void hal_uart_send(const uint8_t *data, size_t length) {
if (data == NULL || length == 0) {
return;
}
HAL_UART_Transmit(&huart1, (uint8_t *)data, length, HAL_MAX_DELAY);
void hal_uart_send(hal_uart_instance_t instance, const uint8_t *data, size_t length) {
/* Call architecture specific UART send implementation */
#if HAL_TARGET_ARCH == HAL_ARCH_STM32F1
hal_stm32f1_uart_send(instance, data, length);
#elif HAL_TARGET_ARCH == HAL_ARCH_STM32F4
hal_stm32f4_uart_send(instance, data, length);
#elif HAL_TARGET_ARCH == HAL_ARCH_STM32F7
hal_stm32f7_uart_send(instance, data, length);
#elif HAL_TARGET_ARCH == HAL_ARCH_STM32L4
hal_stm32l4_uart_send(instance, data, length);
#else
#error "Unsupported HAL architecture"
#endif
}
/**
* @brief Receive data over UART
* @brief Receive data from specific UART instance
* @param instance: UART instance identifier
* @param data: Pointer to data buffer
* @param length: Data length to receive in bytes
* @retval Number of bytes received
*/
size_t hal_uart_receive(uint8_t *data, size_t length) {
if (data == NULL || length == 0) {
return 0;
}
HAL_StatusTypeDef status = HAL_UART_Receive(&huart1, data, length, HAL_MAX_DELAY);
if (status == HAL_OK) {
return length;
}
size_t hal_uart_receive(hal_uart_instance_t instance, uint8_t *data, size_t length) {
/* Call architecture specific UART receive implementation */
#if HAL_TARGET_ARCH == HAL_ARCH_STM32F1
return hal_stm32f1_uart_receive(instance, data, length);
#elif HAL_TARGET_ARCH == HAL_ARCH_STM32F4
return hal_stm32f4_uart_receive(instance, data, length);
#elif HAL_TARGET_ARCH == HAL_ARCH_STM32F7
return hal_stm32f7_uart_receive(instance, data, length);
#elif HAL_TARGET_ARCH == HAL_ARCH_STM32L4
return hal_stm32l4_uart_receive(instance, data, length);
#else
#error "Unsupported HAL architecture"
return 0;
#endif
}
/**
* @brief Check if UART is ready to send
* @brief Check if specific UART instance is ready to send
* @param instance: UART instance identifier
* @retval 1 if ready, 0 otherwise
*/
uint8_t hal_uart_is_tx_ready(void) {
return (HAL_UART_GetState(&huart1) == HAL_UART_STATE_READY) ? 1 : 0;
uint8_t hal_uart_is_tx_ready(hal_uart_instance_t instance) {
/* Call architecture specific UART TX ready check */
#if HAL_TARGET_ARCH == HAL_ARCH_STM32F1
return hal_stm32f1_uart_is_tx_ready(instance);
#elif HAL_TARGET_ARCH == HAL_ARCH_STM32F4
return hal_stm32f4_uart_is_tx_ready(instance);
#elif HAL_TARGET_ARCH == HAL_ARCH_STM32F7
return hal_stm32f7_uart_is_tx_ready(instance);
#elif HAL_TARGET_ARCH == HAL_ARCH_STM32L4
return hal_stm32l4_uart_is_tx_ready(instance);
#else
#error "Unsupported HAL architecture"
return 0;
#endif
}
/**
* @brief Check if UART has data to receive
* @brief Check if specific UART instance has data to receive
* @param instance: UART instance identifier
* @retval 1 if data available, 0 otherwise
*/
uint8_t hal_uart_is_rx_ready(void) {
return (HAL_UART_GetState(&huart1) == HAL_UART_STATE_READY) ? 1 : 0;
uint8_t hal_uart_is_rx_ready(hal_uart_instance_t instance) {
/* Call architecture specific UART RX ready check */
#if HAL_TARGET_ARCH == HAL_ARCH_STM32F1
return hal_stm32f1_uart_is_rx_ready(instance);
#elif HAL_TARGET_ARCH == HAL_ARCH_STM32F4
return hal_stm32f4_uart_is_rx_ready(instance);
#elif HAL_TARGET_ARCH == HAL_ARCH_STM32F7
return hal_stm32f7_uart_is_rx_ready(instance);
#elif HAL_TARGET_ARCH == HAL_ARCH_STM32L4
return hal_stm32l4_uart_is_rx_ready(instance);
#else
#error "Unsupported HAL architecture"
return 0;
#endif
}