/* USER CODE BEGIN Header */ /** ****************************************************************************** * @file : hal.c * @brief : Hardware Abstraction Layer main source file ****************************************************************************** */ /* USER CODE END Header */ #include "hal.h" #include /** * @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; }