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