1 /**
2   ******************************************************************************
3   * @file    stm32f7xx_hal_i2s.c
4   * @author  MCD Application Team
5   * @version V1.0.1
6   * @date    25-June-2015
7   * @brief   I2S HAL module driver.
8   *          This file provides firmware functions to manage the following
9   *          functionalities of the Integrated Interchip Sound (I2S) peripheral:
10   *           + Initialization and de-initialization functions
11   *           + IO operation functions
12   *           + Peripheral State and Errors functions
13   @verbatim
14  ===============================================================================
15                   ##### How to use this driver #####
16  ===============================================================================
17  [..]
18     The I2S HAL driver can be used as follows:
19 
20     (#) Declare a I2S_HandleTypeDef handle structure.
21     (#) Initialize the I2S low level resources by implement the HAL_I2S_MspInit() API:
22         (##) Enable the SPIx interface clock.
23         (##) I2S pins configuration:
24             (+++) Enable the clock for the I2S GPIOs.
25             (+++) Configure these I2S pins as alternate function pull-up.
26         (##) NVIC configuration if you need to use interrupt process (HAL_I2S_Transmit_IT()
27              and HAL_I2S_Receive_IT() APIs).
28             (+++) Configure the I2Sx interrupt priority.
29             (+++) Enable the NVIC I2S IRQ handle.
30         (##) DMA Configuration if you need to use DMA process (HAL_I2S_Transmit_DMA()
31              and HAL_I2S_Receive_DMA() APIs:
32             (+++) Declare a DMA handle structure for the Tx/Rx channel.
33             (+++) Enable the DMAx interface clock.
34             (+++) Configure the declared DMA handle structure with the required Tx/Rx parameters.
35             (+++) Configure the DMA Tx/Rx Channel.
36             (+++) Associate the initialized DMA handle to the I2S DMA Tx/Rx handle.
37             (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on the
38                 DMA Tx/Rx Channel.
39 
40    (#) Program the Mode, Standard, Data Format, MCLK Output, Audio frequency and Polarity
41        using HAL_I2S_Init() function.
42 
43    -@- The specific I2S interrupts (Transmission complete interrupt,
44        RXNE interrupt and Error Interrupts) will be managed using the macros
45        __HAL_I2S_ENABLE_IT() and __HAL_I2S_DISABLE_IT() inside the transmit and receive process.
46    -@- Make sure that either:
47        (+@) I2S clock is configured based on SYSCLK or
48        (+@) External clock source is configured after setting correctly
49             the define constant EXTERNAL_CLOCK_VALUE in the stm32f3xx_hal_conf.h file.
50 
51    (#) Three mode of operations are available within this driver :
52 
53    *** Polling mode IO operation ***
54    =================================
55    [..]
56      (+) Send an amount of data in blocking mode using HAL_I2S_Transmit()
57      (+) Receive an amount of data in blocking mode using HAL_I2S_Receive()
58 
59    *** Interrupt mode IO operation ***
60    ===================================
61    [..]
62      (+) Send an amount of data in non blocking mode using HAL_I2S_Transmit_IT()
63      (+) At transmission end of half transfer HAL_I2S_TxHalfCpltCallback is executed and user can
64          add his own code by customization of function pointer HAL_I2S_TxHalfCpltCallback
65      (+) At transmission end of transfer HAL_I2S_TxCpltCallback is executed and user can
66          add his own code by customization of function pointer HAL_I2S_TxCpltCallback
67      (+) Receive an amount of data in non blocking mode using HAL_I2S_Receive_IT()
68      (+) At reception end of half transfer HAL_I2S_RxHalfCpltCallback is executed and user can
69          add his own code by customization of function pointer HAL_I2S_RxHalfCpltCallback
70      (+) At reception end of transfer HAL_I2S_RxCpltCallback is executed and user can
71          add his own code by customization of function pointer HAL_I2S_RxCpltCallback
72      (+) In case of transfer Error, HAL_I2S_ErrorCallback() function is executed and user can
73          add his own code by customization of function pointer HAL_I2S_ErrorCallback
74 
75    *** DMA mode IO operation ***
76    ==============================
77    [..]
78      (+) Send an amount of data in non blocking mode (DMA) using HAL_I2S_Transmit_DMA()
79      (+) At transmission end of half transfer HAL_I2S_TxHalfCpltCallback is executed and user can
80          add his own code by customization of function pointer HAL_I2S_TxHalfCpltCallback
81      (+) At transmission end of transfer HAL_I2S_TxCpltCallback is executed and user can
82          add his own code by customization of function pointer HAL_I2S_TxCpltCallback
83      (+) Receive an amount of data in non blocking mode (DMA) using HAL_I2S_Receive_DMA()
84      (+) At reception end of half transfer HAL_I2S_RxHalfCpltCallback is executed and user can
85          add his own code by customization of function pointer HAL_I2S_RxHalfCpltCallback
86      (+) At reception end of transfer HAL_I2S_RxCpltCallback is executed and user can
87          add his own code by customization of function pointer HAL_I2S_RxCpltCallback
88      (+) In case of transfer Error, HAL_I2S_ErrorCallback() function is executed and user can
89          add his own code by customization of function pointer HAL_I2S_ErrorCallback
90      (+) Pause the DMA Transfer using HAL_I2S_DMAPause()
91      (+) Resume the DMA Transfer using HAL_I2S_DMAResume()
92      (+) Stop the DMA Transfer using HAL_I2S_DMAStop()
93 
94    *** I2S HAL driver macros list ***
95    =============================================
96    [..]
97      Below the list of most used macros in I2S HAL driver.
98 
99       (+) __HAL_I2S_ENABLE: Enable the specified SPI peripheral (in I2S mode)
100       (+) __HAL_I2S_DISABLE: Disable the specified SPI peripheral (in I2S mode)
101       (+) __HAL_I2S_ENABLE_IT : Enable the specified I2S interrupts
102       (+) __HAL_I2S_DISABLE_IT : Disable the specified I2S interrupts
103       (+) __HAL_I2S_GET_FLAG: Check whether the specified I2S flag is set or not
104 
105     [..]
106       (@) You can refer to the I2S HAL driver header file for more useful macros
107 
108   @endverbatim
109   ******************************************************************************
110   * @attention
111   *
112   * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
113   *
114   * Redistribution and use in source and binary forms, with or without modification,
115   * are permitted provided that the following conditions are met:
116   *   1. Redistributions of source code must retain the above copyright notice,
117   *      this list of conditions and the following disclaimer.
118   *   2. Redistributions in binary form must reproduce the above copyright notice,
119   *      this list of conditions and the following disclaimer in the documentation
120   *      and/or other materials provided with the distribution.
121   *   3. Neither the name of STMicroelectronics nor the names of its contributors
122   *      may be used to endorse or promote products derived from this software
123   *      without specific prior written permission.
124   *
125   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
126   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
127   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
128   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
129   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
130   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
131   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
132   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
133   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
134   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
135   *
136   ******************************************************************************
137   */
138 
139 /* Includes ------------------------------------------------------------------*/
140 #include "stm32f7xx_hal.h"
141 
142 /** @addtogroup STM32F7xx_HAL_Driver
143   * @{
144   */
145 
146 /** @defgroup I2S I2S
147   * @brief I2S HAL module driver
148   * @{
149   */
150 
151 #ifdef HAL_I2S_MODULE_ENABLED
152 
153 /* Private typedef -----------------------------------------------------------*/
154 /* Private define ------------------------------------------------------------*/
155 /* Private macro -------------------------------------------------------------*/
156 /* Private variables ---------------------------------------------------------*/
157 /* Private function prototypes -----------------------------------------------*/
158 /** @defgroup I2S_Private_Functions I2S Private Functions
159   * @{
160   */
161 static void I2S_DMATxCplt(DMA_HandleTypeDef *hdma);
162 static void I2S_DMATxHalfCplt(DMA_HandleTypeDef *hdma);
163 static void I2S_DMARxCplt(DMA_HandleTypeDef *hdma);
164 static void I2S_DMARxHalfCplt(DMA_HandleTypeDef *hdma);
165 static void I2S_DMAError(DMA_HandleTypeDef *hdma);
166 static void I2S_Transmit_IT(I2S_HandleTypeDef *hi2s);
167 static void I2S_Receive_IT(I2S_HandleTypeDef *hi2s);
168 static uint32_t I2S_GetClockFreq(I2S_HandleTypeDef *hi2s);
169 static HAL_StatusTypeDef I2S_WaitFlagStateUntilTimeout(I2S_HandleTypeDef *hi2s, uint32_t Flag, uint32_t State, uint32_t Timeout);
170 /**
171   * @}
172   */
173 
174 /* Exported functions ---------------------------------------------------------*/
175 
176 /** @defgroup I2S_Exported_Functions I2S Exported Functions
177   * @{
178   */
179 
180 /** @defgroup  I2S_Exported_Functions_Group1 Initialization and de-initialization functions
181   *  @brief    Initialization and Configuration functions
182   *
183 @verbatim
184  ===============================================================================
185               ##### Initialization and de-initialization functions #####
186  ===============================================================================
187     [..]  This subsection provides a set of functions allowing to initialize and
188           de-initialize the I2Sx peripheral in simplex mode:
189 
190       (+) User must Implement HAL_I2S_MspInit() function in which he configures
191           all related peripherals resources (CLOCK, GPIO, DMA, IT and NVIC ).
192 
193       (+) Call the function HAL_I2S_Init() to configure the selected device with
194           the selected configuration:
195         (++) Mode
196         (++) Standard
197         (++) Data Format
198         (++) MCLK Output
199         (++) Audio frequency
200         (++) Polarity
201         (++) Full duplex mode
202 
203       (+) Call the function HAL_I2S_DeInit() to restore the default configuration
204           of the selected I2Sx peripheral.
205 @endverbatim
206   * @{
207   */
208 
209 /**
210   * @brief Initializes the I2S according to the specified parameters
211   *         in the I2S_InitTypeDef and create the associated handle.
212   * @param  hi2s: pointer to a I2S_HandleTypeDef structure that contains
213   *         the configuration information for I2S module
214   * @retval HAL status
215   */
HAL_I2S_Init(I2S_HandleTypeDef * hi2s)216 HAL_StatusTypeDef HAL_I2S_Init(I2S_HandleTypeDef *hi2s)
217 {
218     uint16_t tmpreg = 0, i2sdiv = 2, i2sodd = 0, packetlength = 1;
219     uint32_t tmp = 0, i2sclk = 0;
220 
221     /* Check the I2S handle allocation */
222     if (hi2s == NULL) {
223         return HAL_ERROR;
224     }
225 
226     /* Check the parameters */
227     assert_param(IS_I2S_ALL_INSTANCE(hi2s->Instance));
228     assert_param(IS_I2S_MODE(hi2s->Init.Mode));
229     assert_param(IS_I2S_STANDARD(hi2s->Init.Standard));
230     assert_param(IS_I2S_DATA_FORMAT(hi2s->Init.DataFormat));
231     assert_param(IS_I2S_MCLK_OUTPUT(hi2s->Init.MCLKOutput));
232     assert_param(IS_I2S_AUDIO_FREQ(hi2s->Init.AudioFreq));
233     assert_param(IS_I2S_CPOL(hi2s->Init.CPOL));
234     assert_param(IS_I2S_CLOCKSOURCE(hi2s->Init.ClockSource));
235 
236     if (hi2s->State == HAL_I2S_STATE_RESET) {
237         /* Allocate lock resource and initialize it */
238         hi2s->Lock = HAL_UNLOCKED;
239         /* Init the low level hardware : GPIO, CLOCK, CORTEX...etc */
240         HAL_I2S_MspInit(hi2s);
241     }
242 
243     hi2s->State = HAL_I2S_STATE_BUSY;
244 
245     /*----------------------- SPIx I2SCFGR & I2SPR Configuration -----------------*/
246     /* Clear I2SMOD, I2SE, I2SCFG, PCMSYNC, I2SSTD, CKPOL, DATLEN and CHLEN bits */
247     hi2s->Instance->I2SCFGR &= ~(SPI_I2SCFGR_CHLEN | SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CKPOL | \
248                                  SPI_I2SCFGR_I2SSTD | SPI_I2SCFGR_PCMSYNC | SPI_I2SCFGR_I2SCFG | \
249                                  SPI_I2SCFGR_I2SE | SPI_I2SCFGR_I2SMOD);
250     hi2s->Instance->I2SPR = 0x0002;
251 
252     /* Get the I2SCFGR register value */
253     tmpreg = hi2s->Instance->I2SCFGR;
254 
255     /* If the default value has to be written, reinitialize i2sdiv and i2sodd*/
256     if (hi2s->Init.AudioFreq == I2S_AUDIOFREQ_DEFAULT) {
257         i2sodd = (uint16_t)0;
258         i2sdiv = (uint16_t)2;
259     }
260     /* If the requested audio frequency is not the default, compute the prescaler */
261     else {
262         /* Check the frame length (For the Prescaler computing) *******************/
263         if (hi2s->Init.DataFormat == I2S_DATAFORMAT_16B) {
264             /* Packet length is 16 bits */
265             packetlength = 1;
266         } else {
267             /* Packet length is 32 bits */
268             packetlength = 2;
269         }
270 
271         /* Get I2S source Clock frequency  ****************************************/
272 
273         /* If an external I2S clock has to be used, the specific define should be set
274         in the project configuration or in the stm32f3xx_conf.h file */
275         if (hi2s->Init.ClockSource == I2S_CLOCK_EXTERNAL) {
276             /* Set the I2S clock to the external clock  value */
277             i2sclk = EXTERNAL_CLOCK_VALUE;
278         } else {
279             /* Get the I2S source clock value */
280             i2sclk = I2S_GetClockFreq(hi2s);
281         }
282 
283         /* Compute the Real divider depending on the MCLK output state, with a floating point */
284         if (hi2s->Init.MCLKOutput == I2S_MCLKOUTPUT_ENABLE) {
285             /* MCLK output is enabled */
286             tmp = (uint16_t)(((((i2sclk / 256) * 10) / hi2s->Init.AudioFreq)) + 5);
287         } else {
288             /* MCLK output is disabled */
289             tmp = (uint16_t)(((((i2sclk / (32 * packetlength)) *10 ) / hi2s->Init.AudioFreq)) + 5);
290         }
291 
292         /* Remove the flatting point */
293         tmp = tmp / 10;
294 
295         /* Check the parity of the divider */
296         i2sodd = (uint16_t)(tmp & (uint16_t)0x0001);
297 
298         /* Compute the i2sdiv prescaler */
299         i2sdiv = (uint16_t)((tmp - i2sodd) / 2);
300 
301         /* Get the Mask for the Odd bit (SPI_I2SPR[8]) register */
302         i2sodd = (uint16_t) (i2sodd << 8);
303     }
304 
305     /* Test if the divider is 1 or 0 or greater than 0xFF */
306     if ((i2sdiv < 2) || (i2sdiv > 0xFF)) {
307         /* Set the default values */
308         i2sdiv = 2;
309         i2sodd = 0;
310     }
311 
312     /* Write to SPIx I2SPR register the computed value */
313     hi2s->Instance->I2SPR = (uint16_t)((uint16_t)i2sdiv | (uint16_t)(i2sodd | (uint16_t)hi2s->Init.MCLKOutput));
314 
315     /* Configure the I2S with the I2S_InitStruct values */
316     tmpreg |= (uint16_t)((uint16_t)SPI_I2SCFGR_I2SMOD | (uint16_t)(hi2s->Init.Mode | \
317                          (uint16_t)(hi2s->Init.Standard | (uint16_t)(hi2s->Init.DataFormat | \
318                                     (uint16_t)hi2s->Init.CPOL))));
319 
320     /* Write to SPIx I2SCFGR */
321     hi2s->Instance->I2SCFGR = tmpreg;
322 
323     hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
324     hi2s->State= HAL_I2S_STATE_READY;
325 
326     return HAL_OK;
327 }
328 
329 /**
330   * @brief DeInitializes the I2S peripheral
331   * @param  hi2s: pointer to a I2S_HandleTypeDef structure that contains
332   *         the configuration information for I2S module
333   * @retval HAL status
334   */
HAL_I2S_DeInit(I2S_HandleTypeDef * hi2s)335 HAL_StatusTypeDef HAL_I2S_DeInit(I2S_HandleTypeDef *hi2s)
336 {
337     /* Check the I2S handle allocation */
338     if (hi2s == NULL) {
339         return HAL_ERROR;
340     }
341 
342     /* Check the parameters */
343     assert_param(IS_I2S_ALL_INSTANCE(hi2s->Instance));
344 
345     hi2s->State = HAL_I2S_STATE_BUSY;
346 
347     /* DeInit the low level hardware: GPIO, CLOCK, NVIC... */
348     HAL_I2S_MspDeInit(hi2s);
349 
350     hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
351     hi2s->State = HAL_I2S_STATE_RESET;
352 
353     /* Release Lock */
354     __HAL_UNLOCK(hi2s);
355 
356     return HAL_OK;
357 }
358 
359 /**
360   * @brief I2S MSP Init
361   * @param  hi2s: pointer to a I2S_HandleTypeDef structure that contains
362   *         the configuration information for I2S module
363   * @retval None
364   */
HAL_I2S_MspInit(I2S_HandleTypeDef * hi2s)365 __weak void HAL_I2S_MspInit(I2S_HandleTypeDef *hi2s)
366 {
367     /* NOTE : This function Should not be modified, when the callback is needed,
368               the HAL_I2S_MspInit could be implemented in the user file
369      */
370 }
371 
372 /**
373   * @brief I2S MSP DeInit
374   * @param  hi2s: pointer to a I2S_HandleTypeDef structure that contains
375   *         the configuration information for I2S module
376   * @retval None
377   */
HAL_I2S_MspDeInit(I2S_HandleTypeDef * hi2s)378 __weak void HAL_I2S_MspDeInit(I2S_HandleTypeDef *hi2s)
379 {
380     /* NOTE : This function Should not be modified, when the callback is needed,
381               the HAL_I2S_MspDeInit could be implemented in the user file
382      */
383 }
384 
385 /**
386   * @}
387   */
388 
389 /** @defgroup I2S_Exported_Functions_Group2 Input and Output operation functions
390   *  @brief Data transfers functions
391   *
392 @verbatim
393  ===============================================================================
394                       ##### IO operation functions #####
395  ===============================================================================
396     [..]
397     This subsection provides a set of functions allowing to manage the I2S data
398     transfers.
399 
400     (#) There are two modes of transfer:
401        (++) Blocking mode : The communication is performed in the polling mode.
402             The status of all data processing is returned by the same function
403             after finishing transfer.
404        (++) No-Blocking mode : The communication is performed using Interrupts
405             or DMA. These functions return the status of the transfer startup.
406             The end of the data processing will be indicated through the
407             dedicated I2S IRQ when using Interrupt mode or the DMA IRQ when
408             using DMA mode.
409 
410     (#) Blocking mode functions are :
411         (++) HAL_I2S_Transmit()
412         (++) HAL_I2S_Receive()
413 
414     (#) No-Blocking mode functions with Interrupt are :
415         (++) HAL_I2S_Transmit_IT()
416         (++) HAL_I2S_Receive_IT()
417 
418     (#) No-Blocking mode functions with DMA are :
419         (++) HAL_I2S_Transmit_DMA()
420         (++) HAL_I2S_Receive_DMA()
421 
422     (#) A set of Transfer Complete Callbacks are provided in non Blocking mode:
423         (++) HAL_I2S_TxCpltCallback()
424         (++) HAL_I2S_RxCpltCallback()
425         (++) HAL_I2S_ErrorCallback()
426 
427 @endverbatim
428   * @{
429   */
430 
431 /**
432   * @brief Transmit an amount of data in blocking mode
433   * @param  hi2s: pointer to a I2S_HandleTypeDef structure that contains
434   *         the configuration information for I2S module
435   * @param pData: a 16-bit pointer to data buffer.
436   * @param Size: number of data sample to be sent:
437   * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
438   *       configuration phase, the Size parameter means the number of 16-bit data length
439   *       in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
440   *       the Size parameter means the number of 16-bit data length.
441   * @param  Timeout: Timeout duration
442   * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
443   *       between Master and Slave(example: audio streaming).
444   * @retval HAL status
445   */
HAL_I2S_Transmit(I2S_HandleTypeDef * hi2s,uint16_t * pData,uint16_t Size,uint32_t Timeout)446 HAL_StatusTypeDef HAL_I2S_Transmit(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size, uint32_t Timeout)
447 {
448     if ((pData == NULL ) || (Size == 0)) {
449         return  HAL_ERROR;
450     }
451 
452     if (hi2s->State == HAL_I2S_STATE_READY) {
453         if (((hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN)) == I2S_DATAFORMAT_24B)||\
454                 ((hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN)) == I2S_DATAFORMAT_32B)) {
455             hi2s->TxXferSize = (Size << 1);
456             hi2s->TxXferCount = (Size << 1);
457         } else {
458             hi2s->TxXferSize = Size;
459             hi2s->TxXferCount = Size;
460         }
461 
462         /* Process Locked */
463         __HAL_LOCK(hi2s);
464 
465         hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
466         hi2s->State = HAL_I2S_STATE_BUSY_TX;
467 
468         /* Check if the I2S is already enabled */
469         if ((hi2s->Instance->I2SCFGR &SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE) {
470             /* Enable I2S peripheral */
471             __HAL_I2S_ENABLE(hi2s);
472         }
473 
474         while (hi2s->TxXferCount > 0) {
475             hi2s->Instance->DR = (*pData++);
476             hi2s->TxXferCount--;
477             /* Wait until TXE flag is set */
478             if (I2S_WaitFlagStateUntilTimeout(hi2s, I2S_FLAG_TXE, SET, Timeout) != HAL_OK) {
479                 /* Set the error code and execute error callback*/
480                 hi2s->ErrorCode |= HAL_I2S_ERROR_TIMEOUT;
481                 HAL_I2S_ErrorCallback(hi2s);
482                 return HAL_TIMEOUT;
483             }
484 
485             /* Check if an underrun occurs */
486             if (__HAL_I2S_GET_FLAG(hi2s, I2S_FLAG_UDR) == SET) {
487                 /* Set the I2S State ready */
488                 hi2s->State = HAL_I2S_STATE_READY;
489 
490                 /* Process Unlocked */
491                 __HAL_UNLOCK(hi2s);
492 
493                 /* Set the error code and execute error callback*/
494                 hi2s->ErrorCode |= HAL_I2S_ERROR_UDR;
495                 HAL_I2S_ErrorCallback(hi2s);
496 
497                 return HAL_ERROR;
498             }
499         }
500 
501         /* Check if Slave mode is selected */
502         if (((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_SLAVE_TX) || ((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_SLAVE_RX)) {
503             /* Wait until Busy flag is reset */
504             if (I2S_WaitFlagStateUntilTimeout(hi2s, I2S_FLAG_BSY, RESET, Timeout) != HAL_OK) {
505                 /* Set the error code and execute error callback*/
506                 hi2s->ErrorCode |= HAL_I2S_ERROR_TIMEOUT;
507                 HAL_I2S_ErrorCallback(hi2s);
508                 return HAL_TIMEOUT;
509             }
510         }
511 
512         hi2s->State = HAL_I2S_STATE_READY;
513 
514         /* Process Unlocked */
515         __HAL_UNLOCK(hi2s);
516 
517         return HAL_OK;
518     } else {
519         return HAL_BUSY;
520     }
521 }
522 
523 /**
524   * @brief Receive an amount of data in blocking mode
525   * @param  hi2s: pointer to a I2S_HandleTypeDef structure that contains
526   *         the configuration information for I2S module
527   * @param pData: a 16-bit pointer to data buffer.
528   * @param Size: number of data sample to be sent:
529   * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
530   *       configuration phase, the Size parameter means the number of 16-bit data length
531   *       in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
532   *       the Size parameter means the number of 16-bit data length.
533   * @param Timeout: Timeout duration
534   * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
535   *       between Master and Slave(example: audio streaming).
536   * @note In I2S Master Receiver mode, just after enabling the peripheral the clock will be generate
537   *       in continuous way and as the I2S is not disabled at the end of the I2S transaction.
538   * @retval HAL status
539   */
HAL_I2S_Receive(I2S_HandleTypeDef * hi2s,uint16_t * pData,uint16_t Size,uint32_t Timeout)540 HAL_StatusTypeDef HAL_I2S_Receive(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size, uint32_t Timeout)
541 {
542     if ((pData == NULL ) || (Size == 0)) {
543         return  HAL_ERROR;
544     }
545 
546     if (hi2s->State == HAL_I2S_STATE_READY) {
547         if (((hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN)) == I2S_DATAFORMAT_24B)||\
548                 ((hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN)) == I2S_DATAFORMAT_32B)) {
549             hi2s->RxXferSize = (Size << 1);
550             hi2s->RxXferCount = (Size << 1);
551         } else {
552             hi2s->RxXferSize = Size;
553             hi2s->RxXferCount = Size;
554         }
555         /* Process Locked */
556         __HAL_LOCK(hi2s);
557 
558         hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
559         hi2s->State = HAL_I2S_STATE_BUSY_RX;
560 
561         /* Check if the I2S is already enabled */
562         if ((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE) {
563             /* Enable I2S peripheral */
564             __HAL_I2S_ENABLE(hi2s);
565         }
566 
567         /* Check if Master Receiver mode is selected */
568         if ((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_MASTER_RX) {
569             /* Clear the Overrun Flag by a read operation on the SPI_DR register followed by a read
570             access to the SPI_SR register. */
571             __HAL_I2S_CLEAR_OVRFLAG(hi2s);
572         }
573 
574         /* Receive data */
575         while (hi2s->RxXferCount > 0) {
576             /* Wait until RXNE flag is set */
577             if (I2S_WaitFlagStateUntilTimeout(hi2s, I2S_FLAG_RXNE, SET, Timeout) != HAL_OK) {
578                 /* Set the error code and execute error callback*/
579                 hi2s->ErrorCode |= HAL_I2S_ERROR_TIMEOUT;
580                 HAL_I2S_ErrorCallback(hi2s);
581                 return HAL_TIMEOUT;
582             }
583 
584             /* Check if an overrun occurs */
585             if (__HAL_I2S_GET_FLAG(hi2s, I2S_FLAG_OVR) == SET) {
586                 /* Set the I2S State ready */
587                 hi2s->State = HAL_I2S_STATE_READY;
588 
589                 /* Process Unlocked */
590                 __HAL_UNLOCK(hi2s);
591 
592                 /* Set the error code and execute error callback*/
593                 hi2s->ErrorCode |= HAL_I2S_ERROR_OVR;
594                 HAL_I2S_ErrorCallback(hi2s);
595 
596                 return HAL_ERROR;
597             }
598 
599             (*pData++) = hi2s->Instance->DR;
600             hi2s->RxXferCount--;
601         }
602 
603         hi2s->State = HAL_I2S_STATE_READY;
604 
605         /* Process Unlocked */
606         __HAL_UNLOCK(hi2s);
607 
608         return HAL_OK;
609     } else {
610         return HAL_BUSY;
611     }
612 }
613 
614 /**
615   * @brief Transmit an amount of data in non-blocking mode with Interrupt
616   * @param  hi2s: pointer to a I2S_HandleTypeDef structure that contains
617   *         the configuration information for I2S module
618   * @param pData: a 16-bit pointer to data buffer.
619   * @param Size: number of data sample to be sent:
620   * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
621   *       configuration phase, the Size parameter means the number of 16-bit data length
622   *       in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
623   *       the Size parameter means the number of 16-bit data length.
624   * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
625   *       between Master and Slave(example: audio streaming).
626   * @retval HAL status
627   */
HAL_I2S_Transmit_IT(I2S_HandleTypeDef * hi2s,uint16_t * pData,uint16_t Size)628 HAL_StatusTypeDef HAL_I2S_Transmit_IT(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size)
629 {
630     if (hi2s->State == HAL_I2S_STATE_READY) {
631         if ((pData == NULL) || (Size == 0)) {
632             return  HAL_ERROR;
633         }
634 
635         hi2s->pTxBuffPtr = pData;
636         if (((hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN)) == I2S_DATAFORMAT_24B)||\
637                 ((hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN)) == I2S_DATAFORMAT_32B)) {
638             hi2s->TxXferSize = (Size << 1);
639             hi2s->TxXferCount = (Size << 1);
640         } else {
641             hi2s->TxXferSize = Size;
642             hi2s->TxXferCount = Size;
643         }
644 
645         /* Process Locked */
646         __HAL_LOCK(hi2s);
647 
648         hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
649         hi2s->State = HAL_I2S_STATE_BUSY_TX;
650 
651         /* Enable TXE and ERR interrupt */
652         __HAL_I2S_ENABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR));
653 
654         /* Check if the I2S is already enabled */
655         if ((hi2s->Instance->I2SCFGR &SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE) {
656             /* Enable I2S peripheral */
657             __HAL_I2S_ENABLE(hi2s);
658         }
659 
660         /* Process Unlocked */
661         __HAL_UNLOCK(hi2s);
662 
663         return HAL_OK;
664     } else {
665         return HAL_BUSY;
666     }
667 }
668 
669 /**
670   * @brief Receive an amount of data in non-blocking mode with Interrupt
671   * @param  hi2s: pointer to a I2S_HandleTypeDef structure that contains
672   *         the configuration information for I2S module
673   * @param pData: a 16-bit pointer to the Receive data buffer.
674   * @param Size: number of data sample to be sent:
675   * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
676   *       configuration phase, the Size parameter means the number of 16-bit data length
677   *       in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
678   *       the Size parameter means the number of 16-bit data length.
679   * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
680   *       between Master and Slave(example: audio streaming).
681   * @note It is recommended to use DMA for the I2S receiver to avoid de-synchronisation
682   * between Master and Slave otherwise the I2S interrupt should be optimized.
683   * @retval HAL status
684   */
HAL_I2S_Receive_IT(I2S_HandleTypeDef * hi2s,uint16_t * pData,uint16_t Size)685 HAL_StatusTypeDef HAL_I2S_Receive_IT(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size)
686 {
687     if (hi2s->State == HAL_I2S_STATE_READY) {
688         if ((pData == NULL) || (Size == 0)) {
689             return  HAL_ERROR;
690         }
691 
692         hi2s->pRxBuffPtr = pData;
693         if (((hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN)) == I2S_DATAFORMAT_24B)||\
694                 ((hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN)) == I2S_DATAFORMAT_32B)) {
695             hi2s->RxXferSize = (Size << 1);
696             hi2s->RxXferCount = (Size << 1);
697         } else {
698             hi2s->RxXferSize = Size;
699             hi2s->RxXferCount = Size;
700         }
701         /* Process Locked */
702         __HAL_LOCK(hi2s);
703 
704         hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
705         hi2s->State = HAL_I2S_STATE_BUSY_RX;
706 
707         /* Enable TXE and ERR interrupt */
708         __HAL_I2S_ENABLE_IT(hi2s, (I2S_IT_RXNE | I2S_IT_ERR));
709 
710         /* Check if the I2S is already enabled */
711         if ((hi2s->Instance->I2SCFGR &SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE) {
712             /* Enable I2S peripheral */
713             __HAL_I2S_ENABLE(hi2s);
714         }
715 
716         /* Process Unlocked */
717         __HAL_UNLOCK(hi2s);
718 
719         return HAL_OK;
720     } else {
721         return HAL_BUSY;
722     }
723 }
724 
725 /**
726   * @brief Transmit an amount of data in non-blocking mode with DMA
727   * @param  hi2s: pointer to a I2S_HandleTypeDef structure that contains
728   *         the configuration information for I2S module
729   * @param pData: a 16-bit pointer to the Transmit data buffer.
730   * @param Size: number of data sample to be sent:
731   * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
732   *       configuration phase, the Size parameter means the number of 16-bit data length
733   *       in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
734   *       the Size parameter means the number of 16-bit data length.
735   * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
736   *       between Master and Slave(example: audio streaming).
737   * @retval HAL status
738   */
HAL_I2S_Transmit_DMA(I2S_HandleTypeDef * hi2s,uint16_t * pData,uint16_t Size)739 HAL_StatusTypeDef HAL_I2S_Transmit_DMA(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size)
740 {
741     uint32_t *tmp;
742 
743     if ((pData == NULL) || (Size == 0)) {
744         return  HAL_ERROR;
745     }
746 
747     if (hi2s->State == HAL_I2S_STATE_READY) {
748         hi2s->pTxBuffPtr = pData;
749         if (((hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN)) == I2S_DATAFORMAT_24B)||\
750                 ((hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN)) == I2S_DATAFORMAT_32B)) {
751             hi2s->TxXferSize = (Size << 1);
752             hi2s->TxXferCount = (Size << 1);
753         } else {
754             hi2s->TxXferSize = Size;
755             hi2s->TxXferCount = Size;
756         }
757 
758         /* Process Locked */
759         __HAL_LOCK(hi2s);
760 
761         hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
762         hi2s->State = HAL_I2S_STATE_BUSY_TX;
763 
764         /* Set the I2S Tx DMA Half transfer complete callback */
765         hi2s->hdmatx->XferHalfCpltCallback = I2S_DMATxHalfCplt;
766 
767         /* Set the I2S TxDMA transfer complete callback */
768         hi2s->hdmatx->XferCpltCallback = I2S_DMATxCplt;
769 
770         /* Set the DMA error callback */
771         hi2s->hdmatx->XferErrorCallback = I2S_DMAError;
772 
773         /* Enable the Tx DMA Channel */
774         tmp = (uint32_t*)&pData;
775         HAL_DMA_Start_IT(hi2s->hdmatx, *(uint32_t*)tmp, (uint32_t)&hi2s->Instance->DR, hi2s->TxXferSize);
776 
777         /* Check if the I2S is already enabled */
778         if ((hi2s->Instance->I2SCFGR &SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE) {
779             /* Enable I2S peripheral */
780             __HAL_I2S_ENABLE(hi2s);
781         }
782 
783         /* Enable Tx DMA Request */
784         hi2s->Instance->CR2 |= SPI_CR2_TXDMAEN;
785 
786         /* Process Unlocked */
787         __HAL_UNLOCK(hi2s);
788 
789         return HAL_OK;
790     } else {
791         return HAL_BUSY;
792     }
793 }
794 
795 /**
796   * @brief Receive an amount of data in non-blocking mode with DMA
797   * @param  hi2s: pointer to a I2S_HandleTypeDef structure that contains
798   *         the configuration information for I2S module
799   * @param pData: a 16-bit pointer to the Receive data buffer.
800   * @param Size: number of data sample to be sent:
801   * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
802   *       configuration phase, the Size parameter means the number of 16-bit data length
803   *       in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
804   *       the Size parameter means the number of 16-bit data length.
805   * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
806   *       between Master and Slave(example: audio streaming).
807   * @retval HAL status
808   */
HAL_I2S_Receive_DMA(I2S_HandleTypeDef * hi2s,uint16_t * pData,uint16_t Size)809 HAL_StatusTypeDef HAL_I2S_Receive_DMA(I2S_HandleTypeDef *hi2s, uint16_t *pData, uint16_t Size)
810 {
811     uint32_t *tmp;
812 
813     if ((pData == NULL) || (Size == 0)) {
814         return  HAL_ERROR;
815     }
816 
817     if (hi2s->State == HAL_I2S_STATE_READY) {
818         hi2s->pRxBuffPtr = pData;
819         if (((hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN)) == I2S_DATAFORMAT_24B)||\
820                 ((hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN)) == I2S_DATAFORMAT_32B)) {
821             hi2s->RxXferSize = (Size << 1);
822             hi2s->RxXferCount = (Size << 1);
823         } else {
824             hi2s->RxXferSize = Size;
825             hi2s->RxXferCount = Size;
826         }
827         /* Process Locked */
828         __HAL_LOCK(hi2s);
829 
830         hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
831         hi2s->State = HAL_I2S_STATE_BUSY_RX;
832 
833         /* Set the I2S Rx DMA Half transfer complete callback */
834         hi2s->hdmarx->XferHalfCpltCallback = I2S_DMARxHalfCplt;
835 
836         /* Set the I2S Rx DMA transfer complete callback */
837         hi2s->hdmarx->XferCpltCallback = I2S_DMARxCplt;
838 
839         /* Set the DMA error callback */
840         hi2s->hdmarx->XferErrorCallback = I2S_DMAError;
841 
842         /* Check if Master Receiver mode is selected */
843         if ((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_MASTER_RX) {
844             /* Clear the Overrun Flag by a read operation to the SPI_DR register followed by a read
845             access to the SPI_SR register. */
846             __HAL_I2S_CLEAR_OVRFLAG(hi2s);
847         }
848 
849         /* Enable the Rx DMA Channel */
850         tmp = (uint32_t*)&pData;
851         HAL_DMA_Start_IT(hi2s->hdmarx, (uint32_t)&hi2s->Instance->DR, *(uint32_t*)tmp, hi2s->RxXferSize);
852 
853         /* Check if the I2S is already enabled */
854         if ((hi2s->Instance->I2SCFGR &SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE) {
855             /* Enable I2S peripheral */
856             __HAL_I2S_ENABLE(hi2s);
857         }
858 
859         /* Enable Rx DMA Request */
860         hi2s->Instance->CR2 |= SPI_CR2_RXDMAEN;
861 
862         /* Process Unlocked */
863         __HAL_UNLOCK(hi2s);
864 
865         return HAL_OK;
866     } else {
867         return HAL_BUSY;
868     }
869 }
870 
871 /**
872   * @brief Pauses the audio stream playing from the Media.
873   * @param  hi2s: pointer to a I2S_HandleTypeDef structure that contains
874   *         the configuration information for I2S module
875   * @retval HAL status
876   */
HAL_I2S_DMAPause(I2S_HandleTypeDef * hi2s)877 HAL_StatusTypeDef HAL_I2S_DMAPause(I2S_HandleTypeDef *hi2s)
878 {
879     /* Process Locked */
880     __HAL_LOCK(hi2s);
881 
882     if (hi2s->State == HAL_I2S_STATE_BUSY_TX) {
883         /* Disable the I2S DMA Tx request */
884         hi2s->Instance->CR2 &= (uint32_t)(~SPI_CR2_TXDMAEN);
885     } else if (hi2s->State == HAL_I2S_STATE_BUSY_RX) {
886         /* Disable the I2S DMA Rx request */
887         hi2s->Instance->CR2 &= (uint32_t)(~SPI_CR2_RXDMAEN);
888     } else if (hi2s->State == HAL_I2S_STATE_BUSY_TX_RX) {
889         if ((hi2s->Init.Mode == I2S_MODE_SLAVE_TX)||(hi2s->Init.Mode == I2S_MODE_MASTER_TX)) {
890             /* Disable the I2S DMA Tx request */
891             hi2s->Instance->CR2 &= (uint32_t)(~SPI_CR2_TXDMAEN);
892         } else {
893             /* Disable the I2S DMA Rx request */
894             hi2s->Instance->CR2 &= (uint32_t)(~SPI_CR2_RXDMAEN);
895         }
896     }
897 
898     /* Process Unlocked */
899     __HAL_UNLOCK(hi2s);
900 
901     return HAL_OK;
902 }
903 
904 /**
905   * @brief Resumes the audio stream playing from the Media.
906   * @param  hi2s: pointer to a I2S_HandleTypeDef structure that contains
907   *         the configuration information for I2S module
908   * @retval HAL status
909   */
HAL_I2S_DMAResume(I2S_HandleTypeDef * hi2s)910 HAL_StatusTypeDef HAL_I2S_DMAResume(I2S_HandleTypeDef *hi2s)
911 {
912     /* Process Locked */
913     __HAL_LOCK(hi2s);
914 
915     if (hi2s->State == HAL_I2S_STATE_BUSY_TX) {
916         /* Enable the I2S DMA Tx request */
917         SET_BIT(hi2s->Instance->CR2, SPI_CR2_TXDMAEN);
918     } else if (hi2s->State == HAL_I2S_STATE_BUSY_RX) {
919         /* Enable the I2S DMA Rx request */
920         SET_BIT(hi2s->Instance->CR2, SPI_CR2_RXDMAEN);
921     }
922 
923     /* If the I2S peripheral is still not enabled, enable it */
924     if (HAL_IS_BIT_CLR(hi2s->Instance->I2SCFGR, SPI_I2SCFGR_I2SE)) {
925         /* Enable I2S peripheral */
926         __HAL_I2S_ENABLE(hi2s);
927     }
928 
929     /* Process Unlocked */
930     __HAL_UNLOCK(hi2s);
931 
932     return HAL_OK;
933 }
934 
935 /**
936   * @brief Stops the audio stream playing from the Media.
937   * @param  hi2s: pointer to a I2S_HandleTypeDef structure that contains
938   *         the configuration information for I2S module
939   * @retval HAL status
940   */
HAL_I2S_DMAStop(I2S_HandleTypeDef * hi2s)941 HAL_StatusTypeDef HAL_I2S_DMAStop(I2S_HandleTypeDef *hi2s)
942 {
943     /* Process Locked */
944     __HAL_LOCK(hi2s);
945 
946     /* Disable the I2S Tx/Rx DMA requests */
947     CLEAR_BIT(hi2s->Instance->CR2, SPI_CR2_TXDMAEN);
948     CLEAR_BIT(hi2s->Instance->CR2, SPI_CR2_RXDMAEN);
949 
950     /* Abort the I2S DMA Channel tx */
951     if (hi2s->hdmatx != NULL) {
952         /* Disable the I2S DMA channel */
953         __HAL_DMA_DISABLE(hi2s->hdmatx);
954         HAL_DMA_Abort(hi2s->hdmatx);
955     }
956     /* Abort the I2S DMA Channel rx */
957     if (hi2s->hdmarx != NULL) {
958         /* Disable the I2S DMA channel */
959         __HAL_DMA_DISABLE(hi2s->hdmarx);
960         HAL_DMA_Abort(hi2s->hdmarx);
961     }
962 
963     /* Disable I2S peripheral */
964     __HAL_I2S_DISABLE(hi2s);
965 
966     hi2s->State = HAL_I2S_STATE_READY;
967 
968     /* Process Unlocked */
969     __HAL_UNLOCK(hi2s);
970 
971     return HAL_OK;
972 }
973 
974 /**
975   * @brief  This function handles I2S interrupt request.
976   * @param  hi2s: pointer to a I2S_HandleTypeDef structure that contains
977   *         the configuration information for I2S module
978   * @retval HAL status
979   */
HAL_I2S_IRQHandler(I2S_HandleTypeDef * hi2s)980 void HAL_I2S_IRQHandler(I2S_HandleTypeDef *hi2s)
981 {
982     __IO uint32_t i2ssr = hi2s->Instance->SR;
983 
984     if (hi2s->State == HAL_I2S_STATE_BUSY_RX) {
985         /* I2S in mode Receiver ----------------------------------------------------*/
986         if (((i2ssr & I2S_FLAG_RXNE) == I2S_FLAG_RXNE) && (__HAL_I2S_GET_IT_SOURCE(hi2s, I2S_IT_RXNE) != RESET)) {
987             I2S_Receive_IT(hi2s);
988         }
989 
990         /* I2S Overrun error interrupt occurred -------------------------------------*/
991         if (((i2ssr & I2S_FLAG_OVR) == I2S_FLAG_OVR) && (__HAL_I2S_GET_IT_SOURCE(hi2s, I2S_IT_ERR) != RESET)) {
992             /* Disable RXNE and ERR interrupt */
993             __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_RXNE | I2S_IT_ERR));
994 
995             /* Set the I2S State ready */
996             hi2s->State = HAL_I2S_STATE_READY;
997 
998             /* Set the error code and execute error callback*/
999             hi2s->ErrorCode |= HAL_I2S_ERROR_OVR;
1000             HAL_I2S_ErrorCallback(hi2s);
1001         }
1002     } else if (hi2s->State == HAL_I2S_STATE_BUSY_TX) {
1003         /* I2S in mode Transmitter ---------------------------------------------------*/
1004         if (((i2ssr & I2S_FLAG_TXE) == I2S_FLAG_TXE) && (__HAL_I2S_GET_IT_SOURCE(hi2s, I2S_IT_TXE) != RESET)) {
1005             I2S_Transmit_IT(hi2s);
1006         }
1007 
1008         /* I2S Underrun error interrupt occurred ------------------------------------*/
1009         if (((i2ssr & I2S_FLAG_UDR) == I2S_FLAG_UDR) && (__HAL_I2S_GET_IT_SOURCE(hi2s, I2S_IT_ERR) != RESET)) {
1010             /* Disable TXE and ERR interrupt */
1011             __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR));
1012 
1013             /* Set the I2S State ready */
1014             hi2s->State = HAL_I2S_STATE_READY;
1015 
1016             /* Set the error code and execute error callback*/
1017             hi2s->ErrorCode |= HAL_I2S_ERROR_UDR;
1018             HAL_I2S_ErrorCallback(hi2s);
1019         }
1020     }
1021 }
1022 
1023 /**
1024   * @}
1025   */
1026 
1027 /**
1028   * @}
1029   */
1030 
1031 /** @addtogroup I2S_Private_Functions I2S Private Functions
1032   * @{
1033   */
1034 /**
1035   * @brief This function handles I2S Communication Timeout.
1036   * @param  hi2s: pointer to a I2S_HandleTypeDef structure that contains
1037   *         the configuration information for I2S module
1038   * @param Flag: Flag checked
1039   * @param State: Value of the flag expected
1040   * @param Timeout: Duration of the timeout
1041   * @retval HAL status
1042   */
I2S_WaitFlagStateUntilTimeout(I2S_HandleTypeDef * hi2s,uint32_t Flag,uint32_t State,uint32_t Timeout)1043 static HAL_StatusTypeDef I2S_WaitFlagStateUntilTimeout(I2S_HandleTypeDef *hi2s, uint32_t Flag,
1044         uint32_t State, uint32_t Timeout)
1045 {
1046     uint32_t tickstart = 0;
1047 
1048     /* Get tick */
1049     tickstart = HAL_GetTick();
1050 
1051     /* Wait until flag is set */
1052     if (State == RESET) {
1053         while (__HAL_I2S_GET_FLAG(hi2s, Flag) == RESET) {
1054             if (Timeout != HAL_MAX_DELAY) {
1055                 if ((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout)) {
1056                     /* Set the I2S State ready */
1057                     hi2s->State= HAL_I2S_STATE_READY;
1058 
1059                     /* Process Unlocked */
1060                     __HAL_UNLOCK(hi2s);
1061 
1062                     return HAL_TIMEOUT;
1063                 }
1064             }
1065         }
1066     } else {
1067         while (__HAL_I2S_GET_FLAG(hi2s, Flag) != RESET) {
1068             if (Timeout != HAL_MAX_DELAY) {
1069                 if ((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout)) {
1070                     /* Set the I2S State ready */
1071                     hi2s->State= HAL_I2S_STATE_READY;
1072 
1073                     /* Process Unlocked */
1074                     __HAL_UNLOCK(hi2s);
1075 
1076                     return HAL_TIMEOUT;
1077                 }
1078             }
1079         }
1080     }
1081     return HAL_OK;
1082 }
1083 /**
1084   * @}
1085   */
1086 
1087 /** @addtogroup I2S_Exported_Functions I2S Exported Functions
1088   * @{
1089   */
1090 
1091 /** @addtogroup  I2S_Exported_Functions_Group2 Input and Output operation functions
1092   * @{
1093   */
1094 /**
1095   * @brief Tx Transfer Half completed callbacks
1096   * @param  hi2s: pointer to a I2S_HandleTypeDef structure that contains
1097   *         the configuration information for I2S module
1098   * @retval None
1099   */
HAL_I2S_TxHalfCpltCallback(I2S_HandleTypeDef * hi2s)1100 __weak void HAL_I2S_TxHalfCpltCallback(I2S_HandleTypeDef *hi2s)
1101 {
1102     /* NOTE : This function Should not be modified, when the callback is needed,
1103               the HAL_I2S_TxHalfCpltCallback could be implemented in the user file
1104      */
1105 }
1106 
1107 /**
1108   * @brief Tx Transfer completed callbacks
1109   * @param  hi2s: pointer to a I2S_HandleTypeDef structure that contains
1110   *         the configuration information for I2S module
1111   * @retval None
1112   */
HAL_I2S_TxCpltCallback(I2S_HandleTypeDef * hi2s)1113 __weak void HAL_I2S_TxCpltCallback(I2S_HandleTypeDef *hi2s)
1114 {
1115     /* NOTE : This function Should not be modified, when the callback is needed,
1116               the HAL_I2S_TxCpltCallback could be implemented in the user file
1117      */
1118 }
1119 
1120 /**
1121   * @brief Rx Transfer half completed callbacks
1122   * @param  hi2s: pointer to a I2S_HandleTypeDef structure that contains
1123   *         the configuration information for I2S module
1124   * @retval None
1125   */
HAL_I2S_RxHalfCpltCallback(I2S_HandleTypeDef * hi2s)1126 __weak void HAL_I2S_RxHalfCpltCallback(I2S_HandleTypeDef *hi2s)
1127 {
1128     /* NOTE : This function Should not be modified, when the callback is needed,
1129               the HAL_I2S_RxCpltCallback could be implemented in the user file
1130      */
1131 }
1132 
1133 /**
1134   * @brief Rx Transfer completed callbacks
1135   * @param  hi2s: pointer to a I2S_HandleTypeDef structure that contains
1136   *         the configuration information for I2S module
1137   * @retval None
1138   */
HAL_I2S_RxCpltCallback(I2S_HandleTypeDef * hi2s)1139 __weak void HAL_I2S_RxCpltCallback(I2S_HandleTypeDef *hi2s)
1140 {
1141     /* NOTE : This function Should not be modified, when the callback is needed,
1142               the HAL_I2S_RxCpltCallback could be implemented in the user file
1143      */
1144 }
1145 
1146 /**
1147   * @brief I2S error callbacks
1148   * @param  hi2s: pointer to a I2S_HandleTypeDef structure that contains
1149   *         the configuration information for I2S module
1150   * @retval None
1151   */
HAL_I2S_ErrorCallback(I2S_HandleTypeDef * hi2s)1152 __weak void HAL_I2S_ErrorCallback(I2S_HandleTypeDef *hi2s)
1153 {
1154     /* NOTE : This function Should not be modified, when the callback is needed,
1155               the HAL_I2S_ErrorCallback could be implemented in the user file
1156      */
1157 }
1158 
1159 /**
1160   * @}
1161   */
1162 
1163 /** @defgroup I2S_Exported_Functions_Group3 Peripheral State and Errors functions
1164   *  @brief   Peripheral State functions
1165   *
1166 @verbatim
1167  ===============================================================================
1168                       ##### Peripheral State and Errors functions #####
1169  ===============================================================================
1170     [..]
1171     This subsection permits to get in run-time the status of the peripheral
1172     and the data flow.
1173 
1174 @endverbatim
1175   * @{
1176   */
1177 
1178 /**
1179   * @brief  Return the I2S state
1180   * @param  hi2s: pointer to a I2S_HandleTypeDef structure that contains
1181   *         the configuration information for I2S module
1182   * @retval HAL state
1183   */
HAL_I2S_GetState(I2S_HandleTypeDef * hi2s)1184 HAL_I2S_StateTypeDef HAL_I2S_GetState(I2S_HandleTypeDef *hi2s)
1185 {
1186     return hi2s->State;
1187 }
1188 
1189 /**
1190   * @brief  Return the I2S error code
1191   * @param  hi2s: pointer to a I2S_HandleTypeDef structure that contains
1192   *         the configuration information for I2S module
1193   * @retval I2S Error Code
1194   */
HAL_I2S_GetError(I2S_HandleTypeDef * hi2s)1195 uint32_t HAL_I2S_GetError(I2S_HandleTypeDef *hi2s)
1196 {
1197     return hi2s->ErrorCode;
1198 }
1199 /**
1200   * @}
1201   */
1202 
1203 /**
1204   * @}
1205   */
1206 
1207 /**
1208 * @brief  Get I2S Input Clock based on I2S source clock selection
1209 * @param  hi2s: pointer to a I2S_HandleTypeDef structure that contains
1210 *               the configuration information for I2S module.
1211 * @retval I2S Clock Input
1212 */
I2S_GetClockFreq(I2S_HandleTypeDef * hi2s)1213 static uint32_t I2S_GetClockFreq(I2S_HandleTypeDef *hi2s)
1214 {
1215     uint32_t tmpreg = 0;
1216     /* This variable used to store the VCO Input (value in Hz) */
1217     uint32_t vcoinput = 0;
1218     /* This variable used to store the I2S_CK_x (value in Hz) */
1219     uint32_t i2sclocksource = 0;
1220 
1221     /* Configure I2S Clock based on I2S source clock selection */
1222 
1223     /* I2S_CLK_x : I2S Block Clock configuration for different clock sources selected */
1224     switch (hi2s->Init.ClockSource) {
1225         case I2S_CLOCK_SYSCLK : {
1226             /* Configure the PLLI2S division factor */
1227             /* PLLI2S_VCO Input  = PLL_SOURCE/PLLI2SM */
1228             if ((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSI) {
1229                 /* In Case the PLL Source is HSI (Internal Clock) */
1230                 vcoinput = (HSI_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM));
1231             } else {
1232                 /* In Case the PLL Source is HSE (External Clock) */
1233                 vcoinput = ((HSE_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM)));
1234             }
1235 
1236             /* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */
1237             /* I2S_CLK(first level) = PLLI2S_VCO Output/PLLI2SR */
1238             tmpreg = (RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> 28;
1239             i2sclocksource = (vcoinput * ((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> 6))/(tmpreg);
1240 
1241             break;
1242         }
1243         case I2S_CLOCK_EXTERNAL : {
1244             i2sclocksource = EXTERNAL_CLOCK_VALUE;
1245             break;
1246         }
1247         default : {
1248             break;
1249         }
1250     }
1251 
1252     /* the return result is the value of I2S clock */
1253     return i2sclocksource;
1254 }
1255 
1256 /** @addtogroup I2S_Private_Functions I2S Private Functions
1257   * @{
1258   */
1259 /**
1260   * @brief DMA I2S transmit process complete callback
1261   * @param  hdma: pointer to a DMA_HandleTypeDef structure that contains
1262   *                the configuration information for the specified DMA module.
1263   * @retval None
1264   */
I2S_DMATxCplt(DMA_HandleTypeDef * hdma)1265 static void I2S_DMATxCplt(DMA_HandleTypeDef *hdma)
1266 {
1267     I2S_HandleTypeDef* hi2s = (I2S_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
1268 
1269     if ((hdma->Instance->CR & DMA_SxCR_CIRC) == 0) {
1270         hi2s->TxXferCount = 0;
1271 
1272         /* Disable Tx DMA Request */
1273         hi2s->Instance->CR2 &= (uint32_t)(~SPI_CR2_TXDMAEN);
1274 
1275         if (hi2s->State == HAL_I2S_STATE_BUSY_TX_RX) {
1276             if (hi2s->RxXferCount == 0) {
1277                 hi2s->State = HAL_I2S_STATE_READY;
1278             }
1279         } else {
1280             hi2s->State = HAL_I2S_STATE_READY;
1281         }
1282     }
1283     HAL_I2S_TxCpltCallback(hi2s);
1284 }
1285 
1286 /**
1287   * @brief DMA I2S transmit process half complete callback
1288   * @param  hdma: pointer to a DMA_HandleTypeDef structure that contains
1289   *                the configuration information for the specified DMA module.
1290   * @retval None
1291   */
I2S_DMATxHalfCplt(DMA_HandleTypeDef * hdma)1292 static void I2S_DMATxHalfCplt(DMA_HandleTypeDef *hdma)
1293 {
1294     I2S_HandleTypeDef* hi2s = (I2S_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
1295 
1296     HAL_I2S_TxHalfCpltCallback(hi2s);
1297 }
1298 
1299 /**
1300   * @brief DMA I2S receive process complete callback
1301   * @param  hdma: pointer to a DMA_HandleTypeDef structure that contains
1302   *                the configuration information for the specified DMA module.
1303   * @retval None
1304   */
I2S_DMARxCplt(DMA_HandleTypeDef * hdma)1305 static void I2S_DMARxCplt(DMA_HandleTypeDef *hdma)
1306 {
1307     I2S_HandleTypeDef* hi2s = (I2S_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
1308 
1309     if ((hdma->Instance->CR & DMA_SxCR_CIRC) == 0) {
1310         /* Disable Rx DMA Request */
1311         hi2s->Instance->CR2 &= (uint32_t)(~SPI_CR2_RXDMAEN);
1312 
1313         hi2s->RxXferCount = 0;
1314         if (hi2s->State == HAL_I2S_STATE_BUSY_TX_RX) {
1315             if (hi2s->TxXferCount == 0) {
1316                 hi2s->State = HAL_I2S_STATE_READY;
1317             }
1318         } else {
1319             hi2s->State = HAL_I2S_STATE_READY;
1320         }
1321     }
1322     HAL_I2S_RxCpltCallback(hi2s);
1323 }
1324 
1325 /**
1326   * @brief DMA I2S receive process half complete callback
1327   * @param  hdma: pointer to a DMA_HandleTypeDef structure that contains
1328   *                the configuration information for the specified DMA module.
1329   * @retval None
1330   */
I2S_DMARxHalfCplt(DMA_HandleTypeDef * hdma)1331 static void I2S_DMARxHalfCplt(DMA_HandleTypeDef *hdma)
1332 {
1333     I2S_HandleTypeDef* hi2s = (I2S_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
1334 
1335     HAL_I2S_RxHalfCpltCallback(hi2s);
1336 }
1337 
1338 /**
1339   * @brief DMA I2S communication error callback
1340   * @param  hdma: pointer to a DMA_HandleTypeDef structure that contains
1341   *                the configuration information for the specified DMA module.
1342   * @retval None
1343   */
I2S_DMAError(DMA_HandleTypeDef * hdma)1344 static void I2S_DMAError(DMA_HandleTypeDef *hdma)
1345 {
1346     I2S_HandleTypeDef* hi2s = ( I2S_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
1347 
1348     /* Disable Rx and Tx DMA Request */
1349     hi2s->Instance->CR2 &= (uint32_t)(~(SPI_CR2_RXDMAEN | SPI_CR2_TXDMAEN));
1350     hi2s->TxXferCount = 0;
1351     hi2s->RxXferCount = 0;
1352 
1353     hi2s->State= HAL_I2S_STATE_READY;
1354 
1355     /* Set the error code and execute error callback*/
1356     hi2s->ErrorCode |= HAL_I2S_ERROR_DMA;
1357     HAL_I2S_ErrorCallback(hi2s);
1358 }
1359 
1360 /**
1361   * @brief Transmit an amount of data in non-blocking mode with Interrupt
1362   * @param  hi2s: pointer to a I2S_HandleTypeDef structure that contains
1363   *         the configuration information for I2S module
1364   * @retval None
1365   */
I2S_Transmit_IT(I2S_HandleTypeDef * hi2s)1366 static void I2S_Transmit_IT(I2S_HandleTypeDef *hi2s)
1367 {
1368     /* Transmit data */
1369     hi2s->Instance->DR = (*hi2s->pTxBuffPtr++);
1370     hi2s->TxXferCount--;
1371 
1372     if (hi2s->TxXferCount == 0) {
1373         /* Disable TXE and ERR interrupt */
1374         __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR));
1375 
1376         hi2s->State = HAL_I2S_STATE_READY;
1377         HAL_I2S_TxCpltCallback(hi2s);
1378     }
1379 }
1380 
1381 /**
1382   * @brief Receive an amount of data in non-blocking mode with Interrupt
1383   * @param hi2s: I2S handle
1384   * @retval None
1385   */
I2S_Receive_IT(I2S_HandleTypeDef * hi2s)1386 static void I2S_Receive_IT(I2S_HandleTypeDef *hi2s)
1387 {
1388     /* Receive data */
1389     (*hi2s->pRxBuffPtr++) = hi2s->Instance->DR;
1390     hi2s->RxXferCount--;
1391 
1392     if (hi2s->RxXferCount == 0) {
1393         /* Disable RXNE and ERR interrupt */
1394         __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_RXNE | I2S_IT_ERR));
1395 
1396         hi2s->State = HAL_I2S_STATE_READY;
1397         HAL_I2S_RxCpltCallback(hi2s);
1398     }
1399 }
1400 /**
1401   * @}
1402   */
1403 
1404 #endif /* HAL_I2S_MODULE_ENABLED */
1405 /**
1406   * @}
1407   */
1408 
1409 /**
1410   * @}
1411   */
1412 
1413 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
1414