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