351 lines
9.0 KiB
C
351 lines
9.0 KiB
C
/* USER CODE BEGIN Header */
|
|
/**
|
|
******************************************************************************
|
|
* @file : hal.c
|
|
* @brief : Hardware Abstraction Layer main source file
|
|
******************************************************************************
|
|
*/
|
|
/* USER CODE END Header */
|
|
|
|
#include "hal.h"
|
|
#include <string.h>
|
|
|
|
/**
|
|
* @brief HAL module registry
|
|
*/
|
|
static hal_module_config_t hal_module_registry[HAL_MODULE_MAX];
|
|
static uint32_t hal_module_count = 0;
|
|
|
|
/**
|
|
* @brief HAL error context
|
|
*/
|
|
static hal_error_context_t hal_error_ctx = {
|
|
.callback = NULL,
|
|
.error_count = 0,
|
|
.enabled = 1
|
|
};
|
|
|
|
/**
|
|
* @brief HAL module initialization
|
|
* @retval HAL status code
|
|
*/
|
|
hal_ret_t hal_init(void) {
|
|
hal_ret_t status = HAL_RET_OK;
|
|
|
|
/* Clear module registry */
|
|
memset(hal_module_registry, 0, sizeof(hal_module_registry));
|
|
hal_module_count = 0;
|
|
|
|
/* Initialize error handling system */
|
|
status = hal_error_init();
|
|
if (status != HAL_RET_OK) {
|
|
return status;
|
|
}
|
|
|
|
/* Call architecture specific initialization */
|
|
#if HAL_TARGET_ARCH == HAL_ARCH_STM32F1
|
|
hal_stm32f1_init();
|
|
#elif HAL_TARGET_ARCH == HAL_ARCH_STM32F4
|
|
hal_stm32f4_init();
|
|
#elif HAL_TARGET_ARCH == HAL_ARCH_STM32F7
|
|
hal_stm32f7_init();
|
|
#elif HAL_TARGET_ARCH == HAL_ARCH_STM32L4
|
|
hal_stm32l4_init();
|
|
#else
|
|
#error "Unsupported HAL architecture"
|
|
return HAL_RET_ERROR;
|
|
#endif
|
|
|
|
return HAL_RET_OK;
|
|
}
|
|
|
|
/**
|
|
* @brief Register a HAL module
|
|
* @param module_config: Module configuration
|
|
* @retval HAL status code
|
|
*/
|
|
hal_ret_t hal_module_register(const hal_module_config_t* module_config) {
|
|
if (module_config == NULL) {
|
|
return HAL_RET_INVALID_PARAM;
|
|
}
|
|
|
|
if (module_config->type >= HAL_MODULE_MAX) {
|
|
return HAL_RET_INVALID_PARAM;
|
|
}
|
|
|
|
/* Check if module already registered */
|
|
if (hal_module_registry[module_config->type].ops.init != NULL) {
|
|
return HAL_RET_RESOURCE_LOCKED;
|
|
}
|
|
|
|
/* Register the module */
|
|
memcpy(&hal_module_registry[module_config->type], module_config, sizeof(hal_module_config_t));
|
|
hal_module_count++;
|
|
|
|
return HAL_RET_OK;
|
|
}
|
|
|
|
/**
|
|
* @brief Initialize a specific HAL module
|
|
* @param module_type: Module type
|
|
* @param handle: HAL handle for the module
|
|
* @retval HAL status code
|
|
*/
|
|
hal_ret_t hal_module_init(hal_module_type_t module_type, hal_handle_t* handle) {
|
|
if (module_type >= HAL_MODULE_MAX || handle == NULL) {
|
|
return HAL_RET_INVALID_PARAM;
|
|
}
|
|
|
|
if (hal_module_registry[module_type].ops.init == NULL) {
|
|
return HAL_RET_NOT_SUPPORTED;
|
|
}
|
|
|
|
/* Initialize handle if not already initialized */
|
|
if (handle->status == HAL_PERIPH_STATE_RESET) {
|
|
HAL_HANDLE_INIT(handle);
|
|
handle->status = HAL_PERIPH_STATE_READY;
|
|
}
|
|
|
|
return hal_module_registry[module_type].ops.init(handle);
|
|
}
|
|
|
|
/**
|
|
* @brief Deinitialize a specific HAL module
|
|
* @param module_type: Module type
|
|
* @param handle: HAL handle for the module
|
|
* @retval HAL status code
|
|
*/
|
|
hal_ret_t hal_module_deinit(hal_module_type_t module_type, hal_handle_t* handle) {
|
|
if (module_type >= HAL_MODULE_MAX || handle == NULL) {
|
|
return HAL_RET_INVALID_PARAM;
|
|
}
|
|
|
|
if (hal_module_registry[module_type].ops.deinit == NULL) {
|
|
return HAL_RET_NOT_SUPPORTED;
|
|
}
|
|
|
|
hal_ret_t status = hal_module_registry[module_type].ops.deinit(handle);
|
|
if (status == HAL_RET_OK) {
|
|
handle->status = HAL_PERIPH_STATE_RESET;
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
/**
|
|
* @brief Configure a specific HAL module
|
|
* @param module_type: Module type
|
|
* @param handle: HAL handle for the module
|
|
* @param config: Module configuration data
|
|
* @retval HAL status code
|
|
*/
|
|
hal_ret_t hal_module_configure(hal_module_type_t module_type, hal_handle_t* handle, void* config) {
|
|
if (module_type >= HAL_MODULE_MAX || handle == NULL) {
|
|
return HAL_RET_INVALID_PARAM;
|
|
}
|
|
|
|
if (hal_module_registry[module_type].ops.configure == NULL) {
|
|
return HAL_RET_NOT_SUPPORTED;
|
|
}
|
|
|
|
return hal_module_registry[module_type].ops.configure(handle, config);
|
|
}
|
|
|
|
/**
|
|
* @brief Control a specific HAL module
|
|
* @param module_type: Module type
|
|
* @param handle: HAL handle for the module
|
|
* @param cmd: Control command
|
|
* @param param: Control parameter
|
|
* @retval HAL status code
|
|
*/
|
|
hal_ret_t hal_module_control(hal_module_type_t module_type, hal_handle_t* handle, uint32_t cmd, void* param) {
|
|
if (module_type >= HAL_MODULE_MAX || handle == NULL) {
|
|
return HAL_RET_INVALID_PARAM;
|
|
}
|
|
|
|
if (hal_module_registry[module_type].ops.control == NULL) {
|
|
return HAL_RET_NOT_SUPPORTED;
|
|
}
|
|
|
|
return hal_module_registry[module_type].ops.control(handle, cmd, param);
|
|
}
|
|
|
|
/**
|
|
* @brief Get status of a specific HAL module
|
|
* @param module_type: Module type
|
|
* @param handle: HAL handle for the module
|
|
* @param status: Pointer to store module status
|
|
* @retval HAL status code
|
|
*/
|
|
hal_ret_t hal_module_get_status(hal_module_type_t module_type, hal_handle_t* handle, uint32_t* status) {
|
|
if (module_type >= HAL_MODULE_MAX || handle == NULL || status == NULL) {
|
|
return HAL_RET_INVALID_PARAM;
|
|
}
|
|
|
|
if (hal_module_registry[module_type].ops.get_status == NULL) {
|
|
return HAL_RET_NOT_SUPPORTED;
|
|
}
|
|
|
|
return hal_module_registry[module_type].ops.get_status(handle, status);
|
|
}
|
|
|
|
/**
|
|
* @brief Get default configuration for a module
|
|
* @param module_type: Module type
|
|
* @return Pointer to default configuration, or NULL if not available
|
|
*/
|
|
void* hal_module_get_default_config(hal_module_type_t module_type) {
|
|
if (module_type >= HAL_MODULE_MAX) {
|
|
return NULL;
|
|
}
|
|
|
|
return hal_module_registry[module_type].default_config;
|
|
}
|
|
|
|
/**
|
|
* @brief Get HAL version information
|
|
* @param major: Pointer to store major version
|
|
* @param minor: Pointer to store minor version
|
|
* @param patch: Pointer to store patch version
|
|
* @retval HAL status code
|
|
*/
|
|
hal_ret_t hal_get_version(uint8_t* major, uint8_t* minor, uint8_t* patch) {
|
|
if (major == NULL || minor == NULL || patch == NULL) {
|
|
return HAL_RET_INVALID_PARAM;
|
|
}
|
|
|
|
*major = HAL_VERSION_MAJOR;
|
|
*minor = HAL_VERSION_MINOR;
|
|
*patch = HAL_VERSION_PATCH;
|
|
|
|
return HAL_RET_OK;
|
|
}
|
|
|
|
/**
|
|
* @brief Get HAL version string
|
|
* @retval Version string
|
|
*/
|
|
const char* hal_get_version_string(void) {
|
|
return HAL_VERSION_STRING;
|
|
}
|
|
|
|
/**
|
|
* @brief Get HAL module count
|
|
* @retval Number of registered HAL modules
|
|
*/
|
|
uint32_t hal_get_module_count(void) {
|
|
return hal_module_count;
|
|
}
|
|
|
|
/**
|
|
* @brief Get HAL module configuration
|
|
* @param module_type: Module type
|
|
* @retval Pointer to module configuration, or NULL if not found
|
|
*/
|
|
const hal_module_config_t* hal_get_module_config(hal_module_type_t module_type) {
|
|
if (module_type >= HAL_MODULE_MAX) {
|
|
return NULL;
|
|
}
|
|
|
|
if (hal_module_registry[module_type].ops.init == NULL) {
|
|
return NULL;
|
|
}
|
|
|
|
return &hal_module_registry[module_type];
|
|
}
|
|
|
|
/**
|
|
* @brief Initialize HAL error handling system
|
|
* @retval HAL status code
|
|
*/
|
|
hal_ret_t hal_error_init(void) {
|
|
memset(&hal_error_ctx.last_error, 0, sizeof(hal_error_t));
|
|
hal_error_ctx.error_count = 0;
|
|
hal_error_ctx.enabled = 1;
|
|
hal_error_ctx.callback = NULL;
|
|
return HAL_RET_OK;
|
|
}
|
|
|
|
/**
|
|
* @brief Deinitialize HAL error handling system
|
|
* @retval HAL status code
|
|
*/
|
|
hal_ret_t hal_error_deinit(void) {
|
|
hal_error_ctx.enabled = 0;
|
|
hal_error_ctx.callback = NULL;
|
|
return HAL_RET_OK;
|
|
}
|
|
|
|
/**
|
|
* @brief Register an error callback function
|
|
* @param callback: Error callback function
|
|
* @retval HAL status code
|
|
*/
|
|
hal_ret_t hal_error_register_callback(hal_error_callback_t callback) {
|
|
hal_error_ctx.callback = callback;
|
|
return HAL_RET_OK;
|
|
}
|
|
|
|
/**
|
|
* @brief Record an error
|
|
* @param error: Pointer to error information
|
|
* @retval HAL status code
|
|
*/
|
|
hal_ret_t hal_error_record(const hal_error_t* error) {
|
|
if (error == NULL) {
|
|
return HAL_RET_INVALID_PARAM;
|
|
}
|
|
|
|
if (!hal_error_ctx.enabled) {
|
|
return HAL_RET_OK;
|
|
}
|
|
|
|
/* Copy error information */
|
|
memcpy(&hal_error_ctx.last_error, error, sizeof(hal_error_t));
|
|
hal_error_ctx.error_count++;
|
|
|
|
/* Call error callback if registered */
|
|
if (hal_error_ctx.callback != NULL) {
|
|
hal_error_ctx.callback(error);
|
|
}
|
|
|
|
return HAL_RET_OK;
|
|
}
|
|
|
|
/**
|
|
* @brief Get last error information
|
|
* @retval Pointer to last error information
|
|
*/
|
|
const hal_error_t* hal_error_get_last(void) {
|
|
return &hal_error_ctx.last_error;
|
|
}
|
|
|
|
/**
|
|
* @brief Get total error count
|
|
* @retval Total error count
|
|
*/
|
|
uint32_t hal_error_get_count(void) {
|
|
return hal_error_ctx.error_count;
|
|
}
|
|
|
|
/**
|
|
* @brief Clear error information
|
|
* @retval HAL status code
|
|
*/
|
|
hal_ret_t hal_error_clear(void) {
|
|
memset(&hal_error_ctx.last_error, 0, sizeof(hal_error_t));
|
|
hal_error_ctx.error_count = 0;
|
|
return HAL_RET_OK;
|
|
}
|
|
|
|
/**
|
|
* @brief Enable/disable error logging
|
|
* @param enable: Enable flag (1 to enable, 0 to disable)
|
|
* @retval HAL status code
|
|
*/
|
|
hal_ret_t hal_error_enable(uint8_t enable) {
|
|
hal_error_ctx.enabled = enable;
|
|
return HAL_RET_OK;
|
|
}
|