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_EnableLockConfiguration()
62 (++) HAL_SPIEx_ConfigureUnderrun()
63
64 @endverbatim
65 * @{
66 */
67
68 /**
69 * @brief Flush the RX fifo.
70 * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
71 * the configuration information for the specified SPI module.
72 * @retval HAL status
73 */
HAL_SPIEx_FlushRxFifo(const SPI_HandleTypeDef * hspi)74 HAL_StatusTypeDef HAL_SPIEx_FlushRxFifo(const SPI_HandleTypeDef *hspi)
75 {
76 uint8_t count = 0;
77 uint32_t itflag = hspi->Instance->SR;
78 __IO uint32_t tmpreg;
79
80 while (((hspi->Instance->SR & SPI_FLAG_FRLVL) != SPI_RX_FIFO_0PACKET) || ((itflag & SPI_FLAG_RXWNE) != 0UL))
81 {
82 count += (uint8_t)4UL;
83 tmpreg = hspi->Instance->RXDR;
84 UNUSED(tmpreg); /* To avoid GCC warning */
85
86 if (IS_SPI_FULL_INSTANCE(hspi->Instance))
87 {
88 if (count > SPI_HIGHEND_FIFO_SIZE)
89 {
90 return HAL_TIMEOUT;
91 }
92 }
93 else
94 {
95 if (count > SPI_LOWEND_FIFO_SIZE)
96 {
97 return HAL_TIMEOUT;
98 }
99 }
100 }
101 return HAL_OK;
102 }
103
104
105 /**
106 * @brief Enable the Lock for the AF configuration of associated IOs
107 * and write protect the Content of Configuration register 2
108 * when SPI is enabled
109 * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
110 * the configuration information for SPI module.
111 * @retval None
112 */
HAL_SPIEx_EnableLockConfiguration(SPI_HandleTypeDef * hspi)113 HAL_StatusTypeDef HAL_SPIEx_EnableLockConfiguration(SPI_HandleTypeDef *hspi)
114 {
115 HAL_StatusTypeDef errorcode = HAL_OK;
116
117 /* Process Locked */
118 __HAL_LOCK(hspi);
119
120 if (hspi->State != HAL_SPI_STATE_READY)
121 {
122 errorcode = HAL_BUSY;
123 hspi->State = HAL_SPI_STATE_READY;
124 /* Process Unlocked */
125 __HAL_UNLOCK(hspi);
126 return errorcode;
127 }
128
129 /* Check if the SPI is disabled to edit IOLOCK bit */
130 if ((hspi->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE)
131 {
132 SET_BIT(hspi->Instance->CR1, SPI_CR1_IOLOCK);
133 }
134 else
135 {
136 /* Disable SPI peripheral */
137 __HAL_SPI_DISABLE(hspi);
138
139 SET_BIT(hspi->Instance->CR1, SPI_CR1_IOLOCK);
140
141 /* Enable SPI peripheral */
142 __HAL_SPI_ENABLE(hspi);
143 }
144
145 hspi->State = HAL_SPI_STATE_READY;
146 /* Process Unlocked */
147 __HAL_UNLOCK(hspi);
148 return errorcode;
149 }
150
151 /**
152 * @brief Configure the UNDERRUN condition and behavior of slave transmitter.
153 * @param hspi: pointer to a SPI_HandleTypeDef structure that contains
154 * the configuration information for SPI module.
155 * @param UnderrunDetection : Detection of underrun condition at slave transmitter
156 * This parameter is not supported in this SPI version.
157 * It is kept in order to not break the compatibility.
158 * @param UnderrunBehaviour : Behavior of slave transmitter at underrun condition
159 * This parameter can be a value of @ref SPI_Underrun_Behaviour.
160 * @retval None
161 */
HAL_SPIEx_ConfigureUnderrun(SPI_HandleTypeDef * hspi,uint32_t UnderrunDetection,uint32_t UnderrunBehaviour)162 HAL_StatusTypeDef HAL_SPIEx_ConfigureUnderrun(SPI_HandleTypeDef *hspi, uint32_t UnderrunDetection,
163 uint32_t UnderrunBehaviour)
164 {
165 /* Prevent unused argument(s) compilation warning */
166 UNUSED(UnderrunDetection);
167
168 HAL_StatusTypeDef errorcode = HAL_OK;
169
170 /* Process Locked */
171 __HAL_LOCK(hspi);
172
173 /* Check State and Insure that Underrun configuration is managed only by Salve */
174 if ((hspi->State != HAL_SPI_STATE_READY) || (hspi->Init.Mode != SPI_MODE_SLAVE))
175 {
176 errorcode = HAL_BUSY;
177 hspi->State = HAL_SPI_STATE_READY;
178 /* Process Unlocked */
179 __HAL_UNLOCK(hspi);
180 return errorcode;
181 }
182
183 /* Check the parameters */
184 assert_param(IS_SPI_UNDERRUN_BEHAVIOUR(UnderrunBehaviour));
185
186 /* Check if the SPI is disabled to edit CFG1 register */
187 if ((hspi->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE)
188 {
189 /* Configure Underrun fields */
190 MODIFY_REG(hspi->Instance->CFG1, SPI_CFG1_UDRCFG, UnderrunBehaviour);
191 }
192 else
193 {
194 /* Disable SPI peripheral */
195 __HAL_SPI_DISABLE(hspi);
196
197 /* Configure Underrun fields */
198 MODIFY_REG(hspi->Instance->CFG1, SPI_CFG1_UDRCFG, UnderrunBehaviour);
199
200 /* Enable SPI peripheral */
201 __HAL_SPI_ENABLE(hspi);
202 }
203
204
205 hspi->State = HAL_SPI_STATE_READY;
206 /* Process Unlocked */
207 __HAL_UNLOCK(hspi);
208 return errorcode;
209 }
210
211 /**
212 * @brief Set Autonomous Mode configuration
213 * @param hspi Pointer to a SPI_HandleTypeDef structure that contains
214 * the configuration information for the specified SPIx peripheral.
215 * @param sConfig Pointer to a SPI_HandleTypeDef structure that contains
216 * the configuration information of the autonomous mode for the specified SPIx peripheral.
217 * @retval HAL status
218 */
HAL_SPIEx_SetConfigAutonomousMode(SPI_HandleTypeDef * hspi,const SPI_AutonomousModeConfTypeDef * sConfig)219 HAL_StatusTypeDef HAL_SPIEx_SetConfigAutonomousMode(SPI_HandleTypeDef *hspi,
220 const SPI_AutonomousModeConfTypeDef *sConfig)
221 {
222 if (hspi->State == HAL_SPI_STATE_READY)
223 {
224 /* Process Locked */
225 __HAL_LOCK(hspi);
226
227 hspi->State = HAL_SPI_STATE_BUSY;
228
229 /* Check the parameters */
230 assert_param(IS_SPI_AUTONOMOUS_INSTANCE(hspi->Instance));
231 assert_param(IS_SPI_TRIG_SOURCE(hspi->Instance, sConfig->TriggerSelection));
232 assert_param(IS_SPI_AUTO_MODE_TRG_POL(sConfig->TriggerPolarity));
233
234 /* Disable the selected SPI peripheral to be able to configure AUTOCR */
235 __HAL_SPI_DISABLE(hspi);
236
237 /* SPIx AUTOCR Configuration */
238 WRITE_REG(hspi->Instance->AUTOCR, (sConfig->TriggerState | ((sConfig->TriggerSelection) & SPI_AUTOCR_TRIGSEL_Msk) |
239 sConfig->TriggerPolarity));
240
241 hspi->State = HAL_SPI_STATE_READY;
242
243 /* Process Unlocked */
244 __HAL_UNLOCK(hspi);
245
246 return HAL_OK;
247 }
248 else
249 {
250 return HAL_ERROR;
251 }
252 }
253
254 /**
255 * @brief Get Autonomous Mode configuration
256 * @param hspi Pointer to a SPI_HandleTypeDef structure that contains
257 * the configuration information for the specified SPIx peripheral.
258 * @param sConfig Pointer to a SPI_HandleTypeDef structure that contains
259 * the configuration information of the autonomous mode for the specified SPIx peripheral.
260 * @retval HAL status
261 */
HAL_SPIEx_GetConfigAutonomousMode(const SPI_HandleTypeDef * hspi,SPI_AutonomousModeConfTypeDef * sConfig)262 HAL_StatusTypeDef HAL_SPIEx_GetConfigAutonomousMode(const SPI_HandleTypeDef *hspi,
263 SPI_AutonomousModeConfTypeDef *sConfig)
264 {
265 uint32_t autocr_tmp;
266
267 /* Check the parameters */
268 assert_param(IS_SPI_AUTONOMOUS_INSTANCE(hspi->Instance));
269
270 autocr_tmp = hspi->Instance->AUTOCR;
271
272 sConfig->TriggerState = (autocr_tmp & SPI_AUTOCR_TRIGEN);
273 #if defined(SPI_TRIG_GRP2)
274 if (IS_SPI_GRP2_INSTANCE(hspi->Instance))
275 {
276 sConfig->TriggerSelection = ((autocr_tmp & SPI_AUTOCR_TRIGSEL) | SPI_TRIG_GRP2);
277 }
278 else
279 {
280 sConfig->TriggerSelection = ((autocr_tmp & SPI_AUTOCR_TRIGSEL) | SPI_TRIG_GRP1);
281 }
282 #else
283 sConfig->TriggerSelection = ((autocr_tmp & SPI_AUTOCR_TRIGSEL) | SPI_TRIG_GRP1);
284 #endif /* SPI_TRIG_GRP2 */
285 sConfig->TriggerPolarity = (autocr_tmp & SPI_AUTOCR_TRIGPOL);
286
287 return HAL_OK;
288 }
289
290 /**
291 * @brief Clear Autonomous Mode configuration
292 * @param hspi Pointer to a SPI_HandleTypeDef structure that contains
293 * the configuration information for the specified SPIx peripheral.
294 * @retval HAL status
295 */
HAL_SPIEx_ClearConfigAutonomousMode(SPI_HandleTypeDef * hspi)296 HAL_StatusTypeDef HAL_SPIEx_ClearConfigAutonomousMode(SPI_HandleTypeDef *hspi)
297 {
298 if (hspi->State == HAL_SPI_STATE_READY)
299 {
300 /* Process Locked */
301 __HAL_LOCK(hspi);
302
303 hspi->State = HAL_SPI_STATE_BUSY;
304
305 /* Check the parameters */
306 assert_param(IS_SPI_AUTONOMOUS_INSTANCE(hspi->Instance));
307
308 /* Disable the selected SPI peripheral to be able to clear AUTOCR */
309 __HAL_SPI_DISABLE(hspi);
310
311 CLEAR_REG(hspi->Instance->AUTOCR);
312
313 /* Enable the selected SPI peripheral */
314 __HAL_SPI_ENABLE(hspi);
315
316 hspi->State = HAL_SPI_STATE_READY;
317
318 /* Process Unlocked */
319 __HAL_UNLOCK(hspi);
320
321 return HAL_OK;
322 }
323 else
324 {
325 return HAL_ERROR;
326 }
327 }
328
329 /**
330 * @}
331 */
332
333 /**
334 * @}
335 */
336
337 #endif /* HAL_SPI_MODULE_ENABLED */
338
339 /**
340 * @}
341 */
342
343 /**
344 * @}
345 */
346