diff --git a/port/stm32-f4discovery-cc256x-2/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_i2c.h b/port/stm32-f4discovery-cc256x-2/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_i2c.h
new file mode 100644
index 000000000..a3c4753fb
--- /dev/null
+++ b/port/stm32-f4discovery-cc256x-2/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_i2c.h
@@ -0,0 +1,738 @@
+/**
+ ******************************************************************************
+ * @file stm32f4xx_hal_i2c.h
+ * @author MCD Application Team
+ * @brief Header file of I2C HAL module.
+ ******************************************************************************
+ * @attention
+ *
+ *
© Copyright (c) 2016 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software component is licensed by ST under BSD 3-Clause license,
+ * the "License"; You may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ * opensource.org/licenses/BSD-3-Clause
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F4xx_HAL_I2C_H
+#define __STM32F4xx_HAL_I2C_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f4xx_hal_def.h"
+
+/** @addtogroup STM32F4xx_HAL_Driver
+ * @{
+ */
+
+/** @addtogroup I2C
+ * @{
+ */
+
+/* Exported types ------------------------------------------------------------*/
+/** @defgroup I2C_Exported_Types I2C Exported Types
+ * @{
+ */
+
+/** @defgroup I2C_Configuration_Structure_definition I2C Configuration Structure definition
+ * @brief I2C Configuration Structure definition
+ * @{
+ */
+typedef struct
+{
+ uint32_t ClockSpeed; /*!< Specifies the clock frequency.
+ This parameter must be set to a value lower than 400kHz */
+
+ uint32_t DutyCycle; /*!< Specifies the I2C fast mode duty cycle.
+ This parameter can be a value of @ref I2C_duty_cycle_in_fast_mode */
+
+ uint32_t OwnAddress1; /*!< Specifies the first device own address.
+ This parameter can be a 7-bit or 10-bit address. */
+
+ uint32_t AddressingMode; /*!< Specifies if 7-bit or 10-bit addressing mode is selected.
+ This parameter can be a value of @ref I2C_addressing_mode */
+
+ uint32_t DualAddressMode; /*!< Specifies if dual addressing mode is selected.
+ This parameter can be a value of @ref I2C_dual_addressing_mode */
+
+ uint32_t OwnAddress2; /*!< Specifies the second device own address if dual addressing mode is selected
+ This parameter can be a 7-bit address. */
+
+ uint32_t GeneralCallMode; /*!< Specifies if general call mode is selected.
+ This parameter can be a value of @ref I2C_general_call_addressing_mode */
+
+ uint32_t NoStretchMode; /*!< Specifies if nostretch mode is selected.
+ This parameter can be a value of @ref I2C_nostretch_mode */
+
+} I2C_InitTypeDef;
+
+/**
+ * @}
+ */
+
+/** @defgroup HAL_state_structure_definition HAL state structure definition
+ * @brief HAL State structure definition
+ * @note HAL I2C State value coding follow below described bitmap :
+ * b7-b6 Error information
+ * 00 : No Error
+ * 01 : Abort (Abort user request on going)
+ * 10 : Timeout
+ * 11 : Error
+ * b5 Peripheral initilisation status
+ * 0 : Reset (Peripheral not initialized)
+ * 1 : Init done (Peripheral initialized and ready to use. HAL I2C Init function called)
+ * b4 (not used)
+ * x : Should be set to 0
+ * b3
+ * 0 : Ready or Busy (No Listen mode ongoing)
+ * 1 : Listen (Peripheral in Address Listen Mode)
+ * b2 Intrinsic process state
+ * 0 : Ready
+ * 1 : Busy (Peripheral busy with some configuration or internal operations)
+ * b1 Rx state
+ * 0 : Ready (no Rx operation ongoing)
+ * 1 : Busy (Rx operation ongoing)
+ * b0 Tx state
+ * 0 : Ready (no Tx operation ongoing)
+ * 1 : Busy (Tx operation ongoing)
+ * @{
+ */
+typedef enum
+{
+ HAL_I2C_STATE_RESET = 0x00U, /*!< Peripheral is not yet Initialized */
+ HAL_I2C_STATE_READY = 0x20U, /*!< Peripheral Initialized and ready for use */
+ HAL_I2C_STATE_BUSY = 0x24U, /*!< An internal process is ongoing */
+ HAL_I2C_STATE_BUSY_TX = 0x21U, /*!< Data Transmission process is ongoing */
+ HAL_I2C_STATE_BUSY_RX = 0x22U, /*!< Data Reception process is ongoing */
+ HAL_I2C_STATE_LISTEN = 0x28U, /*!< Address Listen Mode is ongoing */
+ HAL_I2C_STATE_BUSY_TX_LISTEN = 0x29U, /*!< Address Listen Mode and Data Transmission
+ process is ongoing */
+ HAL_I2C_STATE_BUSY_RX_LISTEN = 0x2AU, /*!< Address Listen Mode and Data Reception
+ process is ongoing */
+ HAL_I2C_STATE_ABORT = 0x60U, /*!< Abort user request ongoing */
+ HAL_I2C_STATE_TIMEOUT = 0xA0U, /*!< Timeout state */
+ HAL_I2C_STATE_ERROR = 0xE0U /*!< Error */
+
+} HAL_I2C_StateTypeDef;
+
+/**
+ * @}
+ */
+
+/** @defgroup HAL_mode_structure_definition HAL mode structure definition
+ * @brief HAL Mode structure definition
+ * @note HAL I2C Mode value coding follow below described bitmap :\n
+ * b7 (not used)\n
+ * x : Should be set to 0\n
+ * b6\n
+ * 0 : None\n
+ * 1 : Memory (HAL I2C communication is in Memory Mode)\n
+ * b5\n
+ * 0 : None\n
+ * 1 : Slave (HAL I2C communication is in Slave Mode)\n
+ * b4\n
+ * 0 : None\n
+ * 1 : Master (HAL I2C communication is in Master Mode)\n
+ * b3-b2-b1-b0 (not used)\n
+ * xxxx : Should be set to 0000
+ * @{
+ */
+typedef enum
+{
+ HAL_I2C_MODE_NONE = 0x00U, /*!< No I2C communication on going */
+ HAL_I2C_MODE_MASTER = 0x10U, /*!< I2C communication is in Master Mode */
+ HAL_I2C_MODE_SLAVE = 0x20U, /*!< I2C communication is in Slave Mode */
+ HAL_I2C_MODE_MEM = 0x40U /*!< I2C communication is in Memory Mode */
+
+} HAL_I2C_ModeTypeDef;
+
+/**
+ * @}
+ */
+
+/** @defgroup I2C_Error_Code_definition I2C Error Code definition
+ * @brief I2C Error Code definition
+ * @{
+ */
+#define HAL_I2C_ERROR_NONE 0x00000000U /*!< No error */
+#define HAL_I2C_ERROR_BERR 0x00000001U /*!< BERR error */
+#define HAL_I2C_ERROR_ARLO 0x00000002U /*!< ARLO error */
+#define HAL_I2C_ERROR_AF 0x00000004U /*!< AF error */
+#define HAL_I2C_ERROR_OVR 0x00000008U /*!< OVR error */
+#define HAL_I2C_ERROR_DMA 0x00000010U /*!< DMA transfer error */
+#define HAL_I2C_ERROR_TIMEOUT 0x00000020U /*!< Timeout Error */
+#define HAL_I2C_ERROR_SIZE 0x00000040U /*!< Size Management error */
+#define HAL_I2C_ERROR_DMA_PARAM 0x00000080U /*!< DMA Parameter Error */
+#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
+#define HAL_I2C_ERROR_INVALID_CALLBACK 0x00000100U /*!< Invalid Callback error */
+#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
+/**
+ * @}
+ */
+
+/** @defgroup I2C_handle_Structure_definition I2C handle Structure definition
+ * @brief I2C handle Structure definition
+ * @{
+ */
+typedef struct __I2C_HandleTypeDef
+{
+ I2C_TypeDef *Instance; /*!< I2C registers base address */
+
+ I2C_InitTypeDef Init; /*!< I2C communication parameters */
+
+ uint8_t *pBuffPtr; /*!< Pointer to I2C transfer buffer */
+
+ uint16_t XferSize; /*!< I2C transfer size */
+
+ __IO uint16_t XferCount; /*!< I2C transfer counter */
+
+ __IO uint32_t XferOptions; /*!< I2C transfer options */
+
+ __IO uint32_t PreviousState; /*!< I2C communication Previous state and mode
+ context for internal usage */
+
+ DMA_HandleTypeDef *hdmatx; /*!< I2C Tx DMA handle parameters */
+
+ DMA_HandleTypeDef *hdmarx; /*!< I2C Rx DMA handle parameters */
+
+ HAL_LockTypeDef Lock; /*!< I2C locking object */
+
+ __IO HAL_I2C_StateTypeDef State; /*!< I2C communication state */
+
+ __IO HAL_I2C_ModeTypeDef Mode; /*!< I2C communication mode */
+
+ __IO uint32_t ErrorCode; /*!< I2C Error code */
+
+ __IO uint32_t Devaddress; /*!< I2C Target device address */
+
+ __IO uint32_t Memaddress; /*!< I2C Target memory address */
+
+ __IO uint32_t MemaddSize; /*!< I2C Target memory address size */
+
+ __IO uint32_t EventCount; /*!< I2C Event counter */
+
+
+#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
+ void (* MasterTxCpltCallback)(struct __I2C_HandleTypeDef *hi2c); /*!< I2C Master Tx Transfer completed callback */
+ void (* MasterRxCpltCallback)(struct __I2C_HandleTypeDef *hi2c); /*!< I2C Master Rx Transfer completed callback */
+ void (* SlaveTxCpltCallback)(struct __I2C_HandleTypeDef *hi2c); /*!< I2C Slave Tx Transfer completed callback */
+ void (* SlaveRxCpltCallback)(struct __I2C_HandleTypeDef *hi2c); /*!< I2C Slave Rx Transfer completed callback */
+ void (* ListenCpltCallback)(struct __I2C_HandleTypeDef *hi2c); /*!< I2C Listen Complete callback */
+ void (* MemTxCpltCallback)(struct __I2C_HandleTypeDef *hi2c); /*!< I2C Memory Tx Transfer completed callback */
+ void (* MemRxCpltCallback)(struct __I2C_HandleTypeDef *hi2c); /*!< I2C Memory Rx Transfer completed callback */
+ void (* ErrorCallback)(struct __I2C_HandleTypeDef *hi2c); /*!< I2C Error callback */
+ void (* AbortCpltCallback)(struct __I2C_HandleTypeDef *hi2c); /*!< I2C Abort callback */
+
+ void (* AddrCallback)(struct __I2C_HandleTypeDef *hi2c, uint8_t TransferDirection, uint16_t AddrMatchCode); /*!< I2C Slave Address Match callback */
+
+ void (* MspInitCallback)(struct __I2C_HandleTypeDef *hi2c); /*!< I2C Msp Init callback */
+ void (* MspDeInitCallback)(struct __I2C_HandleTypeDef *hi2c); /*!< I2C Msp DeInit callback */
+
+#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
+} I2C_HandleTypeDef;
+
+#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
+/**
+ * @brief HAL I2C Callback ID enumeration definition
+ */
+typedef enum
+{
+ HAL_I2C_MASTER_TX_COMPLETE_CB_ID = 0x00U, /*!< I2C Master Tx Transfer completed callback ID */
+ HAL_I2C_MASTER_RX_COMPLETE_CB_ID = 0x01U, /*!< I2C Master Rx Transfer completed callback ID */
+ HAL_I2C_SLAVE_TX_COMPLETE_CB_ID = 0x02U, /*!< I2C Slave Tx Transfer completed callback ID */
+ HAL_I2C_SLAVE_RX_COMPLETE_CB_ID = 0x03U, /*!< I2C Slave Rx Transfer completed callback ID */
+ HAL_I2C_LISTEN_COMPLETE_CB_ID = 0x04U, /*!< I2C Listen Complete callback ID */
+ HAL_I2C_MEM_TX_COMPLETE_CB_ID = 0x05U, /*!< I2C Memory Tx Transfer callback ID */
+ HAL_I2C_MEM_RX_COMPLETE_CB_ID = 0x06U, /*!< I2C Memory Rx Transfer completed callback ID */
+ HAL_I2C_ERROR_CB_ID = 0x07U, /*!< I2C Error callback ID */
+ HAL_I2C_ABORT_CB_ID = 0x08U, /*!< I2C Abort callback ID */
+
+ HAL_I2C_MSPINIT_CB_ID = 0x09U, /*!< I2C Msp Init callback ID */
+ HAL_I2C_MSPDEINIT_CB_ID = 0x0AU /*!< I2C Msp DeInit callback ID */
+
+} HAL_I2C_CallbackIDTypeDef;
+
+/**
+ * @brief HAL I2C Callback pointer definition
+ */
+typedef void (*pI2C_CallbackTypeDef)(I2C_HandleTypeDef *hi2c); /*!< pointer to an I2C callback function */
+typedef void (*pI2C_AddrCallbackTypeDef)(I2C_HandleTypeDef *hi2c, uint8_t TransferDirection, uint16_t AddrMatchCode); /*!< pointer to an I2C Address Match callback function */
+
+#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+/* Exported constants --------------------------------------------------------*/
+
+/** @defgroup I2C_Exported_Constants I2C Exported Constants
+ * @{
+ */
+
+/** @defgroup I2C_duty_cycle_in_fast_mode I2C duty cycle in fast mode
+ * @{
+ */
+#define I2C_DUTYCYCLE_2 0x00000000U
+#define I2C_DUTYCYCLE_16_9 I2C_CCR_DUTY
+/**
+ * @}
+ */
+
+/** @defgroup I2C_addressing_mode I2C addressing mode
+ * @{
+ */
+#define I2C_ADDRESSINGMODE_7BIT 0x00004000U
+#define I2C_ADDRESSINGMODE_10BIT (I2C_OAR1_ADDMODE | 0x00004000U)
+/**
+ * @}
+ */
+
+/** @defgroup I2C_dual_addressing_mode I2C dual addressing mode
+ * @{
+ */
+#define I2C_DUALADDRESS_DISABLE 0x00000000U
+#define I2C_DUALADDRESS_ENABLE I2C_OAR2_ENDUAL
+/**
+ * @}
+ */
+
+/** @defgroup I2C_general_call_addressing_mode I2C general call addressing mode
+ * @{
+ */
+#define I2C_GENERALCALL_DISABLE 0x00000000U
+#define I2C_GENERALCALL_ENABLE I2C_CR1_ENGC
+/**
+ * @}
+ */
+
+/** @defgroup I2C_nostretch_mode I2C nostretch mode
+ * @{
+ */
+#define I2C_NOSTRETCH_DISABLE 0x00000000U
+#define I2C_NOSTRETCH_ENABLE I2C_CR1_NOSTRETCH
+/**
+ * @}
+ */
+
+/** @defgroup I2C_Memory_Address_Size I2C Memory Address Size
+ * @{
+ */
+#define I2C_MEMADD_SIZE_8BIT 0x00000001U
+#define I2C_MEMADD_SIZE_16BIT 0x00000010U
+/**
+ * @}
+ */
+
+/** @defgroup I2C_XferDirection_definition I2C XferDirection definition
+ * @{
+ */
+#define I2C_DIRECTION_RECEIVE 0x00000000U
+#define I2C_DIRECTION_TRANSMIT 0x00000001U
+/**
+ * @}
+ */
+
+/** @defgroup I2C_XferOptions_definition I2C XferOptions definition
+ * @{
+ */
+#define I2C_FIRST_FRAME 0x00000001U
+#define I2C_FIRST_AND_NEXT_FRAME 0x00000002U
+#define I2C_NEXT_FRAME 0x00000004U
+#define I2C_FIRST_AND_LAST_FRAME 0x00000008U
+#define I2C_LAST_FRAME_NO_STOP 0x00000010U
+#define I2C_LAST_FRAME 0x00000020U
+
+/* List of XferOptions in usage of :
+ * 1- Restart condition in all use cases (direction change or not)
+ */
+#define I2C_OTHER_FRAME (0x00AA0000U)
+#define I2C_OTHER_AND_LAST_FRAME (0xAA000000U)
+/**
+ * @}
+ */
+
+/** @defgroup I2C_Interrupt_configuration_definition I2C Interrupt configuration definition
+ * @brief I2C Interrupt definition
+ * Elements values convention: 0xXXXXXXXX
+ * - XXXXXXXX : Interrupt control mask
+ * @{
+ */
+#define I2C_IT_BUF I2C_CR2_ITBUFEN
+#define I2C_IT_EVT I2C_CR2_ITEVTEN
+#define I2C_IT_ERR I2C_CR2_ITERREN
+/**
+ * @}
+ */
+
+/** @defgroup I2C_Flag_definition I2C Flag definition
+ * @{
+ */
+
+#define I2C_FLAG_OVR 0x00010800U
+#define I2C_FLAG_AF 0x00010400U
+#define I2C_FLAG_ARLO 0x00010200U
+#define I2C_FLAG_BERR 0x00010100U
+#define I2C_FLAG_TXE 0x00010080U
+#define I2C_FLAG_RXNE 0x00010040U
+#define I2C_FLAG_STOPF 0x00010010U
+#define I2C_FLAG_ADD10 0x00010008U
+#define I2C_FLAG_BTF 0x00010004U
+#define I2C_FLAG_ADDR 0x00010002U
+#define I2C_FLAG_SB 0x00010001U
+#define I2C_FLAG_DUALF 0x00100080U
+#define I2C_FLAG_GENCALL 0x00100010U
+#define I2C_FLAG_TRA 0x00100004U
+#define I2C_FLAG_BUSY 0x00100002U
+#define I2C_FLAG_MSL 0x00100001U
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Exported macros -----------------------------------------------------------*/
+
+/** @defgroup I2C_Exported_Macros I2C Exported Macros
+ * @{
+ */
+
+/** @brief Reset I2C handle state.
+ * @param __HANDLE__ specifies the I2C Handle.
+ * @retval None
+ */
+#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
+#define __HAL_I2C_RESET_HANDLE_STATE(__HANDLE__) do{ \
+ (__HANDLE__)->State = HAL_I2C_STATE_RESET; \
+ (__HANDLE__)->MspInitCallback = NULL; \
+ (__HANDLE__)->MspDeInitCallback = NULL; \
+ } while(0)
+#else
+#define __HAL_I2C_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_I2C_STATE_RESET)
+#endif
+
+/** @brief Enable or disable the specified I2C interrupts.
+ * @param __HANDLE__ specifies the I2C Handle.
+ * @param __INTERRUPT__ specifies the interrupt source to enable or disable.
+ * This parameter can be one of the following values:
+ * @arg I2C_IT_BUF: Buffer interrupt enable
+ * @arg I2C_IT_EVT: Event interrupt enable
+ * @arg I2C_IT_ERR: Error interrupt enable
+ * @retval None
+ */
+#define __HAL_I2C_ENABLE_IT(__HANDLE__, __INTERRUPT__) SET_BIT((__HANDLE__)->Instance->CR2,(__INTERRUPT__))
+#define __HAL_I2C_DISABLE_IT(__HANDLE__, __INTERRUPT__) CLEAR_BIT((__HANDLE__)->Instance->CR2, (__INTERRUPT__))
+
+/** @brief Checks if the specified I2C interrupt source is enabled or disabled.
+ * @param __HANDLE__ specifies the I2C Handle.
+ * @param __INTERRUPT__ specifies the I2C interrupt source to check.
+ * This parameter can be one of the following values:
+ * @arg I2C_IT_BUF: Buffer interrupt enable
+ * @arg I2C_IT_EVT: Event interrupt enable
+ * @arg I2C_IT_ERR: Error interrupt enable
+ * @retval The new state of __INTERRUPT__ (TRUE or FALSE).
+ */
+#define __HAL_I2C_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) ((((__HANDLE__)->Instance->CR2 & (__INTERRUPT__)) == (__INTERRUPT__)) ? SET : RESET)
+
+/** @brief Checks whether the specified I2C flag is set or not.
+ * @param __HANDLE__ specifies the I2C Handle.
+ * @param __FLAG__ specifies the flag to check.
+ * This parameter can be one of the following values:
+ * @arg I2C_FLAG_OVR: Overrun/Underrun flag
+ * @arg I2C_FLAG_AF: Acknowledge failure flag
+ * @arg I2C_FLAG_ARLO: Arbitration lost flag
+ * @arg I2C_FLAG_BERR: Bus error flag
+ * @arg I2C_FLAG_TXE: Data register empty flag
+ * @arg I2C_FLAG_RXNE: Data register not empty flag
+ * @arg I2C_FLAG_STOPF: Stop detection flag
+ * @arg I2C_FLAG_ADD10: 10-bit header sent flag
+ * @arg I2C_FLAG_BTF: Byte transfer finished flag
+ * @arg I2C_FLAG_ADDR: Address sent flag
+ * Address matched flag
+ * @arg I2C_FLAG_SB: Start bit flag
+ * @arg I2C_FLAG_DUALF: Dual flag
+ * @arg I2C_FLAG_GENCALL: General call header flag
+ * @arg I2C_FLAG_TRA: Transmitter/Receiver flag
+ * @arg I2C_FLAG_BUSY: Bus busy flag
+ * @arg I2C_FLAG_MSL: Master/Slave flag
+ * @retval The new state of __FLAG__ (TRUE or FALSE).
+ */
+#define __HAL_I2C_GET_FLAG(__HANDLE__, __FLAG__) ((((uint8_t)((__FLAG__) >> 16U)) == 0x01U) ? \
+ (((((__HANDLE__)->Instance->SR1) & ((__FLAG__) & I2C_FLAG_MASK)) == ((__FLAG__) & I2C_FLAG_MASK)) ? SET : RESET) : \
+ (((((__HANDLE__)->Instance->SR2) & ((__FLAG__) & I2C_FLAG_MASK)) == ((__FLAG__) & I2C_FLAG_MASK)) ? SET : RESET))
+
+/** @brief Clears the I2C pending flags which are cleared by writing 0 in a specific bit.
+ * @param __HANDLE__ specifies the I2C Handle.
+ * @param __FLAG__ specifies the flag to clear.
+ * This parameter can be any combination of the following values:
+ * @arg I2C_FLAG_OVR: Overrun/Underrun flag (Slave mode)
+ * @arg I2C_FLAG_AF: Acknowledge failure flag
+ * @arg I2C_FLAG_ARLO: Arbitration lost flag (Master mode)
+ * @arg I2C_FLAG_BERR: Bus error flag
+ * @retval None
+ */
+#define __HAL_I2C_CLEAR_FLAG(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->SR1 = ~((__FLAG__) & I2C_FLAG_MASK))
+
+/** @brief Clears the I2C ADDR pending flag.
+ * @param __HANDLE__ specifies the I2C Handle.
+ * This parameter can be I2C where x: 1, 2, or 3 to select the I2C peripheral.
+ * @retval None
+ */
+#define __HAL_I2C_CLEAR_ADDRFLAG(__HANDLE__) \
+ do{ \
+ __IO uint32_t tmpreg = 0x00U; \
+ tmpreg = (__HANDLE__)->Instance->SR1; \
+ tmpreg = (__HANDLE__)->Instance->SR2; \
+ UNUSED(tmpreg); \
+ } while(0)
+
+/** @brief Clears the I2C STOPF pending flag.
+ * @param __HANDLE__ specifies the I2C Handle.
+ * @retval None
+ */
+#define __HAL_I2C_CLEAR_STOPFLAG(__HANDLE__) \
+ do{ \
+ __IO uint32_t tmpreg = 0x00U; \
+ tmpreg = (__HANDLE__)->Instance->SR1; \
+ SET_BIT((__HANDLE__)->Instance->CR1, I2C_CR1_PE); \
+ UNUSED(tmpreg); \
+ } while(0)
+
+/** @brief Enable the specified I2C peripheral.
+ * @param __HANDLE__ specifies the I2C Handle.
+ * @retval None
+ */
+#define __HAL_I2C_ENABLE(__HANDLE__) SET_BIT((__HANDLE__)->Instance->CR1, I2C_CR1_PE)
+
+/** @brief Disable the specified I2C peripheral.
+ * @param __HANDLE__ specifies the I2C Handle.
+ * @retval None
+ */
+#define __HAL_I2C_DISABLE(__HANDLE__) CLEAR_BIT((__HANDLE__)->Instance->CR1, I2C_CR1_PE)
+
+/**
+ * @}
+ */
+
+/* Include I2C HAL Extension module */
+#include "stm32f4xx_hal_i2c_ex.h"
+
+/* Exported functions --------------------------------------------------------*/
+/** @addtogroup I2C_Exported_Functions
+ * @{
+ */
+
+/** @addtogroup I2C_Exported_Functions_Group1 Initialization and de-initialization functions
+ * @{
+ */
+/* Initialization and de-initialization functions******************************/
+HAL_StatusTypeDef HAL_I2C_Init(I2C_HandleTypeDef *hi2c);
+HAL_StatusTypeDef HAL_I2C_DeInit(I2C_HandleTypeDef *hi2c);
+void HAL_I2C_MspInit(I2C_HandleTypeDef *hi2c);
+void HAL_I2C_MspDeInit(I2C_HandleTypeDef *hi2c);
+
+/* Callbacks Register/UnRegister functions ***********************************/
+#if (USE_HAL_I2C_REGISTER_CALLBACKS == 1)
+HAL_StatusTypeDef HAL_I2C_RegisterCallback(I2C_HandleTypeDef *hi2c, HAL_I2C_CallbackIDTypeDef CallbackID, pI2C_CallbackTypeDef pCallback);
+HAL_StatusTypeDef HAL_I2C_UnRegisterCallback(I2C_HandleTypeDef *hi2c, HAL_I2C_CallbackIDTypeDef CallbackID);
+
+HAL_StatusTypeDef HAL_I2C_RegisterAddrCallback(I2C_HandleTypeDef *hi2c, pI2C_AddrCallbackTypeDef pCallback);
+HAL_StatusTypeDef HAL_I2C_UnRegisterAddrCallback(I2C_HandleTypeDef *hi2c);
+#endif /* USE_HAL_I2C_REGISTER_CALLBACKS */
+/**
+ * @}
+ */
+
+/** @addtogroup I2C_Exported_Functions_Group2 Input and Output operation functions
+ * @{
+ */
+/* IO operation functions ****************************************************/
+/******* Blocking mode: Polling */
+HAL_StatusTypeDef HAL_I2C_Master_Transmit(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout);
+HAL_StatusTypeDef HAL_I2C_Master_Receive(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout);
+HAL_StatusTypeDef HAL_I2C_Slave_Transmit(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t Timeout);
+HAL_StatusTypeDef HAL_I2C_Slave_Receive(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t Timeout);
+HAL_StatusTypeDef HAL_I2C_Mem_Write(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout);
+HAL_StatusTypeDef HAL_I2C_Mem_Read(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout);
+HAL_StatusTypeDef HAL_I2C_IsDeviceReady(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint32_t Trials, uint32_t Timeout);
+
+/******* Non-Blocking mode: Interrupt */
+HAL_StatusTypeDef HAL_I2C_Master_Transmit_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size);
+HAL_StatusTypeDef HAL_I2C_Master_Receive_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size);
+HAL_StatusTypeDef HAL_I2C_Slave_Transmit_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size);
+HAL_StatusTypeDef HAL_I2C_Slave_Receive_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size);
+HAL_StatusTypeDef HAL_I2C_Mem_Write_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size);
+HAL_StatusTypeDef HAL_I2C_Mem_Read_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size);
+
+HAL_StatusTypeDef HAL_I2C_Master_Seq_Transmit_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions);
+HAL_StatusTypeDef HAL_I2C_Master_Seq_Receive_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions);
+HAL_StatusTypeDef HAL_I2C_Slave_Seq_Transmit_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t XferOptions);
+HAL_StatusTypeDef HAL_I2C_Slave_Seq_Receive_IT(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t XferOptions);
+HAL_StatusTypeDef HAL_I2C_EnableListen_IT(I2C_HandleTypeDef *hi2c);
+HAL_StatusTypeDef HAL_I2C_DisableListen_IT(I2C_HandleTypeDef *hi2c);
+HAL_StatusTypeDef HAL_I2C_Master_Abort_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress);
+
+/******* Non-Blocking mode: DMA */
+HAL_StatusTypeDef HAL_I2C_Master_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size);
+HAL_StatusTypeDef HAL_I2C_Master_Receive_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size);
+HAL_StatusTypeDef HAL_I2C_Slave_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size);
+HAL_StatusTypeDef HAL_I2C_Slave_Receive_DMA(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size);
+HAL_StatusTypeDef HAL_I2C_Mem_Write_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size);
+HAL_StatusTypeDef HAL_I2C_Mem_Read_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size);
+
+HAL_StatusTypeDef HAL_I2C_Master_Seq_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions);
+HAL_StatusTypeDef HAL_I2C_Master_Seq_Receive_DMA(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t XferOptions);
+HAL_StatusTypeDef HAL_I2C_Slave_Seq_Transmit_DMA(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t XferOptions);
+HAL_StatusTypeDef HAL_I2C_Slave_Seq_Receive_DMA(I2C_HandleTypeDef *hi2c, uint8_t *pData, uint16_t Size, uint32_t XferOptions);
+/**
+ * @}
+ */
+
+/** @addtogroup I2C_IRQ_Handler_and_Callbacks IRQ Handler and Callbacks
+ * @{
+ */
+/******* I2C IRQHandler and Callbacks used in non blocking modes (Interrupt and DMA) */
+void HAL_I2C_EV_IRQHandler(I2C_HandleTypeDef *hi2c);
+void HAL_I2C_ER_IRQHandler(I2C_HandleTypeDef *hi2c);
+void HAL_I2C_MasterTxCpltCallback(I2C_HandleTypeDef *hi2c);
+void HAL_I2C_MasterRxCpltCallback(I2C_HandleTypeDef *hi2c);
+void HAL_I2C_SlaveTxCpltCallback(I2C_HandleTypeDef *hi2c);
+void HAL_I2C_SlaveRxCpltCallback(I2C_HandleTypeDef *hi2c);
+void HAL_I2C_AddrCallback(I2C_HandleTypeDef *hi2c, uint8_t TransferDirection, uint16_t AddrMatchCode);
+void HAL_I2C_ListenCpltCallback(I2C_HandleTypeDef *hi2c);
+void HAL_I2C_MemTxCpltCallback(I2C_HandleTypeDef *hi2c);
+void HAL_I2C_MemRxCpltCallback(I2C_HandleTypeDef *hi2c);
+void HAL_I2C_ErrorCallback(I2C_HandleTypeDef *hi2c);
+void HAL_I2C_AbortCpltCallback(I2C_HandleTypeDef *hi2c);
+/**
+ * @}
+ */
+
+/** @addtogroup I2C_Exported_Functions_Group3 Peripheral State, Mode and Error functions
+ * @{
+ */
+/* Peripheral State, Mode and Error functions *********************************/
+HAL_I2C_StateTypeDef HAL_I2C_GetState(I2C_HandleTypeDef *hi2c);
+HAL_I2C_ModeTypeDef HAL_I2C_GetMode(I2C_HandleTypeDef *hi2c);
+uint32_t HAL_I2C_GetError(I2C_HandleTypeDef *hi2c);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+/* Private types -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private constants ---------------------------------------------------------*/
+/** @defgroup I2C_Private_Constants I2C Private Constants
+ * @{
+ */
+#define I2C_FLAG_MASK 0x0000FFFFU
+#define I2C_MIN_PCLK_FREQ_STANDARD 2000000U /*!< 2 MHz */
+#define I2C_MIN_PCLK_FREQ_FAST 4000000U /*!< 4 MHz */
+/**
+ * @}
+ */
+
+/* Private macros ------------------------------------------------------------*/
+/** @defgroup I2C_Private_Macros I2C Private Macros
+ * @{
+ */
+
+#define I2C_MIN_PCLK_FREQ(__PCLK__, __SPEED__) (((__SPEED__) <= 100000U) ? ((__PCLK__) < I2C_MIN_PCLK_FREQ_STANDARD) : ((__PCLK__) < I2C_MIN_PCLK_FREQ_FAST))
+#define I2C_CCR_CALCULATION(__PCLK__, __SPEED__, __COEFF__) (((((__PCLK__) - 1U)/((__SPEED__) * (__COEFF__))) + 1U) & I2C_CCR_CCR)
+#define I2C_FREQRANGE(__PCLK__) ((__PCLK__)/1000000U)
+#define I2C_RISE_TIME(__FREQRANGE__, __SPEED__) (((__SPEED__) <= 100000U) ? ((__FREQRANGE__) + 1U) : ((((__FREQRANGE__) * 300U) / 1000U) + 1U))
+#define I2C_SPEED_STANDARD(__PCLK__, __SPEED__) ((I2C_CCR_CALCULATION((__PCLK__), (__SPEED__), 2U) < 4U)? 4U:I2C_CCR_CALCULATION((__PCLK__), (__SPEED__), 2U))
+#define I2C_SPEED_FAST(__PCLK__, __SPEED__, __DUTYCYCLE__) (((__DUTYCYCLE__) == I2C_DUTYCYCLE_2)? I2C_CCR_CALCULATION((__PCLK__), (__SPEED__), 3U) : (I2C_CCR_CALCULATION((__PCLK__), (__SPEED__), 25U) | I2C_DUTYCYCLE_16_9))
+#define I2C_SPEED(__PCLK__, __SPEED__, __DUTYCYCLE__) (((__SPEED__) <= 100000U)? (I2C_SPEED_STANDARD((__PCLK__), (__SPEED__))) : \
+ ((I2C_SPEED_FAST((__PCLK__), (__SPEED__), (__DUTYCYCLE__)) & I2C_CCR_CCR) == 0U)? 1U : \
+ ((I2C_SPEED_FAST((__PCLK__), (__SPEED__), (__DUTYCYCLE__))) | I2C_CCR_FS))
+
+#define I2C_7BIT_ADD_WRITE(__ADDRESS__) ((uint8_t)((__ADDRESS__) & (uint8_t)(~I2C_OAR1_ADD0)))
+#define I2C_7BIT_ADD_READ(__ADDRESS__) ((uint8_t)((__ADDRESS__) | I2C_OAR1_ADD0))
+
+#define I2C_10BIT_ADDRESS(__ADDRESS__) ((uint8_t)((uint16_t)((__ADDRESS__) & (uint16_t)0x00FF)))
+#define I2C_10BIT_HEADER_WRITE(__ADDRESS__) ((uint8_t)((uint16_t)((uint16_t)(((uint16_t)((__ADDRESS__) & (uint16_t)0x0300)) >> 7) | (uint16_t)0x00F0)))
+#define I2C_10BIT_HEADER_READ(__ADDRESS__) ((uint8_t)((uint16_t)((uint16_t)(((uint16_t)((__ADDRESS__) & (uint16_t)0x0300)) >> 7) | (uint16_t)(0x00F1))))
+
+#define I2C_MEM_ADD_MSB(__ADDRESS__) ((uint8_t)((uint16_t)(((uint16_t)((__ADDRESS__) & (uint16_t)0xFF00)) >> 8)))
+#define I2C_MEM_ADD_LSB(__ADDRESS__) ((uint8_t)((uint16_t)((__ADDRESS__) & (uint16_t)0x00FF)))
+
+/** @defgroup I2C_IS_RTC_Definitions I2C Private macros to check input parameters
+ * @{
+ */
+#define IS_I2C_DUTY_CYCLE(CYCLE) (((CYCLE) == I2C_DUTYCYCLE_2) || \
+ ((CYCLE) == I2C_DUTYCYCLE_16_9))
+#define IS_I2C_ADDRESSING_MODE(ADDRESS) (((ADDRESS) == I2C_ADDRESSINGMODE_7BIT) || \
+ ((ADDRESS) == I2C_ADDRESSINGMODE_10BIT))
+#define IS_I2C_DUAL_ADDRESS(ADDRESS) (((ADDRESS) == I2C_DUALADDRESS_DISABLE) || \
+ ((ADDRESS) == I2C_DUALADDRESS_ENABLE))
+#define IS_I2C_GENERAL_CALL(CALL) (((CALL) == I2C_GENERALCALL_DISABLE) || \
+ ((CALL) == I2C_GENERALCALL_ENABLE))
+#define IS_I2C_NO_STRETCH(STRETCH) (((STRETCH) == I2C_NOSTRETCH_DISABLE) || \
+ ((STRETCH) == I2C_NOSTRETCH_ENABLE))
+#define IS_I2C_MEMADD_SIZE(SIZE) (((SIZE) == I2C_MEMADD_SIZE_8BIT) || \
+ ((SIZE) == I2C_MEMADD_SIZE_16BIT))
+#define IS_I2C_CLOCK_SPEED(SPEED) (((SPEED) > 0U) && ((SPEED) <= 400000U))
+#define IS_I2C_OWN_ADDRESS1(ADDRESS1) (((ADDRESS1) & 0xFFFFFC00U) == 0U)
+#define IS_I2C_OWN_ADDRESS2(ADDRESS2) (((ADDRESS2) & 0xFFFFFF01U) == 0U)
+#define IS_I2C_TRANSFER_OPTIONS_REQUEST(REQUEST) (((REQUEST) == I2C_FIRST_FRAME) || \
+ ((REQUEST) == I2C_FIRST_AND_NEXT_FRAME) || \
+ ((REQUEST) == I2C_NEXT_FRAME) || \
+ ((REQUEST) == I2C_FIRST_AND_LAST_FRAME) || \
+ ((REQUEST) == I2C_LAST_FRAME) || \
+ ((REQUEST) == I2C_LAST_FRAME_NO_STOP) || \
+ IS_I2C_TRANSFER_OTHER_OPTIONS_REQUEST(REQUEST))
+
+#define IS_I2C_TRANSFER_OTHER_OPTIONS_REQUEST(REQUEST) (((REQUEST) == I2C_OTHER_FRAME) || \
+ ((REQUEST) == I2C_OTHER_AND_LAST_FRAME))
+
+#define I2C_CHECK_FLAG(__ISR__, __FLAG__) ((((__ISR__) & ((__FLAG__) & I2C_FLAG_MASK)) == ((__FLAG__) & I2C_FLAG_MASK)) ? SET : RESET)
+#define I2C_CHECK_IT_SOURCE(__CR1__, __IT__) ((((__CR1__) & (__IT__)) == (__IT__)) ? SET : RESET)
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Private functions ---------------------------------------------------------*/
+/** @defgroup I2C_Private_Functions I2C Private Functions
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* __STM32F4xx_HAL_I2C_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/port/stm32-f4discovery-cc256x-2/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_i2c_ex.h b/port/stm32-f4discovery-cc256x-2/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_i2c_ex.h
new file mode 100644
index 000000000..d98cea33b
--- /dev/null
+++ b/port/stm32-f4discovery-cc256x-2/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_i2c_ex.h
@@ -0,0 +1,117 @@
+/**
+ ******************************************************************************
+ * @file stm32f4xx_hal_i2c_ex.h
+ * @author MCD Application Team
+ * @brief Header file of I2C HAL Extension module.
+ ******************************************************************************
+ * @attention
+ *
+ * © Copyright (c) 2016 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software component is licensed by ST under BSD 3-Clause license,
+ * the "License"; You may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ * opensource.org/licenses/BSD-3-Clause
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __STM32F4xx_HAL_I2C_EX_H
+#define __STM32F4xx_HAL_I2C_EX_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(I2C_FLTR_ANOFF)&&defined(I2C_FLTR_DNF)
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f4xx_hal_def.h"
+
+/** @addtogroup STM32F4xx_HAL_Driver
+ * @{
+ */
+
+/** @addtogroup I2CEx
+ * @{
+ */
+
+/* Exported types ------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+/** @defgroup I2CEx_Exported_Constants I2C Exported Constants
+ * @{
+ */
+
+/** @defgroup I2CEx_Analog_Filter I2C Analog Filter
+ * @{
+ */
+#define I2C_ANALOGFILTER_ENABLE 0x00000000U
+#define I2C_ANALOGFILTER_DISABLE I2C_FLTR_ANOFF
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Exported macro ------------------------------------------------------------*/
+/* Exported functions --------------------------------------------------------*/
+/** @addtogroup I2CEx_Exported_Functions
+ * @{
+ */
+
+/** @addtogroup I2CEx_Exported_Functions_Group1
+ * @{
+ */
+/* Peripheral Control functions ************************************************/
+HAL_StatusTypeDef HAL_I2CEx_ConfigAnalogFilter(I2C_HandleTypeDef *hi2c, uint32_t AnalogFilter);
+HAL_StatusTypeDef HAL_I2CEx_ConfigDigitalFilter(I2C_HandleTypeDef *hi2c, uint32_t DigitalFilter);
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+/* Private types -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private constants ---------------------------------------------------------*/
+/** @defgroup I2CEx_Private_Constants I2C Private Constants
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/* Private macros ------------------------------------------------------------*/
+/** @defgroup I2CEx_Private_Macros I2C Private Macros
+ * @{
+ */
+#define IS_I2C_ANALOG_FILTER(FILTER) (((FILTER) == I2C_ANALOGFILTER_ENABLE) || \
+ ((FILTER) == I2C_ANALOGFILTER_DISABLE))
+#define IS_I2C_DIGITAL_FILTER(FILTER) ((FILTER) <= 0x0000000FU)
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __STM32F4xx_HAL_I2C_EX_H */
+
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/port/stm32-f4discovery-cc256x-2/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_i2s.h b/port/stm32-f4discovery-cc256x-2/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_i2s.h
new file mode 100644
index 000000000..a0515e0dd
--- /dev/null
+++ b/port/stm32-f4discovery-cc256x-2/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_i2s.h
@@ -0,0 +1,613 @@
+/**
+ ******************************************************************************
+ * @file stm32f4xx_hal_i2s.h
+ * @author MCD Application Team
+ * @brief Header file of I2S HAL module.
+ ******************************************************************************
+ * @attention
+ *
+ * © Copyright (c) 2016 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software component is licensed by ST under BSD 3-Clause license,
+ * the "License"; You may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ * opensource.org/licenses/BSD-3-Clause
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef STM32F4xx_HAL_I2S_H
+#define STM32F4xx_HAL_I2S_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f4xx_hal_def.h"
+
+/** @addtogroup STM32F4xx_HAL_Driver
+ * @{
+ */
+
+/** @addtogroup I2S
+ * @{
+ */
+
+/* Exported types ------------------------------------------------------------*/
+/** @defgroup I2S_Exported_Types I2S Exported Types
+ * @{
+ */
+
+/**
+ * @brief I2S Init structure definition
+ */
+typedef struct
+{
+ uint32_t Mode; /*!< Specifies the I2S operating mode.
+ This parameter can be a value of @ref I2S_Mode */
+
+ uint32_t Standard; /*!< Specifies the standard used for the I2S communication.
+ This parameter can be a value of @ref I2S_Standard */
+
+ uint32_t DataFormat; /*!< Specifies the data format for the I2S communication.
+ This parameter can be a value of @ref I2S_Data_Format */
+
+ uint32_t MCLKOutput; /*!< Specifies whether the I2S MCLK output is enabled or not.
+ This parameter can be a value of @ref I2S_MCLK_Output */
+
+ uint32_t AudioFreq; /*!< Specifies the frequency selected for the I2S communication.
+ This parameter can be a value of @ref I2S_Audio_Frequency */
+
+ uint32_t CPOL; /*!< Specifies the idle state of the I2S clock.
+ This parameter can be a value of @ref I2S_Clock_Polarity */
+
+ uint32_t ClockSource; /*!< Specifies the I2S Clock Source.
+ This parameter can be a value of @ref I2S_Clock_Source */
+ uint32_t FullDuplexMode; /*!< Specifies the I2S FullDuplex mode.
+ This parameter can be a value of @ref I2S_FullDuplex_Mode */
+} I2S_InitTypeDef;
+
+/**
+ * @brief HAL State structures definition
+ */
+typedef enum
+{
+ HAL_I2S_STATE_RESET = 0x00U, /*!< I2S not yet initialized or disabled */
+ HAL_I2S_STATE_READY = 0x01U, /*!< I2S initialized and ready for use */
+ HAL_I2S_STATE_BUSY = 0x02U, /*!< I2S internal process is ongoing */
+ HAL_I2S_STATE_BUSY_TX = 0x03U, /*!< Data Transmission process is ongoing */
+ HAL_I2S_STATE_BUSY_RX = 0x04U, /*!< Data Reception process is ongoing */
+ HAL_I2S_STATE_BUSY_TX_RX = 0x05U, /*!< Data Transmission and Reception process is ongoing */
+ HAL_I2S_STATE_TIMEOUT = 0x06U, /*!< I2S timeout state */
+ HAL_I2S_STATE_ERROR = 0x07U /*!< I2S error state */
+} HAL_I2S_StateTypeDef;
+
+/**
+ * @brief I2S handle Structure definition
+ */
+typedef struct __I2S_HandleTypeDef
+{
+ SPI_TypeDef *Instance; /*!< I2S registers base address */
+
+ I2S_InitTypeDef Init; /*!< I2S communication parameters */
+
+ uint16_t *pTxBuffPtr; /*!< Pointer to I2S Tx transfer buffer */
+
+ __IO uint16_t TxXferSize; /*!< I2S Tx transfer size */
+
+ __IO uint16_t TxXferCount; /*!< I2S Tx transfer Counter */
+
+ uint16_t *pRxBuffPtr; /*!< Pointer to I2S Rx transfer buffer */
+
+ __IO uint16_t RxXferSize; /*!< I2S Rx transfer size */
+
+ __IO uint16_t RxXferCount; /*!< I2S Rx transfer counter
+ (This field is initialized at the
+ same value as transfer size at the
+ beginning of the transfer and
+ decremented when a sample is received
+ NbSamplesReceived = RxBufferSize-RxBufferCount) */
+ void (*IrqHandlerISR)(struct __I2S_HandleTypeDef *hi2s); /*!< I2S function pointer on IrqHandler */
+
+ DMA_HandleTypeDef *hdmatx; /*!< I2S Tx DMA handle parameters */
+
+ DMA_HandleTypeDef *hdmarx; /*!< I2S Rx DMA handle parameters */
+
+ __IO HAL_LockTypeDef Lock; /*!< I2S locking object */
+
+ __IO HAL_I2S_StateTypeDef State; /*!< I2S communication state */
+
+ __IO uint32_t ErrorCode; /*!< I2S Error code
+ This parameter can be a value of @ref I2S_Error */
+
+#if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
+ void (* TxCpltCallback)(struct __I2S_HandleTypeDef *hi2s); /*!< I2S Tx Completed callback */
+ void (* RxCpltCallback)(struct __I2S_HandleTypeDef *hi2s); /*!< I2S Rx Completed callback */
+ void (* TxRxCpltCallback)(struct __I2S_HandleTypeDef *hi2s); /*!< I2S TxRx Completed callback */
+ void (* TxHalfCpltCallback)(struct __I2S_HandleTypeDef *hi2s); /*!< I2S Tx Half Completed callback */
+ void (* RxHalfCpltCallback)(struct __I2S_HandleTypeDef *hi2s); /*!< I2S Rx Half Completed callback */
+ void (* TxRxHalfCpltCallback)(struct __I2S_HandleTypeDef *hi2s); /*!< I2S TxRx Half Completed callback */
+ void (* ErrorCallback)(struct __I2S_HandleTypeDef *hi2s); /*!< I2S Error callback */
+ void (* MspInitCallback)(struct __I2S_HandleTypeDef *hi2s); /*!< I2S Msp Init callback */
+ void (* MspDeInitCallback)(struct __I2S_HandleTypeDef *hi2s); /*!< I2S Msp DeInit callback */
+
+#endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
+} I2S_HandleTypeDef;
+
+#if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
+/**
+ * @brief HAL I2S Callback ID enumeration definition
+ */
+typedef enum
+{
+ HAL_I2S_TX_COMPLETE_CB_ID = 0x00U, /*!< I2S Tx Completed callback ID */
+ HAL_I2S_RX_COMPLETE_CB_ID = 0x01U, /*!< I2S Rx Completed callback ID */
+ HAL_I2S_TX_RX_COMPLETE_CB_ID = 0x02U, /*!< I2S TxRx Completed callback ID */
+ HAL_I2S_TX_HALF_COMPLETE_CB_ID = 0x03U, /*!< I2S Tx Half Completed callback ID */
+ HAL_I2S_RX_HALF_COMPLETE_CB_ID = 0x04U, /*!< I2S Rx Half Completed callback ID */
+ HAL_I2S_TX_RX_HALF_COMPLETE_CB_ID = 0x05U, /*!< I2S TxRx Half Completed callback ID */
+ HAL_I2S_ERROR_CB_ID = 0x06U, /*!< I2S Error callback ID */
+ HAL_I2S_MSPINIT_CB_ID = 0x07U, /*!< I2S Msp Init callback ID */
+ HAL_I2S_MSPDEINIT_CB_ID = 0x08U /*!< I2S Msp DeInit callback ID */
+
+} HAL_I2S_CallbackIDTypeDef;
+
+/**
+ * @brief HAL I2S Callback pointer definition
+ */
+typedef void (*pI2S_CallbackTypeDef)(I2S_HandleTypeDef *hi2s); /*!< pointer to an I2S callback function */
+
+#endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
+/**
+ * @}
+ */
+
+/* Exported constants --------------------------------------------------------*/
+/** @defgroup I2S_Exported_Constants I2S Exported Constants
+ * @{
+ */
+/** @defgroup I2S_Error I2S Error
+ * @{
+ */
+#define HAL_I2S_ERROR_NONE (0x00000000U) /*!< No error */
+#define HAL_I2S_ERROR_TIMEOUT (0x00000001U) /*!< Timeout error */
+#define HAL_I2S_ERROR_OVR (0x00000002U) /*!< OVR error */
+#define HAL_I2S_ERROR_UDR (0x00000004U) /*!< UDR error */
+#define HAL_I2S_ERROR_DMA (0x00000008U) /*!< DMA transfer error */
+#define HAL_I2S_ERROR_PRESCALER (0x00000010U) /*!< Prescaler Calculation error */
+#if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
+#define HAL_I2S_ERROR_INVALID_CALLBACK (0x00000020U) /*!< Invalid Callback error */
+#endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
+/**
+ * @}
+ */
+
+/** @defgroup I2S_Mode I2S Mode
+ * @{
+ */
+#define I2S_MODE_SLAVE_TX (0x00000000U)
+#define I2S_MODE_SLAVE_RX (SPI_I2SCFGR_I2SCFG_0)
+#define I2S_MODE_MASTER_TX (SPI_I2SCFGR_I2SCFG_1)
+#define I2S_MODE_MASTER_RX ((SPI_I2SCFGR_I2SCFG_0 | SPI_I2SCFGR_I2SCFG_1))
+/**
+ * @}
+ */
+
+/** @defgroup I2S_Standard I2S Standard
+ * @{
+ */
+#define I2S_STANDARD_PHILIPS (0x00000000U)
+#define I2S_STANDARD_MSB (SPI_I2SCFGR_I2SSTD_0)
+#define I2S_STANDARD_LSB (SPI_I2SCFGR_I2SSTD_1)
+#define I2S_STANDARD_PCM_SHORT ((SPI_I2SCFGR_I2SSTD_0 | SPI_I2SCFGR_I2SSTD_1))
+#define I2S_STANDARD_PCM_LONG ((SPI_I2SCFGR_I2SSTD_0 | SPI_I2SCFGR_I2SSTD_1 | SPI_I2SCFGR_PCMSYNC))
+/**
+ * @}
+ */
+
+/** @defgroup I2S_Data_Format I2S Data Format
+ * @{
+ */
+#define I2S_DATAFORMAT_16B (0x00000000U)
+#define I2S_DATAFORMAT_16B_EXTENDED (SPI_I2SCFGR_CHLEN)
+#define I2S_DATAFORMAT_24B ((SPI_I2SCFGR_CHLEN | SPI_I2SCFGR_DATLEN_0))
+#define I2S_DATAFORMAT_32B ((SPI_I2SCFGR_CHLEN | SPI_I2SCFGR_DATLEN_1))
+/**
+ * @}
+ */
+
+/** @defgroup I2S_MCLK_Output I2S MCLK Output
+ * @{
+ */
+#define I2S_MCLKOUTPUT_ENABLE (SPI_I2SPR_MCKOE)
+#define I2S_MCLKOUTPUT_DISABLE (0x00000000U)
+/**
+ * @}
+ */
+
+/** @defgroup I2S_Audio_Frequency I2S Audio Frequency
+ * @{
+ */
+#define I2S_AUDIOFREQ_192K (192000U)
+#define I2S_AUDIOFREQ_96K (96000U)
+#define I2S_AUDIOFREQ_48K (48000U)
+#define I2S_AUDIOFREQ_44K (44100U)
+#define I2S_AUDIOFREQ_32K (32000U)
+#define I2S_AUDIOFREQ_22K (22050U)
+#define I2S_AUDIOFREQ_16K (16000U)
+#define I2S_AUDIOFREQ_11K (11025U)
+#define I2S_AUDIOFREQ_8K (8000U)
+#define I2S_AUDIOFREQ_DEFAULT (2U)
+/**
+ * @}
+ */
+
+/** @defgroup I2S_FullDuplex_Mode I2S FullDuplex Mode
+ * @{
+ */
+#define I2S_FULLDUPLEXMODE_DISABLE (0x00000000U)
+#define I2S_FULLDUPLEXMODE_ENABLE (0x00000001U)
+/**
+ * @}
+ */
+
+/** @defgroup I2S_Clock_Polarity I2S Clock Polarity
+ * @{
+ */
+#define I2S_CPOL_LOW (0x00000000U)
+#define I2S_CPOL_HIGH (SPI_I2SCFGR_CKPOL)
+/**
+ * @}
+ */
+
+/** @defgroup I2S_Interrupts_Definition I2S Interrupts Definition
+ * @{
+ */
+#define I2S_IT_TXE SPI_CR2_TXEIE
+#define I2S_IT_RXNE SPI_CR2_RXNEIE
+#define I2S_IT_ERR SPI_CR2_ERRIE
+/**
+ * @}
+ */
+
+/** @defgroup I2S_Flags_Definition I2S Flags Definition
+ * @{
+ */
+#define I2S_FLAG_TXE SPI_SR_TXE
+#define I2S_FLAG_RXNE SPI_SR_RXNE
+
+#define I2S_FLAG_UDR SPI_SR_UDR
+#define I2S_FLAG_OVR SPI_SR_OVR
+#define I2S_FLAG_FRE SPI_SR_FRE
+
+#define I2S_FLAG_CHSIDE SPI_SR_CHSIDE
+#define I2S_FLAG_BSY SPI_SR_BSY
+
+#define I2S_FLAG_MASK (SPI_SR_RXNE | SPI_SR_TXE | SPI_SR_UDR | SPI_SR_OVR | SPI_SR_FRE | SPI_SR_CHSIDE | SPI_SR_BSY)
+/**
+ * @}
+ */
+
+/** @defgroup I2S_Clock_Source I2S Clock Source Definition
+ * @{
+ */
+#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx) || defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) || defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F411xE) || defined(STM32F469xx) || defined(STM32F479xx)
+#define I2S_CLOCK_PLL (0x00000000U)
+#define I2S_CLOCK_EXTERNAL (0x00000001U)
+#endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx || STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx ||
+ STM32F401xC || STM32F401xE || STM32F411xE || STM32F469xx || STM32F479xx */
+
+#if defined(STM32F446xx) || defined(STM32F412Zx) || defined(STM32F412Vx) || defined(STM32F412Rx) || defined(STM32F412Cx) || defined(STM32F413xx) || defined(STM32F423xx)
+#define I2S_CLOCK_PLL (0x00000000U)
+#define I2S_CLOCK_EXTERNAL (0x00000001U)
+#define I2S_CLOCK_PLLR (0x00000002U)
+#define I2S_CLOCK_PLLSRC (0x00000003U)
+#endif /* STM32F446xx || STM32F412Zx || STM32F412Vx || STM32F412Rx || STM32F412Cx || STM32F413xx || STM32F423xx */
+
+#if defined(STM32F410Tx) || defined(STM32F410Cx) || defined(STM32F410Rx)
+#define I2S_CLOCK_PLLSRC (0x00000000U)
+#define I2S_CLOCK_EXTERNAL (0x00000001U)
+#define I2S_CLOCK_PLLR (0x00000002U)
+#endif /* STM32F410Tx || STM32F410Cx || STM32F410Rx */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Exported macros -----------------------------------------------------------*/
+/** @defgroup I2S_Exported_macros I2S Exported Macros
+ * @{
+ */
+
+/** @brief Reset I2S handle state
+ * @param __HANDLE__ specifies the I2S Handle.
+ * @retval None
+ */
+#if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
+#define __HAL_I2S_RESET_HANDLE_STATE(__HANDLE__) do{ \
+ (__HANDLE__)->State = HAL_I2S_STATE_RESET; \
+ (__HANDLE__)->MspInitCallback = NULL; \
+ (__HANDLE__)->MspDeInitCallback = NULL; \
+ } while(0)
+#else
+#define __HAL_I2S_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_I2S_STATE_RESET)
+#endif
+
+/** @brief Enable the specified SPI peripheral (in I2S mode).
+ * @param __HANDLE__ specifies the I2S Handle.
+ * @retval None
+ */
+#define __HAL_I2S_ENABLE(__HANDLE__) (SET_BIT((__HANDLE__)->Instance->I2SCFGR, SPI_I2SCFGR_I2SE))
+
+/** @brief Disable the specified SPI peripheral (in I2S mode).
+ * @param __HANDLE__ specifies the I2S Handle.
+ * @retval None
+ */
+#define __HAL_I2S_DISABLE(__HANDLE__) (CLEAR_BIT((__HANDLE__)->Instance->I2SCFGR, SPI_I2SCFGR_I2SE))
+
+/** @brief Enable the specified I2S interrupts.
+ * @param __HANDLE__ specifies the I2S Handle.
+ * @param __INTERRUPT__ specifies the interrupt source to enable or disable.
+ * This parameter can be one of the following values:
+ * @arg I2S_IT_TXE: Tx buffer empty interrupt enable
+ * @arg I2S_IT_RXNE: RX buffer not empty interrupt enable
+ * @arg I2S_IT_ERR: Error interrupt enable
+ * @retval None
+ */
+#define __HAL_I2S_ENABLE_IT(__HANDLE__, __INTERRUPT__) (SET_BIT((__HANDLE__)->Instance->CR2,(__INTERRUPT__)))
+
+/** @brief Disable the specified I2S interrupts.
+ * @param __HANDLE__ specifies the I2S Handle.
+ * @param __INTERRUPT__ specifies the interrupt source to enable or disable.
+ * This parameter can be one of the following values:
+ * @arg I2S_IT_TXE: Tx buffer empty interrupt enable
+ * @arg I2S_IT_RXNE: RX buffer not empty interrupt enable
+ * @arg I2S_IT_ERR: Error interrupt enable
+ * @retval None
+ */
+#define __HAL_I2S_DISABLE_IT(__HANDLE__, __INTERRUPT__) (CLEAR_BIT((__HANDLE__)->Instance->CR2,(__INTERRUPT__)))
+
+/** @brief Checks if the specified I2S interrupt source is enabled or disabled.
+ * @param __HANDLE__ specifies the I2S Handle.
+ * This parameter can be I2S where x: 1, 2, or 3 to select the I2S peripheral.
+ * @param __INTERRUPT__ specifies the I2S interrupt source to check.
+ * This parameter can be one of the following values:
+ * @arg I2S_IT_TXE: Tx buffer empty interrupt enable
+ * @arg I2S_IT_RXNE: RX buffer not empty interrupt enable
+ * @arg I2S_IT_ERR: Error interrupt enable
+ * @retval The new state of __IT__ (TRUE or FALSE).
+ */
+#define __HAL_I2S_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) ((((__HANDLE__)->Instance->CR2 & (__INTERRUPT__)) == (__INTERRUPT__)) ? SET : RESET)
+
+/** @brief Checks whether the specified I2S flag is set or not.
+ * @param __HANDLE__ specifies the I2S Handle.
+ * @param __FLAG__ specifies the flag to check.
+ * This parameter can be one of the following values:
+ * @arg I2S_FLAG_RXNE: Receive buffer not empty flag
+ * @arg I2S_FLAG_TXE: Transmit buffer empty flag
+ * @arg I2S_FLAG_UDR: Underrun flag
+ * @arg I2S_FLAG_OVR: Overrun flag
+ * @arg I2S_FLAG_FRE: Frame error flag
+ * @arg I2S_FLAG_CHSIDE: Channel Side flag
+ * @arg I2S_FLAG_BSY: Busy flag
+ * @retval The new state of __FLAG__ (TRUE or FALSE).
+ */
+#define __HAL_I2S_GET_FLAG(__HANDLE__, __FLAG__) ((((__HANDLE__)->Instance->SR) & (__FLAG__)) == (__FLAG__))
+
+/** @brief Clears the I2S OVR pending flag.
+ * @param __HANDLE__ specifies the I2S Handle.
+ * @retval None
+ */
+#define __HAL_I2S_CLEAR_OVRFLAG(__HANDLE__) do{ \
+ __IO uint32_t tmpreg_ovr = 0x00U; \
+ tmpreg_ovr = (__HANDLE__)->Instance->DR; \
+ tmpreg_ovr = (__HANDLE__)->Instance->SR; \
+ UNUSED(tmpreg_ovr); \
+ }while(0U)
+/** @brief Clears the I2S UDR pending flag.
+ * @param __HANDLE__ specifies the I2S Handle.
+ * @retval None
+ */
+#define __HAL_I2S_CLEAR_UDRFLAG(__HANDLE__) do{\
+ __IO uint32_t tmpreg_udr = 0x00U;\
+ tmpreg_udr = ((__HANDLE__)->Instance->SR);\
+ UNUSED(tmpreg_udr); \
+ }while(0U)
+/**
+ * @}
+ */
+
+/* Include I2S Extension module */
+#include "stm32f4xx_hal_i2s_ex.h"
+
+/* Exported functions --------------------------------------------------------*/
+/** @addtogroup I2S_Exported_Functions
+ * @{
+ */
+
+/** @addtogroup I2S_Exported_Functions_Group1
+ * @{
+ */
+/* Initialization/de-initialization functions ********************************/
+HAL_StatusTypeDef HAL_I2S_Init(I2S_HandleTypeDef *hi2s);
+HAL_StatusTypeDef HAL_I2S_DeInit(I2S_HandleTypeDef *hi2s);
+void HAL_I2S_MspInit(I2S_HandleTypeDef *hi2s);
+void HAL_I2S_MspDeInit(I2S_HandleTypeDef *hi2s);
+
+/* Callbacks Register/UnRegister functions ***********************************/
+#if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
+HAL_StatusTypeDef HAL_I2S_RegisterCallback(I2S_HandleTypeDef *hi2s, HAL_I2S_CallbackIDTypeDef CallbackID, pI2S_CallbackTypeDef pCallback);
+HAL_StatusTypeDef HAL_I2S_UnRegisterCallback(I2S_HandleTypeDef *hi2s, HAL_I2S_CallbackIDTypeDef CallbackID);
+#endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
+/**
+ * @}
+ */
+
+/** @addtogroup I2S_Exported_Functions_Group2
+ * @{
+ */
+/* I/O operation functions ***************************************************/
+/* Blocking mode: Polling */
+HAL_StatusTypeDef HAL_I2S_Transmit(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size, uint32_t Timeout);
+HAL_StatusTypeDef HAL_I2S_Receive(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size, uint32_t Timeout);
+
+/* Non-Blocking mode: Interrupt */
+HAL_StatusTypeDef HAL_I2S_Transmit_IT(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size);
+HAL_StatusTypeDef HAL_I2S_Receive_IT(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size);
+void HAL_I2S_IRQHandler(I2S_HandleTypeDef *hi2s);
+
+/* Non-Blocking mode: DMA */
+HAL_StatusTypeDef HAL_I2S_Transmit_DMA(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size);
+HAL_StatusTypeDef HAL_I2S_Receive_DMA(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size);
+
+HAL_StatusTypeDef HAL_I2S_DMAPause(I2S_HandleTypeDef *hi2s);
+HAL_StatusTypeDef HAL_I2S_DMAResume(I2S_HandleTypeDef *hi2s);
+HAL_StatusTypeDef HAL_I2S_DMAStop(I2S_HandleTypeDef *hi2s);
+
+/* Callbacks used in non blocking modes (Interrupt and DMA) *******************/
+void HAL_I2S_TxHalfCpltCallback(I2S_HandleTypeDef *hi2s);
+void HAL_I2S_TxCpltCallback(I2S_HandleTypeDef *hi2s);
+void HAL_I2S_RxHalfCpltCallback(I2S_HandleTypeDef *hi2s);
+void HAL_I2S_RxCpltCallback(I2S_HandleTypeDef *hi2s);
+void HAL_I2S_ErrorCallback(I2S_HandleTypeDef *hi2s);
+/**
+ * @}
+ */
+
+/** @addtogroup I2S_Exported_Functions_Group3
+ * @{
+ */
+/* Peripheral Control and State functions ************************************/
+HAL_I2S_StateTypeDef HAL_I2S_GetState(I2S_HandleTypeDef *hi2s);
+uint32_t HAL_I2S_GetError(I2S_HandleTypeDef *hi2s);
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Private types -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private constants ---------------------------------------------------------*/
+/** @defgroup I2S_Private_Constants I2S Private Constants
+ * @{
+ */
+
+/**
+ * @}
+ */
+
+/* Private macros ------------------------------------------------------------*/
+/** @defgroup I2S_Private_Macros I2S Private Macros
+ * @{
+ */
+
+/** @brief Check whether the specified SPI flag is set or not.
+ * @param __SR__ copy of I2S SR regsiter.
+ * @param __FLAG__ specifies the flag to check.
+ * This parameter can be one of the following values:
+ * @arg I2S_FLAG_RXNE: Receive buffer not empty flag
+ * @arg I2S_FLAG_TXE: Transmit buffer empty flag
+ * @arg I2S_FLAG_UDR: Underrun error flag
+ * @arg I2S_FLAG_OVR: Overrun flag
+ * @arg I2S_FLAG_CHSIDE: Channel side flag
+ * @arg I2S_FLAG_BSY: Busy flag
+ * @retval SET or RESET.
+ */
+#define I2S_CHECK_FLAG(__SR__, __FLAG__) ((((__SR__) & ((__FLAG__) & I2S_FLAG_MASK)) == ((__FLAG__) & I2S_FLAG_MASK)) ? SET : RESET)
+
+/** @brief Check whether the specified SPI Interrupt is set or not.
+ * @param __CR2__ copy of I2S CR2 regsiter.
+ * @param __INTERRUPT__ specifies the SPI interrupt source to check.
+ * This parameter can be one of the following values:
+ * @arg I2S_IT_TXE: Tx buffer empty interrupt enable
+ * @arg I2S_IT_RXNE: RX buffer not empty interrupt enable
+ * @arg I2S_IT_ERR: Error interrupt enable
+ * @retval SET or RESET.
+ */
+#define I2S_CHECK_IT_SOURCE(__CR2__, __INTERRUPT__) ((((__CR2__) & (__INTERRUPT__)) == (__INTERRUPT__)) ? SET : RESET)
+
+/** @brief Checks if I2S Mode parameter is in allowed range.
+ * @param __MODE__ specifies the I2S Mode.
+ * This parameter can be a value of @ref I2S_Mode
+ * @retval None
+ */
+#define IS_I2S_MODE(__MODE__) (((__MODE__) == I2S_MODE_SLAVE_TX) || \
+ ((__MODE__) == I2S_MODE_SLAVE_RX) || \
+ ((__MODE__) == I2S_MODE_MASTER_TX) || \
+ ((__MODE__) == I2S_MODE_MASTER_RX))
+
+#define IS_I2S_STANDARD(__STANDARD__) (((__STANDARD__) == I2S_STANDARD_PHILIPS) || \
+ ((__STANDARD__) == I2S_STANDARD_MSB) || \
+ ((__STANDARD__) == I2S_STANDARD_LSB) || \
+ ((__STANDARD__) == I2S_STANDARD_PCM_SHORT) || \
+ ((__STANDARD__) == I2S_STANDARD_PCM_LONG))
+
+#define IS_I2S_DATA_FORMAT(__FORMAT__) (((__FORMAT__) == I2S_DATAFORMAT_16B) || \
+ ((__FORMAT__) == I2S_DATAFORMAT_16B_EXTENDED) || \
+ ((__FORMAT__) == I2S_DATAFORMAT_24B) || \
+ ((__FORMAT__) == I2S_DATAFORMAT_32B))
+
+#define IS_I2S_MCLK_OUTPUT(__OUTPUT__) (((__OUTPUT__) == I2S_MCLKOUTPUT_ENABLE) || \
+ ((__OUTPUT__) == I2S_MCLKOUTPUT_DISABLE))
+
+#define IS_I2S_AUDIO_FREQ(__FREQ__) ((((__FREQ__) >= I2S_AUDIOFREQ_8K) && \
+ ((__FREQ__) <= I2S_AUDIOFREQ_192K)) || \
+ ((__FREQ__) == I2S_AUDIOFREQ_DEFAULT))
+
+#define IS_I2S_FULLDUPLEX_MODE(MODE) (((MODE) == I2S_FULLDUPLEXMODE_DISABLE) || \
+ ((MODE) == I2S_FULLDUPLEXMODE_ENABLE))
+
+/** @brief Checks if I2S Serial clock steady state parameter is in allowed range.
+ * @param __CPOL__ specifies the I2S serial clock steady state.
+ * This parameter can be a value of @ref I2S_Clock_Polarity
+ * @retval None
+ */
+#define IS_I2S_CPOL(__CPOL__) (((__CPOL__) == I2S_CPOL_LOW) || \
+ ((__CPOL__) == I2S_CPOL_HIGH))
+
+#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx) || defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) || defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F411xE) || defined(STM32F469xx) || defined(STM32F479xx)
+#define IS_I2S_CLOCKSOURCE(CLOCK) (((CLOCK) == I2S_CLOCK_EXTERNAL) ||\
+ ((CLOCK) == I2S_CLOCK_PLL))
+#endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx || STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx ||
+ STM32F401xC || STM32F401xE || STM32F411xE || STM32F469xx || STM32F479xx */
+
+#if defined(STM32F446xx) || defined(STM32F412Zx) || defined(STM32F412Vx) || defined(STM32F412Rx) || defined(STM32F412Cx) || defined (STM32F413xx) || defined(STM32F423xx)
+#define IS_I2S_CLOCKSOURCE(CLOCK) (((CLOCK) == I2S_CLOCK_EXTERNAL) ||\
+ ((CLOCK) == I2S_CLOCK_PLL) ||\
+ ((CLOCK) == I2S_CLOCK_PLLSRC) ||\
+ ((CLOCK) == I2S_CLOCK_PLLR))
+#endif /* STM32F446xx || STM32F412Zx || STM32F412Vx || STM32F412Rx || STM32F412Cx || STM32F413xx || STM32F423xx */
+
+#if defined(STM32F410Tx) || defined(STM32F410Cx) || defined(STM32F410Rx)
+#define IS_I2S_CLOCKSOURCE(CLOCK) (((CLOCK) == I2S_CLOCK_EXTERNAL) ||\
+ ((CLOCK) == I2S_CLOCK_PLLSRC) ||\
+ ((CLOCK) == I2S_CLOCK_PLLR))
+#endif /* STM32F410Tx || STM32F410Cx || STM32F410Rx */
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* STM32F4xx_HAL_I2S_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/port/stm32-f4discovery-cc256x-2/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_i2s_ex.h b/port/stm32-f4discovery-cc256x-2/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_i2s_ex.h
new file mode 100644
index 000000000..0273171b4
--- /dev/null
+++ b/port/stm32-f4discovery-cc256x-2/Drivers/STM32F4xx_HAL_Driver/Inc/stm32f4xx_hal_i2s_ex.h
@@ -0,0 +1,174 @@
+/**
+ ******************************************************************************
+ * @file stm32f4xx_hal_i2s_ex.h
+ * @author MCD Application Team
+ * @brief Header file of I2S HAL module.
+ ******************************************************************************
+ * @attention
+ *
+ * © Copyright (c) 2016 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software component is licensed by ST under BSD 3-Clause license,
+ * the "License"; You may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ * opensource.org/licenses/BSD-3-Clause
+ *
+ ******************************************************************************
+ */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef STM32F4xx_HAL_I2S_EX_H
+#define STM32F4xx_HAL_I2S_EX_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f4xx_hal_def.h"
+
+/** @addtogroup STM32F4xx_HAL_Driver
+ * @{
+ */
+#if defined(SPI_I2S_FULLDUPLEX_SUPPORT)
+/** @addtogroup I2SEx I2SEx
+ * @{
+ */
+
+/* Exported types ------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+/* Exported macros -----------------------------------------------------------*/
+/** @defgroup I2SEx_Exported_Macros I2S Extended Exported Macros
+ * @{
+ */
+
+#define I2SxEXT(__INSTANCE__) ((__INSTANCE__) == (SPI2)? (SPI_TypeDef *)(I2S2ext_BASE): (SPI_TypeDef *)(I2S3ext_BASE))
+
+/** @brief Enable or disable the specified I2SExt peripheral.
+ * @param __HANDLE__ specifies the I2S Handle.
+ * @retval None
+ */
+#define __HAL_I2SEXT_ENABLE(__HANDLE__) (I2SxEXT((__HANDLE__)->Instance)->I2SCFGR |= SPI_I2SCFGR_I2SE)
+#define __HAL_I2SEXT_DISABLE(__HANDLE__) (I2SxEXT((__HANDLE__)->Instance)->I2SCFGR &= ~SPI_I2SCFGR_I2SE)
+
+/** @brief Enable or disable the specified I2SExt interrupts.
+ * @param __HANDLE__ specifies the I2S Handle.
+ * @param __INTERRUPT__ specifies the interrupt source to enable or disable.
+ * This parameter can be one of the following values:
+ * @arg I2S_IT_TXE: Tx buffer empty interrupt enable
+ * @arg I2S_IT_RXNE: RX buffer not empty interrupt enable
+ * @arg I2S_IT_ERR: Error interrupt enable
+ * @retval None
+ */
+#define __HAL_I2SEXT_ENABLE_IT(__HANDLE__, __INTERRUPT__) (I2SxEXT((__HANDLE__)->Instance)->CR2 |= (__INTERRUPT__))
+#define __HAL_I2SEXT_DISABLE_IT(__HANDLE__, __INTERRUPT__) (I2SxEXT((__HANDLE__)->Instance)->CR2 &= ~(__INTERRUPT__))
+
+/** @brief Checks if the specified I2SExt interrupt source is enabled or disabled.
+ * @param __HANDLE__ specifies the I2S Handle.
+ * This parameter can be I2S where x: 1, 2, or 3 to select the I2S peripheral.
+ * @param __INTERRUPT__ specifies the I2S interrupt source to check.
+ * This parameter can be one of the following values:
+ * @arg I2S_IT_TXE: Tx buffer empty interrupt enable
+ * @arg I2S_IT_RXNE: RX buffer not empty interrupt enable
+ * @arg I2S_IT_ERR: Error interrupt enable
+ * @retval The new state of __IT__ (TRUE or FALSE).
+ */
+#define __HAL_I2SEXT_GET_IT_SOURCE(__HANDLE__, __INTERRUPT__) (((I2SxEXT((__HANDLE__)->Instance)->CR2 & (__INTERRUPT__)) == (__INTERRUPT__)) ? SET : RESET)
+
+/** @brief Checks whether the specified I2SExt flag is set or not.
+ * @param __HANDLE__ specifies the I2S Handle.
+ * @param __FLAG__ specifies the flag to check.
+ * This parameter can be one of the following values:
+ * @arg I2S_FLAG_RXNE: Receive buffer not empty flag
+ * @arg I2S_FLAG_TXE: Transmit buffer empty flag
+ * @arg I2S_FLAG_UDR: Underrun flag
+ * @arg I2S_FLAG_OVR: Overrun flag
+ * @arg I2S_FLAG_FRE: Frame error flag
+ * @arg I2S_FLAG_CHSIDE: Channel Side flag
+ * @arg I2S_FLAG_BSY: Busy flag
+ * @retval The new state of __FLAG__ (TRUE or FALSE).
+ */
+#define __HAL_I2SEXT_GET_FLAG(__HANDLE__, __FLAG__) (((I2SxEXT((__HANDLE__)->Instance)->SR) & (__FLAG__)) == (__FLAG__))
+
+/** @brief Clears the I2SExt OVR pending flag.
+ * @param __HANDLE__ specifies the I2S Handle.
+ * @retval None
+ */
+#define __HAL_I2SEXT_CLEAR_OVRFLAG(__HANDLE__) do{ \
+ __IO uint32_t tmpreg_ovr = 0x00U; \
+ tmpreg_ovr = I2SxEXT((__HANDLE__)->Instance)->DR;\
+ tmpreg_ovr = I2SxEXT((__HANDLE__)->Instance)->SR;\
+ UNUSED(tmpreg_ovr); \
+ }while(0U)
+/** @brief Clears the I2SExt UDR pending flag.
+ * @param __HANDLE__ specifies the I2S Handle.
+ * @retval None
+ */
+#define __HAL_I2SEXT_CLEAR_UDRFLAG(__HANDLE__) do{ \
+ __IO uint32_t tmpreg_udr = 0x00U; \
+ tmpreg_udr = I2SxEXT((__HANDLE__)->Instance)->SR;\
+ UNUSED(tmpreg_udr); \
+ }while(0U)
+/**
+ * @}
+ */
+
+/* Exported functions --------------------------------------------------------*/
+/** @addtogroup I2SEx_Exported_Functions I2S Extended Exported Functions
+ * @{
+ */
+
+/** @addtogroup I2SEx_Exported_Functions_Group1 I2S Extended IO operation functions
+ * @{
+ */
+
+/* Extended features functions *************************************************/
+/* Blocking mode: Polling */
+HAL_StatusTypeDef HAL_I2SEx_TransmitReceive(I2S_HandleTypeDef *hi2s, uint16_t *pTxData, uint16_t *pRxData,
+ uint16_t Size, uint32_t Timeout);
+/* Non-Blocking mode: Interrupt */
+HAL_StatusTypeDef HAL_I2SEx_TransmitReceive_IT(I2S_HandleTypeDef *hi2s, uint16_t *pTxData, uint16_t *pRxData,
+ uint16_t Size);
+/* Non-Blocking mode: DMA */
+HAL_StatusTypeDef HAL_I2SEx_TransmitReceive_DMA(I2S_HandleTypeDef *hi2s, uint16_t *pTxData, uint16_t *pRxData,
+ uint16_t Size);
+/* I2S IRQHandler and Callbacks used in non blocking modes (Interrupt and DMA) */
+void HAL_I2SEx_FullDuplex_IRQHandler(I2S_HandleTypeDef *hi2s);
+void HAL_I2SEx_TxRxHalfCpltCallback(I2S_HandleTypeDef *hi2s);
+void HAL_I2SEx_TxRxCpltCallback(I2S_HandleTypeDef *hi2s);
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+/* Private types -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private constants ---------------------------------------------------------*/
+/* Private macros ------------------------------------------------------------*/
+
+/**
+ * @}
+ */
+
+/* Private functions ---------------------------------------------------------*/
+
+/**
+ * @}
+ */
+
+#endif /* SPI_I2S_FULLDUPLEX_SUPPORT */
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* STM32F4xx_HAL_I2S_EX_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/port/stm32-f4discovery-cc256x-2/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2s.c b/port/stm32-f4discovery-cc256x-2/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2s.c
new file mode 100644
index 000000000..37e16484b
--- /dev/null
+++ b/port/stm32-f4discovery-cc256x-2/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2s.c
@@ -0,0 +1,1940 @@
+/**
+ ******************************************************************************
+ * @file stm32f4xx_hal_i2s.c
+ * @author MCD Application Team
+ * @brief I2S HAL module driver.
+ * This file provides firmware functions to manage the following
+ * functionalities of the Integrated Interchip Sound (I2S) peripheral:
+ * + Initialization and de-initialization functions
+ * + IO operation functions
+ * + Peripheral State and Errors functions
+ @verbatim
+ ===============================================================================
+ ##### How to use this driver #####
+ ===============================================================================
+ [..]
+ The I2S HAL driver can be used as follow:
+
+ (#) Declare a I2S_HandleTypeDef handle structure.
+ (#) Initialize the I2S low level resources by implement the HAL_I2S_MspInit() API:
+ (##) Enable the SPIx interface clock.
+ (##) I2S pins configuration:
+ (+++) Enable the clock for the I2S GPIOs.
+ (+++) Configure these I2S pins as alternate function pull-up.
+ (##) NVIC configuration if you need to use interrupt process (HAL_I2S_Transmit_IT()
+ and HAL_I2S_Receive_IT() APIs).
+ (+++) Configure the I2Sx interrupt priority.
+ (+++) Enable the NVIC I2S IRQ handle.
+ (##) DMA Configuration if you need to use DMA process (HAL_I2S_Transmit_DMA()
+ and HAL_I2S_Receive_DMA() APIs:
+ (+++) Declare a DMA handle structure for the Tx/Rx Stream/Channel.
+ (+++) Enable the DMAx interface clock.
+ (+++) Configure the declared DMA handle structure with the required Tx/Rx parameters.
+ (+++) Configure the DMA Tx/Rx Stream/Channel.
+ (+++) Associate the initialized DMA handle to the I2S DMA Tx/Rx handle.
+ (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on the
+ DMA Tx/Rx Stream/Channel.
+
+ (#) Program the Mode, Standard, Data Format, MCLK Output, Audio frequency and Polarity
+ using HAL_I2S_Init() function.
+
+ -@- The specific I2S interrupts (Transmission complete interrupt,
+ RXNE interrupt and Error Interrupts) will be managed using the macros
+ __HAL_I2S_ENABLE_IT() and __HAL_I2S_DISABLE_IT() inside the transmit and receive process.
+ -@- Make sure that either:
+ (+@) I2S PLL clock is configured or
+ (+@) External clock source is configured after setting correctly
+ the define constant EXTERNAL_CLOCK_VALUE in the stm32f4xx_hal_conf.h file.
+
+ (#) Three mode of operations are available within this driver :
+
+ *** Polling mode IO operation ***
+ =================================
+ [..]
+ (+) Send an amount of data in blocking mode using HAL_I2S_Transmit()
+ (+) Receive an amount of data in blocking mode using HAL_I2S_Receive()
+
+ *** Interrupt mode IO operation ***
+ ===================================
+ [..]
+ (+) Send an amount of data in non blocking mode using HAL_I2S_Transmit_IT()
+ (+) At transmission end of half transfer HAL_I2S_TxHalfCpltCallback is executed and user can
+ add his own code by customization of function pointer HAL_I2S_TxHalfCpltCallback
+ (+) At transmission end of transfer HAL_I2S_TxCpltCallback is executed and user can
+ add his own code by customization of function pointer HAL_I2S_TxCpltCallback
+ (+) Receive an amount of data in non blocking mode using HAL_I2S_Receive_IT()
+ (+) At reception end of half transfer HAL_I2S_RxHalfCpltCallback is executed and user can
+ add his own code by customization of function pointer HAL_I2S_RxHalfCpltCallback
+ (+) At reception end of transfer HAL_I2S_RxCpltCallback is executed and user can
+ add his own code by customization of function pointer HAL_I2S_RxCpltCallback
+ (+) In case of transfer Error, HAL_I2S_ErrorCallback() function is executed and user can
+ add his own code by customization of function pointer HAL_I2S_ErrorCallback
+
+ *** DMA mode IO operation ***
+ ==============================
+ [..]
+ (+) Send an amount of data in non blocking mode (DMA) using HAL_I2S_Transmit_DMA()
+ (+) At transmission end of half transfer HAL_I2S_TxHalfCpltCallback is executed and user can
+ add his own code by customization of function pointer HAL_I2S_TxHalfCpltCallback
+ (+) At transmission end of transfer HAL_I2S_TxCpltCallback is executed and user can
+ add his own code by customization of function pointer HAL_I2S_TxCpltCallback
+ (+) Receive an amount of data in non blocking mode (DMA) using HAL_I2S_Receive_DMA()
+ (+) At reception end of half transfer HAL_I2S_RxHalfCpltCallback is executed and user can
+ add his own code by customization of function pointer HAL_I2S_RxHalfCpltCallback
+ (+) At reception end of transfer HAL_I2S_RxCpltCallback is executed and user can
+ add his own code by customization of function pointer HAL_I2S_RxCpltCallback
+ (+) In case of transfer Error, HAL_I2S_ErrorCallback() function is executed and user can
+ add his own code by customization of function pointer HAL_I2S_ErrorCallback
+ (+) Pause the DMA Transfer using HAL_I2S_DMAPause()
+ (+) Resume the DMA Transfer using HAL_I2S_DMAResume()
+ (+) Stop the DMA Transfer using HAL_I2S_DMAStop()
+
+ *** I2S HAL driver macros list ***
+ ===================================
+ [..]
+ Below the list of most used macros in I2S HAL driver.
+
+ (+) __HAL_I2S_ENABLE: Enable the specified SPI peripheral (in I2S mode)
+ (+) __HAL_I2S_DISABLE: Disable the specified SPI peripheral (in I2S mode)
+ (+) __HAL_I2S_ENABLE_IT : Enable the specified I2S interrupts
+ (+) __HAL_I2S_DISABLE_IT : Disable the specified I2S interrupts
+ (+) __HAL_I2S_GET_FLAG: Check whether the specified I2S flag is set or not
+
+ [..]
+ (@) You can refer to the I2S HAL driver header file for more useful macros
+
+ *** I2S HAL driver macros list ***
+ ===================================
+ [..]
+ Callback registration:
+
+ (#) The compilation flag USE_HAL_I2S_REGISTER_CALLBACKS when set to 1U
+ allows the user to configure dynamically the driver callbacks.
+ Use Functions HAL_I2S_RegisterCallback() to register an interrupt callback.
+
+ Function HAL_I2S_RegisterCallback() allows to register following callbacks:
+ (+) TxCpltCallback : I2S Tx Completed callback
+ (+) RxCpltCallback : I2S Rx Completed callback
+ (+) TxRxCpltCallback : I2S TxRx Completed callback
+ (+) TxHalfCpltCallback : I2S Tx Half Completed callback
+ (+) RxHalfCpltCallback : I2S Rx Half Completed callback
+ (+) ErrorCallback : I2S Error callback
+ (+) MspInitCallback : I2S Msp Init callback
+ (+) MspDeInitCallback : I2S 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_I2S_UnRegisterCallback to reset a callback to the default
+ weak function.
+ HAL_I2S_UnRegisterCallback takes as parameters the HAL peripheral handle,
+ and the Callback ID.
+ This function allows to reset following callbacks:
+ (+) TxCpltCallback : I2S Tx Completed callback
+ (+) RxCpltCallback : I2S Rx Completed callback
+ (+) TxRxCpltCallback : I2S TxRx Completed callback
+ (+) TxHalfCpltCallback : I2S Tx Half Completed callback
+ (+) RxHalfCpltCallback : I2S Rx Half Completed callback
+ (+) ErrorCallback : I2S Error callback
+ (+) MspInitCallback : I2S Msp Init callback
+ (+) MspDeInitCallback : I2S Msp DeInit callback
+
+ By default, after the HAL_I2S_Init() and when the state is HAL_I2S_STATE_RESET
+ all callbacks are set to the corresponding weak functions:
+ examples HAL_I2S_MasterTxCpltCallback(), HAL_I2S_MasterRxCpltCallback().
+ Exception done for MspInit and MspDeInit functions that are
+ reset to the legacy weak functions in the HAL_I2S_Init()/ HAL_I2S_DeInit() only when
+ these callbacks are null (not registered beforehand).
+ If MspInit or MspDeInit are not null, the HAL_I2S_Init()/ HAL_I2S_DeInit()
+ keep and use the user MspInit/MspDeInit callbacks (registered beforehand) whatever the state.
+
+ Callbacks can be registered/unregistered in HAL_I2S_STATE_READY state only.
+ Exception done MspInit/MspDeInit functions that can be registered/unregistered
+ in HAL_I2S_STATE_READY or HAL_I2S_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_I2S_RegisterCallback() before calling HAL_I2S_DeInit()
+ or HAL_I2S_Init() function.
+
+ When The compilation define USE_HAL_I2S_REGISTER_CALLBACKS is set to 0 or
+ not defined, the callback registering feature is not available
+ and weak (surcharged) callbacks are used.
+
+ @endverbatim
+ ******************************************************************************
+ * @attention
+ *
+ * © Copyright (c) 2016 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software component is licensed by ST under BSD 3-Clause license,
+ * the "License"; You may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ * opensource.org/licenses/BSD-3-Clause
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f4xx_hal.h"
+
+#ifdef HAL_I2S_MODULE_ENABLED
+
+/** @addtogroup STM32F4xx_HAL_Driver
+ * @{
+ */
+
+/** @defgroup I2S I2S
+ * @brief I2S HAL module driver
+ * @{
+ */
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/** @defgroup I2S_Private_Functions I2S Private Functions
+ * @{
+ */
+static void I2S_DMATxCplt(DMA_HandleTypeDef *hdma);
+static void I2S_DMATxHalfCplt(DMA_HandleTypeDef *hdma);
+static void I2S_DMARxCplt(DMA_HandleTypeDef *hdma);
+static void I2S_DMARxHalfCplt(DMA_HandleTypeDef *hdma);
+static void I2S_DMAError(DMA_HandleTypeDef *hdma);
+static void I2S_Transmit_IT(I2S_HandleTypeDef *hi2s);
+static void I2S_Receive_IT(I2S_HandleTypeDef *hi2s);
+static void I2S_IRQHandler(I2S_HandleTypeDef *hi2s);
+static HAL_StatusTypeDef I2S_WaitFlagStateUntilTimeout(I2S_HandleTypeDef *hi2s, uint32_t Flag, FlagStatus State,
+ uint32_t Timeout);
+/**
+ * @}
+ */
+
+/* Exported functions ---------------------------------------------------------*/
+
+/** @defgroup I2S_Exported_Functions I2S Exported Functions
+ * @{
+ */
+
+/** @defgroup I2S_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 I2Sx peripheral in simplex mode:
+
+ (+) User must Implement HAL_I2S_MspInit() function in which he configures
+ all related peripherals resources (CLOCK, GPIO, DMA, IT and NVIC ).
+
+ (+) Call the function HAL_I2S_Init() to configure the selected device with
+ the selected configuration:
+ (++) Mode
+ (++) Standard
+ (++) Data Format
+ (++) MCLK Output
+ (++) Audio frequency
+ (++) Polarity
+ (++) Full duplex mode
+
+ (+) Call the function HAL_I2S_DeInit() to restore the default configuration
+ of the selected I2Sx peripheral.
+ @endverbatim
+ * @{
+ */
+
+/**
+ * @brief Initializes the I2S according to the specified parameters
+ * in the I2S_InitTypeDef and create the associated handle.
+ * @param hi2s pointer to a I2S_HandleTypeDef structure that contains
+ * the configuration information for I2S module
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_I2S_Init(I2S_HandleTypeDef *hi2s)
+{
+ uint32_t i2sdiv;
+ uint32_t i2sodd;
+ uint32_t packetlength;
+ uint32_t tmp;
+ uint32_t i2sclk;
+#if defined (SPI_I2S_FULLDUPLEX_SUPPORT)
+ uint16_t tmpreg;
+#endif
+
+ /* Check the I2S handle allocation */
+ if (hi2s == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Check the I2S parameters */
+ assert_param(IS_I2S_ALL_INSTANCE(hi2s->Instance));
+ assert_param(IS_I2S_MODE(hi2s->Init.Mode));
+ assert_param(IS_I2S_STANDARD(hi2s->Init.Standard));
+ assert_param(IS_I2S_DATA_FORMAT(hi2s->Init.DataFormat));
+ assert_param(IS_I2S_MCLK_OUTPUT(hi2s->Init.MCLKOutput));
+ assert_param(IS_I2S_AUDIO_FREQ(hi2s->Init.AudioFreq));
+ assert_param(IS_I2S_CPOL(hi2s->Init.CPOL));
+ assert_param(IS_I2S_CLOCKSOURCE(hi2s->Init.ClockSource));
+
+ if (hi2s->State == HAL_I2S_STATE_RESET)
+ {
+ /* Allocate lock resource and initialize it */
+ hi2s->Lock = HAL_UNLOCKED;
+
+ /* Initialize Default I2S IrqHandler ISR */
+ hi2s->IrqHandlerISR = I2S_IRQHandler;
+
+#if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
+ /* Init the I2S Callback settings */
+ hi2s->TxCpltCallback = HAL_I2S_TxCpltCallback; /* Legacy weak TxCpltCallback */
+ hi2s->RxCpltCallback = HAL_I2S_RxCpltCallback; /* Legacy weak RxCpltCallback */
+#if defined (SPI_I2S_FULLDUPLEX_SUPPORT)
+ hi2s->TxRxCpltCallback = HAL_I2SEx_TxRxCpltCallback; /* Legacy weak TxRxCpltCallback */
+#endif
+ hi2s->TxHalfCpltCallback = HAL_I2S_TxHalfCpltCallback; /* Legacy weak TxHalfCpltCallback */
+ hi2s->RxHalfCpltCallback = HAL_I2S_RxHalfCpltCallback; /* Legacy weak RxHalfCpltCallback */
+#if defined (SPI_I2S_FULLDUPLEX_SUPPORT)
+ hi2s->TxRxHalfCpltCallback = HAL_I2SEx_TxRxHalfCpltCallback; /* Legacy weak TxRxHalfCpltCallback */
+#endif
+ hi2s->ErrorCallback = HAL_I2S_ErrorCallback; /* Legacy weak ErrorCallback */
+
+ if (hi2s->MspInitCallback == NULL)
+ {
+ hi2s->MspInitCallback = HAL_I2S_MspInit; /* Legacy weak MspInit */
+ }
+
+ /* Init the low level hardware : GPIO, CLOCK, NVIC... */
+ hi2s->MspInitCallback(hi2s);
+#else
+ /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */
+ HAL_I2S_MspInit(hi2s);
+#endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
+ }
+
+ hi2s->State = HAL_I2S_STATE_BUSY;
+
+ /*----------------------- SPIx I2SCFGR & I2SPR Configuration ----------------*/
+ /* Clear I2SMOD, I2SE, I2SCFG, PCMSYNC, I2SSTD, CKPOL, DATLEN and CHLEN bits */
+ CLEAR_BIT(hi2s->Instance->I2SCFGR, (SPI_I2SCFGR_CHLEN | SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CKPOL | \
+ SPI_I2SCFGR_I2SSTD | SPI_I2SCFGR_PCMSYNC | SPI_I2SCFGR_I2SCFG | \
+ SPI_I2SCFGR_I2SE | SPI_I2SCFGR_I2SMOD));
+ hi2s->Instance->I2SPR = 0x0002U;
+
+ /*----------------------- I2SPR: I2SDIV and ODD Calculation -----------------*/
+ /* If the requested audio frequency is not the default, compute the prescaler */
+ if (hi2s->Init.AudioFreq != I2S_AUDIOFREQ_DEFAULT)
+ {
+ /* Check the frame length (For the Prescaler computing) ********************/
+ if (hi2s->Init.DataFormat == I2S_DATAFORMAT_16B)
+ {
+ /* Packet length is 16 bits */
+ packetlength = 16U;
+ }
+ else
+ {
+ /* Packet length is 32 bits */
+ packetlength = 32U;
+ }
+
+ /* I2S standard */
+ if (hi2s->Init.Standard <= I2S_STANDARD_LSB)
+ {
+ /* In I2S standard packet lenght is multiplied by 2 */
+ packetlength = packetlength * 2U;
+ }
+
+ /* Get the source clock value **********************************************/
+#if defined(I2S_APB1_APB2_FEATURE)
+ if (IS_I2S_APB1_INSTANCE(hi2s->Instance))
+ {
+ i2sclk = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_I2S_APB1);
+ }
+ else
+ {
+ i2sclk = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_I2S_APB2);
+ }
+#else
+ i2sclk = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_I2S);
+#endif
+
+ /* Compute the Real divider depending on the MCLK output state, with a floating point */
+ if (hi2s->Init.MCLKOutput == I2S_MCLKOUTPUT_ENABLE)
+ {
+ /* MCLK output is enabled */
+ if (hi2s->Init.DataFormat != I2S_DATAFORMAT_16B)
+ {
+ tmp = (uint32_t)(((((i2sclk / (packetlength * 4U)) * 10U) / hi2s->Init.AudioFreq)) + 5U);
+ }
+ else
+ {
+ tmp = (uint32_t)(((((i2sclk / (packetlength * 8U)) * 10U) / hi2s->Init.AudioFreq)) + 5U);
+ }
+ }
+ else
+ {
+ /* MCLK output is disabled */
+ tmp = (uint32_t)(((((i2sclk / packetlength) * 10U) / hi2s->Init.AudioFreq)) + 5U);
+ }
+
+ /* Remove the flatting point */
+ tmp = tmp / 10U;
+
+ /* Check the parity of the divider */
+ i2sodd = (uint32_t)(tmp & (uint32_t)1U);
+
+ /* Compute the i2sdiv prescaler */
+ i2sdiv = (uint32_t)((tmp - i2sodd) / 2U);
+
+ /* Get the Mask for the Odd bit (SPI_I2SPR[8]) register */
+ i2sodd = (uint32_t)(i2sodd << 8U);
+ }
+ else
+ {
+ /* Set the default values */
+ i2sdiv = 2U;
+ i2sodd = 0U;
+ }
+
+ /* Test if the divider is 1 or 0 or greater than 0xFF */
+ if ((i2sdiv < 2U) || (i2sdiv > 0xFFU))
+ {
+ /* Set the error code and execute error callback*/
+ SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_PRESCALER);
+ return HAL_ERROR;
+ }
+
+ /*----------------------- SPIx I2SCFGR & I2SPR Configuration ----------------*/
+
+ /* Write to SPIx I2SPR register the computed value */
+ hi2s->Instance->I2SPR = (uint32_t)((uint32_t)i2sdiv | (uint32_t)(i2sodd | (uint32_t)hi2s->Init.MCLKOutput));
+
+ /* Clear I2SMOD, I2SE, I2SCFG, PCMSYNC, I2SSTD, CKPOL, DATLEN and CHLEN bits */
+ /* And configure the I2S with the I2S_InitStruct values */
+ MODIFY_REG(hi2s->Instance->I2SCFGR, (SPI_I2SCFGR_CHLEN | SPI_I2SCFGR_DATLEN | \
+ SPI_I2SCFGR_CKPOL | SPI_I2SCFGR_I2SSTD | \
+ SPI_I2SCFGR_PCMSYNC | SPI_I2SCFGR_I2SCFG | \
+ SPI_I2SCFGR_I2SE | SPI_I2SCFGR_I2SMOD), \
+ (SPI_I2SCFGR_I2SMOD | hi2s->Init.Mode | \
+ hi2s->Init.Standard | hi2s->Init.DataFormat | \
+ hi2s->Init.CPOL));
+
+#if defined(SPI_I2SCFGR_ASTRTEN)
+ if ((hi2s->Init.Standard == I2S_STANDARD_PCM_SHORT) || ((hi2s->Init.Standard == I2S_STANDARD_PCM_LONG)))
+ {
+ /* Write to SPIx I2SCFGR */
+ SET_BIT(hi2s->Instance->I2SCFGR, SPI_I2SCFGR_ASTRTEN);
+ }
+#endif
+
+#if defined (SPI_I2S_FULLDUPLEX_SUPPORT)
+
+ /* Configure the I2S extended if the full duplex mode is enabled */
+ assert_param(IS_I2S_FULLDUPLEX_MODE(hi2s->Init.FullDuplexMode));
+
+ if (hi2s->Init.FullDuplexMode == I2S_FULLDUPLEXMODE_ENABLE)
+ {
+ /* Set FullDuplex I2S IrqHandler ISR if FULLDUPLEXMODE is enabled */
+ hi2s->IrqHandlerISR = HAL_I2SEx_FullDuplex_IRQHandler;
+
+ /* Clear I2SMOD, I2SE, I2SCFG, PCMSYNC, I2SSTD, CKPOL, DATLEN and CHLEN bits */
+ CLEAR_BIT(I2SxEXT(hi2s->Instance)->I2SCFGR, (SPI_I2SCFGR_CHLEN | SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CKPOL | \
+ SPI_I2SCFGR_I2SSTD | SPI_I2SCFGR_PCMSYNC | SPI_I2SCFGR_I2SCFG | \
+ SPI_I2SCFGR_I2SE | SPI_I2SCFGR_I2SMOD));
+ I2SxEXT(hi2s->Instance)->I2SPR = 2U;
+
+ /* Get the I2SCFGR register value */
+ tmpreg = I2SxEXT(hi2s->Instance)->I2SCFGR;
+
+ /* Get the mode to be configured for the extended I2S */
+ if ((hi2s->Init.Mode == I2S_MODE_MASTER_TX) || (hi2s->Init.Mode == I2S_MODE_SLAVE_TX))
+ {
+ tmp = I2S_MODE_SLAVE_RX;
+ }
+ else /* I2S_MODE_MASTER_RX || I2S_MODE_SLAVE_RX */
+ {
+ tmp = I2S_MODE_SLAVE_TX;
+ }
+
+ /* Configure the I2S Slave with the I2S Master parameter values */
+ tmpreg |= (uint16_t)((uint16_t)SPI_I2SCFGR_I2SMOD | (uint16_t)(tmp | \
+ (uint16_t)(hi2s->Init.Standard | (uint16_t)(hi2s->Init.DataFormat | \
+ (uint16_t)hi2s->Init.CPOL))));
+
+ /* Write to SPIx I2SCFGR */
+ WRITE_REG(I2SxEXT(hi2s->Instance)->I2SCFGR, tmpreg);
+ }
+#endif /* SPI_I2S_FULLDUPLEX_SUPPORT */
+
+ hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
+ hi2s->State = HAL_I2S_STATE_READY;
+
+ return HAL_OK;
+}
+
+/**
+ * @brief DeInitializes the I2S peripheral
+ * @param hi2s pointer to a I2S_HandleTypeDef structure that contains
+ * the configuration information for I2S module
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_I2S_DeInit(I2S_HandleTypeDef *hi2s)
+{
+ /* Check the I2S handle allocation */
+ if (hi2s == NULL)
+ {
+ return HAL_ERROR;
+ }
+
+ /* Check the parameters */
+ assert_param(IS_I2S_ALL_INSTANCE(hi2s->Instance));
+
+ hi2s->State = HAL_I2S_STATE_BUSY;
+
+ /* Disable the I2S Peripheral Clock */
+ __HAL_I2S_DISABLE(hi2s);
+
+#if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
+ if (hi2s->MspDeInitCallback == NULL)
+ {
+ hi2s->MspDeInitCallback = HAL_I2S_MspDeInit; /* Legacy weak MspDeInit */
+ }
+
+ /* DeInit the low level hardware: GPIO, CLOCK, NVIC... */
+ hi2s->MspDeInitCallback(hi2s);
+#else
+ /* DeInit the low level hardware: GPIO, CLOCK, NVIC... */
+ HAL_I2S_MspDeInit(hi2s);
+#endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
+
+ hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
+ hi2s->State = HAL_I2S_STATE_RESET;
+
+ /* Release Lock */
+ __HAL_UNLOCK(hi2s);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief I2S MSP Init
+ * @param hi2s pointer to a I2S_HandleTypeDef structure that contains
+ * the configuration information for I2S module
+ * @retval None
+ */
+__weak void HAL_I2S_MspInit(I2S_HandleTypeDef *hi2s)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hi2s);
+
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_I2S_MspInit could be implemented in the user file
+ */
+}
+
+/**
+ * @brief I2S MSP DeInit
+ * @param hi2s pointer to a I2S_HandleTypeDef structure that contains
+ * the configuration information for I2S module
+ * @retval None
+ */
+__weak void HAL_I2S_MspDeInit(I2S_HandleTypeDef *hi2s)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hi2s);
+
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_I2S_MspDeInit could be implemented in the user file
+ */
+}
+
+#if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
+/**
+ * @brief Register a User I2S Callback
+ * To be used instead of the weak predefined callback
+ * @param hi2s Pointer to a I2S_HandleTypeDef structure that contains
+ * the configuration information for the specified I2S.
+ * @param CallbackID ID of the callback to be registered
+ * @param pCallback pointer to the Callback function
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_I2S_RegisterCallback(I2S_HandleTypeDef *hi2s, HAL_I2S_CallbackIDTypeDef CallbackID, pI2S_CallbackTypeDef pCallback)
+{
+ HAL_StatusTypeDef status = HAL_OK;
+
+ if (pCallback == NULL)
+ {
+ /* Update the error code */
+ hi2s->ErrorCode |= HAL_I2S_ERROR_INVALID_CALLBACK;
+
+ return HAL_ERROR;
+ }
+ /* Process locked */
+ __HAL_LOCK(hi2s);
+
+ if (HAL_I2S_STATE_READY == hi2s->State)
+ {
+ switch (CallbackID)
+ {
+ case HAL_I2S_TX_COMPLETE_CB_ID :
+ hi2s->TxCpltCallback = pCallback;
+ break;
+
+ case HAL_I2S_RX_COMPLETE_CB_ID :
+ hi2s->RxCpltCallback = pCallback;
+ break;
+
+#if defined (SPI_I2S_FULLDUPLEX_SUPPORT)
+ case HAL_I2S_TX_RX_COMPLETE_CB_ID :
+ hi2s->TxRxCpltCallback = pCallback;
+ break;
+#endif
+
+ case HAL_I2S_TX_HALF_COMPLETE_CB_ID :
+ hi2s->TxHalfCpltCallback = pCallback;
+ break;
+
+ case HAL_I2S_RX_HALF_COMPLETE_CB_ID :
+ hi2s->RxHalfCpltCallback = pCallback;
+ break;
+
+#if defined (SPI_I2S_FULLDUPLEX_SUPPORT)
+ case HAL_I2S_TX_RX_HALF_COMPLETE_CB_ID :
+ hi2s->TxRxHalfCpltCallback = pCallback;
+ break;
+#endif
+
+ case HAL_I2S_ERROR_CB_ID :
+ hi2s->ErrorCallback = pCallback;
+ break;
+
+ case HAL_I2S_MSPINIT_CB_ID :
+ hi2s->MspInitCallback = pCallback;
+ break;
+
+ case HAL_I2S_MSPDEINIT_CB_ID :
+ hi2s->MspDeInitCallback = pCallback;
+ break;
+
+ default :
+ /* Update the error code */
+ SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_INVALID_CALLBACK);
+
+ /* Return error status */
+ status = HAL_ERROR;
+ break;
+ }
+ }
+ else if (HAL_I2S_STATE_RESET == hi2s->State)
+ {
+ switch (CallbackID)
+ {
+ case HAL_I2S_MSPINIT_CB_ID :
+ hi2s->MspInitCallback = pCallback;
+ break;
+
+ case HAL_I2S_MSPDEINIT_CB_ID :
+ hi2s->MspDeInitCallback = pCallback;
+ break;
+
+ default :
+ /* Update the error code */
+ SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_INVALID_CALLBACK);
+
+ /* Return error status */
+ status = HAL_ERROR;
+ break;
+ }
+ }
+ else
+ {
+ /* Update the error code */
+ SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_INVALID_CALLBACK);
+
+ /* Return error status */
+ status = HAL_ERROR;
+ }
+
+ /* Release Lock */
+ __HAL_UNLOCK(hi2s);
+ return status;
+}
+
+/**
+ * @brief Unregister an I2S Callback
+ * I2S callback is redirected to the weak predefined callback
+ * @param hi2s Pointer to a I2S_HandleTypeDef structure that contains
+ * the configuration information for the specified I2S.
+ * @param CallbackID ID of the callback to be unregistered
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_I2S_UnRegisterCallback(I2S_HandleTypeDef *hi2s, HAL_I2S_CallbackIDTypeDef CallbackID)
+{
+ HAL_StatusTypeDef status = HAL_OK;
+
+ /* Process locked */
+ __HAL_LOCK(hi2s);
+
+ if (HAL_I2S_STATE_READY == hi2s->State)
+ {
+ switch (CallbackID)
+ {
+ case HAL_I2S_TX_COMPLETE_CB_ID :
+ hi2s->TxCpltCallback = HAL_I2S_TxCpltCallback; /* Legacy weak TxCpltCallback */
+ break;
+
+ case HAL_I2S_RX_COMPLETE_CB_ID :
+ hi2s->RxCpltCallback = HAL_I2S_RxCpltCallback; /* Legacy weak RxCpltCallback */
+ break;
+
+#if defined (SPI_I2S_FULLDUPLEX_SUPPORT)
+ case HAL_I2S_TX_RX_COMPLETE_CB_ID :
+ hi2s->TxRxCpltCallback = HAL_I2SEx_TxRxCpltCallback; /* Legacy weak TxRxCpltCallback */
+ break;
+#endif
+
+ case HAL_I2S_TX_HALF_COMPLETE_CB_ID :
+ hi2s->TxHalfCpltCallback = HAL_I2S_TxHalfCpltCallback; /* Legacy weak TxHalfCpltCallback */
+ break;
+
+ case HAL_I2S_RX_HALF_COMPLETE_CB_ID :
+ hi2s->RxHalfCpltCallback = HAL_I2S_RxHalfCpltCallback; /* Legacy weak RxHalfCpltCallback */
+ break;
+
+#if defined (SPI_I2S_FULLDUPLEX_SUPPORT)
+ case HAL_I2S_TX_RX_HALF_COMPLETE_CB_ID :
+ hi2s->TxRxHalfCpltCallback = HAL_I2SEx_TxRxHalfCpltCallback; /* Legacy weak TxRxHalfCpltCallback */
+ break;
+#endif
+
+ case HAL_I2S_ERROR_CB_ID :
+ hi2s->ErrorCallback = HAL_I2S_ErrorCallback; /* Legacy weak ErrorCallback */
+ break;
+
+ case HAL_I2S_MSPINIT_CB_ID :
+ hi2s->MspInitCallback = HAL_I2S_MspInit; /* Legacy weak MspInit */
+ break;
+
+ case HAL_I2S_MSPDEINIT_CB_ID :
+ hi2s->MspDeInitCallback = HAL_I2S_MspDeInit; /* Legacy weak MspDeInit */
+ break;
+
+ default :
+ /* Update the error code */
+ SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_INVALID_CALLBACK);
+
+ /* Return error status */
+ status = HAL_ERROR;
+ break;
+ }
+ }
+ else if (HAL_I2S_STATE_RESET == hi2s->State)
+ {
+ switch (CallbackID)
+ {
+ case HAL_I2S_MSPINIT_CB_ID :
+ hi2s->MspInitCallback = HAL_I2S_MspInit; /* Legacy weak MspInit */
+ break;
+
+ case HAL_I2S_MSPDEINIT_CB_ID :
+ hi2s->MspDeInitCallback = HAL_I2S_MspDeInit; /* Legacy weak MspDeInit */
+ break;
+
+ default :
+ /* Update the error code */
+ SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_INVALID_CALLBACK);
+
+ /* Return error status */
+ status = HAL_ERROR;
+ break;
+ }
+ }
+ else
+ {
+ /* Update the error code */
+ SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_INVALID_CALLBACK);
+
+ /* Return error status */
+ status = HAL_ERROR;
+ }
+
+ /* Release Lock */
+ __HAL_UNLOCK(hi2s);
+ return status;
+}
+#endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
+/**
+ * @}
+ */
+
+/** @defgroup I2S_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 I2S data
+ transfers.
+
+ (#) There are two modes of transfer:
+ (++) Blocking mode : The communication is performed in the polling mode.
+ The 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 functions return the status of the transfer startup.
+ The end of the data processing will be indicated through the
+ dedicated I2S IRQ when using Interrupt mode or the DMA IRQ when
+ using DMA mode.
+
+ (#) Blocking mode functions are :
+ (++) HAL_I2S_Transmit()
+ (++) HAL_I2S_Receive()
+
+ (#) No-Blocking mode functions with Interrupt are :
+ (++) HAL_I2S_Transmit_IT()
+ (++) HAL_I2S_Receive_IT()
+
+ (#) No-Blocking mode functions with DMA are :
+ (++) HAL_I2S_Transmit_DMA()
+ (++) HAL_I2S_Receive_DMA()
+
+ (#) A set of Transfer Complete Callbacks are provided in non Blocking mode:
+ (++) HAL_I2S_TxCpltCallback()
+ (++) HAL_I2S_RxCpltCallback()
+ (++) HAL_I2S_ErrorCallback()
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Transmit an amount of data in blocking mode
+ * @param hi2s pointer to a I2S_HandleTypeDef structure that contains
+ * the configuration information for I2S module
+ * @param pData a 16-bit pointer to data buffer.
+ * @param Size number of data sample to be sent:
+ * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
+ * configuration phase, the Size parameter means the number of 16-bit data length
+ * in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
+ * the Size parameter means the number of 16-bit data length.
+ * @param Timeout Timeout duration
+ * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
+ * between Master and Slave(example: audio streaming).
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_I2S_Transmit(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size, uint32_t Timeout)
+{
+ uint32_t tmpreg_cfgr;
+
+ if ((pData == NULL) || (Size == 0U))
+ {
+ return HAL_ERROR;
+ }
+
+ /* Process Locked */
+ __HAL_LOCK(hi2s);
+
+ if (hi2s->State != HAL_I2S_STATE_READY)
+ {
+ __HAL_UNLOCK(hi2s);
+ return HAL_BUSY;
+ }
+
+ /* Set state and reset error code */
+ hi2s->State = HAL_I2S_STATE_BUSY_TX;
+ hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
+ hi2s->pTxBuffPtr = pData;
+
+ tmpreg_cfgr = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN);
+
+ if ((tmpreg_cfgr == I2S_DATAFORMAT_24B) || (tmpreg_cfgr == I2S_DATAFORMAT_32B))
+ {
+ hi2s->TxXferSize = (Size << 1U);
+ hi2s->TxXferCount = (Size << 1U);
+ }
+ else
+ {
+ hi2s->TxXferSize = Size;
+ hi2s->TxXferCount = Size;
+ }
+
+ tmpreg_cfgr = hi2s->Instance->I2SCFGR;
+
+ /* Check if the I2S is already enabled */
+ if ((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE)
+ {
+ /* Enable I2S peripheral */
+ __HAL_I2S_ENABLE(hi2s);
+ }
+
+ /* Wait until TXE flag is set */
+ if (I2S_WaitFlagStateUntilTimeout(hi2s, I2S_FLAG_TXE, SET, Timeout) != HAL_OK)
+ {
+ /* Set the error code */
+ SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_TIMEOUT);
+ hi2s->State = HAL_I2S_STATE_READY;
+ __HAL_UNLOCK(hi2s);
+ return HAL_ERROR;
+ }
+
+ while (hi2s->TxXferCount > 0U)
+ {
+ hi2s->Instance->DR = (*hi2s->pTxBuffPtr);
+ hi2s->pTxBuffPtr++;
+ hi2s->TxXferCount--;
+
+ /* Wait until TXE flag is set */
+ if (I2S_WaitFlagStateUntilTimeout(hi2s, I2S_FLAG_TXE, SET, Timeout) != HAL_OK)
+ {
+ /* Set the error code */
+ SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_TIMEOUT);
+ hi2s->State = HAL_I2S_STATE_READY;
+ __HAL_UNLOCK(hi2s);
+ return HAL_ERROR;
+ }
+
+ /* Check if an underrun occurs */
+ if (__HAL_I2S_GET_FLAG(hi2s, I2S_FLAG_UDR) == SET)
+ {
+ /* Clear underrun flag */
+ __HAL_I2S_CLEAR_UDRFLAG(hi2s);
+
+ /* Set the error code */
+ SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_UDR);
+ }
+ }
+
+ /* Check if Slave mode is selected */
+ if (((tmpreg_cfgr & SPI_I2SCFGR_I2SCFG) == I2S_MODE_SLAVE_TX) || ((tmpreg_cfgr & SPI_I2SCFGR_I2SCFG) == I2S_MODE_SLAVE_RX))
+ {
+ /* Wait until Busy flag is reset */
+ if (I2S_WaitFlagStateUntilTimeout(hi2s, I2S_FLAG_BSY, RESET, Timeout) != HAL_OK)
+ {
+ /* Set the error code */
+ SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_TIMEOUT);
+ hi2s->State = HAL_I2S_STATE_READY;
+ __HAL_UNLOCK(hi2s);
+ return HAL_ERROR;
+ }
+ }
+
+ hi2s->State = HAL_I2S_STATE_READY;
+ __HAL_UNLOCK(hi2s);
+ return HAL_OK;
+}
+
+/**
+ * @brief Receive an amount of data in blocking mode
+ * @param hi2s pointer to a I2S_HandleTypeDef structure that contains
+ * the configuration information for I2S module
+ * @param pData a 16-bit pointer to data buffer.
+ * @param Size number of data sample to be sent:
+ * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
+ * configuration phase, the Size parameter means the number of 16-bit data length
+ * in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
+ * the Size parameter means the number of 16-bit data length.
+ * @param Timeout Timeout duration
+ * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
+ * between Master and Slave(example: audio streaming).
+ * @note In I2S Master Receiver mode, just after enabling the peripheral the clock will be generate
+ * in continuous way and as the I2S is not disabled at the end of the I2S transaction.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_I2S_Receive(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size, uint32_t Timeout)
+{
+ uint32_t tmpreg_cfgr;
+
+ if ((pData == NULL) || (Size == 0U))
+ {
+ return HAL_ERROR;
+ }
+
+ /* Process Locked */
+ __HAL_LOCK(hi2s);
+
+ if (hi2s->State != HAL_I2S_STATE_READY)
+ {
+ __HAL_UNLOCK(hi2s);
+ return HAL_BUSY;
+ }
+
+ /* Set state and reset error code */
+ hi2s->State = HAL_I2S_STATE_BUSY_RX;
+ hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
+ hi2s->pRxBuffPtr = pData;
+
+ tmpreg_cfgr = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN);
+
+ if ((tmpreg_cfgr == I2S_DATAFORMAT_24B) || (tmpreg_cfgr == I2S_DATAFORMAT_32B))
+ {
+ hi2s->RxXferSize = (Size << 1U);
+ hi2s->RxXferCount = (Size << 1U);
+ }
+ else
+ {
+ hi2s->RxXferSize = Size;
+ hi2s->RxXferCount = Size;
+ }
+
+ /* Check if the I2S is already enabled */
+ if ((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE)
+ {
+ /* Enable I2S peripheral */
+ __HAL_I2S_ENABLE(hi2s);
+ }
+
+ /* Check if Master Receiver mode is selected */
+ if ((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_MASTER_RX)
+ {
+ /* Clear the Overrun Flag by a read operation on the SPI_DR register followed by a read
+ access to the SPI_SR register. */
+ __HAL_I2S_CLEAR_OVRFLAG(hi2s);
+ }
+
+ /* Receive data */
+ while (hi2s->RxXferCount > 0U)
+ {
+ /* Wait until RXNE flag is set */
+ if (I2S_WaitFlagStateUntilTimeout(hi2s, I2S_FLAG_RXNE, SET, Timeout) != HAL_OK)
+ {
+ /* Set the error code */
+ SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_TIMEOUT);
+ hi2s->State = HAL_I2S_STATE_READY;
+ __HAL_UNLOCK(hi2s);
+ return HAL_ERROR;
+ }
+
+ (*hi2s->pRxBuffPtr) = (uint16_t)hi2s->Instance->DR;
+ hi2s->pRxBuffPtr++;
+ hi2s->RxXferCount--;
+
+ /* Check if an overrun occurs */
+ if (__HAL_I2S_GET_FLAG(hi2s, I2S_FLAG_OVR) == SET)
+ {
+ /* Clear overrun flag */
+ __HAL_I2S_CLEAR_OVRFLAG(hi2s);
+
+ /* Set the error code */
+ SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_OVR);
+ }
+ }
+
+ hi2s->State = HAL_I2S_STATE_READY;
+ __HAL_UNLOCK(hi2s);
+ return HAL_OK;
+}
+
+/**
+ * @brief Transmit an amount of data in non-blocking mode with Interrupt
+ * @param hi2s pointer to a I2S_HandleTypeDef structure that contains
+ * the configuration information for I2S module
+ * @param pData a 16-bit pointer to data buffer.
+ * @param Size number of data sample to be sent:
+ * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
+ * configuration phase, the Size parameter means the number of 16-bit data length
+ * in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
+ * the Size parameter means the number of 16-bit data length.
+ * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
+ * between Master and Slave(example: audio streaming).
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_I2S_Transmit_IT(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size)
+{
+ uint32_t tmpreg_cfgr;
+
+ if ((pData == NULL) || (Size == 0U))
+ {
+ return HAL_ERROR;
+ }
+
+ /* Process Locked */
+ __HAL_LOCK(hi2s);
+
+ if (hi2s->State != HAL_I2S_STATE_READY)
+ {
+ __HAL_UNLOCK(hi2s);
+ return HAL_BUSY;
+ }
+
+ /* Set state and reset error code */
+ hi2s->State = HAL_I2S_STATE_BUSY_TX;
+ hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
+ hi2s->pTxBuffPtr = pData;
+
+ tmpreg_cfgr = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN);
+
+ if ((tmpreg_cfgr == I2S_DATAFORMAT_24B) || (tmpreg_cfgr == I2S_DATAFORMAT_32B))
+ {
+ hi2s->TxXferSize = (Size << 1U);
+ hi2s->TxXferCount = (Size << 1U);
+ }
+ else
+ {
+ hi2s->TxXferSize = Size;
+ hi2s->TxXferCount = Size;
+ }
+
+ /* Enable TXE and ERR interrupt */
+ __HAL_I2S_ENABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR));
+
+ /* Check if the I2S is already enabled */
+ if ((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE)
+ {
+ /* Enable I2S peripheral */
+ __HAL_I2S_ENABLE(hi2s);
+ }
+
+ __HAL_UNLOCK(hi2s);
+ return HAL_OK;
+}
+
+/**
+ * @brief Receive an amount of data in non-blocking mode with Interrupt
+ * @param hi2s pointer to a I2S_HandleTypeDef structure that contains
+ * the configuration information for I2S module
+ * @param pData a 16-bit pointer to the Receive data buffer.
+ * @param Size number of data sample to be sent:
+ * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
+ * configuration phase, the Size parameter means the number of 16-bit data length
+ * in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
+ * the Size parameter means the number of 16-bit data length.
+ * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
+ * between Master and Slave(example: audio streaming).
+ * @note It is recommended to use DMA for the I2S receiver to avoid de-synchronization
+ * between Master and Slave otherwise the I2S interrupt should be optimized.
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_I2S_Receive_IT(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size)
+{
+ uint32_t tmpreg_cfgr;
+
+ if ((pData == NULL) || (Size == 0U))
+ {
+ return HAL_ERROR;
+ }
+
+ /* Process Locked */
+ __HAL_LOCK(hi2s);
+
+ if (hi2s->State != HAL_I2S_STATE_READY)
+ {
+ __HAL_UNLOCK(hi2s);
+ return HAL_BUSY;
+ }
+
+ /* Set state and reset error code */
+ hi2s->State = HAL_I2S_STATE_BUSY_RX;
+ hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
+ hi2s->pRxBuffPtr = pData;
+
+ tmpreg_cfgr = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN);
+
+ if ((tmpreg_cfgr == I2S_DATAFORMAT_24B) || (tmpreg_cfgr == I2S_DATAFORMAT_32B))
+ {
+ hi2s->RxXferSize = (Size << 1U);
+ hi2s->RxXferCount = (Size << 1U);
+ }
+ else
+ {
+ hi2s->RxXferSize = Size;
+ hi2s->RxXferCount = Size;
+ }
+
+ /* Enable RXNE and ERR interrupt */
+ __HAL_I2S_ENABLE_IT(hi2s, (I2S_IT_RXNE | I2S_IT_ERR));
+
+ /* Check if the I2S is already enabled */
+ if ((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE)
+ {
+ /* Enable I2S peripheral */
+ __HAL_I2S_ENABLE(hi2s);
+ }
+
+ __HAL_UNLOCK(hi2s);
+ return HAL_OK;
+}
+
+/**
+ * @brief Transmit an amount of data in non-blocking mode with DMA
+ * @param hi2s pointer to a I2S_HandleTypeDef structure that contains
+ * the configuration information for I2S module
+ * @param pData a 16-bit pointer to the Transmit data buffer.
+ * @param Size number of data sample to be sent:
+ * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
+ * configuration phase, the Size parameter means the number of 16-bit data length
+ * in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
+ * the Size parameter means the number of 16-bit data length.
+ * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
+ * between Master and Slave(example: audio streaming).
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_I2S_Transmit_DMA(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size)
+{
+ uint32_t tmpreg_cfgr;
+
+ if ((pData == NULL) || (Size == 0U))
+ {
+ return HAL_ERROR;
+ }
+
+ /* Process Locked */
+ __HAL_LOCK(hi2s);
+
+ if (hi2s->State != HAL_I2S_STATE_READY)
+ {
+ __HAL_UNLOCK(hi2s);
+ return HAL_BUSY;
+ }
+
+ /* Set state and reset error code */
+ hi2s->State = HAL_I2S_STATE_BUSY_TX;
+ hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
+ hi2s->pTxBuffPtr = pData;
+
+ tmpreg_cfgr = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN);
+
+ if ((tmpreg_cfgr == I2S_DATAFORMAT_24B) || (tmpreg_cfgr == I2S_DATAFORMAT_32B))
+ {
+ hi2s->TxXferSize = (Size << 1U);
+ hi2s->TxXferCount = (Size << 1U);
+ }
+ else
+ {
+ hi2s->TxXferSize = Size;
+ hi2s->TxXferCount = Size;
+ }
+
+ /* Set the I2S Tx DMA Half transfer complete callback */
+ hi2s->hdmatx->XferHalfCpltCallback = I2S_DMATxHalfCplt;
+
+ /* Set the I2S Tx DMA transfer complete callback */
+ hi2s->hdmatx->XferCpltCallback = I2S_DMATxCplt;
+
+ /* Set the DMA error callback */
+ hi2s->hdmatx->XferErrorCallback = I2S_DMAError;
+
+ /* Enable the Tx DMA Stream/Channel */
+ if (HAL_OK != HAL_DMA_Start_IT(hi2s->hdmatx, (uint32_t)hi2s->pTxBuffPtr, (uint32_t)&hi2s->Instance->DR, hi2s->TxXferSize))
+ {
+ /* Update SPI error code */
+ SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_DMA);
+ hi2s->State = HAL_I2S_STATE_READY;
+
+ __HAL_UNLOCK(hi2s);
+ return HAL_ERROR;
+ }
+
+ /* Check if the I2S is already enabled */
+ if (HAL_IS_BIT_CLR(hi2s->Instance->I2SCFGR, SPI_I2SCFGR_I2SE))
+ {
+ /* Enable I2S peripheral */
+ __HAL_I2S_ENABLE(hi2s);
+ }
+
+ /* Check if the I2S Tx request is already enabled */
+ if (HAL_IS_BIT_CLR(hi2s->Instance->CR2, SPI_CR2_TXDMAEN))
+ {
+ /* Enable Tx DMA Request */
+ SET_BIT(hi2s->Instance->CR2, SPI_CR2_TXDMAEN);
+ }
+
+ __HAL_UNLOCK(hi2s);
+ return HAL_OK;
+}
+
+/**
+ * @brief Receive an amount of data in non-blocking mode with DMA
+ * @param hi2s pointer to a I2S_HandleTypeDef structure that contains
+ * the configuration information for I2S module
+ * @param pData a 16-bit pointer to the Receive data buffer.
+ * @param Size number of data sample to be sent:
+ * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
+ * configuration phase, the Size parameter means the number of 16-bit data length
+ * in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
+ * the Size parameter means the number of 16-bit data length.
+ * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
+ * between Master and Slave(example: audio streaming).
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_I2S_Receive_DMA(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size)
+{
+ uint32_t tmpreg_cfgr;
+
+ if ((pData == NULL) || (Size == 0U))
+ {
+ return HAL_ERROR;
+ }
+
+ /* Process Locked */
+ __HAL_LOCK(hi2s);
+
+ if (hi2s->State != HAL_I2S_STATE_READY)
+ {
+ __HAL_UNLOCK(hi2s);
+ return HAL_BUSY;
+ }
+
+ /* Set state and reset error code */
+ hi2s->State = HAL_I2S_STATE_BUSY_RX;
+ hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
+ hi2s->pRxBuffPtr = pData;
+
+ tmpreg_cfgr = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN);
+
+ if ((tmpreg_cfgr == I2S_DATAFORMAT_24B) || (tmpreg_cfgr == I2S_DATAFORMAT_32B))
+ {
+ hi2s->RxXferSize = (Size << 1U);
+ hi2s->RxXferCount = (Size << 1U);
+ }
+ else
+ {
+ hi2s->RxXferSize = Size;
+ hi2s->RxXferCount = Size;
+ }
+
+ /* Set the I2S Rx DMA Half transfer complete callback */
+ hi2s->hdmarx->XferHalfCpltCallback = I2S_DMARxHalfCplt;
+
+ /* Set the I2S Rx DMA transfer complete callback */
+ hi2s->hdmarx->XferCpltCallback = I2S_DMARxCplt;
+
+ /* Set the DMA error callback */
+ hi2s->hdmarx->XferErrorCallback = I2S_DMAError;
+
+ /* Check if Master Receiver mode is selected */
+ if ((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_MASTER_RX)
+ {
+ /* Clear the Overrun Flag by a read operation to the SPI_DR register followed by a read
+ access to the SPI_SR register. */
+ __HAL_I2S_CLEAR_OVRFLAG(hi2s);
+ }
+
+ /* Enable the Rx DMA Stream/Channel */
+ if (HAL_OK != HAL_DMA_Start_IT(hi2s->hdmarx, (uint32_t)&hi2s->Instance->DR, (uint32_t)hi2s->pRxBuffPtr, hi2s->RxXferSize))
+ {
+ /* Update SPI error code */
+ SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_DMA);
+ hi2s->State = HAL_I2S_STATE_READY;
+
+ __HAL_UNLOCK(hi2s);
+ return HAL_ERROR;
+ }
+
+ /* Check if the I2S is already enabled */
+ if (HAL_IS_BIT_CLR(hi2s->Instance->I2SCFGR, SPI_I2SCFGR_I2SE))
+ {
+ /* Enable I2S peripheral */
+ __HAL_I2S_ENABLE(hi2s);
+ }
+
+ /* Check if the I2S Rx request is already enabled */
+ if (HAL_IS_BIT_CLR(hi2s->Instance->CR2, SPI_CR2_RXDMAEN))
+ {
+ /* Enable Rx DMA Request */
+ SET_BIT(hi2s->Instance->CR2, SPI_CR2_RXDMAEN);
+ }
+
+ __HAL_UNLOCK(hi2s);
+ return HAL_OK;
+}
+
+/**
+ * @brief Pauses the audio DMA Stream/Channel playing from the Media.
+ * @param hi2s pointer to a I2S_HandleTypeDef structure that contains
+ * the configuration information for I2S module
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_I2S_DMAPause(I2S_HandleTypeDef *hi2s)
+{
+ /* Process Locked */
+ __HAL_LOCK(hi2s);
+
+ if (hi2s->State == HAL_I2S_STATE_BUSY_TX)
+ {
+ /* Disable the I2S DMA Tx request */
+ CLEAR_BIT(hi2s->Instance->CR2, SPI_CR2_TXDMAEN);
+ }
+ else if (hi2s->State == HAL_I2S_STATE_BUSY_RX)
+ {
+ /* Disable the I2S DMA Rx request */
+ CLEAR_BIT(hi2s->Instance->CR2, SPI_CR2_RXDMAEN);
+ }
+#if defined (SPI_I2S_FULLDUPLEX_SUPPORT)
+ else if (hi2s->State == HAL_I2S_STATE_BUSY_TX_RX)
+ {
+ /* Pause the audio file playing by disabling the I2S DMA request */
+ CLEAR_BIT(hi2s->Instance->CR2, (SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN));
+ CLEAR_BIT(I2SxEXT(hi2s->Instance)->CR2, (SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN));
+ }
+#endif /* SPI_I2S_FULLDUPLEX_SUPPORT */
+ else
+ {
+ /* nothing to do */
+ }
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2s);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Resumes the audio DMA Stream/Channel playing from the Media.
+ * @param hi2s pointer to a I2S_HandleTypeDef structure that contains
+ * the configuration information for I2S module
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_I2S_DMAResume(I2S_HandleTypeDef *hi2s)
+{
+ /* Process Locked */
+ __HAL_LOCK(hi2s);
+
+ if (hi2s->State == HAL_I2S_STATE_BUSY_TX)
+ {
+ /* Enable the I2S DMA Tx request */
+ SET_BIT(hi2s->Instance->CR2, SPI_CR2_TXDMAEN);
+ }
+ else if (hi2s->State == HAL_I2S_STATE_BUSY_RX)
+ {
+ /* Enable the I2S DMA Rx request */
+ SET_BIT(hi2s->Instance->CR2, SPI_CR2_RXDMAEN);
+ }
+#if defined (SPI_I2S_FULLDUPLEX_SUPPORT)
+ else if (hi2s->State == HAL_I2S_STATE_BUSY_TX_RX)
+ {
+ /* Pause the audio file playing by disabling the I2S DMA request */
+ SET_BIT(hi2s->Instance->CR2, (SPI_CR2_RXDMAEN | SPI_CR2_TXDMAEN));
+ SET_BIT(I2SxEXT(hi2s->Instance)->CR2, (SPI_CR2_RXDMAEN | SPI_CR2_TXDMAEN));
+
+ /* If the I2Sext peripheral is still not enabled, enable it */
+ if ((I2SxEXT(hi2s->Instance)->I2SCFGR & SPI_I2SCFGR_I2SE) == 0U)
+ {
+ /* Enable I2Sext peripheral */
+ __HAL_I2SEXT_ENABLE(hi2s);
+ }
+ }
+#endif /* SPI_I2S_FULLDUPLEX_SUPPORT */
+ else
+ {
+ /* nothing to do */
+ }
+
+ /* If the I2S peripheral is still not enabled, enable it */
+ if (HAL_IS_BIT_CLR(hi2s->Instance->I2SCFGR, SPI_I2SCFGR_I2SE))
+ {
+ /* Enable I2S peripheral */
+ __HAL_I2S_ENABLE(hi2s);
+ }
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2s);
+
+ return HAL_OK;
+}
+
+/**
+ * @brief Stops the audio DMA Stream/Channel playing from the Media.
+ * @param hi2s pointer to a I2S_HandleTypeDef structure that contains
+ * the configuration information for I2S module
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_I2S_DMAStop(I2S_HandleTypeDef *hi2s)
+{
+ HAL_StatusTypeDef errorcode = HAL_OK;
+ /* The Lock is not implemented on this API to allow the user application
+ to call the HAL SPI API under callbacks HAL_I2S_TxCpltCallback() or HAL_I2S_RxCpltCallback()
+ when calling HAL_DMA_Abort() API the DMA TX or RX Transfer complete interrupt is generated
+ and the correspond call back is executed HAL_I2S_TxCpltCallback() or HAL_I2S_RxCpltCallback()
+ */
+
+ /* Disable the I2S Tx/Rx DMA requests */
+ CLEAR_BIT(hi2s->Instance->CR2, SPI_CR2_TXDMAEN);
+ CLEAR_BIT(hi2s->Instance->CR2, SPI_CR2_RXDMAEN);
+
+ /* Abort the I2S DMA tx Stream/Channel */
+ if (hi2s->hdmatx != NULL)
+ {
+ /* Disable the I2S DMA tx Stream/Channel */
+ if (HAL_OK != HAL_DMA_Abort(hi2s->hdmatx))
+ {
+ SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_DMA);
+ errorcode = HAL_ERROR;
+ }
+ }
+
+ /* Abort the I2S DMA rx Stream/Channel */
+ if (hi2s->hdmarx != NULL)
+ {
+ /* Disable the I2S DMA rx Stream/Channel */
+ if (HAL_OK != HAL_DMA_Abort(hi2s->hdmarx))
+ {
+ SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_DMA);
+ errorcode = HAL_ERROR;
+ }
+ }
+#if defined (SPI_I2S_FULLDUPLEX_SUPPORT)
+ /* In case of Full-Duplex, disable the I2SxEXT Tx/Rx DMA requests*/
+ if (hi2s->State == HAL_I2S_STATE_BUSY_TX_RX)
+ {
+ /* Disable the I2SxEXT DMA requests */
+ CLEAR_BIT(I2SxEXT(hi2s->Instance)->CR2, SPI_CR2_TXDMAEN);
+ CLEAR_BIT(I2SxEXT(hi2s->Instance)->CR2, SPI_CR2_RXDMAEN);
+
+ /* Disable I2Sext peripheral */
+ __HAL_I2SEXT_DISABLE(hi2s);
+ }
+#endif /* SPI_I2S_FULLDUPLEX_SUPPORT */
+
+ /* Disable I2S peripheral */
+ __HAL_I2S_DISABLE(hi2s);
+
+ hi2s->State = HAL_I2S_STATE_READY;
+
+ return errorcode;
+}
+
+/**
+ * @brief This function handles I2S interrupt request.
+ * @param hi2s pointer to a I2S_HandleTypeDef structure that contains
+ * the configuration information for I2S module
+ * @retval None
+ */
+void HAL_I2S_IRQHandler(I2S_HandleTypeDef *hi2s)
+{
+ /* Call the IrqHandler ISR set during HAL_I2S_INIT */
+ hi2s->IrqHandlerISR(hi2s);
+}
+
+/**
+ * @brief Tx Transfer Half completed callbacks
+ * @param hi2s pointer to a I2S_HandleTypeDef structure that contains
+ * the configuration information for I2S module
+ * @retval None
+ */
+__weak void HAL_I2S_TxHalfCpltCallback(I2S_HandleTypeDef *hi2s)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hi2s);
+
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_I2S_TxHalfCpltCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @brief Tx Transfer completed callbacks
+ * @param hi2s pointer to a I2S_HandleTypeDef structure that contains
+ * the configuration information for I2S module
+ * @retval None
+ */
+__weak void HAL_I2S_TxCpltCallback(I2S_HandleTypeDef *hi2s)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hi2s);
+
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_I2S_TxCpltCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @brief Rx Transfer half completed callbacks
+ * @param hi2s pointer to a I2S_HandleTypeDef structure that contains
+ * the configuration information for I2S module
+ * @retval None
+ */
+__weak void HAL_I2S_RxHalfCpltCallback(I2S_HandleTypeDef *hi2s)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hi2s);
+
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_I2S_RxHalfCpltCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @brief Rx Transfer completed callbacks
+ * @param hi2s pointer to a I2S_HandleTypeDef structure that contains
+ * the configuration information for I2S module
+ * @retval None
+ */
+__weak void HAL_I2S_RxCpltCallback(I2S_HandleTypeDef *hi2s)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hi2s);
+
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_I2S_RxCpltCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @brief I2S error callbacks
+ * @param hi2s pointer to a I2S_HandleTypeDef structure that contains
+ * the configuration information for I2S module
+ * @retval None
+ */
+__weak void HAL_I2S_ErrorCallback(I2S_HandleTypeDef *hi2s)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hi2s);
+
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_I2S_ErrorCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @}
+ */
+
+/** @defgroup I2S_Exported_Functions_Group3 Peripheral State and Errors functions
+ * @brief Peripheral State functions
+ *
+@verbatim
+ ===============================================================================
+ ##### Peripheral State and Errors functions #####
+ ===============================================================================
+ [..]
+ This subsection permits to get in run-time the status of the peripheral
+ and the data flow.
+
+@endverbatim
+ * @{
+ */
+
+/**
+ * @brief Return the I2S state
+ * @param hi2s pointer to a I2S_HandleTypeDef structure that contains
+ * the configuration information for I2S module
+ * @retval HAL state
+ */
+HAL_I2S_StateTypeDef HAL_I2S_GetState(I2S_HandleTypeDef *hi2s)
+{
+ return hi2s->State;
+}
+
+/**
+ * @brief Return the I2S error code
+ * @param hi2s pointer to a I2S_HandleTypeDef structure that contains
+ * the configuration information for I2S module
+ * @retval I2S Error Code
+ */
+uint32_t HAL_I2S_GetError(I2S_HandleTypeDef *hi2s)
+{
+ return hi2s->ErrorCode;
+}
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/** @addtogroup I2S_Private_Functions I2S Private Functions
+ * @{
+ */
+/**
+ * @brief DMA I2S 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 I2S_DMATxCplt(DMA_HandleTypeDef *hdma)
+{
+ I2S_HandleTypeDef *hi2s = (I2S_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; /* Derogation MISRAC2012-Rule-11.5 */
+
+ /* if DMA is configured in DMA_NORMAL Mode */
+ if (hdma->Init.Mode == DMA_NORMAL)
+ {
+ /* Disable Tx DMA Request */
+ CLEAR_BIT(hi2s->Instance->CR2, SPI_CR2_TXDMAEN);
+
+ hi2s->TxXferCount = 0U;
+ hi2s->State = HAL_I2S_STATE_READY;
+ }
+ /* Call user Tx complete callback */
+#if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
+ hi2s->TxCpltCallback(hi2s);
+#else
+ HAL_I2S_TxCpltCallback(hi2s);
+#endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
+}
+
+/**
+ * @brief DMA I2S transmit process half complete callback
+ * @param hdma pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA module.
+ * @retval None
+ */
+static void I2S_DMATxHalfCplt(DMA_HandleTypeDef *hdma)
+{
+ I2S_HandleTypeDef *hi2s = (I2S_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; /* Derogation MISRAC2012-Rule-11.5 */
+
+ /* Call user Tx half complete callback */
+#if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
+ hi2s->TxHalfCpltCallback(hi2s);
+#else
+ HAL_I2S_TxHalfCpltCallback(hi2s);
+#endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
+}
+
+/**
+ * @brief DMA I2S 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 I2S_DMARxCplt(DMA_HandleTypeDef *hdma)
+{
+ I2S_HandleTypeDef *hi2s = (I2S_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; /* Derogation MISRAC2012-Rule-11.5 */
+
+ /* if DMA is configured in DMA_NORMAL Mode */
+ if (hdma->Init.Mode == DMA_NORMAL)
+ {
+ /* Disable Rx DMA Request */
+ CLEAR_BIT(hi2s->Instance->CR2, SPI_CR2_RXDMAEN);
+ hi2s->RxXferCount = 0U;
+ hi2s->State = HAL_I2S_STATE_READY;
+ }
+ /* Call user Rx complete callback */
+#if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
+ hi2s->RxCpltCallback(hi2s);
+#else
+ HAL_I2S_RxCpltCallback(hi2s);
+#endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
+}
+
+/**
+ * @brief DMA I2S receive process half complete callback
+ * @param hdma pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA module.
+ * @retval None
+ */
+static void I2S_DMARxHalfCplt(DMA_HandleTypeDef *hdma)
+{
+ I2S_HandleTypeDef *hi2s = (I2S_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; /* Derogation MISRAC2012-Rule-11.5 */
+
+ /* Call user Rx half complete callback */
+#if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
+ hi2s->RxHalfCpltCallback(hi2s);
+#else
+ HAL_I2S_RxHalfCpltCallback(hi2s);
+#endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
+}
+
+/**
+ * @brief DMA I2S 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 I2S_DMAError(DMA_HandleTypeDef *hdma)
+{
+ I2S_HandleTypeDef *hi2s = (I2S_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; /* Derogation MISRAC2012-Rule-11.5 */
+
+ /* Disable Rx and Tx DMA Request */
+ CLEAR_BIT(hi2s->Instance->CR2, (SPI_CR2_RXDMAEN | SPI_CR2_TXDMAEN));
+ hi2s->TxXferCount = 0U;
+ hi2s->RxXferCount = 0U;
+
+ hi2s->State = HAL_I2S_STATE_READY;
+
+ /* Set the error code and execute error callback*/
+ SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_DMA);
+ /* Call user error callback */
+#if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
+ hi2s->ErrorCallback(hi2s);
+#else
+ HAL_I2S_ErrorCallback(hi2s);
+#endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
+}
+
+/**
+ * @brief Transmit an amount of data in non-blocking mode with Interrupt
+ * @param hi2s pointer to a I2S_HandleTypeDef structure that contains
+ * the configuration information for I2S module
+ * @retval None
+ */
+static void I2S_Transmit_IT(I2S_HandleTypeDef *hi2s)
+{
+ /* Transmit data */
+ hi2s->Instance->DR = (*hi2s->pTxBuffPtr);
+ hi2s->pTxBuffPtr++;
+ hi2s->TxXferCount--;
+
+ if (hi2s->TxXferCount == 0U)
+ {
+ /* Disable TXE and ERR interrupt */
+ __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR));
+
+ hi2s->State = HAL_I2S_STATE_READY;
+ /* Call user Tx complete callback */
+#if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
+ hi2s->TxCpltCallback(hi2s);
+#else
+ HAL_I2S_TxCpltCallback(hi2s);
+#endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
+ }
+}
+
+/**
+ * @brief Receive an amount of data in non-blocking mode with Interrupt
+ * @param hi2s pointer to a I2S_HandleTypeDef structure that contains
+ * the configuration information for I2S module
+ * @retval None
+ */
+static void I2S_Receive_IT(I2S_HandleTypeDef *hi2s)
+{
+ /* Receive data */
+ (*hi2s->pRxBuffPtr) = (uint16_t)hi2s->Instance->DR;
+ hi2s->pRxBuffPtr++;
+ hi2s->RxXferCount--;
+
+ if (hi2s->RxXferCount == 0U)
+ {
+ /* Disable RXNE and ERR interrupt */
+ __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_RXNE | I2S_IT_ERR));
+
+ hi2s->State = HAL_I2S_STATE_READY;
+ /* Call user Rx complete callback */
+#if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
+ hi2s->RxCpltCallback(hi2s);
+#else
+ HAL_I2S_RxCpltCallback(hi2s);
+#endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
+ }
+}
+
+/**
+ * @brief This function handles I2S interrupt request.
+ * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
+ * the configuration information for I2S module
+ * @retval None
+ */
+static void I2S_IRQHandler(I2S_HandleTypeDef *hi2s)
+{
+ __IO uint32_t i2ssr = hi2s->Instance->SR;
+
+ if (hi2s->State == HAL_I2S_STATE_BUSY_RX)
+ {
+ /* I2S in mode Receiver ------------------------------------------------*/
+ if (((i2ssr & I2S_FLAG_RXNE) == I2S_FLAG_RXNE) && (__HAL_I2S_GET_IT_SOURCE(hi2s, I2S_IT_RXNE) != RESET))
+ {
+ I2S_Receive_IT(hi2s);
+ }
+
+ /* I2S Overrun error interrupt occurred -------------------------------------*/
+ if (((i2ssr & I2S_FLAG_OVR) == I2S_FLAG_OVR) && (__HAL_I2S_GET_IT_SOURCE(hi2s, I2S_IT_ERR) != RESET))
+ {
+ /* Disable RXNE and ERR interrupt */
+ __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_RXNE | I2S_IT_ERR));
+
+ /* Clear Overrun flag */
+ __HAL_I2S_CLEAR_OVRFLAG(hi2s);
+
+ /* Set the I2S State ready */
+ hi2s->State = HAL_I2S_STATE_READY;
+
+
+ /* Set the error code and execute error callback*/
+ SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_OVR);
+ /* Call user error callback */
+#if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
+ hi2s->ErrorCallback(hi2s);
+#else
+ HAL_I2S_ErrorCallback(hi2s);
+#endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
+ }
+ }
+
+ if (hi2s->State == HAL_I2S_STATE_BUSY_TX)
+ {
+ /* I2S in mode Transmitter -----------------------------------------------*/
+ if (((i2ssr & I2S_FLAG_TXE) == I2S_FLAG_TXE) && (__HAL_I2S_GET_IT_SOURCE(hi2s, I2S_IT_TXE) != RESET))
+ {
+ I2S_Transmit_IT(hi2s);
+ }
+
+ /* I2S Underrun error interrupt occurred --------------------------------*/
+ if (((i2ssr & I2S_FLAG_UDR) == I2S_FLAG_UDR) && (__HAL_I2S_GET_IT_SOURCE(hi2s, I2S_IT_ERR) != RESET))
+ {
+ /* Disable TXE and ERR interrupt */
+ __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR));
+
+ /* Clear Underrun flag */
+ __HAL_I2S_CLEAR_UDRFLAG(hi2s);
+
+ /* Set the I2S State ready */
+ hi2s->State = HAL_I2S_STATE_READY;
+
+ /* Set the error code and execute error callback*/
+ SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_UDR);
+ /* Call user error callback */
+#if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
+ hi2s->ErrorCallback(hi2s);
+#else
+ HAL_I2S_ErrorCallback(hi2s);
+#endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
+ }
+ }
+}
+
+/**
+ * @brief This function handles I2S Communication Timeout.
+ * @param hi2s pointer to a I2S_HandleTypeDef structure that contains
+ * the configuration information for I2S module
+ * @param Flag Flag checked
+ * @param State Value of the flag expected
+ * @param Timeout Duration of the timeout
+ * @retval HAL status
+ */
+static HAL_StatusTypeDef I2S_WaitFlagStateUntilTimeout(I2S_HandleTypeDef *hi2s, uint32_t Flag, FlagStatus State, uint32_t Timeout)
+{
+ uint32_t tickstart;
+
+ /* Get tick */
+ tickstart = HAL_GetTick();
+
+ /* Wait until flag is set to status*/
+ while (((__HAL_I2S_GET_FLAG(hi2s, Flag)) ? SET : RESET) != State)
+ {
+ if (Timeout != HAL_MAX_DELAY)
+ {
+ if (((HAL_GetTick() - tickstart) >= Timeout) || (Timeout == 0U))
+ {
+ /* Set the I2S State ready */
+ hi2s->State = HAL_I2S_STATE_READY;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2s);
+
+ return HAL_TIMEOUT;
+ }
+ }
+ }
+ return HAL_OK;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#endif /* HAL_I2S_MODULE_ENABLED */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/port/stm32-f4discovery-cc256x-2/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2s_ex.c b/port/stm32-f4discovery-cc256x-2/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2s_ex.c
new file mode 100644
index 000000000..92ae3485f
--- /dev/null
+++ b/port/stm32-f4discovery-cc256x-2/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2s_ex.c
@@ -0,0 +1,1152 @@
+/**
+ ******************************************************************************
+ * @file stm32f4xx_hal_i2s_ex.c
+ * @author MCD Application Team
+ * @brief I2S HAL module driver.
+ * This file provides firmware functions to manage the following
+ * functionalities of I2S extension peripheral:
+ * + Extension features Functions
+ *
+ @verbatim
+ ==============================================================================
+ ##### I2S Extension features #####
+ ==============================================================================
+ [..]
+ (#) In I2S full duplex mode, each SPI peripheral is able to manage sending and receiving
+ data simultaneously using two data lines. Each SPI peripheral has an extended block
+ called I2Sxext (i.e I2S2ext for SPI2 and I2S3ext for SPI3).
+ (#) The extension block is not a full SPI IP, it is used only as I2S slave to
+ implement full duplex mode. The extension block uses the same clock sources
+ as its master.
+
+ (#) Both I2Sx and I2Sx_ext can be configured as transmitters or receivers.
+
+ [..]
+ (@) Only I2Sx can deliver SCK and WS to I2Sx_ext in full duplex mode, where
+ I2Sx can be I2S2 or I2S3.
+
+ ##### How to use this driver #####
+ ===============================================================================
+ [..]
+ Three operation modes are available within this driver :
+
+ *** Polling mode IO operation ***
+ =================================
+ [..]
+ (+) Send and receive in the same time an amount of data in blocking mode using HAL_I2SEx_TransmitReceive()
+
+ *** Interrupt mode IO operation ***
+ ===================================
+ [..]
+ (+) Send and receive in the same time an amount of data in non blocking mode using HAL_I2SEx_TransmitReceive_IT()
+ (+) At transmission/reception end of transfer HAL_I2SEx_TxRxCpltCallback is executed and user can
+ add his own code by customization of function pointer HAL_I2SEx_TxRxCpltCallback
+ (+) In case of transfer Error, HAL_I2S_ErrorCallback() function is executed and user can
+ add his own code by customization of function pointer HAL_I2S_ErrorCallback
+
+ *** DMA mode IO operation ***
+ ==============================
+ [..]
+ (+) Send and receive an amount of data in non blocking mode (DMA) using HAL_I2SEx_TransmitReceive_DMA()
+ (+) At transmission/reception end of transfer HAL_I2SEx_TxRxCpltCallback is executed and user can
+ add his own code by customization of function pointer HAL_I2S_TxRxCpltCallback
+ (+) In case of transfer Error, HAL_I2S_ErrorCallback() function is executed and user can
+ add his own code by customization of function pointer HAL_I2S_ErrorCallback
+ @endverbatim
+
+ Additional Figure: The Extended block uses the same clock sources as its master.
+
+ +-----------------------+
+ I2Sx_SCK | |
+ ----------+-->| I2Sx |------------------->I2Sx_SD(in/out)
+ +--|-->| |
+ | | +-----------------------+
+ | |
+ I2S_WS | |
+ ------>| |
+ | | +-----------------------+
+ | +-->| |
+ | | I2Sx_ext |------------------->I2Sx_extSD(in/out)
+ +----->| |
+ +-----------------------+
+ ******************************************************************************
+ * @attention
+ *
+ * © Copyright (c) 2016 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software component is licensed by ST under BSD 3-Clause license,
+ * the "License"; You may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ * opensource.org/licenses/BSD-3-Clause
+ *
+ ******************************************************************************
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32f4xx_hal.h"
+
+/** @addtogroup STM32F4xx_HAL_Driver
+ * @{
+ */
+
+#ifdef HAL_I2S_MODULE_ENABLED
+
+/** @defgroup I2SEx I2SEx
+ * @brief I2S Extended HAL module driver
+ * @{
+ */
+
+#if defined (SPI_I2S_FULLDUPLEX_SUPPORT)
+
+/* Private typedef -----------------------------------------------------------*/
+/** @defgroup I2SEx_Private_Typedef I2S Extended Private Typedef
+ * @{
+ */
+typedef enum
+{
+ I2S_USE_I2S = 0x00U, /*!< I2Sx should be used */
+ I2S_USE_I2SEXT = 0x01U, /*!< I2Sx_ext should be used */
+} I2S_UseTypeDef;
+/**
+ * @}
+ */
+/* Private define ------------------------------------------------------------*/
+/* Private macro -------------------------------------------------------------*/
+/* Private variables ---------------------------------------------------------*/
+/* Private function prototypes -----------------------------------------------*/
+/** @defgroup I2SEx_Private_Functions I2S Extended Private Functions
+ * @{
+ */
+static void I2SEx_TxRxDMAHalfCplt(DMA_HandleTypeDef *hdma);
+static void I2SEx_TxRxDMACplt(DMA_HandleTypeDef *hdma);
+static void I2SEx_TxRxDMAError(DMA_HandleTypeDef *hdma);
+static void I2SEx_RxISR_I2S(I2S_HandleTypeDef *hi2s);
+static void I2SEx_RxISR_I2SExt(I2S_HandleTypeDef *hi2s);
+static void I2SEx_TxISR_I2S(I2S_HandleTypeDef *hi2s);
+static void I2SEx_TxISR_I2SExt(I2S_HandleTypeDef *hi2s);
+static HAL_StatusTypeDef I2SEx_FullDuplexWaitFlagStateUntilTimeout(I2S_HandleTypeDef *hi2s, uint32_t Flag,
+ uint32_t State, uint32_t Timeout, I2S_UseTypeDef i2sUsed);
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/* Private functions ---------------------------------------------------------*/
+/* Exported functions --------------------------------------------------------*/
+
+/** @addtogroup I2SEx I2SEx
+ * @{
+ */
+
+/** @addtogroup I2SEx_Exported_Functions I2S Extended Exported Functions
+ * @{
+ */
+
+/** @defgroup I2SEx_Exported_Functions_Group1 I2S Extended IO operation functions
+ * @brief I2SEx IO operation functions
+ *
+@verbatim
+ ===============================================================================
+ ##### IO operation functions#####
+ ===============================================================================
+ [..]
+ This subsection provides a set of functions allowing to manage the I2S data
+ transfers.
+
+ (#) There are two modes of transfer:
+ (++) Blocking mode : The communication is performed in the polling mode.
+ The 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 functions return the status of the transfer startup.
+ The end of the data processing will be indicated through the
+ dedicated I2S IRQ when using Interrupt mode or the DMA IRQ when
+ using DMA mode.
+
+ (#) Blocking mode functions are :
+ (++) HAL_I2SEx_TransmitReceive()
+
+ (#) No-Blocking mode functions with Interrupt are :
+ (++) HAL_I2SEx_TransmitReceive_IT()
+ (++) HAL_I2SEx_FullDuplex_IRQHandler()
+
+ (#) No-Blocking mode functions with DMA are :
+ (++) HAL_I2SEx_TransmitReceive_DMA()
+
+ (#) A set of Transfer Complete Callback are provided in non Blocking mode:
+ (++) HAL_I2SEx_TxRxCpltCallback()
+@endverbatim
+ * @{
+ */
+/**
+ * @brief Full-Duplex Transmit/Receive data in blocking mode.
+ * @param hi2s pointer to a I2S_HandleTypeDef structure that contains
+ * the configuration information for I2S module
+ * @param pTxData a 16-bit pointer to the Transmit data buffer.
+ * @param pRxData a 16-bit pointer to the Receive data buffer.
+ * @param Size number of data sample to be sent:
+ * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
+ * configuration phase, the Size parameter means the number of 16-bit data length
+ * in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
+ * the Size parameter means the number of 16-bit data length.
+ * @param Timeout Timeout duration
+ * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
+ * between Master and Slave(example: audio streaming).
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_I2SEx_TransmitReceive(I2S_HandleTypeDef *hi2s, uint16_t *pTxData, uint16_t *pRxData,
+ uint16_t Size, uint32_t Timeout)
+{
+ uint32_t tmp1 = 0U;
+ HAL_StatusTypeDef errorcode = HAL_OK;
+
+ if (hi2s->State != HAL_I2S_STATE_READY)
+ {
+ errorcode = HAL_BUSY;
+ goto error;
+ }
+
+ if ((pTxData == NULL) || (pRxData == NULL) || (Size == 0U))
+ {
+ return HAL_ERROR;
+ }
+
+ /* Process Locked */
+ __HAL_LOCK(hi2s);
+
+ tmp1 = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN);
+ /* Check the Data format: When a 16-bit data frame or a 16-bit data frame extended
+ is selected during the I2S configuration phase, the Size parameter means the number
+ of 16-bit data length in the transaction and when a 24-bit data frame or a 32-bit data
+ frame is selected the Size parameter means the number of 16-bit data length. */
+ if ((tmp1 == I2S_DATAFORMAT_24B) || (tmp1 == I2S_DATAFORMAT_32B))
+ {
+ hi2s->TxXferSize = (Size << 1U);
+ hi2s->TxXferCount = (Size << 1U);
+ hi2s->RxXferSize = (Size << 1U);
+ hi2s->RxXferCount = (Size << 1U);
+ }
+ else
+ {
+ hi2s->TxXferSize = Size;
+ hi2s->TxXferCount = Size;
+ hi2s->RxXferSize = Size;
+ hi2s->RxXferCount = Size;
+ }
+
+ /* Set state and reset error code */
+ hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
+ hi2s->State = HAL_I2S_STATE_BUSY_TX_RX;
+
+ tmp1 = hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG;
+ /* Check if the I2S_MODE_MASTER_TX or I2S_MODE_SLAVE_TX Mode is selected */
+ if ((tmp1 == I2S_MODE_MASTER_TX) || (tmp1 == I2S_MODE_SLAVE_TX))
+ {
+ /* Prepare the First Data before enabling the I2S */
+ hi2s->Instance->DR = (*pTxData++);
+ hi2s->TxXferCount--;
+
+ /* Enable I2Sext(receiver) before enabling I2Sx peripheral */
+ __HAL_I2SEXT_ENABLE(hi2s);
+
+ /* Enable I2Sx peripheral */
+ __HAL_I2S_ENABLE(hi2s);
+
+ /* Check if Master Receiver mode is selected */
+ if ((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_MASTER_TX)
+ {
+ /* Clear the Overrun Flag by a read operation on the SPI_DR register followed by a read
+ access to the SPI_SR register. */
+ __HAL_I2SEXT_CLEAR_OVRFLAG(hi2s);
+ }
+
+ while ((hi2s->RxXferCount > 0U) || (hi2s->TxXferCount > 0U))
+ {
+ if (hi2s->TxXferCount > 0U)
+ {
+ /* Wait until TXE flag is set */
+ if (I2SEx_FullDuplexWaitFlagStateUntilTimeout(hi2s, I2S_FLAG_TXE, SET, Timeout, I2S_USE_I2S) != HAL_OK)
+ {
+ /* Set the error code */
+ SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_TIMEOUT);
+ errorcode = HAL_ERROR;
+ goto error;
+ }
+ /* Write Data on DR register */
+ hi2s->Instance->DR = (*pTxData++);
+ hi2s->TxXferCount--;
+
+ /* Check if an underrun occurs */
+ if ((__HAL_I2S_GET_FLAG(hi2s, I2S_FLAG_UDR) == SET) && (tmp1 == I2S_MODE_SLAVE_TX))
+ {
+ /* Clear Underrun flag */
+ __HAL_I2S_CLEAR_UDRFLAG(hi2s);
+
+ /* Set the error code */
+ SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_UDR);
+ }
+ }
+ if (hi2s->RxXferCount > 0U)
+ {
+ /* Wait until RXNE flag is set */
+ if (I2SEx_FullDuplexWaitFlagStateUntilTimeout(hi2s, I2S_FLAG_RXNE, SET, Timeout, I2S_USE_I2SEXT) != HAL_OK)
+ {
+ /* Set the error code */
+ SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_TIMEOUT);
+ errorcode = HAL_ERROR;
+ goto error;
+ }
+ /* Read Data from DR register */
+ (*pRxData++) = I2SxEXT(hi2s->Instance)->DR;
+ hi2s->RxXferCount--;
+
+ /* Check if an overrun occurs */
+ if (__HAL_I2SEXT_GET_FLAG(hi2s, I2S_FLAG_OVR) == SET)
+ {
+ /* Clear Overrun flag */
+ __HAL_I2S_CLEAR_OVRFLAG(hi2s);
+
+ /* Set the error code */
+ SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_OVR);
+ }
+ }
+ }
+ }
+ /* The I2S_MODE_MASTER_RX or I2S_MODE_SLAVE_RX Mode is selected */
+ else
+ {
+ /* Prepare the First Data before enabling the I2S */
+ I2SxEXT(hi2s->Instance)->DR = (*pTxData++);
+ hi2s->TxXferCount--;
+
+ /* Enable I2Sext(transmitter) after enabling I2Sx peripheral */
+ __HAL_I2SEXT_ENABLE(hi2s);
+
+ /* Enable I2S peripheral before the I2Sext*/
+ __HAL_I2S_ENABLE(hi2s);
+
+ /* Check if Master Receiver mode is selected */
+ if ((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_MASTER_RX)
+ {
+ /* Clear the Overrun Flag by a read operation on the SPI_DR register followed by a read
+ access to the SPI_SR register. */
+ __HAL_I2S_CLEAR_OVRFLAG(hi2s);
+ }
+
+ while ((hi2s->RxXferCount > 0U) || (hi2s->TxXferCount > 0U))
+ {
+ if (hi2s->TxXferCount > 0U)
+ {
+ /* Wait until TXE flag is set */
+ if (I2SEx_FullDuplexWaitFlagStateUntilTimeout(hi2s, I2S_FLAG_TXE, SET, Timeout, I2S_USE_I2SEXT) != HAL_OK)
+ {
+ /* Set the error code */
+ SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_TIMEOUT);
+ errorcode = HAL_ERROR;
+ goto error;
+ }
+ /* Write Data on DR register */
+ I2SxEXT(hi2s->Instance)->DR = (*pTxData++);
+ hi2s->TxXferCount--;
+
+ /* Check if an underrun occurs */
+ if ((__HAL_I2SEXT_GET_FLAG(hi2s, I2S_FLAG_UDR) == SET) && (tmp1 == I2S_MODE_SLAVE_RX))
+ {
+ /* Clear Underrun flag */
+ __HAL_I2S_CLEAR_UDRFLAG(hi2s);
+
+ /* Set the error code */
+ SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_UDR);
+ }
+ }
+ if (hi2s->RxXferCount > 0U)
+ {
+ /* Wait until RXNE flag is set */
+ if (I2SEx_FullDuplexWaitFlagStateUntilTimeout(hi2s, I2S_FLAG_RXNE, SET, Timeout, I2S_USE_I2S) != HAL_OK)
+ {
+ /* Set the error code */
+ SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_TIMEOUT);
+ errorcode = HAL_ERROR;
+ goto error;
+ }
+ /* Read Data from DR register */
+ (*pRxData++) = hi2s->Instance->DR;
+ hi2s->RxXferCount--;
+
+ /* Check if an overrun occurs */
+ if (__HAL_I2S_GET_FLAG(hi2s, I2S_FLAG_OVR) == SET)
+ {
+ /* Clear Overrun flag */
+ __HAL_I2S_CLEAR_OVRFLAG(hi2s);
+
+ /* Set the error code */
+ SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_OVR);
+ }
+ }
+ }
+ }
+
+ if (hi2s->ErrorCode != HAL_I2S_ERROR_NONE)
+ {
+ errorcode = HAL_ERROR;
+ }
+
+error :
+ hi2s->State = HAL_I2S_STATE_READY;
+ __HAL_UNLOCK(hi2s);
+ return errorcode;
+}
+
+/**
+ * @brief Full-Duplex Transmit/Receive data in non-blocking mode using Interrupt
+ * @param hi2s pointer to a I2S_HandleTypeDef structure that contains
+ * the configuration information for I2S module
+ * @param pTxData a 16-bit pointer to the Transmit data buffer.
+ * @param pRxData a 16-bit pointer to the Receive data buffer.
+ * @param Size number of data sample to be sent:
+ * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
+ * configuration phase, the Size parameter means the number of 16-bit data length
+ * in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
+ * the Size parameter means the number of 16-bit data length.
+ * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
+ * between Master and Slave(example: audio streaming).
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_I2SEx_TransmitReceive_IT(I2S_HandleTypeDef *hi2s, uint16_t *pTxData, uint16_t *pRxData,
+ uint16_t Size)
+{
+ uint32_t tmp1 = 0U;
+ HAL_StatusTypeDef errorcode = HAL_OK;
+
+ if (hi2s->State != HAL_I2S_STATE_READY)
+ {
+ errorcode = HAL_BUSY;
+ goto error;
+ }
+
+ if ((pTxData == NULL) || (pRxData == NULL) || (Size == 0U))
+ {
+ return HAL_ERROR;
+ }
+
+ /* Process Locked */
+ __HAL_LOCK(hi2s);
+
+ hi2s->pTxBuffPtr = pTxData;
+ hi2s->pRxBuffPtr = pRxData;
+
+ tmp1 = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN);
+ /* Check the Data format: When a 16-bit data frame or a 16-bit data frame extended
+ is selected during the I2S configuration phase, the Size parameter means the number
+ of 16-bit data length in the transaction and when a 24-bit data frame or a 32-bit data
+ frame is selected the Size parameter means the number of 16-bit data length. */
+ if ((tmp1 == I2S_DATAFORMAT_24B) || (tmp1 == I2S_DATAFORMAT_32B))
+ {
+ hi2s->TxXferSize = (Size << 1U);
+ hi2s->TxXferCount = (Size << 1U);
+ hi2s->RxXferSize = (Size << 1U);
+ hi2s->RxXferCount = (Size << 1U);
+ }
+ else
+ {
+ hi2s->TxXferSize = Size;
+ hi2s->TxXferCount = Size;
+ hi2s->RxXferSize = Size;
+ hi2s->RxXferCount = Size;
+ }
+
+ hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
+ hi2s->State = HAL_I2S_STATE_BUSY_TX_RX;
+
+ /* Set the function for IT treatment */
+ if ((hi2s->Init.Mode == I2S_MODE_MASTER_TX) || (hi2s->Init.Mode == I2S_MODE_SLAVE_TX))
+ {
+ /* Enable I2Sext RXNE and ERR interrupts */
+ __HAL_I2SEXT_ENABLE_IT(hi2s, (I2S_IT_RXNE | I2S_IT_ERR));
+
+ /* Enable I2Sx TXE and ERR interrupts */
+ __HAL_I2S_ENABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR));
+
+ /* Transmit First data */
+ hi2s->Instance->DR = (*hi2s->pTxBuffPtr++);
+ hi2s->TxXferCount--;
+
+ if (hi2s->TxXferCount == 0U)
+ {
+ /* Disable TXE and ERR interrupt */
+ __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR));
+ }
+ }
+ else /* The I2S_MODE_MASTER_RX or I2S_MODE_SLAVE_RX Mode is selected */
+ {
+ /* Enable I2Sext TXE and ERR interrupts */
+ __HAL_I2SEXT_ENABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR));
+
+ /* Enable I2Sext RXNE and ERR interrupts */
+ __HAL_I2S_ENABLE_IT(hi2s, (I2S_IT_RXNE | I2S_IT_ERR));
+
+ /* Transmit First data */
+ I2SxEXT(hi2s->Instance)->DR = (*hi2s->pTxBuffPtr++);
+ hi2s->TxXferCount--;
+
+ if (hi2s->TxXferCount == 0U)
+ {
+ /* Disable I2Sext TXE and ERR interrupt */
+ __HAL_I2SEXT_DISABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR));
+ }
+ }
+
+ /* Enable I2Sext peripheral */
+ __HAL_I2SEXT_ENABLE(hi2s);
+
+ /* Enable I2S peripheral */
+ __HAL_I2S_ENABLE(hi2s);
+
+error :
+ __HAL_UNLOCK(hi2s);
+ return errorcode;
+}
+
+/**
+ * @brief Full-Duplex Transmit/Receive data in non-blocking mode using DMA
+ * @param hi2s pointer to a I2S_HandleTypeDef structure that contains
+ * the configuration information for I2S module
+ * @param pTxData a 16-bit pointer to the Transmit data buffer.
+ * @param pRxData a 16-bit pointer to the Receive data buffer.
+ * @param Size number of data sample to be sent:
+ * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
+ * configuration phase, the Size parameter means the number of 16-bit data length
+ * in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
+ * the Size parameter means the number of 16-bit data length.
+ * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
+ * between Master and Slave(example: audio streaming).
+ * @retval HAL status
+ */
+HAL_StatusTypeDef HAL_I2SEx_TransmitReceive_DMA(I2S_HandleTypeDef *hi2s, uint16_t *pTxData, uint16_t *pRxData,
+ uint16_t Size)
+{
+ uint32_t *tmp = NULL;
+ uint32_t tmp1 = 0U;
+ HAL_StatusTypeDef errorcode = HAL_OK;
+
+ if (hi2s->State != HAL_I2S_STATE_READY)
+ {
+ errorcode = HAL_BUSY;
+ goto error;
+ }
+
+ if ((pTxData == NULL) || (pRxData == NULL) || (Size == 0U))
+ {
+ return HAL_ERROR;
+ }
+
+ /* Process Locked */
+ __HAL_LOCK(hi2s);
+
+ hi2s->pTxBuffPtr = pTxData;
+ hi2s->pRxBuffPtr = pRxData;
+
+ tmp1 = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN);
+ /* Check the Data format: When a 16-bit data frame or a 16-bit data frame extended
+ is selected during the I2S configuration phase, the Size parameter means the number
+ of 16-bit data length in the transaction and when a 24-bit data frame or a 32-bit data
+ frame is selected the Size parameter means the number of 16-bit data length. */
+ if ((tmp1 == I2S_DATAFORMAT_24B) || (tmp1 == I2S_DATAFORMAT_32B))
+ {
+ hi2s->TxXferSize = (Size << 1U);
+ hi2s->TxXferCount = (Size << 1U);
+ hi2s->RxXferSize = (Size << 1U);
+ hi2s->RxXferCount = (Size << 1U);
+ }
+ else
+ {
+ hi2s->TxXferSize = Size;
+ hi2s->TxXferCount = Size;
+ hi2s->RxXferSize = Size;
+ hi2s->RxXferCount = Size;
+ }
+
+ hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
+ hi2s->State = HAL_I2S_STATE_BUSY_TX_RX;
+
+ /* Set the I2S Rx DMA Half transfer complete callback */
+ hi2s->hdmarx->XferHalfCpltCallback = I2SEx_TxRxDMAHalfCplt;
+
+ /* Set the I2S Rx DMA transfer complete callback */
+ hi2s->hdmarx->XferCpltCallback = I2SEx_TxRxDMACplt;
+
+ /* Set the I2S Rx DMA error callback */
+ hi2s->hdmarx->XferErrorCallback = I2SEx_TxRxDMAError;
+
+ /* Set the I2S Tx DMA Half transfer complete callback */
+ hi2s->hdmatx->XferHalfCpltCallback = I2SEx_TxRxDMAHalfCplt;
+
+ /* Set the I2S Tx DMA transfer complete callback */
+ hi2s->hdmatx->XferCpltCallback = I2SEx_TxRxDMACplt;
+
+ /* Set the I2S Tx DMA error callback */
+ hi2s->hdmatx->XferErrorCallback = I2SEx_TxRxDMAError;
+
+ tmp1 = hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG;
+ /* Check if the I2S_MODE_MASTER_TX or I2S_MODE_SLAVE_TX Mode is selected */
+ if ((tmp1 == I2S_MODE_MASTER_TX) || (tmp1 == I2S_MODE_SLAVE_TX))
+ {
+ /* Enable the Rx DMA Stream */
+ tmp = (uint32_t *)&pRxData;
+ HAL_DMA_Start_IT(hi2s->hdmarx, (uint32_t)&I2SxEXT(hi2s->Instance)->DR, *(uint32_t *)tmp, hi2s->RxXferSize);
+
+ /* Enable Rx DMA Request */
+ SET_BIT(I2SxEXT(hi2s->Instance)->CR2, SPI_CR2_RXDMAEN);
+
+ /* Enable the Tx DMA Stream */
+ tmp = (uint32_t *)&pTxData;
+ HAL_DMA_Start_IT(hi2s->hdmatx, *(uint32_t *)tmp, (uint32_t)&hi2s->Instance->DR, hi2s->TxXferSize);
+
+ /* Enable Tx DMA Request */
+ SET_BIT(hi2s->Instance->CR2, SPI_CR2_TXDMAEN);
+
+ /* Check if the I2S is already enabled */
+ if ((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE)
+ {
+ /* Enable I2Sext(receiver) before enabling I2Sx peripheral */
+ __HAL_I2SEXT_ENABLE(hi2s);
+
+ /* Enable I2S peripheral after the I2Sext */
+ __HAL_I2S_ENABLE(hi2s);
+ }
+ }
+ else
+ {
+ /* Check if Master Receiver mode is selected */
+ if ((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_MASTER_RX)
+ {
+ /* Clear the Overrun Flag by a read operation on the SPI_DR register followed by a read
+ access to the SPI_SR register. */
+ __HAL_I2S_CLEAR_OVRFLAG(hi2s);
+ }
+ /* Enable the Tx DMA Stream */
+ tmp = (uint32_t *)&pTxData;
+ HAL_DMA_Start_IT(hi2s->hdmatx, *(uint32_t *)tmp, (uint32_t)&I2SxEXT(hi2s->Instance)->DR, hi2s->TxXferSize);
+
+ /* Enable Tx DMA Request */
+ SET_BIT(I2SxEXT(hi2s->Instance)->CR2, SPI_CR2_TXDMAEN);
+
+ /* Enable the Rx DMA Stream */
+ tmp = (uint32_t *)&pRxData;
+ HAL_DMA_Start_IT(hi2s->hdmarx, (uint32_t)&hi2s->Instance->DR, *(uint32_t *)tmp, hi2s->RxXferSize);
+
+ /* Enable Rx DMA Request */
+ SET_BIT(hi2s->Instance->CR2, SPI_CR2_RXDMAEN);
+
+ /* Check if the I2S is already enabled */
+ if ((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE)
+ {
+ /* Enable I2Sext(transmitter) before enabling I2Sx peripheral */
+ __HAL_I2SEXT_ENABLE(hi2s);
+ /* Enable I2S peripheral before the I2Sext */
+ __HAL_I2S_ENABLE(hi2s);
+ }
+ }
+
+error :
+ __HAL_UNLOCK(hi2s);
+ return errorcode;
+}
+
+/**
+ * @brief This function handles I2S/I2Sext interrupt requests in full-duplex mode.
+ * @param hi2s I2S handle
+ * @retval HAL status
+ */
+void HAL_I2SEx_FullDuplex_IRQHandler(I2S_HandleTypeDef *hi2s)
+{
+ __IO uint32_t i2ssr = hi2s->Instance->SR;
+ __IO uint32_t i2sextsr = I2SxEXT(hi2s->Instance)->SR;
+ __IO uint32_t i2scr2 = hi2s->Instance->CR2;
+ __IO uint32_t i2sextcr2 = I2SxEXT(hi2s->Instance)->CR2;
+
+ /* Check if the I2S_MODE_MASTER_TX or I2S_MODE_SLAVE_TX Mode is selected */
+ if ((hi2s->Init.Mode == I2S_MODE_MASTER_TX) || (hi2s->Init.Mode == I2S_MODE_SLAVE_TX))
+ {
+ /* I2S in mode Transmitter -------------------------------------------------*/
+ if (((i2ssr & I2S_FLAG_TXE) == I2S_FLAG_TXE) && ((i2scr2 & I2S_IT_TXE) != RESET))
+ {
+ /* When the I2S mode is configured as I2S_MODE_MASTER_TX or I2S_MODE_SLAVE_TX,
+ the I2S TXE interrupt will be generated to manage the full-duplex transmit phase. */
+ I2SEx_TxISR_I2S(hi2s);
+ }
+
+ /* I2Sext in mode Receiver -----------------------------------------------*/
+ if (((i2sextsr & I2S_FLAG_RXNE) == I2S_FLAG_RXNE) && ((i2sextcr2 & I2S_IT_RXNE) != RESET))
+ {
+ /* When the I2S mode is configured as I2S_MODE_MASTER_TX or I2S_MODE_SLAVE_TX,
+ the I2Sext RXNE interrupt will be generated to manage the full-duplex receive phase. */
+ I2SEx_RxISR_I2SExt(hi2s);
+ }
+
+ /* I2Sext Overrun error interrupt occurred --------------------------------*/
+ if (((i2sextsr & I2S_FLAG_OVR) == I2S_FLAG_OVR) && ((i2sextcr2 & I2S_IT_ERR) != RESET))
+ {
+ /* Disable RXNE and ERR interrupt */
+ __HAL_I2SEXT_DISABLE_IT(hi2s, (I2S_IT_RXNE | I2S_IT_ERR));
+
+ /* Disable TXE and ERR interrupt */
+ __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR));
+
+ /* Clear Overrun flag */
+ __HAL_I2S_CLEAR_OVRFLAG(hi2s);
+
+ /* Set the I2S State ready */
+ hi2s->State = HAL_I2S_STATE_READY;
+
+ /* Set the error code and execute error callback*/
+ SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_OVR);
+ /* Call user error callback */
+#if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
+ hi2s->ErrorCallback(hi2s);
+#else
+ HAL_I2S_ErrorCallback(hi2s);
+#endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
+ }
+
+ /* I2S Underrun error interrupt occurred ----------------------------------*/
+ if (((i2ssr & I2S_FLAG_UDR) == I2S_FLAG_UDR) && ((i2scr2 & I2S_IT_ERR) != RESET))
+ {
+ /* Disable TXE and ERR interrupt */
+ __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR));
+
+ /* Disable RXNE and ERR interrupt */
+ __HAL_I2SEXT_DISABLE_IT(hi2s, (I2S_IT_RXNE | I2S_IT_ERR));
+
+ /* Clear underrun flag */
+ __HAL_I2S_CLEAR_UDRFLAG(hi2s);
+
+ /* Set the I2S State ready */
+ hi2s->State = HAL_I2S_STATE_READY;
+
+ /* Set the error code and execute error callback*/
+ SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_UDR);
+ /* Call user error callback */
+#if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
+ hi2s->ErrorCallback(hi2s);
+#else
+ HAL_I2S_ErrorCallback(hi2s);
+#endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
+ }
+ }
+ /* The I2S_MODE_MASTER_RX or I2S_MODE_SLAVE_RX Mode is selected */
+ else
+ {
+ /* I2Sext in mode Transmitter ----------------------------------------------*/
+ if (((i2sextsr & I2S_FLAG_TXE) == I2S_FLAG_TXE) && ((i2sextcr2 & I2S_IT_TXE) != RESET))
+ {
+ /* When the I2S mode is configured as I2S_MODE_MASTER_RX or I2S_MODE_SLAVE_RX,
+ the I2Sext TXE interrupt will be generated to manage the full-duplex transmit phase. */
+ I2SEx_TxISR_I2SExt(hi2s);
+ }
+
+ /* I2S in mode Receiver --------------------------------------------------*/
+ if (((i2ssr & I2S_FLAG_RXNE) == I2S_FLAG_RXNE) && ((i2scr2 & I2S_IT_RXNE) != RESET))
+ {
+ /* When the I2S mode is configured as I2S_MODE_MASTER_RX or I2S_MODE_SLAVE_RX,
+ the I2S RXNE interrupt will be generated to manage the full-duplex receive phase. */
+ I2SEx_RxISR_I2S(hi2s);
+ }
+
+ /* I2S Overrun error interrupt occurred -------------------------------------*/
+ if (((i2ssr & I2S_FLAG_OVR) == I2S_FLAG_OVR) && ((i2scr2 & I2S_IT_ERR) != RESET))
+ {
+ /* Disable RXNE and ERR interrupt */
+ __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_RXNE | I2S_IT_ERR));
+
+ /* Disable TXE and ERR interrupt */
+ __HAL_I2SEXT_DISABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR));
+
+ /* Set the I2S State ready */
+ hi2s->State = HAL_I2S_STATE_READY;
+
+ /* Set the error code and execute error callback*/
+ SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_OVR);
+ /* Call user error callback */
+#if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
+ hi2s->ErrorCallback(hi2s);
+#else
+ HAL_I2S_ErrorCallback(hi2s);
+#endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
+ }
+
+ /* I2Sext Underrun error interrupt occurred -------------------------------*/
+ if (((i2sextsr & I2S_FLAG_UDR) == I2S_FLAG_UDR) && ((i2sextcr2 & I2S_IT_ERR) != RESET))
+ {
+ /* Disable TXE and ERR interrupt */
+ __HAL_I2SEXT_DISABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR));
+
+ /* Disable RXNE and ERR interrupt */
+ __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_RXNE | I2S_IT_ERR));
+
+ /* Set the I2S State ready */
+ hi2s->State = HAL_I2S_STATE_READY;
+
+ /* Set the error code and execute error callback*/
+ SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_UDR);
+ /* Call user error callback */
+#if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
+ hi2s->ErrorCallback(hi2s);
+#else
+ HAL_I2S_ErrorCallback(hi2s);
+#endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
+ }
+ }
+}
+
+/**
+ * @brief Tx and Rx Transfer half completed callback
+ * @param hi2s I2S handle
+ * @retval None
+ */
+__weak void HAL_I2SEx_TxRxHalfCpltCallback(I2S_HandleTypeDef *hi2s)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hi2s);
+
+ /* NOTE : This function Should not be modified, when the callback is needed,
+ the HAL_I2SEx_TxRxHalfCpltCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @brief Tx and Rx Transfer completed callback
+ * @param hi2s I2S handle
+ * @retval None
+ */
+__weak void HAL_I2SEx_TxRxCpltCallback(I2S_HandleTypeDef *hi2s)
+{
+ /* Prevent unused argument(s) compilation warning */
+ UNUSED(hi2s);
+
+ /* NOTE : This function should not be modified, when the callback is needed,
+ the HAL_I2SEx_TxRxCpltCallback could be implemented in the user file
+ */
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/** @addtogroup I2SEx_Private_Functions I2S Extended Private Functions
+ * @{
+ */
+
+/**
+ * @brief DMA I2S transmit receive process half complete callback
+ * @param hdma pointer to a DMA_HandleTypeDef structure that contains
+ * the configuration information for the specified DMA module.
+ * @retval None
+ */
+static void I2SEx_TxRxDMAHalfCplt(DMA_HandleTypeDef *hdma)
+{
+ I2S_HandleTypeDef *hi2s = (I2S_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
+
+ /* Call user TxRx Half complete callback */
+#if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
+ hi2s->TxRxHalfCpltCallback(hi2s);
+#else
+ HAL_I2SEx_TxRxHalfCpltCallback(hi2s);
+#endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
+}
+
+/**
+ * @brief DMA I2S 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 I2SEx_TxRxDMACplt(DMA_HandleTypeDef *hdma)
+{
+ I2S_HandleTypeDef *hi2s = (I2S_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
+
+ /* if DMA is configured in DMA_NORMAL mode */
+ if (hdma->Init.Mode == DMA_NORMAL)
+ {
+ if (hi2s->hdmarx == hdma)
+ {
+ /* Disable Rx DMA Request */
+ if (((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_MASTER_TX) || \
+ ((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_SLAVE_TX))
+ {
+ CLEAR_BIT(I2SxEXT(hi2s->Instance)->CR2, SPI_CR2_RXDMAEN);
+ }
+ else
+ {
+ CLEAR_BIT(hi2s->Instance->CR2, SPI_CR2_RXDMAEN);
+ }
+
+ hi2s->RxXferCount = 0U;
+
+ if (hi2s->TxXferCount == 0U)
+ {
+ hi2s->State = HAL_I2S_STATE_READY;
+
+ /* Call user TxRx complete callback */
+#if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
+ hi2s->TxRxCpltCallback(hi2s);
+#else
+ HAL_I2SEx_TxRxCpltCallback(hi2s);
+#endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
+ }
+ }
+
+ if (hi2s->hdmatx == hdma)
+ {
+ /* Disable Tx DMA Request */
+ if (((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_MASTER_TX) || \
+ ((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_SLAVE_TX))
+ {
+ CLEAR_BIT(hi2s->Instance->CR2, SPI_CR2_TXDMAEN);
+ }
+ else
+ {
+ CLEAR_BIT(I2SxEXT(hi2s->Instance)->CR2, SPI_CR2_TXDMAEN);
+ }
+
+ hi2s->TxXferCount = 0U;
+
+ if (hi2s->RxXferCount == 0U)
+ {
+ hi2s->State = HAL_I2S_STATE_READY;
+
+ /* Call user TxRx complete callback */
+#if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
+ hi2s->TxRxCpltCallback(hi2s);
+#else
+ HAL_I2SEx_TxRxCpltCallback(hi2s);
+#endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
+ }
+ }
+ }
+}
+
+/**
+ * @brief DMA I2S communication error callback
+ * @param hdma DMA handle
+ * @retval None
+ */
+static void I2SEx_TxRxDMAError(DMA_HandleTypeDef *hdma)
+{
+ I2S_HandleTypeDef *hi2s = (I2S_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
+
+ /* Disable Rx and Tx DMA Request */
+ CLEAR_BIT(hi2s->Instance->CR2, (SPI_CR2_RXDMAEN | SPI_CR2_TXDMAEN));
+ CLEAR_BIT(I2SxEXT(hi2s->Instance)->CR2, (SPI_CR2_RXDMAEN | SPI_CR2_TXDMAEN));
+
+ hi2s->TxXferCount = 0U;
+ hi2s->RxXferCount = 0U;
+
+ hi2s->State = HAL_I2S_STATE_READY;
+
+ /* Set the error code and execute error callback*/
+ SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_DMA);
+ /* Call user error callback */
+#if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
+ hi2s->ErrorCallback(hi2s);
+#else
+ HAL_I2S_ErrorCallback(hi2s);
+#endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
+}
+
+/**
+ * @brief I2S Full-Duplex IT handler transmit function
+ * @param hi2s I2S handle
+ * @retval None
+ */
+static void I2SEx_TxISR_I2S(I2S_HandleTypeDef *hi2s)
+{
+ /* Write Data on DR register */
+ hi2s->Instance->DR = (*hi2s->pTxBuffPtr++);
+ hi2s->TxXferCount--;
+
+ if (hi2s->TxXferCount == 0U)
+ {
+ /* Disable TXE and ERR interrupt */
+ __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR));
+
+ if (hi2s->RxXferCount == 0U)
+ {
+ hi2s->State = HAL_I2S_STATE_READY;
+ /* Call user TxRx complete callback */
+#if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
+ hi2s->TxRxCpltCallback(hi2s);
+#else
+ HAL_I2SEx_TxRxCpltCallback(hi2s);
+#endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
+ }
+ }
+}
+
+/**
+ * @brief I2SExt Full-Duplex IT handler transmit function
+ * @param hi2s I2S handle
+ * @retval None
+ */
+static void I2SEx_TxISR_I2SExt(I2S_HandleTypeDef *hi2s)
+{
+ /* Write Data on DR register */
+ I2SxEXT(hi2s->Instance)->DR = (*hi2s->pTxBuffPtr++);
+ hi2s->TxXferCount--;
+
+ if (hi2s->TxXferCount == 0U)
+ {
+ /* Disable I2Sext TXE and ERR interrupt */
+ __HAL_I2SEXT_DISABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR));
+
+ if (hi2s->RxXferCount == 0U)
+ {
+ hi2s->State = HAL_I2S_STATE_READY;
+ /* Call user TxRx complete callback */
+#if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
+ hi2s->TxRxCpltCallback(hi2s);
+#else
+ HAL_I2SEx_TxRxCpltCallback(hi2s);
+#endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
+ }
+ }
+}
+
+/**
+ * @brief I2S Full-Duplex IT handler receive function
+ * @param hi2s I2S handle
+ * @retval None
+ */
+static void I2SEx_RxISR_I2S(I2S_HandleTypeDef *hi2s)
+{
+ /* Read Data from DR register */
+ (*hi2s->pRxBuffPtr++) = hi2s->Instance->DR;
+ hi2s->RxXferCount--;
+
+ if (hi2s->RxXferCount == 0U)
+ {
+ /* Disable RXNE and ERR interrupt */
+ __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_RXNE | I2S_IT_ERR));
+
+ if (hi2s->TxXferCount == 0U)
+ {
+ hi2s->State = HAL_I2S_STATE_READY;
+ /* Call user TxRx complete callback */
+#if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
+ hi2s->TxRxCpltCallback(hi2s);
+#else
+ HAL_I2SEx_TxRxCpltCallback(hi2s);
+#endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
+ }
+ }
+}
+
+/**
+ * @brief I2SExt Full-Duplex IT handler receive function
+ * @param hi2s I2S handle
+ * @retval None
+ */
+static void I2SEx_RxISR_I2SExt(I2S_HandleTypeDef *hi2s)
+{
+ /* Read Data from DR register */
+ (*hi2s->pRxBuffPtr++) = I2SxEXT(hi2s->Instance)->DR;
+ hi2s->RxXferCount--;
+
+ if (hi2s->RxXferCount == 0U)
+ {
+ /* Disable I2Sext RXNE and ERR interrupt */
+ __HAL_I2SEXT_DISABLE_IT(hi2s, (I2S_IT_RXNE | I2S_IT_ERR));
+
+ if (hi2s->TxXferCount == 0U)
+ {
+ hi2s->State = HAL_I2S_STATE_READY;
+ /* Call user TxRx complete callback */
+#if (USE_HAL_I2S_REGISTER_CALLBACKS == 1U)
+ hi2s->TxRxCpltCallback(hi2s);
+#else
+ HAL_I2SEx_TxRxCpltCallback(hi2s);
+#endif /* USE_HAL_I2S_REGISTER_CALLBACKS */
+ }
+ }
+}
+
+/**
+ * @brief This function handles I2S Communication Timeout.
+ * @param hi2s I2S handle
+ * @param Flag Flag checked
+ * @param State Value of the flag expected
+ * @param Timeout Duration of the timeout
+ * @param i2sUsed I2S instance reference
+ * @retval HAL status
+ */
+static HAL_StatusTypeDef I2SEx_FullDuplexWaitFlagStateUntilTimeout(I2S_HandleTypeDef *hi2s, uint32_t Flag,
+ uint32_t State, uint32_t Timeout, I2S_UseTypeDef i2sUsed)
+{
+ uint32_t tickstart = HAL_GetTick();
+
+ if (i2sUsed == I2S_USE_I2S)
+ {
+ /* Wait until flag is reset */
+ while (((__HAL_I2S_GET_FLAG(hi2s, Flag)) ? SET : RESET) != State)
+ {
+ if (Timeout != HAL_MAX_DELAY)
+ {
+ if ((Timeout == 0U) || ((HAL_GetTick() - tickstart) > Timeout))
+ {
+ /* Set the I2S State ready */
+ hi2s->State = HAL_I2S_STATE_READY;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2s);
+
+ return HAL_TIMEOUT;
+ }
+ }
+ }
+ }
+ else /* i2sUsed == I2S_USE_I2SEXT */
+ {
+ /* Wait until flag is reset */
+ while (((__HAL_I2SEXT_GET_FLAG(hi2s, Flag)) ? SET : RESET) != State)
+ {
+ if (Timeout != HAL_MAX_DELAY)
+ {
+ if ((Timeout == 0U) || ((HAL_GetTick() - tickstart) > Timeout))
+ {
+ /* Set the I2S State ready */
+ hi2s->State = HAL_I2S_STATE_READY;
+
+ /* Process Unlocked */
+ __HAL_UNLOCK(hi2s);
+
+ return HAL_TIMEOUT;
+ }
+ }
+ }
+ }
+ return HAL_OK;
+}
+
+/**
+ * @}
+ */
+#endif /* SPI_I2S_FULLDUPLEX_SUPPORT */
+
+/**
+ * @}
+ */
+#endif /* HAL_I2S_MODULE_ENABLED */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/port/stm32-f4discovery-cc256x-2/Inc/i2c.h b/port/stm32-f4discovery-cc256x-2/Inc/i2c.h
new file mode 100644
index 000000000..a412da675
--- /dev/null
+++ b/port/stm32-f4discovery-cc256x-2/Inc/i2c.h
@@ -0,0 +1,58 @@
+/**
+ ******************************************************************************
+ * File Name : I2C.h
+ * Description : This file provides code for the configuration
+ * of the I2C instances.
+ ******************************************************************************
+ * @attention
+ *
+ * © Copyright (c) 2019 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software component is licensed by ST under BSD 3-Clause license,
+ * the "License"; You may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ * opensource.org/licenses/BSD-3-Clause
+ *
+ ******************************************************************************
+ */
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __i2c_H
+#define __i2c_H
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "main.h"
+
+/* USER CODE BEGIN Includes */
+
+/* USER CODE END Includes */
+
+extern I2C_HandleTypeDef hi2c1;
+
+/* USER CODE BEGIN Private defines */
+
+/* USER CODE END Private defines */
+
+void MX_I2C1_Init(void);
+
+/* USER CODE BEGIN Prototypes */
+
+/* USER CODE END Prototypes */
+
+#ifdef __cplusplus
+}
+#endif
+#endif /*__ i2c_H */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/port/stm32-f4discovery-cc256x-2/Inc/i2s.h b/port/stm32-f4discovery-cc256x-2/Inc/i2s.h
new file mode 100644
index 000000000..ec6770470
--- /dev/null
+++ b/port/stm32-f4discovery-cc256x-2/Inc/i2s.h
@@ -0,0 +1,58 @@
+/**
+ ******************************************************************************
+ * File Name : I2S.h
+ * Description : This file provides code for the configuration
+ * of the I2S instances.
+ ******************************************************************************
+ * @attention
+ *
+ * © Copyright (c) 2019 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software component is licensed by ST under BSD 3-Clause license,
+ * the "License"; You may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ * opensource.org/licenses/BSD-3-Clause
+ *
+ ******************************************************************************
+ */
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __i2s_H
+#define __i2s_H
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "main.h"
+
+/* USER CODE BEGIN Includes */
+
+/* USER CODE END Includes */
+
+extern I2S_HandleTypeDef hi2s2;
+
+/* USER CODE BEGIN Private defines */
+
+/* USER CODE END Private defines */
+
+void MX_I2S2_Init(void);
+
+/* USER CODE BEGIN Prototypes */
+
+/* USER CODE END Prototypes */
+
+#ifdef __cplusplus
+}
+#endif
+#endif /*__ i2s_H */
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/