Index: ctrl/firmware/Main/CubeMX/Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_spi.h
===================================================================
--- ctrl/firmware/Main/CubeMX/Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_spi.h	(revision 45)
+++ ctrl/firmware/Main/CubeMX/Drivers/STM32H7xx_HAL_Driver/Inc/stm32h7xx_hal_spi.h	(revision 45)
@@ -0,0 +1,1130 @@
+/**
+  ******************************************************************************
+  * @file    stm32h7xx_hal_spi.h
+  * @author  MCD Application Team
+  * @brief   Header file of SPI HAL module.
+  ******************************************************************************
+  * @attention
+  *
+  * Copyright (c) 2017 STMicroelectronics.
+  * All rights reserved.
+  *
+  * This software is licensed under terms that can be found in the LICENSE file
+  * in the root directory of this software component.
+  * If no LICENSE file comes with this software, it is provided AS-IS.
+  *
+  ******************************************************************************
+  */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef STM32H7xx_HAL_SPI_H
+#define STM32H7xx_HAL_SPI_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32h7xx_hal_def.h"
+
+/** @addtogroup STM32H7xx_HAL_Driver
+  * @{
+  */
+
+/** @addtogroup SPI
+  * @{
+  */
+
+/* Exported types ------------------------------------------------------------*/
+/** @defgroup SPI_Exported_Types SPI Exported Types
+  * @{
+  */
+
+/**
+  * @brief  SPI Configuration Structure definition
+  */
+typedef struct
+{
+  uint32_t Mode;                              /*!< Specifies the SPI operating mode.
+                                                     This parameter can be a value of @ref SPI_Mode */
+
+  uint32_t Direction;                         /*!< Specifies the SPI bidirectional mode state.
+                                                     This parameter can be a value of @ref SPI_Direction */
+
+  uint32_t DataSize;                          /*!< Specifies the SPI data size.
+                                                     This parameter can be a value of @ref SPI_Data_Size */
+
+  uint32_t CLKPolarity;                       /*!< Specifies the serial clock steady state.
+                                                     This parameter can be a value of @ref SPI_Clock_Polarity */
+
+  uint32_t CLKPhase;                          /*!< Specifies the clock active edge for the bit capture.
+                                                     This parameter can be a value of @ref SPI_Clock_Phase */
+
+  uint32_t NSS;                               /*!< Specifies whether the NSS signal is managed by
+                                                     hardware (NSS pin) or by software using the SSI bit.
+                                                     This parameter can be a value of
+                                                     @ref SPI_Slave_Select_Management */
+
+  uint32_t BaudRatePrescaler;                 /*!< Specifies the Baud Rate prescaler value which will be
+                                                     used to configure the transmit and receive SCK clock.
+                                                     This parameter can be a value of @ref SPI_BaudRate_Prescaler
+                                                     @note The communication clock is derived from the master
+                                                     clock. The slave clock does not need to be set. */
+
+  uint32_t FirstBit;                          /*!< Specifies whether data transfers start from MSB or LSB bit.
+                                                     This parameter can be a value of @ref SPI_MSB_LSB_Transmission */
+
+  uint32_t TIMode;                            /*!< Specifies if the TI mode is enabled or not.
+                                                     This parameter can be a value of @ref SPI_TI_Mode */
+
+  uint32_t CRCCalculation;                    /*!< Specifies if the CRC calculation is enabled or not.
+                                                     This parameter can be a value of @ref SPI_CRC_Calculation */
+
+  uint32_t CRCPolynomial;                     /*!< Specifies the polynomial used for the CRC calculation.
+                                                     This parameter must be an odd number between
+                                                     Min_Data = 0 and Max_Data = 65535 */
+
+  uint32_t CRCLength;                         /*!< Specifies the CRC Length used for the CRC calculation.
+                                                     This parameter can be a value of @ref SPI_CRC_length */
+
+  uint32_t NSSPMode;                          /*!< Specifies whether the NSSP signal is enabled or not .
+                                                     This parameter can be a value of @ref SPI_NSSP_Mode
+                                                     This mode is activated by the SSOM bit in the SPIx_CR2 register
+                                                     and it takes effect only if the SPI interface is configured
+                                                     as Motorola SPI master (FRF=0). */
+
+  uint32_t NSSPolarity;                       /*!< Specifies which level of SS input/output external signal
+                                                     (present on SS pin) is considered as active one.
+                                                     This parameter can be a value of @ref SPI_NSS_Polarity */
+
+  uint32_t FifoThreshold;                     /*!< Specifies the FIFO threshold level.
+                                                     This parameter can be a value of @ref SPI_Fifo_Threshold */
+
+  uint32_t TxCRCInitializationPattern;        /*!< Specifies the transmitter CRC initialization Pattern used for
+                                                     the CRC calculation. This parameter can be a value of
+                                                     @ref SPI_CRC_Calculation_Initialization_Pattern */
+
+  uint32_t RxCRCInitializationPattern;        /*!< Specifies the receiver CRC initialization Pattern used for
+                                                     the CRC calculation. This parameter can be a value of
+                                                     @ref SPI_CRC_Calculation_Initialization_Pattern */
+
+  uint32_t MasterSSIdleness;                  /*!< Specifies an extra delay, expressed in number of SPI clock cycle
+                                                     periods, inserted additionally between active edge of SS
+                                                     and first data transaction start in master mode.
+                                                     This parameter can be a value of @ref SPI_Master_SS_Idleness */
+
+  uint32_t MasterInterDataIdleness;           /*!< Specifies minimum time delay (expressed in SPI clock cycles periods)
+                                                     inserted between two consecutive data frames in master mode.
+                                                     This parameter can be a value of
+                                                     @ref SPI_Master_InterData_Idleness */
+
+  uint32_t MasterReceiverAutoSusp;            /*!< Control continuous SPI transfer in master receiver mode
+                                                     and automatic management in order to avoid overrun condition.
+                                                     This parameter can be a value of @ref SPI_Master_RX_AutoSuspend*/
+
+  uint32_t MasterKeepIOState;                 /*!< Control of Alternate function GPIOs state
+                                                     This parameter can be a value of @ref SPI_Master_Keep_IO_State */
+
+  uint32_t IOSwap;                            /*!< Invert MISO/MOSI alternate functions
+                                                     This parameter can be a value of @ref SPI_IO_Swap */
+} SPI_InitTypeDef;
+
+/**
+  * @brief  HAL SPI State structure definition
+  */
+typedef enum
+{
+  HAL_SPI_STATE_RESET      = 0x00UL,    /*!< Peripheral not Initialized                         */
+  HAL_SPI_STATE_READY      = 0x01UL,    /*!< Peripheral Initialized and ready for use           */
+  HAL_SPI_STATE_BUSY       = 0x02UL,    /*!< an internal process is ongoing                     */
+  HAL_SPI_STATE_BUSY_TX    = 0x03UL,    /*!< Data Transmission process is ongoing               */
+  HAL_SPI_STATE_BUSY_RX    = 0x04UL,    /*!< Data Reception process is ongoing                  */
+  HAL_SPI_STATE_BUSY_TX_RX = 0x05UL,    /*!< Data Transmission and Reception process is ongoing */
+  HAL_SPI_STATE_ERROR      = 0x06UL,    /*!< SPI error state                                    */
+  HAL_SPI_STATE_ABORT      = 0x07UL     /*!< SPI abort is ongoing                               */
+} HAL_SPI_StateTypeDef;
+
+#if defined(USE_SPI_RELOAD_TRANSFER)
+/**
+  * @brief  SPI Reload Structure definition
+  */
+typedef struct
+{
+  const uint8_t              *pTxBuffPtr;                  /*!< Pointer to SPI Tx transfer Buffer        */
+
+  uint16_t                   TxXferSize;                   /*!< SPI Tx Transfer size to reload           */
+
+  uint8_t                    *pRxBuffPtr;                  /*!< Pointer to SPI Rx transfer Buffer        */
+
+  uint16_t                   RxXferSize;                   /*!< SPI Rx Transfer size to reload           */
+
+  uint32_t                   Requested;                    /*!< SPI reload request                       */
+
+} SPI_ReloadTypeDef;
+#endif /* USE_SPI_RELOAD_TRANSFER */
+
+/**
+  * @brief  SPI handle Structure definition
+  */
+typedef struct __SPI_HandleTypeDef
+{
+  SPI_TypeDef                *Instance;                    /*!< SPI registers base address               */
+
+  SPI_InitTypeDef            Init;                         /*!< SPI communication parameters             */
+
+  const uint8_t              *pTxBuffPtr;                  /*!< Pointer to SPI Tx transfer Buffer        */
+
+  uint16_t                   TxXferSize;                   /*!< SPI Tx Transfer size                     */
+
+  __IO uint16_t              TxXferCount;                  /*!< SPI Tx Transfer Counter                  */
+
+  uint8_t                    *pRxBuffPtr;                  /*!< Pointer to SPI Rx transfer Buffer        */
+
+  uint16_t                   RxXferSize;                   /*!< SPI Rx Transfer size                     */
+
+  __IO uint16_t              RxXferCount;                  /*!< SPI Rx Transfer Counter                  */
+
+  uint32_t                   CRCSize;                      /*!< SPI CRC size used for the transfer       */
+
+  void (*RxISR)(struct __SPI_HandleTypeDef *hspi);         /*!< function pointer on Rx ISR               */
+
+  void (*TxISR)(struct __SPI_HandleTypeDef *hspi);         /*!< function pointer on Tx ISR               */
+
+  DMA_HandleTypeDef          *hdmatx;                      /*!< SPI Tx DMA Handle parameters             */
+
+  DMA_HandleTypeDef          *hdmarx;                      /*!< SPI Rx DMA Handle parameters             */
+
+  HAL_LockTypeDef            Lock;                         /*!< Locking object                           */
+
+  __IO HAL_SPI_StateTypeDef  State;                        /*!< SPI communication state                  */
+
+  __IO uint32_t              ErrorCode;                    /*!< SPI Error code                           */
+
+#if defined(USE_SPI_RELOAD_TRANSFER)
+
+  SPI_ReloadTypeDef          Reload;                       /*!< SPI reload parameters                    */
+
+#endif /* USE_SPI_RELOAD_TRANSFER */
+
+#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1UL)
+  void (* TxCpltCallback)(struct __SPI_HandleTypeDef *hspi);       /*!< SPI Tx Completed callback          */
+  void (* RxCpltCallback)(struct __SPI_HandleTypeDef *hspi);       /*!< SPI Rx Completed callback          */
+  void (* TxRxCpltCallback)(struct __SPI_HandleTypeDef *hspi);     /*!< SPI TxRx Completed callback        */
+  void (* TxHalfCpltCallback)(struct __SPI_HandleTypeDef *hspi);   /*!< SPI Tx Half Completed callback     */
+  void (* RxHalfCpltCallback)(struct __SPI_HandleTypeDef *hspi);   /*!< SPI Rx Half Completed callback     */
+  void (* TxRxHalfCpltCallback)(struct __SPI_HandleTypeDef *hspi); /*!< SPI TxRx Half Completed callback   */
+  void (* ErrorCallback)(struct __SPI_HandleTypeDef *hspi);        /*!< SPI Error callback                 */
+  void (* AbortCpltCallback)(struct __SPI_HandleTypeDef *hspi);    /*!< SPI Abort callback                 */
+  void (* SuspendCallback)(struct __SPI_HandleTypeDef *hspi);      /*!< SPI Suspend callback               */
+  void (* MspInitCallback)(struct __SPI_HandleTypeDef *hspi);      /*!< SPI Msp Init callback              */
+  void (* MspDeInitCallback)(struct __SPI_HandleTypeDef *hspi);    /*!< SPI Msp DeInit callback            */
+
+#endif  /* USE_HAL_SPI_REGISTER_CALLBACKS */
+} SPI_HandleTypeDef;
+
+#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1UL)
+/**
+  * @brief  HAL SPI Callback ID enumeration definition
+  */
+typedef enum
+{
+  HAL_SPI_TX_COMPLETE_CB_ID             = 0x00UL,    /*!< SPI Tx Completed callback ID         */
+  HAL_SPI_RX_COMPLETE_CB_ID             = 0x01UL,    /*!< SPI Rx Completed callback ID         */
+  HAL_SPI_TX_RX_COMPLETE_CB_ID          = 0x02UL,    /*!< SPI TxRx Completed callback ID       */
+  HAL_SPI_TX_HALF_COMPLETE_CB_ID        = 0x03UL,    /*!< SPI Tx Half Completed callback ID    */
+  HAL_SPI_RX_HALF_COMPLETE_CB_ID        = 0x04UL,    /*!< SPI Rx Half Completed callback ID    */
+  HAL_SPI_TX_RX_HALF_COMPLETE_CB_ID     = 0x05UL,    /*!< SPI TxRx Half Completed callback ID  */
+  HAL_SPI_ERROR_CB_ID                   = 0x06UL,    /*!< SPI Error callback ID                */
+  HAL_SPI_ABORT_CB_ID                   = 0x07UL,    /*!< SPI Abort callback ID                */
+  HAL_SPI_SUSPEND_CB_ID                 = 0x08UL,    /*!< SPI Suspend callback ID              */
+  HAL_SPI_MSPINIT_CB_ID                 = 0x09UL,    /*!< SPI Msp Init callback ID             */
+  HAL_SPI_MSPDEINIT_CB_ID               = 0x0AUL     /*!< SPI Msp DeInit callback ID           */
+
+} HAL_SPI_CallbackIDTypeDef;
+
+/**
+  * @brief  HAL SPI Callback pointer definition
+  */
+typedef  void (*pSPI_CallbackTypeDef)(SPI_HandleTypeDef *hspi); /*!< pointer to an SPI callback function */
+
+#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
+/**
+  * @}
+  */
+
+/* Exported constants --------------------------------------------------------*/
+
+/** @defgroup SPI_Exported_Constants SPI Exported Constants
+  * @{
+  */
+
+/** @defgroup SPI_FIFO_Type SPI FIFO Type
+  * @{
+  */
+#define SPI_LOWEND_FIFO_SIZE                          8UL
+#define SPI_HIGHEND_FIFO_SIZE                         16UL
+/**
+  * @}
+  */
+
+/** @defgroup SPI_Error_Code SPI Error Codes
+  * @{
+  */
+#define HAL_SPI_ERROR_NONE                            (0x00000000UL)   /*!< No error                               */
+#define HAL_SPI_ERROR_MODF                            (0x00000001UL)   /*!< MODF error                             */
+#define HAL_SPI_ERROR_CRC                             (0x00000002UL)   /*!< CRC error                              */
+#define HAL_SPI_ERROR_OVR                             (0x00000004UL)   /*!< OVR error                              */
+#define HAL_SPI_ERROR_FRE                             (0x00000008UL)   /*!< FRE error                              */
+#define HAL_SPI_ERROR_DMA                             (0x00000010UL)   /*!< DMA transfer error                     */
+#define HAL_SPI_ERROR_FLAG                            (0x00000020UL)   /*!< Error on RXP/TXP/DXP/FTLVL/FRLVL Flag  */
+#define HAL_SPI_ERROR_ABORT                           (0x00000040UL)   /*!< Error during SPI Abort procedure       */
+#define HAL_SPI_ERROR_UDR                             (0x00000080UL)   /*!< Underrun error                         */
+#define HAL_SPI_ERROR_TIMEOUT                         (0x00000100UL)   /*!< Timeout error                          */
+#define HAL_SPI_ERROR_UNKNOW                          (0x00000200UL)   /*!< Unknown error                          */
+#define HAL_SPI_ERROR_NOT_SUPPORTED                   (0x00000400UL)   /*!< Requested operation not supported      */
+#define HAL_SPI_ERROR_RELOAD                          (0x00000800UL)   /*!< Reload error                           */
+#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1UL)
+#define HAL_SPI_ERROR_INVALID_CALLBACK                (0x00001000UL)   /*!< Invalid Callback error                 */
+#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
+/**
+  * @}
+  */
+
+/** @defgroup SPI_Mode SPI Mode
+  * @{
+  */
+#define SPI_MODE_SLAVE                                (0x00000000UL)
+#define SPI_MODE_MASTER                               SPI_CFG2_MASTER
+/**
+  * @}
+  */
+
+/** @defgroup SPI_Direction SPI Direction Mode
+  * @{
+  */
+#define SPI_DIRECTION_2LINES                          (0x00000000UL)
+#define SPI_DIRECTION_2LINES_TXONLY                   SPI_CFG2_COMM_0
+#define SPI_DIRECTION_2LINES_RXONLY                   SPI_CFG2_COMM_1
+#define SPI_DIRECTION_1LINE                           SPI_CFG2_COMM
+/**
+  * @}
+  */
+
+/** @defgroup SPI_Data_Size SPI Data Size
+  * @{
+  */
+#define SPI_DATASIZE_4BIT                             (0x00000003UL)
+#define SPI_DATASIZE_5BIT                             (0x00000004UL)
+#define SPI_DATASIZE_6BIT                             (0x00000005UL)
+#define SPI_DATASIZE_7BIT                             (0x00000006UL)
+#define SPI_DATASIZE_8BIT                             (0x00000007UL)
+#define SPI_DATASIZE_9BIT                             (0x00000008UL)
+#define SPI_DATASIZE_10BIT                            (0x00000009UL)
+#define SPI_DATASIZE_11BIT                            (0x0000000AUL)
+#define SPI_DATASIZE_12BIT                            (0x0000000BUL)
+#define SPI_DATASIZE_13BIT                            (0x0000000CUL)
+#define SPI_DATASIZE_14BIT                            (0x0000000DUL)
+#define SPI_DATASIZE_15BIT                            (0x0000000EUL)
+#define SPI_DATASIZE_16BIT                            (0x0000000FUL)
+#define SPI_DATASIZE_17BIT                            (0x00000010UL)
+#define SPI_DATASIZE_18BIT                            (0x00000011UL)
+#define SPI_DATASIZE_19BIT                            (0x00000012UL)
+#define SPI_DATASIZE_20BIT                            (0x00000013UL)
+#define SPI_DATASIZE_21BIT                            (0x00000014UL)
+#define SPI_DATASIZE_22BIT                            (0x00000015UL)
+#define SPI_DATASIZE_23BIT                            (0x00000016UL)
+#define SPI_DATASIZE_24BIT                            (0x00000017UL)
+#define SPI_DATASIZE_25BIT                            (0x00000018UL)
+#define SPI_DATASIZE_26BIT                            (0x00000019UL)
+#define SPI_DATASIZE_27BIT                            (0x0000001AUL)
+#define SPI_DATASIZE_28BIT                            (0x0000001BUL)
+#define SPI_DATASIZE_29BIT                            (0x0000001CUL)
+#define SPI_DATASIZE_30BIT                            (0x0000001DUL)
+#define SPI_DATASIZE_31BIT                            (0x0000001EUL)
+#define SPI_DATASIZE_32BIT                            (0x0000001FUL)
+/**
+  * @}
+  */
+
+/** @defgroup SPI_Clock_Polarity SPI Clock Polarity
+  * @{
+  */
+#define SPI_POLARITY_LOW                              (0x00000000UL)
+#define SPI_POLARITY_HIGH                             SPI_CFG2_CPOL
+/**
+  * @}
+  */
+
+/** @defgroup SPI_Clock_Phase SPI Clock Phase
+  * @{
+  */
+#define SPI_PHASE_1EDGE                               (0x00000000UL)
+#define SPI_PHASE_2EDGE                               SPI_CFG2_CPHA
+/**
+  * @}
+  */
+
+/** @defgroup SPI_Slave_Select_Management SPI Slave Select Management
+  * @{
+  */
+#define SPI_NSS_SOFT                                  SPI_CFG2_SSM
+#define SPI_NSS_HARD_INPUT                            (0x00000000UL)
+#define SPI_NSS_HARD_OUTPUT                           SPI_CFG2_SSOE
+/**
+  * @}
+  */
+
+/** @defgroup SPI_NSSP_Mode SPI NSS Pulse Mode
+  * @{
+  */
+#define SPI_NSS_PULSE_DISABLE                         (0x00000000UL)
+#define SPI_NSS_PULSE_ENABLE                          SPI_CFG2_SSOM
+/**
+  * @}
+  */
+
+/** @defgroup SPI_BaudRate_Prescaler SPI BaudRate Prescaler
+  * @{
+  */
+#define SPI_BAUDRATEPRESCALER_2                       (0x00000000UL)
+#define SPI_BAUDRATEPRESCALER_4                       (0x10000000UL)
+#define SPI_BAUDRATEPRESCALER_8                       (0x20000000UL)
+#define SPI_BAUDRATEPRESCALER_16                      (0x30000000UL)
+#define SPI_BAUDRATEPRESCALER_32                      (0x40000000UL)
+#define SPI_BAUDRATEPRESCALER_64                      (0x50000000UL)
+#define SPI_BAUDRATEPRESCALER_128                     (0x60000000UL)
+#define SPI_BAUDRATEPRESCALER_256                     (0x70000000UL)
+/**
+  * @}
+  */
+
+/** @defgroup SPI_MSB_LSB_Transmission SPI MSB LSB Transmission
+  * @{
+  */
+#define SPI_FIRSTBIT_MSB                              (0x00000000UL)
+#define SPI_FIRSTBIT_LSB                              SPI_CFG2_LSBFRST
+/**
+  * @}
+  */
+
+/** @defgroup SPI_TI_Mode SPI TI Mode
+  * @{
+  */
+#define SPI_TIMODE_DISABLE                            (0x00000000UL)
+#define SPI_TIMODE_ENABLE                             SPI_CFG2_SP_0
+/**
+  * @}
+  */
+
+/** @defgroup SPI_CRC_Calculation SPI CRC Calculation
+  * @{
+  */
+#define SPI_CRCCALCULATION_DISABLE                    (0x00000000UL)
+#define SPI_CRCCALCULATION_ENABLE                     SPI_CFG1_CRCEN
+/**
+  * @}
+  */
+
+/** @defgroup SPI_CRC_length SPI CRC Length
+  * @{
+  */
+#define SPI_CRC_LENGTH_DATASIZE                       (0x00000000UL)
+#define SPI_CRC_LENGTH_4BIT                           (0x00030000UL)
+#define SPI_CRC_LENGTH_5BIT                           (0x00040000UL)
+#define SPI_CRC_LENGTH_6BIT                           (0x00050000UL)
+#define SPI_CRC_LENGTH_7BIT                           (0x00060000UL)
+#define SPI_CRC_LENGTH_8BIT                           (0x00070000UL)
+#define SPI_CRC_LENGTH_9BIT                           (0x00080000UL)
+#define SPI_CRC_LENGTH_10BIT                          (0x00090000UL)
+#define SPI_CRC_LENGTH_11BIT                          (0x000A0000UL)
+#define SPI_CRC_LENGTH_12BIT                          (0x000B0000UL)
+#define SPI_CRC_LENGTH_13BIT                          (0x000C0000UL)
+#define SPI_CRC_LENGTH_14BIT                          (0x000D0000UL)
+#define SPI_CRC_LENGTH_15BIT                          (0x000E0000UL)
+#define SPI_CRC_LENGTH_16BIT                          (0x000F0000UL)
+#define SPI_CRC_LENGTH_17BIT                          (0x00100000UL)
+#define SPI_CRC_LENGTH_18BIT                          (0x00110000UL)
+#define SPI_CRC_LENGTH_19BIT                          (0x00120000UL)
+#define SPI_CRC_LENGTH_20BIT                          (0x00130000UL)
+#define SPI_CRC_LENGTH_21BIT                          (0x00140000UL)
+#define SPI_CRC_LENGTH_22BIT                          (0x00150000UL)
+#define SPI_CRC_LENGTH_23BIT                          (0x00160000UL)
+#define SPI_CRC_LENGTH_24BIT                          (0x00170000UL)
+#define SPI_CRC_LENGTH_25BIT                          (0x00180000UL)
+#define SPI_CRC_LENGTH_26BIT                          (0x00190000UL)
+#define SPI_CRC_LENGTH_27BIT                          (0x001A0000UL)
+#define SPI_CRC_LENGTH_28BIT                          (0x001B0000UL)
+#define SPI_CRC_LENGTH_29BIT                          (0x001C0000UL)
+#define SPI_CRC_LENGTH_30BIT                          (0x001D0000UL)
+#define SPI_CRC_LENGTH_31BIT                          (0x001E0000UL)
+#define SPI_CRC_LENGTH_32BIT                          (0x001F0000UL)
+/**
+  * @}
+  */
+
+/** @defgroup SPI_Fifo_Threshold SPI Fifo Threshold
+  * @{
+  */
+#define SPI_FIFO_THRESHOLD_01DATA                     (0x00000000UL)
+#define SPI_FIFO_THRESHOLD_02DATA                     (0x00000020UL)
+#define SPI_FIFO_THRESHOLD_03DATA                     (0x00000040UL)
+#define SPI_FIFO_THRESHOLD_04DATA                     (0x00000060UL)
+#define SPI_FIFO_THRESHOLD_05DATA                     (0x00000080UL)
+#define SPI_FIFO_THRESHOLD_06DATA                     (0x000000A0UL)
+#define SPI_FIFO_THRESHOLD_07DATA                     (0x000000C0UL)
+#define SPI_FIFO_THRESHOLD_08DATA                     (0x000000E0UL)
+#define SPI_FIFO_THRESHOLD_09DATA                     (0x00000100UL)
+#define SPI_FIFO_THRESHOLD_10DATA                     (0x00000120UL)
+#define SPI_FIFO_THRESHOLD_11DATA                     (0x00000140UL)
+#define SPI_FIFO_THRESHOLD_12DATA                     (0x00000160UL)
+#define SPI_FIFO_THRESHOLD_13DATA                     (0x00000180UL)
+#define SPI_FIFO_THRESHOLD_14DATA                     (0x000001A0UL)
+#define SPI_FIFO_THRESHOLD_15DATA                     (0x000001C0UL)
+#define SPI_FIFO_THRESHOLD_16DATA                     (0x000001E0UL)
+/**
+  * @}
+  */
+
+/** @defgroup SPI_CRC_Calculation_Initialization_Pattern SPI CRC Calculation Initialization Pattern
+  * @{
+  */
+#define SPI_CRC_INITIALIZATION_ALL_ZERO_PATTERN       (0x00000000UL)
+#define SPI_CRC_INITIALIZATION_ALL_ONE_PATTERN        (0x00000001UL)
+/**
+  * @}
+  */
+
+/** @defgroup SPI_NSS_Polarity SPI NSS Polarity
+  * @{
+  */
+#define SPI_NSS_POLARITY_LOW                          (0x00000000UL)
+#define SPI_NSS_POLARITY_HIGH                          SPI_CFG2_SSIOP
+/**
+  * @}
+  */
+
+/** @defgroup SPI_Master_Keep_IO_State Keep IO State
+  * @{
+  */
+#define SPI_MASTER_KEEP_IO_STATE_DISABLE              (0x00000000UL)
+#define SPI_MASTER_KEEP_IO_STATE_ENABLE               SPI_CFG2_AFCNTR
+/**
+  * @}
+  */
+
+/** @defgroup SPI_IO_Swap Control SPI IO Swap
+  * @{
+  */
+#define SPI_IO_SWAP_DISABLE                           (0x00000000UL)
+#define SPI_IO_SWAP_ENABLE                            SPI_CFG2_IOSWP
+/**
+  * @}
+  */
+
+/** @defgroup SPI_Master_SS_Idleness SPI Master SS Idleness
+  * @{
+  */
+#define SPI_MASTER_SS_IDLENESS_00CYCLE                (0x00000000UL)
+#define SPI_MASTER_SS_IDLENESS_01CYCLE                (0x00000001UL)
+#define SPI_MASTER_SS_IDLENESS_02CYCLE                (0x00000002UL)
+#define SPI_MASTER_SS_IDLENESS_03CYCLE                (0x00000003UL)
+#define SPI_MASTER_SS_IDLENESS_04CYCLE                (0x00000004UL)
+#define SPI_MASTER_SS_IDLENESS_05CYCLE                (0x00000005UL)
+#define SPI_MASTER_SS_IDLENESS_06CYCLE                (0x00000006UL)
+#define SPI_MASTER_SS_IDLENESS_07CYCLE                (0x00000007UL)
+#define SPI_MASTER_SS_IDLENESS_08CYCLE                (0x00000008UL)
+#define SPI_MASTER_SS_IDLENESS_09CYCLE                (0x00000009UL)
+#define SPI_MASTER_SS_IDLENESS_10CYCLE                (0x0000000AUL)
+#define SPI_MASTER_SS_IDLENESS_11CYCLE                (0x0000000BUL)
+#define SPI_MASTER_SS_IDLENESS_12CYCLE                (0x0000000CUL)
+#define SPI_MASTER_SS_IDLENESS_13CYCLE                (0x0000000DUL)
+#define SPI_MASTER_SS_IDLENESS_14CYCLE                (0x0000000EUL)
+#define SPI_MASTER_SS_IDLENESS_15CYCLE                (0x0000000FUL)
+/**
+  * @}
+  */
+
+/** @defgroup SPI_Master_InterData_Idleness SPI Master Inter-Data Idleness
+  * @{
+  */
+#define SPI_MASTER_INTERDATA_IDLENESS_00CYCLE         (0x00000000UL)
+#define SPI_MASTER_INTERDATA_IDLENESS_01CYCLE         (0x00000010UL)
+#define SPI_MASTER_INTERDATA_IDLENESS_02CYCLE         (0x00000020UL)
+#define SPI_MASTER_INTERDATA_IDLENESS_03CYCLE         (0x00000030UL)
+#define SPI_MASTER_INTERDATA_IDLENESS_04CYCLE         (0x00000040UL)
+#define SPI_MASTER_INTERDATA_IDLENESS_05CYCLE         (0x00000050UL)
+#define SPI_MASTER_INTERDATA_IDLENESS_06CYCLE         (0x00000060UL)
+#define SPI_MASTER_INTERDATA_IDLENESS_07CYCLE         (0x00000070UL)
+#define SPI_MASTER_INTERDATA_IDLENESS_08CYCLE         (0x00000080UL)
+#define SPI_MASTER_INTERDATA_IDLENESS_09CYCLE         (0x00000090UL)
+#define SPI_MASTER_INTERDATA_IDLENESS_10CYCLE         (0x000000A0UL)
+#define SPI_MASTER_INTERDATA_IDLENESS_11CYCLE         (0x000000B0UL)
+#define SPI_MASTER_INTERDATA_IDLENESS_12CYCLE         (0x000000C0UL)
+#define SPI_MASTER_INTERDATA_IDLENESS_13CYCLE         (0x000000D0UL)
+#define SPI_MASTER_INTERDATA_IDLENESS_14CYCLE         (0x000000E0UL)
+#define SPI_MASTER_INTERDATA_IDLENESS_15CYCLE         (0x000000F0UL)
+/**
+  * @}
+  */
+
+/** @defgroup SPI_Master_RX_AutoSuspend SPI Master Receiver AutoSuspend
+  * @{
+  */
+#define SPI_MASTER_RX_AUTOSUSP_DISABLE                (0x00000000UL)
+#define SPI_MASTER_RX_AUTOSUSP_ENABLE                 SPI_CR1_MASRX
+/**
+  * @}
+  */
+
+/** @defgroup SPI_Underrun_Behaviour SPI Underrun Behavior
+  * @{
+  */
+#define SPI_UNDERRUN_BEHAV_REGISTER_PATTERN           (0x00000000UL)
+#define SPI_UNDERRUN_BEHAV_LAST_RECEIVED              SPI_CFG1_UDRCFG_0
+#define SPI_UNDERRUN_BEHAV_LAST_TRANSMITTED           SPI_CFG1_UDRCFG_1
+/**
+  * @}
+  */
+
+/** @defgroup SPI_Underrun_Detection SPI Underrun Detection
+  * @{
+  */
+#define SPI_UNDERRUN_DETECT_BEGIN_DATA_FRAME          (0x00000000UL)
+#define SPI_UNDERRUN_DETECT_END_DATA_FRAME            SPI_CFG1_UDRDET_0
+#define SPI_UNDERRUN_DETECT_BEGIN_ACTIVE_NSS          SPI_CFG1_UDRDET_1
+/**
+  * @}
+  */
+
+/** @defgroup SPI_Interrupt_definition SPI Interrupt Definition
+  * @{
+  */
+#define SPI_IT_RXP                      SPI_IER_RXPIE
+#define SPI_IT_TXP                      SPI_IER_TXPIE
+#define SPI_IT_DXP                      SPI_IER_DXPIE
+#define SPI_IT_EOT                      SPI_IER_EOTIE
+#define SPI_IT_TXTF                     SPI_IER_TXTFIE
+#define SPI_IT_UDR                      SPI_IER_UDRIE
+#define SPI_IT_OVR                      SPI_IER_OVRIE
+#define SPI_IT_CRCERR                   SPI_IER_CRCEIE
+#define SPI_IT_FRE                      SPI_IER_TIFREIE
+#define SPI_IT_MODF                     SPI_IER_MODFIE
+#define SPI_IT_TSERF                    SPI_IER_TSERFIE
+#define SPI_IT_ERR                      (SPI_IT_UDR | SPI_IT_OVR | SPI_IT_FRE | SPI_IT_MODF | SPI_IT_CRCERR)
+/**
+  * @}
+  */
+
+/** @defgroup SPI_Flags_definition SPI Flags Definition
+  * @{
+  */
+#define SPI_FLAG_RXP                    SPI_SR_RXP     /* SPI status flag : Rx-Packet available flag                 */
+#define SPI_FLAG_TXP                    SPI_SR_TXP     /* SPI status flag : Tx-Packet space available flag           */
+#define SPI_FLAG_DXP                    SPI_SR_DXP     /* SPI status flag : Duplex Packet flag                       */
+#define SPI_FLAG_EOT                    SPI_SR_EOT     /* SPI status flag : End of transfer flag                     */
+#define SPI_FLAG_TXTF                   SPI_SR_TXTF    /* SPI status flag : Transmission Transfer Filled flag        */
+#define SPI_FLAG_UDR                    SPI_SR_UDR     /* SPI Error flag  : Underrun flag                            */
+#define SPI_FLAG_OVR                    SPI_SR_OVR     /* SPI Error flag  : Overrun flag                             */
+#define SPI_FLAG_CRCERR                 SPI_SR_CRCE    /* SPI Error flag  : CRC error flag                           */
+#define SPI_FLAG_FRE                    SPI_SR_TIFRE   /* SPI Error flag  : TI mode frame format error flag          */
+#define SPI_FLAG_MODF                   SPI_SR_MODF    /* SPI Error flag  : Mode fault flag                          */
+#define SPI_FLAG_TSERF                  SPI_SR_TSERF   /* SPI status flag : Additional number of data reloaded flag  */
+#define SPI_FLAG_SUSP                   SPI_SR_SUSP    /* SPI status flag : Transfer suspend complete flag           */
+#define SPI_FLAG_TXC                    SPI_SR_TXC     /* SPI status flag : TxFIFO transmission complete flag        */
+#define SPI_FLAG_FRLVL                  SPI_SR_RXPLVL  /* SPI status flag : Fifo reception level flag                */
+#define SPI_FLAG_RXWNE                  SPI_SR_RXWNE   /* SPI status flag : RxFIFO word not empty flag               */
+/**
+  * @}
+  */
+
+/** @defgroup SPI_reception_fifo_status_level SPI Reception FIFO Status Level
+  * @{
+  */
+#define SPI_RX_FIFO_0PACKET             (0x00000000UL)         /* 0 or multiple of 4 packets available in the RxFIFO */
+#define SPI_RX_FIFO_1PACKET             (SPI_SR_RXPLVL_0)
+#define SPI_RX_FIFO_2PACKET             (SPI_SR_RXPLVL_1)
+#define SPI_RX_FIFO_3PACKET             (SPI_SR_RXPLVL_1 | SPI_SR_RXPLVL_0)
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/* Exported macros -----------------------------------------------------------*/
+/** @defgroup SPI_Exported_Macros SPI Exported Macros
+  * @{
+  */
+
+/** @brief  Reset SPI handle state.
+  * @param  __HANDLE__: specifies the SPI Handle.
+  *         This parameter can be SPI where x: 1, 2, 3, 4, 5 or 6 to select the SPI peripheral.
+  * @retval None
+  */
+#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1UL)
+#define __HAL_SPI_RESET_HANDLE_STATE(__HANDLE__)   do{                                                  \
+                                                       (__HANDLE__)->State = HAL_SPI_STATE_RESET;       \
+                                                       (__HANDLE__)->MspInitCallback = NULL;            \
+                                                       (__HANDLE__)->MspDeInitCallback = NULL;          \
+                                                     } while(0)
+#else
+#define __HAL_SPI_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_SPI_STATE_RESET)
+#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
+
+/** @brief  Enable the specified SPI interrupts.
+  * @param  __HANDLE__: specifies the SPI Handle.
+  *         This parameter can be SPI where x: 1, 2, 3, 4, 5 or 6 to select the SPI peripheral.
+  * @param  __INTERRUPT__: specifies the interrupt source to enable or disable.
+  *         This parameter can be one of the following values:
+  *            @arg SPI_IT_RXP    : Rx-Packet available interrupt
+  *            @arg SPI_IT_TXP    : Tx-Packet space available interrupt
+  *            @arg SPI_IT_DXP    : Duplex Packet interrupt
+  *            @arg SPI_IT_EOT    : End of transfer interrupt
+  *            @arg SPI_IT_TXTF   : Transmission Transfer Filled interrupt
+  *            @arg SPI_IT_UDR    : Underrun interrupt
+  *            @arg SPI_IT_OVR    : Overrun  interrupt
+  *            @arg SPI_IT_CRCERR : CRC error interrupt
+  *            @arg SPI_IT_FRE    : TI mode frame format error interrupt
+  *            @arg SPI_IT_MODF   : Mode fault interrupt
+  *            @arg SPI_IT_TSERF  : Additional number of data reloaded interrupt
+  *            @arg SPI_IT_ERR    : Error interrupt
+  * @retval None
+  */
+#define __HAL_SPI_ENABLE_IT(__HANDLE__, __INTERRUPT__)   ((__HANDLE__)->Instance->IER |= (__INTERRUPT__))
+
+/** @brief  Disable the specified SPI interrupts.
+  * @param  __HANDLE__: specifies the SPI Handle.
+  *         This parameter can be SPI where x: 1, 2, 3, 4, 5 or 6 to select the SPI peripheral.
+  * @param  __INTERRUPT__: specifies the interrupt source to enable or disable.
+  *         This parameter can be one of the following values:
+  *            @arg SPI_IT_RXP    : Rx-Packet available interrupt
+  *            @arg SPI_IT_TXP    : Tx-Packet space available interrupt
+  *            @arg SPI_IT_DXP    : Duplex Packet interrupt
+  *            @arg SPI_IT_EOT    : End of transfer interrupt
+  *            @arg SPI_IT_TXTF   : Transmission Transfer Filled interrupt
+  *            @arg SPI_IT_UDR    : Underrun interrupt
+  *            @arg SPI_IT_OVR    : Overrun  interrupt
+  *            @arg SPI_IT_CRCERR : CRC error interrupt
+  *            @arg SPI_IT_FRE    : TI mode frame format error interrupt
+  *            @arg SPI_IT_MODF   : Mode fault interrupt
+  *            @arg SPI_IT_TSERF  : Additional number of data reloaded interrupt
+  *            @arg SPI_IT_ERR    : Error interrupt
+  * @retval None
+  */
+#define __HAL_SPI_DISABLE_IT(__HANDLE__, __INTERRUPT__)  ((__HANDLE__)->Instance->IER &= (~(__INTERRUPT__)))
+
+/** @brief  Check whether the specified SPI interrupt source is enabled or not.
+  * @param  __HANDLE__: specifies the SPI Handle.
+  *         This parameter can be SPI where x: 1, 2, 3, 4, 5 or 6 to select the SPI peripheral.
+  * @param  __INTERRUPT__: specifies the SPI interrupt source to check.
+  *          This parameter can be one of the following values:
+  *            @arg SPI_IT_RXP    : Rx-Packet available interrupt
+  *            @arg SPI_IT_TXP    : Tx-Packet space available interrupt
+  *            @arg SPI_IT_DXP    : Duplex Packet interrupt
+  *            @arg SPI_IT_EOT    : End of transfer interrupt
+  *            @arg SPI_IT_TXTF   : Transmission Transfer Filled interrupt
+  *            @arg SPI_IT_UDR    : Underrun interrupt
+  *            @arg SPI_IT_OVR    : Overrun  interrupt
+  *            @arg SPI_IT_CRCERR : CRC error interrupt
+  *            @arg SPI_IT_FRE    : TI mode frame format error interrupt
+  *            @arg SPI_IT_MODF   : Mode fault interrupt
+  *            @arg SPI_IT_TSERF  : Additional number of data reloaded interrupt
+  *            @arg SPI_IT_ERR    : Error interrupt
+  * @retval The new state of __IT__ (TRUE or FALSE).
+  */
+#define __HAL_SPI_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) ((((__HANDLE__)->Instance->IER & \
+                                                              (__INTERRUPT__)) == (__INTERRUPT__)) ? SET : RESET)
+
+/** @brief  Check whether the specified SPI flag is set or not.
+  * @param  __HANDLE__: specifies the SPI Handle.
+  *         This parameter can be SPI where x: 1, 2, 3, 4, 5 or 6 to select the SPI peripheral.
+  * @param  __FLAG__: specifies the flag to check.
+  *         This parameter can be one of the following values:
+  *            @arg SPI_FLAG_RXP    : Rx-Packet available flag
+  *            @arg SPI_FLAG_TXP    : Tx-Packet space available flag
+  *            @arg SPI_FLAG_DXP    : Duplex Packet flag
+  *            @arg SPI_FLAG_EOT    : End of transfer flag
+  *            @arg SPI_FLAG_TXTF   : Transmission Transfer Filled flag
+  *            @arg SPI_FLAG_UDR    : Underrun flag
+  *            @arg SPI_FLAG_OVR    : Overrun flag
+  *            @arg SPI_FLAG_CRCERR : CRC error flag
+  *            @arg SPI_FLAG_FRE    : TI mode frame format error flag
+  *            @arg SPI_FLAG_MODF   : Mode fault flag
+  *            @arg SPI_FLAG_TSERF  : Additional number of data reloaded flag
+  *            @arg SPI_FLAG_SUSP   : Transfer suspend complete flag
+  *            @arg SPI_FLAG_TXC    : TxFIFO transmission complete flag
+  *            @arg SPI_FLAG_FRLVL  : Fifo reception level flag
+  *            @arg SPI_FLAG_RXWNE  : RxFIFO word not empty flag
+  * @retval The new state of __FLAG__ (TRUE or FALSE).
+  */
+#define __HAL_SPI_GET_FLAG(__HANDLE__, __FLAG__) ((((__HANDLE__)->Instance->SR) & (__FLAG__)) == (__FLAG__))
+
+/** @brief  Clear the SPI CRCERR pending flag.
+  * @param  __HANDLE__: specifies the SPI Handle.
+  * @retval None
+  */
+#define __HAL_SPI_CLEAR_CRCERRFLAG(__HANDLE__) SET_BIT((__HANDLE__)->Instance->IFCR , SPI_IFCR_CRCEC)
+
+/** @brief  Clear the SPI MODF pending flag.
+  * @param  __HANDLE__: specifies the SPI Handle.
+  * @retval None
+  */
+#define __HAL_SPI_CLEAR_MODFFLAG(__HANDLE__)  SET_BIT((__HANDLE__)->Instance->IFCR , (uint32_t)(SPI_IFCR_MODFC));
+
+/** @brief  Clear the SPI OVR pending flag.
+  * @param  __HANDLE__: specifies the SPI Handle.
+  * @retval None
+  */
+#define __HAL_SPI_CLEAR_OVRFLAG(__HANDLE__) SET_BIT((__HANDLE__)->Instance->IFCR , SPI_IFCR_OVRC)
+
+/** @brief  Clear the SPI FRE pending flag.
+  * @param  __HANDLE__: specifies the SPI Handle.
+  * @retval None
+  */
+#define __HAL_SPI_CLEAR_FREFLAG(__HANDLE__) SET_BIT((__HANDLE__)->Instance->IFCR , SPI_IFCR_TIFREC)
+
+/** @brief  Clear the SPI UDR pending flag.
+  * @param  __HANDLE__: specifies the SPI Handle.
+  * @retval None
+  */
+#define __HAL_SPI_CLEAR_UDRFLAG(__HANDLE__) SET_BIT((__HANDLE__)->Instance->IFCR , SPI_IFCR_UDRC)
+
+/** @brief  Clear the SPI EOT pending flag.
+  * @param  __HANDLE__: specifies the SPI Handle.
+  * @retval None
+  */
+#define __HAL_SPI_CLEAR_EOTFLAG(__HANDLE__) SET_BIT((__HANDLE__)->Instance->IFCR , SPI_IFCR_EOTC)
+
+/** @brief  Clear the SPI UDR pending flag.
+  * @param  __HANDLE__: specifies the SPI Handle.
+  * @retval None
+  */
+#define __HAL_SPI_CLEAR_TXTFFLAG(__HANDLE__) SET_BIT((__HANDLE__)->Instance->IFCR , SPI_IFCR_TXTFC)
+
+/** @brief  Clear the SPI SUSP pending flag.
+  * @param  __HANDLE__: specifies the SPI Handle.
+  * @retval None
+  */
+#define __HAL_SPI_CLEAR_SUSPFLAG(__HANDLE__) SET_BIT((__HANDLE__)->Instance->IFCR , SPI_IFCR_SUSPC)
+
+/** @brief  Clear the SPI TSERF pending flag.
+  * @param  __HANDLE__: specifies the SPI Handle.
+  * @retval None
+  */
+#define __HAL_SPI_CLEAR_TSERFFLAG(__HANDLE__) SET_BIT((__HANDLE__)->Instance->IFCR , SPI_IFCR_TSERFC)
+
+/** @brief  Enable the SPI peripheral.
+  * @param  __HANDLE__: specifies the SPI Handle.
+  * @retval None
+  */
+#define __HAL_SPI_ENABLE(__HANDLE__) SET_BIT((__HANDLE__)->Instance->CR1 , SPI_CR1_SPE)
+
+/** @brief  Disable the SPI peripheral.
+  * @param  __HANDLE__: specifies the SPI Handle.
+  * @retval None
+  */
+#define __HAL_SPI_DISABLE(__HANDLE__) CLEAR_BIT((__HANDLE__)->Instance->CR1 , SPI_CR1_SPE)
+/**
+  * @}
+  */
+
+
+/* Include SPI HAL Extension module */
+#include "stm32h7xx_hal_spi_ex.h"
+
+
+/* Exported functions --------------------------------------------------------*/
+/** @addtogroup SPI_Exported_Functions
+  * @{
+  */
+
+/** @addtogroup SPI_Exported_Functions_Group1 Initialization and de-initialization functions
+  * @{
+  */
+/* Initialization/de-initialization functions  ********************************/
+HAL_StatusTypeDef HAL_SPI_Init(SPI_HandleTypeDef *hspi);
+HAL_StatusTypeDef HAL_SPI_DeInit(SPI_HandleTypeDef *hspi);
+void HAL_SPI_MspInit(SPI_HandleTypeDef *hspi);
+void HAL_SPI_MspDeInit(SPI_HandleTypeDef *hspi);
+
+/* Callbacks Register/UnRegister functions  ***********************************/
+#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U)
+HAL_StatusTypeDef HAL_SPI_RegisterCallback(SPI_HandleTypeDef *hspi, HAL_SPI_CallbackIDTypeDef CallbackID,
+                                           pSPI_CallbackTypeDef pCallback);
+HAL_StatusTypeDef HAL_SPI_UnRegisterCallback(SPI_HandleTypeDef *hspi, HAL_SPI_CallbackIDTypeDef CallbackID);
+#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
+/**
+  * @}
+  */
+
+/** @addtogroup SPI_Exported_Functions_Group2 IO operation functions
+  * @{
+  */
+/* I/O operation functions  ***************************************************/
+HAL_StatusTypeDef HAL_SPI_Transmit(SPI_HandleTypeDef *hspi, const uint8_t *pData, uint16_t Size, uint32_t Timeout);
+HAL_StatusTypeDef HAL_SPI_Receive(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout);
+HAL_StatusTypeDef HAL_SPI_TransmitReceive(SPI_HandleTypeDef *hspi, const uint8_t *pTxData, uint8_t *pRxData,
+                                          uint16_t Size, uint32_t Timeout);
+HAL_StatusTypeDef HAL_SPI_Transmit_IT(SPI_HandleTypeDef *hspi, const uint8_t *pData, uint16_t Size);
+HAL_StatusTypeDef HAL_SPI_Receive_IT(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size);
+HAL_StatusTypeDef HAL_SPI_TransmitReceive_IT(SPI_HandleTypeDef *hspi, const uint8_t *pTxData, uint8_t *pRxData,
+                                             uint16_t Size);
+
+HAL_StatusTypeDef HAL_SPI_Transmit_DMA(SPI_HandleTypeDef *hspi, const uint8_t *pData, uint16_t Size);
+HAL_StatusTypeDef HAL_SPI_Receive_DMA(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size);
+HAL_StatusTypeDef HAL_SPI_TransmitReceive_DMA(SPI_HandleTypeDef *hspi, const uint8_t *pTxData, uint8_t *pRxData,
+                                              uint16_t Size);
+
+#if defined(USE_SPI_RELOAD_TRANSFER)
+HAL_StatusTypeDef HAL_SPI_Reload_Transmit_IT(SPI_HandleTypeDef *hspi, const uint8_t *pData, uint16_t Size);
+HAL_StatusTypeDef HAL_SPI_Reload_Receive_IT(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size);
+HAL_StatusTypeDef HAL_SPI_Reload_TransmitReceive_IT(SPI_HandleTypeDef *hspi, const uint8_t *pTxData,
+                                                    uint8_t *pRxData, uint16_t Size);
+#endif /* USE_SPI_RELOAD_TRANSFER */
+
+HAL_StatusTypeDef HAL_SPI_DMAPause(SPI_HandleTypeDef *hspi);
+HAL_StatusTypeDef HAL_SPI_DMAResume(SPI_HandleTypeDef *hspi);
+HAL_StatusTypeDef HAL_SPI_DMAStop(SPI_HandleTypeDef *hspi);
+
+/* Transfer Abort functions */
+HAL_StatusTypeDef HAL_SPI_Abort(SPI_HandleTypeDef *hspi);
+HAL_StatusTypeDef HAL_SPI_Abort_IT(SPI_HandleTypeDef *hspi);
+
+void HAL_SPI_IRQHandler(SPI_HandleTypeDef *hspi);
+void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi);
+void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi);
+void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi);
+void HAL_SPI_TxHalfCpltCallback(SPI_HandleTypeDef *hspi);
+void HAL_SPI_RxHalfCpltCallback(SPI_HandleTypeDef *hspi);
+void HAL_SPI_TxRxHalfCpltCallback(SPI_HandleTypeDef *hspi);
+void HAL_SPI_ErrorCallback(SPI_HandleTypeDef *hspi);
+void HAL_SPI_AbortCpltCallback(SPI_HandleTypeDef *hspi);
+void HAL_SPI_SuspendCallback(SPI_HandleTypeDef *hspi);
+/**
+  * @}
+  */
+
+/** @addtogroup SPI_Exported_Functions_Group3 Peripheral State and Errors functions
+  * @{
+  */
+
+/* Peripheral State and Error functions ***************************************/
+HAL_SPI_StateTypeDef HAL_SPI_GetState(const SPI_HandleTypeDef *hspi);
+uint32_t             HAL_SPI_GetError(const SPI_HandleTypeDef *hspi);
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/* Private macros ------------------------------------------------------------*/
+/** @defgroup SPI_Private_Macros SPI Private Macros
+  * @{
+  */
+
+/** @brief  Set the SPI transmit-only mode in 1Line configuration.
+  * @param  __HANDLE__: specifies the SPI Handle.
+  *         This parameter can be SPI where x: 1, 2, or 3 to select the SPI peripheral.
+  * @retval None
+  */
+#define SPI_1LINE_TX(__HANDLE__) SET_BIT((__HANDLE__)->Instance->CR1, SPI_CR1_HDDIR)
+
+/** @brief  Set the SPI receive-only mode in 1Line configuration.
+  * @param  __HANDLE__: specifies the SPI Handle.
+  *         This parameter can be SPI where x: 1, 2, or 3 to select the SPI peripheral.
+  * @retval None
+  */
+#define SPI_1LINE_RX(__HANDLE__) CLEAR_BIT((__HANDLE__)->Instance->CR1, SPI_CR1_HDDIR)
+
+/** @brief  Set the SPI transmit-only mode in 2Lines configuration.
+  * @param  __HANDLE__: specifies the SPI Handle.
+  *         This parameter can be SPI where x: 1, 2, or 3 to select the SPI peripheral.
+  * @retval None
+  */
+#define SPI_2LINES_TX(__HANDLE__) MODIFY_REG((__HANDLE__)->Instance->CFG2, SPI_CFG2_COMM, SPI_CFG2_COMM_0)
+
+/** @brief  Set the SPI receive-only mode in 2Lines configuration.
+  * @param  __HANDLE__: specifies the SPI Handle.
+  *         This parameter can be SPI where x: 1, 2, or 3 to select the SPI peripheral.
+  * @retval None
+  */
+#define SPI_2LINES_RX(__HANDLE__) MODIFY_REG((__HANDLE__)->Instance->CFG2, SPI_CFG2_COMM, SPI_CFG2_COMM_1)
+
+/** @brief  Set the SPI Transmit-Receive mode in 2Lines configuration.
+  * @param  __HANDLE__: specifies the SPI Handle.
+  *         This parameter can be SPI where x: 1, 2, or 3 to select the SPI peripheral.
+  * @retval None
+  */
+#define SPI_2LINES(__HANDLE__) MODIFY_REG((__HANDLE__)->Instance->CFG2, SPI_CFG2_COMM, 0x00000000UL)
+
+#define IS_SPI_MODE(MODE)                          (((MODE) == SPI_MODE_SLAVE) || \
+                                                    ((MODE) == SPI_MODE_MASTER))
+
+#define IS_SPI_DIRECTION(MODE)                     (((MODE) == SPI_DIRECTION_2LINES)        || \
+                                                    ((MODE) == SPI_DIRECTION_2LINES_RXONLY) || \
+                                                    ((MODE) == SPI_DIRECTION_1LINE)         || \
+                                                    ((MODE) == SPI_DIRECTION_2LINES_TXONLY))
+
+#define IS_SPI_DIRECTION_2LINES(MODE) ((MODE) == SPI_DIRECTION_2LINES)
+
+#define IS_SPI_DIRECTION_2LINES_OR_1LINE_2LINES_TXONLY(MODE) (((MODE) == SPI_DIRECTION_2LINES)|| \
+                                                              ((MODE) == SPI_DIRECTION_1LINE) || \
+                                                              ((MODE) == SPI_DIRECTION_2LINES_TXONLY))
+
+#define IS_SPI_DIRECTION_2LINES_OR_1LINE_2LINES_RXONLY(MODE) (((MODE) == SPI_DIRECTION_2LINES)|| \
+                                                              ((MODE) == SPI_DIRECTION_1LINE) || \
+                                                              ((MODE) == SPI_DIRECTION_2LINES_RXONLY))
+
+#define IS_SPI_DATASIZE(DATASIZE)                  (((DATASIZE) == SPI_DATASIZE_32BIT) || \
+                                                    ((DATASIZE) == SPI_DATASIZE_31BIT) || \
+                                                    ((DATASIZE) == SPI_DATASIZE_30BIT) || \
+                                                    ((DATASIZE) == SPI_DATASIZE_29BIT) || \
+                                                    ((DATASIZE) == SPI_DATASIZE_28BIT) || \
+                                                    ((DATASIZE) == SPI_DATASIZE_27BIT) || \
+                                                    ((DATASIZE) == SPI_DATASIZE_26BIT) || \
+                                                    ((DATASIZE) == SPI_DATASIZE_25BIT) || \
+                                                    ((DATASIZE) == SPI_DATASIZE_24BIT) || \
+                                                    ((DATASIZE) == SPI_DATASIZE_23BIT) || \
+                                                    ((DATASIZE) == SPI_DATASIZE_22BIT) || \
+                                                    ((DATASIZE) == SPI_DATASIZE_21BIT) || \
+                                                    ((DATASIZE) == SPI_DATASIZE_20BIT) || \
+                                                    ((DATASIZE) == SPI_DATASIZE_22BIT) || \
+                                                    ((DATASIZE) == SPI_DATASIZE_19BIT) || \
+                                                    ((DATASIZE) == SPI_DATASIZE_18BIT) || \
+                                                    ((DATASIZE) == SPI_DATASIZE_17BIT) || \
+                                                    ((DATASIZE) == SPI_DATASIZE_16BIT) || \
+                                                    ((DATASIZE) == SPI_DATASIZE_15BIT) || \
+                                                    ((DATASIZE) == SPI_DATASIZE_14BIT) || \
+                                                    ((DATASIZE) == SPI_DATASIZE_13BIT) || \
+                                                    ((DATASIZE) == SPI_DATASIZE_12BIT) || \
+                                                    ((DATASIZE) == SPI_DATASIZE_11BIT) || \
+                                                    ((DATASIZE) == SPI_DATASIZE_10BIT) || \
+                                                    ((DATASIZE) == SPI_DATASIZE_9BIT)  || \
+                                                    ((DATASIZE) == SPI_DATASIZE_8BIT)  || \
+                                                    ((DATASIZE) == SPI_DATASIZE_7BIT)  || \
+                                                    ((DATASIZE) == SPI_DATASIZE_6BIT)  || \
+                                                    ((DATASIZE) == SPI_DATASIZE_5BIT)  || \
+                                                    ((DATASIZE) == SPI_DATASIZE_4BIT))
+
+#define IS_SPI_FIFOTHRESHOLD(THRESHOLD)            (((THRESHOLD) == SPI_FIFO_THRESHOLD_01DATA) || \
+                                                    ((THRESHOLD) == SPI_FIFO_THRESHOLD_02DATA) || \
+                                                    ((THRESHOLD) == SPI_FIFO_THRESHOLD_03DATA) || \
+                                                    ((THRESHOLD) == SPI_FIFO_THRESHOLD_04DATA) || \
+                                                    ((THRESHOLD) == SPI_FIFO_THRESHOLD_05DATA) || \
+                                                    ((THRESHOLD) == SPI_FIFO_THRESHOLD_06DATA) || \
+                                                    ((THRESHOLD) == SPI_FIFO_THRESHOLD_07DATA) || \
+                                                    ((THRESHOLD) == SPI_FIFO_THRESHOLD_08DATA) || \
+                                                    ((THRESHOLD) == SPI_FIFO_THRESHOLD_09DATA) || \
+                                                    ((THRESHOLD) == SPI_FIFO_THRESHOLD_10DATA) || \
+                                                    ((THRESHOLD) == SPI_FIFO_THRESHOLD_11DATA) || \
+                                                    ((THRESHOLD) == SPI_FIFO_THRESHOLD_12DATA) || \
+                                                    ((THRESHOLD) == SPI_FIFO_THRESHOLD_13DATA) || \
+                                                    ((THRESHOLD) == SPI_FIFO_THRESHOLD_14DATA) || \
+                                                    ((THRESHOLD) == SPI_FIFO_THRESHOLD_15DATA) || \
+                                                    ((THRESHOLD) == SPI_FIFO_THRESHOLD_16DATA))
+
+#define IS_SPI_CPOL(CPOL)                          (((CPOL) == SPI_POLARITY_LOW) || \
+                                                    ((CPOL) == SPI_POLARITY_HIGH))
+
+#define IS_SPI_CPHA(CPHA)                          (((CPHA) == SPI_PHASE_1EDGE) || \
+                                                    ((CPHA) == SPI_PHASE_2EDGE))
+
+#define IS_SPI_NSS(NSS)                            (((NSS) == SPI_NSS_SOFT)       || \
+                                                    ((NSS) == SPI_NSS_HARD_INPUT) || \
+                                                    ((NSS) == SPI_NSS_HARD_OUTPUT))
+
+#define IS_SPI_NSSP(NSSP)                          (((NSSP) == SPI_NSS_PULSE_ENABLE) || \
+                                                    ((NSSP) == SPI_NSS_PULSE_DISABLE))
+
+#define IS_SPI_BAUDRATE_PRESCALER(PRESCALER)       (((PRESCALER) == SPI_BAUDRATEPRESCALER_2)      || \
+                                                    ((PRESCALER) == SPI_BAUDRATEPRESCALER_4)      || \
+                                                    ((PRESCALER) == SPI_BAUDRATEPRESCALER_8)      || \
+                                                    ((PRESCALER) == SPI_BAUDRATEPRESCALER_16)     || \
+                                                    ((PRESCALER) == SPI_BAUDRATEPRESCALER_32)     || \
+                                                    ((PRESCALER) == SPI_BAUDRATEPRESCALER_64)     || \
+                                                    ((PRESCALER) == SPI_BAUDRATEPRESCALER_128)    || \
+                                                    ((PRESCALER) == SPI_BAUDRATEPRESCALER_256))
+
+#define IS_SPI_FIRST_BIT(BIT)                      (((BIT) == SPI_FIRSTBIT_MSB) || \
+                                                    ((BIT) == SPI_FIRSTBIT_LSB))
+
+#define IS_SPI_TIMODE(MODE)                        (((MODE) == SPI_TIMODE_DISABLE) || \
+                                                    ((MODE) == SPI_TIMODE_ENABLE))
+
+#define IS_SPI_CRC_CALCULATION(CALCULATION)        (((CALCULATION) == SPI_CRCCALCULATION_DISABLE) || \
+                                                    ((CALCULATION) == SPI_CRCCALCULATION_ENABLE))
+
+#define IS_SPI_CRC_INITIALIZATION_PATTERN(PATTERN) (((PATTERN) == SPI_CRC_INITIALIZATION_ALL_ZERO_PATTERN) || \
+                                                    ((PATTERN) == SPI_CRC_INITIALIZATION_ALL_ONE_PATTERN))
+
+#define IS_SPI_CRC_LENGTH(LENGTH)                  (((LENGTH) == SPI_CRC_LENGTH_DATASIZE) || \
+                                                    ((LENGTH) == SPI_CRC_LENGTH_32BIT)    || \
+                                                    ((LENGTH) == SPI_CRC_LENGTH_31BIT)    || \
+                                                    ((LENGTH) == SPI_CRC_LENGTH_30BIT)    || \
+                                                    ((LENGTH) == SPI_CRC_LENGTH_29BIT)    || \
+                                                    ((LENGTH) == SPI_CRC_LENGTH_28BIT)    || \
+                                                    ((LENGTH) == SPI_CRC_LENGTH_27BIT)    || \
+                                                    ((LENGTH) == SPI_CRC_LENGTH_26BIT)    || \
+                                                    ((LENGTH) == SPI_CRC_LENGTH_25BIT)    || \
+                                                    ((LENGTH) == SPI_CRC_LENGTH_24BIT)    || \
+                                                    ((LENGTH) == SPI_CRC_LENGTH_23BIT)    || \
+                                                    ((LENGTH) == SPI_CRC_LENGTH_22BIT)    || \
+                                                    ((LENGTH) == SPI_CRC_LENGTH_21BIT)    || \
+                                                    ((LENGTH) == SPI_CRC_LENGTH_20BIT)    || \
+                                                    ((LENGTH) == SPI_CRC_LENGTH_19BIT)    || \
+                                                    ((LENGTH) == SPI_CRC_LENGTH_18BIT)    || \
+                                                    ((LENGTH) == SPI_CRC_LENGTH_17BIT)    || \
+                                                    ((LENGTH) == SPI_CRC_LENGTH_16BIT)    || \
+                                                    ((LENGTH) == SPI_CRC_LENGTH_15BIT)    || \
+                                                    ((LENGTH) == SPI_CRC_LENGTH_14BIT)    || \
+                                                    ((LENGTH) == SPI_CRC_LENGTH_13BIT)    || \
+                                                    ((LENGTH) == SPI_CRC_LENGTH_12BIT)    || \
+                                                    ((LENGTH) == SPI_CRC_LENGTH_11BIT)    || \
+                                                    ((LENGTH) == SPI_CRC_LENGTH_10BIT)    || \
+                                                    ((LENGTH) == SPI_CRC_LENGTH_9BIT)     || \
+                                                    ((LENGTH) == SPI_CRC_LENGTH_8BIT)     || \
+                                                    ((LENGTH) == SPI_CRC_LENGTH_7BIT)     || \
+                                                    ((LENGTH) == SPI_CRC_LENGTH_6BIT)     || \
+                                                    ((LENGTH) == SPI_CRC_LENGTH_5BIT)     || \
+                                                    ((LENGTH) == SPI_CRC_LENGTH_4BIT))
+
+
+#define IS_SPI_CRC_POLYNOMIAL(POLYNOMIAL)          ((POLYNOMIAL) > 0x0UL)
+
+#define IS_SPI_CRC_POLYNOMIAL_SIZE(POLYNOM, LENGTH) (((POLYNOM) >> (((LENGTH) >> SPI_CFG1_CRCSIZE_Pos) + 1UL)) == 0UL)
+
+
+#define IS_SPI_UNDERRUN_DETECTION(MODE)            (((MODE) == SPI_UNDERRUN_DETECT_BEGIN_DATA_FRAME) || \
+                                                    ((MODE) == SPI_UNDERRUN_DETECT_END_DATA_FRAME)   || \
+                                                    ((MODE) == SPI_UNDERRUN_DETECT_BEGIN_ACTIVE_NSS))
+
+#define IS_SPI_UNDERRUN_BEHAVIOUR(MODE)            (((MODE) == SPI_UNDERRUN_BEHAV_REGISTER_PATTERN) || \
+                                                    ((MODE) == SPI_UNDERRUN_BEHAV_LAST_RECEIVED)    || \
+                                                    ((MODE) == SPI_UNDERRUN_BEHAV_LAST_TRANSMITTED))
+
+#define IS_SPI_MASTER_RX_AUTOSUSP(MODE)            (((MODE) == SPI_MASTER_RX_AUTOSUSP_DISABLE) || \
+                                                    ((MODE) == SPI_MASTER_RX_AUTOSUSP_ENABLE))
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* STM32H7xx_HAL_SPI_H */
+
+/**
+  * @}
+  */
Index: ctrl/firmware/Main/CubeMX/Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_dma.c
===================================================================
--- ctrl/firmware/Main/CubeMX/Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_dma.c	(revision 45)
+++ ctrl/firmware/Main/CubeMX/Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_dma.c	(revision 45)
@@ -0,0 +1,2062 @@
+/**
+  ******************************************************************************
+  * @file    stm32h7xx_hal_dma.c
+  * @author  MCD Application Team
+  * @brief   DMA HAL module driver.
+  *          This file provides firmware functions to manage the following
+  *          functionalities of the Direct Memory Access (DMA) peripheral:
+  *           + Initialization and de-initialization functions
+  *           + IO operation functions
+  *           + Peripheral State and errors functions
+  ******************************************************************************
+  * @attention
+  *
+  * Copyright (c) 2017 STMicroelectronics.
+  * All rights reserved.
+  *
+  * This software is licensed under terms that can be found in the LICENSE file
+  * in the root directory of this software component.
+  * If no LICENSE file comes with this software, it is provided AS-IS.
+  *
+  ******************************************************************************
+  @verbatim
+  ==============================================================================
+                        ##### How to use this driver #####
+  ==============================================================================
+  [..]
+   (#) Enable and configure the peripheral to be connected to the DMA Stream
+       (except for internal SRAM/FLASH memories: no initialization is
+       necessary) please refer to Reference manual for connection between peripherals
+       and DMA requests .
+
+   (#) For a given Stream, program the required configuration through the following parameters:
+       Transfer Direction, Source and Destination data formats,
+       Circular, Normal or peripheral flow control mode, Stream Priority level,
+       Source and Destination Increment mode, FIFO mode and its Threshold (if needed),
+       Burst mode for Source and/or Destination (if needed) using HAL_DMA_Init() function.
+
+     *** Polling mode IO operation ***
+     =================================
+    [..]
+          (+) Use HAL_DMA_Start() to start DMA transfer after the configuration of Source
+              address and destination address and the Length of data to be transferred
+          (+) Use HAL_DMA_PollForTransfer() to poll for the end of current transfer, in this
+              case a fixed Timeout can be configured by User depending from his application.
+
+     *** Interrupt mode IO operation ***
+     ===================================
+    [..]
+          (+) Configure the DMA interrupt priority using HAL_NVIC_SetPriority()
+          (+) Enable the DMA IRQ handler using HAL_NVIC_EnableIRQ()
+          (+) Use HAL_DMA_Start_IT() to start DMA transfer after the configuration of
+              Source address and destination address and the Length of data to be transferred. In this
+              case the DMA interrupt is configured
+          (+) Use HAL_DMA_IRQHandler() called under DMA_IRQHandler() Interrupt subroutine
+          (+) At the end of data transfer HAL_DMA_IRQHandler() function is executed and user can
+              add his own function by customization of function pointer XferCpltCallback and
+              XferErrorCallback (i.e a member of DMA handle structure).
+    [..]
+     (#) Use HAL_DMA_GetState() function to return the DMA state and HAL_DMA_GetError() in case of error
+         detection.
+
+     (#) Use HAL_DMA_Abort() function to abort the current transfer
+
+     -@-   In Memory-to-Memory transfer mode, Circular mode is not allowed.
+
+     -@-   The FIFO is used mainly to reduce bus usage and to allow data packing/unpacking: it is
+           possible to set different Data Sizes for the Peripheral and the Memory (ie. you can set
+           Half-Word data size for the peripheral to access its data register and set Word data size
+           for the Memory to gain in access time. Each two half words will be packed and written in
+           a single access to a Word in the Memory).
+
+     -@-   When FIFO is disabled, it is not allowed to configure different Data Sizes for Source
+           and Destination. In this case the Peripheral Data Size will be applied to both Source
+           and Destination.
+
+     *** DMA HAL driver macros list ***
+     =============================================
+     [..]
+       Below the list of most used macros in DMA HAL driver.
+
+      (+) __HAL_DMA_ENABLE: Enable the specified DMA Stream.
+      (+) __HAL_DMA_DISABLE: Disable the specified DMA Stream.
+      (+) __HAL_DMA_GET_FS: Return the current DMA Stream FIFO filled level.
+      (+) __HAL_DMA_ENABLE_IT: Enable the specified DMA Stream interrupts.
+      (+) __HAL_DMA_DISABLE_IT: Disable the specified DMA Stream interrupts.
+      (+) __HAL_DMA_GET_IT_SOURCE: Check whether the specified DMA Stream interrupt has occurred or not.
+
+     [..]
+      (@) You can refer to the DMA HAL driver header file for more useful macros.
+
+  @endverbatim
+  */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32h7xx_hal.h"
+
+/** @addtogroup STM32H7xx_HAL_Driver
+  * @{
+  */
+
+/** @defgroup DMA DMA
+  * @brief DMA HAL module driver
+  * @{
+  */
+
+#ifdef HAL_DMA_MODULE_ENABLED
+
+/* Private types -------------------------------------------------------------*/
+/** @addtogroup DMA_Private_Types
+  * @{
+  */
+typedef struct
+{
+  __IO uint32_t ISR;   /*!< DMA interrupt status register */
+  __IO uint32_t Reserved0;
+  __IO uint32_t IFCR;  /*!< DMA interrupt flag clear register */
+} DMA_Base_Registers;
+
+typedef struct
+{
+  __IO uint32_t ISR;   /*!< BDMA interrupt status register */
+  __IO uint32_t IFCR;  /*!< BDMA interrupt flag clear register */
+} BDMA_Base_Registers;
+/**
+  * @}
+  */
+
+/* Private variables ---------------------------------------------------------*/
+/* Private constants ---------------------------------------------------------*/
+/** @addtogroup DMA_Private_Constants
+ * @{
+ */
+#define HAL_TIMEOUT_DMA_ABORT         (5U)  /* 5 ms */
+
+#define BDMA_PERIPH_TO_MEMORY         (0x00000000U)                /*!< Peripheral to memory direction */
+#define BDMA_MEMORY_TO_PERIPH         ((uint32_t)BDMA_CCR_DIR)     /*!< Memory to peripheral direction */
+#define BDMA_MEMORY_TO_MEMORY         ((uint32_t)BDMA_CCR_MEM2MEM) /*!< Memory to memory direction     */
+
+/* DMA to BDMA conversion */
+#define DMA_TO_BDMA_DIRECTION(__DMA_DIRECTION__) (((__DMA_DIRECTION__) == DMA_MEMORY_TO_PERIPH)? BDMA_MEMORY_TO_PERIPH: \
+                                                  ((__DMA_DIRECTION__) == DMA_MEMORY_TO_MEMORY)? BDMA_MEMORY_TO_MEMORY: \
+                                                  BDMA_PERIPH_TO_MEMORY)
+
+#define DMA_TO_BDMA_PERIPHERAL_INC(__DMA_PERIPHERAL_INC__) ((__DMA_PERIPHERAL_INC__) >> 3U)
+#define DMA_TO_BDMA_MEMORY_INC(__DMA_MEMORY_INC__) ((__DMA_MEMORY_INC__) >> 3U)
+
+#define DMA_TO_BDMA_PDATA_SIZE(__DMA_PDATA_SIZE__) ((__DMA_PDATA_SIZE__) >> 3U)
+#define DMA_TO_BDMA_MDATA_SIZE(__DMA_MDATA_SIZE__) ((__DMA_MDATA_SIZE__) >> 3U)
+
+#define DMA_TO_BDMA_MODE(__DMA_MODE__) ((__DMA_MODE__) >> 3U)
+
+#define DMA_TO_BDMA_PRIORITY(__DMA_PRIORITY__) ((__DMA_PRIORITY__) >> 4U)
+
+#if defined(UART9)
+#define IS_DMA_UART_USART_REQUEST(__REQUEST__) ((((__REQUEST__) >= DMA_REQUEST_USART1_RX)  &&  ((__REQUEST__) <= DMA_REQUEST_USART3_TX)) || \
+                                                 (((__REQUEST__) >= DMA_REQUEST_UART4_RX)  &&  ((__REQUEST__) <= DMA_REQUEST_UART5_TX )) || \
+                                                 (((__REQUEST__) >= DMA_REQUEST_USART6_RX) &&  ((__REQUEST__) <= DMA_REQUEST_USART6_TX)) || \
+                                                 (((__REQUEST__) >= DMA_REQUEST_UART7_RX)  &&  ((__REQUEST__) <= DMA_REQUEST_UART8_TX )) || \
+                                                 (((__REQUEST__) >= DMA_REQUEST_UART9_RX)  &&  ((__REQUEST__) <= DMA_REQUEST_USART10_TX )))
+#else
+#define IS_DMA_UART_USART_REQUEST(__REQUEST__) ((((__REQUEST__) >= DMA_REQUEST_USART1_RX)  &&  ((__REQUEST__) <= DMA_REQUEST_USART3_TX)) || \
+                                                 (((__REQUEST__) >= DMA_REQUEST_UART4_RX)  &&  ((__REQUEST__) <= DMA_REQUEST_UART5_TX )) || \
+                                                 (((__REQUEST__) >= DMA_REQUEST_USART6_RX) &&  ((__REQUEST__) <= DMA_REQUEST_USART6_TX)) || \
+                                                 (((__REQUEST__) >= DMA_REQUEST_UART7_RX)  &&  ((__REQUEST__) <= DMA_REQUEST_UART8_TX )))
+
+#endif
+/**
+  * @}
+  */
+/* Private macros ------------------------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+/** @addtogroup DMA_Private_Functions
+  * @{
+  */
+static void DMA_SetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength);
+static uint32_t DMA_CalcBaseAndBitshift(DMA_HandleTypeDef *hdma);
+static HAL_StatusTypeDef DMA_CheckFifoParam(const DMA_HandleTypeDef *hdma);
+static void DMA_CalcDMAMUXChannelBaseAndMask(DMA_HandleTypeDef *hdma);
+static void DMA_CalcDMAMUXRequestGenBaseAndMask(DMA_HandleTypeDef *hdma);
+
+/**
+  * @}
+  */
+
+/* Exported functions ---------------------------------------------------------*/
+/** @addtogroup DMA_Exported_Functions
+  * @{
+  */
+
+/** @addtogroup DMA_Exported_Functions_Group1
+  *
+@verbatim
+ ===============================================================================
+             ##### Initialization and de-initialization functions  #####
+ ===============================================================================
+    [..]
+    This section provides functions allowing to initialize the DMA Stream source
+    and destination incrementation and data sizes, transfer direction,
+    circular/normal mode selection, memory-to-memory mode selection and Stream priority value.
+    [..]
+    The HAL_DMA_Init() function follows the DMA configuration procedures as described in
+    reference manual.
+    The HAL_DMA_DeInit function allows to deinitialize the DMA stream.
+
+@endverbatim
+  * @{
+  */
+
+/**
+  * @brief  Initialize the DMA according to the specified
+  *         parameters in the DMA_InitTypeDef and create the associated handle.
+  * @param  hdma: Pointer to a DMA_HandleTypeDef structure that contains
+  *               the configuration information for the specified DMA Stream.
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_DMA_Init(DMA_HandleTypeDef *hdma)
+{
+  uint32_t registerValue;
+  uint32_t tickstart = HAL_GetTick();
+  DMA_Base_Registers *regs_dma;
+  BDMA_Base_Registers *regs_bdma;
+
+  /* Check the DMA peripheral handle */
+  if(hdma == NULL)
+  {
+    return HAL_ERROR;
+  }
+
+  /* Check the parameters */
+  assert_param(IS_DMA_ALL_INSTANCE(hdma->Instance));
+  assert_param(IS_DMA_DIRECTION(hdma->Init.Direction));
+  assert_param(IS_DMA_PERIPHERAL_INC_STATE(hdma->Init.PeriphInc));
+  assert_param(IS_DMA_MEMORY_INC_STATE(hdma->Init.MemInc));
+  assert_param(IS_DMA_PERIPHERAL_DATA_SIZE(hdma->Init.PeriphDataAlignment));
+  assert_param(IS_DMA_MEMORY_DATA_SIZE(hdma->Init.MemDataAlignment));
+  assert_param(IS_DMA_MODE(hdma->Init.Mode));
+  assert_param(IS_DMA_PRIORITY(hdma->Init.Priority));
+
+  if(IS_DMA_STREAM_INSTANCE(hdma->Instance) != 0U) /* DMA1 or DMA2 instance */
+  {
+    assert_param(IS_DMA_REQUEST(hdma->Init.Request));
+    assert_param(IS_DMA_FIFO_MODE_STATE(hdma->Init.FIFOMode));
+    /* Check the memory burst, peripheral burst and FIFO threshold parameters only
+       when FIFO mode is enabled */
+    if(hdma->Init.FIFOMode != DMA_FIFOMODE_DISABLE)
+    {
+      assert_param(IS_DMA_FIFO_THRESHOLD(hdma->Init.FIFOThreshold));
+      assert_param(IS_DMA_MEMORY_BURST(hdma->Init.MemBurst));
+      assert_param(IS_DMA_PERIPHERAL_BURST(hdma->Init.PeriphBurst));
+    }
+
+    /* Change DMA peripheral state */
+    hdma->State = HAL_DMA_STATE_BUSY;
+
+    /* Allocate lock resource */
+    __HAL_UNLOCK(hdma);
+
+    /* Disable the peripheral */
+    __HAL_DMA_DISABLE(hdma);
+
+    /* Check if the DMA Stream is effectively disabled */
+    while((((DMA_Stream_TypeDef   *)hdma->Instance)->CR & DMA_SxCR_EN) != 0U)
+    {
+      /* Check for the Timeout */
+      if((HAL_GetTick() - tickstart ) > HAL_TIMEOUT_DMA_ABORT)
+      {
+        /* Update error code */
+        hdma->ErrorCode = HAL_DMA_ERROR_TIMEOUT;
+
+        /* Change the DMA state */
+        hdma->State = HAL_DMA_STATE_ERROR;
+
+        return HAL_ERROR;
+      }
+    }
+
+    /* Get the CR register value */
+    registerValue = ((DMA_Stream_TypeDef   *)hdma->Instance)->CR;
+
+    /* Clear CHSEL, MBURST, PBURST, PL, MSIZE, PSIZE, MINC, PINC, CIRC, DIR, CT and DBM bits */
+    registerValue &= ((uint32_t)~(DMA_SxCR_MBURST | DMA_SxCR_PBURST | \
+                        DMA_SxCR_PL    | DMA_SxCR_MSIZE  | DMA_SxCR_PSIZE  | \
+                        DMA_SxCR_MINC  | DMA_SxCR_PINC   | DMA_SxCR_CIRC   | \
+                        DMA_SxCR_DIR   | DMA_SxCR_CT     | DMA_SxCR_DBM));
+
+    /* Prepare the DMA Stream configuration */
+    registerValue |=  hdma->Init.Direction           |
+            hdma->Init.PeriphInc           | hdma->Init.MemInc           |
+            hdma->Init.PeriphDataAlignment | hdma->Init.MemDataAlignment |
+            hdma->Init.Mode                | hdma->Init.Priority;
+
+    /* the Memory burst and peripheral burst are not used when the FIFO is disabled */
+    if(hdma->Init.FIFOMode == DMA_FIFOMODE_ENABLE)
+    {
+      /* Get memory burst and peripheral burst */
+      registerValue |=  hdma->Init.MemBurst | hdma->Init.PeriphBurst;
+    }
+
+    /* Work around for Errata 2.22: UART/USART- DMA transfer lock: DMA stream could be
+                                    lock when transferring data to/from USART/UART */
+#if (STM32H7_DEV_ID == 0x450UL)
+    if((DBGMCU->IDCODE & 0xFFFF0000U) >= 0x20000000U)
+    {
+#endif /* STM32H7_DEV_ID == 0x450UL */
+      if(IS_DMA_UART_USART_REQUEST(hdma->Init.Request) != 0U)
+      {
+        registerValue |= DMA_SxCR_TRBUFF;
+      }
+#if (STM32H7_DEV_ID == 0x450UL)
+    }
+#endif /* STM32H7_DEV_ID == 0x450UL */
+
+    /* Write to DMA Stream CR register */
+    ((DMA_Stream_TypeDef   *)hdma->Instance)->CR = registerValue;
+
+    /* Get the FCR register value */
+    registerValue = ((DMA_Stream_TypeDef   *)hdma->Instance)->FCR;
+
+    /* Clear Direct mode and FIFO threshold bits */
+    registerValue &= (uint32_t)~(DMA_SxFCR_DMDIS | DMA_SxFCR_FTH);
+
+    /* Prepare the DMA Stream FIFO configuration */
+    registerValue |= hdma->Init.FIFOMode;
+
+    /* the FIFO threshold is not used when the FIFO mode is disabled */
+    if(hdma->Init.FIFOMode == DMA_FIFOMODE_ENABLE)
+    {
+      /* Get the FIFO threshold */
+      registerValue |= hdma->Init.FIFOThreshold;
+
+      /* Check compatibility between FIFO threshold level and size of the memory burst */
+      /* for INCR4, INCR8, INCR16 */
+      if(hdma->Init.MemBurst != DMA_MBURST_SINGLE)
+      {
+        if (DMA_CheckFifoParam(hdma) != HAL_OK)
+        {
+          /* Update error code */
+          hdma->ErrorCode = HAL_DMA_ERROR_PARAM;
+
+          /* Change the DMA state */
+          hdma->State = HAL_DMA_STATE_READY;
+
+          return HAL_ERROR;
+        }
+      }
+    }
+
+    /* Write to DMA Stream FCR */
+    ((DMA_Stream_TypeDef   *)hdma->Instance)->FCR = registerValue;
+
+    /* Initialize StreamBaseAddress and StreamIndex parameters to be used to calculate
+       DMA steam Base Address needed by HAL_DMA_IRQHandler() and HAL_DMA_PollForTransfer() */
+    regs_dma = (DMA_Base_Registers *)DMA_CalcBaseAndBitshift(hdma);
+
+    /* Clear all interrupt flags */
+    regs_dma->IFCR = 0x3FUL << (hdma->StreamIndex & 0x1FU);
+  }
+  else if(IS_BDMA_CHANNEL_INSTANCE(hdma->Instance) != 0U) /* BDMA instance(s) */
+  {
+    if(IS_BDMA_CHANNEL_DMAMUX_INSTANCE(hdma->Instance) != 0U)
+    {
+      /* Check the request parameter */
+      assert_param(IS_BDMA_REQUEST(hdma->Init.Request));
+    }
+
+    /* Change DMA peripheral state */
+    hdma->State = HAL_DMA_STATE_BUSY;
+
+    /* Allocate lock resource */
+    __HAL_UNLOCK(hdma);
+
+    /* Get the CR register value */
+    registerValue = ((BDMA_Channel_TypeDef *)hdma->Instance)->CCR;
+
+    /* Clear PL, MSIZE, PSIZE, MINC, PINC, CIRC, DIR, MEM2MEM, DBM and CT bits */
+    registerValue &= ((uint32_t)~(BDMA_CCR_PL    | BDMA_CCR_MSIZE   | BDMA_CCR_PSIZE  | \
+                                  BDMA_CCR_MINC  | BDMA_CCR_PINC    | BDMA_CCR_CIRC   | \
+                                  BDMA_CCR_DIR   | BDMA_CCR_MEM2MEM | BDMA_CCR_DBM    | \
+                                  BDMA_CCR_CT));
+
+    /* Prepare the DMA Channel configuration */
+    registerValue |=  DMA_TO_BDMA_DIRECTION(hdma->Init.Direction)            |
+                      DMA_TO_BDMA_PERIPHERAL_INC(hdma->Init.PeriphInc)       |
+                      DMA_TO_BDMA_MEMORY_INC(hdma->Init.MemInc)              |
+                      DMA_TO_BDMA_PDATA_SIZE(hdma->Init.PeriphDataAlignment) |
+                      DMA_TO_BDMA_MDATA_SIZE(hdma->Init.MemDataAlignment)    |
+                      DMA_TO_BDMA_MODE(hdma->Init.Mode)                      |
+                      DMA_TO_BDMA_PRIORITY(hdma->Init.Priority);
+
+    /* Write to DMA Channel CR register */
+    ((BDMA_Channel_TypeDef *)hdma->Instance)->CCR = registerValue;
+
+    /* calculation of the channel index */
+    hdma->StreamIndex = (((uint32_t)((uint32_t*)hdma->Instance) - (uint32_t)BDMA_Channel0) / ((uint32_t)BDMA_Channel1 - (uint32_t)BDMA_Channel0)) << 2U;
+
+    /* Initialize StreamBaseAddress and StreamIndex parameters to be used to calculate
+    DMA steam Base Address needed by HAL_DMA_IRQHandler() and HAL_DMA_PollForTransfer() */
+    regs_bdma = (BDMA_Base_Registers *)DMA_CalcBaseAndBitshift(hdma);
+
+    /* Clear all interrupt flags */
+    regs_bdma->IFCR = ((BDMA_IFCR_CGIF0) << (hdma->StreamIndex & 0x1FU));
+  }
+  else
+  {
+    hdma->ErrorCode = HAL_DMA_ERROR_PARAM;
+    hdma->State     = HAL_DMA_STATE_ERROR;
+
+    return HAL_ERROR;
+  }
+
+  if(IS_DMA_DMAMUX_ALL_INSTANCE(hdma->Instance) != 0U) /* No DMAMUX available for BDMA1 */
+  {
+    /* Initialize parameters for DMAMUX channel :
+    DMAmuxChannel, DMAmuxChannelStatus and DMAmuxChannelStatusMask
+    */
+    DMA_CalcDMAMUXChannelBaseAndMask(hdma);
+
+    if(hdma->Init.Direction == DMA_MEMORY_TO_MEMORY)
+    {
+      /* if memory to memory force the request to 0*/
+      hdma->Init.Request = DMA_REQUEST_MEM2MEM;
+    }
+
+    /* Set peripheral request  to DMAMUX channel */
+    hdma->DMAmuxChannel->CCR = (hdma->Init.Request & DMAMUX_CxCR_DMAREQ_ID);
+
+    /* Clear the DMAMUX synchro overrun flag */
+    hdma->DMAmuxChannelStatus->CFR = hdma->DMAmuxChannelStatusMask;
+
+    /* Initialize parameters for DMAMUX request generator :
+    if the DMA request is DMA_REQUEST_GENERATOR0 to DMA_REQUEST_GENERATOR7
+    */
+    if((hdma->Init.Request >= DMA_REQUEST_GENERATOR0) && (hdma->Init.Request <= DMA_REQUEST_GENERATOR7))
+    {
+      /* Initialize parameters for DMAMUX request generator :
+      DMAmuxRequestGen, DMAmuxRequestGenStatus and DMAmuxRequestGenStatusMask */
+      DMA_CalcDMAMUXRequestGenBaseAndMask(hdma);
+
+      /* Reset the DMAMUX request generator register */
+      hdma->DMAmuxRequestGen->RGCR = 0U;
+
+      /* Clear the DMAMUX request generator overrun flag */
+      hdma->DMAmuxRequestGenStatus->RGCFR = hdma->DMAmuxRequestGenStatusMask;
+    }
+    else
+    {
+      hdma->DMAmuxRequestGen = 0U;
+      hdma->DMAmuxRequestGenStatus = 0U;
+      hdma->DMAmuxRequestGenStatusMask = 0U;
+    }
+  }
+
+  /* Initialize the error code */
+  hdma->ErrorCode = HAL_DMA_ERROR_NONE;
+
+  /* Initialize the DMA state */
+  hdma->State = HAL_DMA_STATE_READY;
+
+  return HAL_OK;
+}
+
+/**
+  * @brief  DeInitializes the DMA peripheral
+  * @param  hdma: pointer to a DMA_HandleTypeDef structure that contains
+  *               the configuration information for the specified DMA Stream.
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_DMA_DeInit(DMA_HandleTypeDef *hdma)
+{
+  DMA_Base_Registers *regs_dma;
+  BDMA_Base_Registers *regs_bdma;
+
+  /* Check the DMA peripheral handle */
+  if(hdma == NULL)
+  {
+    return HAL_ERROR;
+  }
+
+  /* Disable the selected DMA Streamx */
+  __HAL_DMA_DISABLE(hdma);
+
+  if(IS_DMA_STREAM_INSTANCE(hdma->Instance) != 0U) /* DMA1 or DMA2 instance */
+  {
+    /* Reset DMA Streamx control register */
+    ((DMA_Stream_TypeDef   *)hdma->Instance)->CR   = 0U;
+
+    /* Reset DMA Streamx number of data to transfer register */
+    ((DMA_Stream_TypeDef   *)hdma->Instance)->NDTR = 0U;
+
+    /* Reset DMA Streamx peripheral address register */
+    ((DMA_Stream_TypeDef   *)hdma->Instance)->PAR  = 0U;
+
+    /* Reset DMA Streamx memory 0 address register */
+    ((DMA_Stream_TypeDef   *)hdma->Instance)->M0AR = 0U;
+
+    /* Reset DMA Streamx memory 1 address register */
+    ((DMA_Stream_TypeDef   *)hdma->Instance)->M1AR = 0U;
+
+    /* Reset DMA Streamx FIFO control register */
+    ((DMA_Stream_TypeDef   *)hdma->Instance)->FCR  = (uint32_t)0x00000021U;
+
+    /* Get DMA steam Base Address */
+    regs_dma = (DMA_Base_Registers *)DMA_CalcBaseAndBitshift(hdma);
+
+    /* Clear all interrupt flags at correct offset within the register */
+    regs_dma->IFCR = 0x3FUL << (hdma->StreamIndex & 0x1FU);
+  }
+  else if(IS_BDMA_CHANNEL_INSTANCE(hdma->Instance) != 0U) /* BDMA instance(s) */
+  {
+    /* Reset DMA Channel control register */
+    ((BDMA_Channel_TypeDef *)hdma->Instance)->CCR  = 0U;
+
+    /* Reset DMA Channel Number of Data to Transfer register */
+    ((BDMA_Channel_TypeDef *)hdma->Instance)->CNDTR = 0U;
+
+    /* Reset DMA Channel peripheral address register */
+    ((BDMA_Channel_TypeDef *)hdma->Instance)->CPAR  = 0U;
+
+    /* Reset DMA Channel memory 0 address register */
+    ((BDMA_Channel_TypeDef *)hdma->Instance)->CM0AR = 0U;
+
+    /* Reset DMA Channel memory 1 address register */
+    ((BDMA_Channel_TypeDef *)hdma->Instance)->CM1AR = 0U;
+
+    /* Get DMA steam Base Address */
+    regs_bdma = (BDMA_Base_Registers *)DMA_CalcBaseAndBitshift(hdma);
+
+    /* Clear all interrupt flags at correct offset within the register */
+    regs_bdma->IFCR = ((BDMA_IFCR_CGIF0) << (hdma->StreamIndex & 0x1FU));
+  }
+  else
+  {
+    /* Return error status */
+    return HAL_ERROR;
+  }
+
+#if defined (BDMA1) /* No DMAMUX available for BDMA1 available on  STM32H7Ax/Bx devices only */
+  if(IS_DMA_DMAMUX_ALL_INSTANCE(hdma->Instance) != 0U) /* No DMAMUX available for BDMA1 */
+#endif /* BDMA1 */
+  {
+    /* Initialize parameters for DMAMUX channel :
+    DMAmuxChannel, DMAmuxChannelStatus and DMAmuxChannelStatusMask */
+    DMA_CalcDMAMUXChannelBaseAndMask(hdma);
+
+    if(hdma->DMAmuxChannel != 0U)
+    {
+      /* Resett he DMAMUX channel that corresponds to the DMA stream */
+      hdma->DMAmuxChannel->CCR = 0U;
+
+      /* Clear the DMAMUX synchro overrun flag */
+      hdma->DMAmuxChannelStatus->CFR = hdma->DMAmuxChannelStatusMask;
+    }
+
+    if((hdma->Init.Request >= DMA_REQUEST_GENERATOR0) && (hdma->Init.Request <= DMA_REQUEST_GENERATOR7))
+    {
+      /* Initialize parameters for DMAMUX request generator :
+      DMAmuxRequestGen, DMAmuxRequestGenStatus and DMAmuxRequestGenStatusMask */
+      DMA_CalcDMAMUXRequestGenBaseAndMask(hdma);
+
+      /* Reset the DMAMUX request generator register */
+      hdma->DMAmuxRequestGen->RGCR = 0U;
+
+      /* Clear the DMAMUX request generator overrun flag */
+      hdma->DMAmuxRequestGenStatus->RGCFR = hdma->DMAmuxRequestGenStatusMask;
+    }
+
+    hdma->DMAmuxRequestGen = 0U;
+    hdma->DMAmuxRequestGenStatus = 0U;
+    hdma->DMAmuxRequestGenStatusMask = 0U;
+  }
+
+
+  /* Clean callbacks */
+  hdma->XferCpltCallback       = NULL;
+  hdma->XferHalfCpltCallback   = NULL;
+  hdma->XferM1CpltCallback     = NULL;
+  hdma->XferM1HalfCpltCallback = NULL;
+  hdma->XferErrorCallback      = NULL;
+  hdma->XferAbortCallback      = NULL;
+
+  /* Initialize the error code */
+  hdma->ErrorCode = HAL_DMA_ERROR_NONE;
+
+  /* Initialize the DMA state */
+  hdma->State = HAL_DMA_STATE_RESET;
+
+  /* Release Lock */
+  __HAL_UNLOCK(hdma);
+
+  return HAL_OK;
+}
+
+/**
+  * @}
+  */
+
+/** @addtogroup DMA_Exported_Functions_Group2
+  *
+@verbatim
+ ===============================================================================
+                      #####  IO operation functions  #####
+ ===============================================================================
+    [..]  This section provides functions allowing to:
+      (+) Configure the source, destination address and data length and Start DMA transfer
+      (+) Configure the source, destination address and data length and
+          Start DMA transfer with interrupt
+      (+) Register and Unregister DMA callbacks
+      (+) Abort DMA transfer
+      (+) Poll for transfer complete
+      (+) Handle DMA interrupt request
+
+@endverbatim
+  * @{
+  */
+
+/**
+  * @brief  Starts the DMA Transfer.
+  * @param  hdma      : pointer to a DMA_HandleTypeDef structure that contains
+  *                     the configuration information for the specified DMA Stream.
+  * @param  SrcAddress: The source memory Buffer address
+  * @param  DstAddress: The destination memory Buffer address
+  * @param  DataLength: The length of data to be transferred from source to destination
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_DMA_Start(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
+{
+  HAL_StatusTypeDef status = HAL_OK;
+
+  /* Check the parameters */
+  assert_param(IS_DMA_BUFFER_SIZE(DataLength));
+
+  /* Check the DMA peripheral handle */
+  if(hdma == NULL)
+  {
+    return HAL_ERROR;
+  }
+
+  /* Process locked */
+  __HAL_LOCK(hdma);
+
+  if(HAL_DMA_STATE_READY == hdma->State)
+  {
+    /* Change DMA peripheral state */
+    hdma->State = HAL_DMA_STATE_BUSY;
+
+    /* Initialize the error code */
+    hdma->ErrorCode = HAL_DMA_ERROR_NONE;
+
+    /* Disable the peripheral */
+    __HAL_DMA_DISABLE(hdma);
+
+    /* Configure the source, destination address and the data length */
+    DMA_SetConfig(hdma, SrcAddress, DstAddress, DataLength);
+
+    /* Enable the Peripheral */
+    __HAL_DMA_ENABLE(hdma);
+  }
+  else
+  {
+    /* Set the error code to busy */
+    hdma->ErrorCode = HAL_DMA_ERROR_BUSY;
+
+    /* Process unlocked */
+    __HAL_UNLOCK(hdma);
+
+    /* Return error status */
+    status = HAL_ERROR;
+  }
+  return status;
+}
+
+/**
+  * @brief  Start the DMA Transfer with interrupt enabled.
+  * @param  hdma:       pointer to a DMA_HandleTypeDef structure that contains
+  *                     the configuration information for the specified DMA Stream.
+  * @param  SrcAddress: The source memory Buffer address
+  * @param  DstAddress: The destination memory Buffer address
+  * @param  DataLength: The length of data to be transferred from source to destination
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_DMA_Start_IT(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
+{
+  HAL_StatusTypeDef status = HAL_OK;
+
+  /* Check the parameters */
+  assert_param(IS_DMA_BUFFER_SIZE(DataLength));
+
+  /* Check the DMA peripheral handle */
+  if(hdma == NULL)
+  {
+    return HAL_ERROR;
+  }
+
+  /* Process locked */
+  __HAL_LOCK(hdma);
+
+  if(HAL_DMA_STATE_READY == hdma->State)
+  {
+    /* Change DMA peripheral state */
+    hdma->State = HAL_DMA_STATE_BUSY;
+
+    /* Initialize the error code */
+    hdma->ErrorCode = HAL_DMA_ERROR_NONE;
+
+    /* Disable the peripheral */
+    __HAL_DMA_DISABLE(hdma);
+
+    /* Configure the source, destination address and the data length */
+    DMA_SetConfig(hdma, SrcAddress, DstAddress, DataLength);
+
+    if(IS_DMA_STREAM_INSTANCE(hdma->Instance) != 0U) /* DMA1 or DMA2 instance */
+    {
+      /* Enable Common interrupts*/
+      MODIFY_REG(((DMA_Stream_TypeDef   *)hdma->Instance)->CR, (DMA_IT_TC | DMA_IT_TE | DMA_IT_DME | DMA_IT_HT), (DMA_IT_TC | DMA_IT_TE | DMA_IT_DME));
+
+      if(hdma->XferHalfCpltCallback != NULL)
+      {
+        /* Enable Half Transfer IT if corresponding Callback is set */
+        ((DMA_Stream_TypeDef   *)hdma->Instance)->CR  |= DMA_IT_HT;
+      }
+    }
+    else /* BDMA channel */
+    {
+      /* Enable Common interrupts */
+      MODIFY_REG(((BDMA_Channel_TypeDef   *)hdma->Instance)->CCR, (BDMA_CCR_TCIE | BDMA_CCR_HTIE | BDMA_CCR_TEIE), (BDMA_CCR_TCIE | BDMA_CCR_TEIE));
+
+      if(hdma->XferHalfCpltCallback != NULL)
+      {
+        /*Enable Half Transfer IT if corresponding Callback is set */
+        ((BDMA_Channel_TypeDef   *)hdma->Instance)->CCR  |= BDMA_CCR_HTIE;
+      }
+    }
+
+    if(IS_DMA_DMAMUX_ALL_INSTANCE(hdma->Instance) != 0U) /* No DMAMUX available for BDMA1 */
+    {
+      /* Check if DMAMUX Synchronization is enabled */
+      if((hdma->DMAmuxChannel->CCR & DMAMUX_CxCR_SE) != 0U)
+      {
+        /* Enable DMAMUX sync overrun IT*/
+        hdma->DMAmuxChannel->CCR |= DMAMUX_CxCR_SOIE;
+      }
+
+      if(hdma->DMAmuxRequestGen != 0U)
+      {
+        /* if using DMAMUX request generator, enable the DMAMUX request generator overrun IT*/
+        /* enable the request gen overrun IT */
+        hdma->DMAmuxRequestGen->RGCR |= DMAMUX_RGxCR_OIE;
+      }
+    }
+
+    /* Enable the Peripheral */
+    __HAL_DMA_ENABLE(hdma);
+  }
+  else
+  {
+    /* Set the error code to busy */
+    hdma->ErrorCode = HAL_DMA_ERROR_BUSY;
+
+    /* Process unlocked */
+    __HAL_UNLOCK(hdma);
+
+    /* Return error status */
+    status = HAL_ERROR;
+  }
+
+  return status;
+}
+
+/**
+  * @brief  Aborts the DMA Transfer.
+  * @param  hdma  : pointer to a DMA_HandleTypeDef structure that contains
+  *                 the configuration information for the specified DMA Stream.
+  *
+  * @note  After disabling a DMA Stream, a check for wait until the DMA Stream is
+  *        effectively disabled is added. If a Stream is disabled
+  *        while a data transfer is ongoing, the current data will be transferred
+  *        and the Stream will be effectively disabled only after the transfer of
+  *        this single data is finished.
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_DMA_Abort(DMA_HandleTypeDef *hdma)
+{
+  /* calculate DMA base and stream number */
+  DMA_Base_Registers *regs_dma;
+  BDMA_Base_Registers *regs_bdma;
+  const __IO uint32_t *enableRegister;
+
+  uint32_t tickstart = HAL_GetTick();
+
+ /* Check the DMA peripheral handle */
+  if(hdma == NULL)
+  {
+    return HAL_ERROR;
+  }
+
+  /* Check the DMA peripheral state */
+  if(hdma->State != HAL_DMA_STATE_BUSY)
+  {
+    hdma->ErrorCode = HAL_DMA_ERROR_NO_XFER;
+
+    /* Process Unlocked */
+    __HAL_UNLOCK(hdma);
+
+    return HAL_ERROR;
+  }
+  else
+  {
+    /* Disable all the transfer interrupts */
+    if(IS_DMA_STREAM_INSTANCE(hdma->Instance) != 0U) /* DMA1 or DMA2 instance */
+    {
+       /* Disable DMA All Interrupts  */
+      ((DMA_Stream_TypeDef   *)hdma->Instance)->CR  &= ~(DMA_IT_TC | DMA_IT_TE | DMA_IT_DME | DMA_IT_HT);
+      ((DMA_Stream_TypeDef   *)hdma->Instance)->FCR &= ~(DMA_IT_FE);
+
+      enableRegister = (__IO uint32_t *)(&(((DMA_Stream_TypeDef   *)hdma->Instance)->CR));
+    }
+    else /* BDMA channel */
+    {
+      /* Disable DMA All Interrupts */
+      ((BDMA_Channel_TypeDef   *)hdma->Instance)->CCR  &= ~(BDMA_CCR_TCIE | BDMA_CCR_HTIE | BDMA_CCR_TEIE);
+
+      enableRegister = (__IO uint32_t *)(&(((BDMA_Channel_TypeDef   *)hdma->Instance)->CCR));
+    }
+
+    if(IS_DMA_DMAMUX_ALL_INSTANCE(hdma->Instance) != 0U) /* No DMAMUX available for BDMA1 */
+    {
+      /* disable the DMAMUX sync overrun IT */
+      hdma->DMAmuxChannel->CCR &= ~DMAMUX_CxCR_SOIE;
+    }
+
+    /* Disable the stream */
+    __HAL_DMA_DISABLE(hdma);
+
+    /* Check if the DMA Stream is effectively disabled */
+    while(((*enableRegister) & DMA_SxCR_EN) != 0U)
+    {
+      /* Check for the Timeout */
+      if((HAL_GetTick() - tickstart ) > HAL_TIMEOUT_DMA_ABORT)
+      {
+        /* Update error code */
+        hdma->ErrorCode = HAL_DMA_ERROR_TIMEOUT;
+
+        /* Change the DMA state */
+        hdma->State = HAL_DMA_STATE_ERROR;
+
+        /* Process Unlocked */
+        __HAL_UNLOCK(hdma);
+
+        return HAL_ERROR;
+      }
+    }
+
+    /* Clear all interrupt flags at correct offset within the register */
+    if(IS_DMA_STREAM_INSTANCE(hdma->Instance) != 0U) /* DMA1 or DMA2 instance */
+    {
+      regs_dma = (DMA_Base_Registers *)hdma->StreamBaseAddress;
+      regs_dma->IFCR = 0x3FUL << (hdma->StreamIndex & 0x1FU);
+    }
+    else /* BDMA channel */
+    {
+      regs_bdma = (BDMA_Base_Registers *)hdma->StreamBaseAddress;
+      regs_bdma->IFCR = ((BDMA_IFCR_CGIF0) << (hdma->StreamIndex & 0x1FU));
+    }
+
+    if(IS_DMA_DMAMUX_ALL_INSTANCE(hdma->Instance) != 0U) /* No DMAMUX available for BDMA1 */
+    {
+      /* Clear the DMAMUX synchro overrun flag */
+      hdma->DMAmuxChannelStatus->CFR = hdma->DMAmuxChannelStatusMask;
+
+      if(hdma->DMAmuxRequestGen != 0U)
+      {
+        /* if using DMAMUX request generator, disable the DMAMUX request generator overrun IT */
+        /* disable the request gen overrun IT */
+        hdma->DMAmuxRequestGen->RGCR &= ~DMAMUX_RGxCR_OIE;
+
+        /* Clear the DMAMUX request generator overrun flag */
+        hdma->DMAmuxRequestGenStatus->RGCFR = hdma->DMAmuxRequestGenStatusMask;
+      }
+    }
+
+    /* Change the DMA state */
+    hdma->State = HAL_DMA_STATE_READY;
+
+    /* Process Unlocked */
+    __HAL_UNLOCK(hdma);
+  }
+
+  return HAL_OK;
+}
+
+/**
+  * @brief  Aborts the DMA Transfer in Interrupt mode.
+  * @param  hdma  : pointer to a DMA_HandleTypeDef structure that contains
+  *                 the configuration information for the specified DMA Stream.
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_DMA_Abort_IT(DMA_HandleTypeDef *hdma)
+{
+  BDMA_Base_Registers *regs_bdma;
+
+  /* Check the DMA peripheral handle */
+  if(hdma == NULL)
+  {
+    return HAL_ERROR;
+  }
+
+  if(hdma->State != HAL_DMA_STATE_BUSY)
+  {
+    hdma->ErrorCode = HAL_DMA_ERROR_NO_XFER;
+    return HAL_ERROR;
+  }
+  else
+  {
+    if(IS_DMA_STREAM_INSTANCE(hdma->Instance) != 0U) /* DMA1 or DMA2 instance */
+    {
+      /* Set Abort State  */
+      hdma->State = HAL_DMA_STATE_ABORT;
+
+      /* Disable the stream */
+      __HAL_DMA_DISABLE(hdma);
+    }
+    else /* BDMA channel */
+    {
+      /* Disable DMA All Interrupts  */
+      ((BDMA_Channel_TypeDef   *)hdma->Instance)->CCR  &= ~(BDMA_CCR_TCIE | BDMA_CCR_HTIE | BDMA_CCR_TEIE);
+
+      /* Disable the channel */
+      __HAL_DMA_DISABLE(hdma);
+
+      if(IS_DMA_DMAMUX_ALL_INSTANCE(hdma->Instance) != 0U) /* No DMAMUX available for BDMA1 */
+      {
+        /* disable the DMAMUX sync overrun IT */
+        hdma->DMAmuxChannel->CCR &= ~DMAMUX_CxCR_SOIE;
+
+        /* Clear all flags */
+        regs_bdma = (BDMA_Base_Registers *)hdma->StreamBaseAddress;
+        regs_bdma->IFCR = ((BDMA_IFCR_CGIF0) << (hdma->StreamIndex & 0x1FU));
+
+        /* Clear the DMAMUX synchro overrun flag */
+        hdma->DMAmuxChannelStatus->CFR = hdma->DMAmuxChannelStatusMask;
+
+        if(hdma->DMAmuxRequestGen != 0U)
+        {
+          /* if using DMAMUX request generator, disable the DMAMUX request generator overrun IT*/
+          /* disable the request gen overrun IT */
+          hdma->DMAmuxRequestGen->RGCR &= ~DMAMUX_RGxCR_OIE;
+
+          /* Clear the DMAMUX request generator overrun flag */
+          hdma->DMAmuxRequestGenStatus->RGCFR = hdma->DMAmuxRequestGenStatusMask;
+        }
+      }
+
+      /* Change the DMA state */
+      hdma->State = HAL_DMA_STATE_READY;
+
+      /* Process Unlocked */
+      __HAL_UNLOCK(hdma);
+
+      /* Call User Abort callback */
+      if(hdma->XferAbortCallback != NULL)
+      {
+        hdma->XferAbortCallback(hdma);
+      }
+    }
+  }
+
+  return HAL_OK;
+}
+
+/**
+  * @brief  Polling for transfer complete.
+  * @param  hdma:          pointer to a DMA_HandleTypeDef structure that contains
+  *                        the configuration information for the specified DMA Stream.
+  * @param  CompleteLevel: Specifies the DMA level complete.
+  * @note   The polling mode is kept in this version for legacy. it is recommended to use the IT model instead.
+  *         This model could be used for debug purpose.
+  * @note   The HAL_DMA_PollForTransfer API cannot be used in circular and double buffering mode (automatic circular mode).
+  * @param  Timeout:       Timeout duration.
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_DMA_PollForTransfer(DMA_HandleTypeDef *hdma, HAL_DMA_LevelCompleteTypeDef CompleteLevel, uint32_t Timeout)
+{
+  HAL_StatusTypeDef status = HAL_OK;
+  uint32_t cpltlevel_mask;
+  uint32_t tickstart = HAL_GetTick();
+
+  /* IT status register */
+  __IO uint32_t *isr_reg;
+  /* IT clear flag register */
+  __IO uint32_t *ifcr_reg;
+
+  /* Check the DMA peripheral handle */
+  if(hdma == NULL)
+  {
+    return HAL_ERROR;
+  }
+
+  if(HAL_DMA_STATE_BUSY != hdma->State)
+  {
+    /* No transfer ongoing */
+    hdma->ErrorCode = HAL_DMA_ERROR_NO_XFER;
+    __HAL_UNLOCK(hdma);
+
+    return HAL_ERROR;
+  }
+
+  if(IS_DMA_STREAM_INSTANCE(hdma->Instance) != 0U) /* DMA1 or DMA2 instance */
+  {
+    /* Polling mode not supported in circular mode and double buffering mode */
+    if ((((DMA_Stream_TypeDef   *)hdma->Instance)->CR & DMA_SxCR_CIRC) != 0U)
+    {
+      hdma->ErrorCode = HAL_DMA_ERROR_NOT_SUPPORTED;
+      return HAL_ERROR;
+    }
+
+    /* Get the level transfer complete flag */
+    if(CompleteLevel == HAL_DMA_FULL_TRANSFER)
+    {
+      /* Transfer Complete flag */
+      cpltlevel_mask = DMA_FLAG_TCIF0_4 << (hdma->StreamIndex & 0x1FU);
+    }
+    else
+    {
+      /* Half Transfer Complete flag */
+      cpltlevel_mask = DMA_FLAG_HTIF0_4 << (hdma->StreamIndex & 0x1FU);
+    }
+
+    isr_reg  = &(((DMA_Base_Registers *)hdma->StreamBaseAddress)->ISR);
+    ifcr_reg = &(((DMA_Base_Registers *)hdma->StreamBaseAddress)->IFCR);
+  }
+  else /* BDMA channel */
+  {
+    /* Polling mode not supported in circular mode */
+    if ((((BDMA_Channel_TypeDef   *)hdma->Instance)->CCR & BDMA_CCR_CIRC) != 0U)
+    {
+      hdma->ErrorCode = HAL_DMA_ERROR_NOT_SUPPORTED;
+      return HAL_ERROR;
+    }
+
+    /* Get the level transfer complete flag */
+    if(CompleteLevel == HAL_DMA_FULL_TRANSFER)
+    {
+      /* Transfer Complete flag */
+      cpltlevel_mask = BDMA_FLAG_TC0 << (hdma->StreamIndex & 0x1FU);
+    }
+    else
+    {
+      /* Half Transfer Complete flag */
+      cpltlevel_mask = BDMA_FLAG_HT0 << (hdma->StreamIndex & 0x1FU);
+    }
+
+    isr_reg  = &(((BDMA_Base_Registers *)hdma->StreamBaseAddress)->ISR);
+    ifcr_reg = &(((BDMA_Base_Registers *)hdma->StreamBaseAddress)->IFCR);
+  }
+
+  while(((*isr_reg) & cpltlevel_mask) == 0U)
+  {
+    if(IS_DMA_STREAM_INSTANCE(hdma->Instance) != 0U) /* DMA1 or DMA2 instance */
+    {
+      if(((*isr_reg) & (DMA_FLAG_FEIF0_4 << (hdma->StreamIndex & 0x1FU))) != 0U)
+      {
+        /* Update error code */
+        hdma->ErrorCode |= HAL_DMA_ERROR_FE;
+
+        /* Clear the FIFO error flag */
+        (*ifcr_reg) = DMA_FLAG_FEIF0_4 << (hdma->StreamIndex & 0x1FU);
+      }
+
+      if(((*isr_reg) & (DMA_FLAG_DMEIF0_4 << (hdma->StreamIndex & 0x1FU))) != 0U)
+      {
+        /* Update error code */
+        hdma->ErrorCode |= HAL_DMA_ERROR_DME;
+
+        /* Clear the Direct Mode error flag */
+        (*ifcr_reg) = DMA_FLAG_DMEIF0_4 << (hdma->StreamIndex & 0x1FU);
+      }
+
+      if(((*isr_reg) & (DMA_FLAG_TEIF0_4 << (hdma->StreamIndex & 0x1FU))) != 0U)
+      {
+        /* Update error code */
+        hdma->ErrorCode |= HAL_DMA_ERROR_TE;
+
+        /* Clear the transfer error flag */
+        (*ifcr_reg) = DMA_FLAG_TEIF0_4 << (hdma->StreamIndex & 0x1FU);
+
+        /* Change the DMA state */
+        hdma->State = HAL_DMA_STATE_READY;
+
+        /* Process Unlocked */
+        __HAL_UNLOCK(hdma);
+
+        return HAL_ERROR;
+      }
+    }
+    else /* BDMA channel */
+    {
+      if(((*isr_reg) & (BDMA_FLAG_TE0 << (hdma->StreamIndex & 0x1FU))) != 0U)
+      {
+        /* When a DMA transfer error occurs */
+        /* A hardware clear of its EN bits is performed */
+        /* Clear all flags */
+        (*isr_reg) = ((BDMA_ISR_GIF0) << (hdma->StreamIndex & 0x1FU));
+
+        /* Update error code */
+        hdma->ErrorCode = HAL_DMA_ERROR_TE;
+
+        /* Change the DMA state */
+        hdma->State = HAL_DMA_STATE_READY;
+
+        /* Process Unlocked */
+        __HAL_UNLOCK(hdma);
+
+        return HAL_ERROR;
+      }
+    }
+
+    /* Check for the Timeout (Not applicable in circular mode)*/
+    if(Timeout != HAL_MAX_DELAY)
+    {
+      if(((HAL_GetTick() - tickstart ) > Timeout)||(Timeout == 0U))
+      {
+        /* Update error code */
+        hdma->ErrorCode = HAL_DMA_ERROR_TIMEOUT;
+
+        /* if timeout then abort the current transfer */
+        /* No need to check return value: as in this case we will return HAL_ERROR with HAL_DMA_ERROR_TIMEOUT error code  */
+        (void) HAL_DMA_Abort(hdma);
+          /*
+            Note that the Abort function will
+              - Clear the transfer error flags
+              - Unlock
+              - Set the State
+          */
+
+        return HAL_ERROR;
+      }
+    }
+
+    if(IS_DMA_DMAMUX_ALL_INSTANCE(hdma->Instance) != 0U) /* No DMAMUX available for BDMA1 */
+    {
+      /* Check for DMAMUX Request generator (if used) overrun status */
+      if(hdma->DMAmuxRequestGen != 0U)
+      {
+        /* if using DMAMUX request generator Check for DMAMUX request generator overrun */
+        if((hdma->DMAmuxRequestGenStatus->RGSR & hdma->DMAmuxRequestGenStatusMask) != 0U)
+        {
+          /* Clear the DMAMUX request generator overrun flag */
+          hdma->DMAmuxRequestGenStatus->RGCFR = hdma->DMAmuxRequestGenStatusMask;
+
+          /* Update error code */
+          hdma->ErrorCode |= HAL_DMA_ERROR_REQGEN;
+        }
+      }
+
+      /* Check for DMAMUX Synchronization overrun */
+      if((hdma->DMAmuxChannelStatus->CSR & hdma->DMAmuxChannelStatusMask) != 0U)
+      {
+        /* Clear the DMAMUX synchro overrun flag */
+        hdma->DMAmuxChannelStatus->CFR = hdma->DMAmuxChannelStatusMask;
+
+        /* Update error code */
+        hdma->ErrorCode |= HAL_DMA_ERROR_SYNC;
+      }
+    }
+  }
+
+
+  /* Get the level transfer complete flag */
+  if(CompleteLevel == HAL_DMA_FULL_TRANSFER)
+  {
+    /* Clear the half transfer and transfer complete flags */
+    if(IS_DMA_STREAM_INSTANCE(hdma->Instance) != 0U) /* DMA1 or DMA2 instance */
+    {
+      (*ifcr_reg) = (DMA_FLAG_HTIF0_4 | DMA_FLAG_TCIF0_4) << (hdma->StreamIndex & 0x1FU);
+    }
+    else /* BDMA channel */
+    {
+      (*ifcr_reg) = (BDMA_FLAG_TC0 << (hdma->StreamIndex & 0x1FU));
+    }
+
+    hdma->State = HAL_DMA_STATE_READY;
+
+    /* Process Unlocked */
+    __HAL_UNLOCK(hdma);
+  }
+  else /*CompleteLevel = HAL_DMA_HALF_TRANSFER*/
+  {
+    /* Clear the half transfer and transfer complete flags */
+    if(IS_DMA_STREAM_INSTANCE(hdma->Instance) != 0U) /* DMA1 or DMA2 instance */
+    {
+      (*ifcr_reg) = (DMA_FLAG_HTIF0_4) << (hdma->StreamIndex & 0x1FU);
+    }
+    else /* BDMA channel */
+    {
+      (*ifcr_reg) = (BDMA_FLAG_HT0 << (hdma->StreamIndex & 0x1FU));
+    }
+  }
+
+  return status;
+}
+
+/**
+  * @brief  Handles DMA interrupt request.
+  * @param  hdma: pointer to a DMA_HandleTypeDef structure that contains
+  *               the configuration information for the specified DMA Stream.
+  * @retval None
+  */
+void HAL_DMA_IRQHandler(DMA_HandleTypeDef *hdma)
+{
+  uint32_t tmpisr_dma, tmpisr_bdma;
+  uint32_t ccr_reg;
+  __IO uint32_t count = 0U;
+  uint32_t timeout = SystemCoreClock / 9600U;
+
+  /* calculate DMA base and stream number */
+  DMA_Base_Registers  *regs_dma  = (DMA_Base_Registers *)hdma->StreamBaseAddress;
+  BDMA_Base_Registers *regs_bdma = (BDMA_Base_Registers *)hdma->StreamBaseAddress;
+
+  tmpisr_dma  = regs_dma->ISR;
+  tmpisr_bdma = regs_bdma->ISR;
+
+  if(IS_DMA_STREAM_INSTANCE(hdma->Instance) != 0U)  /* DMA1 or DMA2 instance */
+  {
+    /* Transfer Error Interrupt management ***************************************/
+    if ((tmpisr_dma & (DMA_FLAG_TEIF0_4 << (hdma->StreamIndex & 0x1FU))) != 0U)
+    {
+      if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_TE) != 0U)
+      {
+        /* Disable the transfer error interrupt */
+        ((DMA_Stream_TypeDef   *)hdma->Instance)->CR  &= ~(DMA_IT_TE);
+
+        /* Clear the transfer error flag */
+        regs_dma->IFCR = DMA_FLAG_TEIF0_4 << (hdma->StreamIndex & 0x1FU);
+
+        /* Update error code */
+        hdma->ErrorCode |= HAL_DMA_ERROR_TE;
+      }
+    }
+    /* FIFO Error Interrupt management ******************************************/
+    if ((tmpisr_dma & (DMA_FLAG_FEIF0_4 << (hdma->StreamIndex & 0x1FU))) != 0U)
+    {
+      if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_FE) != 0U)
+      {
+        /* Clear the FIFO error flag */
+        regs_dma->IFCR = DMA_FLAG_FEIF0_4 << (hdma->StreamIndex & 0x1FU);
+
+        /* Update error code */
+        hdma->ErrorCode |= HAL_DMA_ERROR_FE;
+      }
+    }
+    /* Direct Mode Error Interrupt management ***********************************/
+    if ((tmpisr_dma & (DMA_FLAG_DMEIF0_4 << (hdma->StreamIndex & 0x1FU))) != 0U)
+    {
+      if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_DME) != 0U)
+      {
+        /* Clear the direct mode error flag */
+        regs_dma->IFCR = DMA_FLAG_DMEIF0_4 << (hdma->StreamIndex & 0x1FU);
+
+        /* Update error code */
+        hdma->ErrorCode |= HAL_DMA_ERROR_DME;
+      }
+    }
+    /* Half Transfer Complete Interrupt management ******************************/
+    if ((tmpisr_dma & (DMA_FLAG_HTIF0_4 << (hdma->StreamIndex & 0x1FU))) != 0U)
+    {
+      if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_HT) != 0U)
+      {
+        /* Clear the half transfer complete flag */
+        regs_dma->IFCR = DMA_FLAG_HTIF0_4 << (hdma->StreamIndex & 0x1FU);
+
+        /* Multi_Buffering mode enabled */
+        if(((((DMA_Stream_TypeDef   *)hdma->Instance)->CR) & (uint32_t)(DMA_SxCR_DBM)) != 0U)
+        {
+          /* Current memory buffer used is Memory 0 */
+          if((((DMA_Stream_TypeDef   *)hdma->Instance)->CR & DMA_SxCR_CT) == 0U)
+          {
+            if(hdma->XferHalfCpltCallback != NULL)
+            {
+              /* Half transfer callback */
+              hdma->XferHalfCpltCallback(hdma);
+            }
+          }
+          /* Current memory buffer used is Memory 1 */
+          else
+          {
+            if(hdma->XferM1HalfCpltCallback != NULL)
+            {
+              /* Half transfer callback */
+              hdma->XferM1HalfCpltCallback(hdma);
+            }
+          }
+        }
+        else
+        {
+          /* Disable the half transfer interrupt if the DMA mode is not CIRCULAR */
+          if((((DMA_Stream_TypeDef   *)hdma->Instance)->CR & DMA_SxCR_CIRC) == 0U)
+          {
+            /* Disable the half transfer interrupt */
+            ((DMA_Stream_TypeDef   *)hdma->Instance)->CR  &= ~(DMA_IT_HT);
+          }
+
+          if(hdma->XferHalfCpltCallback != NULL)
+          {
+            /* Half transfer callback */
+            hdma->XferHalfCpltCallback(hdma);
+          }
+        }
+      }
+    }
+    /* Transfer Complete Interrupt management ***********************************/
+    if ((tmpisr_dma & (DMA_FLAG_TCIF0_4 << (hdma->StreamIndex & 0x1FU))) != 0U)
+    {
+      if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_TC) != 0U)
+      {
+        /* Clear the transfer complete flag */
+        regs_dma->IFCR = DMA_FLAG_TCIF0_4 << (hdma->StreamIndex & 0x1FU);
+
+        if(HAL_DMA_STATE_ABORT == hdma->State)
+        {
+          /* Disable all the transfer interrupts */
+          ((DMA_Stream_TypeDef   *)hdma->Instance)->CR  &= ~(DMA_IT_TC | DMA_IT_TE | DMA_IT_DME);
+          ((DMA_Stream_TypeDef   *)hdma->Instance)->FCR &= ~(DMA_IT_FE);
+
+          if((hdma->XferHalfCpltCallback != NULL) || (hdma->XferM1HalfCpltCallback != NULL))
+          {
+            ((DMA_Stream_TypeDef   *)hdma->Instance)->CR  &= ~(DMA_IT_HT);
+          }
+
+          /* Clear all interrupt flags at correct offset within the register */
+          regs_dma->IFCR = 0x3FUL << (hdma->StreamIndex & 0x1FU);
+
+          /* Change the DMA state */
+          hdma->State = HAL_DMA_STATE_READY;
+
+          /* Process Unlocked */
+          __HAL_UNLOCK(hdma);
+
+          if(hdma->XferAbortCallback != NULL)
+          {
+            hdma->XferAbortCallback(hdma);
+          }
+          return;
+        }
+
+        if(((((DMA_Stream_TypeDef   *)hdma->Instance)->CR) & (uint32_t)(DMA_SxCR_DBM)) != 0U)
+        {
+          /* Current memory buffer used is Memory 0 */
+          if((((DMA_Stream_TypeDef   *)hdma->Instance)->CR & DMA_SxCR_CT) == 0U)
+          {
+            if(hdma->XferM1CpltCallback != NULL)
+            {
+              /* Transfer complete Callback for memory1 */
+              hdma->XferM1CpltCallback(hdma);
+            }
+          }
+          /* Current memory buffer used is Memory 1 */
+          else
+          {
+            if(hdma->XferCpltCallback != NULL)
+            {
+              /* Transfer complete Callback for memory0 */
+              hdma->XferCpltCallback(hdma);
+            }
+          }
+        }
+        /* Disable the transfer complete interrupt if the DMA mode is not CIRCULAR */
+        else
+        {
+          if((((DMA_Stream_TypeDef   *)hdma->Instance)->CR & DMA_SxCR_CIRC) == 0U)
+          {
+            /* Disable the transfer complete interrupt */
+            ((DMA_Stream_TypeDef   *)hdma->Instance)->CR  &= ~(DMA_IT_TC);
+
+            /* Change the DMA state */
+            hdma->State = HAL_DMA_STATE_READY;
+
+            /* Process Unlocked */
+            __HAL_UNLOCK(hdma);
+          }
+
+          if(hdma->XferCpltCallback != NULL)
+          {
+            /* Transfer complete callback */
+            hdma->XferCpltCallback(hdma);
+          }
+        }
+      }
+    }
+
+    /* manage error case */
+    if(hdma->ErrorCode != HAL_DMA_ERROR_NONE)
+    {
+      if((hdma->ErrorCode & HAL_DMA_ERROR_TE) != 0U)
+      {
+        hdma->State = HAL_DMA_STATE_ABORT;
+
+        /* Disable the stream */
+        __HAL_DMA_DISABLE(hdma);
+
+        do
+        {
+          if (++count > timeout)
+          {
+            break;
+          }
+        }
+        while((((DMA_Stream_TypeDef   *)hdma->Instance)->CR & DMA_SxCR_EN) != 0U);
+
+        if((((DMA_Stream_TypeDef   *)hdma->Instance)->CR & DMA_SxCR_EN) != 0U)
+        {
+          /* Change the DMA state to error if DMA disable fails */
+          hdma->State = HAL_DMA_STATE_ERROR;
+        }
+        else
+        {
+          /* Change the DMA state to Ready if DMA disable success */
+          hdma->State = HAL_DMA_STATE_READY;
+        }
+
+        /* Process Unlocked */
+        __HAL_UNLOCK(hdma);
+      }
+
+      if(hdma->XferErrorCallback != NULL)
+      {
+        /* Transfer error callback */
+        hdma->XferErrorCallback(hdma);
+      }
+    }
+  }
+  else if(IS_BDMA_CHANNEL_INSTANCE(hdma->Instance) != 0U)  /* BDMA instance(s) */
+  {
+    ccr_reg = (((BDMA_Channel_TypeDef   *)hdma->Instance)->CCR);
+
+    /* Half Transfer Complete Interrupt management ******************************/
+    if (((tmpisr_bdma & (BDMA_FLAG_HT0 << (hdma->StreamIndex & 0x1FU))) != 0U) && ((ccr_reg & BDMA_CCR_HTIE) != 0U))
+    {
+      /* Clear the half transfer complete flag */
+      regs_bdma->IFCR = (BDMA_ISR_HTIF0 << (hdma->StreamIndex & 0x1FU));
+
+      /* Disable the transfer complete interrupt if the DMA mode is Double Buffering */
+      if((ccr_reg & BDMA_CCR_DBM) != 0U)
+      {
+        /* Current memory buffer used is Memory 0 */
+        if((ccr_reg & BDMA_CCR_CT) == 0U)
+        {
+          if(hdma->XferM1HalfCpltCallback != NULL)
+          {
+            /* Half transfer Callback for Memory 1 */
+            hdma->XferM1HalfCpltCallback(hdma);
+          }
+        }
+        /* Current memory buffer used is Memory 1 */
+        else
+        {
+          if(hdma->XferHalfCpltCallback != NULL)
+          {
+            /* Half transfer Callback for Memory 0 */
+            hdma->XferHalfCpltCallback(hdma);
+          }
+        }
+      }
+      else
+      {
+        if((ccr_reg & BDMA_CCR_CIRC) == 0U)
+        {
+          /* Disable the half transfer interrupt */
+          __HAL_DMA_DISABLE_IT(hdma, DMA_IT_HT);
+        }
+
+        /* DMA peripheral state is not updated in Half Transfer */
+        /* but in Transfer Complete case */
+
+       if(hdma->XferHalfCpltCallback != NULL)
+        {
+          /* Half transfer callback */
+          hdma->XferHalfCpltCallback(hdma);
+        }
+      }
+    }
+
+    /* Transfer Complete Interrupt management ***********************************/
+    else if (((tmpisr_bdma & (BDMA_FLAG_TC0 << (hdma->StreamIndex & 0x1FU))) != 0U) && ((ccr_reg & BDMA_CCR_TCIE) != 0U))
+    {
+      /* Clear the transfer complete flag */
+      regs_bdma->IFCR = (BDMA_ISR_TCIF0) << (hdma->StreamIndex & 0x1FU);
+
+      /* Disable the transfer complete interrupt if the DMA mode is Double Buffering */
+      if((ccr_reg & BDMA_CCR_DBM) != 0U)
+      {
+        /* Current memory buffer used is Memory 0 */
+        if((ccr_reg & BDMA_CCR_CT) == 0U)
+        {
+          if(hdma->XferM1CpltCallback != NULL)
+          {
+            /* Transfer complete Callback for Memory 1 */
+            hdma->XferM1CpltCallback(hdma);
+          }
+        }
+        /* Current memory buffer used is Memory 1 */
+        else
+        {
+          if(hdma->XferCpltCallback != NULL)
+          {
+            /* Transfer complete Callback for Memory 0 */
+            hdma->XferCpltCallback(hdma);
+          }
+        }
+      }
+      else
+      {
+        if((ccr_reg & BDMA_CCR_CIRC) == 0U)
+        {
+          /* Disable the transfer complete and error interrupt, if the DMA mode is not CIRCULAR */
+          __HAL_DMA_DISABLE_IT(hdma, DMA_IT_TE | DMA_IT_TC);
+
+          /* Change the DMA state */
+          hdma->State = HAL_DMA_STATE_READY;
+
+          /* Process Unlocked */
+          __HAL_UNLOCK(hdma);
+        }
+
+        if(hdma->XferCpltCallback != NULL)
+        {
+          /* Transfer complete callback */
+          hdma->XferCpltCallback(hdma);
+        }
+      }
+    }
+    /* Transfer Error Interrupt management **************************************/
+    else if (((tmpisr_bdma & (BDMA_FLAG_TE0 << (hdma->StreamIndex & 0x1FU))) != 0U) && ((ccr_reg & BDMA_CCR_TEIE) != 0U))
+    {
+      /* When a DMA transfer error occurs */
+      /* A hardware clear of its EN bits is performed */
+      /* Disable ALL DMA IT */
+      __HAL_DMA_DISABLE_IT(hdma, (DMA_IT_TC | DMA_IT_HT | DMA_IT_TE));
+
+      /* Clear all flags */
+      regs_bdma->IFCR = (BDMA_ISR_GIF0) << (hdma->StreamIndex & 0x1FU);
+
+      /* Update error code */
+      hdma->ErrorCode = HAL_DMA_ERROR_TE;
+
+      /* Change the DMA state */
+      hdma->State = HAL_DMA_STATE_READY;
+
+      /* Process Unlocked */
+      __HAL_UNLOCK(hdma);
+
+      if (hdma->XferErrorCallback != NULL)
+      {
+        /* Transfer error callback */
+        hdma->XferErrorCallback(hdma);
+      }
+    }
+    else
+    {
+      /* Nothing To Do */
+    }
+  }
+  else
+  {
+    /* Nothing To Do */
+  }
+}
+
+/**
+  * @brief  Register callbacks
+  * @param  hdma:                 pointer to a DMA_HandleTypeDef structure that contains
+  *                               the configuration information for the specified DMA Stream.
+  * @param  CallbackID:           User Callback identifier
+  *                               a DMA_HandleTypeDef structure as parameter.
+  * @param  pCallback:            pointer to private callback function which has pointer to
+  *                               a DMA_HandleTypeDef structure as parameter.
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_DMA_RegisterCallback(DMA_HandleTypeDef *hdma, HAL_DMA_CallbackIDTypeDef CallbackID, void (* pCallback)(DMA_HandleTypeDef *_hdma))
+{
+
+  HAL_StatusTypeDef status = HAL_OK;
+
+  /* Check the DMA peripheral handle */
+  if(hdma == NULL)
+  {
+    return HAL_ERROR;
+  }
+
+  /* Process locked */
+  __HAL_LOCK(hdma);
+
+  if(HAL_DMA_STATE_READY == hdma->State)
+  {
+    switch (CallbackID)
+    {
+    case  HAL_DMA_XFER_CPLT_CB_ID:
+      hdma->XferCpltCallback = pCallback;
+      break;
+
+    case  HAL_DMA_XFER_HALFCPLT_CB_ID:
+      hdma->XferHalfCpltCallback = pCallback;
+      break;
+
+    case  HAL_DMA_XFER_M1CPLT_CB_ID:
+      hdma->XferM1CpltCallback = pCallback;
+      break;
+
+    case  HAL_DMA_XFER_M1HALFCPLT_CB_ID:
+      hdma->XferM1HalfCpltCallback = pCallback;
+      break;
+
+    case  HAL_DMA_XFER_ERROR_CB_ID:
+      hdma->XferErrorCallback = pCallback;
+      break;
+
+    case  HAL_DMA_XFER_ABORT_CB_ID:
+      hdma->XferAbortCallback = pCallback;
+      break;
+
+    default:
+      status =  HAL_ERROR;
+      break;
+    }
+  }
+  else
+  {
+    /* Return error status */
+    status =  HAL_ERROR;
+  }
+
+  /* Release Lock */
+  __HAL_UNLOCK(hdma);
+
+  return status;
+}
+
+/**
+  * @brief  UnRegister callbacks
+  * @param  hdma:                 pointer to a DMA_HandleTypeDef structure that contains
+  *                               the configuration information for the specified DMA Stream.
+  * @param  CallbackID:           User Callback identifier
+  *                               a HAL_DMA_CallbackIDTypeDef ENUM as parameter.
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_DMA_UnRegisterCallback(DMA_HandleTypeDef *hdma, HAL_DMA_CallbackIDTypeDef CallbackID)
+{
+  HAL_StatusTypeDef status = HAL_OK;
+
+  /* Check the DMA peripheral handle */
+  if(hdma == NULL)
+  {
+    return HAL_ERROR;
+  }
+
+  /* Process locked */
+  __HAL_LOCK(hdma);
+
+  if(HAL_DMA_STATE_READY == hdma->State)
+  {
+    switch (CallbackID)
+    {
+    case  HAL_DMA_XFER_CPLT_CB_ID:
+      hdma->XferCpltCallback = NULL;
+      break;
+
+    case  HAL_DMA_XFER_HALFCPLT_CB_ID:
+      hdma->XferHalfCpltCallback = NULL;
+      break;
+
+    case  HAL_DMA_XFER_M1CPLT_CB_ID:
+      hdma->XferM1CpltCallback = NULL;
+      break;
+
+    case  HAL_DMA_XFER_M1HALFCPLT_CB_ID:
+      hdma->XferM1HalfCpltCallback = NULL;
+      break;
+
+    case  HAL_DMA_XFER_ERROR_CB_ID:
+      hdma->XferErrorCallback = NULL;
+      break;
+
+    case  HAL_DMA_XFER_ABORT_CB_ID:
+      hdma->XferAbortCallback = NULL;
+      break;
+
+    case   HAL_DMA_XFER_ALL_CB_ID:
+      hdma->XferCpltCallback = NULL;
+      hdma->XferHalfCpltCallback = NULL;
+      hdma->XferM1CpltCallback = NULL;
+      hdma->XferM1HalfCpltCallback = NULL;
+      hdma->XferErrorCallback = NULL;
+      hdma->XferAbortCallback = NULL;
+      break;
+
+    default:
+      status = HAL_ERROR;
+      break;
+    }
+  }
+  else
+  {
+    status = HAL_ERROR;
+  }
+
+  /* Release Lock */
+  __HAL_UNLOCK(hdma);
+
+  return status;
+}
+
+/**
+  * @}
+  */
+
+/** @addtogroup DMA_Exported_Functions_Group3
+  *
+@verbatim
+ ===============================================================================
+                    ##### State and Errors functions #####
+ ===============================================================================
+    [..]
+    This subsection provides functions allowing to
+      (+) Check the DMA state
+      (+) Get error code
+
+@endverbatim
+  * @{
+  */
+
+/**
+  * @brief  Returns the DMA state.
+  * @param  hdma: pointer to a DMA_HandleTypeDef structure that contains
+  *               the configuration information for the specified DMA Stream.
+  * @retval HAL state
+  */
+HAL_DMA_StateTypeDef HAL_DMA_GetState(const DMA_HandleTypeDef *hdma)
+{
+  return hdma->State;
+}
+
+/**
+  * @brief  Return the DMA error code
+  * @param  hdma : pointer to a DMA_HandleTypeDef structure that contains
+  *              the configuration information for the specified DMA Stream.
+  * @retval DMA Error Code
+  */
+uint32_t HAL_DMA_GetError(const DMA_HandleTypeDef *hdma)
+{
+  return hdma->ErrorCode;
+}
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/** @addtogroup DMA_Private_Functions
+  * @{
+  */
+
+/**
+  * @brief  Sets the DMA Transfer parameter.
+  * @param  hdma:       pointer to a DMA_HandleTypeDef structure that contains
+  *                     the configuration information for the specified DMA Stream.
+  * @param  SrcAddress: The source memory Buffer address
+  * @param  DstAddress: The destination memory Buffer address
+  * @param  DataLength: The length of data to be transferred from source to destination
+  * @retval None
+  */
+static void DMA_SetConfig(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
+{
+  /* calculate DMA base and stream number */
+  DMA_Base_Registers  *regs_dma  = (DMA_Base_Registers *)hdma->StreamBaseAddress;
+  BDMA_Base_Registers *regs_bdma = (BDMA_Base_Registers *)hdma->StreamBaseAddress;
+
+  if(IS_DMA_DMAMUX_ALL_INSTANCE(hdma->Instance) != 0U) /* No DMAMUX available for BDMA1 */
+  {
+    /* Clear the DMAMUX synchro overrun flag */
+    hdma->DMAmuxChannelStatus->CFR = hdma->DMAmuxChannelStatusMask;
+
+    if(hdma->DMAmuxRequestGen != 0U)
+    {
+      /* Clear the DMAMUX request generator overrun flag */
+      hdma->DMAmuxRequestGenStatus->RGCFR = hdma->DMAmuxRequestGenStatusMask;
+    }
+  }
+
+  if(IS_DMA_STREAM_INSTANCE(hdma->Instance) != 0U) /* DMA1 or DMA2 instance */
+  {
+    /* Clear all interrupt flags at correct offset within the register */
+    regs_dma->IFCR = 0x3FUL << (hdma->StreamIndex & 0x1FU);
+
+    /* Clear DBM bit */
+    ((DMA_Stream_TypeDef *)hdma->Instance)->CR &= (uint32_t)(~DMA_SxCR_DBM);
+
+    /* Configure DMA Stream data length */
+    ((DMA_Stream_TypeDef *)hdma->Instance)->NDTR = DataLength;
+
+    /* Peripheral to Memory */
+    if((hdma->Init.Direction) == DMA_MEMORY_TO_PERIPH)
+    {
+      /* Configure DMA Stream destination address */
+      ((DMA_Stream_TypeDef *)hdma->Instance)->PAR = DstAddress;
+
+      /* Configure DMA Stream source address */
+      ((DMA_Stream_TypeDef *)hdma->Instance)->M0AR = SrcAddress;
+    }
+    /* Memory to Peripheral */
+    else
+    {
+      /* Configure DMA Stream source address */
+      ((DMA_Stream_TypeDef *)hdma->Instance)->PAR = SrcAddress;
+
+      /* Configure DMA Stream destination address */
+      ((DMA_Stream_TypeDef *)hdma->Instance)->M0AR = DstAddress;
+    }
+  }
+  else if(IS_BDMA_CHANNEL_INSTANCE(hdma->Instance) != 0U) /* BDMA instance(s) */
+  {
+    /* Clear all flags */
+    regs_bdma->IFCR = (BDMA_ISR_GIF0) << (hdma->StreamIndex & 0x1FU);
+
+    /* Configure DMA Channel data length */
+    ((BDMA_Channel_TypeDef *)hdma->Instance)->CNDTR = DataLength;
+
+    /* Peripheral to Memory */
+    if((hdma->Init.Direction) == DMA_MEMORY_TO_PERIPH)
+    {
+      /* Configure DMA Channel destination address */
+      ((BDMA_Channel_TypeDef *)hdma->Instance)->CPAR = DstAddress;
+
+      /* Configure DMA Channel source address */
+      ((BDMA_Channel_TypeDef *)hdma->Instance)->CM0AR = SrcAddress;
+    }
+    /* Memory to Peripheral */
+    else
+    {
+      /* Configure DMA Channel source address */
+      ((BDMA_Channel_TypeDef *)hdma->Instance)->CPAR = SrcAddress;
+
+      /* Configure DMA Channel destination address */
+      ((BDMA_Channel_TypeDef *)hdma->Instance)->CM0AR = DstAddress;
+    }
+  }
+  else
+  {
+    /* Nothing To Do */
+  }
+}
+
+/**
+  * @brief  Returns the DMA Stream base address depending on stream number
+  * @param  hdma:       pointer to a DMA_HandleTypeDef structure that contains
+  *                     the configuration information for the specified DMA Stream.
+  * @retval Stream base address
+  */
+static uint32_t DMA_CalcBaseAndBitshift(DMA_HandleTypeDef *hdma)
+{
+  if(IS_DMA_STREAM_INSTANCE(hdma->Instance) != 0U) /* DMA1 or DMA2 instance */
+  {
+    uint32_t stream_number = (((uint32_t)((uint32_t*)hdma->Instance) & 0xFFU) - 16U) / 24U;
+
+    /* lookup table for necessary bitshift of flags within status registers */
+    static const uint8_t flagBitshiftOffset[8U] = {0U, 6U, 16U, 22U, 0U, 6U, 16U, 22U};
+    hdma->StreamIndex = flagBitshiftOffset[stream_number & 0x7U];
+
+    if (stream_number > 3U)
+    {
+      /* return pointer to HISR and HIFCR */
+      hdma->StreamBaseAddress = (((uint32_t)((uint32_t*)hdma->Instance) & (uint32_t)(~0x3FFU)) + 4U);
+    }
+    else
+    {
+      /* return pointer to LISR and LIFCR */
+      hdma->StreamBaseAddress = ((uint32_t)((uint32_t*)hdma->Instance) & (uint32_t)(~0x3FFU));
+    }
+  }
+  else /* BDMA instance(s) */
+  {
+    /* return pointer to ISR and IFCR */
+    hdma->StreamBaseAddress = ((uint32_t)((uint32_t*)hdma->Instance) & (uint32_t)(~0xFFU));
+  }
+
+  return hdma->StreamBaseAddress;
+}
+
+/**
+  * @brief  Check compatibility between FIFO threshold level and size of the memory burst
+  * @param  hdma:       pointer to a DMA_HandleTypeDef structure that contains
+  *                     the configuration information for the specified DMA Stream.
+  * @retval HAL status
+  */
+static HAL_StatusTypeDef DMA_CheckFifoParam(const DMA_HandleTypeDef *hdma)
+{
+  HAL_StatusTypeDef status = HAL_OK;
+
+  /* Memory Data size equal to Byte */
+  if (hdma->Init.MemDataAlignment == DMA_MDATAALIGN_BYTE)
+  {
+    switch (hdma->Init.FIFOThreshold)
+    {
+      case DMA_FIFO_THRESHOLD_1QUARTERFULL:
+      case DMA_FIFO_THRESHOLD_3QUARTERSFULL:
+
+        if ((hdma->Init.MemBurst & DMA_SxCR_MBURST_1) == DMA_SxCR_MBURST_1)
+        {
+          status = HAL_ERROR;
+        }
+        break;
+
+      case DMA_FIFO_THRESHOLD_HALFFULL:
+        if (hdma->Init.MemBurst == DMA_MBURST_INC16)
+        {
+          status = HAL_ERROR;
+        }
+        break;
+
+      case DMA_FIFO_THRESHOLD_FULL:
+        break;
+
+      default:
+        break;
+    }
+  }
+
+  /* Memory Data size equal to Half-Word */
+  else if (hdma->Init.MemDataAlignment == DMA_MDATAALIGN_HALFWORD)
+  {
+    switch (hdma->Init.FIFOThreshold)
+    {
+      case DMA_FIFO_THRESHOLD_1QUARTERFULL:
+      case DMA_FIFO_THRESHOLD_3QUARTERSFULL:
+        status = HAL_ERROR;
+        break;
+
+      case DMA_FIFO_THRESHOLD_HALFFULL:
+        if ((hdma->Init.MemBurst & DMA_SxCR_MBURST_1) == DMA_SxCR_MBURST_1)
+        {
+          status = HAL_ERROR;
+        }
+        break;
+
+      case DMA_FIFO_THRESHOLD_FULL:
+        if (hdma->Init.MemBurst == DMA_MBURST_INC16)
+        {
+          status = HAL_ERROR;
+        }
+        break;
+
+      default:
+        break;
+    }
+  }
+
+  /* Memory Data size equal to Word */
+  else
+  {
+    switch (hdma->Init.FIFOThreshold)
+    {
+      case DMA_FIFO_THRESHOLD_1QUARTERFULL:
+      case DMA_FIFO_THRESHOLD_HALFFULL:
+      case DMA_FIFO_THRESHOLD_3QUARTERSFULL:
+        status = HAL_ERROR;
+        break;
+
+      case DMA_FIFO_THRESHOLD_FULL:
+        if ((hdma->Init.MemBurst & DMA_SxCR_MBURST_1) == DMA_SxCR_MBURST_1)
+        {
+          status = HAL_ERROR;
+        }
+    break;
+
+      default:
+        break;
+    }
+  }
+
+  return status;
+}
+
+/**
+  * @brief  Updates the DMA handle with the DMAMUX  channel and status mask depending on stream number
+  * @param  hdma:       pointer to a DMA_HandleTypeDef structure that contains
+  *                     the configuration information for the specified DMA Stream.
+  * @retval HAL status
+  */
+static void DMA_CalcDMAMUXChannelBaseAndMask(DMA_HandleTypeDef *hdma)
+{
+  uint32_t stream_number;
+  uint32_t stream_baseaddress = (uint32_t)((uint32_t*)hdma->Instance);
+
+  if(IS_BDMA_CHANNEL_DMAMUX_INSTANCE(hdma->Instance) != 0U)
+  {
+    /* BDMA Channels are connected to DMAMUX2 channels */
+    stream_number = (((uint32_t)((uint32_t*)hdma->Instance) & 0xFFU) - 8U) / 20U;
+    hdma->DMAmuxChannel = (DMAMUX_Channel_TypeDef *)((uint32_t)(((uint32_t)DMAMUX2_Channel0) + (stream_number * 4U)));
+    hdma->DMAmuxChannelStatus = DMAMUX2_ChannelStatus;
+    hdma->DMAmuxChannelStatusMask = 1UL << (stream_number & 0x1FU);
+  }
+  else
+  {
+    /* DMA1/DMA2 Streams are connected to DMAMUX1 channels */
+    stream_number = (((uint32_t)((uint32_t*)hdma->Instance) & 0xFFU) - 16U) / 24U;
+
+    if((stream_baseaddress <= ((uint32_t)DMA2_Stream7) ) && \
+       (stream_baseaddress >= ((uint32_t)DMA2_Stream0)))
+    {
+      stream_number += 8U;
+    }
+    hdma->DMAmuxChannel = (DMAMUX_Channel_TypeDef *)((uint32_t)(((uint32_t)DMAMUX1_Channel0) + (stream_number * 4U)));
+    hdma->DMAmuxChannelStatus = DMAMUX1_ChannelStatus;
+    hdma->DMAmuxChannelStatusMask = 1UL << (stream_number & 0x1FU);
+  }
+}
+
+/**
+  * @brief  Updates the DMA handle with the DMAMUX  request generator params
+  * @param  hdma:       pointer to a DMA_HandleTypeDef structure that contains
+  *                     the configuration information for the specified DMA Stream.
+  * @retval HAL status
+  */
+static void DMA_CalcDMAMUXRequestGenBaseAndMask(DMA_HandleTypeDef *hdma)
+{
+  uint32_t request =  hdma->Init.Request & DMAMUX_CxCR_DMAREQ_ID;
+
+  if((request >= DMA_REQUEST_GENERATOR0) && (request <= DMA_REQUEST_GENERATOR7))
+  {
+    if(IS_BDMA_CHANNEL_DMAMUX_INSTANCE(hdma->Instance) != 0U)
+    {
+      /* BDMA Channels are connected to DMAMUX2 request generator blocks */
+      hdma->DMAmuxRequestGen = (DMAMUX_RequestGen_TypeDef *)((uint32_t)(((uint32_t)DMAMUX2_RequestGenerator0) + ((request - 1U) * 4U)));
+
+      hdma->DMAmuxRequestGenStatus = DMAMUX2_RequestGenStatus;
+    }
+    else
+    {
+      /* DMA1 and DMA2 Streams use DMAMUX1 request generator blocks */
+      hdma->DMAmuxRequestGen = (DMAMUX_RequestGen_TypeDef *)((uint32_t)(((uint32_t)DMAMUX1_RequestGenerator0) + ((request - 1U) * 4U)));
+
+      hdma->DMAmuxRequestGenStatus = DMAMUX1_RequestGenStatus;
+    }
+
+    hdma->DMAmuxRequestGenStatusMask = 1UL << (request - 1U);
+  }
+}
+
+/**
+  * @}
+  */
+
+#endif /* HAL_DMA_MODULE_ENABLED */
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
Index: ctrl/firmware/Main/CubeMX/Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_gpio.c
===================================================================
--- ctrl/firmware/Main/CubeMX/Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_gpio.c	(revision 45)
+++ ctrl/firmware/Main/CubeMX/Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_gpio.c	(revision 45)
@@ -0,0 +1,555 @@
+/**
+  ******************************************************************************
+  * @file    stm32h7xx_hal_gpio.c
+  * @author  MCD Application Team
+  * @brief   GPIO HAL module driver.
+  *          This file provides firmware functions to manage the following
+  *          functionalities of the General Purpose Input/Output (GPIO) peripheral:
+  *           + Initialization and de-initialization functions
+  *           + IO operation functions
+  *
+  ******************************************************************************
+  * @attention
+  *
+  * Copyright (c) 2017 STMicroelectronics.
+  * All rights reserved.
+  *
+  * This software is licensed under terms that can be found in the LICENSE file
+  * in the root directory of this software component.
+  * If no LICENSE file comes with this software, it is provided AS-IS.
+  *
+  ******************************************************************************
+  @verbatim
+  ==============================================================================
+                    ##### GPIO Peripheral features #####
+  ==============================================================================
+  [..]
+    (+) Each port bit of the general-purpose I/O (GPIO) ports can be individually
+        configured by software in several modes:
+        (++) Input mode
+        (++) Analog mode
+        (++) Output mode
+        (++) Alternate function mode
+        (++) External interrupt/event lines
+
+    (+) During and just after reset, the alternate functions and external interrupt
+        lines are not active and the I/O ports are configured in input floating mode.
+
+    (+) All GPIO pins have weak internal pull-up and pull-down resistors, which can be
+        activated or not.
+
+    (+) In Output or Alternate mode, each IO can be configured on open-drain or push-pull
+        type and the IO speed can be selected depending on the VDD value.
+
+    (+) The microcontroller IO pins are connected to onboard peripherals/modules through a
+        multiplexer that allows only one peripheral alternate function (AF) connected
+       to an IO pin at a time. In this way, there can be no conflict between peripherals
+       sharing the same IO pin.
+
+    (+) All ports have external interrupt/event capability. To use external interrupt
+        lines, the port must be configured in input mode. All available GPIO pins are
+        connected to the 16 external interrupt/event lines from EXTI0 to EXTI15.
+
+  The external interrupt/event controller consists of up to 23 edge detectors
+        (16 lines are connected to GPIO) for generating event/interrupt requests (each
+        input line can be independently configured to select the type (interrupt or event)
+        and the corresponding trigger event (rising or falling or both). Each line can
+        also be masked independently.
+
+                     ##### How to use this driver #####
+  ==============================================================================
+  [..]
+    (#) Enable the GPIO AHB clock using the following function: __HAL_RCC_GPIOx_CLK_ENABLE().
+
+    (#) Configure the GPIO pin(s) using HAL_GPIO_Init().
+        (++) Configure the IO mode using "Mode" member from GPIO_InitTypeDef structure
+        (++) Activate Pull-up, Pull-down resistor using "Pull" member from GPIO_InitTypeDef
+             structure.
+        (++) In case of Output or alternate function mode selection: the speed is
+             configured through "Speed" member from GPIO_InitTypeDef structure.
+        (++) In alternate mode is selection, the alternate function connected to the IO
+             is configured through "Alternate" member from GPIO_InitTypeDef structure.
+        (++) Analog mode is required when a pin is to be used as ADC channel
+             or DAC output.
+        (++) In case of external interrupt/event selection the "Mode" member from
+             GPIO_InitTypeDef structure select the type (interrupt or event) and
+             the corresponding trigger event (rising or falling or both).
+
+    (#) In case of external interrupt/event mode selection, configure NVIC IRQ priority
+        mapped to the EXTI line using HAL_NVIC_SetPriority() and enable it using
+        HAL_NVIC_EnableIRQ().
+
+    (#) To get the level of a pin configured in input mode use HAL_GPIO_ReadPin().
+
+    (#) To set/reset the level of a pin configured in output mode use
+        HAL_GPIO_WritePin()/HAL_GPIO_TogglePin().
+
+   (#) To lock pin configuration until next reset use HAL_GPIO_LockPin().
+
+
+    (#) During and just after reset, the alternate functions are not
+        active and the GPIO pins are configured in input floating mode (except JTAG
+        pins).
+
+    (#) The LSE oscillator pins OSC32_IN and OSC32_OUT can be used as general purpose
+        (PC14 and PC15, respectively) when the LSE oscillator is off. The LSE has
+        priority over the GPIO function.
+
+    (#) The HSE oscillator pins OSC_IN/OSC_OUT can be used as
+        general purpose PH0 and PH1, respectively, when the HSE oscillator is off.
+        The HSE has priority over the GPIO function.
+
+  @endverbatim
+  ******************************************************************************
+  */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32h7xx_hal.h"
+
+/** @addtogroup STM32H7xx_HAL_Driver
+  * @{
+  */
+
+/** @defgroup GPIO  GPIO
+  * @brief GPIO HAL module driver
+  * @{
+  */
+
+#ifdef HAL_GPIO_MODULE_ENABLED
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private defines ------------------------------------------------------------*/
+/** @addtogroup GPIO_Private_Constants GPIO Private Constants
+  * @{
+  */
+
+#if defined(DUAL_CORE)
+#define EXTI_CPU1             (0x01000000U)
+#define EXTI_CPU2             (0x02000000U)
+#endif /*DUAL_CORE*/
+#define GPIO_NUMBER           (16U)
+/**
+  * @}
+  */
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/* Private functions ---------------------------------------------------------*/
+/* Exported functions --------------------------------------------------------*/
+/** @defgroup GPIO_Exported_Functions GPIO Exported Functions
+  * @{
+  */
+
+/** @defgroup GPIO_Exported_Functions_Group1 Initialization and de-initialization functions
+ *  @brief    Initialization and Configuration functions
+ *
+@verbatim
+ ===============================================================================
+              ##### Initialization and de-initialization functions #####
+ ===============================================================================
+  [..]
+    This section provides functions allowing to initialize and de-initialize the GPIOs
+    to be ready for use.
+
+@endverbatim
+  * @{
+  */
+
+/**
+  * @brief  Initializes the GPIOx peripheral according to the specified parameters in the GPIO_Init.
+  * @param  GPIOx: where x can be (A..K) to select the GPIO peripheral.
+  * @param  GPIO_Init: pointer to a GPIO_InitTypeDef structure that contains
+  *         the configuration information for the specified GPIO peripheral.
+  * @retval None
+  */
+void HAL_GPIO_Init(GPIO_TypeDef  *GPIOx, const GPIO_InitTypeDef *GPIO_Init)
+{
+  uint32_t position = 0x00U;
+  uint32_t iocurrent;
+  uint32_t temp;
+  EXTI_Core_TypeDef *EXTI_CurrentCPU;
+
+#if defined(DUAL_CORE) && defined(CORE_CM4)
+  EXTI_CurrentCPU = EXTI_D2; /* EXTI for CM4 CPU */
+#else
+  EXTI_CurrentCPU = EXTI_D1; /* EXTI for CM7 CPU */
+#endif
+
+  /* Check the parameters */
+  assert_param(IS_GPIO_ALL_INSTANCE(GPIOx));
+  assert_param(IS_GPIO_PIN(GPIO_Init->Pin));
+  assert_param(IS_GPIO_MODE(GPIO_Init->Mode));
+
+  /* Configure the port pins */
+  while (((GPIO_Init->Pin) >> position) != 0x00U)
+  {
+    /* Get current io position */
+    iocurrent = (GPIO_Init->Pin) & (1UL << position);
+
+    if (iocurrent != 0x00U)
+    {
+      /*--------------------- GPIO Mode Configuration ------------------------*/
+      /* In case of Output or Alternate function mode selection */
+      if (((GPIO_Init->Mode & GPIO_MODE) == MODE_OUTPUT) || ((GPIO_Init->Mode & GPIO_MODE) == MODE_AF))
+      {
+        /* Check the Speed parameter */
+        assert_param(IS_GPIO_SPEED(GPIO_Init->Speed));
+
+        /* Configure the IO Speed */
+        temp = GPIOx->OSPEEDR;
+        temp &= ~(GPIO_OSPEEDR_OSPEED0 << (position * 2U));
+        temp |= (GPIO_Init->Speed << (position * 2U));
+        GPIOx->OSPEEDR = temp;
+
+        /* Configure the IO Output Type */
+        temp = GPIOx->OTYPER;
+        temp &= ~(GPIO_OTYPER_OT0 << position) ;
+        temp |= (((GPIO_Init->Mode & OUTPUT_TYPE) >> OUTPUT_TYPE_Pos) << position);
+        GPIOx->OTYPER = temp;
+      }
+
+      if ((GPIO_Init->Mode & GPIO_MODE) != MODE_ANALOG)
+      {
+       /* Check the Pull parameter */
+       assert_param(IS_GPIO_PULL(GPIO_Init->Pull));
+
+      /* Activate the Pull-up or Pull down resistor for the current IO */
+      temp = GPIOx->PUPDR;
+      temp &= ~(GPIO_PUPDR_PUPD0 << (position * 2U));
+      temp |= ((GPIO_Init->Pull) << (position * 2U));
+      GPIOx->PUPDR = temp;
+      }
+
+      /* In case of Alternate function mode selection */
+      if ((GPIO_Init->Mode & GPIO_MODE) == MODE_AF)
+      {
+        /* Check the Alternate function parameters */
+        assert_param(IS_GPIO_AF_INSTANCE(GPIOx));
+        assert_param(IS_GPIO_AF(GPIO_Init->Alternate));
+
+        /* Configure Alternate function mapped with the current IO */
+        temp = GPIOx->AFR[position >> 3U];
+        temp &= ~(0xFU << ((position & 0x07U) * 4U));
+        temp |= ((GPIO_Init->Alternate) << ((position & 0x07U) * 4U));
+        GPIOx->AFR[position >> 3U] = temp;
+      }
+
+      /* Configure IO Direction mode (Input, Output, Alternate or Analog) */
+      temp = GPIOx->MODER;
+      temp &= ~(GPIO_MODER_MODE0 << (position * 2U));
+      temp |= ((GPIO_Init->Mode & GPIO_MODE) << (position * 2U));
+      GPIOx->MODER = temp;
+
+      /*--------------------- EXTI Mode Configuration ------------------------*/
+      /* Configure the External Interrupt or event for the current IO */
+      if ((GPIO_Init->Mode & EXTI_MODE) != 0x00U)
+      {
+        /* Enable SYSCFG Clock */
+        __HAL_RCC_SYSCFG_CLK_ENABLE();
+
+        temp = SYSCFG->EXTICR[position >> 2U];
+        temp &= ~(0x0FUL << (4U * (position & 0x03U)));
+        temp |= (GPIO_GET_INDEX(GPIOx) << (4U * (position & 0x03U)));
+        SYSCFG->EXTICR[position >> 2U] = temp;
+
+        /* Clear Rising Falling edge configuration */
+        temp = EXTI->RTSR1;
+        temp &= ~(iocurrent);
+        if ((GPIO_Init->Mode & TRIGGER_RISING) != 0x00U)
+        {
+          temp |= iocurrent;
+        }
+        EXTI->RTSR1 = temp;
+
+        temp = EXTI->FTSR1;
+        temp &= ~(iocurrent);
+        if ((GPIO_Init->Mode & TRIGGER_FALLING) != 0x00U)
+        {
+          temp |= iocurrent;
+        }
+        EXTI->FTSR1 = temp;
+
+        temp = EXTI_CurrentCPU->EMR1;
+        temp &= ~(iocurrent);
+        if ((GPIO_Init->Mode & EXTI_EVT) != 0x00U)
+        {
+          temp |= iocurrent;
+        }
+        EXTI_CurrentCPU->EMR1 = temp;
+
+        /* Clear EXTI line configuration */
+        temp = EXTI_CurrentCPU->IMR1;
+        temp &= ~(iocurrent);
+        if ((GPIO_Init->Mode & EXTI_IT) != 0x00U)
+        {
+          temp |= iocurrent;
+        }
+        EXTI_CurrentCPU->IMR1 = temp;
+      }
+    }
+
+    position++;
+  }
+}
+
+/**
+  * @brief  De-initializes the GPIOx peripheral registers to their default reset values.
+  * @param  GPIOx: where x can be (A..K) to select the GPIO peripheral.
+  * @param  GPIO_Pin: specifies the port bit to be written.
+  *          This parameter can be one of GPIO_PIN_x where x can be (0..15).
+  * @retval None
+  */
+void HAL_GPIO_DeInit(GPIO_TypeDef  *GPIOx, uint32_t GPIO_Pin)
+{
+  uint32_t position = 0x00U;
+  uint32_t iocurrent;
+  uint32_t tmp;
+  EXTI_Core_TypeDef *EXTI_CurrentCPU;
+
+#if defined(DUAL_CORE) && defined(CORE_CM4)
+  EXTI_CurrentCPU = EXTI_D2; /* EXTI for CM4 CPU */
+#else
+  EXTI_CurrentCPU = EXTI_D1; /* EXTI for CM7 CPU */
+#endif
+
+  /* Check the parameters */
+  assert_param(IS_GPIO_ALL_INSTANCE(GPIOx));
+  assert_param(IS_GPIO_PIN(GPIO_Pin));
+
+  /* Configure the port pins */
+  while ((GPIO_Pin >> position) != 0x00U)
+  {
+    /* Get current io position */
+    iocurrent = GPIO_Pin & (1UL << position) ;
+
+    if (iocurrent != 0x00U)
+    {
+      /*------------------------- EXTI Mode Configuration --------------------*/
+      /* Clear the External Interrupt or Event for the current IO */
+      tmp = SYSCFG->EXTICR[position >> 2U];
+      tmp &= (0x0FUL << (4U * (position & 0x03U)));
+      if (tmp == (GPIO_GET_INDEX(GPIOx) << (4U * (position & 0x03U))))
+      {
+        /* Clear EXTI line configuration for Current CPU */
+        EXTI_CurrentCPU->IMR1 &= ~(iocurrent);
+        EXTI_CurrentCPU->EMR1 &= ~(iocurrent);
+
+        /* Clear Rising Falling edge configuration */
+        EXTI->FTSR1 &= ~(iocurrent);
+        EXTI->RTSR1 &= ~(iocurrent);
+
+        tmp = 0x0FUL << (4U * (position & 0x03U));
+        SYSCFG->EXTICR[position >> 2U] &= ~tmp;
+      }
+
+      /*------------------------- GPIO Mode Configuration --------------------*/
+      /* Configure IO in Analog Mode */
+      GPIOx->MODER |= (GPIO_MODER_MODE0 << (position * 2U));
+
+      /* Configure the default Alternate Function in current IO */
+      GPIOx->AFR[position >> 3U] &= ~(0xFU << ((position & 0x07U) * 4U)) ;
+
+      /* Deactivate the Pull-up and Pull-down resistor for the current IO */
+      GPIOx->PUPDR &= ~(GPIO_PUPDR_PUPD0 << (position * 2U));
+
+      /* Configure the default value IO Output Type */
+      GPIOx->OTYPER  &= ~(GPIO_OTYPER_OT0 << position) ;
+
+      /* Configure the default value for IO Speed */
+      GPIOx->OSPEEDR &= ~(GPIO_OSPEEDR_OSPEED0 << (position * 2U));
+    }
+
+    position++;
+  }
+}
+
+/**
+  * @}
+  */
+
+/** @defgroup GPIO_Exported_Functions_Group2 IO operation functions
+ *  @brief GPIO Read, Write, Toggle, Lock and EXTI management functions.
+ *
+@verbatim
+ ===============================================================================
+                       ##### IO operation functions #####
+ ===============================================================================
+
+@endverbatim
+  * @{
+  */
+
+/**
+  * @brief  Reads the specified input port pin.
+  * @param  GPIOx: where x can be (A..K) to select the GPIO peripheral.
+  * @param  GPIO_Pin: specifies the port bit to read.
+  *         This parameter can be GPIO_PIN_x where x can be (0..15).
+  * @retval The input port pin value.
+  */
+GPIO_PinState HAL_GPIO_ReadPin(const GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)
+{
+  GPIO_PinState bitstatus;
+
+  /* Check the parameters */
+  assert_param(IS_GPIO_PIN(GPIO_Pin));
+
+  if ((GPIOx->IDR & GPIO_Pin) != 0x00U)
+  {
+    bitstatus = GPIO_PIN_SET;
+  }
+  else
+  {
+    bitstatus = GPIO_PIN_RESET;
+  }
+  return bitstatus;
+}
+
+/**
+  * @brief  Sets or clears the selected data port bit.
+  *
+  * @note   This function uses GPIOx_BSRR register to allow atomic read/modify
+  *         accesses. In this way, there is no risk of an IRQ occurring between
+  *         the read and the modify access.
+  *
+  * @param  GPIOx: where x can be (A..K) to select the GPIO peripheral.
+  * @param  GPIO_Pin: specifies the port bit to be written.
+  *          This parameter can be one of GPIO_PIN_x where x can be (0..15).
+  * @param  PinState: specifies the value to be written to the selected bit.
+  *          This parameter can be one of the GPIO_PinState enum values:
+  *            @arg GPIO_PIN_RESET: to clear the port pin
+  *            @arg GPIO_PIN_SET: to set the port pin
+  * @retval None
+  */
+void HAL_GPIO_WritePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState)
+{
+  /* Check the parameters */
+  assert_param(IS_GPIO_PIN(GPIO_Pin));
+  assert_param(IS_GPIO_PIN_ACTION(PinState));
+
+  if (PinState != GPIO_PIN_RESET)
+  {
+    GPIOx->BSRR = GPIO_Pin;
+  }
+  else
+  {
+    GPIOx->BSRR = (uint32_t)GPIO_Pin << GPIO_NUMBER;
+  }
+}
+
+/**
+  * @brief  Toggles the specified GPIO pins.
+  * @param  GPIOx: Where x can be (A..K) to select the GPIO peripheral.
+  * @param  GPIO_Pin: Specifies the pins to be toggled.
+  * @retval None
+  */
+void HAL_GPIO_TogglePin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)
+{
+  uint32_t odr;
+
+  /* Check the parameters */
+  assert_param(IS_GPIO_PIN(GPIO_Pin));
+
+  /* get current Output Data Register value */
+  odr = GPIOx->ODR;
+
+  /* Set selected pins that were at low level, and reset ones that were high */
+  GPIOx->BSRR = ((odr & GPIO_Pin) << GPIO_NUMBER) | (~odr & GPIO_Pin);
+}
+
+/**
+  * @brief  Locks GPIO Pins configuration registers.
+  * @note   The locked registers are GPIOx_MODER, GPIOx_OTYPER, GPIOx_OSPEEDR,
+  *         GPIOx_PUPDR, GPIOx_AFRL and GPIOx_AFRH.
+  * @note   The configuration of the locked GPIO pins can no longer be modified
+  *         until the next reset.
+  * @param  GPIOx: where x can be (A..K) to select the GPIO peripheral for STM32H7 family
+  * @param  GPIO_Pin: specifies the port bit to be locked.
+  *         This parameter can be any combination of GPIO_PIN_x where x can be (0..15).
+  * @retval None
+  */
+HAL_StatusTypeDef HAL_GPIO_LockPin(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)
+{
+  __IO uint32_t tmp = GPIO_LCKR_LCKK;
+
+  /* Check the parameters */
+  assert_param(IS_GPIO_LOCK_INSTANCE(GPIOx));
+  assert_param(IS_GPIO_PIN(GPIO_Pin));
+
+  /* Apply lock key write sequence */
+  tmp |= GPIO_Pin;
+  /* Set LCKx bit(s): LCKK='1' + LCK[15-0] */
+  GPIOx->LCKR = tmp;
+  /* Reset LCKx bit(s): LCKK='0' + LCK[15-0] */
+  GPIOx->LCKR = GPIO_Pin;
+  /* Set LCKx bit(s): LCKK='1' + LCK[15-0] */
+  GPIOx->LCKR = tmp;
+  /* Read LCKK register. This read is mandatory to complete key lock sequence*/
+  tmp = GPIOx->LCKR;
+
+  /* read again in order to confirm lock is active */
+  if ((GPIOx->LCKR & GPIO_LCKR_LCKK) != 0x00U)
+  {
+    return HAL_OK;
+  }
+  else
+  {
+    return HAL_ERROR;
+  }
+}
+
+/**
+  * @brief  Handle EXTI interrupt request.
+  * @param  GPIO_Pin: Specifies the port pin connected to corresponding EXTI line.
+  * @retval None
+  */
+void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin)
+{
+#if defined(DUAL_CORE) && defined(CORE_CM4)
+  if (__HAL_GPIO_EXTID2_GET_IT(GPIO_Pin) != 0x00U)
+  {
+    __HAL_GPIO_EXTID2_CLEAR_IT(GPIO_Pin);
+    HAL_GPIO_EXTI_Callback(GPIO_Pin);
+  }
+#else
+  /* EXTI line interrupt detected */
+  if (__HAL_GPIO_EXTI_GET_IT(GPIO_Pin) != 0x00U)
+  {
+    __HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin);
+    HAL_GPIO_EXTI_Callback(GPIO_Pin);
+  }
+#endif
+}
+
+/**
+  * @brief  EXTI line detection callback.
+  * @param  GPIO_Pin: Specifies the port pin connected to corresponding EXTI line.
+  * @retval None
+  */
+__weak void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
+{
+  /* Prevent unused argument(s) compilation warning */
+  UNUSED(GPIO_Pin);
+
+  /* NOTE: This function Should not be modified, when the callback is needed,
+           the HAL_GPIO_EXTI_Callback could be implemented in the user file
+   */
+}
+
+/**
+  * @}
+  */
+
+
+/**
+  * @}
+  */
+
+#endif /* HAL_GPIO_MODULE_ENABLED */
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
Index: ctrl/firmware/Main/CubeMX/Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_spi.c
===================================================================
--- ctrl/firmware/Main/CubeMX/Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_spi.c	(revision 45)
+++ ctrl/firmware/Main/CubeMX/Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_spi.c	(revision 45)
@@ -0,0 +1,4016 @@
+/**
+  ******************************************************************************
+  * @file    stm32h7xx_hal_spi.c
+  * @author  MCD Application Team
+  * @brief   SPI HAL module driver.
+  *          This file provides firmware functions to manage the following
+  *          functionalities of the Serial Peripheral Interface (SPI) peripheral:
+  *           + Initialization and de-initialization functions
+  *           + IO operation functions
+  *           + Peripheral Control functions
+  *           + Peripheral State functions
+  *
+  ******************************************************************************
+  * @attention
+  *
+  * Copyright (c) 2017 STMicroelectronics.
+  * All rights reserved.
+  *
+  * This software is licensed under terms that can be found in the LICENSE file
+  * in the root directory of this software component.
+  * If no LICENSE file comes with this software, it is provided AS-IS.
+  *
+  ******************************************************************************
+  @verbatim
+  ==============================================================================
+                        ##### How to use this driver #####
+  ==============================================================================
+    [..]
+      The SPI HAL driver can be used as follows:
+
+      (#) Declare a SPI_HandleTypeDef handle structure, for example:
+          SPI_HandleTypeDef  hspi;
+
+      (#)Initialize the SPI low level resources by implementing the HAL_SPI_MspInit() API:
+          (##) Enable the SPIx interface clock
+          (##) SPI pins configuration
+              (+++) Enable the clock for the SPI GPIOs
+              (+++) Configure these SPI pins as alternate function push-pull
+          (##) NVIC configuration if you need to use interrupt process or DMA process
+              (+++) Configure the SPIx interrupt priority
+              (+++) Enable the NVIC SPI IRQ handle
+          (##) DMA Configuration if you need to use DMA process
+              (+++) Declare a DMA_HandleTypeDef handle structure for the transmit or receive Stream/Channel
+              (+++) Enable the DMAx clock
+              (+++) Configure the DMA handle parameters
+              (+++) Configure the DMA Tx or Rx Stream/Channel
+              (+++) Associate the initialized hdma_tx handle to the hspi DMA Tx or Rx handle
+              (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on the DMA Tx
+                    or Rx Stream/Channel
+
+      (#) Program the Mode, BidirectionalMode , Data size, Baudrate Prescaler, NSS
+          management, Clock polarity and phase, FirstBit and CRC configuration in the hspi Init structure.
+
+      (#) Initialize the SPI registers by calling the HAL_SPI_Init() API:
+          (++) This API configures also the low level Hardware GPIO, CLOCK, CORTEX...etc)
+              by calling the customized HAL_SPI_MspInit() API.
+     [..]
+       Callback registration:
+
+      (#) The compilation flag USE_HAL_SPI_REGISTER_CALLBACKS when set to 1UL
+          allows the user to configure dynamically the driver callbacks.
+          Use Functions HAL_SPI_RegisterCallback() to register an interrupt callback.
+
+          Function HAL_SPI_RegisterCallback() allows to register following callbacks:
+            (+) TxCpltCallback        : SPI Tx Completed callback
+            (+) RxCpltCallback        : SPI Rx Completed callback
+            (+) TxRxCpltCallback      : SPI TxRx Completed callback
+            (+) TxHalfCpltCallback    : SPI Tx Half Completed callback
+            (+) RxHalfCpltCallback    : SPI Rx Half Completed callback
+            (+) TxRxHalfCpltCallback  : SPI TxRx Half Completed callback
+            (+) ErrorCallback         : SPI Error callback
+            (+) AbortCpltCallback     : SPI Abort callback
+            (+) SuspendCallback       : SPI Suspend callback
+            (+) MspInitCallback       : SPI Msp Init callback
+            (+) MspDeInitCallback     : SPI Msp DeInit callback
+          This function takes as parameters the HAL peripheral handle, the Callback ID
+          and a pointer to the user callback function.
+
+
+      (#) Use function HAL_SPI_UnRegisterCallback to reset a callback to the default
+          weak function.
+          HAL_SPI_UnRegisterCallback takes as parameters the HAL peripheral handle,
+          and the Callback ID.
+          This function allows to reset following callbacks:
+            (+) TxCpltCallback        : SPI Tx Completed callback
+            (+) RxCpltCallback        : SPI Rx Completed callback
+            (+) TxRxCpltCallback      : SPI TxRx Completed callback
+            (+) TxHalfCpltCallback    : SPI Tx Half Completed callback
+            (+) RxHalfCpltCallback    : SPI Rx Half Completed callback
+            (+) TxRxHalfCpltCallback  : SPI TxRx Half Completed callback
+            (+) ErrorCallback         : SPI Error callback
+            (+) AbortCpltCallback     : SPI Abort callback
+            (+) SuspendCallback       : SPI Suspend callback
+            (+) MspInitCallback       : SPI Msp Init callback
+            (+) MspDeInitCallback     : SPI Msp DeInit callback
+
+       By default, after the HAL_SPI_Init() and when the state is HAL_SPI_STATE_RESET
+       all callbacks are set to the corresponding weak functions:
+       examples HAL_SPI_MasterTxCpltCallback(), HAL_SPI_MasterRxCpltCallback().
+       Exception done for MspInit and MspDeInit functions that are
+       reset to the legacy weak functions in the HAL_SPI_Init()/ HAL_SPI_DeInit() only when
+       these callbacks are null (not registered beforehand).
+       If MspInit or MspDeInit are not null, the HAL_SPI_Init()/ HAL_SPI_DeInit()
+       keep and use the user MspInit/MspDeInit callbacks (registered beforehand) whatever the state.
+
+       Callbacks can be registered/unregistered in HAL_SPI_STATE_READY state only.
+       Exception done MspInit/MspDeInit functions that can be registered/unregistered
+       in HAL_SPI_STATE_READY or HAL_SPI_STATE_RESET state,
+       thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit.
+       Then, the user first registers the MspInit/MspDeInit user callbacks
+       using HAL_SPI_RegisterCallback() before calling HAL_SPI_DeInit()
+       or HAL_SPI_Init() function.
+
+       When The compilation define USE_HAL_PPP_REGISTER_CALLBACKS is set to 0 or not defined,
+       the callback registering feature is not available and weak callbacks are used.
+
+       SuspendCallback restriction:
+           SuspendCallback is called only when MasterReceiverAutoSusp is enabled and
+       EOT interrupt is activated. SuspendCallback is used in relation with functions
+       HAL_SPI_Transmit_IT, HAL_SPI_Receive_IT and HAL_SPI_TransmitReceive_IT.
+
+    [..]
+      Circular mode restriction:
+      (+) The DMA circular mode cannot be used when the SPI is configured in these modes:
+          (++) Master 2Lines RxOnly
+          (++) Master 1Line Rx
+      (+) The CRC feature is not managed when the DMA circular mode is enabled
+      (+) The functions HAL_SPI_DMAPause()/ HAL_SPI_DMAResume() are not supported. Return always
+          HAL_ERROR with ErrorCode set to HAL_SPI_ERROR_NOT_SUPPORTED.
+          Those functions are maintained for backward compatibility reasons.
+
+  @endverbatim
+  */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32h7xx_hal.h"
+
+/** @addtogroup STM32H7xx_HAL_Driver
+  * @{
+  */
+
+/** @defgroup SPI SPI
+  * @brief SPI HAL module driver
+  * @{
+  */
+#ifdef HAL_SPI_MODULE_ENABLED
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private defines -----------------------------------------------------------*/
+/** @defgroup SPI_Private_Constants SPI Private Constants
+  * @{
+  */
+#define SPI_DEFAULT_TIMEOUT 100UL
+/**
+  * @}
+  */
+
+/* Private macros ------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/** @defgroup SPI_Private_Functions SPI Private Functions
+  * @{
+  */
+static void SPI_DMATransmitCplt(DMA_HandleTypeDef *hdma);
+static void SPI_DMAReceiveCplt(DMA_HandleTypeDef *hdma);
+static void SPI_DMATransmitReceiveCplt(DMA_HandleTypeDef *hdma);
+static void SPI_DMAHalfTransmitCplt(DMA_HandleTypeDef *hdma);
+static void SPI_DMAHalfReceiveCplt(DMA_HandleTypeDef *hdma);
+static void SPI_DMAHalfTransmitReceiveCplt(DMA_HandleTypeDef *hdma);
+static void SPI_DMAError(DMA_HandleTypeDef *hdma);
+static void SPI_DMAAbortOnError(DMA_HandleTypeDef *hdma);
+static void SPI_DMATxAbortCallback(DMA_HandleTypeDef *hdma);
+static void SPI_DMARxAbortCallback(DMA_HandleTypeDef *hdma);
+static HAL_StatusTypeDef SPI_WaitOnFlagUntilTimeout(const SPI_HandleTypeDef *hspi, uint32_t Flag,
+                                                    FlagStatus FlagStatus, uint32_t Timeout, uint32_t Tickstart);
+static void SPI_TxISR_8BIT(SPI_HandleTypeDef *hspi);
+static void SPI_TxISR_16BIT(SPI_HandleTypeDef *hspi);
+static void SPI_TxISR_32BIT(SPI_HandleTypeDef *hspi);
+static void SPI_RxISR_8BIT(SPI_HandleTypeDef *hspi);
+static void SPI_RxISR_16BIT(SPI_HandleTypeDef *hspi);
+static void SPI_RxISR_32BIT(SPI_HandleTypeDef *hspi);
+static void SPI_AbortTransfer(SPI_HandleTypeDef *hspi);
+static void SPI_CloseTransfer(SPI_HandleTypeDef *hspi);
+static uint32_t SPI_GetPacketSize(const SPI_HandleTypeDef *hspi);
+
+
+/**
+  * @}
+  */
+
+/* Exported functions --------------------------------------------------------*/
+/** @defgroup SPI_Exported_Functions SPI Exported Functions
+  * @{
+  */
+
+/** @defgroup SPI_Exported_Functions_Group1 Initialization and de-initialization functions
+  *  @brief    Initialization and Configuration functions
+  *
+@verbatim
+ ===============================================================================
+              ##### Initialization and de-initialization functions #####
+ ===============================================================================
+    [..]  This subsection provides a set of functions allowing to initialize and
+          de-initialize the SPIx peripheral:
+
+      (+) User must implement HAL_SPI_MspInit() function in which he configures
+          all related peripherals resources (CLOCK, GPIO, DMA, IT and NVIC ).
+
+      (+) Call the function HAL_SPI_Init() to configure the selected device with
+          the selected configuration:
+        (++) Mode
+        (++) Direction
+        (++) Data Size
+        (++) Clock Polarity and Phase
+        (++) NSS Management
+        (++) BaudRate Prescaler
+        (++) FirstBit
+        (++) TIMode
+        (++) CRC Calculation
+        (++) CRC Polynomial if CRC enabled
+        (++) CRC Length, used only with Data8 and Data16
+        (++) FIFO reception threshold
+        (++) FIFO transmission threshold
+
+      (+) Call the function HAL_SPI_DeInit() to restore the default configuration
+          of the selected SPIx peripheral.
+
+@endverbatim
+  * @{
+  */
+
+/**
+  * @brief  Initialize the SPI according to the specified parameters
+  *         in the SPI_InitTypeDef and initialize the associated handle.
+  * @param  hspi: pointer to a SPI_HandleTypeDef structure that contains
+  *               the configuration information for SPI module.
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_SPI_Init(SPI_HandleTypeDef *hspi)
+{
+  uint32_t crc_length;
+  uint32_t packet_length;
+#if (USE_SPI_CRC != 0UL)
+  uint32_t crc_poly_msb_mask;
+#endif /* USE_SPI_CRC */
+
+  /* Check the SPI handle allocation */
+  if (hspi == NULL)
+  {
+    return HAL_ERROR;
+  }
+
+  /* Check the parameters */
+  assert_param(IS_SPI_ALL_INSTANCE(hspi->Instance));
+  assert_param(IS_SPI_MODE(hspi->Init.Mode));
+  assert_param(IS_SPI_DIRECTION(hspi->Init.Direction));
+  assert_param(IS_SPI_DATASIZE(hspi->Init.DataSize));
+  assert_param(IS_SPI_FIFOTHRESHOLD(hspi->Init.FifoThreshold));
+  assert_param(IS_SPI_NSS(hspi->Init.NSS));
+  assert_param(IS_SPI_NSSP(hspi->Init.NSSPMode));
+  assert_param(IS_SPI_BAUDRATE_PRESCALER(hspi->Init.BaudRatePrescaler));
+  assert_param(IS_SPI_FIRST_BIT(hspi->Init.FirstBit));
+  assert_param(IS_SPI_TIMODE(hspi->Init.TIMode));
+  if (hspi->Init.TIMode == SPI_TIMODE_DISABLE)
+  {
+    assert_param(IS_SPI_CPOL(hspi->Init.CLKPolarity));
+    assert_param(IS_SPI_CPHA(hspi->Init.CLKPhase));
+  }
+#if (USE_SPI_CRC != 0UL)
+  assert_param(IS_SPI_CRC_CALCULATION(hspi->Init.CRCCalculation));
+  if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
+  {
+    assert_param(IS_SPI_CRC_LENGTH(hspi->Init.CRCLength));
+    assert_param(IS_SPI_CRC_POLYNOMIAL(hspi->Init.CRCPolynomial));
+    assert_param(IS_SPI_CRC_INITIALIZATION_PATTERN(hspi->Init.TxCRCInitializationPattern));
+    assert_param(IS_SPI_CRC_INITIALIZATION_PATTERN(hspi->Init.RxCRCInitializationPattern));
+  }
+#else
+  hspi->Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
+#endif /* USE_SPI_CRC */
+
+  /* Verify that the SPI instance supports Data Size higher than 16bits */
+  if ((!IS_SPI_HIGHEND_INSTANCE(hspi->Instance)) && (hspi->Init.DataSize > SPI_DATASIZE_16BIT))
+  {
+    return HAL_ERROR;
+  }
+
+  /* Verify that the SPI instance supports requested data packing */
+  packet_length = SPI_GetPacketSize(hspi);
+  if (((!IS_SPI_HIGHEND_INSTANCE(hspi->Instance)) && (packet_length > SPI_LOWEND_FIFO_SIZE)) ||
+      ((IS_SPI_HIGHEND_INSTANCE(hspi->Instance)) && (packet_length > SPI_HIGHEND_FIFO_SIZE)))
+  {
+    return HAL_ERROR;
+  }
+
+#if (USE_SPI_CRC != 0UL)
+  if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
+  {
+    /* Verify that the SPI instance supports CRC Length higher than 16bits */
+    if ((!IS_SPI_HIGHEND_INSTANCE(hspi->Instance)) && (hspi->Init.CRCLength > SPI_CRC_LENGTH_16BIT))
+    {
+      return HAL_ERROR;
+    }
+
+    /* Align the CRC Length on the data size */
+    if (hspi->Init.CRCLength == SPI_CRC_LENGTH_DATASIZE)
+    {
+      crc_length = (hspi->Init.DataSize >> SPI_CFG1_DSIZE_Pos) << SPI_CFG1_CRCSIZE_Pos;
+    }
+    else
+    {
+      crc_length = hspi->Init.CRCLength;
+    }
+
+    /* Verify the correctness of polynom size */
+    assert_param(IS_SPI_CRC_POLYNOMIAL_SIZE(hspi->Init.CRCPolynomial, crc_length));
+
+    /* Verify that the CRC Length is higher than DataSize */
+    if ((hspi->Init.DataSize >> SPI_CFG1_DSIZE_Pos) > (crc_length >> SPI_CFG1_CRCSIZE_Pos))
+    {
+      return HAL_ERROR;
+    }
+  }
+  else
+  {
+    crc_length = hspi->Init.DataSize << SPI_CFG1_CRCSIZE_Pos;
+  }
+#endif /* USE_SPI_CRC */
+
+  if (hspi->State == HAL_SPI_STATE_RESET)
+  {
+    /* Allocate lock resource and initialize it */
+    hspi->Lock = HAL_UNLOCKED;
+
+#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1UL)
+    /* Init the SPI Callback settings */
+    hspi->TxCpltCallback       = HAL_SPI_TxCpltCallback;       /* Legacy weak TxCpltCallback       */
+    hspi->RxCpltCallback       = HAL_SPI_RxCpltCallback;       /* Legacy weak RxCpltCallback       */
+    hspi->TxRxCpltCallback     = HAL_SPI_TxRxCpltCallback;     /* Legacy weak TxRxCpltCallback     */
+    hspi->TxHalfCpltCallback   = HAL_SPI_TxHalfCpltCallback;   /* Legacy weak TxHalfCpltCallback   */
+    hspi->RxHalfCpltCallback   = HAL_SPI_RxHalfCpltCallback;   /* Legacy weak RxHalfCpltCallback   */
+    hspi->TxRxHalfCpltCallback = HAL_SPI_TxRxHalfCpltCallback; /* Legacy weak TxRxHalfCpltCallback */
+    hspi->ErrorCallback        = HAL_SPI_ErrorCallback;        /* Legacy weak ErrorCallback        */
+    hspi->AbortCpltCallback    = HAL_SPI_AbortCpltCallback;    /* Legacy weak AbortCpltCallback    */
+    hspi->SuspendCallback      = HAL_SPI_SuspendCallback;      /* Legacy weak SuspendCallback      */
+
+    if (hspi->MspInitCallback == NULL)
+    {
+      hspi->MspInitCallback = HAL_SPI_MspInit; /* Legacy weak MspInit  */
+    }
+
+    /* Init the low level hardware : GPIO, CLOCK, NVIC... */
+    hspi->MspInitCallback(hspi);
+#else
+    /* Init the low level hardware : GPIO, CLOCK, NVIC... */
+    HAL_SPI_MspInit(hspi);
+#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
+  }
+
+  hspi->State = HAL_SPI_STATE_BUSY;
+
+  /* Disable the selected SPI peripheral */
+  __HAL_SPI_DISABLE(hspi);
+
+#if (USE_SPI_CRC == 0)
+  /* Keep the default value of CRCSIZE in case of CRC is not used */
+  crc_length = hspi->Instance->CFG1 & SPI_CFG1_CRCSIZE;
+#endif /* USE_SPI_CRC */
+
+  /*----------------------- SPIx CR1 & CR2 Configuration ---------------------*/
+  /* Configure : SPI Mode, Communication Mode, Clock polarity and phase, NSS management,
+  Communication speed, First bit, CRC calculation state, CRC Length */
+
+  /* SPIx NSS Software Management Configuration */
+  if ((hspi->Init.NSS == SPI_NSS_SOFT) && (((hspi->Init.Mode == SPI_MODE_MASTER) &&  \
+                                            (hspi->Init.NSSPolarity == SPI_NSS_POLARITY_LOW)) || \
+                                           ((hspi->Init.Mode == SPI_MODE_SLAVE) && \
+                                            (hspi->Init.NSSPolarity == SPI_NSS_POLARITY_HIGH))))
+  {
+    SET_BIT(hspi->Instance->CR1, SPI_CR1_SSI);
+  }
+
+  /* SPIx Master Rx Auto Suspend Configuration */
+  if (((hspi->Init.Mode & SPI_MODE_MASTER) == SPI_MODE_MASTER) && (hspi->Init.DataSize >= SPI_DATASIZE_8BIT))
+  {
+    MODIFY_REG(hspi->Instance->CR1, SPI_CR1_MASRX, hspi->Init.MasterReceiverAutoSusp);
+  }
+  else
+  {
+    CLEAR_BIT(hspi->Instance->CR1, SPI_CR1_MASRX);
+  }
+
+  /* SPIx CFG1 Configuration */
+  WRITE_REG(hspi->Instance->CFG1, (hspi->Init.BaudRatePrescaler | hspi->Init.CRCCalculation | crc_length |
+                                   hspi->Init.FifoThreshold     | hspi->Init.DataSize));
+
+  /* SPIx CFG2 Configuration */
+  WRITE_REG(hspi->Instance->CFG2, (hspi->Init.NSSPMode                | hspi->Init.TIMode    |
+                                   hspi->Init.NSSPolarity             | hspi->Init.NSS       |
+                                   hspi->Init.CLKPolarity             | hspi->Init.CLKPhase  |
+                                   hspi->Init.FirstBit                | hspi->Init.Mode      |
+                                   hspi->Init.MasterInterDataIdleness | hspi->Init.Direction |
+                                   hspi->Init.MasterSSIdleness        | hspi->Init.IOSwap));
+
+#if (USE_SPI_CRC != 0UL)
+  /*---------------------------- SPIx CRCPOLY Configuration ------------------*/
+  /* Configure : CRC Polynomial */
+  if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
+  {
+    /* Initialize TXCRC Pattern Initial Value */
+    if (hspi->Init.TxCRCInitializationPattern == SPI_CRC_INITIALIZATION_ALL_ONE_PATTERN)
+    {
+      SET_BIT(hspi->Instance->CR1, SPI_CR1_TCRCINI);
+    }
+    else
+    {
+      CLEAR_BIT(hspi->Instance->CR1, SPI_CR1_TCRCINI);
+    }
+
+    /* Initialize RXCRC Pattern Initial Value */
+    if (hspi->Init.RxCRCInitializationPattern == SPI_CRC_INITIALIZATION_ALL_ONE_PATTERN)
+    {
+      SET_BIT(hspi->Instance->CR1, SPI_CR1_RCRCINI);
+    }
+    else
+    {
+      CLEAR_BIT(hspi->Instance->CR1, SPI_CR1_RCRCINI);
+    }
+
+    /* Enable 33/17 bits CRC computation */
+    if (((!IS_SPI_HIGHEND_INSTANCE(hspi->Instance)) && (crc_length == SPI_CRC_LENGTH_16BIT)) ||
+        ((IS_SPI_HIGHEND_INSTANCE(hspi->Instance))  && (crc_length == SPI_CRC_LENGTH_32BIT)))
+    {
+      /* Set SPI_CR1_CRC33_17 bit */
+      SET_BIT(hspi->Instance->CR1, SPI_CR1_CRC33_17);
+      /* Write CRC polynomial in SPI Register */
+      WRITE_REG(hspi->Instance->CRCPOLY, hspi->Init.CRCPolynomial);
+    }
+    else
+    {
+      /* Clear SPI_CR1_CRC33_17 bit */
+      CLEAR_BIT(hspi->Instance->CR1, SPI_CR1_CRC33_17);
+
+      /* Write CRC polynomial and set MSB bit at 1 in SPI Register */
+      /* Set MSB is mandatory for a correct CRC computation        */
+      crc_poly_msb_mask = (0x1UL << ((crc_length >> SPI_CFG1_CRCSIZE_Pos) + 0x1U));
+      WRITE_REG(hspi->Instance->CRCPOLY, (hspi->Init.CRCPolynomial) | crc_poly_msb_mask);
+    }
+  }
+#endif /* USE_SPI_CRC */
+
+  /* Insure that Underrun configuration is managed only by Salve */
+  if (hspi->Init.Mode == SPI_MODE_SLAVE)
+  {
+    /* Set Default Underrun configuration */
+#if (USE_SPI_CRC != 0UL)
+    if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_DISABLE)
+#endif /* USE_SPI_CRC */
+    {
+      MODIFY_REG(hspi->Instance->CFG1, SPI_CFG1_UDRDET, SPI_CFG1_UDRDET_0);
+    }
+    MODIFY_REG(hspi->Instance->CFG1, SPI_CFG1_UDRCFG, SPI_CFG1_UDRCFG_1);
+  }
+
+#if defined(SPI_I2SCFGR_I2SMOD)
+  /* Activate the SPI mode (Make sure that I2SMOD bit in I2SCFGR register is reset) */
+  CLEAR_BIT(hspi->Instance->I2SCFGR, SPI_I2SCFGR_I2SMOD);
+#endif /* SPI_I2SCFGR_I2SMOD */
+
+  /* Insure that AFCNTR is managed only by Master */
+  if ((hspi->Init.Mode & SPI_MODE_MASTER) == SPI_MODE_MASTER)
+  {
+    /* Alternate function GPIOs control */
+    MODIFY_REG(hspi->Instance->CFG2, SPI_CFG2_AFCNTR, (hspi->Init.MasterKeepIOState));
+  }
+
+  hspi->ErrorCode = HAL_SPI_ERROR_NONE;
+  hspi->State     = HAL_SPI_STATE_READY;
+
+  return HAL_OK;
+}
+
+/**
+  * @brief  De-Initialize the SPI peripheral.
+  * @param  hspi: pointer to a SPI_HandleTypeDef structure that contains
+  *               the configuration information for SPI module.
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_SPI_DeInit(SPI_HandleTypeDef *hspi)
+{
+  /* Check the SPI handle allocation */
+  if (hspi == NULL)
+  {
+    return HAL_ERROR;
+  }
+
+  /* Check SPI Instance parameter */
+  assert_param(IS_SPI_ALL_INSTANCE(hspi->Instance));
+
+  hspi->State = HAL_SPI_STATE_BUSY;
+
+  /* Disable the SPI Peripheral Clock */
+  __HAL_SPI_DISABLE(hspi);
+
+#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1UL)
+  if (hspi->MspDeInitCallback == NULL)
+  {
+    hspi->MspDeInitCallback = HAL_SPI_MspDeInit; /* Legacy weak MspDeInit  */
+  }
+
+  /* DeInit the low level hardware: GPIO, CLOCK, NVIC... */
+  hspi->MspDeInitCallback(hspi);
+#else
+  /* DeInit the low level hardware: GPIO, CLOCK, NVIC... */
+  HAL_SPI_MspDeInit(hspi);
+#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
+
+  hspi->ErrorCode = HAL_SPI_ERROR_NONE;
+  hspi->State = HAL_SPI_STATE_RESET;
+
+  /* Release Lock */
+  __HAL_UNLOCK(hspi);
+
+  return HAL_OK;
+}
+
+/**
+  * @brief  Initialize the SPI MSP.
+  * @param  hspi: pointer to a SPI_HandleTypeDef structure that contains
+  *               the configuration information for SPI module.
+  * @retval None
+  */
+__weak void HAL_SPI_MspInit(SPI_HandleTypeDef *hspi)
+{
+  /* Prevent unused argument(s) compilation warning */
+  UNUSED(hspi);
+
+  /* NOTE : This function should not be modified, when the callback is needed,
+            the HAL_SPI_MspInit should be implemented in the user file
+   */
+}
+
+/**
+  * @brief  De-Initialize the SPI MSP.
+  * @param  hspi: pointer to a SPI_HandleTypeDef structure that contains
+  *               the configuration information for SPI module.
+  * @retval None
+  */
+__weak void HAL_SPI_MspDeInit(SPI_HandleTypeDef *hspi)
+{
+  /* Prevent unused argument(s) compilation warning */
+  UNUSED(hspi);
+
+  /* NOTE : This function should not be modified, when the callback is needed,
+            the HAL_SPI_MspDeInit should be implemented in the user file
+   */
+}
+
+#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1UL)
+/**
+  * @brief  Register a User SPI Callback
+  *         To be used instead of the weak predefined callback
+  * @param  hspi Pointer to a SPI_HandleTypeDef structure that contains
+  *                the configuration information for the specified SPI.
+  * @param  CallbackID ID of the callback to be registered
+  * @param  pCallback pointer to the Callback function
+  * @note   The HAL_SPI_RegisterCallback() may be called before HAL_SPI_Init() in HAL_SPI_STATE_RESET
+  *         to register callbacks for HAL_SPI_MSPINIT_CB_ID and HAL_SPI_MSPDEINIT_CB_ID
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_SPI_RegisterCallback(SPI_HandleTypeDef *hspi, HAL_SPI_CallbackIDTypeDef CallbackID,
+                                           pSPI_CallbackTypeDef pCallback)
+{
+  HAL_StatusTypeDef status = HAL_OK;
+
+  if (pCallback == NULL)
+  {
+    /* Update the error code */
+    hspi->ErrorCode |= HAL_SPI_ERROR_INVALID_CALLBACK;
+
+    return HAL_ERROR;
+  }
+
+  if (HAL_SPI_STATE_READY == hspi->State)
+  {
+    switch (CallbackID)
+    {
+      case HAL_SPI_TX_COMPLETE_CB_ID :
+        hspi->TxCpltCallback = pCallback;
+        break;
+
+      case HAL_SPI_RX_COMPLETE_CB_ID :
+        hspi->RxCpltCallback = pCallback;
+        break;
+
+      case HAL_SPI_TX_RX_COMPLETE_CB_ID :
+        hspi->TxRxCpltCallback = pCallback;
+        break;
+
+      case HAL_SPI_TX_HALF_COMPLETE_CB_ID :
+        hspi->TxHalfCpltCallback = pCallback;
+        break;
+
+      case HAL_SPI_RX_HALF_COMPLETE_CB_ID :
+        hspi->RxHalfCpltCallback = pCallback;
+        break;
+
+      case HAL_SPI_TX_RX_HALF_COMPLETE_CB_ID :
+        hspi->TxRxHalfCpltCallback = pCallback;
+        break;
+
+      case HAL_SPI_ERROR_CB_ID :
+        hspi->ErrorCallback = pCallback;
+        break;
+
+      case HAL_SPI_ABORT_CB_ID :
+        hspi->AbortCpltCallback = pCallback;
+        break;
+
+      case HAL_SPI_SUSPEND_CB_ID :
+        hspi->SuspendCallback = pCallback;
+        break;
+
+      case HAL_SPI_MSPINIT_CB_ID :
+        hspi->MspInitCallback = pCallback;
+        break;
+
+      case HAL_SPI_MSPDEINIT_CB_ID :
+        hspi->MspDeInitCallback = pCallback;
+        break;
+
+      default :
+        /* Update the error code */
+        SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_INVALID_CALLBACK);
+
+        /* Return error status */
+        status =  HAL_ERROR;
+        break;
+    }
+  }
+  else if (HAL_SPI_STATE_RESET == hspi->State)
+  {
+    switch (CallbackID)
+    {
+      case HAL_SPI_MSPINIT_CB_ID :
+        hspi->MspInitCallback = pCallback;
+        break;
+
+      case HAL_SPI_MSPDEINIT_CB_ID :
+        hspi->MspDeInitCallback = pCallback;
+        break;
+
+      default :
+        /* Update the error code */
+        SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_INVALID_CALLBACK);
+
+        /* Return error status */
+        status =  HAL_ERROR;
+        break;
+    }
+  }
+  else
+  {
+    /* Update the error code */
+    SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_INVALID_CALLBACK);
+
+    /* Return error status */
+    status =  HAL_ERROR;
+  }
+
+  return status;
+}
+
+/**
+  * @brief  Unregister an SPI Callback
+  *         SPI callback is redirected to the weak predefined callback
+  * @param  hspi Pointer to a SPI_HandleTypeDef structure that contains
+  *                the configuration information for the specified SPI.
+  * @param  CallbackID ID of the callback to be unregistered
+  * @note   The HAL_SPI_UnRegisterCallback() may be called before HAL_SPI_Init() in HAL_SPI_STATE_RESET
+  *         to un-register callbacks for HAL_SPI_MSPINIT_CB_ID and HAL_SPI_MSPDEINIT_CB_ID
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_SPI_UnRegisterCallback(SPI_HandleTypeDef *hspi, HAL_SPI_CallbackIDTypeDef CallbackID)
+{
+  HAL_StatusTypeDef status = HAL_OK;
+
+  if (HAL_SPI_STATE_READY == hspi->State)
+  {
+    switch (CallbackID)
+    {
+      case HAL_SPI_TX_COMPLETE_CB_ID :
+        hspi->TxCpltCallback = HAL_SPI_TxCpltCallback;             /* Legacy weak TxCpltCallback       */
+        break;
+
+      case HAL_SPI_RX_COMPLETE_CB_ID :
+        hspi->RxCpltCallback = HAL_SPI_RxCpltCallback;             /* Legacy weak RxCpltCallback       */
+        break;
+
+      case HAL_SPI_TX_RX_COMPLETE_CB_ID :
+        hspi->TxRxCpltCallback = HAL_SPI_TxRxCpltCallback;         /* Legacy weak TxRxCpltCallback     */
+        break;
+
+      case HAL_SPI_TX_HALF_COMPLETE_CB_ID :
+        hspi->TxHalfCpltCallback = HAL_SPI_TxHalfCpltCallback;     /* Legacy weak TxHalfCpltCallback   */
+        break;
+
+      case HAL_SPI_RX_HALF_COMPLETE_CB_ID :
+        hspi->RxHalfCpltCallback = HAL_SPI_RxHalfCpltCallback;     /* Legacy weak RxHalfCpltCallback   */
+        break;
+
+      case HAL_SPI_TX_RX_HALF_COMPLETE_CB_ID :
+        hspi->TxRxHalfCpltCallback = HAL_SPI_TxRxHalfCpltCallback; /* Legacy weak TxRxHalfCpltCallback */
+        break;
+
+      case HAL_SPI_ERROR_CB_ID :
+        hspi->ErrorCallback = HAL_SPI_ErrorCallback;               /* Legacy weak ErrorCallback        */
+        break;
+
+      case HAL_SPI_ABORT_CB_ID :
+        hspi->AbortCpltCallback = HAL_SPI_AbortCpltCallback;       /* Legacy weak AbortCpltCallback    */
+        break;
+
+      case HAL_SPI_SUSPEND_CB_ID :
+        hspi->SuspendCallback = HAL_SPI_SuspendCallback;           /* Legacy weak SuspendCallback      */
+        break;
+
+      case HAL_SPI_MSPINIT_CB_ID :
+        hspi->MspInitCallback = HAL_SPI_MspInit;                   /* Legacy weak MspInit              */
+        break;
+
+      case HAL_SPI_MSPDEINIT_CB_ID :
+        hspi->MspDeInitCallback = HAL_SPI_MspDeInit;               /* Legacy weak MspDeInit            */
+        break;
+
+      default :
+        /* Update the error code */
+        SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_INVALID_CALLBACK);
+
+        /* Return error status */
+        status =  HAL_ERROR;
+        break;
+    }
+  }
+  else if (HAL_SPI_STATE_RESET == hspi->State)
+  {
+    switch (CallbackID)
+    {
+      case HAL_SPI_MSPINIT_CB_ID :
+        hspi->MspInitCallback = HAL_SPI_MspInit;                   /* Legacy weak MspInit              */
+        break;
+
+      case HAL_SPI_MSPDEINIT_CB_ID :
+        hspi->MspDeInitCallback = HAL_SPI_MspDeInit;               /* Legacy weak MspDeInit            */
+        break;
+
+      default :
+        /* Update the error code */
+        SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_INVALID_CALLBACK);
+
+        /* Return error status */
+        status =  HAL_ERROR;
+        break;
+    }
+  }
+  else
+  {
+    /* Update the error code */
+    SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_INVALID_CALLBACK);
+
+    /* Return error status */
+    status =  HAL_ERROR;
+  }
+
+  return status;
+}
+#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
+/**
+  * @}
+  */
+
+/** @defgroup SPI_Exported_Functions_Group2 IO operation functions
+  *  @brief   Data transfers functions
+  *
+@verbatim
+  ==============================================================================
+                      ##### IO operation functions #####
+ ===============================================================================
+ [..]
+    This subsection provides a set of functions allowing to manage the SPI
+    data transfers.
+
+    [..] The SPI supports master and slave mode :
+
+    (#) There are two modes of transfer:
+       (##) Blocking mode: The communication is performed in polling mode.
+            The HAL status of all data processing is returned by the same function
+            after finishing transfer.
+       (##) No-Blocking mode: The communication is performed using Interrupts
+            or DMA, These APIs return the HAL status.
+            The end of the data processing will be indicated through the
+            dedicated SPI IRQ when using Interrupt mode or the DMA IRQ when
+            using DMA mode.
+            The HAL_SPI_TxCpltCallback(), HAL_SPI_RxCpltCallback() and HAL_SPI_TxRxCpltCallback() user callbacks
+            will be executed respectively at the end of the transmit or Receive process
+            The HAL_SPI_ErrorCallback()user callback will be executed when a communication error is detected
+
+    (#) APIs provided for these 2 transfer modes (Blocking mode or Non blocking mode using either Interrupt or DMA)
+        exist for 1Line (simplex) and 2Lines (full duplex) modes.
+
+@endverbatim
+  * @{
+  */
+
+/**
+  * @brief  Transmit an amount of data in blocking mode.
+  * @param  hspi   : pointer to a SPI_HandleTypeDef structure that contains
+  *                  the configuration information for SPI module.
+  * @param  pData  : pointer to data buffer
+  * @param  Size   : amount of data to be sent
+  * @param  Timeout: Timeout duration
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_SPI_Transmit(SPI_HandleTypeDef *hspi, const uint8_t *pData, uint16_t Size, uint32_t Timeout)
+{
+#if defined (__GNUC__)
+  __IO uint16_t *ptxdr_16bits = (__IO uint16_t *)(&(hspi->Instance->TXDR));
+#endif /* __GNUC__ */
+
+  uint32_t tickstart;
+
+  /* Check Direction parameter */
+  assert_param(IS_SPI_DIRECTION_2LINES_OR_1LINE_2LINES_TXONLY(hspi->Init.Direction));
+
+  /* Init tickstart for timeout management*/
+  tickstart = HAL_GetTick();
+
+  if (hspi->State != HAL_SPI_STATE_READY)
+  {
+    return HAL_BUSY;
+  }
+
+  if ((pData == NULL) || (Size == 0UL))
+  {
+    return HAL_ERROR;
+  }
+
+  /* Lock the process */
+  __HAL_LOCK(hspi);
+
+  /* Set the transaction information */
+  hspi->State       = HAL_SPI_STATE_BUSY_TX;
+  hspi->ErrorCode   = HAL_SPI_ERROR_NONE;
+  hspi->pTxBuffPtr  = (const uint8_t *)pData;
+  hspi->TxXferSize  = Size;
+  hspi->TxXferCount = Size;
+
+  /*Init field not used in handle to zero */
+  hspi->pRxBuffPtr  = NULL;
+  hspi->RxXferSize  = (uint16_t) 0UL;
+  hspi->RxXferCount = (uint16_t) 0UL;
+  hspi->TxISR       = NULL;
+  hspi->RxISR       = NULL;
+
+  /* Configure communication direction : 1Line */
+  if (hspi->Init.Direction == SPI_DIRECTION_1LINE)
+  {
+    SPI_1LINE_TX(hspi);
+  }
+  else
+  {
+    SPI_2LINES_TX(hspi);
+  }
+
+  /* Set the number of data at current transfer */
+  MODIFY_REG(hspi->Instance->CR2, SPI_CR2_TSIZE, Size);
+
+  /* Enable SPI peripheral */
+  __HAL_SPI_ENABLE(hspi);
+
+  if (hspi->Init.Mode == SPI_MODE_MASTER)
+  {
+    /* Master transfer start */
+    SET_BIT(hspi->Instance->CR1, SPI_CR1_CSTART);
+  }
+
+  /* Transmit data in 32 Bit mode */
+  if (hspi->Init.DataSize > SPI_DATASIZE_16BIT)
+  {
+    /* Transmit data in 32 Bit mode */
+    while (hspi->TxXferCount > 0UL)
+    {
+      /* Wait until TXP flag is set to send data */
+      if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXP))
+      {
+        *((__IO uint32_t *)&hspi->Instance->TXDR) = *((const uint32_t *)hspi->pTxBuffPtr);
+        hspi->pTxBuffPtr += sizeof(uint32_t);
+        hspi->TxXferCount--;
+      }
+      else
+      {
+        /* Timeout management */
+        if ((((HAL_GetTick() - tickstart) >=  Timeout) && (Timeout != HAL_MAX_DELAY)) || (Timeout == 0U))
+        {
+          /* Call standard close procedure with error check */
+          SPI_CloseTransfer(hspi);
+
+          SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_TIMEOUT);
+          hspi->State = HAL_SPI_STATE_READY;
+
+          /* Unlock the process */
+          __HAL_UNLOCK(hspi);
+
+          return HAL_TIMEOUT;
+        }
+      }
+    }
+  }
+  /* Transmit data in 16 Bit mode */
+  else if (hspi->Init.DataSize > SPI_DATASIZE_8BIT)
+  {
+    /* Transmit data in 16 Bit mode */
+    while (hspi->TxXferCount > 0UL)
+    {
+      /* Wait until TXP flag is set to send data */
+      if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXP))
+      {
+        if ((hspi->TxXferCount > 1UL) && (hspi->Init.FifoThreshold > SPI_FIFO_THRESHOLD_01DATA))
+        {
+          *((__IO uint32_t *)&hspi->Instance->TXDR) = *((const uint32_t *)hspi->pTxBuffPtr);
+          hspi->pTxBuffPtr += sizeof(uint32_t);
+          hspi->TxXferCount -= (uint16_t)2UL;
+        }
+        else
+        {
+#if defined (__GNUC__)
+          *ptxdr_16bits = *((const uint16_t *)hspi->pTxBuffPtr);
+#else
+          *((__IO uint16_t *)&hspi->Instance->TXDR) = *((const uint16_t *)hspi->pTxBuffPtr);
+#endif /* __GNUC__ */
+          hspi->pTxBuffPtr += sizeof(uint16_t);
+          hspi->TxXferCount--;
+        }
+      }
+      else
+      {
+        /* Timeout management */
+        if ((((HAL_GetTick() - tickstart) >=  Timeout) && (Timeout != HAL_MAX_DELAY)) || (Timeout == 0U))
+        {
+          /* Call standard close procedure with error check */
+          SPI_CloseTransfer(hspi);
+
+          SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_TIMEOUT);
+          hspi->State = HAL_SPI_STATE_READY;
+
+          /* Unlock the process */
+          __HAL_UNLOCK(hspi);
+
+          return HAL_TIMEOUT;
+        }
+      }
+    }
+  }
+  /* Transmit data in 8 Bit mode */
+  else
+  {
+    while (hspi->TxXferCount > 0UL)
+    {
+      /* Wait until TXP flag is set to send data */
+      if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXP))
+      {
+        if ((hspi->TxXferCount > 3UL) && (hspi->Init.FifoThreshold > SPI_FIFO_THRESHOLD_03DATA))
+        {
+          *((__IO uint32_t *)&hspi->Instance->TXDR) = *((const uint32_t *)hspi->pTxBuffPtr);
+          hspi->pTxBuffPtr += sizeof(uint32_t);
+          hspi->TxXferCount -= (uint16_t)4UL;
+        }
+        else if ((hspi->TxXferCount > 1UL) && (hspi->Init.FifoThreshold > SPI_FIFO_THRESHOLD_01DATA))
+        {
+#if defined (__GNUC__)
+          *ptxdr_16bits = *((const uint16_t *)hspi->pTxBuffPtr);
+#else
+          *((__IO uint16_t *)&hspi->Instance->TXDR) = *((const uint16_t *)hspi->pTxBuffPtr);
+#endif /* __GNUC__ */
+          hspi->pTxBuffPtr += sizeof(uint16_t);
+          hspi->TxXferCount -= (uint16_t)2UL;
+        }
+        else
+        {
+          *((__IO uint8_t *)&hspi->Instance->TXDR) = *((const uint8_t *)hspi->pTxBuffPtr);
+          hspi->pTxBuffPtr += sizeof(uint8_t);
+          hspi->TxXferCount--;
+        }
+      }
+      else
+      {
+        /* Timeout management */
+        if ((((HAL_GetTick() - tickstart) >=  Timeout) && (Timeout != HAL_MAX_DELAY)) || (Timeout == 0U))
+        {
+          /* Call standard close procedure with error check */
+          SPI_CloseTransfer(hspi);
+
+          SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_TIMEOUT);
+          hspi->State = HAL_SPI_STATE_READY;
+
+          /* Unlock the process */
+          __HAL_UNLOCK(hspi);
+
+          return HAL_TIMEOUT;
+        }
+      }
+    }
+  }
+
+  /* Wait for Tx (and CRC) data to be sent */
+  if (SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_EOT, RESET, Timeout, tickstart) != HAL_OK)
+  {
+    SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG);
+  }
+
+  /* Call standard close procedure with error check */
+  SPI_CloseTransfer(hspi);
+
+  hspi->State = HAL_SPI_STATE_READY;
+
+  /* Unlock the process */
+  __HAL_UNLOCK(hspi);
+
+  if (hspi->ErrorCode != HAL_SPI_ERROR_NONE)
+  {
+    return HAL_ERROR;
+  }
+  else
+  {
+    return HAL_OK;
+  }
+}
+
+/**
+  * @brief  Receive an amount of data in blocking mode.
+  * @param  hspi   : pointer to a SPI_HandleTypeDef structure that contains
+  *                  the configuration information for SPI module.
+  * @param  pData  : pointer to data buffer
+  * @param  Size   : amount of data to be received
+  * @param  Timeout: Timeout duration
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_SPI_Receive(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout)
+{
+  uint32_t tickstart;
+  uint32_t temp_sr_reg;
+  uint16_t init_max_data_in_fifo;
+  init_max_data_in_fifo = (((uint16_t)(hspi->Init.FifoThreshold >> 5U) + 1U));
+#if defined (__GNUC__)
+  __IO uint16_t *prxdr_16bits = (__IO uint16_t *)(&(hspi->Instance->RXDR));
+#endif /* __GNUC__ */
+
+  /* Check Direction parameter */
+  assert_param(IS_SPI_DIRECTION_2LINES_OR_1LINE_2LINES_RXONLY(hspi->Init.Direction));
+
+  /* Init tickstart for timeout management*/
+  tickstart = HAL_GetTick();
+
+  if (hspi->State != HAL_SPI_STATE_READY)
+  {
+    return HAL_BUSY;
+  }
+
+  if ((pData == NULL) || (Size == 0UL))
+  {
+    return HAL_ERROR;
+  }
+
+  /* Lock the process */
+  __HAL_LOCK(hspi);
+
+  /* Set the transaction information */
+  hspi->State       = HAL_SPI_STATE_BUSY_RX;
+  hspi->ErrorCode   = HAL_SPI_ERROR_NONE;
+  hspi->pRxBuffPtr  = (uint8_t *)pData;
+  hspi->RxXferSize  = Size;
+  hspi->RxXferCount = Size;
+
+  /*Init field not used in handle to zero */
+  hspi->pTxBuffPtr  = NULL;
+  hspi->TxXferSize  = (uint16_t) 0UL;
+  hspi->TxXferCount = (uint16_t) 0UL;
+  hspi->RxISR       = NULL;
+  hspi->TxISR       = NULL;
+
+  /* Configure communication direction: 1Line */
+  if (hspi->Init.Direction == SPI_DIRECTION_1LINE)
+  {
+    SPI_1LINE_RX(hspi);
+  }
+  else
+  {
+    SPI_2LINES_RX(hspi);
+  }
+
+  /* Set the number of data at current transfer */
+  MODIFY_REG(hspi->Instance->CR2, SPI_CR2_TSIZE, Size);
+
+  /* Enable SPI peripheral */
+  __HAL_SPI_ENABLE(hspi);
+
+  if (hspi->Init.Mode == SPI_MODE_MASTER)
+  {
+    /* Master transfer start */
+    SET_BIT(hspi->Instance->CR1, SPI_CR1_CSTART);
+  }
+
+  /* Receive data in 32 Bit mode */
+  if (hspi->Init.DataSize > SPI_DATASIZE_16BIT)
+  {
+    /* Transfer loop */
+    while (hspi->RxXferCount > 0UL)
+    {
+      /* Evaluate state of SR register */
+      temp_sr_reg = hspi->Instance->SR;
+
+      /* Check the RXP flag */
+      if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_RXP))
+      {
+        *((uint32_t *)hspi->pRxBuffPtr) = *((__IO uint32_t *)&hspi->Instance->RXDR);
+        hspi->pRxBuffPtr += sizeof(uint32_t);
+        hspi->RxXferCount--;
+      }
+      /* Check RXWNE flag if RXP cannot be reached */
+      else if ((hspi->RxXferCount < init_max_data_in_fifo) && ((temp_sr_reg & SPI_SR_RXWNE_Msk) != 0UL))
+      {
+        *((uint32_t *)hspi->pRxBuffPtr) = *((__IO uint32_t *)&hspi->Instance->RXDR);
+        hspi->pRxBuffPtr += sizeof(uint32_t);
+        hspi->RxXferCount--;
+      }
+      else
+      {
+        /* Timeout management */
+        if ((((HAL_GetTick() - tickstart) >=  Timeout) && (Timeout != HAL_MAX_DELAY)) || (Timeout == 0U))
+        {
+          /* Call standard close procedure with error check */
+          SPI_CloseTransfer(hspi);
+
+          SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_TIMEOUT);
+          hspi->State = HAL_SPI_STATE_READY;
+
+          /* Unlock the process */
+          __HAL_UNLOCK(hspi);
+
+          return HAL_TIMEOUT;
+        }
+      }
+    }
+  }
+  /* Receive data in 16 Bit mode */
+  else if (hspi->Init.DataSize > SPI_DATASIZE_8BIT)
+  {
+    /* Transfer loop */
+    while (hspi->RxXferCount > 0UL)
+    {
+      /* Evaluate state of SR register */
+      temp_sr_reg = hspi->Instance->SR;
+
+      /* Check the RXP flag */
+      if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_RXP))
+      {
+#if defined (__GNUC__)
+        *((uint16_t *)hspi->pRxBuffPtr) = *prxdr_16bits;
+#else
+        *((uint16_t *)hspi->pRxBuffPtr) = *((__IO uint16_t *)&hspi->Instance->RXDR);
+#endif /* __GNUC__ */
+        hspi->pRxBuffPtr += sizeof(uint16_t);
+        hspi->RxXferCount--;
+      }
+      /* Check RXWNE flag if RXP cannot be reached */
+      else if ((hspi->RxXferCount < init_max_data_in_fifo) && ((temp_sr_reg & SPI_SR_RXWNE_Msk) != 0UL))
+      {
+#if defined (__GNUC__)
+        *((uint16_t *)hspi->pRxBuffPtr) = *prxdr_16bits;
+#else
+        *((uint16_t *)hspi->pRxBuffPtr) = *((__IO uint16_t *)&hspi->Instance->RXDR);
+#endif /* __GNUC__ */
+        hspi->pRxBuffPtr += sizeof(uint16_t);
+#if defined (__GNUC__)
+        *((uint16_t *)hspi->pRxBuffPtr) = *prxdr_16bits;
+#else
+        *((uint16_t *)hspi->pRxBuffPtr) = *((__IO uint16_t *)&hspi->Instance->RXDR);
+#endif /* __GNUC__ */
+        hspi->pRxBuffPtr += sizeof(uint16_t);
+        hspi->RxXferCount -= (uint16_t)2UL;
+      }
+      /* Check RXPLVL flags when RXWNE cannot be reached */
+      else if ((hspi->RxXferCount == 1UL) && ((temp_sr_reg & SPI_SR_RXPLVL_0) != 0UL))
+      {
+#if defined (__GNUC__)
+        *((uint16_t *)hspi->pRxBuffPtr) = *prxdr_16bits;
+#else
+        *((uint16_t *)hspi->pRxBuffPtr) = *((__IO uint16_t *)&hspi->Instance->RXDR);
+#endif /* __GNUC__ */
+        hspi->pRxBuffPtr += sizeof(uint16_t);
+        hspi->RxXferCount--;
+      }
+      else
+      {
+        /* Timeout management */
+        if ((((HAL_GetTick() - tickstart) >=  Timeout) && (Timeout != HAL_MAX_DELAY)) || (Timeout == 0U))
+        {
+          /* Call standard close procedure with error check */
+          SPI_CloseTransfer(hspi);
+
+          SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_TIMEOUT);
+          hspi->State = HAL_SPI_STATE_READY;
+
+          /* Unlock the process */
+          __HAL_UNLOCK(hspi);
+
+          return HAL_TIMEOUT;
+        }
+      }
+    }
+  }
+  /* Receive data in 8 Bit mode */
+  else
+  {
+    /* Transfer loop */
+    while (hspi->RxXferCount > 0UL)
+    {
+      /* Evaluate state of SR register */
+      temp_sr_reg = hspi->Instance->SR;
+
+      /* Check the RXP flag */
+      if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_RXP))
+      {
+        *((uint8_t *)hspi->pRxBuffPtr) = *((__IO uint8_t *)&hspi->Instance->RXDR);
+        hspi->pRxBuffPtr += sizeof(uint8_t);
+        hspi->RxXferCount--;
+      }
+      /* Check RXWNE flag if RXP cannot be reached */
+      else if ((hspi->RxXferCount < init_max_data_in_fifo) && ((temp_sr_reg & SPI_SR_RXWNE_Msk) != 0UL))
+      {
+        *((uint8_t *)hspi->pRxBuffPtr) = *((__IO uint8_t *)&hspi->Instance->RXDR);
+        hspi->pRxBuffPtr += sizeof(uint8_t);
+        *((uint8_t *)hspi->pRxBuffPtr) = *((__IO uint8_t *)&hspi->Instance->RXDR);
+        hspi->pRxBuffPtr += sizeof(uint8_t);
+        *((uint8_t *)hspi->pRxBuffPtr) = *((__IO uint8_t *)&hspi->Instance->RXDR);
+        hspi->pRxBuffPtr += sizeof(uint8_t);
+        *((uint8_t *)hspi->pRxBuffPtr) = *((__IO uint8_t *)&hspi->Instance->RXDR);
+        hspi->pRxBuffPtr += sizeof(uint8_t);
+        hspi->RxXferCount -= (uint16_t)4UL;
+      }
+      /* Check RXPLVL flags when RXWNE cannot be reached */
+      else if ((hspi->RxXferCount < 4UL) && ((temp_sr_reg & SPI_SR_RXPLVL_Msk) != 0UL))
+      {
+        *((uint8_t *)hspi->pRxBuffPtr) = *((__IO uint8_t *)&hspi->Instance->RXDR);
+        hspi->pRxBuffPtr += sizeof(uint8_t);
+        hspi->RxXferCount--;
+      }
+      else
+      {
+        /* Timeout management */
+        if ((((HAL_GetTick() - tickstart) >=  Timeout) && (Timeout != HAL_MAX_DELAY)) || (Timeout == 0U))
+        {
+          /* Call standard close procedure with error check */
+          SPI_CloseTransfer(hspi);
+
+          SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_TIMEOUT);
+          hspi->State = HAL_SPI_STATE_READY;
+
+          /* Unlock the process */
+          __HAL_UNLOCK(hspi);
+
+          return HAL_TIMEOUT;
+        }
+      }
+    }
+  }
+
+#if (USE_SPI_CRC != 0UL)
+  if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
+  {
+    /* Wait for crc data to be received */
+    if (SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_EOT, RESET, Timeout, tickstart) != HAL_OK)
+    {
+      SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG);
+    }
+  }
+#endif /* USE_SPI_CRC */
+
+  /* Call standard close procedure with error check */
+  SPI_CloseTransfer(hspi);
+
+  hspi->State = HAL_SPI_STATE_READY;
+
+  /* Unlock the process */
+  __HAL_UNLOCK(hspi);
+
+
+  if (hspi->ErrorCode != HAL_SPI_ERROR_NONE)
+  {
+    return HAL_ERROR;
+  }
+  else
+  {
+    return HAL_OK;
+  }
+}
+
+/**
+  * @brief  Transmit and Receive an amount of data in blocking mode.
+  * @param  hspi   : pointer to a SPI_HandleTypeDef structure that contains
+  *                  the configuration information for SPI module.
+  * @param  pTxData: pointer to transmission data buffer
+  * @param  pRxData: pointer to reception data buffer
+  * @param  Size   : amount of data to be sent and received
+  * @param  Timeout: Timeout duration
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_SPI_TransmitReceive(SPI_HandleTypeDef *hspi, const uint8_t *pTxData, uint8_t *pRxData,
+                                          uint16_t Size, uint32_t Timeout)
+{
+#if defined (__GNUC__)
+  __IO uint16_t *ptxdr_16bits = (__IO uint16_t *)(&(hspi->Instance->TXDR));
+  __IO uint16_t *prxdr_16bits = (__IO uint16_t *)(&(hspi->Instance->RXDR));
+#endif /* __GNUC__ */
+
+  uint32_t   tickstart;
+  uint32_t   fifo_length;
+  uint32_t   temp_sr_reg;
+  uint16_t   initial_TxXferCount;
+  uint16_t   initial_RxXferCount;
+  uint16_t   init_max_data_in_fifo;
+  init_max_data_in_fifo = (((uint16_t)(hspi->Init.FifoThreshold >> 5U) + 1U));
+
+  /* Check Direction parameter */
+  assert_param(IS_SPI_DIRECTION_2LINES(hspi->Init.Direction));
+
+  /* Init tickstart for timeout management*/
+  tickstart = HAL_GetTick();
+
+  initial_TxXferCount = Size;
+  initial_RxXferCount = Size;
+
+  if (hspi->State != HAL_SPI_STATE_READY)
+  {
+    return HAL_BUSY;
+  }
+
+  if ((pTxData == NULL) || (pRxData == NULL) || (Size == 0UL))
+  {
+    return HAL_ERROR;
+  }
+
+  /* Lock the process */
+  __HAL_LOCK(hspi);
+
+  /* Set the transaction information */
+  hspi->State       = HAL_SPI_STATE_BUSY_TX_RX;
+  hspi->ErrorCode   = HAL_SPI_ERROR_NONE;
+  hspi->pRxBuffPtr  = (uint8_t *)pRxData;
+  hspi->RxXferCount = Size;
+  hspi->RxXferSize  = Size;
+  hspi->pTxBuffPtr  = (const uint8_t *)pTxData;
+  hspi->TxXferCount = Size;
+  hspi->TxXferSize  = Size;
+
+  /*Init field not used in handle to zero */
+  hspi->RxISR       = NULL;
+  hspi->TxISR       = NULL;
+
+  /* Set Full-Duplex mode */
+  SPI_2LINES(hspi);
+
+  /* Initialize FIFO length */
+  if (IS_SPI_HIGHEND_INSTANCE(hspi->Instance))
+  {
+    fifo_length = SPI_HIGHEND_FIFO_SIZE;
+  }
+  else
+  {
+    fifo_length = SPI_LOWEND_FIFO_SIZE;
+  }
+
+  /* Set the number of data at current transfer */
+  MODIFY_REG(hspi->Instance->CR2, SPI_CR2_TSIZE, Size);
+
+  __HAL_SPI_ENABLE(hspi);
+
+  if (hspi->Init.Mode == SPI_MODE_MASTER)
+  {
+    /* Master transfer start */
+    SET_BIT(hspi->Instance->CR1, SPI_CR1_CSTART);
+  }
+
+  /* Transmit and Receive data in 32 Bit mode */
+  if (hspi->Init.DataSize > SPI_DATASIZE_16BIT)
+  {
+    /* Adapt fifo length to 32bits data width */
+    fifo_length = (fifo_length / 4UL);
+
+    while ((initial_TxXferCount > 0UL) || (initial_RxXferCount > 0UL))
+    {
+      /* Check TXP flag */
+      if ((__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXP)) && (initial_TxXferCount > 0UL) &&
+          (initial_RxXferCount  < (initial_TxXferCount + fifo_length)))
+      {
+        *((__IO uint32_t *)&hspi->Instance->TXDR) = *((const uint32_t *)hspi->pTxBuffPtr);
+        hspi->pTxBuffPtr += sizeof(uint32_t);
+        hspi->TxXferCount --;
+        initial_TxXferCount = hspi->TxXferCount;
+      }
+
+      /* Evaluate state of SR register */
+      temp_sr_reg = hspi->Instance->SR;
+
+      if (initial_RxXferCount > 0UL)
+      {
+        /* Check the RXP flag */
+        if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_RXP))
+        {
+          *((uint32_t *)hspi->pRxBuffPtr) = *((__IO uint32_t *)&hspi->Instance->RXDR);
+          hspi->pRxBuffPtr += sizeof(uint32_t);
+          hspi->RxXferCount--;
+          initial_RxXferCount = hspi->RxXferCount;
+        }
+        /* Check RXWNE flag if RXP cannot be reached */
+        else if ((initial_RxXferCount < init_max_data_in_fifo) && ((temp_sr_reg & SPI_SR_RXWNE_Msk) != 0UL))
+        {
+          *((uint32_t *)hspi->pRxBuffPtr) = *((__IO uint32_t *)&hspi->Instance->RXDR);
+          hspi->pRxBuffPtr += sizeof(uint32_t);
+          hspi->RxXferCount--;
+          initial_RxXferCount = hspi->RxXferCount;
+        }
+        else
+        {
+          /* Timeout management */
+          if ((((HAL_GetTick() - tickstart) >=  Timeout) && (Timeout != HAL_MAX_DELAY)) || (Timeout == 0U))
+          {
+            /* Call standard close procedure with error check */
+            SPI_CloseTransfer(hspi);
+
+            SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_TIMEOUT);
+            hspi->State = HAL_SPI_STATE_READY;
+
+            /* Unlock the process */
+            __HAL_UNLOCK(hspi);
+
+            return HAL_TIMEOUT;
+          }
+        }
+      }
+    }
+  }
+  /* Transmit and Receive data in 16 Bit mode */
+  else if (hspi->Init.DataSize > SPI_DATASIZE_8BIT)
+  {
+    /* Adapt fifo length to 16bits data width */
+    fifo_length = (fifo_length / 2UL);
+
+    while ((initial_TxXferCount > 0UL) || (initial_RxXferCount > 0UL))
+    {
+      /* Check the TXP flag */
+      if ((__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXP)) && (initial_TxXferCount > 0UL) &&
+          (initial_RxXferCount  < (initial_TxXferCount + fifo_length)))
+      {
+#if defined (__GNUC__)
+        *ptxdr_16bits = *((const uint16_t *)hspi->pTxBuffPtr);
+#else
+        *((__IO uint16_t *)&hspi->Instance->TXDR) = *((const uint16_t *)hspi->pTxBuffPtr);
+#endif /* __GNUC__ */
+        hspi->pTxBuffPtr += sizeof(uint16_t);
+        hspi->TxXferCount--;
+        initial_TxXferCount = hspi->TxXferCount;
+      }
+
+      /* Evaluate state of SR register */
+      temp_sr_reg = hspi->Instance->SR;
+
+      if (initial_RxXferCount > 0UL)
+      {
+        /* Check the RXP flag */
+        if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_RXP))
+        {
+#if defined (__GNUC__)
+          *((uint16_t *)hspi->pRxBuffPtr) = *prxdr_16bits;
+#else
+          *((uint16_t *)hspi->pRxBuffPtr) = *((__IO uint16_t *)&hspi->Instance->RXDR);
+#endif /* __GNUC__ */
+          hspi->pRxBuffPtr += sizeof(uint16_t);
+          hspi->RxXferCount--;
+          initial_RxXferCount = hspi->RxXferCount;
+        }
+        /* Check RXWNE flag if RXP cannot be reached */
+        else if ((initial_RxXferCount < init_max_data_in_fifo) && ((temp_sr_reg & SPI_SR_RXWNE_Msk) != 0UL))
+        {
+#if defined (__GNUC__)
+          *((uint16_t *)hspi->pRxBuffPtr) = *prxdr_16bits;
+#else
+          *((uint16_t *)hspi->pRxBuffPtr) = *((__IO uint16_t *)&hspi->Instance->RXDR);
+#endif /* __GNUC__ */
+          hspi->pRxBuffPtr += sizeof(uint16_t);
+#if defined (__GNUC__)
+          *((uint16_t *)hspi->pRxBuffPtr) = *prxdr_16bits;
+#else
+          *((uint16_t *)hspi->pRxBuffPtr) = *((__IO uint16_t *)&hspi->Instance->RXDR);
+#endif /* __GNUC__ */
+          hspi->pRxBuffPtr += sizeof(uint16_t);
+          hspi->RxXferCount -= (uint16_t)2UL;
+          initial_RxXferCount = hspi->RxXferCount;
+        }
+        /* Check RXPLVL flags when RXWNE cannot be reached */
+        else if ((initial_RxXferCount == 1UL) && ((temp_sr_reg & SPI_SR_RXPLVL_0) != 0UL))
+        {
+#if defined (__GNUC__)
+          *((uint16_t *)hspi->pRxBuffPtr) = *prxdr_16bits;
+#else
+          *((uint16_t *)hspi->pRxBuffPtr) = *((__IO uint16_t *)&hspi->Instance->RXDR);
+#endif /* __GNUC__ */
+          hspi->pRxBuffPtr += sizeof(uint16_t);
+          hspi->RxXferCount--;
+          initial_RxXferCount = hspi->RxXferCount;
+        }
+        else
+        {
+          /* Timeout management */
+          if ((((HAL_GetTick() - tickstart) >=  Timeout) && (Timeout != HAL_MAX_DELAY)) || (Timeout == 0U))
+          {
+            /* Call standard close procedure with error check */
+            SPI_CloseTransfer(hspi);
+
+            SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_TIMEOUT);
+            hspi->State = HAL_SPI_STATE_READY;
+
+            /* Unlock the process */
+            __HAL_UNLOCK(hspi);
+
+            return HAL_TIMEOUT;
+          }
+        }
+      }
+    }
+  }
+  /* Transmit and Receive data in 8 Bit mode */
+  else
+  {
+    while ((initial_TxXferCount > 0UL) || (initial_RxXferCount > 0UL))
+    {
+      /* Check the TXP flag */
+      if ((__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXP)) && (initial_TxXferCount > 0UL) &&
+          (initial_RxXferCount  < (initial_TxXferCount + fifo_length)))
+      {
+        *((__IO uint8_t *)&hspi->Instance->TXDR) = *((const uint8_t *)hspi->pTxBuffPtr);
+        hspi->pTxBuffPtr += sizeof(uint8_t);
+        hspi->TxXferCount--;
+        initial_TxXferCount = hspi->TxXferCount;
+      }
+
+      /* Evaluate state of SR register */
+      temp_sr_reg = hspi->Instance->SR;
+
+      if (initial_RxXferCount > 0UL)
+      {
+        /* Check the RXP flag */
+        if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_RXP))
+        {
+          *((uint8_t *)hspi->pRxBuffPtr) = *((__IO uint8_t *)&hspi->Instance->RXDR);
+          hspi->pRxBuffPtr += sizeof(uint8_t);
+          hspi->RxXferCount--;
+          initial_RxXferCount = hspi->RxXferCount;
+        }
+        /* Check RXWNE flag if RXP cannot be reached */
+        else if ((initial_RxXferCount < init_max_data_in_fifo) && ((temp_sr_reg & SPI_SR_RXWNE_Msk) != 0UL))
+        {
+          *((uint8_t *)hspi->pRxBuffPtr) = *((__IO uint8_t *)&hspi->Instance->RXDR);
+          hspi->pRxBuffPtr += sizeof(uint8_t);
+          *((uint8_t *)hspi->pRxBuffPtr) = *((__IO uint8_t *)&hspi->Instance->RXDR);
+          hspi->pRxBuffPtr += sizeof(uint8_t);
+          *((uint8_t *)hspi->pRxBuffPtr) = *((__IO uint8_t *)&hspi->Instance->RXDR);
+          hspi->pRxBuffPtr += sizeof(uint8_t);
+          *((uint8_t *)hspi->pRxBuffPtr) = *((__IO uint8_t *)&hspi->Instance->RXDR);
+          hspi->pRxBuffPtr += sizeof(uint8_t);
+          hspi->RxXferCount -= (uint16_t)4UL;
+          initial_RxXferCount = hspi->RxXferCount;
+        }
+        /* Check RXPLVL flags when RXWNE cannot be reached */
+        else if ((initial_RxXferCount < 4UL) && ((temp_sr_reg & SPI_SR_RXPLVL_Msk) != 0UL))
+        {
+          *((uint8_t *)hspi->pRxBuffPtr) = *((__IO uint8_t *)&hspi->Instance->RXDR);
+          hspi->pRxBuffPtr += sizeof(uint8_t);
+          hspi->RxXferCount--;
+          initial_RxXferCount = hspi->RxXferCount;
+        }
+        else
+        {
+          /* Timeout management */
+          if ((((HAL_GetTick() - tickstart) >=  Timeout) && (Timeout != HAL_MAX_DELAY)) || (Timeout == 0U))
+          {
+            /* Call standard close procedure with error check */
+            SPI_CloseTransfer(hspi);
+
+            SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_TIMEOUT);
+            hspi->State = HAL_SPI_STATE_READY;
+
+            /* Unlock the process */
+            __HAL_UNLOCK(hspi);
+
+            return HAL_TIMEOUT;
+          }
+        }
+      }
+    }
+  }
+
+  /* Wait for Tx/Rx (and CRC) data to be sent/received */
+  if (SPI_WaitOnFlagUntilTimeout(hspi, SPI_FLAG_EOT, RESET, Timeout, tickstart) != HAL_OK)
+  {
+    SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG);
+  }
+
+  /* Call standard close procedure with error check */
+  SPI_CloseTransfer(hspi);
+
+  hspi->State = HAL_SPI_STATE_READY;
+
+  /* Unlock the process */
+  __HAL_UNLOCK(hspi);
+
+  if (hspi->ErrorCode != HAL_SPI_ERROR_NONE)
+  {
+    return HAL_ERROR;
+  }
+  else
+  {
+    return HAL_OK;
+  }
+}
+
+/**
+  * @brief  Transmit an amount of data in non-blocking mode with Interrupt.
+  * @param  hspi : pointer to a SPI_HandleTypeDef structure that contains
+  *                the configuration information for SPI module.
+  * @param  pData: pointer to data buffer
+  * @param  Size : amount of data to be sent
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_SPI_Transmit_IT(SPI_HandleTypeDef *hspi, const uint8_t *pData, uint16_t Size)
+{
+  /* Check Direction parameter */
+  assert_param(IS_SPI_DIRECTION_2LINES_OR_1LINE_2LINES_TXONLY(hspi->Init.Direction));
+
+  if ((pData == NULL) || (Size == 0UL))
+  {
+    return HAL_ERROR;
+  }
+
+  if (hspi->State != HAL_SPI_STATE_READY)
+  {
+    return HAL_BUSY;
+  }
+
+  /* Lock the process */
+  __HAL_LOCK(hspi);
+
+  /* Set the transaction information */
+  hspi->State       = HAL_SPI_STATE_BUSY_TX;
+  hspi->ErrorCode   = HAL_SPI_ERROR_NONE;
+  hspi->pTxBuffPtr  = (const uint8_t *)pData;
+  hspi->TxXferSize  = Size;
+  hspi->TxXferCount = Size;
+
+  /* Init field not used in handle to zero */
+  hspi->pRxBuffPtr  = NULL;
+  hspi->RxXferSize  = (uint16_t) 0UL;
+  hspi->RxXferCount = (uint16_t) 0UL;
+  hspi->RxISR       = NULL;
+
+#if defined(USE_SPI_RELOAD_TRANSFER)
+  hspi->Reload.Requested   = 0UL;
+  hspi->Reload.pTxBuffPtr  = NULL;
+  hspi->Reload.TxXferSize  = NULL;
+#endif /* USE_SPI_RELOAD_TRANSFER */
+
+  /* Set the function for IT treatment */
+  if (hspi->Init.DataSize > SPI_DATASIZE_16BIT)
+  {
+    hspi->TxISR = SPI_TxISR_32BIT;
+  }
+  else if (hspi->Init.DataSize > SPI_DATASIZE_8BIT)
+  {
+    hspi->TxISR = SPI_TxISR_16BIT;
+  }
+  else
+  {
+    hspi->TxISR = SPI_TxISR_8BIT;
+  }
+
+  /* Configure communication direction : 1Line */
+  if (hspi->Init.Direction == SPI_DIRECTION_1LINE)
+  {
+    SPI_1LINE_TX(hspi);
+  }
+  else
+  {
+    SPI_2LINES_TX(hspi);
+  }
+
+  /* Set the number of data at current transfer */
+  MODIFY_REG(hspi->Instance->CR2, SPI_CR2_TSIZE, Size);
+
+  /* Enable SPI peripheral */
+  __HAL_SPI_ENABLE(hspi);
+
+  /* Unlock the process */
+  __HAL_UNLOCK(hspi);
+
+  /* Enable EOT, TXP, FRE, MODF, UDR and TSERF interrupts */
+  __HAL_SPI_ENABLE_IT(hspi, (SPI_IT_EOT | SPI_IT_TXP | SPI_IT_UDR | SPI_IT_FRE | SPI_IT_MODF | SPI_IT_TSERF));
+
+  if (hspi->Init.Mode == SPI_MODE_MASTER)
+  {
+    /* Master transfer start */
+    SET_BIT(hspi->Instance->CR1, SPI_CR1_CSTART);
+  }
+
+  return HAL_OK;
+}
+
+/**
+  * @brief  Receive an amount of data in non-blocking mode with Interrupt.
+  * @param  hspi : pointer to a SPI_HandleTypeDef structure that contains
+  *                the configuration information for SPI module.
+  * @param  pData: pointer to data buffer
+  * @param  Size : amount of data to be sent
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_SPI_Receive_IT(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size)
+{
+  /* Check Direction parameter */
+  assert_param(IS_SPI_DIRECTION_2LINES_OR_1LINE_2LINES_RXONLY(hspi->Init.Direction));
+
+  if (hspi->State != HAL_SPI_STATE_READY)
+  {
+    return HAL_BUSY;
+  }
+
+  if ((pData == NULL) || (Size == 0UL))
+  {
+    return HAL_ERROR;
+  }
+
+  /* Lock the process */
+  __HAL_LOCK(hspi);
+
+  /* Set the transaction information */
+  hspi->State       = HAL_SPI_STATE_BUSY_RX;
+  hspi->ErrorCode   = HAL_SPI_ERROR_NONE;
+  hspi->pRxBuffPtr  = (uint8_t *)pData;
+  hspi->RxXferSize  = Size;
+  hspi->RxXferCount = Size;
+
+  /* Init field not used in handle to zero */
+  hspi->pTxBuffPtr  = NULL;
+  hspi->TxXferSize  = (uint16_t) 0UL;
+  hspi->TxXferCount = (uint16_t) 0UL;
+  hspi->TxISR       = NULL;
+
+#if defined(USE_SPI_RELOAD_TRANSFER)
+  hspi->Reload.Requested   = 0UL;
+  hspi->Reload.pRxBuffPtr  = NULL;
+  hspi->Reload.RxXferSize  = NULL;
+#endif /* USE_SPI_RELOAD_TRANSFER */
+
+  /* Set the function for IT treatment */
+  if (hspi->Init.DataSize > SPI_DATASIZE_16BIT)
+  {
+    hspi->RxISR = SPI_RxISR_32BIT;
+  }
+  else if (hspi->Init.DataSize > SPI_DATASIZE_8BIT)
+  {
+    hspi->RxISR = SPI_RxISR_16BIT;
+  }
+  else
+  {
+    hspi->RxISR = SPI_RxISR_8BIT;
+  }
+
+  /* Configure communication direction : 1Line */
+  if (hspi->Init.Direction == SPI_DIRECTION_1LINE)
+  {
+    SPI_1LINE_RX(hspi);
+  }
+  else
+  {
+    SPI_2LINES_RX(hspi);
+  }
+
+  /* Note : The SPI must be enabled after unlocking current process
+            to avoid the risk of SPI interrupt handle execution before current
+            process unlock */
+
+  /* Set the number of data at current transfer */
+  MODIFY_REG(hspi->Instance->CR2, SPI_CR2_TSIZE, Size);
+
+  /* Enable SPI peripheral */
+  __HAL_SPI_ENABLE(hspi);
+
+  /* Unlock the process */
+  __HAL_UNLOCK(hspi);
+
+  /* Enable EOT, RXP, OVR, FRE, MODF and TSERF interrupts */
+  __HAL_SPI_ENABLE_IT(hspi, (SPI_IT_EOT | SPI_IT_RXP | SPI_IT_OVR | SPI_IT_FRE | SPI_IT_MODF | SPI_IT_TSERF));
+
+  if (hspi->Init.Mode == SPI_MODE_MASTER)
+  {
+    /* Master transfer start */
+    SET_BIT(hspi->Instance->CR1, SPI_CR1_CSTART);
+  }
+
+  return HAL_OK;
+}
+
+/**
+  * @brief  Transmit and Receive an amount of data in non-blocking mode with Interrupt.
+  * @param  hspi   : pointer to a SPI_HandleTypeDef structure that contains
+  *                  the configuration information for SPI module.
+  * @param  pTxData: pointer to transmission data buffer
+  * @param  pRxData: pointer to reception data buffer
+  * @param  Size   : amount of data to be sent and received
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_SPI_TransmitReceive_IT(SPI_HandleTypeDef *hspi, const uint8_t *pTxData, uint8_t *pRxData,
+                                             uint16_t Size)
+{
+  uint32_t tmp_TxXferCount;
+#if defined (__GNUC__)
+  __IO uint16_t *ptxdr_16bits = (__IO uint16_t *)(&(hspi->Instance->TXDR));
+#endif /* __GNUC__ */
+
+  /* Check Direction parameter */
+  assert_param(IS_SPI_DIRECTION_2LINES(hspi->Init.Direction));
+
+  if (hspi->State != HAL_SPI_STATE_READY)
+  {
+    return HAL_BUSY;
+  }
+
+  if ((pTxData == NULL) || (pRxData == NULL) || (Size == 0UL))
+  {
+    return HAL_ERROR;
+  }
+
+  /* Lock the process */
+  __HAL_LOCK(hspi);
+
+  /* Set the transaction information */
+  hspi->State       = HAL_SPI_STATE_BUSY_TX_RX;
+  hspi->ErrorCode   = HAL_SPI_ERROR_NONE;
+  hspi->pTxBuffPtr  = (const uint8_t *)pTxData;
+  hspi->TxXferSize  = Size;
+  hspi->TxXferCount = Size;
+  hspi->pRxBuffPtr  = (uint8_t *)pRxData;
+  hspi->RxXferSize  = Size;
+  hspi->RxXferCount = Size;
+  tmp_TxXferCount   = hspi->TxXferCount;
+
+#if defined(USE_SPI_RELOAD_TRANSFER)
+  hspi->Reload.Requested   = 0UL;
+  hspi->Reload.pRxBuffPtr  = NULL;
+  hspi->Reload.RxXferSize  = NULL;
+  hspi->Reload.pTxBuffPtr  = NULL;
+  hspi->Reload.TxXferSize  = NULL;
+#endif /* USE_SPI_RELOAD_TRANSFER */
+
+  /* Set the function for IT treatment */
+  if (hspi->Init.DataSize > SPI_DATASIZE_16BIT)
+  {
+    hspi->TxISR     = SPI_TxISR_32BIT;
+    hspi->RxISR     = SPI_RxISR_32BIT;
+  }
+  else if (hspi->Init.DataSize > SPI_DATASIZE_8BIT)
+  {
+    hspi->RxISR     = SPI_RxISR_16BIT;
+    hspi->TxISR     = SPI_TxISR_16BIT;
+  }
+  else
+  {
+    hspi->RxISR     = SPI_RxISR_8BIT;
+    hspi->TxISR     = SPI_TxISR_8BIT;
+  }
+
+  /* Set Full-Duplex mode */
+  SPI_2LINES(hspi);
+
+  /* Set the number of data at current transfer */
+  MODIFY_REG(hspi->Instance->CR2, SPI_CR2_TSIZE, Size);
+
+  /* Enable SPI peripheral */
+  __HAL_SPI_ENABLE(hspi);
+
+  /* Fill in the TxFIFO */
+  while ((__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXP)) && (tmp_TxXferCount != 0UL))
+  {
+    /* Transmit data in 32 Bit mode */
+    if (hspi->Init.DataSize > SPI_DATASIZE_16BIT)
+    {
+      *((__IO uint32_t *)&hspi->Instance->TXDR) = *((const uint32_t *)hspi->pTxBuffPtr);
+      hspi->pTxBuffPtr += sizeof(uint32_t);
+      hspi->TxXferCount--;
+      tmp_TxXferCount = hspi->TxXferCount;
+    }
+    /* Transmit data in 16 Bit mode */
+    else if (hspi->Init.DataSize > SPI_DATASIZE_8BIT)
+    {
+#if defined (__GNUC__)
+      *ptxdr_16bits = *((const uint16_t *)hspi->pTxBuffPtr);
+#else
+      *((__IO uint16_t *)&hspi->Instance->TXDR) = *((const uint16_t *)hspi->pTxBuffPtr);
+#endif /* __GNUC__ */
+      hspi->pTxBuffPtr += sizeof(uint16_t);
+      hspi->TxXferCount--;
+      tmp_TxXferCount = hspi->TxXferCount;
+    }
+    /* Transmit data in 8 Bit mode */
+    else
+    {
+      *((__IO uint8_t *)&hspi->Instance->TXDR) = *((const uint8_t *)hspi->pTxBuffPtr);
+      hspi->pTxBuffPtr += sizeof(uint8_t);
+      hspi->TxXferCount--;
+      tmp_TxXferCount = hspi->TxXferCount;
+    }
+  }
+
+  /* Unlock the process */
+  __HAL_UNLOCK(hspi);
+
+  /* Enable EOT, DXP, UDR, OVR, FRE, MODF and TSERF interrupts */
+  __HAL_SPI_ENABLE_IT(hspi, (SPI_IT_EOT | SPI_IT_DXP | SPI_IT_UDR | SPI_IT_OVR |
+                             SPI_IT_FRE | SPI_IT_MODF | SPI_IT_TSERF));
+
+  if (hspi->Init.Mode == SPI_MODE_MASTER)
+  {
+    /* Start Master transfer */
+    SET_BIT(hspi->Instance->CR1, SPI_CR1_CSTART);
+  }
+
+  return HAL_OK;
+}
+
+#if defined(USE_SPI_RELOAD_TRANSFER)
+/**
+  * @brief  Transmit an additional amount of data in blocking mode.
+  * @param  hspi : pointer to a SPI_HandleTypeDef structure that contains
+  *                the configuration information for SPI module.
+  * @param  pData: pointer to data buffer
+  * @param  Size : amount of data to be sent
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_SPI_Reload_Transmit_IT(SPI_HandleTypeDef *hspi, const uint8_t *pData, uint16_t Size)
+{
+  /* check if there is already a request to reload */
+  if ((hspi->Reload.Requested == 1UL) || (pData == NULL) || (Size == 0UL))
+  {
+    return HAL_ERROR;
+  }
+
+  if (hspi->State == HAL_SPI_STATE_BUSY_TX)
+  {
+    /* Lock the process */
+    __HAL_LOCK(hspi);
+
+    /* Insert the new number of data to be sent just after the current one */
+    MODIFY_REG(hspi->Instance->CR2, SPI_CR2_TSER, (Size & 0xFFFFFFFFUL) << 16UL);
+
+    /* Set the transaction information */
+    hspi->Reload.Requested   = 1UL;
+    hspi->Reload.pTxBuffPtr  = (const uint8_t *)pData;
+    hspi->Reload.TxXferSize  = Size;
+
+    /* Unlock the process */
+    __HAL_UNLOCK(hspi);
+
+    return HAL_OK;
+  }
+  else
+  {
+    return HAL_ERROR;
+  }
+}
+#endif /* USE_SPI_RELOAD_TRANSFER */
+
+#if defined(USE_SPI_RELOAD_TRANSFER)
+/**
+  * @brief  Receive an additional amount of data in blocking mode.
+  * @param  hspi : pointer to a SPI_HandleTypeDef structure that contains
+  *                the configuration information for SPI module.
+  * @param  pData: pointer to data buffer
+  * @param  Size : amount of data to be sent
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_SPI_Reload_Receive_IT(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size)
+{
+  /* check if there is already a request to reload */
+  if ((hspi->Reload.Requested == 1UL) || (pData == NULL) || (Size == 0UL))
+  {
+    return HAL_ERROR;
+  }
+
+  if (hspi->State == HAL_SPI_STATE_BUSY_RX)
+  {
+    /* Lock the process */
+    __HAL_LOCK(hspi);
+
+    /* Insert the new number of data that will be received just after the current one */
+    MODIFY_REG(hspi->Instance->CR2, SPI_CR2_TSER, (Size & 0xFFFFFFFFUL) << 16UL);
+
+    /* Set the transaction information */
+    hspi->Reload.Requested   = 1UL;
+    hspi->Reload.pRxBuffPtr  = (uint8_t *)pData;
+    hspi->Reload.RxXferSize  = Size;
+
+    /* Unlock the process */
+    __HAL_UNLOCK(hspi);
+
+    return HAL_OK;
+  }
+  else
+  {
+    return HAL_ERROR;
+  }
+}
+#endif /* USE_SPI_RELOAD_TRANSFER */
+
+#if defined(USE_SPI_RELOAD_TRANSFER)
+/**
+  * @brief  Transmit and receive an additional amount of data in blocking mode.
+  * @param  hspi   : pointer to a SPI_HandleTypeDef structure that contains
+  *                  the configuration information for SPI module.
+  * @param  pTxData: pointer to transmission data buffer
+  * @param  pRxData: pointer to reception data buffer
+  * @param  Size   : amount of data to be sent and received
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_SPI_Reload_TransmitReceive_IT(SPI_HandleTypeDef *hspi, const uint8_t *pTxData,
+                                                    uint8_t *pRxData, uint16_t Size)
+{
+  /* check if there is already a request to reload */
+  if ((hspi->Reload.Requested == 1UL) || (pTxData == NULL) || (pRxData == NULL) || (Size == 0UL))
+  {
+    return HAL_ERROR;
+  }
+
+  if (hspi->State == HAL_SPI_STATE_BUSY_TX_RX)
+  {
+    /* Lock the process */
+    __HAL_LOCK(hspi);
+
+    /* Insert the new number of data that will be sent and received just after the current one */
+    MODIFY_REG(hspi->Instance->CR2, SPI_CR2_TSER, (Size & 0xFFFFFFFFUL) << 16UL);
+
+    /* Set the transaction information */
+    hspi->Reload.Requested   = 1UL;
+    hspi->Reload.pTxBuffPtr  = (const uint8_t *)pTxData;
+    hspi->Reload.TxXferSize  = Size;
+    hspi->Reload.pRxBuffPtr  = (uint8_t *)pRxData;
+    hspi->Reload.RxXferSize  = Size;
+
+    /* Unlock the process */
+    __HAL_UNLOCK(hspi);
+
+    return HAL_OK;
+  }
+  else
+  {
+    return HAL_ERROR;
+  }
+}
+#endif /* USE_SPI_RELOAD_TRANSFER */
+
+/**
+  * @brief  Transmit an amount of data in non-blocking mode with DMA.
+  * @param  hspi : pointer to a SPI_HandleTypeDef structure that contains
+  *                the configuration information for SPI module.
+  * @param  pData: pointer to data buffer
+  * @param  Size : amount of data to be sent
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_SPI_Transmit_DMA(SPI_HandleTypeDef *hspi, const uint8_t *pData, uint16_t Size)
+{
+
+  /* Check Direction parameter */
+  assert_param(IS_SPI_DIRECTION_2LINES_OR_1LINE_2LINES_TXONLY(hspi->Init.Direction));
+
+  if (hspi->State != HAL_SPI_STATE_READY)
+  {
+    return HAL_BUSY;
+  }
+
+  if ((pData == NULL) || (Size == 0UL))
+  {
+    return HAL_ERROR;
+  }
+
+  /* Lock the process */
+  __HAL_LOCK(hspi);
+
+  /* Set the transaction information */
+  hspi->State       = HAL_SPI_STATE_BUSY_TX;
+  hspi->ErrorCode   = HAL_SPI_ERROR_NONE;
+  hspi->pTxBuffPtr  = (const uint8_t *)pData;
+  hspi->TxXferSize  = Size;
+  hspi->TxXferCount = Size;
+
+  /* Init field not used in handle to zero */
+  hspi->pRxBuffPtr  = NULL;
+  hspi->TxISR       = NULL;
+  hspi->RxISR       = NULL;
+  hspi->RxXferSize  = (uint16_t)0UL;
+  hspi->RxXferCount = (uint16_t)0UL;
+
+  /* Configure communication direction : 1Line */
+  if (hspi->Init.Direction == SPI_DIRECTION_1LINE)
+  {
+    SPI_1LINE_TX(hspi);
+  }
+  else
+  {
+    SPI_2LINES_TX(hspi);
+  }
+
+  /* Packing mode management is enabled by the DMA settings */
+  if (((hspi->Init.DataSize > SPI_DATASIZE_16BIT) && (hspi->hdmatx->Init.MemDataAlignment != DMA_MDATAALIGN_WORD))    || \
+      ((hspi->Init.DataSize > SPI_DATASIZE_8BIT) && ((hspi->hdmatx->Init.MemDataAlignment != DMA_MDATAALIGN_HALFWORD) && \
+                                                     (hspi->hdmatx->Init.MemDataAlignment != DMA_MDATAALIGN_WORD))))
+  {
+    /* Restriction the DMA data received is not allowed in this mode */
+    __HAL_UNLOCK(hspi);
+    return HAL_ERROR;
+  }
+
+  /* Adjust XferCount according to DMA alignment / Data size */
+  if (hspi->Init.DataSize <= SPI_DATASIZE_8BIT)
+  {
+    if (hspi->hdmatx->Init.MemDataAlignment == DMA_MDATAALIGN_HALFWORD)
+    {
+      hspi->TxXferCount = (hspi->TxXferCount + (uint16_t) 1UL) >> 1UL;
+    }
+    if (hspi->hdmatx->Init.MemDataAlignment == DMA_MDATAALIGN_WORD)
+    {
+      hspi->TxXferCount = (hspi->TxXferCount + (uint16_t) 3UL) >> 2UL;
+    }
+  }
+  else if (hspi->Init.DataSize <= SPI_DATASIZE_16BIT)
+  {
+    if (hspi->hdmatx->Init.MemDataAlignment == DMA_MDATAALIGN_WORD)
+    {
+      hspi->TxXferCount = (hspi->TxXferCount + (uint16_t) 1UL) >> 1UL;
+    }
+  }
+  else
+  {
+    /* Adjustment done */
+  }
+
+  /* Set the SPI TxDMA Half transfer complete callback */
+  hspi->hdmatx->XferHalfCpltCallback = SPI_DMAHalfTransmitCplt;
+
+  /* Set the SPI TxDMA transfer complete callback */
+  hspi->hdmatx->XferCpltCallback = SPI_DMATransmitCplt;
+
+  /* Set the DMA error callback */
+  hspi->hdmatx->XferErrorCallback = SPI_DMAError;
+
+  /* Set the DMA AbortCpltCallback */
+  hspi->hdmatx->XferAbortCallback = NULL;
+
+  /* Clear TXDMAEN bit*/
+  CLEAR_BIT(hspi->Instance->CFG1, SPI_CFG1_TXDMAEN);
+
+  /* Enable the Tx DMA Stream/Channel */
+  if (HAL_OK != HAL_DMA_Start_IT(hspi->hdmatx, (uint32_t)hspi->pTxBuffPtr, (uint32_t)&hspi->Instance->TXDR,
+                                 hspi->TxXferCount))
+  {
+    /* Update SPI error code */
+    SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_DMA);
+    hspi->State = HAL_SPI_STATE_READY;
+
+    /* Unlock the process */
+    __HAL_UNLOCK(hspi);
+
+    return HAL_ERROR;
+  }
+
+  /* Set the number of data at current transfer */
+  if (hspi->hdmatx->Init.Mode == DMA_CIRCULAR)
+  {
+    MODIFY_REG(hspi->Instance->CR2, SPI_CR2_TSIZE, 0UL);
+  }
+  else
+  {
+    MODIFY_REG(hspi->Instance->CR2, SPI_CR2_TSIZE, Size);
+  }
+
+  /* Enable Tx DMA Request */
+  SET_BIT(hspi->Instance->CFG1, SPI_CFG1_TXDMAEN);
+
+  /* Enable the SPI Error Interrupt Bit */
+  __HAL_SPI_ENABLE_IT(hspi, (SPI_IT_UDR | SPI_IT_FRE | SPI_IT_MODF));
+
+  /* Enable SPI peripheral */
+  __HAL_SPI_ENABLE(hspi);
+
+  if (hspi->Init.Mode == SPI_MODE_MASTER)
+  {
+    /* Master transfer start */
+    SET_BIT(hspi->Instance->CR1, SPI_CR1_CSTART);
+  }
+
+  /* Unlock the process */
+  __HAL_UNLOCK(hspi);
+
+  return HAL_OK;
+}
+
+/**
+  * @brief  Receive an amount of data in non-blocking mode with DMA.
+  * @param  hspi : pointer to a SPI_HandleTypeDef structure that contains
+  *                the configuration information for SPI module.
+  * @param  pData: pointer to data buffer
+  * @param  Size : amount of data to be sent
+  * @note   When the CRC feature is enabled the pData Length must be Size + 1.
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_SPI_Receive_DMA(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size)
+{
+
+  /* Check Direction parameter */
+  assert_param(IS_SPI_DIRECTION_2LINES_OR_1LINE_2LINES_RXONLY(hspi->Init.Direction));
+
+  if (hspi->State != HAL_SPI_STATE_READY)
+  {
+    __HAL_UNLOCK(hspi);
+    return HAL_BUSY;
+  }
+
+  if ((pData == NULL) || (Size == 0UL))
+  {
+    __HAL_UNLOCK(hspi);
+    return HAL_ERROR;
+  }
+
+  /* Lock the process */
+  __HAL_LOCK(hspi);
+
+  /* Set the transaction information */
+  hspi->State       = HAL_SPI_STATE_BUSY_RX;
+  hspi->ErrorCode   = HAL_SPI_ERROR_NONE;
+  hspi->pRxBuffPtr  = (uint8_t *)pData;
+  hspi->RxXferSize  = Size;
+  hspi->RxXferCount = Size;
+
+  /*Init field not used in handle to zero */
+  hspi->RxISR       = NULL;
+  hspi->TxISR       = NULL;
+  hspi->TxXferSize  = (uint16_t) 0UL;
+  hspi->TxXferCount = (uint16_t) 0UL;
+
+  /* Configure communication direction : 1Line */
+  if (hspi->Init.Direction == SPI_DIRECTION_1LINE)
+  {
+    SPI_1LINE_RX(hspi);
+  }
+  else
+  {
+    SPI_2LINES_RX(hspi);
+  }
+
+  /* Packing mode management is enabled by the DMA settings */
+  if (((hspi->Init.DataSize > SPI_DATASIZE_16BIT) && (hspi->hdmarx->Init.MemDataAlignment != DMA_MDATAALIGN_WORD))    || \
+      ((hspi->Init.DataSize > SPI_DATASIZE_8BIT) && ((hspi->hdmarx->Init.MemDataAlignment != DMA_MDATAALIGN_HALFWORD) && \
+                                                     (hspi->hdmarx->Init.MemDataAlignment != DMA_MDATAALIGN_WORD))))
+  {
+    /* Restriction the DMA data received is not allowed in this mode */
+    __HAL_UNLOCK(hspi);
+    return HAL_ERROR;
+  }
+
+  /* Clear RXDMAEN bit */
+  CLEAR_BIT(hspi->Instance->CFG1, SPI_CFG1_RXDMAEN);
+
+  /* Adjust XferCount according to DMA alignment / Data size */
+  if (hspi->Init.DataSize <= SPI_DATASIZE_8BIT)
+  {
+    if (hspi->hdmarx->Init.MemDataAlignment == DMA_MDATAALIGN_HALFWORD)
+    {
+      hspi->RxXferCount = (hspi->RxXferCount + (uint16_t) 1UL) >> 1UL;
+    }
+    if (hspi->hdmarx->Init.MemDataAlignment == DMA_MDATAALIGN_WORD)
+    {
+      hspi->RxXferCount = (hspi->RxXferCount + (uint16_t) 3UL) >> 2UL;
+    }
+  }
+  else if (hspi->Init.DataSize <= SPI_DATASIZE_16BIT)
+  {
+    if (hspi->hdmarx->Init.MemDataAlignment == DMA_MDATAALIGN_WORD)
+    {
+      hspi->RxXferCount = (hspi->RxXferCount + (uint16_t) 1UL) >> 1UL;
+    }
+  }
+  else
+  {
+    /* Adjustment done */
+  }
+
+  /* Set the SPI RxDMA Half transfer complete callback */
+  hspi->hdmarx->XferHalfCpltCallback = SPI_DMAHalfReceiveCplt;
+
+  /* Set the SPI Rx DMA transfer complete callback */
+  hspi->hdmarx->XferCpltCallback = SPI_DMAReceiveCplt;
+
+  /* Set the DMA error callback */
+  hspi->hdmarx->XferErrorCallback = SPI_DMAError;
+
+  /* Set the DMA AbortCpltCallback */
+  hspi->hdmarx->XferAbortCallback = NULL;
+
+  /* Enable the Rx DMA Stream/Channel  */
+  if (HAL_OK != HAL_DMA_Start_IT(hspi->hdmarx, (uint32_t)&hspi->Instance->RXDR, (uint32_t)hspi->pRxBuffPtr,
+                                 hspi->RxXferCount))
+  {
+    /* Update SPI error code */
+    SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_DMA);
+    hspi->State = HAL_SPI_STATE_READY;
+
+    /* Unlock the process */
+    __HAL_UNLOCK(hspi);
+
+    return HAL_ERROR;
+  }
+
+  /* Set the number of data at current transfer */
+  if (hspi->hdmarx->Init.Mode == DMA_CIRCULAR)
+  {
+    MODIFY_REG(hspi->Instance->CR2, SPI_CR2_TSIZE, 0UL);
+  }
+  else
+  {
+    MODIFY_REG(hspi->Instance->CR2, SPI_CR2_TSIZE, Size);
+  }
+
+  /* Enable Rx DMA Request */
+  SET_BIT(hspi->Instance->CFG1, SPI_CFG1_RXDMAEN);
+
+  /* Enable the SPI Error Interrupt Bit */
+  __HAL_SPI_ENABLE_IT(hspi, (SPI_IT_OVR | SPI_IT_FRE | SPI_IT_MODF));
+
+  /* Enable SPI peripheral */
+  __HAL_SPI_ENABLE(hspi);
+
+  if (hspi->Init.Mode == SPI_MODE_MASTER)
+  {
+    /* Master transfer start */
+    SET_BIT(hspi->Instance->CR1, SPI_CR1_CSTART);
+  }
+
+  /* Unlock the process */
+  __HAL_UNLOCK(hspi);
+
+  return HAL_OK;
+}
+
+/**
+  * @brief  Transmit and Receive an amount of data in non-blocking mode with DMA.
+  * @param  hspi   : pointer to a SPI_HandleTypeDef structure that contains
+  *                  the configuration information for SPI module.
+  * @param  pTxData: pointer to transmission data buffer
+  * @param  pRxData: pointer to reception data buffer
+  * @param  Size   : amount of data to be sent
+  * @note   When the CRC feature is enabled the pRxData Length must be Size + 1
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_SPI_TransmitReceive_DMA(SPI_HandleTypeDef *hspi, const uint8_t *pTxData, uint8_t *pRxData,
+                                              uint16_t Size)
+{
+  /* Check Direction parameter */
+  assert_param(IS_SPI_DIRECTION_2LINES(hspi->Init.Direction));
+
+  if (hspi->State != HAL_SPI_STATE_READY)
+  {
+    return HAL_BUSY;
+  }
+
+  if ((pTxData == NULL) || (pRxData == NULL) || (Size == 0UL))
+  {
+    return HAL_ERROR;
+  }
+
+  /* Lock the process */
+  __HAL_LOCK(hspi);
+
+  /* Set the transaction information */
+  hspi->State       = HAL_SPI_STATE_BUSY_TX_RX;
+  hspi->ErrorCode   = HAL_SPI_ERROR_NONE;
+  hspi->pTxBuffPtr  = (const uint8_t *)pTxData;
+  hspi->TxXferSize  = Size;
+  hspi->TxXferCount = Size;
+  hspi->pRxBuffPtr  = (uint8_t *)pRxData;
+  hspi->RxXferSize  = Size;
+  hspi->RxXferCount = Size;
+
+  /* Init field not used in handle to zero */
+  hspi->RxISR       = NULL;
+  hspi->TxISR       = NULL;
+
+  /* Set Full-Duplex mode */
+  SPI_2LINES(hspi);
+
+  /* Reset the Tx/Rx DMA bits */
+  CLEAR_BIT(hspi->Instance->CFG1, SPI_CFG1_TXDMAEN | SPI_CFG1_RXDMAEN);
+
+  /* Packing mode management is enabled by the DMA settings */
+  if (((hspi->Init.DataSize > SPI_DATASIZE_16BIT) && \
+       ((hspi->hdmarx->Init.MemDataAlignment != DMA_MDATAALIGN_WORD) || \
+        (hspi->hdmatx->Init.MemDataAlignment != DMA_MDATAALIGN_WORD))) || \
+      ((hspi->Init.DataSize > SPI_DATASIZE_8BIT) && \
+       (((hspi->hdmarx->Init.MemDataAlignment != DMA_MDATAALIGN_HALFWORD) && \
+         (hspi->hdmarx->Init.MemDataAlignment != DMA_MDATAALIGN_WORD)) || \
+        ((hspi->hdmatx->Init.MemDataAlignment != DMA_MDATAALIGN_HALFWORD) && \
+         (hspi->hdmatx->Init.MemDataAlignment != DMA_MDATAALIGN_WORD)))))
+  {
+    /* Restriction the DMA data received is not allowed in this mode */
+    /* Unlock the process */
+    __HAL_UNLOCK(hspi);
+    return HAL_ERROR;
+  }
+
+  /* Adjust XferCount according to DMA alignment / Data size */
+  if (hspi->Init.DataSize <= SPI_DATASIZE_8BIT)
+  {
+    if (hspi->hdmatx->Init.MemDataAlignment == DMA_MDATAALIGN_HALFWORD)
+    {
+      hspi->TxXferCount = (hspi->TxXferCount + (uint16_t) 1UL) >> 1UL;
+    }
+    if (hspi->hdmatx->Init.MemDataAlignment == DMA_MDATAALIGN_WORD)
+    {
+      hspi->TxXferCount = (hspi->TxXferCount + (uint16_t) 3UL) >> 2UL;
+    }
+    if (hspi->hdmarx->Init.MemDataAlignment == DMA_MDATAALIGN_HALFWORD)
+    {
+      hspi->RxXferCount = (hspi->RxXferCount + (uint16_t) 1UL) >> 1UL;
+    }
+    if (hspi->hdmarx->Init.MemDataAlignment == DMA_MDATAALIGN_WORD)
+    {
+      hspi->RxXferCount = (hspi->RxXferCount + (uint16_t) 3UL) >> 2UL;
+    }
+  }
+  else if (hspi->Init.DataSize <= SPI_DATASIZE_16BIT)
+  {
+    if (hspi->hdmatx->Init.MemDataAlignment == DMA_MDATAALIGN_WORD)
+    {
+      hspi->TxXferCount = (hspi->TxXferCount + (uint16_t) 1UL) >> 1UL;
+    }
+    if (hspi->hdmarx->Init.MemDataAlignment == DMA_MDATAALIGN_WORD)
+    {
+      hspi->RxXferCount = (hspi->RxXferCount + (uint16_t) 1UL) >> 1UL;
+    }
+  }
+  else
+  {
+    /* Adjustment done */
+  }
+
+  /* Set the SPI Tx/Rx DMA Half transfer complete callback */
+  hspi->hdmarx->XferHalfCpltCallback = SPI_DMAHalfTransmitReceiveCplt;
+  hspi->hdmarx->XferCpltCallback     = SPI_DMATransmitReceiveCplt;
+
+  /* Set the DMA error callback */
+  hspi->hdmarx->XferErrorCallback = SPI_DMAError;
+
+  /* Set the DMA AbortCallback */
+  hspi->hdmarx->XferAbortCallback = NULL;
+
+  /* Enable the Rx DMA Stream/Channel  */
+  if (HAL_OK != HAL_DMA_Start_IT(hspi->hdmarx, (uint32_t)&hspi->Instance->RXDR, (uint32_t)hspi->pRxBuffPtr,
+                                 hspi->RxXferCount))
+  {
+    /* Update SPI error code */
+    SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_DMA);
+    hspi->State = HAL_SPI_STATE_READY;
+
+    /* Unlock the process */
+    __HAL_UNLOCK(hspi);
+
+    return HAL_ERROR;
+  }
+
+  /* Enable Rx DMA Request */
+  SET_BIT(hspi->Instance->CFG1, SPI_CFG1_RXDMAEN);
+
+  /* Set the SPI Tx DMA transfer complete callback as NULL because the communication closing
+  is performed in DMA reception complete callback  */
+  hspi->hdmatx->XferHalfCpltCallback = NULL;
+  hspi->hdmatx->XferCpltCallback     = NULL;
+  hspi->hdmatx->XferAbortCallback    = NULL;
+
+  /* Set the DMA error callback */
+  hspi->hdmatx->XferErrorCallback    = SPI_DMAError;
+
+  /* Enable the Tx DMA Stream/Channel  */
+  if (HAL_OK != HAL_DMA_Start_IT(hspi->hdmatx, (uint32_t)hspi->pTxBuffPtr, (uint32_t)&hspi->Instance->TXDR,
+                                 hspi->TxXferCount))
+  {
+    /* Abort Rx DMA Channel already started */
+    (void)HAL_DMA_Abort(hspi->hdmarx);
+
+    /* Update SPI error code */
+    SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_DMA);
+    hspi->State = HAL_SPI_STATE_READY;
+
+    /* Unlock the process */
+    __HAL_UNLOCK(hspi);
+
+    return HAL_ERROR;
+  }
+
+  if (hspi->hdmatx->Init.Mode == DMA_CIRCULAR)
+  {
+    MODIFY_REG(hspi->Instance->CR2, SPI_CR2_TSIZE, 0UL);
+  }
+  else
+  {
+    MODIFY_REG(hspi->Instance->CR2, SPI_CR2_TSIZE, Size);
+  }
+
+  /* Enable Tx DMA Request */
+  SET_BIT(hspi->Instance->CFG1, SPI_CFG1_TXDMAEN);
+
+  /* Enable the SPI Error Interrupt Bit */
+  __HAL_SPI_ENABLE_IT(hspi, (SPI_IT_OVR | SPI_IT_UDR | SPI_IT_FRE | SPI_IT_MODF));
+
+  /* Enable SPI peripheral */
+  __HAL_SPI_ENABLE(hspi);
+
+  if (hspi->Init.Mode == SPI_MODE_MASTER)
+  {
+    /* Master transfer start */
+    SET_BIT(hspi->Instance->CR1, SPI_CR1_CSTART);
+  }
+
+  /* Unlock the process */
+  __HAL_UNLOCK(hspi);
+
+  return HAL_OK;
+}
+
+/**
+  * @brief  Abort ongoing transfer (blocking mode).
+  * @param  hspi SPI handle.
+  * @note   This procedure could be used for aborting any ongoing transfer (Tx and Rx),
+  *         started in Interrupt or DMA mode.
+  * @note   This procedure performs following operations :
+  *          + Disable SPI Interrupts (depending of transfer direction)
+  *          + Disable the DMA transfer in the peripheral register (if enabled)
+  *          + Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode)
+  *          + Set handle State to READY.
+  * @note   This procedure is executed in blocking mode : when exiting function, Abort is considered as completed.
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_SPI_Abort(SPI_HandleTypeDef *hspi)
+{
+  HAL_StatusTypeDef errorcode;
+
+  __IO uint32_t count;
+
+  /* Lock the process */
+  __HAL_LOCK(hspi);
+
+  /* Set hspi->state to aborting to avoid any interaction */
+  hspi->State = HAL_SPI_STATE_ABORT;
+
+  /* Initialized local variable  */
+  errorcode = HAL_OK;
+  count = SPI_DEFAULT_TIMEOUT * (SystemCoreClock / 24UL / 1000UL);
+
+  /* If master communication on going, make sure current frame is done before closing the connection */
+  if (HAL_IS_BIT_SET(hspi->Instance->CR1, SPI_CR1_CSTART))
+  {
+    /* Disable EOT interrupt */
+    __HAL_SPI_DISABLE_IT(hspi, SPI_IT_EOT);
+    do
+    {
+      count--;
+      if (count == 0UL)
+      {
+        SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_ABORT);
+        break;
+      }
+    } while (HAL_IS_BIT_SET(hspi->Instance->IER, SPI_IT_EOT));
+
+    /* Request a Suspend transfer */
+    SET_BIT(hspi->Instance->CR1, SPI_CR1_CSUSP);
+    do
+    {
+      count--;
+      if (count == 0UL)
+      {
+        SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_ABORT);
+        break;
+      }
+    } while (HAL_IS_BIT_SET(hspi->Instance->CR1, SPI_CR1_CSTART));
+
+    /* Clear SUSP flag */
+    __HAL_SPI_CLEAR_SUSPFLAG(hspi);
+    do
+    {
+      count--;
+      if (count == 0UL)
+      {
+        SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_ABORT);
+        break;
+      }
+    } while (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_SUSP));
+  }
+
+  /* Disable the SPI DMA Tx request if enabled */
+  if (HAL_IS_BIT_SET(hspi->Instance->CFG1, SPI_CFG1_TXDMAEN))
+  {
+    if (hspi->hdmatx != NULL)
+    {
+      /* Abort the SPI DMA Tx Stream/Channel : use blocking DMA Abort API (no callback) */
+      hspi->hdmatx->XferAbortCallback = NULL;
+
+      /* Abort DMA Tx Handle linked to SPI Peripheral */
+      if (HAL_DMA_Abort(hspi->hdmatx) != HAL_OK)
+      {
+        if (HAL_DMA_GetError(hspi->hdmatx) == HAL_DMA_ERROR_TIMEOUT)
+        {
+          hspi->ErrorCode = HAL_SPI_ERROR_ABORT;
+        }
+      }
+    }
+  }
+
+  /* Disable the SPI DMA Rx request if enabled */
+  if (HAL_IS_BIT_SET(hspi->Instance->CFG1, SPI_CFG1_RXDMAEN))
+  {
+    if (hspi->hdmarx != NULL)
+    {
+      /* Abort the SPI DMA Rx Stream/Channel : use blocking DMA Abort API (no callback) */
+      hspi->hdmarx->XferAbortCallback = NULL;
+
+      /* Abort DMA Rx Handle linked to SPI Peripheral */
+      if (HAL_DMA_Abort(hspi->hdmarx) != HAL_OK)
+      {
+        if (HAL_DMA_GetError(hspi->hdmarx) == HAL_DMA_ERROR_TIMEOUT)
+        {
+          hspi->ErrorCode = HAL_SPI_ERROR_ABORT;
+        }
+      }
+    }
+  }
+
+  /* Proceed with abort procedure */
+  SPI_AbortTransfer(hspi);
+
+  /* Check error during Abort procedure */
+  if (HAL_IS_BIT_SET(hspi->ErrorCode, HAL_SPI_ERROR_ABORT))
+  {
+    /* return HAL_Error in case of error during Abort procedure */
+    errorcode = HAL_ERROR;
+  }
+  else
+  {
+    /* Reset errorCode */
+    hspi->ErrorCode = HAL_SPI_ERROR_NONE;
+  }
+
+  /* Restore hspi->state to ready */
+  hspi->State = HAL_SPI_STATE_READY;
+
+  /* Unlock the process */
+  __HAL_UNLOCK(hspi);
+
+  return errorcode;
+}
+
+/**
+  * @brief  Abort ongoing transfer (Interrupt mode).
+  * @param  hspi SPI handle.
+  * @note   This procedure could be used for aborting any ongoing transfer (Tx and Rx),
+  *         started in Interrupt or DMA mode.
+  * @note   This procedure performs following operations :
+  *          + Disable SPI Interrupts (depending of transfer direction)
+  *          + Disable the DMA transfer in the peripheral register (if enabled)
+  *          + Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode)
+  *          + Set handle State to READY
+  *          + At abort completion, call user abort complete callback.
+  * @note   This procedure is executed in Interrupt mode, meaning that abort procedure could be
+  *         considered as completed only when user abort complete callback is executed (not when exiting function).
+  * @retval HAL status
+  */
+HAL_StatusTypeDef HAL_SPI_Abort_IT(SPI_HandleTypeDef *hspi)
+{
+  HAL_StatusTypeDef errorcode;
+  __IO uint32_t count;
+  uint32_t dma_tx_abort_done = 1UL;
+  uint32_t dma_rx_abort_done = 1UL;
+
+  /* Set hspi->state to aborting to avoid any interaction */
+  hspi->State = HAL_SPI_STATE_ABORT;
+
+  /* Initialized local variable  */
+  errorcode = HAL_OK;
+  count = SPI_DEFAULT_TIMEOUT * (SystemCoreClock / 24UL / 1000UL);
+
+  /* If master communication on going, make sure current frame is done before closing the connection */
+  if (HAL_IS_BIT_SET(hspi->Instance->CR1, SPI_CR1_CSTART))
+  {
+    /* Disable EOT interrupt */
+    __HAL_SPI_DISABLE_IT(hspi, SPI_IT_EOT);
+    do
+    {
+      count--;
+      if (count == 0UL)
+      {
+        SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_ABORT);
+        break;
+      }
+    } while (HAL_IS_BIT_SET(hspi->Instance->IER, SPI_IT_EOT));
+
+    /* Request a Suspend transfer */
+    SET_BIT(hspi->Instance->CR1, SPI_CR1_CSUSP);
+    do
+    {
+      count--;
+      if (count == 0UL)
+      {
+        SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_ABORT);
+        break;
+      }
+    } while (HAL_IS_BIT_SET(hspi->Instance->CR1, SPI_CR1_CSTART));
+
+    /* Clear SUSP flag */
+    __HAL_SPI_CLEAR_SUSPFLAG(hspi);
+    do
+    {
+      count--;
+      if (count == 0UL)
+      {
+        SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_ABORT);
+        break;
+      }
+    } while (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_SUSP));
+  }
+
+  /* If DMA Tx and/or DMA Rx Handles are associated to SPI Handle, DMA Abort complete callbacks should be initialized
+     before any call to DMA Abort functions */
+
+  if (hspi->hdmatx != NULL)
+  {
+    if (HAL_IS_BIT_SET(hspi->Instance->CFG1, SPI_CFG1_TXDMAEN))
+    {
+      /* Set DMA Abort Complete callback if SPI DMA Tx request if enabled */
+      hspi->hdmatx->XferAbortCallback = SPI_DMATxAbortCallback;
+
+      dma_tx_abort_done = 0UL;
+
+      /* Abort DMA Tx Handle linked to SPI Peripheral */
+      if (HAL_DMA_Abort_IT(hspi->hdmatx) != HAL_OK)
+      {
+        if (HAL_DMA_GetError(hspi->hdmatx) == HAL_DMA_ERROR_NO_XFER)
+        {
+          dma_tx_abort_done = 1UL;
+          hspi->hdmatx->XferAbortCallback = NULL;
+        }
+      }
+    }
+    else
+    {
+      hspi->hdmatx->XferAbortCallback = NULL;
+    }
+  }
+
+  if (hspi->hdmarx != NULL)
+  {
+    if (HAL_IS_BIT_SET(hspi->Instance->CFG1, SPI_CFG1_RXDMAEN))
+    {
+      /* Set DMA Abort Complete callback if SPI DMA Rx request if enabled */
+      hspi->hdmarx->XferAbortCallback = SPI_DMARxAbortCallback;
+
+      dma_rx_abort_done = 0UL;
+
+      /* Abort DMA Rx Handle linked to SPI Peripheral */
+      if (HAL_DMA_Abort_IT(hspi->hdmarx) != HAL_OK)
+      {
+        if (HAL_DMA_GetError(hspi->hdmarx) == HAL_DMA_ERROR_NO_XFER)
+        {
+          dma_rx_abort_done = 1UL;
+          hspi->hdmarx->XferAbortCallback = NULL;
+        }
+      }
+    }
+    else
+    {
+      hspi->hdmarx->XferAbortCallback = NULL;
+    }
+  }
+
+  /* If no running DMA transfer, finish cleanup and call callbacks */
+  if ((dma_tx_abort_done == 1UL) && (dma_rx_abort_done == 1UL))
+  {
+    /* Proceed with abort procedure */
+    SPI_AbortTransfer(hspi);
+
+    /* Check error during Abort procedure */
+    if (HAL_IS_BIT_SET(hspi->ErrorCode, HAL_SPI_ERROR_ABORT))
+    {
+      /* return HAL_Error in case of error during Abort procedure */
+      errorcode = HAL_ERROR;
+    }
+    else
+    {
+      /* Reset errorCode */
+      hspi->ErrorCode = HAL_SPI_ERROR_NONE;
+    }
+
+    /* Restore hspi->state to ready */
+    hspi->State = HAL_SPI_STATE_READY;
+
+    /* Call user Abort complete callback */
+#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1UL)
+    hspi->AbortCpltCallback(hspi);
+#else
+    HAL_SPI_AbortCpltCallback(hspi);
+#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
+  }
+
+  return errorcode;
+}
+
+/**
+  * @brief  Pause the DMA Transfer.
+  *         This API is not supported, it is maintained for backward compatibility.
+  * @param  hspi: pointer to a SPI_HandleTypeDef structure that contains
+  *               the configuration information for the specified SPI module.
+  * @retval HAL_ERROR
+  */
+HAL_StatusTypeDef HAL_SPI_DMAPause(SPI_HandleTypeDef *hspi)
+{
+  /* Set error code to not supported */
+  SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_NOT_SUPPORTED);
+
+  return HAL_ERROR;
+}
+
+/**
+  * @brief  Resume the DMA Transfer.
+  *         This API is not supported, it is maintained for backward compatibility.
+  * @param  hspi: pointer to a SPI_HandleTypeDef structure that contains
+  *               the configuration information for the specified SPI module.
+  * @retval HAL_ERROR
+  */
+HAL_StatusTypeDef HAL_SPI_DMAResume(SPI_HandleTypeDef *hspi)
+{
+  /* Set error code to not supported */
+  SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_NOT_SUPPORTED);
+
+  return HAL_ERROR;
+}
+
+/**
+  * @brief  Stop the DMA Transfer.
+  *         This API is not supported, it is maintained for backward compatibility.
+  * @param  hspi: pointer to a SPI_HandleTypeDef structure that contains
+  *               the configuration information for the specified SPI module.
+  * @retval HAL_ERROR
+  */
+HAL_StatusTypeDef HAL_SPI_DMAStop(SPI_HandleTypeDef *hspi)
+{
+  /* Set error code to not supported */
+  SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_NOT_SUPPORTED);
+
+  return HAL_ERROR;
+}
+
+/**
+  * @brief  Handle SPI interrupt request.
+  * @param  hspi: pointer to a SPI_HandleTypeDef structure that contains
+  *               the configuration information for the specified SPI module.
+  * @retval None
+  */
+void HAL_SPI_IRQHandler(SPI_HandleTypeDef *hspi)
+{
+  uint32_t itsource = hspi->Instance->IER;
+  uint32_t itflag   = hspi->Instance->SR;
+  uint32_t trigger  = itsource & itflag;
+  uint32_t cfg1     = hspi->Instance->CFG1;
+  uint32_t handled  = 0UL;
+
+  HAL_SPI_StateTypeDef State = hspi->State;
+#if defined (__GNUC__)
+  __IO uint16_t *prxdr_16bits = (__IO uint16_t *)(&(hspi->Instance->RXDR));
+#endif /* __GNUC__ */
+
+  /* SPI in SUSPEND mode  ----------------------------------------------------*/
+  if (HAL_IS_BIT_SET(itflag, SPI_FLAG_SUSP) && HAL_IS_BIT_SET(itsource, SPI_FLAG_EOT))
+  {
+    /* Clear the Suspend flag */
+    __HAL_SPI_CLEAR_SUSPFLAG(hspi);
+
+    /* Suspend on going, Call the Suspend callback */
+#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1UL)
+    hspi->SuspendCallback(hspi);
+#else
+    HAL_SPI_SuspendCallback(hspi);
+#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
+    return;
+  }
+
+  /* SPI in mode Transmitter and Receiver ------------------------------------*/
+  if (HAL_IS_BIT_CLR(trigger, SPI_FLAG_OVR) && HAL_IS_BIT_CLR(trigger, SPI_FLAG_UDR) && \
+      HAL_IS_BIT_SET(trigger, SPI_FLAG_DXP))
+  {
+    hspi->TxISR(hspi);
+    hspi->RxISR(hspi);
+    handled = 1UL;
+  }
+
+  /* SPI in mode Receiver ----------------------------------------------------*/
+  if (HAL_IS_BIT_CLR(trigger, SPI_FLAG_OVR) && HAL_IS_BIT_SET(trigger, SPI_FLAG_RXP) && \
+      HAL_IS_BIT_CLR(trigger, SPI_FLAG_DXP))
+  {
+    hspi->RxISR(hspi);
+    handled = 1UL;
+  }
+
+  /* SPI in mode Transmitter -------------------------------------------------*/
+  if (HAL_IS_BIT_CLR(trigger, SPI_FLAG_UDR) && HAL_IS_BIT_SET(trigger, SPI_FLAG_TXP) && \
+      HAL_IS_BIT_CLR(trigger, SPI_FLAG_DXP))
+  {
+    hspi->TxISR(hspi);
+    handled = 1UL;
+  }
+
+#if defined(USE_SPI_RELOAD_TRANSFER)
+  /* SPI Reload  -------------------------------------------------*/
+  if (HAL_IS_BIT_SET(trigger, SPI_FLAG_TSERF))
+  {
+    __HAL_SPI_CLEAR_TSERFFLAG(hspi);
+  }
+#endif /* USE_SPI_RELOAD_TRANSFER */
+
+  if (handled != 0UL)
+  {
+    return;
+  }
+
+  /* SPI End Of Transfer: DMA or IT based transfer */
+  if (HAL_IS_BIT_SET(trigger, SPI_FLAG_EOT))
+  {
+    /* Clear EOT/TXTF/SUSP flag */
+    __HAL_SPI_CLEAR_EOTFLAG(hspi);
+    __HAL_SPI_CLEAR_TXTFFLAG(hspi);
+    __HAL_SPI_CLEAR_SUSPFLAG(hspi);
+
+    /* Disable EOT interrupt */
+    __HAL_SPI_DISABLE_IT(hspi, SPI_IT_EOT);
+
+    /* For the IT based receive extra polling maybe required for last packet */
+    if (HAL_IS_BIT_CLR(hspi->Instance->CFG1, SPI_CFG1_TXDMAEN | SPI_CFG1_RXDMAEN))
+    {
+      /* Pooling remaining data */
+      while (hspi->RxXferCount != 0UL)
+      {
+        /* Receive data in 32 Bit mode */
+        if (hspi->Init.DataSize > SPI_DATASIZE_16BIT)
+        {
+          *((uint32_t *)hspi->pRxBuffPtr) = *((__IO uint32_t *)&hspi->Instance->RXDR);
+          hspi->pRxBuffPtr += sizeof(uint32_t);
+        }
+        /* Receive data in 16 Bit mode */
+        else if (hspi->Init.DataSize > SPI_DATASIZE_8BIT)
+        {
+#if defined (__GNUC__)
+          *((uint16_t *)hspi->pRxBuffPtr) = *prxdr_16bits;
+#else
+          *((uint16_t *)hspi->pRxBuffPtr) = *((__IO uint16_t *)&hspi->Instance->RXDR);
+#endif /* __GNUC__ */
+          hspi->pRxBuffPtr += sizeof(uint16_t);
+        }
+        /* Receive data in 8 Bit mode */
+        else
+        {
+          *((uint8_t *)hspi->pRxBuffPtr) = *((__IO uint8_t *)&hspi->Instance->RXDR);
+          hspi->pRxBuffPtr += sizeof(uint8_t);
+        }
+
+        hspi->RxXferCount--;
+      }
+    }
+
+    /* Call SPI Standard close procedure */
+    SPI_CloseTransfer(hspi);
+
+    hspi->State = HAL_SPI_STATE_READY;
+    if (hspi->ErrorCode != HAL_SPI_ERROR_NONE)
+    {
+#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1UL)
+      hspi->ErrorCallback(hspi);
+#else
+      HAL_SPI_ErrorCallback(hspi);
+#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
+      return;
+    }
+
+#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1UL)
+    /* Call appropriate user callback */
+    if (State == HAL_SPI_STATE_BUSY_TX_RX)
+    {
+      hspi->TxRxCpltCallback(hspi);
+    }
+    else if (State == HAL_SPI_STATE_BUSY_RX)
+    {
+      hspi->RxCpltCallback(hspi);
+    }
+    else if (State == HAL_SPI_STATE_BUSY_TX)
+    {
+      hspi->TxCpltCallback(hspi);
+    }
+#else
+    /* Call appropriate user callback */
+    if (State == HAL_SPI_STATE_BUSY_TX_RX)
+    {
+      HAL_SPI_TxRxCpltCallback(hspi);
+    }
+    else if (State == HAL_SPI_STATE_BUSY_RX)
+    {
+      HAL_SPI_RxCpltCallback(hspi);
+    }
+    else if (State == HAL_SPI_STATE_BUSY_TX)
+    {
+      HAL_SPI_TxCpltCallback(hspi);
+    }
+#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
+    else
+    {
+      /* End of the appropriate call */
+    }
+
+    return;
+  }
+
+  /* SPI in Error Treatment --------------------------------------------------*/
+  if ((trigger & (SPI_FLAG_MODF | SPI_FLAG_OVR | SPI_FLAG_FRE | SPI_FLAG_UDR)) != 0UL)
+  {
+    /* SPI Overrun error interrupt occurred ----------------------------------*/
+    if ((trigger & SPI_FLAG_OVR) != 0UL)
+    {
+      SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_OVR);
+      __HAL_SPI_CLEAR_OVRFLAG(hspi);
+    }
+
+    /* SPI Mode Fault error interrupt occurred -------------------------------*/
+    if ((trigger & SPI_FLAG_MODF) != 0UL)
+    {
+      SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_MODF);
+      __HAL_SPI_CLEAR_MODFFLAG(hspi);
+    }
+
+    /* SPI Frame error interrupt occurred ------------------------------------*/
+    if ((trigger & SPI_FLAG_FRE) != 0UL)
+    {
+      SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FRE);
+      __HAL_SPI_CLEAR_FREFLAG(hspi);
+    }
+
+    /* SPI Underrun error interrupt occurred ------------------------------------*/
+    if ((trigger & SPI_FLAG_UDR) != 0UL)
+    {
+      SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_UDR);
+      __HAL_SPI_CLEAR_UDRFLAG(hspi);
+    }
+
+    if (hspi->ErrorCode != HAL_SPI_ERROR_NONE)
+    {
+      /* Disable SPI peripheral */
+      __HAL_SPI_DISABLE(hspi);
+
+      /* Disable all interrupts */
+      __HAL_SPI_DISABLE_IT(hspi, (SPI_IT_EOT | SPI_IT_RXP | SPI_IT_TXP | SPI_IT_MODF |
+                                  SPI_IT_OVR | SPI_IT_FRE | SPI_IT_UDR));
+
+      /* Disable the SPI DMA requests if enabled */
+      if (HAL_IS_BIT_SET(cfg1, SPI_CFG1_TXDMAEN | SPI_CFG1_RXDMAEN))
+      {
+        /* Disable the SPI DMA requests */
+        CLEAR_BIT(hspi->Instance->CFG1, SPI_CFG1_TXDMAEN | SPI_CFG1_RXDMAEN);
+
+        /* Abort the SPI DMA Rx channel */
+        if (hspi->hdmarx != NULL)
+        {
+          /* Set the SPI DMA Abort callback :
+          will lead to call HAL_SPI_ErrorCallback() at end of DMA abort procedure */
+          hspi->hdmarx->XferAbortCallback = SPI_DMAAbortOnError;
+          if (HAL_OK != HAL_DMA_Abort_IT(hspi->hdmarx))
+          {
+            SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_ABORT);
+          }
+        }
+        /* Abort the SPI DMA Tx channel */
+        if (hspi->hdmatx != NULL)
+        {
+          /* Set the SPI DMA Abort callback :
+          will lead to call HAL_SPI_ErrorCallback() at end of DMA abort procedure */
+          hspi->hdmatx->XferAbortCallback = SPI_DMAAbortOnError;
+          if (HAL_OK != HAL_DMA_Abort_IT(hspi->hdmatx))
+          {
+            SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_ABORT);
+          }
+        }
+      }
+      else
+      {
+        /* Restore hspi->State to Ready */
+        hspi->State = HAL_SPI_STATE_READY;
+
+        /* Call user error callback */
+#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1UL)
+        hspi->ErrorCallback(hspi);
+#else
+        HAL_SPI_ErrorCallback(hspi);
+#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
+      }
+    }
+    return;
+  }
+}
+
+/**
+  * @brief Tx Transfer completed callback.
+  * @param  hspi: pointer to a SPI_HandleTypeDef structure that contains
+  *               the configuration information for SPI module.
+  * @retval None
+  */
+__weak void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi) /* Derogation MISRAC2012-Rule-8.13 */
+{
+  /* Prevent unused argument(s) compilation warning */
+  UNUSED(hspi);
+
+  /* NOTE : This function should not be modified, when the callback is needed,
+            the HAL_SPI_TxCpltCallback should be implemented in the user file
+   */
+}
+
+/**
+  * @brief Rx Transfer completed callback.
+  * @param  hspi: pointer to a SPI_HandleTypeDef structure that contains
+  *               the configuration information for SPI module.
+  * @retval None
+  */
+__weak void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi) /* Derogation MISRAC2012-Rule-8.13 */
+{
+  /* Prevent unused argument(s) compilation warning */
+  UNUSED(hspi);
+
+  /* NOTE : This function should not be modified, when the callback is needed,
+            the HAL_SPI_RxCpltCallback should be implemented in the user file
+   */
+}
+
+/**
+  * @brief Tx and Rx Transfer completed callback.
+  * @param  hspi: pointer to a SPI_HandleTypeDef structure that contains
+  *               the configuration information for SPI module.
+  * @retval None
+  */
+__weak void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi) /* Derogation MISRAC2012-Rule-8.13 */
+{
+  /* Prevent unused argument(s) compilation warning */
+  UNUSED(hspi);
+
+  /* NOTE : This function should not be modified, when the callback is needed,
+            the HAL_SPI_TxRxCpltCallback should be implemented in the user file
+   */
+}
+
+/**
+  * @brief Tx Half Transfer completed callback.
+  * @param  hspi: pointer to a SPI_HandleTypeDef structure that contains
+  *               the configuration information for SPI module.
+  * @retval None
+  */
+__weak void HAL_SPI_TxHalfCpltCallback(SPI_HandleTypeDef *hspi) /* Derogation MISRAC2012-Rule-8.13 */
+{
+  /* Prevent unused argument(s) compilation warning */
+  UNUSED(hspi);
+
+  /* NOTE : This function should not be modified, when the callback is needed,
+            the HAL_SPI_TxHalfCpltCallback should be implemented in the user file
+   */
+}
+
+/**
+  * @brief Rx Half Transfer completed callback.
+  * @param  hspi: pointer to a SPI_HandleTypeDef structure that contains
+  *               the configuration information for SPI module.
+  * @retval None
+  */
+__weak void HAL_SPI_RxHalfCpltCallback(SPI_HandleTypeDef *hspi) /* Derogation MISRAC2012-Rule-8.13 */
+{
+  /* Prevent unused argument(s) compilation warning */
+  UNUSED(hspi);
+
+  /* NOTE : This function should not be modified, when the callback is needed,
+            the HAL_SPI_RxHalfCpltCallback() should be implemented in the user file
+   */
+}
+
+/**
+  * @brief Tx and Rx Half Transfer callback.
+  * @param  hspi: pointer to a SPI_HandleTypeDef structure that contains
+  *               the configuration information for SPI module.
+  * @retval None
+  */
+__weak void HAL_SPI_TxRxHalfCpltCallback(SPI_HandleTypeDef *hspi) /* Derogation MISRAC2012-Rule-8.13 */
+{
+  /* Prevent unused argument(s) compilation warning */
+  UNUSED(hspi);
+
+  /* NOTE : This function should not be modified, when the callback is needed,
+            the HAL_SPI_TxRxHalfCpltCallback() should be implemented in the user file
+   */
+}
+
+/**
+  * @brief SPI error callback.
+  * @param  hspi: pointer to a SPI_HandleTypeDef structure that contains
+  *               the configuration information for SPI module.
+  * @retval None
+  */
+__weak void HAL_SPI_ErrorCallback(SPI_HandleTypeDef *hspi) /* Derogation MISRAC2012-Rule-8.13 */
+{
+  /* Prevent unused argument(s) compilation warning */
+  UNUSED(hspi);
+
+  /* NOTE : This function should not be modified, when the callback is needed,
+            the HAL_SPI_ErrorCallback should be implemented in the user file
+   */
+  /* NOTE : The ErrorCode parameter in the hspi handle is updated by the SPI processes
+            and user can use HAL_SPI_GetError() API to check the latest error occurred
+   */
+}
+
+/**
+  * @brief  SPI Abort Complete callback.
+  * @param  hspi SPI handle.
+  * @retval None
+  */
+__weak void HAL_SPI_AbortCpltCallback(SPI_HandleTypeDef *hspi) /* Derogation MISRAC2012-Rule-8.13 */
+{
+  /* Prevent unused argument(s) compilation warning */
+  UNUSED(hspi);
+
+  /* NOTE : This function should not be modified, when the callback is needed,
+            the HAL_SPI_AbortCpltCallback can be implemented in the user file.
+   */
+}
+
+/**
+  * @brief  SPI Suspend callback.
+  * @param  hspi SPI handle.
+  * @retval None
+  */
+__weak void HAL_SPI_SuspendCallback(SPI_HandleTypeDef *hspi) /* Derogation MISRAC2012-Rule-8.13 */
+{
+  /* Prevent unused argument(s) compilation warning */
+  UNUSED(hspi);
+
+  /* NOTE : This function should not be modified, when the callback is needed,
+            the HAL_SPI_SuspendCallback can be implemented in the user file.
+   */
+}
+
+/**
+  * @}
+  */
+
+/** @defgroup SPI_Exported_Functions_Group3 Peripheral State and Errors functions
+  * @brief   SPI control functions
+  *
+@verbatim
+ ===============================================================================
+                      ##### Peripheral State and Errors functions #####
+ ===============================================================================
+    [..]
+    This subsection provides a set of functions allowing to control the SPI.
+     (+) HAL_SPI_GetState() API can be helpful to check in run-time the state of the SPI peripheral
+     (+) HAL_SPI_GetError() check in run-time Errors occurring during communication
+@endverbatim
+  * @{
+  */
+
+/**
+  * @brief  Return the SPI handle state.
+  * @param  hspi: pointer to a SPI_HandleTypeDef structure that contains
+  *               the configuration information for SPI module.
+  * @retval SPI state
+  */
+HAL_SPI_StateTypeDef HAL_SPI_GetState(const SPI_HandleTypeDef *hspi)
+{
+  /* Return SPI handle state */
+  return hspi->State;
+}
+
+/**
+  * @brief  Return the SPI error code.
+  * @param  hspi: pointer to a SPI_HandleTypeDef structure that contains
+  *               the configuration information for SPI module.
+  * @retval SPI error code in bitmap format
+  */
+uint32_t HAL_SPI_GetError(const SPI_HandleTypeDef *hspi)
+{
+  /* Return SPI ErrorCode */
+  return hspi->ErrorCode;
+}
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/** @addtogroup SPI_Private_Functions
+  * @brief   Private functions
+  * @{
+  */
+
+/**
+  * @brief DMA SPI transmit process complete callback.
+  * @param  hdma: pointer to a DMA_HandleTypeDef structure that contains
+  *               the configuration information for the specified DMA module.
+  * @retval None
+  */
+static void SPI_DMATransmitCplt(DMA_HandleTypeDef *hdma)
+{
+  SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
+
+  if (hspi->State != HAL_SPI_STATE_ABORT)
+  {
+    if (hspi->hdmatx->Init.Mode == DMA_CIRCULAR)
+    {
+#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1UL)
+      hspi->TxCpltCallback(hspi);
+#else
+      HAL_SPI_TxCpltCallback(hspi);
+#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
+    }
+    else
+    {
+      /* Enable EOT interrupt */
+      __HAL_SPI_ENABLE_IT(hspi, SPI_IT_EOT);
+    }
+  }
+}
+
+/**
+  * @brief DMA SPI receive process complete callback.
+  * @param  hdma: pointer to a DMA_HandleTypeDef structure that contains
+  *               the configuration information for the specified DMA module.
+  * @retval None
+  */
+static void SPI_DMAReceiveCplt(DMA_HandleTypeDef *hdma)
+{
+  SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
+
+  if (hspi->State != HAL_SPI_STATE_ABORT)
+  {
+    if (hspi->hdmarx->Init.Mode == DMA_CIRCULAR)
+    {
+#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1UL)
+      hspi->RxCpltCallback(hspi);
+#else
+      HAL_SPI_RxCpltCallback(hspi);
+#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
+    }
+    else
+    {
+      /* Enable EOT interrupt */
+      __HAL_SPI_ENABLE_IT(hspi, SPI_IT_EOT);
+    }
+  }
+}
+
+/**
+  * @brief  DMA SPI transmit receive process complete callback.
+  * @param  hdma: pointer to a DMA_HandleTypeDef structure that contains
+  *               the configuration information for the specified DMA module.
+  * @retval None
+  */
+static void SPI_DMATransmitReceiveCplt(DMA_HandleTypeDef *hdma)
+{
+  SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
+
+  if (hspi->State != HAL_SPI_STATE_ABORT)
+  {
+    if (hspi->hdmatx->Init.Mode == DMA_CIRCULAR)
+    {
+#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1UL)
+      hspi->TxRxCpltCallback(hspi);
+#else
+      HAL_SPI_TxRxCpltCallback(hspi);
+#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
+    }
+    else
+    {
+      /* Enable EOT interrupt */
+      __HAL_SPI_ENABLE_IT(hspi, SPI_IT_EOT);
+    }
+  }
+}
+
+/**
+  * @brief  DMA SPI half transmit process complete callback.
+  * @param  hdma: pointer to a DMA_HandleTypeDef structure that contains
+  *               the configuration information for the specified DMA module.
+  * @retval None
+  */
+static void SPI_DMAHalfTransmitCplt(DMA_HandleTypeDef *hdma) /* Derogation MISRAC2012-Rule-8.13 */
+{
+  SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef *)
+                            ((DMA_HandleTypeDef *)hdma)->Parent; /* Derogation MISRAC2012-Rule-8.13 */
+
+#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1UL)
+  hspi->TxHalfCpltCallback(hspi);
+#else
+  HAL_SPI_TxHalfCpltCallback(hspi);
+#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
+}
+
+/**
+  * @brief  DMA SPI half receive process complete callback
+  * @param  hdma: pointer to a DMA_HandleTypeDef structure that contains
+  *               the configuration information for the specified DMA module.
+  * @retval None
+  */
+static void SPI_DMAHalfReceiveCplt(DMA_HandleTypeDef *hdma) /* Derogation MISRAC2012-Rule-8.13 */
+{
+  SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef *)
+                            ((DMA_HandleTypeDef *)hdma)->Parent; /* Derogation MISRAC2012-Rule-8.13 */
+
+#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1UL)
+  hspi->RxHalfCpltCallback(hspi);
+#else
+  HAL_SPI_RxHalfCpltCallback(hspi);
+#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
+}
+
+/**
+  * @brief  DMA SPI half transmit receive process complete callback.
+  * @param  hdma: pointer to a DMA_HandleTypeDef structure that contains
+  *               the configuration information for the specified DMA module.
+  * @retval None
+  */
+static void SPI_DMAHalfTransmitReceiveCplt(DMA_HandleTypeDef *hdma) /* Derogation MISRAC2012-Rule-8.13 */
+{
+  SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef *)
+                            ((DMA_HandleTypeDef *)hdma)->Parent; /* Derogation MISRAC2012-Rule-8.13 */
+
+#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1UL)
+  hspi->TxRxHalfCpltCallback(hspi);
+#else
+  HAL_SPI_TxRxHalfCpltCallback(hspi);
+#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
+}
+
+/**
+  * @brief  DMA SPI communication error callback.
+  * @param  hdma: pointer to a DMA_HandleTypeDef structure that contains
+  *               the configuration information for the specified DMA module.
+  * @retval None
+  */
+static void SPI_DMAError(DMA_HandleTypeDef *hdma)
+{
+  SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
+
+  /* if DMA error is FIFO error ignore it */
+  if (HAL_DMA_GetError(hdma) != HAL_DMA_ERROR_FE)
+  {
+    /* Call SPI standard close procedure */
+    SPI_CloseTransfer(hspi);
+
+    SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_DMA);
+    hspi->State = HAL_SPI_STATE_READY;
+#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1UL)
+    hspi->ErrorCallback(hspi);
+#else
+    HAL_SPI_ErrorCallback(hspi);
+#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
+  }
+}
+
+/**
+  * @brief  DMA SPI communication abort callback, when initiated by HAL services on Error
+  *         (To be called at end of DMA Abort procedure following error occurrence).
+  * @param  hdma DMA handle.
+  * @retval None
+  */
+static void SPI_DMAAbortOnError(DMA_HandleTypeDef *hdma)
+{
+  SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
+  hspi->RxXferCount = (uint16_t) 0UL;
+  hspi->TxXferCount = (uint16_t) 0UL;
+
+  /* Restore hspi->State to Ready */
+  hspi->State = HAL_SPI_STATE_READY;
+
+#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1UL)
+  hspi->ErrorCallback(hspi);
+#else
+  HAL_SPI_ErrorCallback(hspi);
+#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
+}
+
+/**
+  * @brief  DMA SPI Tx communication abort callback, when initiated by user
+  *         (To be called at end of DMA Tx Abort procedure following user abort request).
+  * @note   When this callback is executed, User Abort complete call back is called only if no
+  *         Abort still ongoing for Rx DMA Handle.
+  * @param  hdma DMA handle.
+  * @retval None
+  */
+static void SPI_DMATxAbortCallback(DMA_HandleTypeDef *hdma)
+{
+  SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
+
+  hspi->hdmatx->XferAbortCallback = NULL;
+
+  /* Check if an Abort process is still ongoing */
+  if (hspi->hdmarx != NULL)
+  {
+    if (hspi->hdmarx->XferAbortCallback != NULL)
+    {
+      return;
+    }
+  }
+
+  /* Call the Abort procedure */
+  SPI_AbortTransfer(hspi);
+
+  /* Restore hspi->State to Ready */
+  hspi->State = HAL_SPI_STATE_READY;
+
+  /* Call user Abort complete callback */
+#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1UL)
+  hspi->AbortCpltCallback(hspi);
+#else
+  HAL_SPI_AbortCpltCallback(hspi);
+#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
+}
+
+/**
+  * @brief  DMA SPI Rx communication abort callback, when initiated by user
+  *         (To be called at end of DMA Rx Abort procedure following user abort request).
+  * @note   When this callback is executed, User Abort complete call back is called only if no
+  *         Abort still ongoing for Tx DMA Handle.
+  * @param  hdma DMA handle.
+  * @retval None
+  */
+static void SPI_DMARxAbortCallback(DMA_HandleTypeDef *hdma)
+{
+  SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
+
+  hspi->hdmarx->XferAbortCallback = NULL;
+
+  /* Check if an Abort process is still ongoing */
+  if (hspi->hdmatx != NULL)
+  {
+    if (hspi->hdmatx->XferAbortCallback != NULL)
+    {
+      return;
+    }
+  }
+
+  /* Call the Abort procedure */
+  SPI_AbortTransfer(hspi);
+
+  /* Restore hspi->State to Ready */
+  hspi->State = HAL_SPI_STATE_READY;
+
+  /* Call user Abort complete callback */
+#if (USE_HAL_SPI_REGISTER_CALLBACKS == 1UL)
+  hspi->AbortCpltCallback(hspi);
+#else
+  HAL_SPI_AbortCpltCallback(hspi);
+#endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
+}
+
+/**
+  * @brief  Manage the receive 8-bit in Interrupt context.
+  * @param  hspi: pointer to a SPI_HandleTypeDef structure that contains
+  *               the configuration information for SPI module.
+  * @retval None
+  */
+static void SPI_RxISR_8BIT(SPI_HandleTypeDef *hspi)
+{
+  /* Receive data in 8 Bit mode */
+  *((uint8_t *)hspi->pRxBuffPtr) = (*(__IO uint8_t *)&hspi->Instance->RXDR);
+  hspi->pRxBuffPtr += sizeof(uint8_t);
+  hspi->RxXferCount--;
+
+  /* Disable IT if no more data excepted */
+  if (hspi->RxXferCount == 0UL)
+  {
+#if defined(USE_SPI_RELOAD_TRANSFER)
+    /* Check if there is any request to reload */
+    if (hspi->Reload.Requested == 1UL)
+    {
+      hspi->RxXferSize  = hspi->Reload.RxXferSize;
+      hspi->RxXferCount = hspi->Reload.RxXferSize;
+      hspi->pRxBuffPtr  = hspi->Reload.pRxBuffPtr;
+      hspi->Reload.Requested = 0UL;
+    }
+    else
+    {
+      /* Disable RXP interrupts */
+      __HAL_SPI_DISABLE_IT(hspi, SPI_IT_RXP);
+    }
+#else
+    /* Disable RXP interrupts */
+    __HAL_SPI_DISABLE_IT(hspi, SPI_IT_RXP);
+#endif /* USE_SPI_RELOAD_TRANSFER */
+  }
+}
+
+
+/**
+  * @brief  Manage the 16-bit receive in Interrupt context.
+  * @param  hspi: pointer to a SPI_HandleTypeDef structure that contains
+  *               the configuration information for SPI module.
+  * @retval None
+  */
+static void SPI_RxISR_16BIT(SPI_HandleTypeDef *hspi)
+{
+  /* Receive data in 16 Bit mode */
+#if defined (__GNUC__)
+  __IO uint16_t *prxdr_16bits = (__IO uint16_t *)(&(hspi->Instance->RXDR));
+
+  *((uint16_t *)hspi->pRxBuffPtr) = *prxdr_16bits;
+#else
+  *((uint16_t *)hspi->pRxBuffPtr) = (*(__IO uint16_t *)&hspi->Instance->RXDR);
+#endif /* __GNUC__ */
+  hspi->pRxBuffPtr += sizeof(uint16_t);
+  hspi->RxXferCount--;
+
+  /* Disable IT if no more data excepted */
+  if (hspi->RxXferCount == 0UL)
+  {
+#if defined(USE_SPI_RELOAD_TRANSFER)
+    /* Check if there is any request to reload */
+    if (hspi->Reload.Requested == 1UL)
+    {
+      hspi->RxXferSize  = hspi->Reload.RxXferSize;
+      hspi->RxXferCount = hspi->Reload.RxXferSize;
+      hspi->pRxBuffPtr  = hspi->Reload.pRxBuffPtr;
+      hspi->Reload.Requested = 0UL;
+    }
+    else
+    {
+      /* Disable RXP interrupts */
+      __HAL_SPI_DISABLE_IT(hspi, SPI_IT_RXP);
+    }
+#else
+    /* Disable RXP interrupts */
+    __HAL_SPI_DISABLE_IT(hspi, SPI_IT_RXP);
+#endif /* USE_SPI_RELOAD_TRANSFER */
+  }
+}
+
+
+/**
+  * @brief  Manage the 32-bit receive in Interrupt context.
+  * @param  hspi: pointer to a SPI_HandleTypeDef structure that contains
+  *               the configuration information for SPI module.
+  * @retval None
+  */
+static void SPI_RxISR_32BIT(SPI_HandleTypeDef *hspi)
+{
+  /* Receive data in 32 Bit mode */
+  *((uint32_t *)hspi->pRxBuffPtr) = (*(__IO uint32_t *)&hspi->Instance->RXDR);
+  hspi->pRxBuffPtr += sizeof(uint32_t);
+  hspi->RxXferCount--;
+
+  /* Disable IT if no more data excepted */
+  if (hspi->RxXferCount == 0UL)
+  {
+#if defined(USE_SPI_RELOAD_TRANSFER)
+    /* Check if there is any request to reload */
+    if (hspi->Reload.Requested == 1UL)
+    {
+      hspi->RxXferSize  = hspi->Reload.RxXferSize;
+      hspi->RxXferCount = hspi->Reload.RxXferSize;
+      hspi->pRxBuffPtr  = hspi->Reload.pRxBuffPtr;
+      hspi->Reload.Requested = 0UL;
+    }
+    else
+    {
+      /* Disable RXP interrupts */
+      __HAL_SPI_DISABLE_IT(hspi, SPI_IT_RXP);
+    }
+#else
+    /* Disable RXP interrupts */
+    __HAL_SPI_DISABLE_IT(hspi, SPI_IT_RXP);
+#endif /* USE_SPI_RELOAD_TRANSFER */
+  }
+}
+
+
+/**
+  * @brief  Handle the data 8-bit transmit in Interrupt mode.
+  * @param  hspi: pointer to a SPI_HandleTypeDef structure that contains
+  *               the configuration information for SPI module.
+  * @retval None
+  */
+static void SPI_TxISR_8BIT(SPI_HandleTypeDef *hspi)
+{
+  /* Transmit data in 8 Bit mode */
+  *(__IO uint8_t *)&hspi->Instance->TXDR = *((const uint8_t *)hspi->pTxBuffPtr);
+  hspi->pTxBuffPtr += sizeof(uint8_t);
+  hspi->TxXferCount--;
+
+  /* Disable IT if no more data excepted */
+  if (hspi->TxXferCount == 0UL)
+  {
+#if defined(USE_SPI_RELOAD_TRANSFER)
+    /* Check if there is any request to reload */
+    if (hspi->Reload.Requested == 1UL)
+    {
+      hspi->TxXferSize  = hspi->Reload.TxXferSize;
+      hspi->TxXferCount = hspi->Reload.TxXferSize;
+      hspi->pTxBuffPtr  = hspi->Reload.pTxBuffPtr;
+
+      /* In full duplex mode the reload request is reset in RX side */
+      if (hspi->State == HAL_SPI_STATE_BUSY_TX)
+      {
+        hspi->Reload.Requested = 0UL;
+      }
+    }
+    else
+    {
+      /* Disable TXP interrupts */
+      __HAL_SPI_DISABLE_IT(hspi, SPI_IT_TXP);
+    }
+#else
+    /* Disable TXP interrupts */
+    __HAL_SPI_DISABLE_IT(hspi, SPI_IT_TXP);
+#endif /* USE_SPI_RELOAD_TRANSFER */
+  }
+}
+
+/**
+  * @brief  Handle the data 16-bit transmit in Interrupt mode.
+  * @param  hspi: pointer to a SPI_HandleTypeDef structure that contains
+  *               the configuration information for SPI module.
+  * @retval None
+  */
+static void SPI_TxISR_16BIT(SPI_HandleTypeDef *hspi)
+{
+  /* Transmit data in 16 Bit mode */
+#if defined (__GNUC__)
+  __IO uint16_t *ptxdr_16bits = (__IO uint16_t *)(&(hspi->Instance->TXDR));
+
+  *ptxdr_16bits = *((const uint16_t *)hspi->pTxBuffPtr);
+#else
+  *((__IO uint16_t *)&hspi->Instance->TXDR) = *((const uint16_t *)hspi->pTxBuffPtr);
+#endif /* __GNUC__ */
+  hspi->pTxBuffPtr += sizeof(uint16_t);
+  hspi->TxXferCount--;
+
+  /* Disable IT if no more data excepted */
+  if (hspi->TxXferCount == 0UL)
+  {
+#if defined(USE_SPI_RELOAD_TRANSFER)
+    /* Check if there is any request to reload */
+    if (hspi->Reload.Requested == 1UL)
+    {
+      hspi->TxXferSize  = hspi->Reload.TxXferSize;
+      hspi->TxXferCount = hspi->Reload.TxXferSize;
+      hspi->pTxBuffPtr  = hspi->Reload.pTxBuffPtr;
+
+      /* In full duplex mode the reload request is reset in RX side */
+      if (hspi->State == HAL_SPI_STATE_BUSY_TX)
+      {
+        hspi->Reload.Requested = 0UL;
+      }
+    }
+    else
+    {
+      /* Disable TXP interrupts */
+      __HAL_SPI_DISABLE_IT(hspi, SPI_IT_TXP);
+    }
+#else
+    /* Disable TXP interrupts */
+    __HAL_SPI_DISABLE_IT(hspi, SPI_IT_TXP);
+#endif /* USE_SPI_RELOAD_TRANSFER */
+  }
+}
+
+/**
+  * @brief  Handle the data 32-bit transmit in Interrupt mode.
+  * @param  hspi: pointer to a SPI_HandleTypeDef structure that contains
+  *               the configuration information for SPI module.
+  * @retval None
+  */
+static void SPI_TxISR_32BIT(SPI_HandleTypeDef *hspi)
+{
+  /* Transmit data in 32 Bit mode */
+  *((__IO uint32_t *)&hspi->Instance->TXDR) = *((const uint32_t *)hspi->pTxBuffPtr);
+  hspi->pTxBuffPtr += sizeof(uint32_t);
+  hspi->TxXferCount--;
+
+  /* Disable IT if no more data excepted */
+  if (hspi->TxXferCount == 0UL)
+  {
+#if defined(USE_SPI_RELOAD_TRANSFER)
+    /* Check if there is any request to reload */
+    if (hspi->Reload.Requested == 1UL)
+    {
+      hspi->TxXferSize  = hspi->Reload.TxXferSize;
+      hspi->TxXferCount = hspi->Reload.TxXferSize;
+      hspi->pTxBuffPtr  = hspi->Reload.pTxBuffPtr;
+
+      /* In full duplex mode the reload request is reset in RX side */
+      if (hspi->State == HAL_SPI_STATE_BUSY_TX)
+      {
+        hspi->Reload.Requested = 0UL;
+      }
+    }
+    else
+    {
+      /* Disable TXP interrupts */
+      __HAL_SPI_DISABLE_IT(hspi, SPI_IT_TXP);
+    }
+#else
+    /* Disable TXP interrupts */
+    __HAL_SPI_DISABLE_IT(hspi, SPI_IT_TXP);
+#endif /* USE_SPI_RELOAD_TRANSFER */
+  }
+}
+
+/**
+  * @brief  Abort Transfer and clear flags.
+  * @param  hspi: pointer to a SPI_HandleTypeDef structure that contains
+  *               the configuration information for SPI module.
+  * @retval None
+  */
+static void SPI_AbortTransfer(SPI_HandleTypeDef *hspi)
+{
+  /* Disable SPI peripheral */
+  __HAL_SPI_DISABLE(hspi);
+
+  /* Disable ITs */
+  __HAL_SPI_DISABLE_IT(hspi, (SPI_IT_EOT | SPI_IT_TXP | SPI_IT_RXP | SPI_IT_DXP | SPI_IT_UDR | SPI_IT_OVR | \
+                              SPI_IT_FRE | SPI_IT_MODF));
+
+  /* Clear the Status flags in the SR register */
+  __HAL_SPI_CLEAR_EOTFLAG(hspi);
+  __HAL_SPI_CLEAR_TXTFFLAG(hspi);
+
+  /* Disable Tx DMA Request */
+  CLEAR_BIT(hspi->Instance->CFG1, SPI_CFG1_TXDMAEN | SPI_CFG1_RXDMAEN);
+
+  /* Clear the Error flags in the SR register */
+  __HAL_SPI_CLEAR_OVRFLAG(hspi);
+  __HAL_SPI_CLEAR_UDRFLAG(hspi);
+  __HAL_SPI_CLEAR_FREFLAG(hspi);
+  __HAL_SPI_CLEAR_MODFFLAG(hspi);
+  __HAL_SPI_CLEAR_SUSPFLAG(hspi);
+
+#if (USE_SPI_CRC != 0U)
+  __HAL_SPI_CLEAR_CRCERRFLAG(hspi);
+#endif /* USE_SPI_CRC */
+
+  hspi->TxXferCount = (uint16_t)0UL;
+  hspi->RxXferCount = (uint16_t)0UL;
+}
+
+
+/**
+  * @brief  Close Transfer and clear flags.
+  * @param  hspi: pointer to a SPI_HandleTypeDef structure that contains
+  *               the configuration information for SPI module.
+  * @retval HAL_ERROR: if any error detected
+  *         HAL_OK: if nothing detected
+  */
+static void SPI_CloseTransfer(SPI_HandleTypeDef *hspi)
+{
+  uint32_t itflag = hspi->Instance->SR;
+
+  __HAL_SPI_CLEAR_EOTFLAG(hspi);
+  __HAL_SPI_CLEAR_TXTFFLAG(hspi);
+
+  /* Disable SPI peripheral */
+  __HAL_SPI_DISABLE(hspi);
+
+  /* Disable ITs */
+  __HAL_SPI_DISABLE_IT(hspi, (SPI_IT_EOT | SPI_IT_TXP | SPI_IT_RXP | SPI_IT_DXP | SPI_IT_UDR | SPI_IT_OVR | \
+                              SPI_IT_FRE | SPI_IT_MODF));
+
+  /* Disable Tx DMA Request */
+  CLEAR_BIT(hspi->Instance->CFG1, SPI_CFG1_TXDMAEN | SPI_CFG1_RXDMAEN);
+
+  /* Report UnderRun error for non RX Only communication */
+  if (hspi->State != HAL_SPI_STATE_BUSY_RX)
+  {
+    if ((itflag & SPI_FLAG_UDR) != 0UL)
+    {
+      SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_UDR);
+      __HAL_SPI_CLEAR_UDRFLAG(hspi);
+    }
+  }
+
+  /* Report OverRun error for non TX Only communication */
+  if (hspi->State != HAL_SPI_STATE_BUSY_TX)
+  {
+    if ((itflag & SPI_FLAG_OVR) != 0UL)
+    {
+      SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_OVR);
+      __HAL_SPI_CLEAR_OVRFLAG(hspi);
+    }
+
+#if (USE_SPI_CRC != 0UL)
+    /* Check if CRC error occurred */
+    if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
+    {
+      if ((itflag & SPI_FLAG_CRCERR) != 0UL)
+      {
+        SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC);
+        __HAL_SPI_CLEAR_CRCERRFLAG(hspi);
+      }
+    }
+#endif /* USE_SPI_CRC */
+  }
+
+  /* SPI Mode Fault error interrupt occurred -------------------------------*/
+  if ((itflag & SPI_FLAG_MODF) != 0UL)
+  {
+    SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_MODF);
+    __HAL_SPI_CLEAR_MODFFLAG(hspi);
+  }
+
+  /* SPI Frame error interrupt occurred ------------------------------------*/
+  if ((itflag & SPI_FLAG_FRE) != 0UL)
+  {
+    SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FRE);
+    __HAL_SPI_CLEAR_FREFLAG(hspi);
+  }
+
+  hspi->TxXferCount = (uint16_t)0UL;
+  hspi->RxXferCount = (uint16_t)0UL;
+}
+
+/**
+  * @brief Handle SPI Communication Timeout.
+  * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
+  *              the configuration information for SPI module.
+  * @param Flag: SPI flag to check
+  * @param Status: flag state to check
+  * @param Timeout: Timeout duration
+  * @param Tickstart: Tick start value
+  * @retval HAL status
+  */
+static HAL_StatusTypeDef SPI_WaitOnFlagUntilTimeout(const SPI_HandleTypeDef *hspi, uint32_t Flag, FlagStatus Status,
+                                                    uint32_t Timeout, uint32_t Tickstart)
+{
+  /* Wait until flag is set */
+  while ((__HAL_SPI_GET_FLAG(hspi, Flag) ? SET : RESET) == Status)
+  {
+    /* Check for the Timeout */
+    if ((((HAL_GetTick() - Tickstart) >=  Timeout) && (Timeout != HAL_MAX_DELAY)) || (Timeout == 0U))
+    {
+      return HAL_TIMEOUT;
+    }
+  }
+  return HAL_OK;
+}
+
+/**
+  * @brief  Compute configured packet size from fifo perspective.
+  * @param  hspi: pointer to a SPI_HandleTypeDef structure that contains
+  *               the configuration information for SPI module.
+  * @retval Packet size occupied in the fifo
+  */
+static uint32_t SPI_GetPacketSize(const SPI_HandleTypeDef *hspi)
+{
+  uint32_t fifo_threashold = (hspi->Init.FifoThreshold >> SPI_CFG1_FTHLV_Pos) + 1UL;
+  uint32_t data_size       = (hspi->Init.DataSize      >> SPI_CFG1_DSIZE_Pos) + 1UL;
+
+  /* Convert data size to Byte */
+  data_size = (data_size + 7UL) / 8UL;
+
+  return data_size * fifo_threashold;
+}
+
+/**
+  * @}
+  */
+
+#endif /* HAL_SPI_MODULE_ENABLED */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
