comparison Common/Drivers/STM32F4xx_HAL_DRIVER_v120/Src/stm32f4xx_hal_i2s_ex.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_ex.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 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) 2014 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
118 /* Private typedef -----------------------------------------------------------*/
119 /* Private define ------------------------------------------------------------*/
120 /* Private macro -------------------------------------------------------------*/
121 /* Private variables ---------------------------------------------------------*/
122 /* Private function prototypes -----------------------------------------------*/
123 /* Private functions ---------------------------------------------------------*/
124 /** @addtogroup I2SEx_Private_Functions
125 * @{
126 */
127 /**
128 * @}
129 */
130
131 /* Exported functions --------------------------------------------------------*/
132 /** @defgroup I2SEx_Exported_Functions I2S Exported Functions
133 * @{
134 */
135
136 /** @defgroup I2SEx_Group1 Extension features functions
137 * @brief Extension features functions
138 *
139 @verbatim
140 ===============================================================================
141 ##### Extension features Functions #####
142 ===============================================================================
143 [..]
144 This subsection provides a set of functions allowing to manage the I2S data
145 transfers.
146
147 (#) There are two modes of transfer:
148 (++) Blocking mode : The communication is performed in the polling mode.
149 The status of all data processing is returned by the same function
150 after finishing transfer.
151 (++) No-Blocking mode : The communication is performed using Interrupts
152 or DMA. These functions return the status of the transfer startup.
153 The end of the data processing will be indicated through the
154 dedicated I2S IRQ when using Interrupt mode or the DMA IRQ when
155 using DMA mode.
156
157 (#) Blocking mode functions are :
158 (++) HAL_I2S_TransmitReceive()
159
160 (#) No-Blocking mode functions with Interrupt are :
161 (++) HAL_I2S_TransmitReceive_IT()
162
163 (#) No-Blocking mode functions with DMA are :
164 (++) HAL_I2S_TransmitReceive_DMA()
165
166 (#) A set of Transfer Complete Callbacks are provided in non Blocking mode:
167 (++) HAL_I2S_TxCpltCallback()
168 (++) HAL_I2S_RxCpltCallback()
169 (++) HAL_I2S_ErrorCallback()
170
171 @endverbatim
172 * @{
173 */
174
175 /**
176 * @brief Full-Duplex Transmit/Receive data in blocking mode.
177 * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
178 * the configuration information for I2S module
179 * @param pTxData: a 16-bit pointer to the Transmit data buffer.
180 * @param pRxData: a 16-bit pointer to the Receive data buffer.
181 * @param Size: number of data sample to be sent:
182 * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
183 * configuration phase, the Size parameter means the number of 16-bit data length
184 * in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
185 * the Size parameter means the number of 16-bit data length.
186 * @param Timeout: Timeout duration
187 * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
188 * between Master and Slave(example: audio streaming).
189 * @retval HAL status
190 */
191 HAL_StatusTypeDef HAL_I2SEx_TransmitReceive(I2S_HandleTypeDef *hi2s, uint16_t *pTxData, uint16_t *pRxData, uint16_t Size, uint32_t Timeout)
192 {
193 uint32_t tickstart = 0;
194 uint32_t tmp1 = 0, tmp2 = 0;
195
196 if((pTxData == NULL ) || (pRxData == NULL ) || (Size == 0))
197 {
198 return HAL_ERROR;
199 }
200
201 /* Check the I2S State */
202 if(hi2s->State == HAL_I2S_STATE_READY)
203 {
204 tmp1 = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN);
205 tmp2 = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN);
206 /* Check the Data format: When a 16-bit data frame or a 16-bit data frame extended
207 is selected during the I2S configuration phase, the Size parameter means the number
208 of 16-bit data length in the transaction and when a 24-bit data frame or a 32-bit data
209 frame is selected the Size parameter means the number of 16-bit data length. */
210 if((tmp1 == I2S_DATAFORMAT_24B)|| \
211 (tmp2 == I2S_DATAFORMAT_32B))
212 {
213 hi2s->TxXferSize = Size*2;
214 hi2s->TxXferCount = Size*2;
215 hi2s->RxXferSize = Size*2;
216 hi2s->RxXferCount = Size*2;
217 }
218 else
219 {
220 hi2s->TxXferSize = Size;
221 hi2s->TxXferCount = Size;
222 hi2s->RxXferSize = Size;
223 hi2s->RxXferCount = Size;
224 }
225
226 /* Process Locked */
227 __HAL_LOCK(hi2s);
228
229 /* Set the I2S State busy TX/RX */
230 hi2s->State = HAL_I2S_STATE_BUSY_TX_RX;
231
232 tmp1 = hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG;
233 tmp2 = hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG;
234 /* Check if the I2S_MODE_MASTER_TX or I2S_MODE_SLAVE_TX Mode is selected */
235 if((tmp1 == I2S_MODE_MASTER_TX) || (tmp2 == I2S_MODE_SLAVE_TX))
236 {
237 /* Check if the I2S is already enabled: The I2S is kept enabled at the end of transaction
238 to avoid the clock de-synchronization between Master and Slave. */
239 if((hi2s->Instance->I2SCFGR &SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE)
240 {
241 /* Enable I2Sext(receiver) before enabling I2Sx peripheral */
242 I2SxEXT(hi2s->Instance)->I2SCFGR |= SPI_I2SCFGR_I2SE;
243
244 /* Enable I2Sx peripheral */
245 __HAL_I2S_ENABLE(hi2s);
246 }
247
248 while(hi2s->TxXferCount > 0)
249 {
250 /* Wait until TXE flag is set */
251 if (I2S_WaitFlagStateUntilTimeout(hi2s, I2S_FLAG_TXE, RESET, Timeout) != HAL_OK)
252 {
253 return HAL_TIMEOUT;
254 }
255 hi2s->Instance->DR = (*pTxData++);
256
257 /* Get tick */
258 tickstart = HAL_GetTick();
259
260 /* Wait until RXNE flag is set */
261 while((I2SxEXT(hi2s->Instance)->SR & SPI_SR_RXNE) != SPI_SR_RXNE)
262 {
263 if(Timeout != HAL_MAX_DELAY)
264 {
265 if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
266 {
267 /* Process Unlocked */
268 __HAL_UNLOCK(hi2s);
269
270 return HAL_TIMEOUT;
271 }
272 }
273 }
274 (*pRxData++) = I2SxEXT(hi2s->Instance)->DR;
275
276 hi2s->TxXferCount--;
277 hi2s->RxXferCount--;
278 }
279 }
280 /* The I2S_MODE_MASTER_RX or I2S_MODE_SLAVE_RX Mode is selected */
281 else
282 {
283 /* Check if the I2S is already enabled */
284 if((hi2s->Instance->I2SCFGR &SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE)
285 {
286 /* Enable I2S peripheral before the I2Sext*/
287 __HAL_I2S_ENABLE(hi2s);
288
289 /* Enable I2Sext(transmitter) after enabling I2Sx peripheral */
290 I2SxEXT(hi2s->Instance)->I2SCFGR |= SPI_I2SCFGR_I2SE;
291 }
292 else
293 {
294 /* Check if Master Receiver mode is selected */
295 if((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_MASTER_RX)
296 {
297 /* Clear the Overrun Flag by a read operation on the SPI_DR register followed by a read
298 access to the SPI_SR register. */
299 __HAL_I2S_CLEAR_OVRFLAG(hi2s);
300 }
301 }
302 while(hi2s->TxXferCount > 0)
303 {
304 /* Get tick */
305 tickstart = HAL_GetTick();
306
307 /* Wait until TXE flag is set */
308 while((I2SxEXT(hi2s->Instance)->SR & SPI_SR_TXE) != SPI_SR_TXE)
309 {
310 if(Timeout != HAL_MAX_DELAY)
311 {
312 if((Timeout == 0)||((HAL_GetTick() - tickstart ) > Timeout))
313 {
314 /* Process Unlocked */
315 __HAL_UNLOCK(hi2s);
316
317 return HAL_TIMEOUT;
318 }
319 }
320 }
321 I2SxEXT(hi2s->Instance)->DR = (*pTxData++);
322
323 /* Wait until RXNE flag is set */
324 if (I2S_WaitFlagStateUntilTimeout(hi2s, I2S_FLAG_RXNE, RESET, Timeout) != HAL_OK)
325 {
326 return HAL_TIMEOUT;
327 }
328 (*pRxData++) = hi2s->Instance->DR;
329
330 hi2s->TxXferCount--;
331 hi2s->RxXferCount--;
332 }
333 }
334
335 /* Set the I2S State ready */
336 hi2s->State = HAL_I2S_STATE_READY;
337
338 /* Process Unlocked */
339 __HAL_UNLOCK(hi2s);
340
341 return HAL_OK;
342 }
343 else
344 {
345 return HAL_BUSY;
346 }
347 }
348
349 /**
350 * @brief Full-Duplex Transmit/Receive data in non-blocking mode using Interrupt
351 * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
352 * the configuration information for I2S module
353 * @param pTxData: a 16-bit pointer to the Transmit data buffer.
354 * @param pRxData: a 16-bit pointer to the Receive data buffer.
355 * @param Size: number of data sample to be sent:
356 * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
357 * configuration phase, the Size parameter means the number of 16-bit data length
358 * in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
359 * the Size parameter means the number of 16-bit data length.
360 * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
361 * between Master and Slave(example: audio streaming).
362 * @retval HAL status
363 */
364 HAL_StatusTypeDef HAL_I2SEx_TransmitReceive_IT(I2S_HandleTypeDef *hi2s, uint16_t *pTxData, uint16_t *pRxData, uint16_t Size)
365 {
366 uint32_t tmp1 = 0, tmp2 = 0;
367
368 if(hi2s->State == HAL_I2S_STATE_READY)
369 {
370 if((pTxData == NULL ) || (pRxData == NULL ) || (Size == 0))
371 {
372 return HAL_ERROR;
373 }
374
375 hi2s->pTxBuffPtr = pTxData;
376 hi2s->pRxBuffPtr = pRxData;
377
378 tmp1 = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN);
379 tmp2 = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN);
380 /* Check the Data format: When a 16-bit data frame or a 16-bit data frame extended
381 is selected during the I2S configuration phase, the Size parameter means the number
382 of 16-bit data length in the transaction and when a 24-bit data frame or a 32-bit data
383 frame is selected the Size parameter means the number of 16-bit data length. */
384 if((tmp1 == I2S_DATAFORMAT_24B)||\
385 (tmp2 == I2S_DATAFORMAT_32B))
386 {
387 hi2s->TxXferSize = Size*2;
388 hi2s->TxXferCount = Size*2;
389 hi2s->RxXferSize = Size*2;
390 hi2s->RxXferCount = Size*2;
391 }
392 else
393 {
394 hi2s->TxXferSize = Size;
395 hi2s->TxXferCount = Size;
396 hi2s->RxXferSize = Size;
397 hi2s->RxXferCount = Size;
398 }
399
400 /* Process Locked */
401 __HAL_LOCK(hi2s);
402
403 hi2s->State = HAL_I2S_STATE_BUSY_TX_RX;
404 hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
405
406 tmp1 = hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG;
407 tmp2 = hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG;
408 /* Check if the I2S_MODE_MASTER_TX or I2S_MODE_SLAVE_TX Mode is selected */
409 if((tmp1 == I2S_MODE_MASTER_TX) || (tmp2 == I2S_MODE_SLAVE_TX))
410 {
411 /* Enable I2Sext RXNE and ERR interrupts */
412 I2SxEXT(hi2s->Instance)->CR2 |= (I2S_IT_RXNE | I2S_IT_ERR);
413
414 /* Enable I2Sx TXE and ERR interrupts */
415 __HAL_I2S_ENABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR));
416
417 /* Check if the I2S is already enabled */
418 if((hi2s->Instance->I2SCFGR &SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE)
419 {
420 /* Enable I2Sext(receiver) before enabling I2Sx peripheral */
421 I2SxEXT(hi2s->Instance)->I2SCFGR |= SPI_I2SCFGR_I2SE;
422
423 /* Enable I2Sx peripheral */
424 __HAL_I2S_ENABLE(hi2s);
425 }
426 }
427 /* The I2S_MODE_MASTER_RX or I2S_MODE_SLAVE_RX Mode is selected */
428 else
429 {
430 /* Enable I2Sext TXE and ERR interrupts */
431 I2SxEXT(hi2s->Instance)->CR2 |= (I2S_IT_TXE |I2S_IT_ERR);
432
433 /* Enable I2Sext RXNE and ERR interrupts */
434 __HAL_I2S_ENABLE_IT(hi2s, (I2S_IT_RXNE | I2S_IT_ERR));
435
436 /* Check if the I2S is already enabled */
437 if((hi2s->Instance->I2SCFGR &SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE)
438 {
439 /* Check if the I2S_MODE_MASTER_RX is selected */
440 if((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_MASTER_RX)
441 {
442 /* Prepare the First Data before enabling the I2S */
443 if(hi2s->TxXferCount != 0)
444 {
445 /* Transmit First data */
446 I2SxEXT(hi2s->Instance)->DR = (*hi2s->pTxBuffPtr++);
447 hi2s->TxXferCount--;
448
449 if(hi2s->TxXferCount == 0)
450 {
451 /* Disable I2Sext TXE interrupt */
452 I2SxEXT(hi2s->Instance)->CR2 &= ~I2S_IT_TXE;
453 }
454 }
455 }
456 /* Enable I2S peripheral */
457 __HAL_I2S_ENABLE(hi2s);
458
459 /* Enable I2Sext(transmitter) after enabling I2Sx peripheral */
460 I2SxEXT(hi2s->Instance)->I2SCFGR |= SPI_I2SCFGR_I2SE;
461 }
462 }
463 /* Process Unlocked */
464 __HAL_UNLOCK(hi2s);
465
466 return HAL_OK;
467 }
468 else
469 {
470 return HAL_BUSY;
471 }
472 }
473
474 /**
475 * @brief Full-Duplex Transmit/Receive data in non-blocking mode using DMA
476 * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
477 * the configuration information for I2S module
478 * @param pTxData: a 16-bit pointer to the Transmit data buffer.
479 * @param pRxData: a 16-bit pointer to the Receive data buffer.
480 * @param Size: number of data sample to be sent:
481 * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S
482 * configuration phase, the Size parameter means the number of 16-bit data length
483 * in the transaction and when a 24-bit data frame or a 32-bit data frame is selected
484 * the Size parameter means the number of 16-bit data length.
485 * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization
486 * between Master and Slave(example: audio streaming).
487 * @retval HAL status
488 */
489 HAL_StatusTypeDef HAL_I2SEx_TransmitReceive_DMA(I2S_HandleTypeDef *hi2s, uint16_t *pTxData, uint16_t *pRxData, uint16_t Size)
490 {
491 uint32_t *tmp;
492 uint32_t tmp1 = 0, tmp2 = 0;
493
494 if((pTxData == NULL ) || (pRxData == NULL ) || (Size == 0))
495 {
496 return HAL_ERROR;
497 }
498
499 if(hi2s->State == HAL_I2S_STATE_READY)
500 {
501 hi2s->pTxBuffPtr = pTxData;
502 hi2s->pRxBuffPtr = pRxData;
503
504 tmp1 = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN);
505 tmp2 = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN);
506 /* Check the Data format: When a 16-bit data frame or a 16-bit data frame extended
507 is selected during the I2S configuration phase, the Size parameter means the number
508 of 16-bit data length in the transaction and when a 24-bit data frame or a 32-bit data
509 frame is selected the Size parameter means the number of 16-bit data length. */
510 if((tmp1 == I2S_DATAFORMAT_24B)||\
511 (tmp2 == I2S_DATAFORMAT_32B))
512 {
513 hi2s->TxXferSize = Size*2;
514 hi2s->TxXferCount = Size*2;
515 hi2s->RxXferSize = Size*2;
516 hi2s->RxXferCount = Size*2;
517 }
518 else
519 {
520 hi2s->TxXferSize = Size;
521 hi2s->TxXferCount = Size;
522 hi2s->RxXferSize = Size;
523 hi2s->RxXferCount = Size;
524 }
525
526 /* Process Locked */
527 __HAL_LOCK(hi2s);
528
529 hi2s->State = HAL_I2S_STATE_BUSY_TX_RX;
530 hi2s->ErrorCode = HAL_I2S_ERROR_NONE;
531
532 /* Set the I2S Rx DMA Half transfer complete callback */
533 hi2s->hdmarx->XferHalfCpltCallback = I2S_DMARxHalfCplt;
534
535 /* Set the I2S Rx DMA transfer complete callback */
536 hi2s->hdmarx->XferCpltCallback = I2S_DMARxCplt;
537
538 /* Set the I2S Rx DMA error callback */
539 hi2s->hdmarx->XferErrorCallback = I2S_DMAError;
540
541 /* Set the I2S Tx DMA Half transfer complete callback */
542 hi2s->hdmatx->XferHalfCpltCallback = I2S_DMATxHalfCplt;
543
544 /* Set the I2S Tx DMA transfer complete callback */
545 hi2s->hdmatx->XferCpltCallback = I2S_DMATxCplt;
546
547 /* Set the I2S Tx DMA error callback */
548 hi2s->hdmatx->XferErrorCallback = I2S_DMAError;
549
550 tmp1 = hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG;
551 tmp2 = hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG;
552 /* Check if the I2S_MODE_MASTER_TX or I2S_MODE_SLAVE_TX Mode is selected */
553 if((tmp1 == I2S_MODE_MASTER_TX) || (tmp2 == I2S_MODE_SLAVE_TX))
554 {
555 /* Enable the Rx DMA Stream */
556 tmp = (uint32_t*)&pRxData;
557 HAL_DMA_Start_IT(hi2s->hdmarx, (uint32_t)&I2SxEXT(hi2s->Instance)->DR, *(uint32_t*)tmp, hi2s->RxXferSize);
558
559 /* Enable Rx DMA Request */
560 I2SxEXT(hi2s->Instance)->CR2 |= SPI_CR2_RXDMAEN;
561
562 /* Enable the Tx DMA Stream */
563 tmp = (uint32_t*)&pTxData;
564 HAL_DMA_Start_IT(hi2s->hdmatx, *(uint32_t*)tmp, (uint32_t)&hi2s->Instance->DR, hi2s->TxXferSize);
565
566 /* Enable Tx DMA Request */
567 hi2s->Instance->CR2 |= SPI_CR2_TXDMAEN;
568
569 /* Check if the I2S is already enabled */
570 if((hi2s->Instance->I2SCFGR &SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE)
571 {
572 /* Enable I2Sext(receiver) before enabling I2Sx peripheral */
573 I2SxEXT(hi2s->Instance)->I2SCFGR |= SPI_I2SCFGR_I2SE;
574
575 /* Enable I2S peripheral after the I2Sext */
576 __HAL_I2S_ENABLE(hi2s);
577 }
578 }
579 else
580 {
581 /* Enable the Tx DMA Stream */
582 tmp = (uint32_t*)&pTxData;
583 HAL_DMA_Start_IT(hi2s->hdmatx, *(uint32_t*)tmp, (uint32_t)&I2SxEXT(hi2s->Instance)->DR, hi2s->TxXferSize);
584
585 /* Enable Tx DMA Request */
586 I2SxEXT(hi2s->Instance)->CR2 |= SPI_CR2_TXDMAEN;
587
588 /* Enable the Rx DMA Stream */
589 tmp = (uint32_t*)&pRxData;
590 HAL_DMA_Start_IT(hi2s->hdmarx, (uint32_t)&hi2s->Instance->DR, *(uint32_t*)tmp, hi2s->RxXferSize);
591
592 /* Enable Rx DMA Request */
593 hi2s->Instance->CR2 |= SPI_CR2_RXDMAEN;
594
595 /* Check if the I2S is already enabled */
596 if((hi2s->Instance->I2SCFGR &SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE)
597 {
598 /* Enable I2S peripheral before the I2Sext */
599 __HAL_I2S_ENABLE(hi2s);
600
601 /* Enable I2Sext(transmitter) after enabling I2Sx peripheral */
602 I2SxEXT(hi2s->Instance)->I2SCFGR |= SPI_I2SCFGR_I2SE;
603 }
604 else
605 {
606 /* Check if Master Receiver mode is selected */
607 if((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_MASTER_RX)
608 {
609 /* Clear the Overrun Flag by a read operation on the SPI_DR register followed by a read
610 access to the SPI_SR register. */
611 __HAL_I2S_CLEAR_OVRFLAG(hi2s);
612 }
613 }
614 }
615
616 /* Process Unlocked */
617 __HAL_UNLOCK(hi2s);
618
619 return HAL_OK;
620 }
621 else
622 {
623 return HAL_BUSY;
624 }
625 }
626
627 /**
628 * @}
629 */
630
631
632 /**
633 * @brief Full-Duplex Transmit/Receive data in non-blocking mode using Interrupt
634 * @param hi2s: pointer to a I2S_HandleTypeDef structure that contains
635 * the configuration information for I2S module
636 * @retval HAL status
637 */
638 HAL_StatusTypeDef I2SEx_TransmitReceive_IT(I2S_HandleTypeDef *hi2s)
639 {
640 uint32_t tmp1 = 0, tmp2 = 0;
641
642 if(hi2s->State == HAL_I2S_STATE_BUSY_TX_RX)
643 {
644 /* Process Locked */
645 __HAL_LOCK(hi2s);
646
647 tmp1 = hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG;
648 tmp2 = hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG;
649 /* Check if the I2S_MODE_MASTER_TX or I2S_MODE_SLAVE_TX Mode is selected */
650 if((tmp1 == I2S_MODE_MASTER_TX) || (tmp2 == I2S_MODE_SLAVE_TX))
651 {
652 if(hi2s->TxXferCount != 0)
653 {
654 if(__HAL_I2S_GET_FLAG(hi2s, I2S_FLAG_TXE) != RESET)
655 {
656 /* Transmit data */
657 hi2s->Instance->DR = (*hi2s->pTxBuffPtr++);
658 hi2s->TxXferCount--;
659
660 if(hi2s->TxXferCount == 0)
661 {
662 /* Disable TXE interrupt */
663 __HAL_I2S_DISABLE_IT(hi2s, I2S_IT_TXE);
664 }
665 }
666 }
667
668 if(hi2s->RxXferCount != 0)
669 {
670 if((I2SxEXT(hi2s->Instance)->SR & SPI_SR_RXNE) == SPI_SR_RXNE)
671 {
672 /* Receive data */
673 (*hi2s->pRxBuffPtr++) = I2SxEXT(hi2s->Instance)->DR;
674 hi2s->RxXferCount--;
675
676 if(hi2s->RxXferCount == 0)
677 {
678 /* Disable I2Sext RXNE interrupt */
679 I2SxEXT(hi2s->Instance)->CR2 &= ~I2S_IT_RXNE;
680 }
681 }
682 }
683 }
684 /* The I2S_MODE_MASTER_RX or I2S_MODE_SLAVE_RX Mode is selected */
685 else
686 {
687 if(hi2s->TxXferCount != 0)
688 {
689 if((I2SxEXT(hi2s->Instance)->SR & SPI_SR_TXE) == SPI_SR_TXE)
690 {
691 /* Transmit data */
692 I2SxEXT(hi2s->Instance)->DR = (*hi2s->pTxBuffPtr++);
693 hi2s->TxXferCount--;
694
695 if(hi2s->TxXferCount == 0)
696 {
697 /* Disable I2Sext TXE interrupt */
698 I2SxEXT(hi2s->Instance)->CR2 &= ~I2S_IT_TXE;
699
700 HAL_I2S_TxCpltCallback(hi2s);
701 }
702 }
703 }
704 if(hi2s->RxXferCount != 0)
705 {
706 if(__HAL_I2S_GET_FLAG(hi2s, I2S_FLAG_RXNE) != RESET)
707 {
708 /* Receive data */
709 (*hi2s->pRxBuffPtr++) = hi2s->Instance->DR;
710 hi2s->RxXferCount--;
711
712 if(hi2s->RxXferCount == 0)
713 {
714 /* Disable RXNE interrupt */
715 __HAL_I2S_DISABLE_IT(hi2s, I2S_IT_RXNE);
716
717 HAL_I2S_RxCpltCallback(hi2s);
718 }
719 }
720 }
721 }
722
723 tmp1 = hi2s->RxXferCount;
724 tmp2 = hi2s->TxXferCount;
725 if((tmp1 == 0) && (tmp2 == 0))
726 {
727 /* Disable I2Sx ERR interrupt */
728 __HAL_I2S_DISABLE_IT(hi2s, I2S_IT_ERR);
729 /* Disable I2Sext ERR interrupt */
730 I2SxEXT(hi2s->Instance)->CR2 &= ~I2S_IT_ERR;
731
732 hi2s->State = HAL_I2S_STATE_READY;
733 }
734
735 /* Process Unlocked */
736 __HAL_UNLOCK(hi2s);
737
738 return HAL_OK;
739 }
740 else
741 {
742 return HAL_BUSY;
743 }
744 }
745
746 /**
747 * @}
748 */
749
750 #endif /* HAL_I2S_MODULE_ENABLED */
751 /**
752 * @}
753 */
754
755 /**
756 * @}
757 */
758
759 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/