/* 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
 * @retval HAL status code
 */
hal_ret_t hal_spi_init(hal_spi_instance_t instance, const hal_spi_config_t *config) {
    if (config == NULL) {
        return HAL_RET_INVALID_PARAM;
    }
    
    if (instance >= HAL_SPI_INSTANCE_MAX) {
        return HAL_RET_INVALID_PARAM;
    }
    
    /* Call architecture specific SPI initialization */
#if HAL_TARGET_ARCH == HAL_ARCH_STM32F1
    return hal_stm32f1_spi_init(instance, config) ? HAL_RET_OK : HAL_RET_ERROR;
#elif HAL_TARGET_ARCH == HAL_ARCH_STM32F4
    return hal_stm32f4_spi_init(instance, config) ? HAL_RET_OK : HAL_RET_ERROR;
#elif HAL_TARGET_ARCH == HAL_ARCH_STM32F7
    return hal_stm32f7_spi_init(instance, config) ? HAL_OK : HAL_ERROR;
#elif HAL_TARGET_ARCH == HAL_ARCH_STM32L4
    return hal_stm32l4_spi_init(instance, config) ? HAL_OK : HAL_ERROR;
#else
#error "Unsupported HAL architecture"
    return HAL_RET_ERROR;
#endif
}

/**
 * @brief Deinitialize SPI hardware
 * @param instance SPI instance identifier
 * @retval HAL status code
 */
hal_ret_t hal_spi_deinit(hal_spi_instance_t instance) {
    if (instance >= HAL_SPI_INSTANCE_MAX) {
        return HAL_RET_INVALID_PARAM;
    }
    
    /* Call architecture specific SPI deinitialization */
#if HAL_TARGET_ARCH == HAL_ARCH_STM32F1
    return hal_stm32f1_spi_deinit(instance) ? HAL_OK : HAL_ERROR;
#elif HAL_TARGET_ARCH == HAL_ARCH_STM32F4
    return hal_stm32f4_spi_deinit(instance) ? HAL_RET_OK : HAL_RET_ERROR;
#elif HAL_TARGET_ARCH == HAL_ARCH_STM32F7
    return hal_stm32f7_spi_deinit(instance) ? HAL_OK : HAL_ERROR;
#elif HAL_TARGET_ARCH == HAL_ARCH_STM32L4
    return hal_stm32l4_spi_deinit(instance) ? HAL_OK : HAL_ERROR;
#else
#error "Unsupported HAL architecture"
    return HAL_RET_ERROR;
#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
 * @retval HAL status code
 */
hal_ret_t hal_spi_transmit(hal_spi_instance_t instance, const uint8_t *p_data, uint16_t size) {
    if (p_data == NULL || size == 0) {
        return HAL_RET_INVALID_PARAM;
    }
    
    if (instance >= HAL_SPI_INSTANCE_MAX) {
        return HAL_RET_INVALID_PARAM;
    }
    
    /* Call architecture specific SPI transmit implementation */
#if HAL_TARGET_ARCH == HAL_ARCH_STM32F1
    return hal_stm32f1_spi_transmit(instance, p_data, size) ? HAL_OK : HAL_ERROR;
#elif HAL_TARGET_ARCH == HAL_ARCH_STM32F4
    return hal_stm32f4_spi_transmit(instance, p_data, size) ? HAL_RET_OK : HAL_RET_ERROR;
#elif HAL_TARGET_ARCH == HAL_ARCH_STM32F7
    return hal_stm32f7_spi_transmit(instance, p_data, size) ? HAL_OK : HAL_ERROR;
#elif HAL_TARGET_ARCH == HAL_ARCH_STM32L4
    return hal_stm32l4_spi_transmit(instance, p_data, size) ? HAL_OK : HAL_ERROR;
#else
#error "Unsupported HAL architecture"
    return HAL_RET_ERROR;
#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
 * @retval HAL status code
 */
hal_ret_t hal_spi_receive(hal_spi_instance_t instance, uint8_t *p_data, uint16_t size) {
    if (p_data == NULL || size == 0) {
        return HAL_RET_INVALID_PARAM;
    }
    
    if (instance >= HAL_SPI_INSTANCE_MAX) {
        return HAL_RET_INVALID_PARAM;
    }
    
    /* Call architecture specific SPI receive implementation */
#if HAL_TARGET_ARCH == HAL_ARCH_STM32F1
    return hal_stm32f1_spi_receive(instance, p_data, size) ? HAL_OK : HAL_ERROR;
#elif HAL_TARGET_ARCH == HAL_ARCH_STM32F4
    return hal_stm32f4_spi_receive(instance, p_data, size) ? HAL_RET_OK : HAL_RET_ERROR;
#elif HAL_TARGET_ARCH == HAL_ARCH_STM32F7
    return hal_stm32f7_spi_receive(instance, p_data, size) ? HAL_OK : HAL_ERROR;
#elif HAL_TARGET_ARCH == HAL_ARCH_STM32L4
    return hal_stm32l4_spi_receive(instance, p_data, size) ? HAL_OK : HAL_ERROR;
#else
#error "Unsupported HAL architecture"
    return HAL_RET_ERROR;
#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
 * @retval HAL status code
 */
hal_ret_t hal_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 HAL_RET_INVALID_PARAM;
    }
    
    if (instance >= HAL_SPI_INSTANCE_MAX) {
        return HAL_RET_INVALID_PARAM;
    }
    
    /* 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) ? HAL_OK : HAL_ERROR;
#elif HAL_TARGET_ARCH == HAL_ARCH_STM32F4
    return hal_stm32f4_spi_transmit_receive(instance, p_tx_data, p_rx_data, size) ? HAL_RET_OK : HAL_RET_ERROR;
#elif HAL_TARGET_ARCH == HAL_ARCH_STM32F7
    return hal_stm32f7_spi_transmit_receive(instance, p_tx_data, p_rx_data, size) ? HAL_OK : HAL_ERROR;
#elif HAL_TARGET_ARCH == HAL_ARCH_STM32L4
    return hal_stm32l4_spi_transmit_receive(instance, p_tx_data, p_rx_data, size) ? HAL_OK : HAL_ERROR;
#else
#error "Unsupported HAL architecture"
    return HAL_RET_ERROR;
#endif
}