/* 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>
#include "hal.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
 * @retval HAL status code
 */
hal_ret_t hal_spi_init(hal_spi_instance_t instance, const hal_spi_config_t *config);

/**
 * @brief Deinitialize SPI hardware
 * @param instance SPI instance identifier
 * @retval HAL status code
 */
hal_ret_t 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
 * @retval HAL status code
 */
hal_ret_t 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
 * @retval HAL status code
 */
hal_ret_t 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
 * @retval HAL status code
 */
hal_ret_t 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 */
