1 /**
2   ******************************************************************************
3   * @file    stm32wbaxx_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) 2022 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 "stm32wbaxx_hal.h"
26 
27 /** @addtogroup STM32WBAxx_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_GRP1)
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_GRP2);
285 #endif /* SPI_TRIG_GRP1 */
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