1 | /**
|
---|
2 | ******************************************************************************
|
---|
3 | * @file stm32f4xx_ll_spi.c
|
---|
4 | * @author MCD Application Team
|
---|
5 | * @brief SPI LL module driver.
|
---|
6 | ******************************************************************************
|
---|
7 | * @attention
|
---|
8 | *
|
---|
9 | * <h2><center>© Copyright (c) 2016 STMicroelectronics.
|
---|
10 | * All rights reserved.</center></h2>
|
---|
11 | *
|
---|
12 | * This software component is licensed by ST under BSD 3-Clause license,
|
---|
13 | * the "License"; You may not use this file except in compliance with the
|
---|
14 | * License. You may obtain a copy of the License at:
|
---|
15 | * opensource.org/licenses/BSD-3-Clause
|
---|
16 | *
|
---|
17 | ******************************************************************************
|
---|
18 | */
|
---|
19 | #if defined(USE_FULL_LL_DRIVER)
|
---|
20 |
|
---|
21 | /* Includes ------------------------------------------------------------------*/
|
---|
22 | #include "stm32f4xx_ll_spi.h"
|
---|
23 | #include "stm32f4xx_ll_bus.h"
|
---|
24 | #include "stm32f4xx_ll_rcc.h"
|
---|
25 |
|
---|
26 | #ifdef USE_FULL_ASSERT
|
---|
27 | #include "stm32_assert.h"
|
---|
28 | #else
|
---|
29 | #define assert_param(expr) ((void)0U)
|
---|
30 | #endif
|
---|
31 |
|
---|
32 | /** @addtogroup STM32F4xx_LL_Driver
|
---|
33 | * @{
|
---|
34 | */
|
---|
35 |
|
---|
36 | #if defined (SPI1) || defined (SPI2) || defined (SPI3) || defined (SPI4) || defined (SPI5) || defined(SPI6)
|
---|
37 |
|
---|
38 | /** @addtogroup SPI_LL
|
---|
39 | * @{
|
---|
40 | */
|
---|
41 |
|
---|
42 | /* Private types -------------------------------------------------------------*/
|
---|
43 | /* Private variables ---------------------------------------------------------*/
|
---|
44 |
|
---|
45 | /* Private constants ---------------------------------------------------------*/
|
---|
46 | /** @defgroup SPI_LL_Private_Constants SPI Private Constants
|
---|
47 | * @{
|
---|
48 | */
|
---|
49 | /* SPI registers Masks */
|
---|
50 | #define SPI_CR1_CLEAR_MASK (SPI_CR1_CPHA | SPI_CR1_CPOL | SPI_CR1_MSTR | \
|
---|
51 | SPI_CR1_BR | SPI_CR1_LSBFIRST | SPI_CR1_SSI | \
|
---|
52 | SPI_CR1_SSM | SPI_CR1_RXONLY | SPI_CR1_DFF | \
|
---|
53 | SPI_CR1_CRCNEXT | SPI_CR1_CRCEN | SPI_CR1_BIDIOE | \
|
---|
54 | SPI_CR1_BIDIMODE)
|
---|
55 | /**
|
---|
56 | * @}
|
---|
57 | */
|
---|
58 |
|
---|
59 | /* Private macros ------------------------------------------------------------*/
|
---|
60 | /** @defgroup SPI_LL_Private_Macros SPI Private Macros
|
---|
61 | * @{
|
---|
62 | */
|
---|
63 | #define IS_LL_SPI_TRANSFER_DIRECTION(__VALUE__) (((__VALUE__) == LL_SPI_FULL_DUPLEX) \
|
---|
64 | || ((__VALUE__) == LL_SPI_SIMPLEX_RX) \
|
---|
65 | || ((__VALUE__) == LL_SPI_HALF_DUPLEX_RX) \
|
---|
66 | || ((__VALUE__) == LL_SPI_HALF_DUPLEX_TX))
|
---|
67 |
|
---|
68 | #define IS_LL_SPI_MODE(__VALUE__) (((__VALUE__) == LL_SPI_MODE_MASTER) \
|
---|
69 | || ((__VALUE__) == LL_SPI_MODE_SLAVE))
|
---|
70 |
|
---|
71 | #define IS_LL_SPI_DATAWIDTH(__VALUE__) (((__VALUE__) == LL_SPI_DATAWIDTH_8BIT) \
|
---|
72 | || ((__VALUE__) == LL_SPI_DATAWIDTH_16BIT))
|
---|
73 |
|
---|
74 | #define IS_LL_SPI_POLARITY(__VALUE__) (((__VALUE__) == LL_SPI_POLARITY_LOW) \
|
---|
75 | || ((__VALUE__) == LL_SPI_POLARITY_HIGH))
|
---|
76 |
|
---|
77 | #define IS_LL_SPI_PHASE(__VALUE__) (((__VALUE__) == LL_SPI_PHASE_1EDGE) \
|
---|
78 | || ((__VALUE__) == LL_SPI_PHASE_2EDGE))
|
---|
79 |
|
---|
80 | #define IS_LL_SPI_NSS(__VALUE__) (((__VALUE__) == LL_SPI_NSS_SOFT) \
|
---|
81 | || ((__VALUE__) == LL_SPI_NSS_HARD_INPUT) \
|
---|
82 | || ((__VALUE__) == LL_SPI_NSS_HARD_OUTPUT))
|
---|
83 |
|
---|
84 | #define IS_LL_SPI_BAUDRATE(__VALUE__) (((__VALUE__) == LL_SPI_BAUDRATEPRESCALER_DIV2) \
|
---|
85 | || ((__VALUE__) == LL_SPI_BAUDRATEPRESCALER_DIV4) \
|
---|
86 | || ((__VALUE__) == LL_SPI_BAUDRATEPRESCALER_DIV8) \
|
---|
87 | || ((__VALUE__) == LL_SPI_BAUDRATEPRESCALER_DIV16) \
|
---|
88 | || ((__VALUE__) == LL_SPI_BAUDRATEPRESCALER_DIV32) \
|
---|
89 | || ((__VALUE__) == LL_SPI_BAUDRATEPRESCALER_DIV64) \
|
---|
90 | || ((__VALUE__) == LL_SPI_BAUDRATEPRESCALER_DIV128) \
|
---|
91 | || ((__VALUE__) == LL_SPI_BAUDRATEPRESCALER_DIV256))
|
---|
92 |
|
---|
93 | #define IS_LL_SPI_BITORDER(__VALUE__) (((__VALUE__) == LL_SPI_LSB_FIRST) \
|
---|
94 | || ((__VALUE__) == LL_SPI_MSB_FIRST))
|
---|
95 |
|
---|
96 | #define IS_LL_SPI_CRCCALCULATION(__VALUE__) (((__VALUE__) == LL_SPI_CRCCALCULATION_ENABLE) \
|
---|
97 | || ((__VALUE__) == LL_SPI_CRCCALCULATION_DISABLE))
|
---|
98 |
|
---|
99 | #define IS_LL_SPI_CRC_POLYNOMIAL(__VALUE__) ((__VALUE__) >= 0x1U)
|
---|
100 |
|
---|
101 | /**
|
---|
102 | * @}
|
---|
103 | */
|
---|
104 |
|
---|
105 | /* Private function prototypes -----------------------------------------------*/
|
---|
106 |
|
---|
107 | /* Exported functions --------------------------------------------------------*/
|
---|
108 | /** @addtogroup SPI_LL_Exported_Functions
|
---|
109 | * @{
|
---|
110 | */
|
---|
111 |
|
---|
112 | /** @addtogroup SPI_LL_EF_Init
|
---|
113 | * @{
|
---|
114 | */
|
---|
115 |
|
---|
116 | /**
|
---|
117 | * @brief De-initialize the SPI registers to their default reset values.
|
---|
118 | * @param SPIx SPI Instance
|
---|
119 | * @retval An ErrorStatus enumeration value:
|
---|
120 | * - SUCCESS: SPI registers are de-initialized
|
---|
121 | * - ERROR: SPI registers are not de-initialized
|
---|
122 | */
|
---|
123 | ErrorStatus LL_SPI_DeInit(SPI_TypeDef *SPIx)
|
---|
124 | {
|
---|
125 | ErrorStatus status = ERROR;
|
---|
126 |
|
---|
127 | /* Check the parameters */
|
---|
128 | assert_param(IS_SPI_ALL_INSTANCE(SPIx));
|
---|
129 |
|
---|
130 | #if defined(SPI1)
|
---|
131 | if (SPIx == SPI1)
|
---|
132 | {
|
---|
133 | /* Force reset of SPI clock */
|
---|
134 | LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_SPI1);
|
---|
135 |
|
---|
136 | /* Release reset of SPI clock */
|
---|
137 | LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_SPI1);
|
---|
138 |
|
---|
139 | status = SUCCESS;
|
---|
140 | }
|
---|
141 | #endif /* SPI1 */
|
---|
142 | #if defined(SPI2)
|
---|
143 | if (SPIx == SPI2)
|
---|
144 | {
|
---|
145 | /* Force reset of SPI clock */
|
---|
146 | LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_SPI2);
|
---|
147 |
|
---|
148 | /* Release reset of SPI clock */
|
---|
149 | LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_SPI2);
|
---|
150 |
|
---|
151 | status = SUCCESS;
|
---|
152 | }
|
---|
153 | #endif /* SPI2 */
|
---|
154 | #if defined(SPI3)
|
---|
155 | if (SPIx == SPI3)
|
---|
156 | {
|
---|
157 | /* Force reset of SPI clock */
|
---|
158 | LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_SPI3);
|
---|
159 |
|
---|
160 | /* Release reset of SPI clock */
|
---|
161 | LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_SPI3);
|
---|
162 |
|
---|
163 | status = SUCCESS;
|
---|
164 | }
|
---|
165 | #endif /* SPI3 */
|
---|
166 | #if defined(SPI4)
|
---|
167 | if (SPIx == SPI4)
|
---|
168 | {
|
---|
169 | /* Force reset of SPI clock */
|
---|
170 | LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_SPI4);
|
---|
171 |
|
---|
172 | /* Release reset of SPI clock */
|
---|
173 | LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_SPI4);
|
---|
174 |
|
---|
175 | status = SUCCESS;
|
---|
176 | }
|
---|
177 | #endif /* SPI4 */
|
---|
178 | #if defined(SPI5)
|
---|
179 | if (SPIx == SPI5)
|
---|
180 | {
|
---|
181 | /* Force reset of SPI clock */
|
---|
182 | LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_SPI5);
|
---|
183 |
|
---|
184 | /* Release reset of SPI clock */
|
---|
185 | LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_SPI5);
|
---|
186 |
|
---|
187 | status = SUCCESS;
|
---|
188 | }
|
---|
189 | #endif /* SPI5 */
|
---|
190 | #if defined(SPI6)
|
---|
191 | if (SPIx == SPI6)
|
---|
192 | {
|
---|
193 | /* Force reset of SPI clock */
|
---|
194 | LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_SPI6);
|
---|
195 |
|
---|
196 | /* Release reset of SPI clock */
|
---|
197 | LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_SPI6);
|
---|
198 |
|
---|
199 | status = SUCCESS;
|
---|
200 | }
|
---|
201 | #endif /* SPI6 */
|
---|
202 |
|
---|
203 | return status;
|
---|
204 | }
|
---|
205 |
|
---|
206 | /**
|
---|
207 | * @brief Initialize the SPI registers according to the specified parameters in SPI_InitStruct.
|
---|
208 | * @note As some bits in SPI configuration registers can only be written when the SPI is disabled (SPI_CR1_SPE bit =0),
|
---|
209 | * SPI peripheral should be in disabled state prior calling this function. Otherwise, ERROR result will be returned.
|
---|
210 | * @param SPIx SPI Instance
|
---|
211 | * @param SPI_InitStruct pointer to a @ref LL_SPI_InitTypeDef structure
|
---|
212 | * @retval An ErrorStatus enumeration value. (Return always SUCCESS)
|
---|
213 | */
|
---|
214 | ErrorStatus LL_SPI_Init(SPI_TypeDef *SPIx, LL_SPI_InitTypeDef *SPI_InitStruct)
|
---|
215 | {
|
---|
216 | ErrorStatus status = ERROR;
|
---|
217 |
|
---|
218 | /* Check the SPI Instance SPIx*/
|
---|
219 | assert_param(IS_SPI_ALL_INSTANCE(SPIx));
|
---|
220 |
|
---|
221 | /* Check the SPI parameters from SPI_InitStruct*/
|
---|
222 | assert_param(IS_LL_SPI_TRANSFER_DIRECTION(SPI_InitStruct->TransferDirection));
|
---|
223 | assert_param(IS_LL_SPI_MODE(SPI_InitStruct->Mode));
|
---|
224 | assert_param(IS_LL_SPI_DATAWIDTH(SPI_InitStruct->DataWidth));
|
---|
225 | assert_param(IS_LL_SPI_POLARITY(SPI_InitStruct->ClockPolarity));
|
---|
226 | assert_param(IS_LL_SPI_PHASE(SPI_InitStruct->ClockPhase));
|
---|
227 | assert_param(IS_LL_SPI_NSS(SPI_InitStruct->NSS));
|
---|
228 | assert_param(IS_LL_SPI_BAUDRATE(SPI_InitStruct->BaudRate));
|
---|
229 | assert_param(IS_LL_SPI_BITORDER(SPI_InitStruct->BitOrder));
|
---|
230 | assert_param(IS_LL_SPI_CRCCALCULATION(SPI_InitStruct->CRCCalculation));
|
---|
231 |
|
---|
232 | if (LL_SPI_IsEnabled(SPIx) == 0x00000000U)
|
---|
233 | {
|
---|
234 | /*---------------------------- SPIx CR1 Configuration ------------------------
|
---|
235 | * Configure SPIx CR1 with parameters:
|
---|
236 | * - TransferDirection: SPI_CR1_BIDIMODE, SPI_CR1_BIDIOE and SPI_CR1_RXONLY bits
|
---|
237 | * - Master/Slave Mode: SPI_CR1_MSTR bit
|
---|
238 | * - DataWidth: SPI_CR1_DFF bit
|
---|
239 | * - ClockPolarity: SPI_CR1_CPOL bit
|
---|
240 | * - ClockPhase: SPI_CR1_CPHA bit
|
---|
241 | * - NSS management: SPI_CR1_SSM bit
|
---|
242 | * - BaudRate prescaler: SPI_CR1_BR[2:0] bits
|
---|
243 | * - BitOrder: SPI_CR1_LSBFIRST bit
|
---|
244 | * - CRCCalculation: SPI_CR1_CRCEN bit
|
---|
245 | */
|
---|
246 | MODIFY_REG(SPIx->CR1,
|
---|
247 | SPI_CR1_CLEAR_MASK,
|
---|
248 | SPI_InitStruct->TransferDirection | SPI_InitStruct->Mode | SPI_InitStruct->DataWidth |
|
---|
249 | SPI_InitStruct->ClockPolarity | SPI_InitStruct->ClockPhase |
|
---|
250 | SPI_InitStruct->NSS | SPI_InitStruct->BaudRate |
|
---|
251 | SPI_InitStruct->BitOrder | SPI_InitStruct->CRCCalculation);
|
---|
252 |
|
---|
253 | /*---------------------------- SPIx CR2 Configuration ------------------------
|
---|
254 | * Configure SPIx CR2 with parameters:
|
---|
255 | * - NSS management: SSOE bit
|
---|
256 | */
|
---|
257 | MODIFY_REG(SPIx->CR2, SPI_CR2_SSOE, (SPI_InitStruct->NSS >> 16U));
|
---|
258 |
|
---|
259 | /*---------------------------- SPIx CRCPR Configuration ----------------------
|
---|
260 | * Configure SPIx CRCPR with parameters:
|
---|
261 | * - CRCPoly: CRCPOLY[15:0] bits
|
---|
262 | */
|
---|
263 | if (SPI_InitStruct->CRCCalculation == LL_SPI_CRCCALCULATION_ENABLE)
|
---|
264 | {
|
---|
265 | assert_param(IS_LL_SPI_CRC_POLYNOMIAL(SPI_InitStruct->CRCPoly));
|
---|
266 | LL_SPI_SetCRCPolynomial(SPIx, SPI_InitStruct->CRCPoly);
|
---|
267 | }
|
---|
268 | status = SUCCESS;
|
---|
269 | }
|
---|
270 |
|
---|
271 | /* Activate the SPI mode (Reset I2SMOD bit in I2SCFGR register) */
|
---|
272 | CLEAR_BIT(SPIx->I2SCFGR, SPI_I2SCFGR_I2SMOD);
|
---|
273 | return status;
|
---|
274 | }
|
---|
275 |
|
---|
276 | /**
|
---|
277 | * @brief Set each @ref LL_SPI_InitTypeDef field to default value.
|
---|
278 | * @param SPI_InitStruct pointer to a @ref LL_SPI_InitTypeDef structure
|
---|
279 | * whose fields will be set to default values.
|
---|
280 | * @retval None
|
---|
281 | */
|
---|
282 | void LL_SPI_StructInit(LL_SPI_InitTypeDef *SPI_InitStruct)
|
---|
283 | {
|
---|
284 | /* Set SPI_InitStruct fields to default values */
|
---|
285 | SPI_InitStruct->TransferDirection = LL_SPI_FULL_DUPLEX;
|
---|
286 | SPI_InitStruct->Mode = LL_SPI_MODE_SLAVE;
|
---|
287 | SPI_InitStruct->DataWidth = LL_SPI_DATAWIDTH_8BIT;
|
---|
288 | SPI_InitStruct->ClockPolarity = LL_SPI_POLARITY_LOW;
|
---|
289 | SPI_InitStruct->ClockPhase = LL_SPI_PHASE_1EDGE;
|
---|
290 | SPI_InitStruct->NSS = LL_SPI_NSS_HARD_INPUT;
|
---|
291 | SPI_InitStruct->BaudRate = LL_SPI_BAUDRATEPRESCALER_DIV2;
|
---|
292 | SPI_InitStruct->BitOrder = LL_SPI_MSB_FIRST;
|
---|
293 | SPI_InitStruct->CRCCalculation = LL_SPI_CRCCALCULATION_DISABLE;
|
---|
294 | SPI_InitStruct->CRCPoly = 7U;
|
---|
295 | }
|
---|
296 |
|
---|
297 | /**
|
---|
298 | * @}
|
---|
299 | */
|
---|
300 |
|
---|
301 | /**
|
---|
302 | * @}
|
---|
303 | */
|
---|
304 |
|
---|
305 | /**
|
---|
306 | * @}
|
---|
307 | */
|
---|
308 |
|
---|
309 | /** @addtogroup I2S_LL
|
---|
310 | * @{
|
---|
311 | */
|
---|
312 |
|
---|
313 | /* Private types -------------------------------------------------------------*/
|
---|
314 | /* Private variables ---------------------------------------------------------*/
|
---|
315 | /* Private constants ---------------------------------------------------------*/
|
---|
316 | /** @defgroup I2S_LL_Private_Constants I2S Private Constants
|
---|
317 | * @{
|
---|
318 | */
|
---|
319 | /* I2S registers Masks */
|
---|
320 | #define I2S_I2SCFGR_CLEAR_MASK (SPI_I2SCFGR_CHLEN | SPI_I2SCFGR_DATLEN | \
|
---|
321 | SPI_I2SCFGR_CKPOL | SPI_I2SCFGR_I2SSTD | \
|
---|
322 | SPI_I2SCFGR_I2SCFG | SPI_I2SCFGR_I2SMOD )
|
---|
323 |
|
---|
324 | #define I2S_I2SPR_CLEAR_MASK 0x0002U
|
---|
325 | /**
|
---|
326 | * @}
|
---|
327 | */
|
---|
328 | /* Private macros ------------------------------------------------------------*/
|
---|
329 | /** @defgroup I2S_LL_Private_Macros I2S Private Macros
|
---|
330 | * @{
|
---|
331 | */
|
---|
332 |
|
---|
333 | #define IS_LL_I2S_DATAFORMAT(__VALUE__) (((__VALUE__) == LL_I2S_DATAFORMAT_16B) \
|
---|
334 | || ((__VALUE__) == LL_I2S_DATAFORMAT_16B_EXTENDED) \
|
---|
335 | || ((__VALUE__) == LL_I2S_DATAFORMAT_24B) \
|
---|
336 | || ((__VALUE__) == LL_I2S_DATAFORMAT_32B))
|
---|
337 |
|
---|
338 | #define IS_LL_I2S_CPOL(__VALUE__) (((__VALUE__) == LL_I2S_POLARITY_LOW) \
|
---|
339 | || ((__VALUE__) == LL_I2S_POLARITY_HIGH))
|
---|
340 |
|
---|
341 | #define IS_LL_I2S_STANDARD(__VALUE__) (((__VALUE__) == LL_I2S_STANDARD_PHILIPS) \
|
---|
342 | || ((__VALUE__) == LL_I2S_STANDARD_MSB) \
|
---|
343 | || ((__VALUE__) == LL_I2S_STANDARD_LSB) \
|
---|
344 | || ((__VALUE__) == LL_I2S_STANDARD_PCM_SHORT) \
|
---|
345 | || ((__VALUE__) == LL_I2S_STANDARD_PCM_LONG))
|
---|
346 |
|
---|
347 | #define IS_LL_I2S_MODE(__VALUE__) (((__VALUE__) == LL_I2S_MODE_SLAVE_TX) \
|
---|
348 | || ((__VALUE__) == LL_I2S_MODE_SLAVE_RX) \
|
---|
349 | || ((__VALUE__) == LL_I2S_MODE_MASTER_TX) \
|
---|
350 | || ((__VALUE__) == LL_I2S_MODE_MASTER_RX))
|
---|
351 |
|
---|
352 | #define IS_LL_I2S_MCLK_OUTPUT(__VALUE__) (((__VALUE__) == LL_I2S_MCLK_OUTPUT_ENABLE) \
|
---|
353 | || ((__VALUE__) == LL_I2S_MCLK_OUTPUT_DISABLE))
|
---|
354 |
|
---|
355 | #define IS_LL_I2S_AUDIO_FREQ(__VALUE__) ((((__VALUE__) >= LL_I2S_AUDIOFREQ_8K) \
|
---|
356 | && ((__VALUE__) <= LL_I2S_AUDIOFREQ_192K)) \
|
---|
357 | || ((__VALUE__) == LL_I2S_AUDIOFREQ_DEFAULT))
|
---|
358 |
|
---|
359 | #define IS_LL_I2S_PRESCALER_LINEAR(__VALUE__) ((__VALUE__) >= 0x2U)
|
---|
360 |
|
---|
361 | #define IS_LL_I2S_PRESCALER_PARITY(__VALUE__) (((__VALUE__) == LL_I2S_PRESCALER_PARITY_EVEN) \
|
---|
362 | || ((__VALUE__) == LL_I2S_PRESCALER_PARITY_ODD))
|
---|
363 | /**
|
---|
364 | * @}
|
---|
365 | */
|
---|
366 |
|
---|
367 | /* Private function prototypes -----------------------------------------------*/
|
---|
368 |
|
---|
369 | /* Exported functions --------------------------------------------------------*/
|
---|
370 | /** @addtogroup I2S_LL_Exported_Functions
|
---|
371 | * @{
|
---|
372 | */
|
---|
373 |
|
---|
374 | /** @addtogroup I2S_LL_EF_Init
|
---|
375 | * @{
|
---|
376 | */
|
---|
377 |
|
---|
378 | /**
|
---|
379 | * @brief De-initialize the SPI/I2S registers to their default reset values.
|
---|
380 | * @param SPIx SPI Instance
|
---|
381 | * @retval An ErrorStatus enumeration value:
|
---|
382 | * - SUCCESS: SPI registers are de-initialized
|
---|
383 | * - ERROR: SPI registers are not de-initialized
|
---|
384 | */
|
---|
385 | ErrorStatus LL_I2S_DeInit(SPI_TypeDef *SPIx)
|
---|
386 | {
|
---|
387 | return LL_SPI_DeInit(SPIx);
|
---|
388 | }
|
---|
389 |
|
---|
390 | /**
|
---|
391 | * @brief Initializes the SPI/I2S registers according to the specified parameters in I2S_InitStruct.
|
---|
392 | * @note As some bits in SPI configuration registers can only be written when the SPI is disabled (SPI_CR1_SPE bit =0),
|
---|
393 | * SPI peripheral should be in disabled state prior calling this function. Otherwise, ERROR result will be returned.
|
---|
394 | * @param SPIx SPI Instance
|
---|
395 | * @param I2S_InitStruct pointer to a @ref LL_I2S_InitTypeDef structure
|
---|
396 | * @retval An ErrorStatus enumeration value:
|
---|
397 | * - SUCCESS: SPI registers are Initialized
|
---|
398 | * - ERROR: SPI registers are not Initialized
|
---|
399 | */
|
---|
400 | ErrorStatus LL_I2S_Init(SPI_TypeDef *SPIx, LL_I2S_InitTypeDef *I2S_InitStruct)
|
---|
401 | {
|
---|
402 | uint32_t i2sdiv = 2U;
|
---|
403 | uint32_t i2sodd = 0U;
|
---|
404 | uint32_t packetlength = 1U;
|
---|
405 | uint32_t tmp;
|
---|
406 | uint32_t sourceclock;
|
---|
407 | ErrorStatus status = ERROR;
|
---|
408 |
|
---|
409 | /* Check the I2S parameters */
|
---|
410 | assert_param(IS_I2S_ALL_INSTANCE(SPIx));
|
---|
411 | assert_param(IS_LL_I2S_MODE(I2S_InitStruct->Mode));
|
---|
412 | assert_param(IS_LL_I2S_STANDARD(I2S_InitStruct->Standard));
|
---|
413 | assert_param(IS_LL_I2S_DATAFORMAT(I2S_InitStruct->DataFormat));
|
---|
414 | assert_param(IS_LL_I2S_MCLK_OUTPUT(I2S_InitStruct->MCLKOutput));
|
---|
415 | assert_param(IS_LL_I2S_AUDIO_FREQ(I2S_InitStruct->AudioFreq));
|
---|
416 | assert_param(IS_LL_I2S_CPOL(I2S_InitStruct->ClockPolarity));
|
---|
417 |
|
---|
418 | if (LL_I2S_IsEnabled(SPIx) == 0x00000000U)
|
---|
419 | {
|
---|
420 | /*---------------------------- SPIx I2SCFGR Configuration --------------------
|
---|
421 | * Configure SPIx I2SCFGR with parameters:
|
---|
422 | * - Mode: SPI_I2SCFGR_I2SCFG[1:0] bit
|
---|
423 | * - Standard: SPI_I2SCFGR_I2SSTD[1:0] and SPI_I2SCFGR_PCMSYNC bits
|
---|
424 | * - DataFormat: SPI_I2SCFGR_CHLEN and SPI_I2SCFGR_DATLEN bits
|
---|
425 | * - ClockPolarity: SPI_I2SCFGR_CKPOL bit
|
---|
426 | */
|
---|
427 |
|
---|
428 | /* Write to SPIx I2SCFGR */
|
---|
429 | MODIFY_REG(SPIx->I2SCFGR,
|
---|
430 | I2S_I2SCFGR_CLEAR_MASK,
|
---|
431 | I2S_InitStruct->Mode | I2S_InitStruct->Standard |
|
---|
432 | I2S_InitStruct->DataFormat | I2S_InitStruct->ClockPolarity |
|
---|
433 | SPI_I2SCFGR_I2SMOD);
|
---|
434 |
|
---|
435 | /*---------------------------- SPIx I2SPR Configuration ----------------------
|
---|
436 | * Configure SPIx I2SPR with parameters:
|
---|
437 | * - MCLKOutput: SPI_I2SPR_MCKOE bit
|
---|
438 | * - AudioFreq: SPI_I2SPR_I2SDIV[7:0] and SPI_I2SPR_ODD bits
|
---|
439 | */
|
---|
440 |
|
---|
441 | /* If the requested audio frequency is not the default, compute the prescaler (i2sodd, i2sdiv)
|
---|
442 | * else, default values are used: i2sodd = 0U, i2sdiv = 2U.
|
---|
443 | */
|
---|
444 | if (I2S_InitStruct->AudioFreq != LL_I2S_AUDIOFREQ_DEFAULT)
|
---|
445 | {
|
---|
446 | /* Check the frame length (For the Prescaler computing)
|
---|
447 | * Default value: LL_I2S_DATAFORMAT_16B (packetlength = 1U).
|
---|
448 | */
|
---|
449 | if (I2S_InitStruct->DataFormat != LL_I2S_DATAFORMAT_16B)
|
---|
450 | {
|
---|
451 | /* Packet length is 32 bits */
|
---|
452 | packetlength = 2U;
|
---|
453 | }
|
---|
454 |
|
---|
455 | /* If an external I2S clock has to be used, the specific define should be set
|
---|
456 | in the project configuration or in the stm32f4xx_ll_rcc.h file */
|
---|
457 | /* Get the I2S source clock value */
|
---|
458 | sourceclock = LL_RCC_GetI2SClockFreq(LL_RCC_I2S1_CLKSOURCE);
|
---|
459 |
|
---|
460 | /* Compute the Real divider depending on the MCLK output state with a floating point */
|
---|
461 | if (I2S_InitStruct->MCLKOutput == LL_I2S_MCLK_OUTPUT_ENABLE)
|
---|
462 | {
|
---|
463 | /* MCLK output is enabled */
|
---|
464 | tmp = (((((sourceclock / 256U) * 10U) / I2S_InitStruct->AudioFreq)) + 5U);
|
---|
465 | }
|
---|
466 | else
|
---|
467 | {
|
---|
468 | /* MCLK output is disabled */
|
---|
469 | tmp = (((((sourceclock / (32U * packetlength)) * 10U) / I2S_InitStruct->AudioFreq)) + 5U);
|
---|
470 | }
|
---|
471 |
|
---|
472 | /* Remove the floating point */
|
---|
473 | tmp = tmp / 10U;
|
---|
474 |
|
---|
475 | /* Check the parity of the divider */
|
---|
476 | i2sodd = (tmp & (uint16_t)0x0001U);
|
---|
477 |
|
---|
478 | /* Compute the i2sdiv prescaler */
|
---|
479 | i2sdiv = ((tmp - i2sodd) / 2U);
|
---|
480 |
|
---|
481 | /* Get the Mask for the Odd bit (SPI_I2SPR[8]) register */
|
---|
482 | i2sodd = (i2sodd << 8U);
|
---|
483 | }
|
---|
484 |
|
---|
485 | /* Test if the divider is 1 or 0 or greater than 0xFF */
|
---|
486 | if ((i2sdiv < 2U) || (i2sdiv > 0xFFU))
|
---|
487 | {
|
---|
488 | /* Set the default values */
|
---|
489 | i2sdiv = 2U;
|
---|
490 | i2sodd = 0U;
|
---|
491 | }
|
---|
492 |
|
---|
493 | /* Write to SPIx I2SPR register the computed value */
|
---|
494 | WRITE_REG(SPIx->I2SPR, i2sdiv | i2sodd | I2S_InitStruct->MCLKOutput);
|
---|
495 |
|
---|
496 | status = SUCCESS;
|
---|
497 | }
|
---|
498 | return status;
|
---|
499 | }
|
---|
500 |
|
---|
501 | /**
|
---|
502 | * @brief Set each @ref LL_I2S_InitTypeDef field to default value.
|
---|
503 | * @param I2S_InitStruct pointer to a @ref LL_I2S_InitTypeDef structure
|
---|
504 | * whose fields will be set to default values.
|
---|
505 | * @retval None
|
---|
506 | */
|
---|
507 | void LL_I2S_StructInit(LL_I2S_InitTypeDef *I2S_InitStruct)
|
---|
508 | {
|
---|
509 | /*--------------- Reset I2S init structure parameters values -----------------*/
|
---|
510 | I2S_InitStruct->Mode = LL_I2S_MODE_SLAVE_TX;
|
---|
511 | I2S_InitStruct->Standard = LL_I2S_STANDARD_PHILIPS;
|
---|
512 | I2S_InitStruct->DataFormat = LL_I2S_DATAFORMAT_16B;
|
---|
513 | I2S_InitStruct->MCLKOutput = LL_I2S_MCLK_OUTPUT_DISABLE;
|
---|
514 | I2S_InitStruct->AudioFreq = LL_I2S_AUDIOFREQ_DEFAULT;
|
---|
515 | I2S_InitStruct->ClockPolarity = LL_I2S_POLARITY_LOW;
|
---|
516 | }
|
---|
517 |
|
---|
518 | /**
|
---|
519 | * @brief Set linear and parity prescaler.
|
---|
520 | * @note To calculate value of PrescalerLinear(I2SDIV[7:0] bits) and PrescalerParity(ODD bit)\n
|
---|
521 | * Check Audio frequency table and formulas inside Reference Manual (SPI/I2S).
|
---|
522 | * @param SPIx SPI Instance
|
---|
523 | * @param PrescalerLinear value Min_Data=0x02 and Max_Data=0xFF.
|
---|
524 | * @param PrescalerParity This parameter can be one of the following values:
|
---|
525 | * @arg @ref LL_I2S_PRESCALER_PARITY_EVEN
|
---|
526 | * @arg @ref LL_I2S_PRESCALER_PARITY_ODD
|
---|
527 | * @retval None
|
---|
528 | */
|
---|
529 | void LL_I2S_ConfigPrescaler(SPI_TypeDef *SPIx, uint32_t PrescalerLinear, uint32_t PrescalerParity)
|
---|
530 | {
|
---|
531 | /* Check the I2S parameters */
|
---|
532 | assert_param(IS_I2S_ALL_INSTANCE(SPIx));
|
---|
533 | assert_param(IS_LL_I2S_PRESCALER_LINEAR(PrescalerLinear));
|
---|
534 | assert_param(IS_LL_I2S_PRESCALER_PARITY(PrescalerParity));
|
---|
535 |
|
---|
536 | /* Write to SPIx I2SPR */
|
---|
537 | MODIFY_REG(SPIx->I2SPR, SPI_I2SPR_I2SDIV | SPI_I2SPR_ODD, PrescalerLinear | (PrescalerParity << 8U));
|
---|
538 | }
|
---|
539 |
|
---|
540 | #if defined (SPI_I2S_FULLDUPLEX_SUPPORT)
|
---|
541 | /**
|
---|
542 | * @brief Configures the full duplex mode for the I2Sx peripheral using its extension
|
---|
543 | * I2Sxext according to the specified parameters in the I2S_InitStruct.
|
---|
544 | * @note The structure pointed by I2S_InitStruct parameter should be the same
|
---|
545 | * used for the master I2S peripheral. In this case, if the master is
|
---|
546 | * configured as transmitter, the slave will be receiver and vice versa.
|
---|
547 | * Or you can force a different mode by modifying the field I2S_Mode to the
|
---|
548 | * value I2S_SlaveRx or I2S_SlaveTx independently of the master configuration.
|
---|
549 | * @param I2Sxext SPI Instance
|
---|
550 | * @param I2S_InitStruct pointer to a @ref LL_I2S_InitTypeDef structure
|
---|
551 | * @retval An ErrorStatus enumeration value:
|
---|
552 | * - SUCCESS: I2Sxext registers are Initialized
|
---|
553 | * - ERROR: I2Sxext registers are not Initialized
|
---|
554 | */
|
---|
555 | ErrorStatus LL_I2S_InitFullDuplex(SPI_TypeDef *I2Sxext, LL_I2S_InitTypeDef *I2S_InitStruct)
|
---|
556 | {
|
---|
557 | uint32_t mode = 0U;
|
---|
558 | ErrorStatus status = ERROR;
|
---|
559 |
|
---|
560 | /* Check the I2S parameters */
|
---|
561 | assert_param(IS_I2S_EXT_ALL_INSTANCE(I2Sxext));
|
---|
562 | assert_param(IS_LL_I2S_MODE(I2S_InitStruct->Mode));
|
---|
563 | assert_param(IS_LL_I2S_STANDARD(I2S_InitStruct->Standard));
|
---|
564 | assert_param(IS_LL_I2S_DATAFORMAT(I2S_InitStruct->DataFormat));
|
---|
565 | assert_param(IS_LL_I2S_CPOL(I2S_InitStruct->ClockPolarity));
|
---|
566 |
|
---|
567 | if (LL_I2S_IsEnabled(I2Sxext) == 0x00000000U)
|
---|
568 | {
|
---|
569 | /*---------------------------- SPIx I2SCFGR Configuration --------------------
|
---|
570 | * Configure SPIx I2SCFGR with parameters:
|
---|
571 | * - Mode: SPI_I2SCFGR_I2SCFG[1:0] bit
|
---|
572 | * - Standard: SPI_I2SCFGR_I2SSTD[1:0] and SPI_I2SCFGR_PCMSYNC bits
|
---|
573 | * - DataFormat: SPI_I2SCFGR_CHLEN and SPI_I2SCFGR_DATLEN bits
|
---|
574 | * - ClockPolarity: SPI_I2SCFGR_CKPOL bit
|
---|
575 | */
|
---|
576 |
|
---|
577 | /* Reset I2SPR registers */
|
---|
578 | WRITE_REG(I2Sxext->I2SPR, I2S_I2SPR_CLEAR_MASK);
|
---|
579 |
|
---|
580 | /* Get the mode to be configured for the extended I2S */
|
---|
581 | if ((I2S_InitStruct->Mode == LL_I2S_MODE_MASTER_TX) || (I2S_InitStruct->Mode == LL_I2S_MODE_SLAVE_TX))
|
---|
582 | {
|
---|
583 | mode = LL_I2S_MODE_SLAVE_RX;
|
---|
584 | }
|
---|
585 | else
|
---|
586 | {
|
---|
587 | if ((I2S_InitStruct->Mode == LL_I2S_MODE_MASTER_RX) || (I2S_InitStruct->Mode == LL_I2S_MODE_SLAVE_RX))
|
---|
588 | {
|
---|
589 | mode = LL_I2S_MODE_SLAVE_TX;
|
---|
590 | }
|
---|
591 | }
|
---|
592 |
|
---|
593 | /* Write to SPIx I2SCFGR */
|
---|
594 | MODIFY_REG(I2Sxext->I2SCFGR,
|
---|
595 | I2S_I2SCFGR_CLEAR_MASK,
|
---|
596 | I2S_InitStruct->Standard |
|
---|
597 | I2S_InitStruct->DataFormat | I2S_InitStruct->ClockPolarity |
|
---|
598 | SPI_I2SCFGR_I2SMOD | mode);
|
---|
599 |
|
---|
600 | status = SUCCESS;
|
---|
601 | }
|
---|
602 | return status;
|
---|
603 | }
|
---|
604 | #endif /* SPI_I2S_FULLDUPLEX_SUPPORT */
|
---|
605 |
|
---|
606 | /**
|
---|
607 | * @}
|
---|
608 | */
|
---|
609 |
|
---|
610 | /**
|
---|
611 | * @}
|
---|
612 | */
|
---|
613 |
|
---|
614 | /**
|
---|
615 | * @}
|
---|
616 | */
|
---|
617 |
|
---|
618 | #endif /* defined (SPI1) || defined (SPI2) || defined (SPI3) || defined (SPI4) || defined (SPI5) || defined(SPI6) */
|
---|
619 |
|
---|
620 | /**
|
---|
621 | * @}
|
---|
622 | */
|
---|
623 |
|
---|
624 | #endif /* USE_FULL_LL_DRIVER */
|
---|
625 |
|
---|
626 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
---|