source: asp3_wo_tecs/trunk/arch/arm_m_gcc/stm32f4xx_stm32cube/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2s_ex.c@ 303

Last change on this file since 303 was 303, checked in by ertl-honda, 7 years ago

nucleo_f401re依存部の追加

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