1 /**
2 ******************************************************************************
3 * @file stm32u5xx_hal_spi_ex.c
4 * @author MCD Application Team
5 * @brief Extended SPI HAL module driver.
6 * This file provides firmware functions to manage the following
7 * SPI peripheral extended functionalities :
8 * + IO operation functions
9 * + Peripheral Control functions
10 *
11 ******************************************************************************
12 * @attention
13 *
14 * Copyright (c) 2021 STMicroelectronics.
15 * All rights reserved.
16 *
17 * This software is licensed under terms that can be found in the LICENSE file
18 * in the root directory of this software component.
19 * If no LICENSE file comes with this software, it is provided AS-IS.
20 *
21 ******************************************************************************
22 */
23
24 /* Includes ------------------------------------------------------------------*/
25 #include "stm32u5xx_hal.h"
26
27 /** @addtogroup STM32U5xx_HAL_Driver
28 * @{
29 */
30
31 /** @defgroup SPIEx SPIEx
32 * @brief SPI Extended HAL module driver
33 * @{
34 */
35 #ifdef HAL_SPI_MODULE_ENABLED
36
37 /* Private typedef -----------------------------------------------------------*/
38 /* Private defines -----------------------------------------------------------*/
39 /* Private macros ------------------------------------------------------------*/
40 /* Private variables ---------------------------------------------------------*/
41 /* Private function prototypes -----------------------------------------------*/
42 /* Exported functions --------------------------------------------------------*/
43
44 /** @defgroup SPIEx_Exported_Functions SPIEx Exported Functions
45 * @{
46 */
47
48 /** @defgroup SPIEx_Exported_Functions_Group1 IO operation functions
49 * @brief Data transfers functions
50 *
51 @verbatim
52 ==============================================================================
53 ##### IO operation functions #####
54 ===============================================================================
55 [..]
56 This subsection provides a set of extended functions to manage the SPI
57 data transfers.
58
59 (#) SPIEx function:
60 (++) HAL_SPIEx_FlushRxFifo()
61 (++) HAL_SPIEx_FlushRxFifo()
62 (++) HAL_SPIEx_EnableLockConfiguration()
63 (++) HAL_SPIEx_ConfigureUnderrun()
64
65 @endverbatim
66 * @{
67 */
68
69 /**
70 * @brief Flush the RX fifo.
71 * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
72 * the configuration information for the specified SPI module.
73 * @retval HAL status
74 */
HAL_SPIEx_FlushRxFifo(const SPI_HandleTypeDef * hspi)75 HAL_StatusTypeDef HAL_SPIEx_FlushRxFifo(const SPI_HandleTypeDef *hspi)
76 {
77 uint8_t count = 0;
78 uint32_t itflag = hspi->Instance->SR;
79 __IO uint32_t tmpreg;
80
81 while (((hspi->Instance->SR & SPI_FLAG_FRLVL) != SPI_RX_FIFO_0PACKET) || ((itflag & SPI_FLAG_RXWNE) != 0UL))
82 {
83 count += (uint8_t)4UL;
84 tmpreg = hspi->Instance->RXDR;
85 UNUSED(tmpreg); /* To avoid GCC warning */
86
87 if (IS_SPI_FULL_INSTANCE(hspi->Instance))
88 {
89 if (count > SPI_HIGHEND_FIFO_SIZE)
90 {
91 return HAL_TIMEOUT;
92 }
93 }
94 else
95 {
96 if (count > SPI_LOWEND_FIFO_SIZE)
97 {
98 return HAL_TIMEOUT;
99 }
100 }
101 }
102 return HAL_OK;
103 }
104
105
106 /**
107 * @brief Enable the Lock for the AF configuration of associated IOs
108 * and write protect the Content of Configuration register 2
109 * when SPI is enabled
110 * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
111 * the configuration information for SPI module.
112 * @retval None
113 */
HAL_SPIEx_EnableLockConfiguration(SPI_HandleTypeDef * hspi)114 HAL_StatusTypeDef HAL_SPIEx_EnableLockConfiguration(SPI_HandleTypeDef *hspi)
115 {
116 HAL_StatusTypeDef errorcode = HAL_OK;
117
118 /* Process Locked */
119 __HAL_LOCK(hspi);
120
121 if (hspi->State != HAL_SPI_STATE_READY)
122 {
123 errorcode = HAL_BUSY;
124 hspi->State = HAL_SPI_STATE_READY;
125 /* Process Unlocked */
126 __HAL_UNLOCK(hspi);
127 return errorcode;
128 }
129
130 /* Check if the SPI is disabled to edit IOLOCK bit */
131 if ((hspi->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE)
132 {
133 SET_BIT(hspi->Instance->CR1, SPI_CR1_IOLOCK);
134 }
135 else
136 {
137 /* Disable SPI peripheral */
138 __HAL_SPI_DISABLE(hspi);
139
140 SET_BIT(hspi->Instance->CR1, SPI_CR1_IOLOCK);
141
142 /* Enable SPI peripheral */
143 __HAL_SPI_ENABLE(hspi);
144 }
145
146 hspi->State = HAL_SPI_STATE_READY;
147 /* Process Unlocked */
148 __HAL_UNLOCK(hspi);
149 return errorcode;
150 }
151
152 /**
153 * @brief Configure the UNDERRUN condition and behavior of slave transmitter.
154 * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
155 * the configuration information for SPI module.
156 * @param UnderrunDetection : Detection of underrun condition at slave transmitter
157 * This parameter is not supported in this SPI version.
158 * It is kept in order to not break the compatibility.
159 * @param UnderrunBehaviour : Behavior of slave transmitter at underrun condition
160 * This parameter can be a value of @ref SPI_Underrun_Behaviour.
161 * @retval None
162 */
HAL_SPIEx_ConfigureUnderrun(SPI_HandleTypeDef * hspi,uint32_t UnderrunDetection,uint32_t UnderrunBehaviour)163 HAL_StatusTypeDef HAL_SPIEx_ConfigureUnderrun(SPI_HandleTypeDef *hspi, uint32_t UnderrunDetection,
164 uint32_t UnderrunBehaviour)
165 {
166 /* Prevent unused argument(s) compilation warning */
167 UNUSED(UnderrunDetection);
168
169 HAL_StatusTypeDef errorcode = HAL_OK;
170
171 /* Process Locked */
172 __HAL_LOCK(hspi);
173
174 /* Check State and Insure that Underrun configuration is managed only by Salve */
175 if ((hspi->State != HAL_SPI_STATE_READY) || (hspi->Init.Mode != SPI_MODE_SLAVE))
176 {
177 errorcode = HAL_BUSY;
178 hspi->State = HAL_SPI_STATE_READY;
179 /* Process Unlocked */
180 __HAL_UNLOCK(hspi);
181 return errorcode;
182 }
183
184 /* Check the parameters */
185 assert_param(IS_SPI_UNDERRUN_BEHAVIOUR(UnderrunBehaviour));
186
187 /* Check if the SPI is disabled to edit CFG1 register */
188 if ((hspi->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE)
189 {
190 /* Configure Underrun fields */
191 MODIFY_REG(hspi->Instance->CFG1, SPI_CFG1_UDRCFG, UnderrunBehaviour);
192 }
193 else
194 {
195 /* Disable SPI peripheral */
196 __HAL_SPI_DISABLE(hspi);
197
198 /* Configure Underrun fields */
199 MODIFY_REG(hspi->Instance->CFG1, SPI_CFG1_UDRCFG, UnderrunBehaviour);
200
201 /* Enable SPI peripheral */
202 __HAL_SPI_ENABLE(hspi);
203 }
204
205
206 hspi->State = HAL_SPI_STATE_READY;
207 /* Process Unlocked */
208 __HAL_UNLOCK(hspi);
209 return errorcode;
210 }
211
212 /**
213 * @brief Set Autonomous Mode configuration
214 * @param hspi Pointer to a SPI_HandleTypeDef structure that contains
215 * the configuration information for the specified SPIx peripheral.
216 * @param sConfig Pointer to a SPI_HandleTypeDef structure that contains
217 * the configuration information of the autonomous mode for the specified SPIx peripheral.
218 * @retval HAL status
219 */
HAL_SPIEx_SetConfigAutonomousMode(SPI_HandleTypeDef * hspi,const SPI_AutonomousModeConfTypeDef * sConfig)220 HAL_StatusTypeDef HAL_SPIEx_SetConfigAutonomousMode(SPI_HandleTypeDef *hspi,
221 const SPI_AutonomousModeConfTypeDef *sConfig)
222 {
223 if (hspi->State == HAL_SPI_STATE_READY)
224 {
225 /* Process Locked */
226 __HAL_LOCK(hspi);
227
228 hspi->State = HAL_SPI_STATE_BUSY;
229
230 /* Check the parameters */
231 assert_param(IS_SPI_AUTONOMOUS_INSTANCE(hspi->Instance));
232 assert_param(IS_SPI_TRIG_SOURCE(hspi->Instance, sConfig->TriggerSelection));
233 assert_param(IS_SPI_AUTO_MODE_TRG_POL(sConfig->TriggerPolarity));
234
235 /* Disable the selected SPI peripheral to be able to configure AUTOCR */
236 __HAL_SPI_DISABLE(hspi);
237
238 /* SPIx AUTOCR Configuration */
239 WRITE_REG(hspi->Instance->AUTOCR, (sConfig->TriggerState | ((sConfig->TriggerSelection) & SPI_AUTOCR_TRIGSEL_Msk) |
240 sConfig->TriggerPolarity));
241
242 hspi->State = HAL_SPI_STATE_READY;
243
244 /* Process Unlocked */
245 __HAL_UNLOCK(hspi);
246
247 return HAL_OK;
248 }
249 else
250 {
251 return HAL_ERROR;
252 }
253 }
254
255 /**
256 * @brief Get Autonomous Mode configuration
257 * @param hspi Pointer to a SPI_HandleTypeDef structure that contains
258 * the configuration information for the specified SPIx peripheral.
259 * @param sConfig Pointer to a SPI_HandleTypeDef structure that contains
260 * the configuration information of the autonomous mode for the specified SPIx peripheral.
261 * @retval HAL status
262 */
HAL_SPIEx_GetConfigAutonomousMode(const SPI_HandleTypeDef * hspi,SPI_AutonomousModeConfTypeDef * sConfig)263 HAL_StatusTypeDef HAL_SPIEx_GetConfigAutonomousMode(const SPI_HandleTypeDef *hspi,
264 SPI_AutonomousModeConfTypeDef *sConfig)
265 {
266 uint32_t autocr_tmp;
267
268 /* Check the parameters */
269 assert_param(IS_SPI_AUTONOMOUS_INSTANCE(hspi->Instance));
270
271 autocr_tmp = hspi->Instance->AUTOCR;
272
273 sConfig->TriggerState = (autocr_tmp & SPI_AUTOCR_TRIGEN);
274 #if defined(SPI_TRIG_GRP2)
275 if (IS_SPI_GRP2_INSTANCE(hspi->Instance))
276 {
277 sConfig->TriggerSelection = ((autocr_tmp & SPI_AUTOCR_TRIGSEL) | SPI_TRIG_GRP2);
278 }
279 else
280 {
281 sConfig->TriggerSelection = ((autocr_tmp & SPI_AUTOCR_TRIGSEL) | SPI_TRIG_GRP1);
282 }
283 #else
284 sConfig->TriggerSelection = ((autocr_tmp & SPI_AUTOCR_TRIGSEL) | SPI_TRIG_GRP1);
285 #endif /* SPI_TRIG_GRP2 */
286 sConfig->TriggerPolarity = (autocr_tmp & SPI_AUTOCR_TRIGPOL);
287
288 return HAL_OK;
289 }
290
291 /**
292 * @brief Clear Autonomous Mode configuration
293 * @param hspi Pointer to a SPI_HandleTypeDef structure that contains
294 * the configuration information for the specified SPIx peripheral.
295 * @retval HAL status
296 */
HAL_SPIEx_ClearConfigAutonomousMode(SPI_HandleTypeDef * hspi)297 HAL_StatusTypeDef HAL_SPIEx_ClearConfigAutonomousMode(SPI_HandleTypeDef *hspi)
298 {
299 if (hspi->State == HAL_SPI_STATE_READY)
300 {
301 /* Process Locked */
302 __HAL_LOCK(hspi);
303
304 hspi->State = HAL_SPI_STATE_BUSY;
305
306 /* Check the parameters */
307 assert_param(IS_SPI_AUTONOMOUS_INSTANCE(hspi->Instance));
308
309 /* Disable the selected SPI peripheral to be able to clear AUTOCR */
310 __HAL_SPI_DISABLE(hspi);
311
312 CLEAR_REG(hspi->Instance->AUTOCR);
313
314 /* Enable the selected SPI peripheral */
315 __HAL_SPI_ENABLE(hspi);
316
317 hspi->State = HAL_SPI_STATE_READY;
318
319 /* Process Unlocked */
320 __HAL_UNLOCK(hspi);
321
322 return HAL_OK;
323 }
324 else
325 {
326 return HAL_ERROR;
327 }
328 }
329
330 /**
331 * @}
332 */
333
334 /**
335 * @}
336 */
337
338 #endif /* HAL_SPI_MODULE_ENABLED */
339
340 /**
341 * @}
342 */
343
344 /**
345 * @}
346 */
347