Mercurial > public > ostc4
comparison Common/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_i2s_ex.c @ 160:e3ca52b8e7fa
Merge with FlipDisplay
author | heinrichsweikamp |
---|---|
date | Thu, 07 Mar 2019 15:06:43 +0100 |
parents | c78bcbd5deda |
children |
comparison
equal
deleted
inserted
replaced
80:cc2bb7bb8456 | 160:e3ca52b8e7fa |
---|---|
1 /** | |
2 ****************************************************************************** | |
3 * @file stm32f4xx_hal_i2s_ex.c | |
4 * @author MCD Application Team | |
5 * @brief I2S HAL module driver. | |
6 * This file provides firmware functions to manage the following | |
7 * functionalities of I2S extension peripheral: | |
8 * + Extension features Functions | |
9 * | |
10 @verbatim | |
11 ============================================================================== | |
12 ##### I2S Extension features ##### | |
13 ============================================================================== | |
14 [..] | |
15 (#) In I2S full duplex mode, each SPI peripheral is able to manage sending and receiving | |
16 data simultaneously using two data lines. Each SPI peripheral has an extended block | |
17 called I2Sxext (i.e I2S2ext for SPI2 and I2S3ext for SPI3). | |
18 (#) The extension block is not a full SPI IP, it is used only as I2S slave to | |
19 implement full duplex mode. The extension block uses the same clock sources | |
20 as its master. | |
21 | |
22 (#) Both I2Sx and I2Sx_ext can be configured as transmitters or receivers. | |
23 | |
24 [..] | |
25 (@) Only I2Sx can deliver SCK and WS to I2Sx_ext in full duplex mode, where | |
26 I2Sx can be I2S2 or I2S3. | |
27 | |
28 ##### How to use this driver ##### | |
29 =============================================================================== | |
30 [..] | |
31 Three operation modes are available within this driver : | |
32 | |
33 *** Polling mode IO operation *** | |
34 ================================= | |
35 [..] | |
36 (+) Send and receive in the same time an amount of data in blocking mode using HAL_I2SEx_TransmitReceive() | |
37 | |
38 *** Interrupt mode IO operation *** | |
39 =================================== | |
40 [..] | |
41 (+) Send and receive in the same time an amount of data in non blocking mode using HAL_I2SEx_TransmitReceive_IT() | |
42 (+) At transmission/reception end of transfer HAL_I2SEx_TxRxCpltCallback is executed and user can | |
43 add his own code by customization of function pointer HAL_I2SEx_TxRxCpltCallback | |
44 (+) In case of transfer Error, HAL_I2S_ErrorCallback() function is executed and user can | |
45 add his own code by customization of function pointer HAL_I2S_ErrorCallback | |
46 | |
47 *** DMA mode IO operation *** | |
48 ============================== | |
49 [..] | |
50 (+) Send and receive an amount of data in non blocking mode (DMA) using HAL_I2SEx_TransmitReceive_DMA() | |
51 (+) At transmission/reception end of transfer HAL_I2SEx_TxRxCpltCallback is executed and user can | |
52 add his own code by customization of function pointer HAL_I2S_TxRxCpltCallback | |
53 (+) In case of transfer Error, HAL_I2S_ErrorCallback() function is executed and user can | |
54 add his own code by customization of function pointer HAL_I2S_ErrorCallback | |
55 @endverbatim | |
56 | |
57 Additional Figure: The Extended block uses the same clock sources as its master. | |
58 | |
59 +-----------------------+ | |
60 I2Sx_SCK | | | |
61 ----------+-->| I2Sx |------------------->I2Sx_SD(in/out) | |
62 +--|-->| | | |
63 | | +-----------------------+ | |
64 | | | |
65 I2S_WS | | | |
66 ------>| | | |
67 | | +-----------------------+ | |
68 | +-->| | | |
69 | | I2Sx_ext |------------------->I2Sx_extSD(in/out) | |
70 +----->| | | |
71 +-----------------------+ | |
72 ****************************************************************************** | |
73 * @attention | |
74 * | |
75 * <h2><center>© COPYRIGHT(c) 2017 STMicroelectronics</center></h2> | |
76 * | |
77 * Redistribution and use in source and binary forms, with or without modification, | |
78 * are permitted provided that the following conditions are met: | |
79 * 1. Redistributions of source code must retain the above copyright notice, | |
80 * this list of conditions and the following disclaimer. | |
81 * 2. Redistributions in binary form must reproduce the above copyright notice, | |
82 * this list of conditions and the following disclaimer in the documentation | |
83 * and/or other materials provided with the distribution. | |
84 * 3. Neither the name of STMicroelectronics nor the names of its contributors | |
85 * may be used to endorse or promote products derived from this software | |
86 * without specific prior written permission. | |
87 * | |
88 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | |
89 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
90 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
91 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE | |
92 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
93 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | |
94 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | |
95 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | |
96 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
97 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
98 * | |
99 ****************************************************************************** | |
100 */ | |
101 | |
102 /* Includes ------------------------------------------------------------------*/ | |
103 #include "stm32f4xx_hal.h" | |
104 | |
105 /** @addtogroup STM32F4xx_HAL_Driver | |
106 * @{ | |
107 */ | |
108 | |
109 #ifdef HAL_I2S_MODULE_ENABLED | |
110 | |
111 /** @defgroup I2SEx I2SEx | |
112 * @brief I2S Extended HAL module driver | |
113 * @{ | |
114 */ | |
115 | |
116 #if defined (SPI_I2S_FULLDUPLEX_SUPPORT) | |
117 | |
118 /* Private typedef -----------------------------------------------------------*/ | |
119 /** @defgroup I2SEx_Private_Typedef I2S Extended Private Typedef | |
120 * @{ | |
121 */ | |
122 typedef enum | |
123 { | |
124 I2S_USE_I2S = 0x00U, /*!< I2Sx should be used */ | |
125 I2S_USE_I2SEXT = 0x01U, /*!< I2Sx_ext should be used */ | |
126 }I2S_UseTypeDef; | |
127 /** | |
128 * @} | |
129 */ | |
130 /* Private define ------------------------------------------------------------*/ | |
131 /* Private macro -------------------------------------------------------------*/ | |
132 /* Private variables ---------------------------------------------------------*/ | |
133 /* Private function prototypes -----------------------------------------------*/ | |
134 /** @defgroup I2SEx_Private_Functions I2S Extended Private Functions | |
135 * @{ | |
136 */ | |
137 static void I2SEx_TxRxDMAHalfCplt(DMA_HandleTypeDef *hdma); | |
138 static void I2SEx_TxRxDMACplt(DMA_HandleTypeDef *hdma); | |
139 static void I2SEx_TxRxDMAError(DMA_HandleTypeDef *hdma); | |
140 static void I2SEx_FullDuplexTx_IT(I2S_HandleTypeDef *hi2s, I2S_UseTypeDef i2sUsed); | |
141 static void I2SEx_FullDuplexRx_IT(I2S_HandleTypeDef *hi2s, I2S_UseTypeDef i2sUsed); | |
142 static HAL_StatusTypeDef I2SEx_FullDuplexWaitFlagStateUntilTimeout(I2S_HandleTypeDef *hi2s, uint32_t Flag, | |
143 uint32_t State, uint32_t Timeout, I2S_UseTypeDef i2sUsed); | |
144 /** | |
145 * @} | |
146 */ | |
147 | |
148 /** | |
149 * @} | |
150 */ | |
151 | |
152 /* Private functions ---------------------------------------------------------*/ | |
153 /* Exported functions --------------------------------------------------------*/ | |
154 | |
155 /** @addtogroup I2SEx I2SEx | |
156 * @{ | |
157 */ | |
158 | |
159 /** @addtogroup I2SEx_Exported_Functions I2S Extended Exported Functions | |
160 * @{ | |
161 */ | |
162 | |
163 /** @defgroup I2SEx_Exported_Functions_Group1 I2S Extended IO operation functions | |
164 * @brief I2SEx IO operation functions | |
165 * | |
166 @verbatim | |
167 =============================================================================== | |
168 ##### IO operation functions##### | |
169 =============================================================================== | |
170 [..] | |
171 This subsection provides a set of functions allowing to manage the I2S data | |
172 transfers. | |
173 | |
174 (#) There are two modes of transfer: | |
175 (++) Blocking mode : The communication is performed in the polling mode. | |
176 The status of all data processing is returned by the same function | |
177 after finishing transfer. | |
178 (++) No-Blocking mode : The communication is performed using Interrupts | |
179 or DMA. These functions return the status of the transfer startup. | |
180 The end of the data processing will be indicated through the | |
181 dedicated I2S IRQ when using Interrupt mode or the DMA IRQ when | |
182 using DMA mode. | |
183 | |
184 (#) Blocking mode functions are : | |
185 (++) HAL_I2SEx_TransmitReceive() | |
186 | |
187 (#) No-Blocking mode functions with Interrupt are : | |
188 (++) HAL_I2SEx_TransmitReceive_IT() | |
189 (++) HAL_I2SEx_FullDuplex_IRQHandler() | |
190 | |
191 (#) No-Blocking mode functions with DMA are : | |
192 (++) HAL_I2SEx_TransmitReceive_DMA() | |
193 | |
194 (#) A set of Transfer Complete Callback are provided in non Blocking mode: | |
195 (++) HAL_I2SEx_TxRxCpltCallback() | |
196 @endverbatim | |
197 * @{ | |
198 */ | |
199 /** | |
200 * @brief Full-Duplex Transmit/Receive data in blocking mode. | |
201 * @param hi2s pointer to a I2S_HandleTypeDef structure that contains | |
202 * the configuration information for I2S module | |
203 * @param pTxData a 16-bit pointer to the Transmit data buffer. | |
204 * @param pRxData a 16-bit pointer to the Receive data buffer. | |
205 * @param Size number of data sample to be sent: | |
206 * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S | |
207 * configuration phase, the Size parameter means the number of 16-bit data length | |
208 * in the transaction and when a 24-bit data frame or a 32-bit data frame is selected | |
209 * the Size parameter means the number of 16-bit data length. | |
210 * @param Timeout Timeout duration | |
211 * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization | |
212 * between Master and Slave(example: audio streaming). | |
213 * @retval HAL status | |
214 */ | |
215 HAL_StatusTypeDef HAL_I2SEx_TransmitReceive(I2S_HandleTypeDef *hi2s, uint16_t *pTxData, uint16_t *pRxData, | |
216 uint16_t Size, uint32_t Timeout) | |
217 { | |
218 uint32_t tmp1 = 0U; | |
219 | |
220 if((pTxData == NULL ) || (pRxData == NULL ) || (Size == 0U)) | |
221 { | |
222 return HAL_ERROR; | |
223 } | |
224 | |
225 /* Check the I2S State */ | |
226 if(hi2s->State == HAL_I2S_STATE_READY) | |
227 { | |
228 tmp1 = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN); | |
229 /* Check the Data format: When a 16-bit data frame or a 16-bit data frame extended | |
230 is selected during the I2S configuration phase, the Size parameter means the number | |
231 of 16-bit data length in the transaction and when a 24-bit data frame or a 32-bit data | |
232 frame is selected the Size parameter means the number of 16-bit data length. */ | |
233 if((tmp1 == I2S_DATAFORMAT_24B) || (tmp1 == I2S_DATAFORMAT_32B)) | |
234 { | |
235 hi2s->TxXferSize = (Size << 1U); | |
236 hi2s->TxXferCount = (Size << 1U); | |
237 hi2s->RxXferSize = (Size << 1U); | |
238 hi2s->RxXferCount = (Size << 1U); | |
239 } | |
240 else | |
241 { | |
242 hi2s->TxXferSize = Size; | |
243 hi2s->TxXferCount = Size; | |
244 hi2s->RxXferSize = Size; | |
245 hi2s->RxXferCount = Size; | |
246 } | |
247 | |
248 /* Process Locked */ | |
249 __HAL_LOCK(hi2s); | |
250 | |
251 hi2s->ErrorCode = HAL_I2S_ERROR_NONE; | |
252 | |
253 /* Set the I2S State busy TX/RX */ | |
254 hi2s->State = HAL_I2S_STATE_BUSY_TX_RX; | |
255 | |
256 tmp1 = hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG; | |
257 /* Check if the I2S_MODE_MASTER_TX or I2S_MODE_SLAVE_TX Mode is selected */ | |
258 if((tmp1 == I2S_MODE_MASTER_TX) || (tmp1 == I2S_MODE_SLAVE_TX)) | |
259 { | |
260 /* Prepare the First Data before enabling the I2S */ | |
261 hi2s->Instance->DR = (*pTxData++); | |
262 hi2s->TxXferCount--; | |
263 | |
264 /* Enable I2Sext(receiver) before enabling I2Sx peripheral */ | |
265 __HAL_I2SEXT_ENABLE(hi2s); | |
266 | |
267 /* Enable I2Sx peripheral */ | |
268 __HAL_I2S_ENABLE(hi2s); | |
269 | |
270 /* Check if Master Receiver mode is selected */ | |
271 if((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_MASTER_TX) | |
272 { | |
273 /* Clear the Overrun Flag by a read operation on the SPI_DR register followed by a read | |
274 access to the SPI_SR register. */ | |
275 __HAL_I2SEXT_CLEAR_OVRFLAG(hi2s); | |
276 } | |
277 | |
278 while((hi2s->RxXferCount > 0U) || (hi2s->TxXferCount > 0U)) | |
279 { | |
280 if(hi2s->TxXferCount > 0U) | |
281 { | |
282 /* Wait until TXE flag is set */ | |
283 if (I2SEx_FullDuplexWaitFlagStateUntilTimeout(hi2s, I2S_FLAG_TXE, SET, Timeout, I2S_USE_I2S) != HAL_OK) | |
284 { | |
285 /* Set the error code and execute error callback*/ | |
286 SET_BIT(hi2s->ErrorCode, HAL_I2S_ERROR_TIMEOUT); | |
287 HAL_I2S_ErrorCallback(hi2s); | |
288 return HAL_TIMEOUT; | |
289 } | |
290 /* Write Data on DR register */ | |
291 hi2s->Instance->DR = (*pTxData++); | |
292 hi2s->TxXferCount--; | |
293 | |
294 /* Check if an underrun occurs */ | |
295 if((__HAL_I2S_GET_FLAG(hi2s, I2S_FLAG_UDR) == SET) && (tmp1 == I2S_MODE_SLAVE_TX)) | |
296 { | |
297 /* Clear Underrun flag */ | |
298 __HAL_I2S_CLEAR_UDRFLAG(hi2s); | |
299 | |
300 /* Set the I2S State ready */ | |
301 hi2s->State = HAL_I2S_STATE_READY; | |
302 | |
303 /* Process Unlocked */ | |
304 __HAL_UNLOCK(hi2s); | |
305 | |
306 /* Set the error code and execute error callback*/ | |
307 SET_BIT(hi2s->ErrorCode,HAL_I2S_ERROR_UDR); | |
308 HAL_I2S_ErrorCallback(hi2s); | |
309 | |
310 return HAL_ERROR; | |
311 } | |
312 } | |
313 if(hi2s->RxXferCount > 0U) | |
314 { | |
315 /* Wait until RXNE flag is set */ | |
316 if (I2SEx_FullDuplexWaitFlagStateUntilTimeout(hi2s, I2S_FLAG_RXNE, SET, Timeout, I2S_USE_I2SEXT) != HAL_OK) | |
317 { | |
318 /* Set the error code and execute error callback*/ | |
319 SET_BIT(hi2s->ErrorCode,HAL_I2S_ERROR_TIMEOUT); | |
320 HAL_I2S_ErrorCallback(hi2s); | |
321 return HAL_TIMEOUT; | |
322 } | |
323 /* Read Data from DR register */ | |
324 (*pRxData++) = I2SxEXT(hi2s->Instance)->DR; | |
325 hi2s->RxXferCount--; | |
326 | |
327 /* Check if an overrun occurs */ | |
328 if(__HAL_I2SEXT_GET_FLAG(hi2s, I2S_FLAG_OVR) == SET) | |
329 { | |
330 /* Clear Overrun flag */ | |
331 __HAL_I2S_CLEAR_OVRFLAG(hi2s); | |
332 | |
333 /* Set the I2S State ready */ | |
334 hi2s->State = HAL_I2S_STATE_READY; | |
335 | |
336 /* Process Unlocked */ | |
337 __HAL_UNLOCK(hi2s); | |
338 | |
339 /* Set the error code and execute error callback*/ | |
340 SET_BIT(hi2s->ErrorCode,HAL_I2S_ERROR_OVR); | |
341 HAL_I2S_ErrorCallback(hi2s); | |
342 | |
343 return HAL_ERROR; | |
344 } | |
345 } | |
346 } | |
347 } | |
348 /* The I2S_MODE_MASTER_RX or I2S_MODE_SLAVE_RX Mode is selected */ | |
349 else | |
350 { | |
351 /* Prepare the First Data before enabling the I2S */ | |
352 I2SxEXT(hi2s->Instance)->DR = (*pTxData++); | |
353 hi2s->TxXferCount--; | |
354 | |
355 /* Enable I2Sext(transmitter) after enabling I2Sx peripheral */ | |
356 __HAL_I2SEXT_ENABLE(hi2s); | |
357 | |
358 /* Enable I2S peripheral before the I2Sext*/ | |
359 __HAL_I2S_ENABLE(hi2s); | |
360 | |
361 /* Check if Master Receiver mode is selected */ | |
362 if((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_MASTER_RX) | |
363 { | |
364 /* Clear the Overrun Flag by a read operation on the SPI_DR register followed by a read | |
365 access to the SPI_SR register. */ | |
366 __HAL_I2S_CLEAR_OVRFLAG(hi2s); | |
367 } | |
368 | |
369 while((hi2s->RxXferCount > 0U) || (hi2s->TxXferCount > 0U)) | |
370 { | |
371 if(hi2s->TxXferCount > 0U) | |
372 { | |
373 /* Wait until TXE flag is set */ | |
374 if (I2SEx_FullDuplexWaitFlagStateUntilTimeout(hi2s, I2S_FLAG_TXE, SET, Timeout, I2S_USE_I2SEXT) != HAL_OK) | |
375 { | |
376 /* Set the error code and execute error callback*/ | |
377 SET_BIT(hi2s->ErrorCode,HAL_I2S_ERROR_TIMEOUT); | |
378 HAL_I2S_ErrorCallback(hi2s); | |
379 return HAL_TIMEOUT; | |
380 } | |
381 /* Write Data on DR register */ | |
382 I2SxEXT(hi2s->Instance)->DR = (*pTxData++); | |
383 hi2s->TxXferCount--; | |
384 | |
385 /* Check if an underrun occurs */ | |
386 if((__HAL_I2SEXT_GET_FLAG(hi2s, I2S_FLAG_UDR) == SET) && (tmp1 == I2S_MODE_SLAVE_RX)) | |
387 { | |
388 /* Clear Underrun flag */ | |
389 __HAL_I2S_CLEAR_UDRFLAG(hi2s); | |
390 | |
391 /* Set the I2S State ready */ | |
392 hi2s->State = HAL_I2S_STATE_READY; | |
393 | |
394 /* Process Unlocked */ | |
395 __HAL_UNLOCK(hi2s); | |
396 | |
397 /* Set the error code and execute error callback*/ | |
398 SET_BIT(hi2s->ErrorCode,HAL_I2S_ERROR_UDR); | |
399 HAL_I2S_ErrorCallback(hi2s); | |
400 | |
401 return HAL_ERROR; | |
402 } | |
403 } | |
404 if(hi2s->RxXferCount > 0U) | |
405 { | |
406 /* Wait until RXNE flag is set */ | |
407 if (I2SEx_FullDuplexWaitFlagStateUntilTimeout(hi2s, I2S_FLAG_RXNE, SET, Timeout, I2S_USE_I2S) != HAL_OK) | |
408 { | |
409 /* Set the error code and execute error callback*/ | |
410 SET_BIT(hi2s->ErrorCode,HAL_I2S_ERROR_TIMEOUT); | |
411 HAL_I2S_ErrorCallback(hi2s); | |
412 return HAL_TIMEOUT; | |
413 } | |
414 /* Read Data from DR register */ | |
415 (*pRxData++) = hi2s->Instance->DR; | |
416 hi2s->RxXferCount--; | |
417 | |
418 /* Check if an overrun occurs */ | |
419 if(__HAL_I2S_GET_FLAG(hi2s, I2S_FLAG_OVR) == SET) | |
420 { | |
421 /* Clear Overrun flag */ | |
422 __HAL_I2S_CLEAR_OVRFLAG(hi2s); | |
423 | |
424 /* Set the I2S State ready */ | |
425 hi2s->State = HAL_I2S_STATE_READY; | |
426 | |
427 /* Process Unlocked */ | |
428 __HAL_UNLOCK(hi2s); | |
429 | |
430 /* Set the error code and execute error callback*/ | |
431 SET_BIT(hi2s->ErrorCode,HAL_I2S_ERROR_OVR); | |
432 HAL_I2S_ErrorCallback(hi2s); | |
433 | |
434 return HAL_ERROR; | |
435 } | |
436 } | |
437 } | |
438 } | |
439 | |
440 /* Set the I2S State ready */ | |
441 hi2s->State = HAL_I2S_STATE_READY; | |
442 | |
443 /* Process Unlocked */ | |
444 __HAL_UNLOCK(hi2s); | |
445 | |
446 return HAL_OK; | |
447 } | |
448 else | |
449 { | |
450 return HAL_BUSY; | |
451 } | |
452 } | |
453 | |
454 /** | |
455 * @brief Full-Duplex Transmit/Receive data in non-blocking mode using Interrupt | |
456 * @param hi2s pointer to a I2S_HandleTypeDef structure that contains | |
457 * the configuration information for I2S module | |
458 * @param pTxData a 16-bit pointer to the Transmit data buffer. | |
459 * @param pRxData a 16-bit pointer to the Receive data buffer. | |
460 * @param Size number of data sample to be sent: | |
461 * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S | |
462 * configuration phase, the Size parameter means the number of 16-bit data length | |
463 * in the transaction and when a 24-bit data frame or a 32-bit data frame is selected | |
464 * the Size parameter means the number of 16-bit data length. | |
465 * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization | |
466 * between Master and Slave(example: audio streaming). | |
467 * @retval HAL status | |
468 */ | |
469 HAL_StatusTypeDef HAL_I2SEx_TransmitReceive_IT(I2S_HandleTypeDef *hi2s, uint16_t *pTxData, uint16_t *pRxData, | |
470 uint16_t Size) | |
471 { | |
472 uint32_t tmp1 = 0U; | |
473 | |
474 if(hi2s->State == HAL_I2S_STATE_READY) | |
475 { | |
476 if((pTxData == NULL ) || (pRxData == NULL ) || (Size == 0U)) | |
477 { | |
478 return HAL_ERROR; | |
479 } | |
480 | |
481 hi2s->pTxBuffPtr = pTxData; | |
482 hi2s->pRxBuffPtr = pRxData; | |
483 | |
484 tmp1 = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN); | |
485 /* Check the Data format: When a 16-bit data frame or a 16-bit data frame extended | |
486 is selected during the I2S configuration phase, the Size parameter means the number | |
487 of 16-bit data length in the transaction and when a 24-bit data frame or a 32-bit data | |
488 frame is selected the Size parameter means the number of 16-bit data length. */ | |
489 if((tmp1 == I2S_DATAFORMAT_24B) || (tmp1 == I2S_DATAFORMAT_32B)) | |
490 { | |
491 hi2s->TxXferSize = (Size << 1U); | |
492 hi2s->TxXferCount = (Size << 1U); | |
493 hi2s->RxXferSize = (Size << 1U); | |
494 hi2s->RxXferCount = (Size << 1U); | |
495 } | |
496 else | |
497 { | |
498 hi2s->TxXferSize = Size; | |
499 hi2s->TxXferCount = Size; | |
500 hi2s->RxXferSize = Size; | |
501 hi2s->RxXferCount = Size; | |
502 } | |
503 | |
504 /* Process Locked */ | |
505 __HAL_LOCK(hi2s); | |
506 | |
507 hi2s->ErrorCode = HAL_I2S_ERROR_NONE; | |
508 hi2s->State = HAL_I2S_STATE_BUSY_TX_RX; | |
509 | |
510 tmp1 = hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG; | |
511 /* Check if the I2S_MODE_MASTER_TX or I2S_MODE_SLAVE_TX Mode is selected */ | |
512 if((tmp1 == I2S_MODE_MASTER_TX) || (tmp1 == I2S_MODE_SLAVE_TX)) | |
513 { | |
514 /* Enable I2Sext RXNE and ERR interrupts */ | |
515 __HAL_I2SEXT_ENABLE_IT(hi2s, (I2S_IT_RXNE | I2S_IT_ERR)); | |
516 | |
517 /* Enable I2Sx TXE and ERR interrupts */ | |
518 __HAL_I2S_ENABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR)); | |
519 | |
520 /* Check if the I2S is already enabled */ | |
521 if((hi2s->Instance->I2SCFGR &SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE) | |
522 { | |
523 if((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_SLAVE_TX) | |
524 { | |
525 /* Prepare the First Data before enabling the I2S */ | |
526 if(hi2s->TxXferCount != 0U) | |
527 { | |
528 /* Transmit First data */ | |
529 hi2s->Instance->DR = (*hi2s->pTxBuffPtr++); | |
530 hi2s->TxXferCount--; | |
531 | |
532 if(hi2s->TxXferCount == 0U) | |
533 { | |
534 /* Disable TXE and ERR interrupt */ | |
535 __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR)); | |
536 | |
537 if(hi2s->RxXferCount == 0U) | |
538 { | |
539 /* Disable I2Sext RXNE and ERR interrupt */ | |
540 __HAL_I2SEXT_DISABLE_IT(hi2s, (I2S_IT_RXNE| I2S_IT_ERR)); | |
541 | |
542 hi2s->State = HAL_I2S_STATE_READY; | |
543 HAL_I2SEx_TxRxCpltCallback(hi2s); | |
544 } | |
545 } | |
546 } | |
547 } | |
548 /* Enable I2Sext(receiver) before enabling I2Sx peripheral */ | |
549 __HAL_I2SEXT_ENABLE(hi2s); | |
550 | |
551 /* Enable I2Sx peripheral */ | |
552 __HAL_I2S_ENABLE(hi2s); | |
553 } | |
554 } | |
555 /* The I2S_MODE_MASTER_RX or I2S_MODE_SLAVE_RX Mode is selected */ | |
556 else | |
557 { | |
558 /* Enable I2Sext TXE and ERR interrupts */ | |
559 __HAL_I2SEXT_ENABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR)); | |
560 | |
561 /* Enable I2Sext RXNE and ERR interrupts */ | |
562 __HAL_I2S_ENABLE_IT(hi2s, (I2S_IT_RXNE | I2S_IT_ERR)); | |
563 | |
564 /* Check if the I2S is already enabled */ | |
565 if((hi2s->Instance->I2SCFGR &SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE) | |
566 { | |
567 /* Check if the I2S_MODE_MASTER_RX is selected */ | |
568 if((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_MASTER_RX) | |
569 { | |
570 /* Prepare the First Data before enabling the I2S */ | |
571 if(hi2s->TxXferCount != 0U) | |
572 { | |
573 /* Transmit First data */ | |
574 I2SxEXT(hi2s->Instance)->DR = (*hi2s->pTxBuffPtr++); | |
575 hi2s->TxXferCount--; | |
576 | |
577 if(hi2s->TxXferCount == 0U) | |
578 { | |
579 /* Disable I2Sext TXE and ERR interrupt */ | |
580 __HAL_I2SEXT_DISABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR)); | |
581 if(hi2s->RxXferCount == 0U) | |
582 { | |
583 /* Disable RXNE and ERR interrupt */ | |
584 __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_RXNE| I2S_IT_ERR)); | |
585 | |
586 hi2s->State = HAL_I2S_STATE_READY; | |
587 HAL_I2SEx_TxRxCpltCallback(hi2s); | |
588 } | |
589 } | |
590 } | |
591 } | |
592 /* Enable I2Sext(transmitter) after enabling I2Sx peripheral */ | |
593 __HAL_I2SEXT_ENABLE(hi2s); | |
594 | |
595 /* Enable I2S peripheral */ | |
596 __HAL_I2S_ENABLE(hi2s); | |
597 } | |
598 } | |
599 /* Process Unlocked */ | |
600 __HAL_UNLOCK(hi2s); | |
601 | |
602 return HAL_OK; | |
603 } | |
604 else | |
605 { | |
606 return HAL_BUSY; | |
607 } | |
608 } | |
609 | |
610 /** | |
611 * @brief Full-Duplex Transmit/Receive data in non-blocking mode using DMA | |
612 * @param hi2s pointer to a I2S_HandleTypeDef structure that contains | |
613 * the configuration information for I2S module | |
614 * @param pTxData a 16-bit pointer to the Transmit data buffer. | |
615 * @param pRxData a 16-bit pointer to the Receive data buffer. | |
616 * @param Size number of data sample to be sent: | |
617 * @note When a 16-bit data frame or a 16-bit data frame extended is selected during the I2S | |
618 * configuration phase, the Size parameter means the number of 16-bit data length | |
619 * in the transaction and when a 24-bit data frame or a 32-bit data frame is selected | |
620 * the Size parameter means the number of 16-bit data length. | |
621 * @note The I2S is kept enabled at the end of transaction to avoid the clock de-synchronization | |
622 * between Master and Slave(example: audio streaming). | |
623 * @retval HAL status | |
624 */ | |
625 HAL_StatusTypeDef HAL_I2SEx_TransmitReceive_DMA(I2S_HandleTypeDef *hi2s, uint16_t *pTxData, uint16_t *pRxData, | |
626 uint16_t Size) | |
627 { | |
628 uint32_t *tmp = NULL; | |
629 uint32_t tmp1 = 0U; | |
630 | |
631 if((pTxData == NULL ) || (pRxData == NULL ) || (Size == 0U)) | |
632 { | |
633 return HAL_ERROR; | |
634 } | |
635 | |
636 if(hi2s->State == HAL_I2S_STATE_READY) | |
637 { | |
638 hi2s->pTxBuffPtr = pTxData; | |
639 hi2s->pRxBuffPtr = pRxData; | |
640 | |
641 tmp1 = hi2s->Instance->I2SCFGR & (SPI_I2SCFGR_DATLEN | SPI_I2SCFGR_CHLEN); | |
642 /* Check the Data format: When a 16-bit data frame or a 16-bit data frame extended | |
643 is selected during the I2S configuration phase, the Size parameter means the number | |
644 of 16-bit data length in the transaction and when a 24-bit data frame or a 32-bit data | |
645 frame is selected the Size parameter means the number of 16-bit data length. */ | |
646 if((tmp1 == I2S_DATAFORMAT_24B) || (tmp1 == I2S_DATAFORMAT_32B)) | |
647 { | |
648 hi2s->TxXferSize = (Size << 1U); | |
649 hi2s->TxXferCount = (Size << 1U); | |
650 hi2s->RxXferSize = (Size << 1U); | |
651 hi2s->RxXferCount = (Size << 1U); | |
652 } | |
653 else | |
654 { | |
655 hi2s->TxXferSize = Size; | |
656 hi2s->TxXferCount = Size; | |
657 hi2s->RxXferSize = Size; | |
658 hi2s->RxXferCount = Size; | |
659 } | |
660 | |
661 /* Process Locked */ | |
662 __HAL_LOCK(hi2s); | |
663 | |
664 hi2s->ErrorCode = HAL_I2S_ERROR_NONE; | |
665 hi2s->State = HAL_I2S_STATE_BUSY_TX_RX; | |
666 | |
667 /* Set the I2S Rx DMA Half transfer complete callback */ | |
668 hi2s->hdmarx->XferHalfCpltCallback = I2SEx_TxRxDMAHalfCplt; | |
669 | |
670 /* Set the I2S Rx DMA transfer complete callback */ | |
671 hi2s->hdmarx->XferCpltCallback = I2SEx_TxRxDMACplt; | |
672 | |
673 /* Set the I2S Rx DMA error callback */ | |
674 hi2s->hdmarx->XferErrorCallback = I2SEx_TxRxDMAError; | |
675 | |
676 /* Set the I2S Tx DMA Half transfer complete callback */ | |
677 hi2s->hdmatx->XferHalfCpltCallback = I2SEx_TxRxDMAHalfCplt; | |
678 | |
679 /* Set the I2S Tx DMA transfer complete callback */ | |
680 hi2s->hdmatx->XferCpltCallback = I2SEx_TxRxDMACplt; | |
681 | |
682 /* Set the I2S Tx DMA error callback */ | |
683 hi2s->hdmatx->XferErrorCallback = I2SEx_TxRxDMAError; | |
684 | |
685 tmp1 = hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG; | |
686 /* Check if the I2S_MODE_MASTER_TX or I2S_MODE_SLAVE_TX Mode is selected */ | |
687 if((tmp1 == I2S_MODE_MASTER_TX) || (tmp1 == I2S_MODE_SLAVE_TX)) | |
688 { | |
689 /* Enable the Rx DMA Stream */ | |
690 tmp = (uint32_t*)&pRxData; | |
691 HAL_DMA_Start_IT(hi2s->hdmarx, (uint32_t)&I2SxEXT(hi2s->Instance)->DR, *(uint32_t*)tmp, hi2s->RxXferSize); | |
692 | |
693 /* Enable Rx DMA Request */ | |
694 SET_BIT(I2SxEXT(hi2s->Instance)->CR2,SPI_CR2_RXDMAEN); | |
695 | |
696 /* Enable the Tx DMA Stream */ | |
697 tmp = (uint32_t*)&pTxData; | |
698 HAL_DMA_Start_IT(hi2s->hdmatx, *(uint32_t*)tmp, (uint32_t)&hi2s->Instance->DR, hi2s->TxXferSize); | |
699 | |
700 /* Enable Tx DMA Request */ | |
701 SET_BIT(hi2s->Instance->CR2,SPI_CR2_TXDMAEN); | |
702 | |
703 /* Check if the I2S is already enabled */ | |
704 if((hi2s->Instance->I2SCFGR &SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE) | |
705 { | |
706 /* Enable I2Sext(receiver) before enabling I2Sx peripheral */ | |
707 __HAL_I2SEXT_ENABLE(hi2s); | |
708 | |
709 /* Enable I2S peripheral after the I2Sext */ | |
710 __HAL_I2S_ENABLE(hi2s); | |
711 } | |
712 } | |
713 else | |
714 { | |
715 /* Check if Master Receiver mode is selected */ | |
716 if((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_MASTER_RX) | |
717 { | |
718 /* Clear the Overrun Flag by a read operation on the SPI_DR register followed by a read | |
719 access to the SPI_SR register. */ | |
720 __HAL_I2S_CLEAR_OVRFLAG(hi2s); | |
721 } | |
722 /* Enable the Tx DMA Stream */ | |
723 tmp = (uint32_t*)&pTxData; | |
724 HAL_DMA_Start_IT(hi2s->hdmatx, *(uint32_t*)tmp, (uint32_t)&I2SxEXT(hi2s->Instance)->DR, hi2s->TxXferSize); | |
725 | |
726 /* Enable Tx DMA Request */ | |
727 SET_BIT(I2SxEXT(hi2s->Instance)->CR2,SPI_CR2_TXDMAEN); | |
728 | |
729 /* Enable the Rx DMA Stream */ | |
730 tmp = (uint32_t*)&pRxData; | |
731 HAL_DMA_Start_IT(hi2s->hdmarx, (uint32_t)&hi2s->Instance->DR, *(uint32_t*)tmp, hi2s->RxXferSize); | |
732 | |
733 /* Enable Rx DMA Request */ | |
734 SET_BIT(hi2s->Instance->CR2,SPI_CR2_RXDMAEN); | |
735 | |
736 /* Check if the I2S is already enabled */ | |
737 if((hi2s->Instance->I2SCFGR &SPI_I2SCFGR_I2SE) != SPI_I2SCFGR_I2SE) | |
738 { | |
739 /* Enable I2Sext(transmitter) before enabling I2Sx peripheral */ | |
740 __HAL_I2SEXT_ENABLE(hi2s); | |
741 /* Enable I2S peripheral before the I2Sext */ | |
742 __HAL_I2S_ENABLE(hi2s); | |
743 } | |
744 } | |
745 | |
746 /* Process Unlocked */ | |
747 __HAL_UNLOCK(hi2s); | |
748 | |
749 return HAL_OK; | |
750 } | |
751 else | |
752 { | |
753 return HAL_BUSY; | |
754 } | |
755 } | |
756 | |
757 /** | |
758 * @brief This function handles I2S/I2Sext interrupt requests in full-duplex mode. | |
759 * @param hi2s I2S handle | |
760 * @retval HAL status | |
761 */ | |
762 void HAL_I2SEx_FullDuplex_IRQHandler(I2S_HandleTypeDef *hi2s) | |
763 { | |
764 __IO uint32_t i2ssr = hi2s->Instance->SR ; | |
765 __IO uint32_t i2sextsr = I2SxEXT(hi2s->Instance)->SR; | |
766 | |
767 /* Check if the I2S_MODE_MASTER_TX or I2S_MODE_SLAVE_TX Mode is selected */ | |
768 if (((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_MASTER_TX) | |
769 || ((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_SLAVE_TX)) | |
770 { | |
771 /* I2S in mode Transmitter -------------------------------------------------*/ | |
772 if(((i2ssr & I2S_FLAG_TXE) == I2S_FLAG_TXE) && (__HAL_I2S_GET_IT_SOURCE(hi2s, I2S_IT_TXE) != RESET)) | |
773 { | |
774 /* When the I2S mode is configured as I2S_MODE_MASTER_TX or I2S_MODE_SLAVE_TX, | |
775 the I2S TXE interrupt will be generated to manage the full-duplex transmit phase. */ | |
776 I2SEx_FullDuplexTx_IT(hi2s, I2S_USE_I2S); | |
777 } | |
778 | |
779 /* I2Sext in mode Receiver -----------------------------------------------*/ | |
780 if(((i2sextsr & I2S_FLAG_RXNE) == I2S_FLAG_RXNE) && (__HAL_I2SEXT_GET_IT_SOURCE(hi2s, I2S_IT_RXNE) != RESET)) | |
781 { | |
782 /* When the I2S mode is configured as I2S_MODE_MASTER_TX or I2S_MODE_SLAVE_TX, | |
783 the I2Sext RXNE interrupt will be generated to manage the full-duplex receive phase. */ | |
784 I2SEx_FullDuplexRx_IT(hi2s, I2S_USE_I2SEXT); | |
785 } | |
786 | |
787 /* I2Sext Overrun error interrupt occured --------------------------------*/ | |
788 if(((i2sextsr & I2S_FLAG_OVR) == I2S_FLAG_OVR) && (__HAL_I2SEXT_GET_IT_SOURCE(hi2s, I2S_IT_ERR) != RESET)) | |
789 { | |
790 /* Disable RXNE and ERR interrupt */ | |
791 __HAL_I2SEXT_DISABLE_IT(hi2s, (I2S_IT_RXNE | I2S_IT_ERR)); | |
792 | |
793 /* Disable TXE and ERR interrupt */ | |
794 __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR)); | |
795 | |
796 /* Clear Overrun flag */ | |
797 __HAL_I2S_CLEAR_OVRFLAG(hi2s); | |
798 | |
799 /* Set the I2S State ready */ | |
800 hi2s->State = HAL_I2S_STATE_READY; | |
801 | |
802 /* Set the error code and execute error callback*/ | |
803 SET_BIT(hi2s->ErrorCode,HAL_I2S_ERROR_OVR); | |
804 HAL_I2S_ErrorCallback(hi2s); | |
805 } | |
806 | |
807 /* I2S Underrun error interrupt occured ----------------------------------*/ | |
808 if(((i2ssr & I2S_FLAG_UDR) == I2S_FLAG_UDR) && (__HAL_I2S_GET_IT_SOURCE(hi2s, I2S_IT_ERR) != RESET)) | |
809 { | |
810 /* Disable TXE and ERR interrupt */ | |
811 __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR)); | |
812 | |
813 /* Disable RXNE and ERR interrupt */ | |
814 __HAL_I2SEXT_DISABLE_IT(hi2s, (I2S_IT_RXNE | I2S_IT_ERR)); | |
815 | |
816 /* Clear underrun flag */ | |
817 __HAL_I2S_CLEAR_UDRFLAG(hi2s); | |
818 | |
819 /* Set the I2S State ready */ | |
820 hi2s->State = HAL_I2S_STATE_READY; | |
821 | |
822 /* Set the error code and execute error callback*/ | |
823 SET_BIT(hi2s->ErrorCode,HAL_I2S_ERROR_UDR); | |
824 HAL_I2S_ErrorCallback(hi2s); | |
825 } | |
826 } | |
827 /* The I2S_MODE_MASTER_RX or I2S_MODE_SLAVE_RX Mode is selected */ | |
828 else | |
829 { | |
830 /* I2Sext in mode Transmitter ----------------------------------------------*/ | |
831 if(((i2sextsr & I2S_FLAG_TXE) == I2S_FLAG_TXE) && (__HAL_I2SEXT_GET_IT_SOURCE(hi2s, I2S_IT_TXE) != RESET)) | |
832 { | |
833 /* When the I2S mode is configured as I2S_MODE_MASTER_RX or I2S_MODE_SLAVE_RX, | |
834 the I2Sext TXE interrupt will be generated to manage the full-duplex transmit phase. */ | |
835 I2SEx_FullDuplexTx_IT(hi2s, I2S_USE_I2SEXT); | |
836 } | |
837 | |
838 /* I2S in mode Receiver --------------------------------------------------*/ | |
839 if(((i2ssr & I2S_FLAG_RXNE) == I2S_FLAG_RXNE) && (__HAL_I2S_GET_IT_SOURCE(hi2s, I2S_IT_RXNE) != RESET)) | |
840 { | |
841 /* When the I2S mode is configured as I2S_MODE_MASTER_RX or I2S_MODE_SLAVE_RX, | |
842 the I2S RXNE interrupt will be generated to manage the full-duplex receive phase. */ | |
843 I2SEx_FullDuplexRx_IT(hi2s, I2S_USE_I2S); | |
844 } | |
845 | |
846 /* I2S Overrun error interrupt occured -------------------------------------*/ | |
847 if(((i2ssr & I2S_FLAG_OVR) == I2S_FLAG_OVR) && (__HAL_I2S_GET_IT_SOURCE(hi2s, I2S_IT_ERR) != RESET)) | |
848 { | |
849 /* Disable RXNE and ERR interrupt */ | |
850 __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_RXNE | I2S_IT_ERR)); | |
851 | |
852 /* Disable TXE and ERR interrupt */ | |
853 __HAL_I2SEXT_DISABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR)); | |
854 | |
855 /* Set the I2S State ready */ | |
856 hi2s->State = HAL_I2S_STATE_READY; | |
857 | |
858 /* Set the error code and execute error callback*/ | |
859 SET_BIT(hi2s->ErrorCode,HAL_I2S_ERROR_OVR); | |
860 HAL_I2S_ErrorCallback(hi2s); | |
861 } | |
862 | |
863 /* I2Sext Underrun error interrupt occured -------------------------------*/ | |
864 if(((i2sextsr & I2S_FLAG_UDR) == I2S_FLAG_UDR) && (__HAL_I2SEXT_GET_IT_SOURCE(hi2s, I2S_IT_ERR) != RESET)) | |
865 { | |
866 /* Disable TXE and ERR interrupt */ | |
867 __HAL_I2SEXT_DISABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR)); | |
868 | |
869 /* Disable RXNE and ERR interrupt */ | |
870 __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_RXNE | I2S_IT_ERR)); | |
871 | |
872 /* Set the I2S State ready */ | |
873 hi2s->State = HAL_I2S_STATE_READY; | |
874 | |
875 /* Set the error code and execute error callback*/ | |
876 SET_BIT(hi2s->ErrorCode,HAL_I2S_ERROR_UDR); | |
877 HAL_I2S_ErrorCallback(hi2s); | |
878 } | |
879 } | |
880 } | |
881 | |
882 /** | |
883 * @brief Tx and Rx Transfer half completed callback | |
884 * @param hi2s I2S handle | |
885 * @retval None | |
886 */ | |
887 __weak void HAL_I2SEx_TxRxHalfCpltCallback(I2S_HandleTypeDef *hi2s) | |
888 { | |
889 /* Prevent unused argument(s) compilation warning */ | |
890 UNUSED(hi2s); | |
891 | |
892 /* NOTE : This function Should not be modified, when the callback is needed, | |
893 the HAL_I2SEx_TxRxHalfCpltCallback could be implemented in the user file | |
894 */ | |
895 } | |
896 | |
897 /** | |
898 * @brief Tx and Rx Transfer completed callback | |
899 * @param hi2s I2S handle | |
900 * @retval None | |
901 */ | |
902 __weak void HAL_I2SEx_TxRxCpltCallback(I2S_HandleTypeDef *hi2s) | |
903 { | |
904 /* Prevent unused argument(s) compilation warning */ | |
905 UNUSED(hi2s); | |
906 | |
907 /* NOTE : This function Should not be modified, when the callback is needed, | |
908 the HAL_I2SEx_TxRxCpltCallback could be implemented in the user file | |
909 */ | |
910 } | |
911 | |
912 /** | |
913 * @} | |
914 */ | |
915 | |
916 /** | |
917 * @} | |
918 */ | |
919 | |
920 /** @addtogroup I2SEx_Private_Functions I2S Extended Private Functions | |
921 * @{ | |
922 */ | |
923 | |
924 /** | |
925 * @brief DMA I2S transmit receive process half complete callback | |
926 * @param hdma pointer to a DMA_HandleTypeDef structure that contains | |
927 * the configuration information for the specified DMA module. | |
928 * @retval None | |
929 */ | |
930 static void I2SEx_TxRxDMAHalfCplt(DMA_HandleTypeDef *hdma) | |
931 { | |
932 I2S_HandleTypeDef* hi2s = (I2S_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent; | |
933 | |
934 HAL_I2SEx_TxRxHalfCpltCallback(hi2s); | |
935 } | |
936 | |
937 /** | |
938 * @brief DMA I2S transmit receive process complete callback | |
939 * @param hdma pointer to a DMA_HandleTypeDef structure that contains | |
940 * the configuration information for the specified DMA module. | |
941 * @retval None | |
942 */ | |
943 static void I2SEx_TxRxDMACplt(DMA_HandleTypeDef *hdma) | |
944 { | |
945 I2S_HandleTypeDef* hi2s = (I2S_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent; | |
946 | |
947 /* if DMA is not configured in DMA_CIRCULAR mode */ | |
948 if((hdma->Instance->CR & DMA_SxCR_CIRC) == 0U) | |
949 { | |
950 if (hi2s->hdmarx == hdma) | |
951 { | |
952 /* Disable Rx DMA Request */ | |
953 if (((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_MASTER_TX) ||\ | |
954 ((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_SLAVE_TX)) | |
955 { | |
956 CLEAR_BIT(I2SxEXT(hi2s->Instance)->CR2,SPI_CR2_RXDMAEN); | |
957 } | |
958 else | |
959 { | |
960 CLEAR_BIT(hi2s->Instance->CR2,SPI_CR2_RXDMAEN); | |
961 } | |
962 | |
963 hi2s->RxXferCount = 0U; | |
964 | |
965 if (hi2s->TxXferCount == 0U) | |
966 { | |
967 hi2s->State = HAL_I2S_STATE_READY; | |
968 | |
969 HAL_I2SEx_TxRxCpltCallback(hi2s); | |
970 } | |
971 } | |
972 | |
973 if (hi2s->hdmatx == hdma) | |
974 { | |
975 /* Disable Tx DMA Request */ | |
976 if (((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_MASTER_TX) ||\ | |
977 ((hi2s->Instance->I2SCFGR & SPI_I2SCFGR_I2SCFG) == I2S_MODE_SLAVE_TX)) | |
978 { | |
979 CLEAR_BIT(hi2s->Instance->CR2,SPI_CR2_TXDMAEN); | |
980 } | |
981 else | |
982 { | |
983 CLEAR_BIT(I2SxEXT(hi2s->Instance)->CR2,SPI_CR2_TXDMAEN); | |
984 } | |
985 | |
986 hi2s->TxXferCount = 0U; | |
987 | |
988 if (hi2s->RxXferCount == 0U) | |
989 { | |
990 hi2s->State = HAL_I2S_STATE_READY; | |
991 | |
992 HAL_I2SEx_TxRxCpltCallback(hi2s); | |
993 } | |
994 } | |
995 } | |
996 } | |
997 | |
998 /** | |
999 * @brief DMA I2S communication error callback | |
1000 * @param hdma DMA handle | |
1001 * @retval None | |
1002 */ | |
1003 static void I2SEx_TxRxDMAError(DMA_HandleTypeDef *hdma) | |
1004 { | |
1005 I2S_HandleTypeDef* hi2s = ( I2S_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent; | |
1006 | |
1007 /* Disable Rx and Tx DMA Request */ | |
1008 CLEAR_BIT(hi2s->Instance->CR2,(SPI_CR2_RXDMAEN | SPI_CR2_TXDMAEN)); | |
1009 CLEAR_BIT(I2SxEXT(hi2s->Instance)->CR2,(SPI_CR2_RXDMAEN | SPI_CR2_TXDMAEN)); | |
1010 | |
1011 hi2s->TxXferCount = 0U; | |
1012 hi2s->RxXferCount = 0U; | |
1013 | |
1014 hi2s->State= HAL_I2S_STATE_READY; | |
1015 | |
1016 /* Set the error code and execute error callback*/ | |
1017 SET_BIT(hi2s->ErrorCode,HAL_I2S_ERROR_DMA); | |
1018 HAL_I2S_ErrorCallback(hi2s); | |
1019 } | |
1020 | |
1021 /** | |
1022 * @brief Full-Duplex IT handler transmit function | |
1023 * @param hi2s I2S handle | |
1024 * @param i2sUsed indicate if I2Sx or I2Sx_ext is concerned | |
1025 * @retval None | |
1026 */ | |
1027 static void I2SEx_FullDuplexTx_IT(I2S_HandleTypeDef *hi2s, I2S_UseTypeDef i2sUsed) | |
1028 { | |
1029 if(i2sUsed == I2S_USE_I2S) | |
1030 { | |
1031 /* Write Data on DR register */ | |
1032 hi2s->Instance->DR = (*hi2s->pTxBuffPtr++); | |
1033 hi2s->TxXferCount--; | |
1034 | |
1035 if(hi2s->TxXferCount == 0U) | |
1036 { | |
1037 /* Disable TXE and ERR interrupt */ | |
1038 __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR)); | |
1039 | |
1040 if(hi2s->RxXferCount == 0U) | |
1041 { | |
1042 hi2s->State = HAL_I2S_STATE_READY; | |
1043 HAL_I2SEx_TxRxCpltCallback(hi2s); | |
1044 } | |
1045 } | |
1046 } | |
1047 else | |
1048 { | |
1049 /* Write Data on DR register */ | |
1050 I2SxEXT(hi2s->Instance)->DR = (*hi2s->pTxBuffPtr++); | |
1051 hi2s->TxXferCount--; | |
1052 | |
1053 if(hi2s->TxXferCount == 0U) | |
1054 { | |
1055 /* Disable I2Sext TXE and ERR interrupt */ | |
1056 __HAL_I2SEXT_DISABLE_IT(hi2s, (I2S_IT_TXE | I2S_IT_ERR)); | |
1057 | |
1058 if(hi2s->RxXferCount == 0U) | |
1059 { | |
1060 hi2s->State = HAL_I2S_STATE_READY; | |
1061 HAL_I2SEx_TxRxCpltCallback(hi2s); | |
1062 } | |
1063 } | |
1064 } | |
1065 } | |
1066 | |
1067 /** | |
1068 * @brief Full-Duplex IT handler receive function | |
1069 * @param hi2s I2S handle | |
1070 * @param i2sUsed indicate if I2Sx or I2Sx_ext is concerned | |
1071 * @retval None | |
1072 */ | |
1073 static void I2SEx_FullDuplexRx_IT(I2S_HandleTypeDef *hi2s, I2S_UseTypeDef i2sUsed) | |
1074 { | |
1075 if(i2sUsed == I2S_USE_I2S) | |
1076 { | |
1077 /* Read Data from DR register */ | |
1078 (*hi2s->pRxBuffPtr++) = hi2s->Instance->DR; | |
1079 hi2s->RxXferCount--; | |
1080 | |
1081 if(hi2s->RxXferCount == 0U) | |
1082 { | |
1083 /* Disable RXNE and ERR interrupt */ | |
1084 __HAL_I2S_DISABLE_IT(hi2s, (I2S_IT_RXNE | I2S_IT_ERR)); | |
1085 | |
1086 if(hi2s->TxXferCount == 0U) | |
1087 { | |
1088 hi2s->State = HAL_I2S_STATE_READY; | |
1089 HAL_I2SEx_TxRxCpltCallback(hi2s); | |
1090 } | |
1091 } | |
1092 } | |
1093 else | |
1094 { | |
1095 /* Read Data from DR register */ | |
1096 (*hi2s->pRxBuffPtr++) = I2SxEXT(hi2s->Instance)->DR; | |
1097 hi2s->RxXferCount--; | |
1098 | |
1099 if(hi2s->RxXferCount == 0U) | |
1100 { | |
1101 /* Disable I2Sext RXNE and ERR interrupt */ | |
1102 __HAL_I2SEXT_DISABLE_IT(hi2s, (I2S_IT_RXNE | I2S_IT_ERR)); | |
1103 | |
1104 if(hi2s->TxXferCount == 0U) | |
1105 { | |
1106 hi2s->State = HAL_I2S_STATE_READY; | |
1107 HAL_I2SEx_TxRxCpltCallback(hi2s); | |
1108 } | |
1109 } | |
1110 } | |
1111 } | |
1112 | |
1113 /** | |
1114 * @brief This function handles I2S Communication Timeout. | |
1115 * @param hi2s I2S handle | |
1116 * @param Flag Flag checked | |
1117 * @param State Value of the flag expected | |
1118 * @param Timeout Duration of the timeout | |
1119 * @param i2sUsed I2S instance reference | |
1120 * @retval HAL status | |
1121 */ | |
1122 static HAL_StatusTypeDef I2SEx_FullDuplexWaitFlagStateUntilTimeout(I2S_HandleTypeDef *hi2s, uint32_t Flag, | |
1123 uint32_t State, uint32_t Timeout, I2S_UseTypeDef i2sUsed) | |
1124 { | |
1125 uint32_t tickstart = HAL_GetTick(); | |
1126 | |
1127 if(i2sUsed == I2S_USE_I2S) | |
1128 { | |
1129 /* Wait until flag is reset */ | |
1130 while(((__HAL_I2S_GET_FLAG(hi2s, Flag)) ? SET : RESET) != State) | |
1131 { | |
1132 if(Timeout != HAL_MAX_DELAY) | |
1133 { | |
1134 if((Timeout == 0U) || ((HAL_GetTick()-tickstart) > Timeout)) | |
1135 { | |
1136 /* Set the I2S State ready */ | |
1137 hi2s->State= HAL_I2S_STATE_READY; | |
1138 | |
1139 /* Process Unlocked */ | |
1140 __HAL_UNLOCK(hi2s); | |
1141 | |
1142 return HAL_TIMEOUT; | |
1143 } | |
1144 } | |
1145 } | |
1146 } | |
1147 else /* i2sUsed == I2S_USE_I2SEXT */ | |
1148 { | |
1149 /* Wait until flag is reset */ | |
1150 while(((__HAL_I2SEXT_GET_FLAG(hi2s, Flag)) ? SET : RESET) != State) | |
1151 { | |
1152 if(Timeout != HAL_MAX_DELAY) | |
1153 { | |
1154 if((Timeout == 0U) || ((HAL_GetTick()-tickstart) > Timeout)) | |
1155 { | |
1156 /* Set the I2S State ready */ | |
1157 hi2s->State= HAL_I2S_STATE_READY; | |
1158 | |
1159 /* Process Unlocked */ | |
1160 __HAL_UNLOCK(hi2s); | |
1161 | |
1162 return HAL_TIMEOUT; | |
1163 } | |
1164 } | |
1165 } | |
1166 } | |
1167 return HAL_OK; | |
1168 } | |
1169 | |
1170 /** | |
1171 * @} | |
1172 */ | |
1173 #endif /* SPI_I2S_FULLDUPLEX_SUPPORT */ | |
1174 | |
1175 /** | |
1176 * @} | |
1177 */ | |
1178 #endif /* HAL_I2S_MODULE_ENABLED */ | |
1179 | |
1180 /** | |
1181 * @} | |
1182 */ | |
1183 | |
1184 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ |