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