Go to most recent revision | Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
30 | mjames | 1 | /** |
2 | ****************************************************************************** |
||
3 | * @file stm32l1xx_hal_spi.c |
||
4 | * @author MCD Application Team |
||
5 | * @brief SPI HAL module driver. |
||
50 | mjames | 6 | * This file provides firmware functions to manage the following |
30 | mjames | 7 | * functionalities of the Serial Peripheral Interface (SPI) peripheral: |
8 | * + Initialization and de-initialization functions |
||
9 | * + IO operation functions |
||
50 | mjames | 10 | * + Peripheral Control functions |
30 | mjames | 11 | * + Peripheral State functions |
50 | mjames | 12 | * |
30 | mjames | 13 | @verbatim |
14 | ============================================================================== |
||
15 | ##### How to use this driver ##### |
||
16 | ============================================================================== |
||
17 | [..] |
||
18 | The SPI HAL driver can be used as follows: |
||
19 | |||
20 | (#) Declare a SPI_HandleTypeDef handle structure, for example: |
||
50 | mjames | 21 | SPI_HandleTypeDef hspi; |
30 | mjames | 22 | |
50 | mjames | 23 | (#)Initialize the SPI low level resources by implementing the HAL_SPI_MspInit() API: |
24 | (##) Enable the SPIx interface clock |
||
30 | mjames | 25 | (##) SPI pins configuration |
50 | mjames | 26 | (+++) Enable the clock for the SPI GPIOs |
30 | mjames | 27 | (+++) Configure these SPI pins as alternate function push-pull |
28 | (##) NVIC configuration if you need to use interrupt process |
||
29 | (+++) Configure the SPIx interrupt priority |
||
30 | (+++) Enable the NVIC SPI IRQ handle |
||
31 | (##) DMA Configuration if you need to use DMA process |
||
50 | mjames | 32 | (+++) Declare a DMA_HandleTypeDef handle structure for the transmit or receive Stream/Channel |
30 | mjames | 33 | (+++) Enable the DMAx clock |
50 | mjames | 34 | (+++) Configure the DMA handle parameters |
35 | (+++) Configure the DMA Tx or Rx Stream/Channel |
||
36 | (+++) Associate the initialized hdma_tx(or _rx) handle to the hspi DMA Tx or Rx handle |
||
37 | (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on the DMA Tx or Rx Stream/Channel |
||
30 | mjames | 38 | |
50 | mjames | 39 | (#) Program the Mode, BidirectionalMode , Data size, Baudrate Prescaler, NSS |
30 | mjames | 40 | management, Clock polarity and phase, FirstBit and CRC configuration in the hspi Init structure. |
41 | |||
42 | (#) Initialize the SPI registers by calling the HAL_SPI_Init() API: |
||
43 | (++) This API configures also the low level Hardware GPIO, CLOCK, CORTEX...etc) |
||
50 | mjames | 44 | by calling the customized HAL_SPI_MspInit() API. |
30 | mjames | 45 | [..] |
46 | Circular mode restriction: |
||
47 | (#) The DMA circular mode cannot be used when the SPI is configured in these modes: |
||
48 | (##) Master 2Lines RxOnly |
||
49 | (##) Master 1Line Rx |
||
50 | (#) The CRC feature is not managed when the DMA circular mode is enabled |
||
50 | mjames | 51 | (#) When the SPI DMA Pause/Stop features are used, we must use the following APIs |
30 | mjames | 52 | the HAL_SPI_DMAPause()/ HAL_SPI_DMAStop() only under the SPI callbacks |
50 | mjames | 53 | [..] |
54 | Master Receive mode restriction: |
||
55 | (#) In Master unidirectional receive-only mode (MSTR =1, BIDIMODE=0, RXONLY=1) or |
||
56 | bidirectional receive mode (MSTR=1, BIDIMODE=1, BIDIOE=0), to ensure that the SPI |
||
57 | does not initiate a new transfer the following procedure has to be respected: |
||
58 | (##) HAL_SPI_DeInit() |
||
59 | (##) HAL_SPI_Init() |
||
60 | [..] |
||
61 | Callback registration: |
||
30 | mjames | 62 | |
50 | mjames | 63 | (#) The compilation flag USE_HAL_SPI_REGISTER_CALLBACKS when set to 1U |
64 | allows the user to configure dynamically the driver callbacks. |
||
65 | Use Functions HAL_SPI_RegisterCallback() to register an interrupt callback. |
||
30 | mjames | 66 | |
50 | mjames | 67 | Function HAL_SPI_RegisterCallback() allows to register following callbacks: |
68 | (++) TxCpltCallback : SPI Tx Completed callback |
||
69 | (++) RxCpltCallback : SPI Rx Completed callback |
||
70 | (++) TxRxCpltCallback : SPI TxRx Completed callback |
||
71 | (++) TxHalfCpltCallback : SPI Tx Half Completed callback |
||
72 | (++) RxHalfCpltCallback : SPI Rx Half Completed callback |
||
73 | (++) TxRxHalfCpltCallback : SPI TxRx Half Completed callback |
||
74 | (++) ErrorCallback : SPI Error callback |
||
75 | (++) AbortCpltCallback : SPI Abort callback |
||
76 | (++) MspInitCallback : SPI Msp Init callback |
||
77 | (++) MspDeInitCallback : SPI Msp DeInit callback |
||
78 | This function takes as parameters the HAL peripheral handle, the Callback ID |
||
79 | and a pointer to the user callback function. |
||
80 | |||
81 | |||
82 | (#) Use function HAL_SPI_UnRegisterCallback to reset a callback to the default |
||
83 | weak function. |
||
84 | HAL_SPI_UnRegisterCallback takes as parameters the HAL peripheral handle, |
||
85 | and the Callback ID. |
||
86 | This function allows to reset following callbacks: |
||
87 | (++) TxCpltCallback : SPI Tx Completed callback |
||
88 | (++) RxCpltCallback : SPI Rx Completed callback |
||
89 | (++) TxRxCpltCallback : SPI TxRx Completed callback |
||
90 | (++) TxHalfCpltCallback : SPI Tx Half Completed callback |
||
91 | (++) RxHalfCpltCallback : SPI Rx Half Completed callback |
||
92 | (++) TxRxHalfCpltCallback : SPI TxRx Half Completed callback |
||
93 | (++) ErrorCallback : SPI Error callback |
||
94 | (++) AbortCpltCallback : SPI Abort callback |
||
95 | (++) MspInitCallback : SPI Msp Init callback |
||
96 | (++) MspDeInitCallback : SPI Msp DeInit callback |
||
97 | |||
98 | [..] |
||
99 | By default, after the HAL_SPI_Init() and when the state is HAL_SPI_STATE_RESET |
||
100 | all callbacks are set to the corresponding weak functions: |
||
101 | examples HAL_SPI_MasterTxCpltCallback(), HAL_SPI_MasterRxCpltCallback(). |
||
102 | Exception done for MspInit and MspDeInit functions that are |
||
103 | reset to the legacy weak functions in the HAL_SPI_Init()/ HAL_SPI_DeInit() only when |
||
104 | these callbacks are null (not registered beforehand). |
||
105 | If MspInit or MspDeInit are not null, the HAL_SPI_Init()/ HAL_SPI_DeInit() |
||
106 | keep and use the user MspInit/MspDeInit callbacks (registered beforehand) whatever the state. |
||
107 | |||
108 | [..] |
||
109 | Callbacks can be registered/unregistered in HAL_SPI_STATE_READY state only. |
||
110 | Exception done MspInit/MspDeInit functions that can be registered/unregistered |
||
111 | in HAL_SPI_STATE_READY or HAL_SPI_STATE_RESET state, |
||
112 | thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit. |
||
113 | Then, the user first registers the MspInit/MspDeInit user callbacks |
||
114 | using HAL_SPI_RegisterCallback() before calling HAL_SPI_DeInit() |
||
115 | or HAL_SPI_Init() function. |
||
116 | |||
117 | [..] |
||
118 | When the compilation define USE_HAL_PPP_REGISTER_CALLBACKS is set to 0 or |
||
119 | not defined, the callback registering feature is not available |
||
120 | and weak (surcharged) callbacks are used. |
||
121 | |||
122 | [..] |
||
123 | Using the HAL it is not possible to reach all supported SPI frequency with the different SPI Modes, |
||
124 | the following table resume the max SPI frequency reached with data size 8bits/16bits, |
||
125 | according to frequency of the APBx Peripheral Clock (fPCLK) used by the SPI instance. |
||
126 | |||
30 | mjames | 127 | @endverbatim |
50 | mjames | 128 | |
129 | Additional table : |
||
130 | |||
131 | DataSize = SPI_DATASIZE_8BIT: |
||
132 | +----------------------------------------------------------------------------------------------+ |
||
133 | | | | 2Lines Fullduplex | 2Lines RxOnly | 1Line | |
||
134 | | Process | Transfer mode |---------------------|----------------------|----------------------| |
||
135 | | | | Master | Slave | Master | Slave | Master | Slave | |
||
136 | |==============================================================================================| |
||
137 | | T | Polling | Fpclk/2 | Fpclk/2 | NA | NA | NA | NA | |
||
138 | | X |----------------|----------|----------|-----------|----------|-----------|----------| |
||
139 | | / | Interrupt | Fpclk/4 | Fpclk/8 | NA | NA | NA | NA | |
||
140 | | R |----------------|----------|----------|-----------|----------|-----------|----------| |
||
141 | | X | DMA | Fpclk/2 | Fpclk/2 | NA | NA | NA | NA | |
||
142 | |=========|================|==========|==========|===========|==========|===========|==========| |
||
143 | | | Polling | Fpclk/2 | Fpclk/2 | Fpclk/64 | Fpclk/2 | Fpclk/64 | Fpclk/2 | |
||
144 | | |----------------|----------|----------|-----------|----------|-----------|----------| |
||
145 | | R | Interrupt | Fpclk/8 | Fpclk/8 | Fpclk/64 | Fpclk/2 | Fpclk/64 | Fpclk/2 | |
||
146 | | X |----------------|----------|----------|-----------|----------|-----------|----------| |
||
147 | | | DMA | Fpclk/2 | Fpclk/2 | Fpclk/64 | Fpclk/2 | Fpclk/128 | Fpclk/2 | |
||
148 | |=========|================|==========|==========|===========|==========|===========|==========| |
||
149 | | | Polling | Fpclk/2 | Fpclk/4 | NA | NA | Fpclk/2 | Fpclk/64 | |
||
150 | | |----------------|----------|----------|-----------|----------|-----------|----------| |
||
151 | | T | Interrupt | Fpclk/2 | Fpclk/4 | NA | NA | Fpclk/2 | Fpclk/64 | |
||
152 | | X |----------------|----------|----------|-----------|----------|-----------|----------| |
||
153 | | | DMA | Fpclk/2 | Fpclk/2 | NA | NA | Fpclk/2 | Fpclk/128| |
||
154 | +----------------------------------------------------------------------------------------------+ |
||
155 | |||
156 | DataSize = SPI_DATASIZE_16BIT: |
||
157 | +----------------------------------------------------------------------------------------------+ |
||
158 | | | | 2Lines Fullduplex | 2Lines RxOnly | 1Line | |
||
159 | | Process | Transfer mode |---------------------|----------------------|----------------------| |
||
160 | | | | Master | Slave | Master | Slave | Master | Slave | |
||
161 | |==============================================================================================| |
||
162 | | T | Polling | Fpclk/2 | Fpclk/2 | NA | NA | NA | NA | |
||
163 | | X |----------------|----------|----------|-----------|----------|-----------|----------| |
||
164 | | / | Interrupt | Fpclk/4 | Fpclk/4 | NA | NA | NA | NA | |
||
165 | | R |----------------|----------|----------|-----------|----------|-----------|----------| |
||
166 | | X | DMA | Fpclk/2 | Fpclk/2 | NA | NA | NA | NA | |
||
167 | |=========|================|==========|==========|===========|==========|===========|==========| |
||
168 | | | Polling | Fpclk/2 | Fpclk/2 | Fpclk/64 | Fpclk/2 | Fpclk/32 | Fpclk/2 | |
||
169 | | |----------------|----------|----------|-----------|----------|-----------|----------| |
||
170 | | R | Interrupt | Fpclk/4 | Fpclk/4 | Fpclk/64 | Fpclk/2 | Fpclk/64 | Fpclk/2 | |
||
171 | | X |----------------|----------|----------|-----------|----------|-----------|----------| |
||
172 | | | DMA | Fpclk/2 | Fpclk/2 | Fpclk/64 | Fpclk/2 | Fpclk/128 | Fpclk/2 | |
||
173 | |=========|================|==========|==========|===========|==========|===========|==========| |
||
174 | | | Polling | Fpclk/2 | Fpclk/2 | NA | NA | Fpclk/2 | Fpclk/32 | |
||
175 | | |----------------|----------|----------|-----------|----------|-----------|----------| |
||
176 | | T | Interrupt | Fpclk/2 | Fpclk/2 | NA | NA | Fpclk/2 | Fpclk/64 | |
||
177 | | X |----------------|----------|----------|-----------|----------|-----------|----------| |
||
178 | | | DMA | Fpclk/2 | Fpclk/2 | NA | NA | Fpclk/2 | Fpclk/128| |
||
179 | +----------------------------------------------------------------------------------------------+ |
||
180 | @note The max SPI frequency depend on SPI data size (8bits, 16bits), |
||
181 | SPI mode(2 Lines fullduplex, 2 lines RxOnly, 1 line TX/RX) and Process mode (Polling, IT, DMA). |
||
182 | @note |
||
183 | (#) TX/RX processes are HAL_SPI_TransmitReceive(), HAL_SPI_TransmitReceive_IT() and HAL_SPI_TransmitReceive_DMA() |
||
184 | (#) RX processes are HAL_SPI_Receive(), HAL_SPI_Receive_IT() and HAL_SPI_Receive_DMA() |
||
185 | (#) TX processes are HAL_SPI_Transmit(), HAL_SPI_Transmit_IT() and HAL_SPI_Transmit_DMA() |
||
186 | |||
30 | mjames | 187 | ****************************************************************************** |
188 | * @attention |
||
189 | * |
||
50 | mjames | 190 | * <h2><center>© Copyright (c) 2016 STMicroelectronics. |
191 | * All rights reserved.</center></h2> |
||
30 | mjames | 192 | * |
50 | mjames | 193 | * This software component is licensed by ST under BSD 3-Clause license, |
194 | * the "License"; You may not use this file except in compliance with the |
||
195 | * License. You may obtain a copy of the License at: |
||
196 | * opensource.org/licenses/BSD-3-Clause |
||
30 | mjames | 197 | * |
198 | ****************************************************************************** |
||
199 | */ |
||
200 | |||
201 | /* Includes ------------------------------------------------------------------*/ |
||
202 | #include "stm32l1xx_hal.h" |
||
203 | |||
204 | /** @addtogroup STM32L1xx_HAL_Driver |
||
205 | * @{ |
||
206 | */ |
||
207 | |||
208 | /** @defgroup SPI SPI |
||
209 | * @brief SPI HAL module driver |
||
210 | * @{ |
||
211 | */ |
||
212 | #ifdef HAL_SPI_MODULE_ENABLED |
||
213 | |||
214 | /* Private typedef -----------------------------------------------------------*/ |
||
50 | mjames | 215 | /* Private defines -----------------------------------------------------------*/ |
30 | mjames | 216 | /** @defgroup SPI_Private_Constants SPI Private Constants |
217 | * @{ |
||
218 | */ |
||
50 | mjames | 219 | #define SPI_DEFAULT_TIMEOUT 100U |
220 | #define SPI_BSY_FLAG_WORKAROUND_TIMEOUT 1000U /*!< Timeout 1000 µs */ |
||
30 | mjames | 221 | /** |
222 | * @} |
||
223 | */ |
||
224 | |||
50 | mjames | 225 | /* Private macros ------------------------------------------------------------*/ |
30 | mjames | 226 | /* Private variables ---------------------------------------------------------*/ |
227 | /* Private function prototypes -----------------------------------------------*/ |
||
228 | /** @defgroup SPI_Private_Functions SPI Private Functions |
||
229 | * @{ |
||
230 | */ |
||
50 | mjames | 231 | static void SPI_DMATransmitCplt(DMA_HandleTypeDef *hdma); |
232 | static void SPI_DMAReceiveCplt(DMA_HandleTypeDef *hdma); |
||
233 | static void SPI_DMATransmitReceiveCplt(DMA_HandleTypeDef *hdma); |
||
234 | static void SPI_DMAHalfTransmitCplt(DMA_HandleTypeDef *hdma); |
||
235 | static void SPI_DMAHalfReceiveCplt(DMA_HandleTypeDef *hdma); |
||
236 | static void SPI_DMAHalfTransmitReceiveCplt(DMA_HandleTypeDef *hdma); |
||
237 | static void SPI_DMAError(DMA_HandleTypeDef *hdma); |
||
238 | static void SPI_DMAAbortOnError(DMA_HandleTypeDef *hdma); |
||
239 | static void SPI_DMATxAbortCallback(DMA_HandleTypeDef *hdma); |
||
240 | static void SPI_DMARxAbortCallback(DMA_HandleTypeDef *hdma); |
||
241 | static HAL_StatusTypeDef SPI_WaitFlagStateUntilTimeout(SPI_HandleTypeDef *hspi, uint32_t Flag, FlagStatus State, |
||
242 | uint32_t Timeout, uint32_t Tickstart); |
||
243 | static void SPI_TxISR_8BIT(struct __SPI_HandleTypeDef *hspi); |
||
244 | static void SPI_TxISR_16BIT(struct __SPI_HandleTypeDef *hspi); |
||
245 | static void SPI_RxISR_8BIT(struct __SPI_HandleTypeDef *hspi); |
||
246 | static void SPI_RxISR_16BIT(struct __SPI_HandleTypeDef *hspi); |
||
247 | static void SPI_2linesRxISR_8BIT(struct __SPI_HandleTypeDef *hspi); |
||
248 | static void SPI_2linesTxISR_8BIT(struct __SPI_HandleTypeDef *hspi); |
||
249 | static void SPI_2linesTxISR_16BIT(struct __SPI_HandleTypeDef *hspi); |
||
250 | static void SPI_2linesRxISR_16BIT(struct __SPI_HandleTypeDef *hspi); |
||
251 | #if (USE_SPI_CRC != 0U) |
||
252 | static void SPI_RxISR_8BITCRC(struct __SPI_HandleTypeDef *hspi); |
||
253 | static void SPI_RxISR_16BITCRC(struct __SPI_HandleTypeDef *hspi); |
||
254 | static void SPI_2linesRxISR_8BITCRC(struct __SPI_HandleTypeDef *hspi); |
||
255 | static void SPI_2linesRxISR_16BITCRC(struct __SPI_HandleTypeDef *hspi); |
||
256 | #endif /* USE_SPI_CRC */ |
||
257 | static void SPI_AbortRx_ISR(SPI_HandleTypeDef *hspi); |
||
258 | static void SPI_AbortTx_ISR(SPI_HandleTypeDef *hspi); |
||
259 | static void SPI_CloseRxTx_ISR(SPI_HandleTypeDef *hspi); |
||
260 | static void SPI_CloseRx_ISR(SPI_HandleTypeDef *hspi); |
||
261 | static void SPI_CloseTx_ISR(SPI_HandleTypeDef *hspi); |
||
262 | static HAL_StatusTypeDef SPI_EndRxTransaction(SPI_HandleTypeDef *hspi, uint32_t Timeout, uint32_t Tickstart); |
||
263 | static HAL_StatusTypeDef SPI_EndRxTxTransaction(SPI_HandleTypeDef *hspi, uint32_t Timeout, uint32_t Tickstart); |
||
30 | mjames | 264 | /** |
265 | * @} |
||
266 | */ |
||
267 | |||
50 | mjames | 268 | /* Exported functions --------------------------------------------------------*/ |
30 | mjames | 269 | /** @defgroup SPI_Exported_Functions SPI Exported Functions |
270 | * @{ |
||
271 | */ |
||
272 | |||
50 | mjames | 273 | /** @defgroup SPI_Exported_Functions_Group1 Initialization and de-initialization functions |
274 | * @brief Initialization and Configuration functions |
||
275 | * |
||
30 | mjames | 276 | @verbatim |
277 | =============================================================================== |
||
278 | ##### Initialization and de-initialization functions ##### |
||
279 | =============================================================================== |
||
50 | mjames | 280 | [..] This subsection provides a set of functions allowing to initialize and |
281 | de-initialize the SPIx peripheral: |
||
30 | mjames | 282 | |
50 | mjames | 283 | (+) User must implement HAL_SPI_MspInit() function in which he configures |
30 | mjames | 284 | all related peripherals resources (CLOCK, GPIO, DMA, IT and NVIC ). |
285 | |||
50 | mjames | 286 | (+) Call the function HAL_SPI_Init() to configure the selected device with |
30 | mjames | 287 | the selected configuration: |
288 | (++) Mode |
||
50 | mjames | 289 | (++) Direction |
30 | mjames | 290 | (++) Data Size |
291 | (++) Clock Polarity and Phase |
||
292 | (++) NSS Management |
||
293 | (++) BaudRate Prescaler |
||
294 | (++) FirstBit |
||
295 | (++) TIMode |
||
296 | (++) CRC Calculation |
||
297 | (++) CRC Polynomial if CRC enabled |
||
298 | |||
50 | mjames | 299 | (+) Call the function HAL_SPI_DeInit() to restore the default configuration |
300 | of the selected SPIx peripheral. |
||
30 | mjames | 301 | |
302 | @endverbatim |
||
303 | * @{ |
||
304 | */ |
||
305 | |||
306 | /** |
||
50 | mjames | 307 | * @brief Initialize the SPI according to the specified parameters |
308 | * in the SPI_InitTypeDef and initialize the associated handle. |
||
309 | * @param hspi pointer to a SPI_HandleTypeDef structure that contains |
||
310 | * the configuration information for SPI module. |
||
30 | mjames | 311 | * @retval HAL status |
312 | */ |
||
50 | mjames | 313 | HAL_StatusTypeDef HAL_SPI_Init(SPI_HandleTypeDef *hspi) |
30 | mjames | 314 | { |
50 | mjames | 315 | /* Check the SPI handle allocation */ |
316 | if (hspi == NULL) |
||
317 | { |
||
318 | return HAL_ERROR; |
||
319 | } |
||
30 | mjames | 320 | |
50 | mjames | 321 | /* Check the parameters */ |
322 | assert_param(IS_SPI_ALL_INSTANCE(hspi->Instance)); |
||
323 | assert_param(IS_SPI_MODE(hspi->Init.Mode)); |
||
324 | assert_param(IS_SPI_DIRECTION(hspi->Init.Direction)); |
||
325 | assert_param(IS_SPI_DATASIZE(hspi->Init.DataSize)); |
||
326 | assert_param(IS_SPI_NSS(hspi->Init.NSS)); |
||
327 | assert_param(IS_SPI_BAUDRATE_PRESCALER(hspi->Init.BaudRatePrescaler)); |
||
328 | assert_param(IS_SPI_FIRST_BIT(hspi->Init.FirstBit)); |
||
329 | /* TI mode is not supported on all devices in stm32l1xx serie. |
||
330 | TIMode parameter is mandatory equal to SPI_TIMODE_DISABLE if TI mode is not supported */ |
||
331 | assert_param(IS_SPI_TIMODE(hspi->Init.TIMode)); |
||
332 | if (hspi->Init.TIMode == SPI_TIMODE_DISABLE) |
||
333 | { |
||
334 | assert_param(IS_SPI_CPOL(hspi->Init.CLKPolarity)); |
||
335 | assert_param(IS_SPI_CPHA(hspi->Init.CLKPhase)); |
||
336 | |||
337 | if (hspi->Init.Mode == SPI_MODE_MASTER) |
||
338 | { |
||
339 | assert_param(IS_SPI_BAUDRATE_PRESCALER(hspi->Init.BaudRatePrescaler)); |
||
340 | } |
||
341 | else |
||
342 | { |
||
343 | /* Baudrate prescaler not use in Motoraola Slave mode. force to default value */ |
||
344 | hspi->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2; |
||
345 | } |
||
346 | } |
||
347 | else |
||
348 | { |
||
349 | assert_param(IS_SPI_BAUDRATE_PRESCALER(hspi->Init.BaudRatePrescaler)); |
||
350 | |||
351 | /* Force polarity and phase to TI protocaol requirements */ |
||
352 | hspi->Init.CLKPolarity = SPI_POLARITY_LOW; |
||
353 | hspi->Init.CLKPhase = SPI_PHASE_1EDGE; |
||
354 | } |
||
355 | #if (USE_SPI_CRC != 0U) |
||
356 | assert_param(IS_SPI_CRC_CALCULATION(hspi->Init.CRCCalculation)); |
||
357 | if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) |
||
358 | { |
||
359 | assert_param(IS_SPI_CRC_POLYNOMIAL(hspi->Init.CRCPolynomial)); |
||
360 | } |
||
361 | #else |
||
362 | hspi->Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; |
||
363 | #endif /* USE_SPI_CRC */ |
||
364 | |||
365 | if (hspi->State == HAL_SPI_STATE_RESET) |
||
366 | { |
||
367 | /* Allocate lock resource and initialize it */ |
||
368 | hspi->Lock = HAL_UNLOCKED; |
||
369 | |||
370 | #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U) |
||
371 | /* Init the SPI Callback settings */ |
||
372 | hspi->TxCpltCallback = HAL_SPI_TxCpltCallback; /* Legacy weak TxCpltCallback */ |
||
373 | hspi->RxCpltCallback = HAL_SPI_RxCpltCallback; /* Legacy weak RxCpltCallback */ |
||
374 | hspi->TxRxCpltCallback = HAL_SPI_TxRxCpltCallback; /* Legacy weak TxRxCpltCallback */ |
||
375 | hspi->TxHalfCpltCallback = HAL_SPI_TxHalfCpltCallback; /* Legacy weak TxHalfCpltCallback */ |
||
376 | hspi->RxHalfCpltCallback = HAL_SPI_RxHalfCpltCallback; /* Legacy weak RxHalfCpltCallback */ |
||
377 | hspi->TxRxHalfCpltCallback = HAL_SPI_TxRxHalfCpltCallback; /* Legacy weak TxRxHalfCpltCallback */ |
||
378 | hspi->ErrorCallback = HAL_SPI_ErrorCallback; /* Legacy weak ErrorCallback */ |
||
379 | hspi->AbortCpltCallback = HAL_SPI_AbortCpltCallback; /* Legacy weak AbortCpltCallback */ |
||
380 | |||
381 | if (hspi->MspInitCallback == NULL) |
||
382 | { |
||
383 | hspi->MspInitCallback = HAL_SPI_MspInit; /* Legacy weak MspInit */ |
||
384 | } |
||
385 | |||
386 | /* Init the low level hardware : GPIO, CLOCK, NVIC... */ |
||
387 | hspi->MspInitCallback(hspi); |
||
388 | #else |
||
389 | /* Init the low level hardware : GPIO, CLOCK, NVIC... */ |
||
390 | HAL_SPI_MspInit(hspi); |
||
391 | #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ |
||
392 | } |
||
393 | |||
394 | hspi->State = HAL_SPI_STATE_BUSY; |
||
395 | |||
396 | /* Disable the selected SPI peripheral */ |
||
397 | __HAL_SPI_DISABLE(hspi); |
||
398 | |||
399 | /*----------------------- SPIx CR1 & CR2 Configuration ---------------------*/ |
||
400 | /* Configure : SPI Mode, Communication Mode, Data size, Clock polarity and phase, NSS management, |
||
401 | Communication speed, First bit and CRC calculation state */ |
||
402 | WRITE_REG(hspi->Instance->CR1, ((hspi->Init.Mode & (SPI_CR1_MSTR | SPI_CR1_SSI)) | |
||
403 | (hspi->Init.Direction & (SPI_CR1_RXONLY | SPI_CR1_BIDIMODE)) | |
||
404 | (hspi->Init.DataSize & SPI_CR1_DFF) | |
||
405 | (hspi->Init.CLKPolarity & SPI_CR1_CPOL) | |
||
406 | (hspi->Init.CLKPhase & SPI_CR1_CPHA) | |
||
407 | (hspi->Init.NSS & SPI_CR1_SSM) | |
||
408 | (hspi->Init.BaudRatePrescaler & SPI_CR1_BR_Msk) | |
||
409 | (hspi->Init.FirstBit & SPI_CR1_LSBFIRST) | |
||
410 | (hspi->Init.CRCCalculation & SPI_CR1_CRCEN))); |
||
411 | |||
412 | #if defined(SPI_CR2_FRF) |
||
413 | /* Configure : NSS management, TI Mode */ |
||
414 | WRITE_REG(hspi->Instance->CR2, (((hspi->Init.NSS >> 16U) & SPI_CR2_SSOE) | (hspi->Init.TIMode & SPI_CR2_FRF))); |
||
415 | #else |
||
416 | /* Configure : NSS management */ |
||
417 | WRITE_REG(hspi->Instance->CR2, ((hspi->Init.NSS >> 16U) & SPI_CR2_SSOE)); |
||
418 | #endif |
||
419 | |||
420 | #if (USE_SPI_CRC != 0U) |
||
421 | /*---------------------------- SPIx CRCPOLY Configuration ------------------*/ |
||
422 | /* Configure : CRC Polynomial */ |
||
423 | if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) |
||
424 | { |
||
425 | WRITE_REG(hspi->Instance->CRCPR, (hspi->Init.CRCPolynomial & SPI_CRCPR_CRCPOLY_Msk)); |
||
426 | } |
||
427 | #endif /* USE_SPI_CRC */ |
||
428 | |||
429 | #if defined(SPI_I2SCFGR_I2SMOD) |
||
430 | /* Activate the SPI mode (Make sure that I2SMOD bit in I2SCFGR register is reset) */ |
||
431 | CLEAR_BIT(hspi->Instance->I2SCFGR, SPI_I2SCFGR_I2SMOD); |
||
432 | #endif /* SPI_I2SCFGR_I2SMOD */ |
||
433 | |||
434 | hspi->ErrorCode = HAL_SPI_ERROR_NONE; |
||
435 | hspi->State = HAL_SPI_STATE_READY; |
||
436 | |||
437 | return HAL_OK; |
||
30 | mjames | 438 | } |
439 | |||
440 | /** |
||
50 | mjames | 441 | * @brief De-Initialize the SPI peripheral. |
442 | * @param hspi pointer to a SPI_HandleTypeDef structure that contains |
||
443 | * the configuration information for SPI module. |
||
30 | mjames | 444 | * @retval HAL status |
445 | */ |
||
446 | HAL_StatusTypeDef HAL_SPI_DeInit(SPI_HandleTypeDef *hspi) |
||
447 | { |
||
448 | /* Check the SPI handle allocation */ |
||
50 | mjames | 449 | if (hspi == NULL) |
30 | mjames | 450 | { |
451 | return HAL_ERROR; |
||
452 | } |
||
453 | |||
50 | mjames | 454 | /* Check SPI Instance parameter */ |
455 | assert_param(IS_SPI_ALL_INSTANCE(hspi->Instance)); |
||
456 | |||
457 | hspi->State = HAL_SPI_STATE_BUSY; |
||
458 | |||
30 | mjames | 459 | /* Disable the SPI Peripheral Clock */ |
460 | __HAL_SPI_DISABLE(hspi); |
||
461 | |||
50 | mjames | 462 | #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U) |
463 | if (hspi->MspDeInitCallback == NULL) |
||
464 | { |
||
465 | hspi->MspDeInitCallback = HAL_SPI_MspDeInit; /* Legacy weak MspDeInit */ |
||
466 | } |
||
467 | |||
30 | mjames | 468 | /* DeInit the low level hardware: GPIO, CLOCK, NVIC... */ |
50 | mjames | 469 | hspi->MspDeInitCallback(hspi); |
470 | #else |
||
471 | /* DeInit the low level hardware: GPIO, CLOCK, NVIC... */ |
||
30 | mjames | 472 | HAL_SPI_MspDeInit(hspi); |
50 | mjames | 473 | #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ |
30 | mjames | 474 | |
475 | hspi->ErrorCode = HAL_SPI_ERROR_NONE; |
||
476 | hspi->State = HAL_SPI_STATE_RESET; |
||
477 | |||
478 | /* Release Lock */ |
||
479 | __HAL_UNLOCK(hspi); |
||
480 | |||
481 | return HAL_OK; |
||
482 | } |
||
483 | |||
484 | /** |
||
50 | mjames | 485 | * @brief Initialize the SPI MSP. |
486 | * @param hspi pointer to a SPI_HandleTypeDef structure that contains |
||
487 | * the configuration information for SPI module. |
||
30 | mjames | 488 | * @retval None |
489 | */ |
||
50 | mjames | 490 | __weak void HAL_SPI_MspInit(SPI_HandleTypeDef *hspi) |
491 | { |
||
30 | mjames | 492 | /* Prevent unused argument(s) compilation warning */ |
493 | UNUSED(hspi); |
||
494 | |||
50 | mjames | 495 | /* NOTE : This function should not be modified, when the callback is needed, |
496 | the HAL_SPI_MspInit should be implemented in the user file |
||
30 | mjames | 497 | */ |
498 | } |
||
499 | |||
500 | /** |
||
50 | mjames | 501 | * @brief De-Initialize the SPI MSP. |
502 | * @param hspi pointer to a SPI_HandleTypeDef structure that contains |
||
503 | * the configuration information for SPI module. |
||
30 | mjames | 504 | * @retval None |
505 | */ |
||
50 | mjames | 506 | __weak void HAL_SPI_MspDeInit(SPI_HandleTypeDef *hspi) |
30 | mjames | 507 | { |
508 | /* Prevent unused argument(s) compilation warning */ |
||
509 | UNUSED(hspi); |
||
510 | |||
50 | mjames | 511 | /* NOTE : This function should not be modified, when the callback is needed, |
512 | the HAL_SPI_MspDeInit should be implemented in the user file |
||
30 | mjames | 513 | */ |
514 | } |
||
515 | |||
50 | mjames | 516 | #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U) |
30 | mjames | 517 | /** |
50 | mjames | 518 | * @brief Register a User SPI Callback |
519 | * To be used instead of the weak predefined callback |
||
520 | * @param hspi Pointer to a SPI_HandleTypeDef structure that contains |
||
521 | * the configuration information for the specified SPI. |
||
522 | * @param CallbackID ID of the callback to be registered |
||
523 | * @param pCallback pointer to the Callback function |
||
524 | * @retval HAL status |
||
525 | */ |
||
526 | HAL_StatusTypeDef HAL_SPI_RegisterCallback(SPI_HandleTypeDef *hspi, HAL_SPI_CallbackIDTypeDef CallbackID, |
||
527 | pSPI_CallbackTypeDef pCallback) |
||
528 | { |
||
529 | HAL_StatusTypeDef status = HAL_OK; |
||
530 | |||
531 | if (pCallback == NULL) |
||
532 | { |
||
533 | /* Update the error code */ |
||
534 | hspi->ErrorCode |= HAL_SPI_ERROR_INVALID_CALLBACK; |
||
535 | |||
536 | return HAL_ERROR; |
||
537 | } |
||
538 | /* Process locked */ |
||
539 | __HAL_LOCK(hspi); |
||
540 | |||
541 | if (HAL_SPI_STATE_READY == hspi->State) |
||
542 | { |
||
543 | switch (CallbackID) |
||
544 | { |
||
545 | case HAL_SPI_TX_COMPLETE_CB_ID : |
||
546 | hspi->TxCpltCallback = pCallback; |
||
547 | break; |
||
548 | |||
549 | case HAL_SPI_RX_COMPLETE_CB_ID : |
||
550 | hspi->RxCpltCallback = pCallback; |
||
551 | break; |
||
552 | |||
553 | case HAL_SPI_TX_RX_COMPLETE_CB_ID : |
||
554 | hspi->TxRxCpltCallback = pCallback; |
||
555 | break; |
||
556 | |||
557 | case HAL_SPI_TX_HALF_COMPLETE_CB_ID : |
||
558 | hspi->TxHalfCpltCallback = pCallback; |
||
559 | break; |
||
560 | |||
561 | case HAL_SPI_RX_HALF_COMPLETE_CB_ID : |
||
562 | hspi->RxHalfCpltCallback = pCallback; |
||
563 | break; |
||
564 | |||
565 | case HAL_SPI_TX_RX_HALF_COMPLETE_CB_ID : |
||
566 | hspi->TxRxHalfCpltCallback = pCallback; |
||
567 | break; |
||
568 | |||
569 | case HAL_SPI_ERROR_CB_ID : |
||
570 | hspi->ErrorCallback = pCallback; |
||
571 | break; |
||
572 | |||
573 | case HAL_SPI_ABORT_CB_ID : |
||
574 | hspi->AbortCpltCallback = pCallback; |
||
575 | break; |
||
576 | |||
577 | case HAL_SPI_MSPINIT_CB_ID : |
||
578 | hspi->MspInitCallback = pCallback; |
||
579 | break; |
||
580 | |||
581 | case HAL_SPI_MSPDEINIT_CB_ID : |
||
582 | hspi->MspDeInitCallback = pCallback; |
||
583 | break; |
||
584 | |||
585 | default : |
||
586 | /* Update the error code */ |
||
587 | SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_INVALID_CALLBACK); |
||
588 | |||
589 | /* Return error status */ |
||
590 | status = HAL_ERROR; |
||
591 | break; |
||
592 | } |
||
593 | } |
||
594 | else if (HAL_SPI_STATE_RESET == hspi->State) |
||
595 | { |
||
596 | switch (CallbackID) |
||
597 | { |
||
598 | case HAL_SPI_MSPINIT_CB_ID : |
||
599 | hspi->MspInitCallback = pCallback; |
||
600 | break; |
||
601 | |||
602 | case HAL_SPI_MSPDEINIT_CB_ID : |
||
603 | hspi->MspDeInitCallback = pCallback; |
||
604 | break; |
||
605 | |||
606 | default : |
||
607 | /* Update the error code */ |
||
608 | SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_INVALID_CALLBACK); |
||
609 | |||
610 | /* Return error status */ |
||
611 | status = HAL_ERROR; |
||
612 | break; |
||
613 | } |
||
614 | } |
||
615 | else |
||
616 | { |
||
617 | /* Update the error code */ |
||
618 | SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_INVALID_CALLBACK); |
||
619 | |||
620 | /* Return error status */ |
||
621 | status = HAL_ERROR; |
||
622 | } |
||
623 | |||
624 | /* Release Lock */ |
||
625 | __HAL_UNLOCK(hspi); |
||
626 | return status; |
||
627 | } |
||
628 | |||
629 | /** |
||
630 | * @brief Unregister an SPI Callback |
||
631 | * SPI callback is redirected to the weak predefined callback |
||
632 | * @param hspi Pointer to a SPI_HandleTypeDef structure that contains |
||
633 | * the configuration information for the specified SPI. |
||
634 | * @param CallbackID ID of the callback to be unregistered |
||
635 | * @retval HAL status |
||
636 | */ |
||
637 | HAL_StatusTypeDef HAL_SPI_UnRegisterCallback(SPI_HandleTypeDef *hspi, HAL_SPI_CallbackIDTypeDef CallbackID) |
||
638 | { |
||
639 | HAL_StatusTypeDef status = HAL_OK; |
||
640 | |||
641 | /* Process locked */ |
||
642 | __HAL_LOCK(hspi); |
||
643 | |||
644 | if (HAL_SPI_STATE_READY == hspi->State) |
||
645 | { |
||
646 | switch (CallbackID) |
||
647 | { |
||
648 | case HAL_SPI_TX_COMPLETE_CB_ID : |
||
649 | hspi->TxCpltCallback = HAL_SPI_TxCpltCallback; /* Legacy weak TxCpltCallback */ |
||
650 | break; |
||
651 | |||
652 | case HAL_SPI_RX_COMPLETE_CB_ID : |
||
653 | hspi->RxCpltCallback = HAL_SPI_RxCpltCallback; /* Legacy weak RxCpltCallback */ |
||
654 | break; |
||
655 | |||
656 | case HAL_SPI_TX_RX_COMPLETE_CB_ID : |
||
657 | hspi->TxRxCpltCallback = HAL_SPI_TxRxCpltCallback; /* Legacy weak TxRxCpltCallback */ |
||
658 | break; |
||
659 | |||
660 | case HAL_SPI_TX_HALF_COMPLETE_CB_ID : |
||
661 | hspi->TxHalfCpltCallback = HAL_SPI_TxHalfCpltCallback; /* Legacy weak TxHalfCpltCallback */ |
||
662 | break; |
||
663 | |||
664 | case HAL_SPI_RX_HALF_COMPLETE_CB_ID : |
||
665 | hspi->RxHalfCpltCallback = HAL_SPI_RxHalfCpltCallback; /* Legacy weak RxHalfCpltCallback */ |
||
666 | break; |
||
667 | |||
668 | case HAL_SPI_TX_RX_HALF_COMPLETE_CB_ID : |
||
669 | hspi->TxRxHalfCpltCallback = HAL_SPI_TxRxHalfCpltCallback; /* Legacy weak TxRxHalfCpltCallback */ |
||
670 | break; |
||
671 | |||
672 | case HAL_SPI_ERROR_CB_ID : |
||
673 | hspi->ErrorCallback = HAL_SPI_ErrorCallback; /* Legacy weak ErrorCallback */ |
||
674 | break; |
||
675 | |||
676 | case HAL_SPI_ABORT_CB_ID : |
||
677 | hspi->AbortCpltCallback = HAL_SPI_AbortCpltCallback; /* Legacy weak AbortCpltCallback */ |
||
678 | break; |
||
679 | |||
680 | case HAL_SPI_MSPINIT_CB_ID : |
||
681 | hspi->MspInitCallback = HAL_SPI_MspInit; /* Legacy weak MspInit */ |
||
682 | break; |
||
683 | |||
684 | case HAL_SPI_MSPDEINIT_CB_ID : |
||
685 | hspi->MspDeInitCallback = HAL_SPI_MspDeInit; /* Legacy weak MspDeInit */ |
||
686 | break; |
||
687 | |||
688 | default : |
||
689 | /* Update the error code */ |
||
690 | SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_INVALID_CALLBACK); |
||
691 | |||
692 | /* Return error status */ |
||
693 | status = HAL_ERROR; |
||
694 | break; |
||
695 | } |
||
696 | } |
||
697 | else if (HAL_SPI_STATE_RESET == hspi->State) |
||
698 | { |
||
699 | switch (CallbackID) |
||
700 | { |
||
701 | case HAL_SPI_MSPINIT_CB_ID : |
||
702 | hspi->MspInitCallback = HAL_SPI_MspInit; /* Legacy weak MspInit */ |
||
703 | break; |
||
704 | |||
705 | case HAL_SPI_MSPDEINIT_CB_ID : |
||
706 | hspi->MspDeInitCallback = HAL_SPI_MspDeInit; /* Legacy weak MspDeInit */ |
||
707 | break; |
||
708 | |||
709 | default : |
||
710 | /* Update the error code */ |
||
711 | SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_INVALID_CALLBACK); |
||
712 | |||
713 | /* Return error status */ |
||
714 | status = HAL_ERROR; |
||
715 | break; |
||
716 | } |
||
717 | } |
||
718 | else |
||
719 | { |
||
720 | /* Update the error code */ |
||
721 | SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_INVALID_CALLBACK); |
||
722 | |||
723 | /* Return error status */ |
||
724 | status = HAL_ERROR; |
||
725 | } |
||
726 | |||
727 | /* Release Lock */ |
||
728 | __HAL_UNLOCK(hspi); |
||
729 | return status; |
||
730 | } |
||
731 | #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ |
||
732 | /** |
||
30 | mjames | 733 | * @} |
734 | */ |
||
735 | |||
736 | /** @defgroup SPI_Exported_Functions_Group2 IO operation functions |
||
50 | mjames | 737 | * @brief Data transfers functions |
738 | * |
||
30 | mjames | 739 | @verbatim |
740 | ============================================================================== |
||
741 | ##### IO operation functions ##### |
||
742 | =============================================================================== |
||
50 | mjames | 743 | [..] |
30 | mjames | 744 | This subsection provides a set of functions allowing to manage the SPI |
745 | data transfers. |
||
746 | |||
747 | [..] The SPI supports master and slave mode : |
||
748 | |||
749 | (#) There are two modes of transfer: |
||
750 | (++) Blocking mode: The communication is performed in polling mode. |
||
751 | The HAL status of all data processing is returned by the same function |
||
752 | after finishing transfer. |
||
753 | (++) No-Blocking mode: The communication is performed using Interrupts |
||
754 | or DMA, These APIs return the HAL status. |
||
50 | mjames | 755 | The end of the data processing will be indicated through the |
756 | dedicated SPI IRQ when using Interrupt mode or the DMA IRQ when |
||
30 | mjames | 757 | using DMA mode. |
50 | mjames | 758 | The HAL_SPI_TxCpltCallback(), HAL_SPI_RxCpltCallback() and HAL_SPI_TxRxCpltCallback() user callbacks |
759 | will be executed respectively at the end of the transmit or Receive process |
||
30 | mjames | 760 | The HAL_SPI_ErrorCallback()user callback will be executed when a communication error is detected |
761 | |||
762 | (#) APIs provided for these 2 transfer modes (Blocking mode or Non blocking mode using either Interrupt or DMA) |
||
763 | exist for 1Line (simplex) and 2Lines (full duplex) modes. |
||
764 | |||
765 | @endverbatim |
||
766 | * @{ |
||
767 | */ |
||
768 | |||
769 | /** |
||
50 | mjames | 770 | * @brief Transmit an amount of data in blocking mode. |
771 | * @param hspi pointer to a SPI_HandleTypeDef structure that contains |
||
772 | * the configuration information for SPI module. |
||
773 | * @param pData pointer to data buffer |
||
774 | * @param Size amount of data to be sent |
||
775 | * @param Timeout Timeout duration |
||
30 | mjames | 776 | * @retval HAL status |
777 | */ |
||
778 | HAL_StatusTypeDef HAL_SPI_Transmit(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout) |
||
779 | { |
||
50 | mjames | 780 | uint32_t tickstart; |
781 | HAL_StatusTypeDef errorcode = HAL_OK; |
||
782 | uint16_t initial_TxXferCount; |
||
30 | mjames | 783 | |
50 | mjames | 784 | /* Check Direction parameter */ |
785 | assert_param(IS_SPI_DIRECTION_2LINES_OR_1LINE(hspi->Init.Direction)); |
||
786 | |||
787 | /* Process Locked */ |
||
788 | __HAL_LOCK(hspi); |
||
789 | |||
790 | /* Init tickstart for timeout management*/ |
||
791 | tickstart = HAL_GetTick(); |
||
792 | initial_TxXferCount = Size; |
||
793 | |||
794 | if (hspi->State != HAL_SPI_STATE_READY) |
||
30 | mjames | 795 | { |
50 | mjames | 796 | errorcode = HAL_BUSY; |
797 | goto error; |
||
798 | } |
||
30 | mjames | 799 | |
50 | mjames | 800 | if ((pData == NULL) || (Size == 0U)) |
801 | { |
||
802 | errorcode = HAL_ERROR; |
||
803 | goto error; |
||
804 | } |
||
30 | mjames | 805 | |
50 | mjames | 806 | /* Set the transaction information */ |
807 | hspi->State = HAL_SPI_STATE_BUSY_TX; |
||
808 | hspi->ErrorCode = HAL_SPI_ERROR_NONE; |
||
809 | hspi->pTxBuffPtr = (uint8_t *)pData; |
||
810 | hspi->TxXferSize = Size; |
||
811 | hspi->TxXferCount = Size; |
||
30 | mjames | 812 | |
50 | mjames | 813 | /*Init field not used in handle to zero */ |
814 | hspi->pRxBuffPtr = (uint8_t *)NULL; |
||
815 | hspi->RxXferSize = 0U; |
||
816 | hspi->RxXferCount = 0U; |
||
817 | hspi->TxISR = NULL; |
||
818 | hspi->RxISR = NULL; |
||
30 | mjames | 819 | |
50 | mjames | 820 | /* Configure communication direction : 1Line */ |
821 | if (hspi->Init.Direction == SPI_DIRECTION_1LINE) |
||
822 | { |
||
823 | /* Disable SPI Peripheral before set 1Line direction (BIDIOE bit) */ |
||
824 | __HAL_SPI_DISABLE(hspi); |
||
825 | SPI_1LINE_TX(hspi); |
||
826 | } |
||
30 | mjames | 827 | |
50 | mjames | 828 | #if (USE_SPI_CRC != 0U) |
829 | /* Reset CRC Calculation */ |
||
830 | if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) |
||
831 | { |
||
832 | SPI_RESET_CRC(hspi); |
||
833 | } |
||
834 | #endif /* USE_SPI_CRC */ |
||
30 | mjames | 835 | |
50 | mjames | 836 | /* Check if the SPI is already enabled */ |
837 | if ((hspi->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE) |
||
838 | { |
||
839 | /* Enable SPI peripheral */ |
||
840 | __HAL_SPI_ENABLE(hspi); |
||
841 | } |
||
30 | mjames | 842 | |
50 | mjames | 843 | /* Transmit data in 16 Bit mode */ |
844 | if (hspi->Init.DataSize == SPI_DATASIZE_16BIT) |
||
845 | { |
||
846 | if ((hspi->Init.Mode == SPI_MODE_SLAVE) || (initial_TxXferCount == 0x01U)) |
||
30 | mjames | 847 | { |
50 | mjames | 848 | hspi->Instance->DR = *((uint16_t *)hspi->pTxBuffPtr); |
849 | hspi->pTxBuffPtr += sizeof(uint16_t); |
||
850 | hspi->TxXferCount--; |
||
30 | mjames | 851 | } |
50 | mjames | 852 | /* Transmit data in 16 Bit mode */ |
853 | while (hspi->TxXferCount > 0U) |
||
30 | mjames | 854 | { |
50 | mjames | 855 | /* Wait until TXE flag is set to send data */ |
856 | if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXE)) |
||
30 | mjames | 857 | { |
50 | mjames | 858 | hspi->Instance->DR = *((uint16_t *)hspi->pTxBuffPtr); |
859 | hspi->pTxBuffPtr += sizeof(uint16_t); |
||
30 | mjames | 860 | hspi->TxXferCount--; |
861 | } |
||
50 | mjames | 862 | else |
30 | mjames | 863 | { |
50 | mjames | 864 | /* Timeout management */ |
865 | if ((((HAL_GetTick() - tickstart) >= Timeout) && (Timeout != HAL_MAX_DELAY)) || (Timeout == 0U)) |
||
866 | { |
||
867 | errorcode = HAL_TIMEOUT; |
||
868 | goto error; |
||
30 | mjames | 869 | } |
870 | } |
||
871 | } |
||
50 | mjames | 872 | } |
873 | /* Transmit data in 8 Bit mode */ |
||
874 | else |
||
875 | { |
||
876 | if ((hspi->Init.Mode == SPI_MODE_SLAVE) || (initial_TxXferCount == 0x01U)) |
||
30 | mjames | 877 | { |
50 | mjames | 878 | *((__IO uint8_t *)&hspi->Instance->DR) = (*hspi->pTxBuffPtr); |
879 | hspi->pTxBuffPtr += sizeof(uint8_t); |
||
880 | hspi->TxXferCount--; |
||
881 | } |
||
882 | while (hspi->TxXferCount > 0U) |
||
883 | { |
||
884 | /* Wait until TXE flag is set to send data */ |
||
885 | if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXE)) |
||
30 | mjames | 886 | { |
50 | mjames | 887 | *((__IO uint8_t *)&hspi->Instance->DR) = (*hspi->pTxBuffPtr); |
888 | hspi->pTxBuffPtr += sizeof(uint8_t); |
||
30 | mjames | 889 | hspi->TxXferCount--; |
890 | } |
||
50 | mjames | 891 | else |
30 | mjames | 892 | { |
50 | mjames | 893 | /* Timeout management */ |
894 | if ((((HAL_GetTick() - tickstart) >= Timeout) && (Timeout != HAL_MAX_DELAY)) || (Timeout == 0U)) |
||
895 | { |
||
896 | errorcode = HAL_TIMEOUT; |
||
897 | goto error; |
||
30 | mjames | 898 | } |
899 | } |
||
900 | } |
||
50 | mjames | 901 | } |
902 | #if (USE_SPI_CRC != 0U) |
||
903 | /* Enable CRC Transmission */ |
||
904 | if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) |
||
905 | { |
||
906 | SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT); |
||
907 | } |
||
908 | #endif /* USE_SPI_CRC */ |
||
30 | mjames | 909 | |
50 | mjames | 910 | /* Check the end of the transaction */ |
911 | if (SPI_EndRxTxTransaction(hspi, Timeout, tickstart) != HAL_OK) |
||
912 | { |
||
913 | hspi->ErrorCode = HAL_SPI_ERROR_FLAG; |
||
914 | } |
||
30 | mjames | 915 | |
50 | mjames | 916 | /* Clear overrun flag in 2 Lines communication mode because received is not read */ |
917 | if (hspi->Init.Direction == SPI_DIRECTION_2LINES) |
||
918 | { |
||
919 | __HAL_SPI_CLEAR_OVRFLAG(hspi); |
||
920 | } |
||
30 | mjames | 921 | |
50 | mjames | 922 | if (hspi->ErrorCode != HAL_SPI_ERROR_NONE) |
30 | mjames | 923 | { |
50 | mjames | 924 | errorcode = HAL_ERROR; |
30 | mjames | 925 | } |
50 | mjames | 926 | |
927 | error: |
||
928 | hspi->State = HAL_SPI_STATE_READY; |
||
929 | /* Process Unlocked */ |
||
930 | __HAL_UNLOCK(hspi); |
||
931 | return errorcode; |
||
30 | mjames | 932 | } |
933 | |||
934 | /** |
||
50 | mjames | 935 | * @brief Receive an amount of data in blocking mode. |
936 | * @param hspi pointer to a SPI_HandleTypeDef structure that contains |
||
937 | * the configuration information for SPI module. |
||
938 | * @param pData pointer to data buffer |
||
939 | * @param Size amount of data to be received |
||
940 | * @param Timeout Timeout duration |
||
30 | mjames | 941 | * @retval HAL status |
942 | */ |
||
943 | HAL_StatusTypeDef HAL_SPI_Receive(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout) |
||
944 | { |
||
61 | mjames | 945 | #if (USE_SPI_CRC != 0U) |
946 | __IO uint32_t tmpreg = 0U; |
||
947 | #endif /* USE_SPI_CRC */ |
||
50 | mjames | 948 | uint32_t tickstart; |
949 | HAL_StatusTypeDef errorcode = HAL_OK; |
||
30 | mjames | 950 | |
50 | mjames | 951 | if ((hspi->Init.Mode == SPI_MODE_MASTER) && (hspi->Init.Direction == SPI_DIRECTION_2LINES)) |
30 | mjames | 952 | { |
50 | mjames | 953 | hspi->State = HAL_SPI_STATE_BUSY_RX; |
954 | /* Call transmit-receive function to send Dummy data on Tx line and generate clock on CLK line */ |
||
955 | return HAL_SPI_TransmitReceive(hspi, pData, pData, Size, Timeout); |
||
956 | } |
||
30 | mjames | 957 | |
50 | mjames | 958 | /* Process Locked */ |
959 | __HAL_LOCK(hspi); |
||
30 | mjames | 960 | |
50 | mjames | 961 | /* Init tickstart for timeout management*/ |
962 | tickstart = HAL_GetTick(); |
||
30 | mjames | 963 | |
50 | mjames | 964 | if (hspi->State != HAL_SPI_STATE_READY) |
965 | { |
||
966 | errorcode = HAL_BUSY; |
||
967 | goto error; |
||
968 | } |
||
30 | mjames | 969 | |
50 | mjames | 970 | if ((pData == NULL) || (Size == 0U)) |
971 | { |
||
972 | errorcode = HAL_ERROR; |
||
973 | goto error; |
||
974 | } |
||
30 | mjames | 975 | |
50 | mjames | 976 | /* Set the transaction information */ |
977 | hspi->State = HAL_SPI_STATE_BUSY_RX; |
||
978 | hspi->ErrorCode = HAL_SPI_ERROR_NONE; |
||
979 | hspi->pRxBuffPtr = (uint8_t *)pData; |
||
980 | hspi->RxXferSize = Size; |
||
981 | hspi->RxXferCount = Size; |
||
30 | mjames | 982 | |
50 | mjames | 983 | /*Init field not used in handle to zero */ |
984 | hspi->pTxBuffPtr = (uint8_t *)NULL; |
||
985 | hspi->TxXferSize = 0U; |
||
986 | hspi->TxXferCount = 0U; |
||
987 | hspi->RxISR = NULL; |
||
988 | hspi->TxISR = NULL; |
||
30 | mjames | 989 | |
50 | mjames | 990 | #if (USE_SPI_CRC != 0U) |
991 | /* Reset CRC Calculation */ |
||
992 | if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) |
||
993 | { |
||
994 | SPI_RESET_CRC(hspi); |
||
995 | /* this is done to handle the CRCNEXT before the latest data */ |
||
996 | hspi->RxXferCount--; |
||
997 | } |
||
998 | #endif /* USE_SPI_CRC */ |
||
30 | mjames | 999 | |
50 | mjames | 1000 | /* Configure communication direction: 1Line */ |
1001 | if (hspi->Init.Direction == SPI_DIRECTION_1LINE) |
||
1002 | { |
||
1003 | /* Disable SPI Peripheral before set 1Line direction (BIDIOE bit) */ |
||
1004 | __HAL_SPI_DISABLE(hspi); |
||
1005 | SPI_1LINE_RX(hspi); |
||
1006 | } |
||
30 | mjames | 1007 | |
50 | mjames | 1008 | /* Check if the SPI is already enabled */ |
1009 | if ((hspi->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE) |
||
1010 | { |
||
1011 | /* Enable SPI peripheral */ |
||
1012 | __HAL_SPI_ENABLE(hspi); |
||
1013 | } |
||
1014 | |||
1015 | /* Receive data in 8 Bit mode */ |
||
1016 | if (hspi->Init.DataSize == SPI_DATASIZE_8BIT) |
||
1017 | { |
||
1018 | /* Transfer loop */ |
||
1019 | while (hspi->RxXferCount > 0U) |
||
30 | mjames | 1020 | { |
50 | mjames | 1021 | /* Check the RXNE flag */ |
1022 | if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_RXNE)) |
||
30 | mjames | 1023 | { |
50 | mjames | 1024 | /* read the received data */ |
1025 | (* (uint8_t *)hspi->pRxBuffPtr) = *(__IO uint8_t *)&hspi->Instance->DR; |
||
1026 | hspi->pRxBuffPtr += sizeof(uint8_t); |
||
30 | mjames | 1027 | hspi->RxXferCount--; |
1028 | } |
||
50 | mjames | 1029 | else |
30 | mjames | 1030 | { |
50 | mjames | 1031 | /* Timeout management */ |
1032 | if ((((HAL_GetTick() - tickstart) >= Timeout) && (Timeout != HAL_MAX_DELAY)) || (Timeout == 0U)) |
||
1033 | { |
||
1034 | errorcode = HAL_TIMEOUT; |
||
1035 | goto error; |
||
1036 | } |
||
30 | mjames | 1037 | } |
1038 | } |
||
50 | mjames | 1039 | } |
1040 | else |
||
1041 | { |
||
1042 | /* Transfer loop */ |
||
1043 | while (hspi->RxXferCount > 0U) |
||
30 | mjames | 1044 | { |
50 | mjames | 1045 | /* Check the RXNE flag */ |
1046 | if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_RXNE)) |
||
30 | mjames | 1047 | { |
50 | mjames | 1048 | *((uint16_t *)hspi->pRxBuffPtr) = (uint16_t)hspi->Instance->DR; |
1049 | hspi->pRxBuffPtr += sizeof(uint16_t); |
||
30 | mjames | 1050 | hspi->RxXferCount--; |
1051 | } |
||
50 | mjames | 1052 | else |
30 | mjames | 1053 | { |
50 | mjames | 1054 | /* Timeout management */ |
1055 | if ((((HAL_GetTick() - tickstart) >= Timeout) && (Timeout != HAL_MAX_DELAY)) || (Timeout == 0U)) |
||
1056 | { |
||
1057 | errorcode = HAL_TIMEOUT; |
||
1058 | goto error; |
||
1059 | } |
||
30 | mjames | 1060 | } |
1061 | } |
||
50 | mjames | 1062 | } |
30 | mjames | 1063 | |
50 | mjames | 1064 | #if (USE_SPI_CRC != 0U) |
1065 | /* Handle the CRC Transmission */ |
||
1066 | if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) |
||
1067 | { |
||
1068 | /* freeze the CRC before the latest data */ |
||
1069 | SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT); |
||
1070 | |||
1071 | /* Read the latest data */ |
||
1072 | if (SPI_WaitFlagStateUntilTimeout(hspi, SPI_FLAG_RXNE, SET, Timeout, tickstart) != HAL_OK) |
||
1073 | { |
||
1074 | /* the latest data has not been received */ |
||
1075 | errorcode = HAL_TIMEOUT; |
||
1076 | goto error; |
||
30 | mjames | 1077 | } |
1078 | |||
50 | mjames | 1079 | /* Receive last data in 16 Bit mode */ |
1080 | if (hspi->Init.DataSize == SPI_DATASIZE_16BIT) |
||
30 | mjames | 1081 | { |
50 | mjames | 1082 | *((uint16_t *)hspi->pRxBuffPtr) = (uint16_t)hspi->Instance->DR; |
30 | mjames | 1083 | } |
50 | mjames | 1084 | /* Receive last data in 8 Bit mode */ |
30 | mjames | 1085 | else |
1086 | { |
||
50 | mjames | 1087 | (*(uint8_t *)hspi->pRxBuffPtr) = *(__IO uint8_t *)&hspi->Instance->DR; |
30 | mjames | 1088 | } |
1089 | |||
50 | mjames | 1090 | /* Wait the CRC data */ |
1091 | if (SPI_WaitFlagStateUntilTimeout(hspi, SPI_FLAG_RXNE, SET, Timeout, tickstart) != HAL_OK) |
||
30 | mjames | 1092 | { |
1093 | SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC); |
||
50 | mjames | 1094 | errorcode = HAL_TIMEOUT; |
1095 | goto error; |
||
30 | mjames | 1096 | } |
1097 | |||
50 | mjames | 1098 | /* Read CRC to Flush DR and RXNE flag */ |
61 | mjames | 1099 | tmpreg = READ_REG(hspi->Instance->DR); |
1100 | /* To avoid GCC warning */ |
||
1101 | UNUSED(tmpreg); |
||
50 | mjames | 1102 | } |
1103 | #endif /* USE_SPI_CRC */ |
||
30 | mjames | 1104 | |
50 | mjames | 1105 | /* Check the end of the transaction */ |
1106 | if (SPI_EndRxTransaction(hspi, Timeout, tickstart) != HAL_OK) |
||
1107 | { |
||
1108 | hspi->ErrorCode = HAL_SPI_ERROR_FLAG; |
||
30 | mjames | 1109 | } |
50 | mjames | 1110 | |
1111 | #if (USE_SPI_CRC != 0U) |
||
1112 | /* Check if CRC error occurred */ |
||
1113 | if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_CRCERR)) |
||
30 | mjames | 1114 | { |
50 | mjames | 1115 | SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC); |
1116 | __HAL_SPI_CLEAR_CRCERRFLAG(hspi); |
||
30 | mjames | 1117 | } |
50 | mjames | 1118 | #endif /* USE_SPI_CRC */ |
1119 | |||
1120 | if (hspi->ErrorCode != HAL_SPI_ERROR_NONE) |
||
1121 | { |
||
1122 | errorcode = HAL_ERROR; |
||
1123 | } |
||
1124 | |||
1125 | error : |
||
1126 | hspi->State = HAL_SPI_STATE_READY; |
||
1127 | __HAL_UNLOCK(hspi); |
||
1128 | return errorcode; |
||
30 | mjames | 1129 | } |
1130 | |||
1131 | /** |
||
50 | mjames | 1132 | * @brief Transmit and Receive an amount of data in blocking mode. |
1133 | * @param hspi pointer to a SPI_HandleTypeDef structure that contains |
||
1134 | * the configuration information for SPI module. |
||
1135 | * @param pTxData pointer to transmission data buffer |
||
1136 | * @param pRxData pointer to reception data buffer |
||
1137 | * @param Size amount of data to be sent and received |
||
1138 | * @param Timeout Timeout duration |
||
30 | mjames | 1139 | * @retval HAL status |
1140 | */ |
||
50 | mjames | 1141 | HAL_StatusTypeDef HAL_SPI_TransmitReceive(SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size, |
1142 | uint32_t Timeout) |
||
30 | mjames | 1143 | { |
50 | mjames | 1144 | uint16_t initial_TxXferCount; |
1145 | uint32_t tmp_mode; |
||
1146 | HAL_SPI_StateTypeDef tmp_state; |
||
1147 | uint32_t tickstart; |
||
61 | mjames | 1148 | #if (USE_SPI_CRC != 0U) |
1149 | __IO uint32_t tmpreg = 0U; |
||
1150 | #endif /* USE_SPI_CRC */ |
||
30 | mjames | 1151 | |
50 | mjames | 1152 | /* Variable used to alternate Rx and Tx during transfer */ |
1153 | uint32_t txallowed = 1U; |
||
1154 | HAL_StatusTypeDef errorcode = HAL_OK; |
||
1155 | |||
1156 | /* Check Direction parameter */ |
||
1157 | assert_param(IS_SPI_DIRECTION_2LINES(hspi->Init.Direction)); |
||
1158 | |||
1159 | /* Process Locked */ |
||
1160 | __HAL_LOCK(hspi); |
||
1161 | |||
1162 | /* Init tickstart for timeout management*/ |
||
1163 | tickstart = HAL_GetTick(); |
||
1164 | |||
1165 | /* Init temporary variables */ |
||
1166 | tmp_state = hspi->State; |
||
1167 | tmp_mode = hspi->Init.Mode; |
||
1168 | initial_TxXferCount = Size; |
||
1169 | |||
1170 | if (!((tmp_state == HAL_SPI_STATE_READY) || \ |
||
1171 | ((tmp_mode == SPI_MODE_MASTER) && (hspi->Init.Direction == SPI_DIRECTION_2LINES) && (tmp_state == HAL_SPI_STATE_BUSY_RX)))) |
||
30 | mjames | 1172 | { |
50 | mjames | 1173 | errorcode = HAL_BUSY; |
1174 | goto error; |
||
1175 | } |
||
30 | mjames | 1176 | |
50 | mjames | 1177 | if ((pTxData == NULL) || (pRxData == NULL) || (Size == 0U)) |
1178 | { |
||
1179 | errorcode = HAL_ERROR; |
||
1180 | goto error; |
||
1181 | } |
||
30 | mjames | 1182 | |
50 | mjames | 1183 | /* Don't overwrite in case of HAL_SPI_STATE_BUSY_RX */ |
1184 | if (hspi->State != HAL_SPI_STATE_BUSY_RX) |
||
1185 | { |
||
1186 | hspi->State = HAL_SPI_STATE_BUSY_TX_RX; |
||
1187 | } |
||
30 | mjames | 1188 | |
50 | mjames | 1189 | /* Set the transaction information */ |
1190 | hspi->ErrorCode = HAL_SPI_ERROR_NONE; |
||
1191 | hspi->pRxBuffPtr = (uint8_t *)pRxData; |
||
1192 | hspi->RxXferCount = Size; |
||
1193 | hspi->RxXferSize = Size; |
||
1194 | hspi->pTxBuffPtr = (uint8_t *)pTxData; |
||
1195 | hspi->TxXferCount = Size; |
||
1196 | hspi->TxXferSize = Size; |
||
30 | mjames | 1197 | |
50 | mjames | 1198 | /*Init field not used in handle to zero */ |
1199 | hspi->RxISR = NULL; |
||
1200 | hspi->TxISR = NULL; |
||
30 | mjames | 1201 | |
50 | mjames | 1202 | #if (USE_SPI_CRC != 0U) |
1203 | /* Reset CRC Calculation */ |
||
1204 | if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) |
||
1205 | { |
||
1206 | SPI_RESET_CRC(hspi); |
||
1207 | } |
||
1208 | #endif /* USE_SPI_CRC */ |
||
30 | mjames | 1209 | |
50 | mjames | 1210 | /* Check if the SPI is already enabled */ |
1211 | if ((hspi->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE) |
||
1212 | { |
||
1213 | /* Enable SPI peripheral */ |
||
1214 | __HAL_SPI_ENABLE(hspi); |
||
1215 | } |
||
30 | mjames | 1216 | |
50 | mjames | 1217 | /* Transmit and Receive data in 16 Bit mode */ |
1218 | if (hspi->Init.DataSize == SPI_DATASIZE_16BIT) |
||
1219 | { |
||
1220 | if ((hspi->Init.Mode == SPI_MODE_SLAVE) || (initial_TxXferCount == 0x01U)) |
||
30 | mjames | 1221 | { |
50 | mjames | 1222 | hspi->Instance->DR = *((uint16_t *)hspi->pTxBuffPtr); |
1223 | hspi->pTxBuffPtr += sizeof(uint16_t); |
||
1224 | hspi->TxXferCount--; |
||
30 | mjames | 1225 | } |
50 | mjames | 1226 | while ((hspi->TxXferCount > 0U) || (hspi->RxXferCount > 0U)) |
30 | mjames | 1227 | { |
50 | mjames | 1228 | /* Check TXE flag */ |
1229 | if ((__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXE)) && (hspi->TxXferCount > 0U) && (txallowed == 1U)) |
||
30 | mjames | 1230 | { |
50 | mjames | 1231 | hspi->Instance->DR = *((uint16_t *)hspi->pTxBuffPtr); |
1232 | hspi->pTxBuffPtr += sizeof(uint16_t); |
||
30 | mjames | 1233 | hspi->TxXferCount--; |
50 | mjames | 1234 | /* Next Data is a reception (Rx). Tx not allowed */ |
1235 | txallowed = 0U; |
||
1236 | |||
1237 | #if (USE_SPI_CRC != 0U) |
||
30 | mjames | 1238 | /* Enable CRC Transmission */ |
50 | mjames | 1239 | if ((hspi->TxXferCount == 0U) && (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)) |
30 | mjames | 1240 | { |
1241 | SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT); |
||
1242 | } |
||
50 | mjames | 1243 | #endif /* USE_SPI_CRC */ |
1244 | } |
||
30 | mjames | 1245 | |
50 | mjames | 1246 | /* Check RXNE flag */ |
1247 | if ((__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_RXNE)) && (hspi->RxXferCount > 0U)) |
||
1248 | { |
||
1249 | *((uint16_t *)hspi->pRxBuffPtr) = (uint16_t)hspi->Instance->DR; |
||
1250 | hspi->pRxBuffPtr += sizeof(uint16_t); |
||
30 | mjames | 1251 | hspi->RxXferCount--; |
50 | mjames | 1252 | /* Next Data is a Transmission (Tx). Tx is allowed */ |
1253 | txallowed = 1U; |
||
30 | mjames | 1254 | } |
50 | mjames | 1255 | if (((HAL_GetTick() - tickstart) >= Timeout) && (Timeout != HAL_MAX_DELAY)) |
30 | mjames | 1256 | { |
50 | mjames | 1257 | errorcode = HAL_TIMEOUT; |
1258 | goto error; |
||
30 | mjames | 1259 | } |
1260 | } |
||
50 | mjames | 1261 | } |
1262 | /* Transmit and Receive data in 8 Bit mode */ |
||
1263 | else |
||
1264 | { |
||
1265 | if ((hspi->Init.Mode == SPI_MODE_SLAVE) || (initial_TxXferCount == 0x01U)) |
||
30 | mjames | 1266 | { |
50 | mjames | 1267 | *((__IO uint8_t *)&hspi->Instance->DR) = (*hspi->pTxBuffPtr); |
1268 | hspi->pTxBuffPtr += sizeof(uint8_t); |
||
1269 | hspi->TxXferCount--; |
||
1270 | } |
||
1271 | while ((hspi->TxXferCount > 0U) || (hspi->RxXferCount > 0U)) |
||
1272 | { |
||
1273 | /* Check TXE flag */ |
||
1274 | if ((__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXE)) && (hspi->TxXferCount > 0U) && (txallowed == 1U)) |
||
30 | mjames | 1275 | { |
50 | mjames | 1276 | *(__IO uint8_t *)&hspi->Instance->DR = (*hspi->pTxBuffPtr); |
1277 | hspi->pTxBuffPtr++; |
||
30 | mjames | 1278 | hspi->TxXferCount--; |
50 | mjames | 1279 | /* Next Data is a reception (Rx). Tx not allowed */ |
1280 | txallowed = 0U; |
||
1281 | |||
1282 | #if (USE_SPI_CRC != 0U) |
||
30 | mjames | 1283 | /* Enable CRC Transmission */ |
50 | mjames | 1284 | if ((hspi->TxXferCount == 0U) && (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)) |
30 | mjames | 1285 | { |
1286 | SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT); |
||
1287 | } |
||
50 | mjames | 1288 | #endif /* USE_SPI_CRC */ |
1289 | } |
||
30 | mjames | 1290 | |
50 | mjames | 1291 | /* Wait until RXNE flag is reset */ |
1292 | if ((__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_RXNE)) && (hspi->RxXferCount > 0U)) |
||
1293 | { |
||
1294 | (*(uint8_t *)hspi->pRxBuffPtr) = hspi->Instance->DR; |
||
1295 | hspi->pRxBuffPtr++; |
||
30 | mjames | 1296 | hspi->RxXferCount--; |
50 | mjames | 1297 | /* Next Data is a Transmission (Tx). Tx is allowed */ |
1298 | txallowed = 1U; |
||
30 | mjames | 1299 | } |
50 | mjames | 1300 | if ((((HAL_GetTick() - tickstart) >= Timeout) && ((Timeout != HAL_MAX_DELAY))) || (Timeout == 0U)) |
30 | mjames | 1301 | { |
50 | mjames | 1302 | errorcode = HAL_TIMEOUT; |
1303 | goto error; |
||
30 | mjames | 1304 | } |
1305 | } |
||
50 | mjames | 1306 | } |
30 | mjames | 1307 | |
50 | mjames | 1308 | #if (USE_SPI_CRC != 0U) |
1309 | /* Read CRC from DR to close CRC calculation process */ |
||
1310 | if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) |
||
1311 | { |
||
1312 | /* Wait until TXE flag */ |
||
1313 | if (SPI_WaitFlagStateUntilTimeout(hspi, SPI_FLAG_RXNE, SET, Timeout, tickstart) != HAL_OK) |
||
30 | mjames | 1314 | { |
50 | mjames | 1315 | /* Error on the CRC reception */ |
30 | mjames | 1316 | SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC); |
50 | mjames | 1317 | errorcode = HAL_TIMEOUT; |
1318 | goto error; |
||
30 | mjames | 1319 | } |
50 | mjames | 1320 | /* Read CRC */ |
61 | mjames | 1321 | tmpreg = READ_REG(hspi->Instance->DR); |
1322 | /* To avoid GCC warning */ |
||
1323 | UNUSED(tmpreg); |
||
50 | mjames | 1324 | } |
30 | mjames | 1325 | |
50 | mjames | 1326 | /* Check if CRC error occurred */ |
1327 | if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_CRCERR)) |
||
1328 | { |
||
1329 | SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC); |
||
1330 | /* Clear CRC Flag */ |
||
1331 | __HAL_SPI_CLEAR_CRCERRFLAG(hspi); |
||
30 | mjames | 1332 | |
50 | mjames | 1333 | errorcode = HAL_ERROR; |
30 | mjames | 1334 | } |
50 | mjames | 1335 | #endif /* USE_SPI_CRC */ |
1336 | |||
1337 | /* Check the end of the transaction */ |
||
1338 | if (SPI_EndRxTxTransaction(hspi, Timeout, tickstart) != HAL_OK) |
||
30 | mjames | 1339 | { |
50 | mjames | 1340 | errorcode = HAL_ERROR; |
1341 | hspi->ErrorCode = HAL_SPI_ERROR_FLAG; |
||
1342 | goto error; |
||
30 | mjames | 1343 | } |
50 | mjames | 1344 | |
1345 | /* Clear overrun flag in 2 Lines communication mode because received is not read */ |
||
1346 | if (hspi->Init.Direction == SPI_DIRECTION_2LINES) |
||
1347 | { |
||
1348 | __HAL_SPI_CLEAR_OVRFLAG(hspi); |
||
1349 | } |
||
1350 | |||
1351 | error : |
||
1352 | hspi->State = HAL_SPI_STATE_READY; |
||
1353 | __HAL_UNLOCK(hspi); |
||
1354 | return errorcode; |
||
30 | mjames | 1355 | } |
1356 | |||
1357 | /** |
||
50 | mjames | 1358 | * @brief Transmit an amount of data in non-blocking mode with Interrupt. |
1359 | * @param hspi pointer to a SPI_HandleTypeDef structure that contains |
||
1360 | * the configuration information for SPI module. |
||
1361 | * @param pData pointer to data buffer |
||
1362 | * @param Size amount of data to be sent |
||
30 | mjames | 1363 | * @retval HAL status |
1364 | */ |
||
1365 | HAL_StatusTypeDef HAL_SPI_Transmit_IT(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size) |
||
1366 | { |
||
50 | mjames | 1367 | HAL_StatusTypeDef errorcode = HAL_OK; |
1368 | |||
1369 | /* Check Direction parameter */ |
||
1370 | assert_param(IS_SPI_DIRECTION_2LINES_OR_1LINE(hspi->Init.Direction)); |
||
1371 | |||
1372 | /* Process Locked */ |
||
1373 | __HAL_LOCK(hspi); |
||
1374 | |||
1375 | if ((pData == NULL) || (Size == 0U)) |
||
30 | mjames | 1376 | { |
50 | mjames | 1377 | errorcode = HAL_ERROR; |
1378 | goto error; |
||
1379 | } |
||
30 | mjames | 1380 | |
50 | mjames | 1381 | if (hspi->State != HAL_SPI_STATE_READY) |
1382 | { |
||
1383 | errorcode = HAL_BUSY; |
||
1384 | goto error; |
||
1385 | } |
||
30 | mjames | 1386 | |
50 | mjames | 1387 | /* Set the transaction information */ |
1388 | hspi->State = HAL_SPI_STATE_BUSY_TX; |
||
1389 | hspi->ErrorCode = HAL_SPI_ERROR_NONE; |
||
1390 | hspi->pTxBuffPtr = (uint8_t *)pData; |
||
1391 | hspi->TxXferSize = Size; |
||
1392 | hspi->TxXferCount = Size; |
||
30 | mjames | 1393 | |
50 | mjames | 1394 | /* Init field not used in handle to zero */ |
1395 | hspi->pRxBuffPtr = (uint8_t *)NULL; |
||
1396 | hspi->RxXferSize = 0U; |
||
1397 | hspi->RxXferCount = 0U; |
||
1398 | hspi->RxISR = NULL; |
||
30 | mjames | 1399 | |
50 | mjames | 1400 | /* Set the function for IT treatment */ |
1401 | if (hspi->Init.DataSize > SPI_DATASIZE_8BIT) |
||
1402 | { |
||
1403 | hspi->TxISR = SPI_TxISR_16BIT; |
||
1404 | } |
||
1405 | else |
||
1406 | { |
||
1407 | hspi->TxISR = SPI_TxISR_8BIT; |
||
1408 | } |
||
30 | mjames | 1409 | |
50 | mjames | 1410 | /* Configure communication direction : 1Line */ |
1411 | if (hspi->Init.Direction == SPI_DIRECTION_1LINE) |
||
1412 | { |
||
1413 | /* Disable SPI Peripheral before set 1Line direction (BIDIOE bit) */ |
||
1414 | __HAL_SPI_DISABLE(hspi); |
||
1415 | SPI_1LINE_TX(hspi); |
||
1416 | } |
||
30 | mjames | 1417 | |
50 | mjames | 1418 | #if (USE_SPI_CRC != 0U) |
1419 | /* Reset CRC Calculation */ |
||
1420 | if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) |
||
1421 | { |
||
1422 | SPI_RESET_CRC(hspi); |
||
1423 | } |
||
1424 | #endif /* USE_SPI_CRC */ |
||
30 | mjames | 1425 | |
50 | mjames | 1426 | /* Enable TXE and ERR interrupt */ |
1427 | __HAL_SPI_ENABLE_IT(hspi, (SPI_IT_TXE | SPI_IT_ERR)); |
||
30 | mjames | 1428 | |
1429 | |||
50 | mjames | 1430 | /* Check if the SPI is already enabled */ |
1431 | if ((hspi->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE) |
||
30 | mjames | 1432 | { |
50 | mjames | 1433 | /* Enable SPI peripheral */ |
1434 | __HAL_SPI_ENABLE(hspi); |
||
30 | mjames | 1435 | } |
50 | mjames | 1436 | |
1437 | error : |
||
1438 | __HAL_UNLOCK(hspi); |
||
1439 | return errorcode; |
||
30 | mjames | 1440 | } |
1441 | |||
1442 | /** |
||
50 | mjames | 1443 | * @brief Receive an amount of data in non-blocking mode with Interrupt. |
1444 | * @param hspi pointer to a SPI_HandleTypeDef structure that contains |
||
1445 | * the configuration information for SPI module. |
||
1446 | * @param pData pointer to data buffer |
||
1447 | * @param Size amount of data to be sent |
||
30 | mjames | 1448 | * @retval HAL status |
1449 | */ |
||
1450 | HAL_StatusTypeDef HAL_SPI_Receive_IT(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size) |
||
1451 | { |
||
50 | mjames | 1452 | HAL_StatusTypeDef errorcode = HAL_OK; |
1453 | |||
1454 | if ((hspi->Init.Direction == SPI_DIRECTION_2LINES) && (hspi->Init.Mode == SPI_MODE_MASTER)) |
||
30 | mjames | 1455 | { |
50 | mjames | 1456 | hspi->State = HAL_SPI_STATE_BUSY_RX; |
1457 | /* Call transmit-receive function to send Dummy data on Tx line and generate clock on CLK line */ |
||
1458 | return HAL_SPI_TransmitReceive_IT(hspi, pData, pData, Size); |
||
1459 | } |
||
30 | mjames | 1460 | |
50 | mjames | 1461 | /* Process Locked */ |
1462 | __HAL_LOCK(hspi); |
||
30 | mjames | 1463 | |
50 | mjames | 1464 | if (hspi->State != HAL_SPI_STATE_READY) |
1465 | { |
||
1466 | errorcode = HAL_BUSY; |
||
1467 | goto error; |
||
1468 | } |
||
30 | mjames | 1469 | |
50 | mjames | 1470 | if ((pData == NULL) || (Size == 0U)) |
1471 | { |
||
1472 | errorcode = HAL_ERROR; |
||
1473 | goto error; |
||
1474 | } |
||
30 | mjames | 1475 | |
50 | mjames | 1476 | /* Set the transaction information */ |
1477 | hspi->State = HAL_SPI_STATE_BUSY_RX; |
||
1478 | hspi->ErrorCode = HAL_SPI_ERROR_NONE; |
||
1479 | hspi->pRxBuffPtr = (uint8_t *)pData; |
||
1480 | hspi->RxXferSize = Size; |
||
1481 | hspi->RxXferCount = Size; |
||
30 | mjames | 1482 | |
50 | mjames | 1483 | /* Init field not used in handle to zero */ |
1484 | hspi->pTxBuffPtr = (uint8_t *)NULL; |
||
1485 | hspi->TxXferSize = 0U; |
||
1486 | hspi->TxXferCount = 0U; |
||
1487 | hspi->TxISR = NULL; |
||
30 | mjames | 1488 | |
50 | mjames | 1489 | /* Set the function for IT treatment */ |
1490 | if (hspi->Init.DataSize > SPI_DATASIZE_8BIT) |
||
1491 | { |
||
1492 | hspi->RxISR = SPI_RxISR_16BIT; |
||
1493 | } |
||
1494 | else |
||
1495 | { |
||
1496 | hspi->RxISR = SPI_RxISR_8BIT; |
||
1497 | } |
||
30 | mjames | 1498 | |
50 | mjames | 1499 | /* Configure communication direction : 1Line */ |
1500 | if (hspi->Init.Direction == SPI_DIRECTION_1LINE) |
||
1501 | { |
||
1502 | /* Disable SPI Peripheral before set 1Line direction (BIDIOE bit) */ |
||
1503 | __HAL_SPI_DISABLE(hspi); |
||
1504 | SPI_1LINE_RX(hspi); |
||
1505 | } |
||
30 | mjames | 1506 | |
50 | mjames | 1507 | #if (USE_SPI_CRC != 0U) |
1508 | /* Reset CRC Calculation */ |
||
1509 | if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) |
||
1510 | { |
||
1511 | SPI_RESET_CRC(hspi); |
||
1512 | } |
||
1513 | #endif /* USE_SPI_CRC */ |
||
30 | mjames | 1514 | |
50 | mjames | 1515 | /* Enable TXE and ERR interrupt */ |
1516 | __HAL_SPI_ENABLE_IT(hspi, (SPI_IT_RXNE | SPI_IT_ERR)); |
||
30 | mjames | 1517 | |
50 | mjames | 1518 | /* Note : The SPI must be enabled after unlocking current process |
1519 | to avoid the risk of SPI interrupt handle execution before current |
||
1520 | process unlock */ |
||
30 | mjames | 1521 | |
50 | mjames | 1522 | /* Check if the SPI is already enabled */ |
1523 | if ((hspi->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE) |
||
1524 | { |
||
1525 | /* Enable SPI peripheral */ |
||
1526 | __HAL_SPI_ENABLE(hspi); |
||
1527 | } |
||
30 | mjames | 1528 | |
50 | mjames | 1529 | error : |
1530 | /* Process Unlocked */ |
||
1531 | __HAL_UNLOCK(hspi); |
||
1532 | return errorcode; |
||
1533 | } |
||
1534 | |||
1535 | /** |
||
1536 | * @brief Transmit and Receive an amount of data in non-blocking mode with Interrupt. |
||
1537 | * @param hspi pointer to a SPI_HandleTypeDef structure that contains |
||
1538 | * the configuration information for SPI module. |
||
1539 | * @param pTxData pointer to transmission data buffer |
||
1540 | * @param pRxData pointer to reception data buffer |
||
1541 | * @param Size amount of data to be sent and received |
||
1542 | * @retval HAL status |
||
1543 | */ |
||
1544 | HAL_StatusTypeDef HAL_SPI_TransmitReceive_IT(SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size) |
||
1545 | { |
||
1546 | uint32_t tmp_mode; |
||
1547 | HAL_SPI_StateTypeDef tmp_state; |
||
1548 | HAL_StatusTypeDef errorcode = HAL_OK; |
||
1549 | |||
1550 | /* Check Direction parameter */ |
||
1551 | assert_param(IS_SPI_DIRECTION_2LINES(hspi->Init.Direction)); |
||
1552 | |||
1553 | /* Process locked */ |
||
1554 | __HAL_LOCK(hspi); |
||
1555 | |||
1556 | /* Init temporary variables */ |
||
1557 | tmp_state = hspi->State; |
||
1558 | tmp_mode = hspi->Init.Mode; |
||
1559 | |||
1560 | if (!((tmp_state == HAL_SPI_STATE_READY) || \ |
||
1561 | ((tmp_mode == SPI_MODE_MASTER) && (hspi->Init.Direction == SPI_DIRECTION_2LINES) && (tmp_state == HAL_SPI_STATE_BUSY_RX)))) |
||
1562 | { |
||
1563 | errorcode = HAL_BUSY; |
||
1564 | goto error; |
||
30 | mjames | 1565 | } |
50 | mjames | 1566 | |
1567 | if ((pTxData == NULL) || (pRxData == NULL) || (Size == 0U)) |
||
1568 | { |
||
1569 | errorcode = HAL_ERROR; |
||
1570 | goto error; |
||
1571 | } |
||
1572 | |||
1573 | /* Don't overwrite in case of HAL_SPI_STATE_BUSY_RX */ |
||
1574 | if (hspi->State != HAL_SPI_STATE_BUSY_RX) |
||
1575 | { |
||
1576 | hspi->State = HAL_SPI_STATE_BUSY_TX_RX; |
||
1577 | } |
||
1578 | |||
1579 | /* Set the transaction information */ |
||
1580 | hspi->ErrorCode = HAL_SPI_ERROR_NONE; |
||
1581 | hspi->pTxBuffPtr = (uint8_t *)pTxData; |
||
1582 | hspi->TxXferSize = Size; |
||
1583 | hspi->TxXferCount = Size; |
||
1584 | hspi->pRxBuffPtr = (uint8_t *)pRxData; |
||
1585 | hspi->RxXferSize = Size; |
||
1586 | hspi->RxXferCount = Size; |
||
1587 | |||
1588 | /* Set the function for IT treatment */ |
||
1589 | if (hspi->Init.DataSize > SPI_DATASIZE_8BIT) |
||
1590 | { |
||
1591 | hspi->RxISR = SPI_2linesRxISR_16BIT; |
||
1592 | hspi->TxISR = SPI_2linesTxISR_16BIT; |
||
1593 | } |
||
30 | mjames | 1594 | else |
1595 | { |
||
50 | mjames | 1596 | hspi->RxISR = SPI_2linesRxISR_8BIT; |
1597 | hspi->TxISR = SPI_2linesTxISR_8BIT; |
||
30 | mjames | 1598 | } |
50 | mjames | 1599 | |
1600 | #if (USE_SPI_CRC != 0U) |
||
1601 | /* Reset CRC Calculation */ |
||
1602 | if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) |
||
1603 | { |
||
1604 | SPI_RESET_CRC(hspi); |
||
1605 | } |
||
1606 | #endif /* USE_SPI_CRC */ |
||
1607 | |||
1608 | /* Enable TXE, RXNE and ERR interrupt */ |
||
1609 | __HAL_SPI_ENABLE_IT(hspi, (SPI_IT_TXE | SPI_IT_RXNE | SPI_IT_ERR)); |
||
1610 | |||
1611 | /* Check if the SPI is already enabled */ |
||
1612 | if ((hspi->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE) |
||
1613 | { |
||
1614 | /* Enable SPI peripheral */ |
||
1615 | __HAL_SPI_ENABLE(hspi); |
||
1616 | } |
||
1617 | |||
1618 | error : |
||
1619 | /* Process Unlocked */ |
||
1620 | __HAL_UNLOCK(hspi); |
||
1621 | return errorcode; |
||
30 | mjames | 1622 | } |
1623 | |||
1624 | /** |
||
50 | mjames | 1625 | * @brief Transmit an amount of data in non-blocking mode with DMA. |
1626 | * @param hspi pointer to a SPI_HandleTypeDef structure that contains |
||
1627 | * the configuration information for SPI module. |
||
1628 | * @param pData pointer to data buffer |
||
1629 | * @param Size amount of data to be sent |
||
30 | mjames | 1630 | * @retval HAL status |
1631 | */ |
||
50 | mjames | 1632 | HAL_StatusTypeDef HAL_SPI_Transmit_DMA(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size) |
30 | mjames | 1633 | { |
50 | mjames | 1634 | HAL_StatusTypeDef errorcode = HAL_OK; |
30 | mjames | 1635 | |
50 | mjames | 1636 | /* Check tx dma handle */ |
1637 | assert_param(IS_SPI_DMA_HANDLE(hspi->hdmatx)); |
||
1638 | |||
1639 | /* Check Direction parameter */ |
||
1640 | assert_param(IS_SPI_DIRECTION_2LINES_OR_1LINE(hspi->Init.Direction)); |
||
1641 | |||
1642 | /* Process Locked */ |
||
1643 | __HAL_LOCK(hspi); |
||
1644 | |||
1645 | if (hspi->State != HAL_SPI_STATE_READY) |
||
30 | mjames | 1646 | { |
50 | mjames | 1647 | errorcode = HAL_BUSY; |
1648 | goto error; |
||
1649 | } |
||
30 | mjames | 1650 | |
50 | mjames | 1651 | if ((pData == NULL) || (Size == 0U)) |
1652 | { |
||
1653 | errorcode = HAL_ERROR; |
||
1654 | goto error; |
||
1655 | } |
||
30 | mjames | 1656 | |
50 | mjames | 1657 | /* Set the transaction information */ |
1658 | hspi->State = HAL_SPI_STATE_BUSY_TX; |
||
1659 | hspi->ErrorCode = HAL_SPI_ERROR_NONE; |
||
1660 | hspi->pTxBuffPtr = (uint8_t *)pData; |
||
1661 | hspi->TxXferSize = Size; |
||
1662 | hspi->TxXferCount = Size; |
||
30 | mjames | 1663 | |
50 | mjames | 1664 | /* Init field not used in handle to zero */ |
1665 | hspi->pRxBuffPtr = (uint8_t *)NULL; |
||
1666 | hspi->TxISR = NULL; |
||
1667 | hspi->RxISR = NULL; |
||
1668 | hspi->RxXferSize = 0U; |
||
1669 | hspi->RxXferCount = 0U; |
||
30 | mjames | 1670 | |
50 | mjames | 1671 | /* Configure communication direction : 1Line */ |
1672 | if (hspi->Init.Direction == SPI_DIRECTION_1LINE) |
||
1673 | { |
||
1674 | /* Disable SPI Peripheral before set 1Line direction (BIDIOE bit) */ |
||
1675 | __HAL_SPI_DISABLE(hspi); |
||
1676 | SPI_1LINE_TX(hspi); |
||
1677 | } |
||
30 | mjames | 1678 | |
50 | mjames | 1679 | #if (USE_SPI_CRC != 0U) |
1680 | /* Reset CRC Calculation */ |
||
1681 | if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) |
||
1682 | { |
||
1683 | SPI_RESET_CRC(hspi); |
||
1684 | } |
||
1685 | #endif /* USE_SPI_CRC */ |
||
30 | mjames | 1686 | |
50 | mjames | 1687 | /* Set the SPI TxDMA Half transfer complete callback */ |
1688 | hspi->hdmatx->XferHalfCpltCallback = SPI_DMAHalfTransmitCplt; |
||
30 | mjames | 1689 | |
50 | mjames | 1690 | /* Set the SPI TxDMA transfer complete callback */ |
1691 | hspi->hdmatx->XferCpltCallback = SPI_DMATransmitCplt; |
||
30 | mjames | 1692 | |
50 | mjames | 1693 | /* Set the DMA error callback */ |
1694 | hspi->hdmatx->XferErrorCallback = SPI_DMAError; |
||
30 | mjames | 1695 | |
50 | mjames | 1696 | /* Set the DMA AbortCpltCallback */ |
1697 | hspi->hdmatx->XferAbortCallback = NULL; |
||
30 | mjames | 1698 | |
50 | mjames | 1699 | /* Enable the Tx DMA Stream/Channel */ |
1700 | if (HAL_OK != HAL_DMA_Start_IT(hspi->hdmatx, (uint32_t)hspi->pTxBuffPtr, (uint32_t)&hspi->Instance->DR, |
||
1701 | hspi->TxXferCount)) |
||
1702 | { |
||
1703 | /* Update SPI error code */ |
||
1704 | SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_DMA); |
||
1705 | errorcode = HAL_ERROR; |
||
30 | mjames | 1706 | |
50 | mjames | 1707 | hspi->State = HAL_SPI_STATE_READY; |
1708 | goto error; |
||
30 | mjames | 1709 | } |
50 | mjames | 1710 | |
1711 | /* Check if the SPI is already enabled */ |
||
1712 | if ((hspi->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE) |
||
30 | mjames | 1713 | { |
50 | mjames | 1714 | /* Enable SPI peripheral */ |
1715 | __HAL_SPI_ENABLE(hspi); |
||
30 | mjames | 1716 | } |
50 | mjames | 1717 | |
1718 | /* Enable the SPI Error Interrupt Bit */ |
||
1719 | __HAL_SPI_ENABLE_IT(hspi, (SPI_IT_ERR)); |
||
1720 | |||
1721 | /* Enable Tx DMA Request */ |
||
1722 | SET_BIT(hspi->Instance->CR2, SPI_CR2_TXDMAEN); |
||
1723 | |||
1724 | error : |
||
1725 | /* Process Unlocked */ |
||
1726 | __HAL_UNLOCK(hspi); |
||
1727 | return errorcode; |
||
30 | mjames | 1728 | } |
1729 | |||
1730 | /** |
||
50 | mjames | 1731 | * @brief Receive an amount of data in non-blocking mode with DMA. |
1732 | * @note In case of MASTER mode and SPI_DIRECTION_2LINES direction, hdmatx shall be defined. |
||
1733 | * @param hspi pointer to a SPI_HandleTypeDef structure that contains |
||
1734 | * the configuration information for SPI module. |
||
1735 | * @param pData pointer to data buffer |
||
1736 | * @note When the CRC feature is enabled the pData Length must be Size + 1. |
||
1737 | * @param Size amount of data to be sent |
||
30 | mjames | 1738 | * @retval HAL status |
1739 | */ |
||
50 | mjames | 1740 | HAL_StatusTypeDef HAL_SPI_Receive_DMA(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size) |
30 | mjames | 1741 | { |
50 | mjames | 1742 | HAL_StatusTypeDef errorcode = HAL_OK; |
1743 | |||
1744 | /* Check rx dma handle */ |
||
1745 | assert_param(IS_SPI_DMA_HANDLE(hspi->hdmarx)); |
||
1746 | |||
1747 | if ((hspi->Init.Direction == SPI_DIRECTION_2LINES) && (hspi->Init.Mode == SPI_MODE_MASTER)) |
||
30 | mjames | 1748 | { |
50 | mjames | 1749 | hspi->State = HAL_SPI_STATE_BUSY_RX; |
30 | mjames | 1750 | |
50 | mjames | 1751 | /* Check tx dma handle */ |
1752 | assert_param(IS_SPI_DMA_HANDLE(hspi->hdmatx)); |
||
30 | mjames | 1753 | |
50 | mjames | 1754 | /* Call transmit-receive function to send Dummy data on Tx line and generate clock on CLK line */ |
1755 | return HAL_SPI_TransmitReceive_DMA(hspi, pData, pData, Size); |
||
1756 | } |
||
30 | mjames | 1757 | |
50 | mjames | 1758 | /* Process Locked */ |
1759 | __HAL_LOCK(hspi); |
||
30 | mjames | 1760 | |
50 | mjames | 1761 | if (hspi->State != HAL_SPI_STATE_READY) |
1762 | { |
||
1763 | errorcode = HAL_BUSY; |
||
1764 | goto error; |
||
1765 | } |
||
30 | mjames | 1766 | |
50 | mjames | 1767 | if ((pData == NULL) || (Size == 0U)) |
1768 | { |
||
1769 | errorcode = HAL_ERROR; |
||
1770 | goto error; |
||
1771 | } |
||
30 | mjames | 1772 | |
50 | mjames | 1773 | /* Set the transaction information */ |
1774 | hspi->State = HAL_SPI_STATE_BUSY_RX; |
||
1775 | hspi->ErrorCode = HAL_SPI_ERROR_NONE; |
||
1776 | hspi->pRxBuffPtr = (uint8_t *)pData; |
||
1777 | hspi->RxXferSize = Size; |
||
1778 | hspi->RxXferCount = Size; |
||
30 | mjames | 1779 | |
50 | mjames | 1780 | /*Init field not used in handle to zero */ |
1781 | hspi->RxISR = NULL; |
||
1782 | hspi->TxISR = NULL; |
||
1783 | hspi->TxXferSize = 0U; |
||
1784 | hspi->TxXferCount = 0U; |
||
30 | mjames | 1785 | |
50 | mjames | 1786 | /* Configure communication direction : 1Line */ |
1787 | if (hspi->Init.Direction == SPI_DIRECTION_1LINE) |
||
1788 | { |
||
1789 | /* Disable SPI Peripheral before set 1Line direction (BIDIOE bit) */ |
||
1790 | __HAL_SPI_DISABLE(hspi); |
||
1791 | SPI_1LINE_RX(hspi); |
||
1792 | } |
||
30 | mjames | 1793 | |
50 | mjames | 1794 | #if (USE_SPI_CRC != 0U) |
1795 | /* Reset CRC Calculation */ |
||
1796 | if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) |
||
1797 | { |
||
1798 | SPI_RESET_CRC(hspi); |
||
1799 | } |
||
1800 | #endif /* USE_SPI_CRC */ |
||
30 | mjames | 1801 | |
50 | mjames | 1802 | /* Set the SPI RxDMA Half transfer complete callback */ |
1803 | hspi->hdmarx->XferHalfCpltCallback = SPI_DMAHalfReceiveCplt; |
||
30 | mjames | 1804 | |
50 | mjames | 1805 | /* Set the SPI Rx DMA transfer complete callback */ |
1806 | hspi->hdmarx->XferCpltCallback = SPI_DMAReceiveCplt; |
||
30 | mjames | 1807 | |
50 | mjames | 1808 | /* Set the DMA error callback */ |
1809 | hspi->hdmarx->XferErrorCallback = SPI_DMAError; |
||
30 | mjames | 1810 | |
50 | mjames | 1811 | /* Set the DMA AbortCpltCallback */ |
1812 | hspi->hdmarx->XferAbortCallback = NULL; |
||
30 | mjames | 1813 | |
50 | mjames | 1814 | /* Enable the Rx DMA Stream/Channel */ |
1815 | if (HAL_OK != HAL_DMA_Start_IT(hspi->hdmarx, (uint32_t)&hspi->Instance->DR, (uint32_t)hspi->pRxBuffPtr, |
||
1816 | hspi->RxXferCount)) |
||
1817 | { |
||
1818 | /* Update SPI error code */ |
||
1819 | SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_DMA); |
||
1820 | errorcode = HAL_ERROR; |
||
1821 | |||
1822 | hspi->State = HAL_SPI_STATE_READY; |
||
1823 | goto error; |
||
30 | mjames | 1824 | } |
50 | mjames | 1825 | |
1826 | /* Check if the SPI is already enabled */ |
||
1827 | if ((hspi->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE) |
||
30 | mjames | 1828 | { |
50 | mjames | 1829 | /* Enable SPI peripheral */ |
1830 | __HAL_SPI_ENABLE(hspi); |
||
30 | mjames | 1831 | } |
50 | mjames | 1832 | |
1833 | /* Enable the SPI Error Interrupt Bit */ |
||
1834 | __HAL_SPI_ENABLE_IT(hspi, (SPI_IT_ERR)); |
||
1835 | |||
1836 | /* Enable Rx DMA Request */ |
||
1837 | SET_BIT(hspi->Instance->CR2, SPI_CR2_RXDMAEN); |
||
1838 | |||
1839 | error: |
||
1840 | /* Process Unlocked */ |
||
1841 | __HAL_UNLOCK(hspi); |
||
1842 | return errorcode; |
||
30 | mjames | 1843 | } |
1844 | |||
1845 | /** |
||
50 | mjames | 1846 | * @brief Transmit and Receive an amount of data in non-blocking mode with DMA. |
1847 | * @param hspi pointer to a SPI_HandleTypeDef structure that contains |
||
1848 | * the configuration information for SPI module. |
||
1849 | * @param pTxData pointer to transmission data buffer |
||
1850 | * @param pRxData pointer to reception data buffer |
||
1851 | * @note When the CRC feature is enabled the pRxData Length must be Size + 1 |
||
1852 | * @param Size amount of data to be sent |
||
30 | mjames | 1853 | * @retval HAL status |
1854 | */ |
||
50 | mjames | 1855 | HAL_StatusTypeDef HAL_SPI_TransmitReceive_DMA(SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData, |
1856 | uint16_t Size) |
||
30 | mjames | 1857 | { |
50 | mjames | 1858 | uint32_t tmp_mode; |
1859 | HAL_SPI_StateTypeDef tmp_state; |
||
1860 | HAL_StatusTypeDef errorcode = HAL_OK; |
||
30 | mjames | 1861 | |
50 | mjames | 1862 | /* Check rx & tx dma handles */ |
1863 | assert_param(IS_SPI_DMA_HANDLE(hspi->hdmarx)); |
||
1864 | assert_param(IS_SPI_DMA_HANDLE(hspi->hdmatx)); |
||
30 | mjames | 1865 | |
50 | mjames | 1866 | /* Check Direction parameter */ |
1867 | assert_param(IS_SPI_DIRECTION_2LINES(hspi->Init.Direction)); |
||
30 | mjames | 1868 | |
50 | mjames | 1869 | /* Process locked */ |
1870 | __HAL_LOCK(hspi); |
||
30 | mjames | 1871 | |
50 | mjames | 1872 | /* Init temporary variables */ |
1873 | tmp_state = hspi->State; |
||
1874 | tmp_mode = hspi->Init.Mode; |
||
30 | mjames | 1875 | |
50 | mjames | 1876 | if (!((tmp_state == HAL_SPI_STATE_READY) || |
1877 | ((tmp_mode == SPI_MODE_MASTER) && (hspi->Init.Direction == SPI_DIRECTION_2LINES) && (tmp_state == HAL_SPI_STATE_BUSY_RX)))) |
||
1878 | { |
||
1879 | errorcode = HAL_BUSY; |
||
1880 | goto error; |
||
1881 | } |
||
30 | mjames | 1882 | |
50 | mjames | 1883 | if ((pTxData == NULL) || (pRxData == NULL) || (Size == 0U)) |
1884 | { |
||
1885 | errorcode = HAL_ERROR; |
||
1886 | goto error; |
||
1887 | } |
||
30 | mjames | 1888 | |
50 | mjames | 1889 | /* Don't overwrite in case of HAL_SPI_STATE_BUSY_RX */ |
1890 | if (hspi->State != HAL_SPI_STATE_BUSY_RX) |
||
1891 | { |
||
1892 | hspi->State = HAL_SPI_STATE_BUSY_TX_RX; |
||
1893 | } |
||
30 | mjames | 1894 | |
50 | mjames | 1895 | /* Set the transaction information */ |
1896 | hspi->ErrorCode = HAL_SPI_ERROR_NONE; |
||
1897 | hspi->pTxBuffPtr = (uint8_t *)pTxData; |
||
1898 | hspi->TxXferSize = Size; |
||
1899 | hspi->TxXferCount = Size; |
||
1900 | hspi->pRxBuffPtr = (uint8_t *)pRxData; |
||
1901 | hspi->RxXferSize = Size; |
||
1902 | hspi->RxXferCount = Size; |
||
1903 | |||
1904 | /* Init field not used in handle to zero */ |
||
1905 | hspi->RxISR = NULL; |
||
1906 | hspi->TxISR = NULL; |
||
1907 | |||
1908 | #if (USE_SPI_CRC != 0U) |
||
1909 | /* Reset CRC Calculation */ |
||
1910 | if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) |
||
1911 | { |
||
1912 | SPI_RESET_CRC(hspi); |
||
1913 | } |
||
1914 | #endif /* USE_SPI_CRC */ |
||
1915 | |||
1916 | /* Check if we are in Rx only or in Rx/Tx Mode and configure the DMA transfer complete callback */ |
||
1917 | if (hspi->State == HAL_SPI_STATE_BUSY_RX) |
||
1918 | { |
||
1919 | /* Set the SPI Rx DMA Half transfer complete callback */ |
||
30 | mjames | 1920 | hspi->hdmarx->XferHalfCpltCallback = SPI_DMAHalfReceiveCplt; |
50 | mjames | 1921 | hspi->hdmarx->XferCpltCallback = SPI_DMAReceiveCplt; |
1922 | } |
||
1923 | else |
||
1924 | { |
||
1925 | /* Set the SPI Tx/Rx DMA Half transfer complete callback */ |
||
1926 | hspi->hdmarx->XferHalfCpltCallback = SPI_DMAHalfTransmitReceiveCplt; |
||
1927 | hspi->hdmarx->XferCpltCallback = SPI_DMATransmitReceiveCplt; |
||
1928 | } |
||
30 | mjames | 1929 | |
50 | mjames | 1930 | /* Set the DMA error callback */ |
1931 | hspi->hdmarx->XferErrorCallback = SPI_DMAError; |
||
30 | mjames | 1932 | |
50 | mjames | 1933 | /* Set the DMA AbortCpltCallback */ |
1934 | hspi->hdmarx->XferAbortCallback = NULL; |
||
30 | mjames | 1935 | |
50 | mjames | 1936 | /* Enable the Rx DMA Stream/Channel */ |
1937 | if (HAL_OK != HAL_DMA_Start_IT(hspi->hdmarx, (uint32_t)&hspi->Instance->DR, (uint32_t)hspi->pRxBuffPtr, |
||
1938 | hspi->RxXferCount)) |
||
1939 | { |
||
1940 | /* Update SPI error code */ |
||
1941 | SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_DMA); |
||
1942 | errorcode = HAL_ERROR; |
||
30 | mjames | 1943 | |
50 | mjames | 1944 | hspi->State = HAL_SPI_STATE_READY; |
1945 | goto error; |
||
1946 | } |
||
30 | mjames | 1947 | |
50 | mjames | 1948 | /* Enable Rx DMA Request */ |
1949 | SET_BIT(hspi->Instance->CR2, SPI_CR2_RXDMAEN); |
||
30 | mjames | 1950 | |
50 | mjames | 1951 | /* Set the SPI Tx DMA transfer complete callback as NULL because the communication closing |
1952 | is performed in DMA reception complete callback */ |
||
1953 | hspi->hdmatx->XferHalfCpltCallback = NULL; |
||
1954 | hspi->hdmatx->XferCpltCallback = NULL; |
||
1955 | hspi->hdmatx->XferErrorCallback = NULL; |
||
1956 | hspi->hdmatx->XferAbortCallback = NULL; |
||
1957 | |||
1958 | /* Enable the Tx DMA Stream/Channel */ |
||
1959 | if (HAL_OK != HAL_DMA_Start_IT(hspi->hdmatx, (uint32_t)hspi->pTxBuffPtr, (uint32_t)&hspi->Instance->DR, |
||
1960 | hspi->TxXferCount)) |
||
1961 | { |
||
1962 | /* Update SPI error code */ |
||
1963 | SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_DMA); |
||
1964 | errorcode = HAL_ERROR; |
||
1965 | |||
1966 | hspi->State = HAL_SPI_STATE_READY; |
||
1967 | goto error; |
||
30 | mjames | 1968 | } |
50 | mjames | 1969 | |
1970 | /* Check if the SPI is already enabled */ |
||
1971 | if ((hspi->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE) |
||
30 | mjames | 1972 | { |
50 | mjames | 1973 | /* Enable SPI peripheral */ |
1974 | __HAL_SPI_ENABLE(hspi); |
||
30 | mjames | 1975 | } |
50 | mjames | 1976 | /* Enable the SPI Error Interrupt Bit */ |
1977 | __HAL_SPI_ENABLE_IT(hspi, (SPI_IT_ERR)); |
||
1978 | |||
1979 | /* Enable Tx DMA Request */ |
||
1980 | SET_BIT(hspi->Instance->CR2, SPI_CR2_TXDMAEN); |
||
1981 | |||
1982 | error : |
||
1983 | /* Process Unlocked */ |
||
1984 | __HAL_UNLOCK(hspi); |
||
1985 | return errorcode; |
||
30 | mjames | 1986 | } |
1987 | |||
1988 | /** |
||
50 | mjames | 1989 | * @brief Abort ongoing transfer (blocking mode). |
1990 | * @param hspi SPI handle. |
||
1991 | * @note This procedure could be used for aborting any ongoing transfer (Tx and Rx), |
||
1992 | * started in Interrupt or DMA mode. |
||
1993 | * This procedure performs following operations : |
||
1994 | * - Disable SPI Interrupts (depending of transfer direction) |
||
1995 | * - Disable the DMA transfer in the peripheral register (if enabled) |
||
1996 | * - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode) |
||
1997 | * - Set handle State to READY |
||
1998 | * @note This procedure is executed in blocking mode : when exiting function, Abort is considered as completed. |
||
30 | mjames | 1999 | * @retval HAL status |
2000 | */ |
||
50 | mjames | 2001 | HAL_StatusTypeDef HAL_SPI_Abort(SPI_HandleTypeDef *hspi) |
30 | mjames | 2002 | { |
50 | mjames | 2003 | HAL_StatusTypeDef errorcode; |
2004 | __IO uint32_t count; |
||
2005 | __IO uint32_t resetcount; |
||
2006 | |||
2007 | /* Initialized local variable */ |
||
2008 | errorcode = HAL_OK; |
||
2009 | resetcount = SPI_DEFAULT_TIMEOUT * (SystemCoreClock / 24U / 1000U); |
||
2010 | count = resetcount; |
||
2011 | |||
2012 | /* Clear ERRIE interrupt to avoid error interrupts generation during Abort procedure */ |
||
2013 | CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_ERRIE); |
||
2014 | |||
2015 | /* Disable TXEIE, RXNEIE and ERRIE(mode fault event, overrun error, TI frame error) interrupts */ |
||
2016 | if (HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_TXEIE)) |
||
30 | mjames | 2017 | { |
50 | mjames | 2018 | hspi->TxISR = SPI_AbortTx_ISR; |
2019 | /* Wait HAL_SPI_STATE_ABORT state */ |
||
2020 | do |
||
30 | mjames | 2021 | { |
50 | mjames | 2022 | if (count == 0U) |
2023 | { |
||
2024 | SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_ABORT); |
||
2025 | break; |
||
2026 | } |
||
2027 | count--; |
||
2028 | } while (hspi->State != HAL_SPI_STATE_ABORT); |
||
2029 | /* Reset Timeout Counter */ |
||
2030 | count = resetcount; |
||
2031 | } |
||
30 | mjames | 2032 | |
50 | mjames | 2033 | if (HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_RXNEIE)) |
2034 | { |
||
2035 | hspi->RxISR = SPI_AbortRx_ISR; |
||
2036 | /* Wait HAL_SPI_STATE_ABORT state */ |
||
2037 | do |
||
2038 | { |
||
2039 | if (count == 0U) |
||
2040 | { |
||
2041 | SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_ABORT); |
||
2042 | break; |
||
2043 | } |
||
2044 | count--; |
||
2045 | } while (hspi->State != HAL_SPI_STATE_ABORT); |
||
2046 | /* Reset Timeout Counter */ |
||
2047 | count = resetcount; |
||
2048 | } |
||
30 | mjames | 2049 | |
50 | mjames | 2050 | /* Disable the SPI DMA Tx request if enabled */ |
2051 | if (HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_TXDMAEN)) |
||
2052 | { |
||
2053 | /* Abort the SPI DMA Tx Stream/Channel : use blocking DMA Abort API (no callback) */ |
||
2054 | if (hspi->hdmatx != NULL) |
||
30 | mjames | 2055 | { |
50 | mjames | 2056 | /* Set the SPI DMA Abort callback : |
2057 | will lead to call HAL_SPI_AbortCpltCallback() at end of DMA abort procedure */ |
||
2058 | hspi->hdmatx->XferAbortCallback = NULL; |
||
2059 | |||
2060 | /* Abort DMA Tx Handle linked to SPI Peripheral */ |
||
2061 | if (HAL_DMA_Abort(hspi->hdmatx) != HAL_OK) |
||
2062 | { |
||
2063 | hspi->ErrorCode = HAL_SPI_ERROR_ABORT; |
||
2064 | } |
||
2065 | |||
2066 | /* Disable Tx DMA Request */ |
||
2067 | CLEAR_BIT(hspi->Instance->CR2, (SPI_CR2_TXDMAEN)); |
||
2068 | |||
2069 | /* Wait until TXE flag is set */ |
||
2070 | do |
||
2071 | { |
||
2072 | if (count == 0U) |
||
2073 | { |
||
2074 | SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_ABORT); |
||
2075 | break; |
||
2076 | } |
||
2077 | count--; |
||
2078 | } while ((hspi->Instance->SR & SPI_FLAG_TXE) == RESET); |
||
30 | mjames | 2079 | } |
50 | mjames | 2080 | } |
30 | mjames | 2081 | |
50 | mjames | 2082 | /* Disable the SPI DMA Rx request if enabled */ |
2083 | if (HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_RXDMAEN)) |
||
2084 | { |
||
2085 | /* Abort the SPI DMA Rx Stream/Channel : use blocking DMA Abort API (no callback) */ |
||
2086 | if (hspi->hdmarx != NULL) |
||
2087 | { |
||
2088 | /* Set the SPI DMA Abort callback : |
||
2089 | will lead to call HAL_SPI_AbortCpltCallback() at end of DMA abort procedure */ |
||
2090 | hspi->hdmarx->XferAbortCallback = NULL; |
||
30 | mjames | 2091 | |
50 | mjames | 2092 | /* Abort DMA Rx Handle linked to SPI Peripheral */ |
2093 | if (HAL_DMA_Abort(hspi->hdmarx) != HAL_OK) |
||
2094 | { |
||
2095 | hspi->ErrorCode = HAL_SPI_ERROR_ABORT; |
||
2096 | } |
||
30 | mjames | 2097 | |
50 | mjames | 2098 | /* Disable peripheral */ |
2099 | __HAL_SPI_DISABLE(hspi); |
||
30 | mjames | 2100 | |
50 | mjames | 2101 | /* Disable Rx DMA Request */ |
2102 | CLEAR_BIT(hspi->Instance->CR2, (SPI_CR2_RXDMAEN)); |
||
2103 | } |
||
2104 | } |
||
2105 | /* Reset Tx and Rx transfer counters */ |
||
2106 | hspi->RxXferCount = 0U; |
||
2107 | hspi->TxXferCount = 0U; |
||
30 | mjames | 2108 | |
50 | mjames | 2109 | /* Check error during Abort procedure */ |
2110 | if (hspi->ErrorCode == HAL_SPI_ERROR_ABORT) |
||
2111 | { |
||
2112 | /* return HAL_Error in case of error during Abort procedure */ |
||
2113 | errorcode = HAL_ERROR; |
||
2114 | } |
||
2115 | else |
||
2116 | { |
||
2117 | /* Reset errorCode */ |
||
2118 | hspi->ErrorCode = HAL_SPI_ERROR_NONE; |
||
2119 | } |
||
2120 | |||
2121 | /* Clear the Error flags in the SR register */ |
||
2122 | __HAL_SPI_CLEAR_OVRFLAG(hspi); |
||
2123 | #if defined(SPI_CR2_FRF) |
||
2124 | __HAL_SPI_CLEAR_FREFLAG(hspi); |
||
2125 | #endif |
||
2126 | |||
2127 | /* Restore hspi->state to ready */ |
||
2128 | hspi->State = HAL_SPI_STATE_READY; |
||
2129 | |||
2130 | return errorcode; |
||
2131 | } |
||
2132 | |||
2133 | /** |
||
2134 | * @brief Abort ongoing transfer (Interrupt mode). |
||
2135 | * @param hspi SPI handle. |
||
2136 | * @note This procedure could be used for aborting any ongoing transfer (Tx and Rx), |
||
2137 | * started in Interrupt or DMA mode. |
||
2138 | * This procedure performs following operations : |
||
2139 | * - Disable SPI Interrupts (depending of transfer direction) |
||
2140 | * - Disable the DMA transfer in the peripheral register (if enabled) |
||
2141 | * - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode) |
||
2142 | * - Set handle State to READY |
||
2143 | * - At abort completion, call user abort complete callback |
||
2144 | * @note This procedure is executed in Interrupt mode, meaning that abort procedure could be |
||
2145 | * considered as completed only when user abort complete callback is executed (not when exiting function). |
||
2146 | * @retval HAL status |
||
2147 | */ |
||
2148 | HAL_StatusTypeDef HAL_SPI_Abort_IT(SPI_HandleTypeDef *hspi) |
||
2149 | { |
||
2150 | HAL_StatusTypeDef errorcode; |
||
2151 | uint32_t abortcplt ; |
||
2152 | __IO uint32_t count; |
||
2153 | __IO uint32_t resetcount; |
||
2154 | |||
2155 | /* Initialized local variable */ |
||
2156 | errorcode = HAL_OK; |
||
2157 | abortcplt = 1U; |
||
2158 | resetcount = SPI_DEFAULT_TIMEOUT * (SystemCoreClock / 24U / 1000U); |
||
2159 | count = resetcount; |
||
2160 | |||
2161 | /* Clear ERRIE interrupt to avoid error interrupts generation during Abort procedure */ |
||
2162 | CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_ERRIE); |
||
2163 | |||
2164 | /* Change Rx and Tx Irq Handler to Disable TXEIE, RXNEIE and ERRIE interrupts */ |
||
2165 | if (HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_TXEIE)) |
||
2166 | { |
||
2167 | hspi->TxISR = SPI_AbortTx_ISR; |
||
2168 | /* Wait HAL_SPI_STATE_ABORT state */ |
||
2169 | do |
||
30 | mjames | 2170 | { |
50 | mjames | 2171 | if (count == 0U) |
2172 | { |
||
2173 | SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_ABORT); |
||
2174 | break; |
||
2175 | } |
||
2176 | count--; |
||
2177 | } while (hspi->State != HAL_SPI_STATE_ABORT); |
||
2178 | /* Reset Timeout Counter */ |
||
2179 | count = resetcount; |
||
2180 | } |
||
30 | mjames | 2181 | |
50 | mjames | 2182 | if (HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_RXNEIE)) |
2183 | { |
||
2184 | hspi->RxISR = SPI_AbortRx_ISR; |
||
2185 | /* Wait HAL_SPI_STATE_ABORT state */ |
||
2186 | do |
||
30 | mjames | 2187 | { |
50 | mjames | 2188 | if (count == 0U) |
2189 | { |
||
2190 | SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_ABORT); |
||
2191 | break; |
||
2192 | } |
||
2193 | count--; |
||
2194 | } while (hspi->State != HAL_SPI_STATE_ABORT); |
||
2195 | /* Reset Timeout Counter */ |
||
2196 | count = resetcount; |
||
2197 | } |
||
2198 | |||
2199 | /* If DMA Tx and/or DMA Rx Handles are associated to SPI Handle, DMA Abort complete callbacks should be initialised |
||
2200 | before any call to DMA Abort functions */ |
||
2201 | /* DMA Tx Handle is valid */ |
||
2202 | if (hspi->hdmatx != NULL) |
||
2203 | { |
||
2204 | /* Set DMA Abort Complete callback if UART DMA Tx request if enabled. |
||
2205 | Otherwise, set it to NULL */ |
||
2206 | if (HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_TXDMAEN)) |
||
2207 | { |
||
2208 | hspi->hdmatx->XferAbortCallback = SPI_DMATxAbortCallback; |
||
30 | mjames | 2209 | } |
2210 | else |
||
2211 | { |
||
50 | mjames | 2212 | hspi->hdmatx->XferAbortCallback = NULL; |
30 | mjames | 2213 | } |
50 | mjames | 2214 | } |
2215 | /* DMA Rx Handle is valid */ |
||
2216 | if (hspi->hdmarx != NULL) |
||
2217 | { |
||
2218 | /* Set DMA Abort Complete callback if UART DMA Rx request if enabled. |
||
2219 | Otherwise, set it to NULL */ |
||
2220 | if (HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_RXDMAEN)) |
||
2221 | { |
||
2222 | hspi->hdmarx->XferAbortCallback = SPI_DMARxAbortCallback; |
||
2223 | } |
||
2224 | else |
||
2225 | { |
||
2226 | hspi->hdmarx->XferAbortCallback = NULL; |
||
2227 | } |
||
2228 | } |
||
30 | mjames | 2229 | |
50 | mjames | 2230 | /* Disable the SPI DMA Tx request if enabled */ |
2231 | if (HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_TXDMAEN)) |
||
2232 | { |
||
2233 | /* Abort the SPI DMA Tx Stream/Channel */ |
||
2234 | if (hspi->hdmatx != NULL) |
||
2235 | { |
||
2236 | /* Abort DMA Tx Handle linked to SPI Peripheral */ |
||
2237 | if (HAL_DMA_Abort_IT(hspi->hdmatx) != HAL_OK) |
||
2238 | { |
||
2239 | hspi->hdmatx->XferAbortCallback = NULL; |
||
2240 | hspi->ErrorCode = HAL_SPI_ERROR_ABORT; |
||
2241 | } |
||
2242 | else |
||
2243 | { |
||
2244 | abortcplt = 0U; |
||
2245 | } |
||
2246 | } |
||
2247 | } |
||
2248 | /* Disable the SPI DMA Rx request if enabled */ |
||
2249 | if (HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_RXDMAEN)) |
||
2250 | { |
||
2251 | /* Abort the SPI DMA Rx Stream/Channel */ |
||
2252 | if (hspi->hdmarx != NULL) |
||
2253 | { |
||
2254 | /* Abort DMA Rx Handle linked to SPI Peripheral */ |
||
2255 | if (HAL_DMA_Abort_IT(hspi->hdmarx) != HAL_OK) |
||
2256 | { |
||
2257 | hspi->hdmarx->XferAbortCallback = NULL; |
||
2258 | hspi->ErrorCode = HAL_SPI_ERROR_ABORT; |
||
2259 | } |
||
2260 | else |
||
2261 | { |
||
2262 | abortcplt = 0U; |
||
2263 | } |
||
2264 | } |
||
2265 | } |
||
30 | mjames | 2266 | |
50 | mjames | 2267 | if (abortcplt == 1U) |
2268 | { |
||
2269 | /* Reset Tx and Rx transfer counters */ |
||
2270 | hspi->RxXferCount = 0U; |
||
2271 | hspi->TxXferCount = 0U; |
||
30 | mjames | 2272 | |
50 | mjames | 2273 | /* Check error during Abort procedure */ |
2274 | if (hspi->ErrorCode == HAL_SPI_ERROR_ABORT) |
||
30 | mjames | 2275 | { |
50 | mjames | 2276 | /* return HAL_Error in case of error during Abort procedure */ |
2277 | errorcode = HAL_ERROR; |
||
30 | mjames | 2278 | } |
2279 | else |
||
2280 | { |
||
50 | mjames | 2281 | /* Reset errorCode */ |
2282 | hspi->ErrorCode = HAL_SPI_ERROR_NONE; |
||
30 | mjames | 2283 | } |
2284 | |||
50 | mjames | 2285 | /* Clear the Error flags in the SR register */ |
2286 | __HAL_SPI_CLEAR_OVRFLAG(hspi); |
||
2287 | #if defined(SPI_CR2_FRF) |
||
2288 | __HAL_SPI_CLEAR_FREFLAG(hspi); |
||
2289 | #endif |
||
30 | mjames | 2290 | |
50 | mjames | 2291 | /* Restore hspi->State to Ready */ |
2292 | hspi->State = HAL_SPI_STATE_READY; |
||
30 | mjames | 2293 | |
50 | mjames | 2294 | /* As no DMA to be aborted, call directly user Abort complete callback */ |
2295 | #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U) |
||
2296 | hspi->AbortCpltCallback(hspi); |
||
2297 | #else |
||
2298 | HAL_SPI_AbortCpltCallback(hspi); |
||
2299 | #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ |
||
2300 | } |
||
30 | mjames | 2301 | |
50 | mjames | 2302 | return errorcode; |
30 | mjames | 2303 | } |
2304 | |||
2305 | /** |
||
50 | mjames | 2306 | * @brief Pause the DMA Transfer. |
2307 | * @param hspi pointer to a SPI_HandleTypeDef structure that contains |
||
2308 | * the configuration information for the specified SPI module. |
||
30 | mjames | 2309 | * @retval HAL status |
2310 | */ |
||
2311 | HAL_StatusTypeDef HAL_SPI_DMAPause(SPI_HandleTypeDef *hspi) |
||
2312 | { |
||
2313 | /* Process Locked */ |
||
2314 | __HAL_LOCK(hspi); |
||
50 | mjames | 2315 | |
30 | mjames | 2316 | /* Disable the SPI DMA Tx & Rx requests */ |
50 | mjames | 2317 | CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN); |
2318 | |||
30 | mjames | 2319 | /* Process Unlocked */ |
2320 | __HAL_UNLOCK(hspi); |
||
50 | mjames | 2321 | |
2322 | return HAL_OK; |
||
30 | mjames | 2323 | } |
2324 | |||
2325 | /** |
||
50 | mjames | 2326 | * @brief Resume the DMA Transfer. |
2327 | * @param hspi pointer to a SPI_HandleTypeDef structure that contains |
||
2328 | * the configuration information for the specified SPI module. |
||
30 | mjames | 2329 | * @retval HAL status |
2330 | */ |
||
2331 | HAL_StatusTypeDef HAL_SPI_DMAResume(SPI_HandleTypeDef *hspi) |
||
2332 | { |
||
2333 | /* Process Locked */ |
||
2334 | __HAL_LOCK(hspi); |
||
50 | mjames | 2335 | |
30 | mjames | 2336 | /* Enable the SPI DMA Tx & Rx requests */ |
50 | mjames | 2337 | SET_BIT(hspi->Instance->CR2, SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN); |
2338 | |||
30 | mjames | 2339 | /* Process Unlocked */ |
2340 | __HAL_UNLOCK(hspi); |
||
50 | mjames | 2341 | |
30 | mjames | 2342 | return HAL_OK; |
2343 | } |
||
2344 | |||
2345 | /** |
||
50 | mjames | 2346 | * @brief Stop the DMA Transfer. |
2347 | * @param hspi pointer to a SPI_HandleTypeDef structure that contains |
||
2348 | * the configuration information for the specified SPI module. |
||
30 | mjames | 2349 | * @retval HAL status |
2350 | */ |
||
2351 | HAL_StatusTypeDef HAL_SPI_DMAStop(SPI_HandleTypeDef *hspi) |
||
2352 | { |
||
50 | mjames | 2353 | HAL_StatusTypeDef errorcode = HAL_OK; |
30 | mjames | 2354 | /* The Lock is not implemented on this API to allow the user application |
2355 | to call the HAL SPI API under callbacks HAL_SPI_TxCpltCallback() or HAL_SPI_RxCpltCallback() or HAL_SPI_TxRxCpltCallback(): |
||
2356 | when calling HAL_DMA_Abort() API the DMA TX/RX Transfer complete interrupt is generated |
||
2357 | and the correspond call back is executed HAL_SPI_TxCpltCallback() or HAL_SPI_RxCpltCallback() or HAL_SPI_TxRxCpltCallback() |
||
2358 | */ |
||
50 | mjames | 2359 | |
2360 | /* Abort the SPI DMA tx Stream/Channel */ |
||
2361 | if (hspi->hdmatx != NULL) |
||
30 | mjames | 2362 | { |
50 | mjames | 2363 | if (HAL_OK != HAL_DMA_Abort(hspi->hdmatx)) |
2364 | { |
||
2365 | SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_DMA); |
||
2366 | errorcode = HAL_ERROR; |
||
2367 | } |
||
30 | mjames | 2368 | } |
50 | mjames | 2369 | /* Abort the SPI DMA rx Stream/Channel */ |
2370 | if (hspi->hdmarx != NULL) |
||
30 | mjames | 2371 | { |
50 | mjames | 2372 | if (HAL_OK != HAL_DMA_Abort(hspi->hdmarx)) |
2373 | { |
||
2374 | SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_DMA); |
||
2375 | errorcode = HAL_ERROR; |
||
2376 | } |
||
30 | mjames | 2377 | } |
50 | mjames | 2378 | |
30 | mjames | 2379 | /* Disable the SPI DMA Tx & Rx requests */ |
50 | mjames | 2380 | CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN); |
30 | mjames | 2381 | hspi->State = HAL_SPI_STATE_READY; |
50 | mjames | 2382 | return errorcode; |
30 | mjames | 2383 | } |
2384 | |||
2385 | /** |
||
50 | mjames | 2386 | * @brief Handle SPI interrupt request. |
2387 | * @param hspi pointer to a SPI_HandleTypeDef structure that contains |
||
2388 | * the configuration information for the specified SPI module. |
||
2389 | * @retval None |
||
30 | mjames | 2390 | */ |
2391 | void HAL_SPI_IRQHandler(SPI_HandleTypeDef *hspi) |
||
2392 | { |
||
50 | mjames | 2393 | uint32_t itsource = hspi->Instance->CR2; |
2394 | uint32_t itflag = hspi->Instance->SR; |
||
2395 | |||
2396 | /* SPI in mode Receiver ----------------------------------------------------*/ |
||
2397 | if ((SPI_CHECK_FLAG(itflag, SPI_FLAG_OVR) == RESET) && |
||
2398 | (SPI_CHECK_FLAG(itflag, SPI_FLAG_RXNE) != RESET) && (SPI_CHECK_IT_SOURCE(itsource, SPI_IT_RXNE) != RESET)) |
||
30 | mjames | 2399 | { |
2400 | hspi->RxISR(hspi); |
||
2401 | return; |
||
2402 | } |
||
2403 | |||
50 | mjames | 2404 | /* SPI in mode Transmitter -------------------------------------------------*/ |
2405 | if ((SPI_CHECK_FLAG(itflag, SPI_FLAG_TXE) != RESET) && (SPI_CHECK_IT_SOURCE(itsource, SPI_IT_TXE) != RESET)) |
||
30 | mjames | 2406 | { |
2407 | hspi->TxISR(hspi); |
||
2408 | return; |
||
2409 | } |
||
2410 | |||
50 | mjames | 2411 | /* SPI in Error Treatment --------------------------------------------------*/ |
2412 | #if defined(SPI_CR2_FRF) |
||
2413 | if (((SPI_CHECK_FLAG(itflag, SPI_FLAG_MODF) != RESET) || (SPI_CHECK_FLAG(itflag, SPI_FLAG_OVR) != RESET) |
||
2414 | || (SPI_CHECK_FLAG(itflag, SPI_FLAG_FRE) != RESET)) && (SPI_CHECK_IT_SOURCE(itsource, SPI_IT_ERR) != RESET)) |
||
2415 | #else |
||
2416 | if (((SPI_CHECK_FLAG(itflag, SPI_FLAG_MODF) != RESET) || (SPI_CHECK_FLAG(itflag, SPI_FLAG_OVR) != RESET)) |
||
2417 | && (SPI_CHECK_IT_SOURCE(itsource, SPI_IT_ERR) != RESET)) |
||
2418 | #endif |
||
30 | mjames | 2419 | { |
50 | mjames | 2420 | /* SPI Overrun error interrupt occurred ----------------------------------*/ |
2421 | if (SPI_CHECK_FLAG(itflag, SPI_FLAG_OVR) != RESET) |
||
30 | mjames | 2422 | { |
50 | mjames | 2423 | if (hspi->State != HAL_SPI_STATE_BUSY_TX) |
2424 | { |
||
2425 | SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_OVR); |
||
2426 | __HAL_SPI_CLEAR_OVRFLAG(hspi); |
||
2427 | } |
||
2428 | else |
||
2429 | { |
||
2430 | __HAL_SPI_CLEAR_OVRFLAG(hspi); |
||
2431 | return; |
||
2432 | } |
||
30 | mjames | 2433 | } |
50 | mjames | 2434 | |
2435 | /* SPI Mode Fault error interrupt occurred -------------------------------*/ |
||
2436 | if (SPI_CHECK_FLAG(itflag, SPI_FLAG_MODF) != RESET) |
||
30 | mjames | 2437 | { |
2438 | SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_MODF); |
||
2439 | __HAL_SPI_CLEAR_MODFFLAG(hspi); |
||
2440 | } |
||
2441 | |||
50 | mjames | 2442 | /* SPI Frame error interrupt occurred ------------------------------------*/ |
2443 | #if defined(SPI_CR2_FRF) |
||
2444 | if (SPI_CHECK_FLAG(itflag, SPI_FLAG_FRE) != RESET) |
||
30 | mjames | 2445 | { |
2446 | SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FRE); |
||
2447 | __HAL_SPI_CLEAR_FREFLAG(hspi); |
||
2448 | } |
||
50 | mjames | 2449 | #endif |
30 | mjames | 2450 | |
50 | mjames | 2451 | if (hspi->ErrorCode != HAL_SPI_ERROR_NONE) |
30 | mjames | 2452 | { |
50 | mjames | 2453 | /* Disable all interrupts */ |
30 | mjames | 2454 | __HAL_SPI_DISABLE_IT(hspi, SPI_IT_RXNE | SPI_IT_TXE | SPI_IT_ERR); |
50 | mjames | 2455 | |
30 | mjames | 2456 | hspi->State = HAL_SPI_STATE_READY; |
50 | mjames | 2457 | /* Disable the SPI DMA requests if enabled */ |
2458 | if ((HAL_IS_BIT_SET(itsource, SPI_CR2_TXDMAEN)) || (HAL_IS_BIT_SET(itsource, SPI_CR2_RXDMAEN))) |
||
2459 | { |
||
2460 | CLEAR_BIT(hspi->Instance->CR2, (SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN)); |
||
2461 | |||
2462 | /* Abort the SPI DMA Rx channel */ |
||
2463 | if (hspi->hdmarx != NULL) |
||
2464 | { |
||
2465 | /* Set the SPI DMA Abort callback : |
||
2466 | will lead to call HAL_SPI_ErrorCallback() at end of DMA abort procedure */ |
||
2467 | hspi->hdmarx->XferAbortCallback = SPI_DMAAbortOnError; |
||
2468 | if (HAL_OK != HAL_DMA_Abort_IT(hspi->hdmarx)) |
||
2469 | { |
||
2470 | SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_ABORT); |
||
2471 | } |
||
2472 | } |
||
2473 | /* Abort the SPI DMA Tx channel */ |
||
2474 | if (hspi->hdmatx != NULL) |
||
2475 | { |
||
2476 | /* Set the SPI DMA Abort callback : |
||
2477 | will lead to call HAL_SPI_ErrorCallback() at end of DMA abort procedure */ |
||
2478 | hspi->hdmatx->XferAbortCallback = SPI_DMAAbortOnError; |
||
2479 | if (HAL_OK != HAL_DMA_Abort_IT(hspi->hdmatx)) |
||
2480 | { |
||
2481 | SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_ABORT); |
||
2482 | } |
||
2483 | } |
||
2484 | } |
||
2485 | else |
||
2486 | { |
||
2487 | /* Call user error callback */ |
||
2488 | #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U) |
||
2489 | hspi->ErrorCallback(hspi); |
||
2490 | #else |
||
2491 | HAL_SPI_ErrorCallback(hspi); |
||
2492 | #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ |
||
2493 | } |
||
30 | mjames | 2494 | } |
50 | mjames | 2495 | return; |
30 | mjames | 2496 | } |
2497 | } |
||
2498 | |||
2499 | /** |
||
50 | mjames | 2500 | * @brief Tx Transfer completed callback. |
2501 | * @param hspi pointer to a SPI_HandleTypeDef structure that contains |
||
2502 | * the configuration information for SPI module. |
||
30 | mjames | 2503 | * @retval None |
2504 | */ |
||
2505 | __weak void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi) |
||
2506 | { |
||
2507 | /* Prevent unused argument(s) compilation warning */ |
||
2508 | UNUSED(hspi); |
||
2509 | |||
50 | mjames | 2510 | /* NOTE : This function should not be modified, when the callback is needed, |
2511 | the HAL_SPI_TxCpltCallback should be implemented in the user file |
||
30 | mjames | 2512 | */ |
2513 | } |
||
2514 | |||
2515 | /** |
||
50 | mjames | 2516 | * @brief Rx Transfer completed callback. |
2517 | * @param hspi pointer to a SPI_HandleTypeDef structure that contains |
||
2518 | * the configuration information for SPI module. |
||
30 | mjames | 2519 | * @retval None |
2520 | */ |
||
2521 | __weak void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi) |
||
2522 | { |
||
2523 | /* Prevent unused argument(s) compilation warning */ |
||
2524 | UNUSED(hspi); |
||
2525 | |||
50 | mjames | 2526 | /* NOTE : This function should not be modified, when the callback is needed, |
2527 | the HAL_SPI_RxCpltCallback should be implemented in the user file |
||
30 | mjames | 2528 | */ |
2529 | } |
||
2530 | |||
2531 | /** |
||
50 | mjames | 2532 | * @brief Tx and Rx Transfer completed callback. |
2533 | * @param hspi pointer to a SPI_HandleTypeDef structure that contains |
||
2534 | * the configuration information for SPI module. |
||
30 | mjames | 2535 | * @retval None |
2536 | */ |
||
2537 | __weak void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi) |
||
2538 | { |
||
2539 | /* Prevent unused argument(s) compilation warning */ |
||
2540 | UNUSED(hspi); |
||
2541 | |||
50 | mjames | 2542 | /* NOTE : This function should not be modified, when the callback is needed, |
2543 | the HAL_SPI_TxRxCpltCallback should be implemented in the user file |
||
30 | mjames | 2544 | */ |
2545 | } |
||
2546 | |||
2547 | /** |
||
50 | mjames | 2548 | * @brief Tx Half Transfer completed callback. |
2549 | * @param hspi pointer to a SPI_HandleTypeDef structure that contains |
||
2550 | * the configuration information for SPI module. |
||
30 | mjames | 2551 | * @retval None |
2552 | */ |
||
2553 | __weak void HAL_SPI_TxHalfCpltCallback(SPI_HandleTypeDef *hspi) |
||
2554 | { |
||
2555 | /* Prevent unused argument(s) compilation warning */ |
||
2556 | UNUSED(hspi); |
||
2557 | |||
50 | mjames | 2558 | /* NOTE : This function should not be modified, when the callback is needed, |
2559 | the HAL_SPI_TxHalfCpltCallback should be implemented in the user file |
||
30 | mjames | 2560 | */ |
2561 | } |
||
2562 | |||
2563 | /** |
||
50 | mjames | 2564 | * @brief Rx Half Transfer completed callback. |
2565 | * @param hspi pointer to a SPI_HandleTypeDef structure that contains |
||
2566 | * the configuration information for SPI module. |
||
30 | mjames | 2567 | * @retval None |
2568 | */ |
||
2569 | __weak void HAL_SPI_RxHalfCpltCallback(SPI_HandleTypeDef *hspi) |
||
2570 | { |
||
2571 | /* Prevent unused argument(s) compilation warning */ |
||
2572 | UNUSED(hspi); |
||
2573 | |||
50 | mjames | 2574 | /* NOTE : This function should not be modified, when the callback is needed, |
2575 | the HAL_SPI_RxHalfCpltCallback() should be implemented in the user file |
||
30 | mjames | 2576 | */ |
2577 | } |
||
2578 | |||
2579 | /** |
||
50 | mjames | 2580 | * @brief Tx and Rx Half Transfer callback. |
2581 | * @param hspi pointer to a SPI_HandleTypeDef structure that contains |
||
2582 | * the configuration information for SPI module. |
||
30 | mjames | 2583 | * @retval None |
2584 | */ |
||
2585 | __weak void HAL_SPI_TxRxHalfCpltCallback(SPI_HandleTypeDef *hspi) |
||
2586 | { |
||
2587 | /* Prevent unused argument(s) compilation warning */ |
||
2588 | UNUSED(hspi); |
||
2589 | |||
50 | mjames | 2590 | /* NOTE : This function should not be modified, when the callback is needed, |
2591 | the HAL_SPI_TxRxHalfCpltCallback() should be implemented in the user file |
||
30 | mjames | 2592 | */ |
2593 | } |
||
2594 | |||
2595 | /** |
||
50 | mjames | 2596 | * @brief SPI error callback. |
2597 | * @param hspi pointer to a SPI_HandleTypeDef structure that contains |
||
2598 | * the configuration information for SPI module. |
||
30 | mjames | 2599 | * @retval None |
2600 | */ |
||
50 | mjames | 2601 | __weak void HAL_SPI_ErrorCallback(SPI_HandleTypeDef *hspi) |
30 | mjames | 2602 | { |
2603 | /* Prevent unused argument(s) compilation warning */ |
||
2604 | UNUSED(hspi); |
||
2605 | |||
50 | mjames | 2606 | /* NOTE : This function should not be modified, when the callback is needed, |
2607 | the HAL_SPI_ErrorCallback should be implemented in the user file |
||
30 | mjames | 2608 | */ |
50 | mjames | 2609 | /* NOTE : The ErrorCode parameter in the hspi handle is updated by the SPI processes |
2610 | and user can use HAL_SPI_GetError() API to check the latest error occurred |
||
2611 | */ |
||
30 | mjames | 2612 | } |
2613 | |||
2614 | /** |
||
50 | mjames | 2615 | * @brief SPI Abort Complete callback. |
2616 | * @param hspi SPI handle. |
||
2617 | * @retval None |
||
2618 | */ |
||
2619 | __weak void HAL_SPI_AbortCpltCallback(SPI_HandleTypeDef *hspi) |
||
2620 | { |
||
2621 | /* Prevent unused argument(s) compilation warning */ |
||
2622 | UNUSED(hspi); |
||
2623 | |||
2624 | /* NOTE : This function should not be modified, when the callback is needed, |
||
2625 | the HAL_SPI_AbortCpltCallback can be implemented in the user file. |
||
2626 | */ |
||
2627 | } |
||
2628 | |||
2629 | /** |
||
30 | mjames | 2630 | * @} |
2631 | */ |
||
2632 | |||
50 | mjames | 2633 | /** @defgroup SPI_Exported_Functions_Group3 Peripheral State and Errors functions |
2634 | * @brief SPI control functions |
||
30 | mjames | 2635 | * |
2636 | @verbatim |
||
2637 | =============================================================================== |
||
2638 | ##### Peripheral State and Errors functions ##### |
||
50 | mjames | 2639 | =============================================================================== |
30 | mjames | 2640 | [..] |
2641 | This subsection provides a set of functions allowing to control the SPI. |
||
2642 | (+) HAL_SPI_GetState() API can be helpful to check in run-time the state of the SPI peripheral |
||
2643 | (+) HAL_SPI_GetError() check in run-time Errors occurring during communication |
||
2644 | @endverbatim |
||
2645 | * @{ |
||
2646 | */ |
||
2647 | |||
2648 | /** |
||
50 | mjames | 2649 | * @brief Return the SPI handle state. |
2650 | * @param hspi pointer to a SPI_HandleTypeDef structure that contains |
||
2651 | * the configuration information for SPI module. |
||
2652 | * @retval SPI state |
||
30 | mjames | 2653 | */ |
2654 | HAL_SPI_StateTypeDef HAL_SPI_GetState(SPI_HandleTypeDef *hspi) |
||
2655 | { |
||
50 | mjames | 2656 | /* Return SPI handle state */ |
30 | mjames | 2657 | return hspi->State; |
2658 | } |
||
2659 | |||
2660 | /** |
||
50 | mjames | 2661 | * @brief Return the SPI error code. |
2662 | * @param hspi pointer to a SPI_HandleTypeDef structure that contains |
||
2663 | * the configuration information for SPI module. |
||
2664 | * @retval SPI error code in bitmap format |
||
30 | mjames | 2665 | */ |
2666 | uint32_t HAL_SPI_GetError(SPI_HandleTypeDef *hspi) |
||
2667 | { |
||
50 | mjames | 2668 | /* Return SPI ErrorCode */ |
30 | mjames | 2669 | return hspi->ErrorCode; |
2670 | } |
||
2671 | |||
2672 | /** |
||
2673 | * @} |
||
2674 | */ |
||
50 | mjames | 2675 | |
30 | mjames | 2676 | /** |
50 | mjames | 2677 | * @} |
2678 | */ |
||
30 | mjames | 2679 | |
2680 | /** @addtogroup SPI_Private_Functions |
||
50 | mjames | 2681 | * @brief Private functions |
2682 | * @{ |
||
2683 | */ |
||
30 | mjames | 2684 | |
50 | mjames | 2685 | /** |
2686 | * @brief DMA SPI transmit process complete callback. |
||
2687 | * @param hdma pointer to a DMA_HandleTypeDef structure that contains |
||
2688 | * the configuration information for the specified DMA module. |
||
2689 | * @retval None |
||
30 | mjames | 2690 | */ |
50 | mjames | 2691 | static void SPI_DMATransmitCplt(DMA_HandleTypeDef *hdma) |
30 | mjames | 2692 | { |
50 | mjames | 2693 | SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent); /* Derogation MISRAC2012-Rule-11.5 */ |
2694 | uint32_t tickstart; |
||
30 | mjames | 2695 | |
50 | mjames | 2696 | /* Init tickstart for timeout management*/ |
2697 | tickstart = HAL_GetTick(); |
||
30 | mjames | 2698 | |
50 | mjames | 2699 | /* DMA Normal Mode */ |
2700 | if ((hdma->Instance->CCR & DMA_CCR_CIRC) != DMA_CCR_CIRC) |
||
30 | mjames | 2701 | { |
50 | mjames | 2702 | /* Disable ERR interrupt */ |
2703 | __HAL_SPI_DISABLE_IT(hspi, SPI_IT_ERR); |
||
30 | mjames | 2704 | |
50 | mjames | 2705 | /* Disable Tx DMA Request */ |
2706 | CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_TXDMAEN); |
||
2707 | |||
2708 | /* Check the end of the transaction */ |
||
2709 | if (SPI_EndRxTxTransaction(hspi, SPI_DEFAULT_TIMEOUT, tickstart) != HAL_OK) |
||
30 | mjames | 2710 | { |
2711 | SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG); |
||
2712 | } |
||
2713 | |||
50 | mjames | 2714 | /* Clear overrun flag in 2 Lines communication mode because received data is not read */ |
2715 | if (hspi->Init.Direction == SPI_DIRECTION_2LINES) |
||
30 | mjames | 2716 | { |
2717 | __HAL_SPI_CLEAR_OVRFLAG(hspi); |
||
2718 | } |
||
50 | mjames | 2719 | |
2720 | hspi->TxXferCount = 0U; |
||
2721 | hspi->State = HAL_SPI_STATE_READY; |
||
2722 | |||
2723 | if (hspi->ErrorCode != HAL_SPI_ERROR_NONE) |
||
30 | mjames | 2724 | { |
50 | mjames | 2725 | /* Call user error callback */ |
2726 | #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U) |
||
2727 | hspi->ErrorCallback(hspi); |
||
2728 | #else |
||
30 | mjames | 2729 | HAL_SPI_ErrorCallback(hspi); |
50 | mjames | 2730 | #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ |
2731 | return; |
||
30 | mjames | 2732 | } |
2733 | } |
||
50 | mjames | 2734 | /* Call user Tx complete callback */ |
2735 | #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U) |
||
2736 | hspi->TxCpltCallback(hspi); |
||
2737 | #else |
||
2738 | HAL_SPI_TxCpltCallback(hspi); |
||
2739 | #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ |
||
30 | mjames | 2740 | } |
2741 | |||
2742 | /** |
||
50 | mjames | 2743 | * @brief DMA SPI receive process complete callback. |
2744 | * @param hdma pointer to a DMA_HandleTypeDef structure that contains |
||
2745 | * the configuration information for the specified DMA module. |
||
2746 | * @retval None |
||
30 | mjames | 2747 | */ |
50 | mjames | 2748 | static void SPI_DMAReceiveCplt(DMA_HandleTypeDef *hdma) |
30 | mjames | 2749 | { |
50 | mjames | 2750 | SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent); /* Derogation MISRAC2012-Rule-11.5 */ |
2751 | uint32_t tickstart; |
||
61 | mjames | 2752 | #if (USE_SPI_CRC != 0U) |
2753 | __IO uint32_t tmpreg = 0U; |
||
2754 | #endif /* USE_SPI_CRC */ |
||
50 | mjames | 2755 | |
2756 | /* Init tickstart for timeout management*/ |
||
2757 | tickstart = HAL_GetTick(); |
||
2758 | |||
2759 | /* DMA Normal Mode */ |
||
2760 | if ((hdma->Instance->CCR & DMA_CCR_CIRC) != DMA_CCR_CIRC) |
||
30 | mjames | 2761 | { |
50 | mjames | 2762 | /* Disable ERR interrupt */ |
2763 | __HAL_SPI_DISABLE_IT(hspi, SPI_IT_ERR); |
||
30 | mjames | 2764 | |
50 | mjames | 2765 | #if (USE_SPI_CRC != 0U) |
2766 | /* CRC handling */ |
||
2767 | if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) |
||
30 | mjames | 2768 | { |
50 | mjames | 2769 | /* Wait until RXNE flag */ |
2770 | if (SPI_WaitFlagStateUntilTimeout(hspi, SPI_FLAG_RXNE, SET, SPI_DEFAULT_TIMEOUT, tickstart) != HAL_OK) |
||
2771 | { |
||
2772 | /* Error on the CRC reception */ |
||
2773 | SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC); |
||
2774 | } |
||
2775 | /* Read CRC */ |
||
61 | mjames | 2776 | tmpreg = READ_REG(hspi->Instance->DR); |
2777 | /* To avoid GCC warning */ |
||
2778 | UNUSED(tmpreg); |
||
30 | mjames | 2779 | } |
50 | mjames | 2780 | #endif /* USE_SPI_CRC */ |
30 | mjames | 2781 | |
50 | mjames | 2782 | /* Check if we are in Master RX 2 line mode */ |
2783 | if ((hspi->Init.Direction == SPI_DIRECTION_2LINES) && (hspi->Init.Mode == SPI_MODE_MASTER)) |
||
30 | mjames | 2784 | { |
50 | mjames | 2785 | /* Disable Rx/Tx DMA Request (done by default to handle the case master rx direction 2 lines) */ |
2786 | CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN); |
||
30 | mjames | 2787 | } |
50 | mjames | 2788 | else |
2789 | { |
||
2790 | /* Normal case */ |
||
2791 | CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_RXDMAEN); |
||
2792 | } |
||
30 | mjames | 2793 | |
50 | mjames | 2794 | /* Check the end of the transaction */ |
2795 | if (SPI_EndRxTransaction(hspi, SPI_DEFAULT_TIMEOUT, tickstart) != HAL_OK) |
||
30 | mjames | 2796 | { |
50 | mjames | 2797 | hspi->ErrorCode = HAL_SPI_ERROR_FLAG; |
30 | mjames | 2798 | } |
2799 | |||
50 | mjames | 2800 | hspi->RxXferCount = 0U; |
2801 | hspi->State = HAL_SPI_STATE_READY; |
||
2802 | |||
2803 | #if (USE_SPI_CRC != 0U) |
||
30 | mjames | 2804 | /* Check if CRC error occurred */ |
50 | mjames | 2805 | if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_CRCERR)) |
30 | mjames | 2806 | { |
2807 | SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC); |
||
50 | mjames | 2808 | __HAL_SPI_CLEAR_CRCERRFLAG(hspi); |
2809 | } |
||
2810 | #endif /* USE_SPI_CRC */ |
||
30 | mjames | 2811 | |
50 | mjames | 2812 | if (hspi->ErrorCode != HAL_SPI_ERROR_NONE) |
2813 | { |
||
2814 | /* Call user error callback */ |
||
2815 | #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U) |
||
2816 | hspi->ErrorCallback(hspi); |
||
2817 | #else |
||
2818 | HAL_SPI_ErrorCallback(hspi); |
||
2819 | #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ |
||
2820 | return; |
||
30 | mjames | 2821 | } |
2822 | } |
||
50 | mjames | 2823 | /* Call user Rx complete callback */ |
2824 | #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U) |
||
2825 | hspi->RxCpltCallback(hspi); |
||
2826 | #else |
||
2827 | HAL_SPI_RxCpltCallback(hspi); |
||
2828 | #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ |
||
2829 | } |
||
30 | mjames | 2830 | |
50 | mjames | 2831 | /** |
2832 | * @brief DMA SPI transmit receive process complete callback. |
||
2833 | * @param hdma pointer to a DMA_HandleTypeDef structure that contains |
||
2834 | * the configuration information for the specified DMA module. |
||
2835 | * @retval None |
||
2836 | */ |
||
2837 | static void SPI_DMATransmitReceiveCplt(DMA_HandleTypeDef *hdma) |
||
2838 | { |
||
2839 | SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent); /* Derogation MISRAC2012-Rule-11.5 */ |
||
2840 | uint32_t tickstart; |
||
61 | mjames | 2841 | #if (USE_SPI_CRC != 0U) |
2842 | __IO uint32_t tmpreg = 0U; |
||
2843 | #endif /* USE_SPI_CRC */ |
||
30 | mjames | 2844 | |
50 | mjames | 2845 | /* Init tickstart for timeout management*/ |
2846 | tickstart = HAL_GetTick(); |
||
2847 | |||
2848 | /* DMA Normal Mode */ |
||
2849 | if ((hdma->Instance->CCR & DMA_CCR_CIRC) != DMA_CCR_CIRC) |
||
30 | mjames | 2850 | { |
2851 | /* Disable ERR interrupt */ |
||
50 | mjames | 2852 | __HAL_SPI_DISABLE_IT(hspi, SPI_IT_ERR); |
30 | mjames | 2853 | |
50 | mjames | 2854 | #if (USE_SPI_CRC != 0U) |
2855 | /* CRC handling */ |
||
2856 | if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) |
||
30 | mjames | 2857 | { |
50 | mjames | 2858 | /* Wait the CRC data */ |
2859 | if (SPI_WaitFlagStateUntilTimeout(hspi, SPI_FLAG_RXNE, SET, SPI_DEFAULT_TIMEOUT, tickstart) != HAL_OK) |
||
30 | mjames | 2860 | { |
50 | mjames | 2861 | SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC); |
30 | mjames | 2862 | } |
50 | mjames | 2863 | /* Read CRC to Flush DR and RXNE flag */ |
61 | mjames | 2864 | tmpreg = READ_REG(hspi->Instance->DR); |
2865 | /* To avoid GCC warning */ |
||
2866 | UNUSED(tmpreg); |
||
30 | mjames | 2867 | } |
50 | mjames | 2868 | #endif /* USE_SPI_CRC */ |
2869 | |||
2870 | /* Check the end of the transaction */ |
||
2871 | if (SPI_EndRxTxTransaction(hspi, SPI_DEFAULT_TIMEOUT, tickstart) != HAL_OK) |
||
30 | mjames | 2872 | { |
50 | mjames | 2873 | SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG); |
2874 | } |
||
2875 | |||
2876 | /* Disable Rx/Tx DMA Request */ |
||
2877 | CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN); |
||
2878 | |||
2879 | hspi->TxXferCount = 0U; |
||
2880 | hspi->RxXferCount = 0U; |
||
2881 | hspi->State = HAL_SPI_STATE_READY; |
||
2882 | |||
2883 | #if (USE_SPI_CRC != 0U) |
||
2884 | /* Check if CRC error occurred */ |
||
2885 | if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_CRCERR)) |
||
2886 | { |
||
2887 | SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC); |
||
2888 | __HAL_SPI_CLEAR_CRCERRFLAG(hspi); |
||
2889 | } |
||
2890 | #endif /* USE_SPI_CRC */ |
||
2891 | |||
2892 | if (hspi->ErrorCode != HAL_SPI_ERROR_NONE) |
||
2893 | { |
||
2894 | /* Call user error callback */ |
||
2895 | #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U) |
||
2896 | hspi->ErrorCallback(hspi); |
||
2897 | #else |
||
30 | mjames | 2898 | HAL_SPI_ErrorCallback(hspi); |
50 | mjames | 2899 | #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ |
2900 | return; |
||
30 | mjames | 2901 | } |
2902 | } |
||
50 | mjames | 2903 | /* Call user TxRx complete callback */ |
2904 | #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U) |
||
2905 | hspi->TxRxCpltCallback(hspi); |
||
2906 | #else |
||
2907 | HAL_SPI_TxRxCpltCallback(hspi); |
||
2908 | #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ |
||
30 | mjames | 2909 | } |
2910 | |||
2911 | /** |
||
50 | mjames | 2912 | * @brief DMA SPI half transmit process complete callback. |
2913 | * @param hdma pointer to a DMA_HandleTypeDef structure that contains |
||
2914 | * the configuration information for the specified DMA module. |
||
2915 | * @retval None |
||
30 | mjames | 2916 | */ |
50 | mjames | 2917 | static void SPI_DMAHalfTransmitCplt(DMA_HandleTypeDef *hdma) |
30 | mjames | 2918 | { |
50 | mjames | 2919 | SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent); /* Derogation MISRAC2012-Rule-11.5 */ |
2920 | |||
2921 | /* Call user Tx half complete callback */ |
||
2922 | #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U) |
||
2923 | hspi->TxHalfCpltCallback(hspi); |
||
2924 | #else |
||
2925 | HAL_SPI_TxHalfCpltCallback(hspi); |
||
2926 | #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ |
||
2927 | } |
||
2928 | |||
2929 | /** |
||
2930 | * @brief DMA SPI half receive process complete callback |
||
2931 | * @param hdma pointer to a DMA_HandleTypeDef structure that contains |
||
2932 | * the configuration information for the specified DMA module. |
||
2933 | * @retval None |
||
2934 | */ |
||
2935 | static void SPI_DMAHalfReceiveCplt(DMA_HandleTypeDef *hdma) |
||
2936 | { |
||
2937 | SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent); /* Derogation MISRAC2012-Rule-11.5 */ |
||
2938 | |||
2939 | /* Call user Rx half complete callback */ |
||
2940 | #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U) |
||
2941 | hspi->RxHalfCpltCallback(hspi); |
||
2942 | #else |
||
2943 | HAL_SPI_RxHalfCpltCallback(hspi); |
||
2944 | #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ |
||
2945 | } |
||
2946 | |||
2947 | /** |
||
2948 | * @brief DMA SPI half transmit receive process complete callback. |
||
2949 | * @param hdma pointer to a DMA_HandleTypeDef structure that contains |
||
2950 | * the configuration information for the specified DMA module. |
||
2951 | * @retval None |
||
2952 | */ |
||
2953 | static void SPI_DMAHalfTransmitReceiveCplt(DMA_HandleTypeDef *hdma) |
||
2954 | { |
||
2955 | SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent); /* Derogation MISRAC2012-Rule-11.5 */ |
||
2956 | |||
2957 | /* Call user TxRx half complete callback */ |
||
2958 | #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U) |
||
2959 | hspi->TxRxHalfCpltCallback(hspi); |
||
2960 | #else |
||
2961 | HAL_SPI_TxRxHalfCpltCallback(hspi); |
||
2962 | #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ |
||
2963 | } |
||
2964 | |||
2965 | /** |
||
2966 | * @brief DMA SPI communication error callback. |
||
2967 | * @param hdma pointer to a DMA_HandleTypeDef structure that contains |
||
2968 | * the configuration information for the specified DMA module. |
||
2969 | * @retval None |
||
2970 | */ |
||
2971 | static void SPI_DMAError(DMA_HandleTypeDef *hdma) |
||
2972 | { |
||
2973 | SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent); /* Derogation MISRAC2012-Rule-11.5 */ |
||
2974 | |||
2975 | /* Stop the disable DMA transfer on SPI side */ |
||
2976 | CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN); |
||
2977 | |||
2978 | SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_DMA); |
||
2979 | hspi->State = HAL_SPI_STATE_READY; |
||
2980 | /* Call user error callback */ |
||
2981 | #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U) |
||
2982 | hspi->ErrorCallback(hspi); |
||
2983 | #else |
||
2984 | HAL_SPI_ErrorCallback(hspi); |
||
2985 | #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ |
||
2986 | } |
||
2987 | |||
2988 | /** |
||
2989 | * @brief DMA SPI communication abort callback, when initiated by HAL services on Error |
||
2990 | * (To be called at end of DMA Abort procedure following error occurrence). |
||
2991 | * @param hdma DMA handle. |
||
2992 | * @retval None |
||
2993 | */ |
||
2994 | static void SPI_DMAAbortOnError(DMA_HandleTypeDef *hdma) |
||
2995 | { |
||
2996 | SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent); /* Derogation MISRAC2012-Rule-11.5 */ |
||
2997 | hspi->RxXferCount = 0U; |
||
2998 | hspi->TxXferCount = 0U; |
||
2999 | |||
3000 | /* Call user error callback */ |
||
3001 | #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U) |
||
3002 | hspi->ErrorCallback(hspi); |
||
3003 | #else |
||
3004 | HAL_SPI_ErrorCallback(hspi); |
||
3005 | #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ |
||
3006 | } |
||
3007 | |||
3008 | /** |
||
3009 | * @brief DMA SPI Tx communication abort callback, when initiated by user |
||
3010 | * (To be called at end of DMA Tx Abort procedure following user abort request). |
||
3011 | * @note When this callback is executed, User Abort complete call back is called only if no |
||
3012 | * Abort still ongoing for Rx DMA Handle. |
||
3013 | * @param hdma DMA handle. |
||
3014 | * @retval None |
||
3015 | */ |
||
3016 | static void SPI_DMATxAbortCallback(DMA_HandleTypeDef *hdma) |
||
3017 | { |
||
3018 | SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent); /* Derogation MISRAC2012-Rule-11.5 */ |
||
3019 | __IO uint32_t count; |
||
3020 | |||
3021 | hspi->hdmatx->XferAbortCallback = NULL; |
||
3022 | count = SPI_DEFAULT_TIMEOUT * (SystemCoreClock / 24U / 1000U); |
||
3023 | |||
3024 | /* Disable Tx DMA Request */ |
||
3025 | CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_TXDMAEN); |
||
3026 | |||
3027 | /* Wait until TXE flag is set */ |
||
3028 | do |
||
30 | mjames | 3029 | { |
50 | mjames | 3030 | if (count == 0U) |
3031 | { |
||
3032 | SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_ABORT); |
||
3033 | break; |
||
3034 | } |
||
3035 | count--; |
||
3036 | } while ((hspi->Instance->SR & SPI_FLAG_TXE) == RESET); |
||
3037 | |||
3038 | /* Check if an Abort process is still ongoing */ |
||
3039 | if (hspi->hdmarx != NULL) |
||
30 | mjames | 3040 | { |
50 | mjames | 3041 | if (hspi->hdmarx->XferAbortCallback != NULL) |
3042 | { |
||
3043 | return; |
||
3044 | } |
||
30 | mjames | 3045 | } |
3046 | |||
50 | mjames | 3047 | /* No Abort process still ongoing : All DMA Stream/Channel are aborted, call user Abort Complete callback */ |
3048 | hspi->RxXferCount = 0U; |
||
3049 | hspi->TxXferCount = 0U; |
||
3050 | |||
3051 | /* Check no error during Abort procedure */ |
||
3052 | if (hspi->ErrorCode != HAL_SPI_ERROR_ABORT) |
||
30 | mjames | 3053 | { |
50 | mjames | 3054 | /* Reset errorCode */ |
3055 | hspi->ErrorCode = HAL_SPI_ERROR_NONE; |
||
30 | mjames | 3056 | } |
50 | mjames | 3057 | |
3058 | /* Clear the Error flags in the SR register */ |
||
3059 | __HAL_SPI_CLEAR_OVRFLAG(hspi); |
||
3060 | #if defined(SPI_CR2_FRF) |
||
3061 | __HAL_SPI_CLEAR_FREFLAG(hspi); |
||
3062 | #endif |
||
3063 | |||
3064 | /* Restore hspi->State to Ready */ |
||
3065 | hspi->State = HAL_SPI_STATE_READY; |
||
3066 | |||
3067 | /* Call user Abort complete callback */ |
||
3068 | #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U) |
||
3069 | hspi->AbortCpltCallback(hspi); |
||
3070 | #else |
||
3071 | HAL_SPI_AbortCpltCallback(hspi); |
||
3072 | #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ |
||
30 | mjames | 3073 | } |
3074 | |||
3075 | /** |
||
50 | mjames | 3076 | * @brief DMA SPI Rx communication abort callback, when initiated by user |
3077 | * (To be called at end of DMA Rx Abort procedure following user abort request). |
||
3078 | * @note When this callback is executed, User Abort complete call back is called only if no |
||
3079 | * Abort still ongoing for Tx DMA Handle. |
||
3080 | * @param hdma DMA handle. |
||
3081 | * @retval None |
||
30 | mjames | 3082 | */ |
50 | mjames | 3083 | static void SPI_DMARxAbortCallback(DMA_HandleTypeDef *hdma) |
30 | mjames | 3084 | { |
50 | mjames | 3085 | SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent); /* Derogation MISRAC2012-Rule-11.5 */ |
3086 | |||
3087 | /* Disable SPI Peripheral */ |
||
3088 | __HAL_SPI_DISABLE(hspi); |
||
3089 | |||
3090 | hspi->hdmarx->XferAbortCallback = NULL; |
||
3091 | |||
3092 | /* Disable Rx DMA Request */ |
||
3093 | CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_RXDMAEN); |
||
3094 | |||
3095 | /* Check Busy flag */ |
||
3096 | if (SPI_EndRxTxTransaction(hspi, SPI_DEFAULT_TIMEOUT, HAL_GetTick()) != HAL_OK) |
||
30 | mjames | 3097 | { |
50 | mjames | 3098 | SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_ABORT); |
30 | mjames | 3099 | } |
50 | mjames | 3100 | |
3101 | /* Check if an Abort process is still ongoing */ |
||
3102 | if (hspi->hdmatx != NULL) |
||
30 | mjames | 3103 | { |
50 | mjames | 3104 | if (hspi->hdmatx->XferAbortCallback != NULL) |
3105 | { |
||
3106 | return; |
||
3107 | } |
||
30 | mjames | 3108 | } |
3109 | |||
50 | mjames | 3110 | /* No Abort process still ongoing : All DMA Stream/Channel are aborted, call user Abort Complete callback */ |
3111 | hspi->RxXferCount = 0U; |
||
3112 | hspi->TxXferCount = 0U; |
||
3113 | |||
3114 | /* Check no error during Abort procedure */ |
||
3115 | if (hspi->ErrorCode != HAL_SPI_ERROR_ABORT) |
||
30 | mjames | 3116 | { |
50 | mjames | 3117 | /* Reset errorCode */ |
3118 | hspi->ErrorCode = HAL_SPI_ERROR_NONE; |
||
30 | mjames | 3119 | } |
3120 | |||
50 | mjames | 3121 | /* Clear the Error flags in the SR register */ |
3122 | __HAL_SPI_CLEAR_OVRFLAG(hspi); |
||
3123 | #if defined(SPI_CR2_FRF) |
||
3124 | __HAL_SPI_CLEAR_FREFLAG(hspi); |
||
3125 | #endif |
||
3126 | |||
3127 | /* Restore hspi->State to Ready */ |
||
3128 | hspi->State = HAL_SPI_STATE_READY; |
||
3129 | |||
3130 | /* Call user Abort complete callback */ |
||
3131 | #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U) |
||
3132 | hspi->AbortCpltCallback(hspi); |
||
3133 | #else |
||
3134 | HAL_SPI_AbortCpltCallback(hspi); |
||
3135 | #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ |
||
30 | mjames | 3136 | } |
3137 | |||
3138 | /** |
||
50 | mjames | 3139 | * @brief Rx 8-bit handler for Transmit and Receive in Interrupt mode. |
3140 | * @param hspi pointer to a SPI_HandleTypeDef structure that contains |
||
3141 | * the configuration information for SPI module. |
||
30 | mjames | 3142 | * @retval None |
3143 | */ |
||
50 | mjames | 3144 | static void SPI_2linesRxISR_8BIT(struct __SPI_HandleTypeDef *hspi) |
30 | mjames | 3145 | { |
50 | mjames | 3146 | /* Receive data in 8bit mode */ |
3147 | *hspi->pRxBuffPtr = *((__IO uint8_t *)&hspi->Instance->DR); |
||
3148 | hspi->pRxBuffPtr++; |
||
3149 | hspi->RxXferCount--; |
||
30 | mjames | 3150 | |
50 | mjames | 3151 | /* Check end of the reception */ |
3152 | if (hspi->RxXferCount == 0U) |
||
30 | mjames | 3153 | { |
50 | mjames | 3154 | #if (USE_SPI_CRC != 0U) |
3155 | if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) |
||
30 | mjames | 3156 | { |
50 | mjames | 3157 | hspi->RxISR = SPI_2linesRxISR_8BITCRC; |
3158 | return; |
||
30 | mjames | 3159 | } |
50 | mjames | 3160 | #endif /* USE_SPI_CRC */ |
30 | mjames | 3161 | |
50 | mjames | 3162 | /* Disable RXNE and ERR interrupt */ |
3163 | __HAL_SPI_DISABLE_IT(hspi, (SPI_IT_RXNE | SPI_IT_ERR)); |
||
30 | mjames | 3164 | |
50 | mjames | 3165 | if (hspi->TxXferCount == 0U) |
30 | mjames | 3166 | { |
50 | mjames | 3167 | SPI_CloseRxTx_ISR(hspi); |
30 | mjames | 3168 | } |
3169 | } |
||
50 | mjames | 3170 | } |
30 | mjames | 3171 | |
50 | mjames | 3172 | #if (USE_SPI_CRC != 0U) |
3173 | /** |
||
3174 | * @brief Rx 8-bit handler for Transmit and Receive in Interrupt mode. |
||
3175 | * @param hspi pointer to a SPI_HandleTypeDef structure that contains |
||
3176 | * the configuration information for SPI module. |
||
3177 | * @retval None |
||
3178 | */ |
||
3179 | static void SPI_2linesRxISR_8BITCRC(struct __SPI_HandleTypeDef *hspi) |
||
3180 | { |
||
61 | mjames | 3181 | __IO uint8_t * ptmpreg8; |
3182 | __IO uint8_t tmpreg8 = 0; |
||
3183 | |||
3184 | /* Initialize the 8bit temporary pointer */ |
||
3185 | ptmpreg8 = (__IO uint8_t *)&hspi->Instance->DR; |
||
50 | mjames | 3186 | /* Read 8bit CRC to flush Data Register */ |
61 | mjames | 3187 | tmpreg8 = *ptmpreg8; |
3188 | /* To avoid GCC warning */ |
||
3189 | UNUSED(tmpreg8); |
||
30 | mjames | 3190 | |
50 | mjames | 3191 | /* Disable RXNE and ERR interrupt */ |
3192 | __HAL_SPI_DISABLE_IT(hspi, (SPI_IT_RXNE | SPI_IT_ERR)); |
||
3193 | |||
3194 | if (hspi->TxXferCount == 0U) |
||
30 | mjames | 3195 | { |
50 | mjames | 3196 | SPI_CloseRxTx_ISR(hspi); |
30 | mjames | 3197 | } |
3198 | } |
||
50 | mjames | 3199 | #endif /* USE_SPI_CRC */ |
30 | mjames | 3200 | |
3201 | /** |
||
50 | mjames | 3202 | * @brief Tx 8-bit handler for Transmit and Receive in Interrupt mode. |
3203 | * @param hspi pointer to a SPI_HandleTypeDef structure that contains |
||
3204 | * the configuration information for SPI module. |
||
30 | mjames | 3205 | * @retval None |
3206 | */ |
||
50 | mjames | 3207 | static void SPI_2linesTxISR_8BIT(struct __SPI_HandleTypeDef *hspi) |
30 | mjames | 3208 | { |
50 | mjames | 3209 | *(__IO uint8_t *)&hspi->Instance->DR = (*hspi->pTxBuffPtr); |
3210 | hspi->pTxBuffPtr++; |
||
3211 | hspi->TxXferCount--; |
||
30 | mjames | 3212 | |
50 | mjames | 3213 | /* Check the end of the transmission */ |
3214 | if (hspi->TxXferCount == 0U) |
||
30 | mjames | 3215 | { |
50 | mjames | 3216 | #if (USE_SPI_CRC != 0U) |
3217 | if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) |
||
30 | mjames | 3218 | { |
50 | mjames | 3219 | /* Set CRC Next Bit to send CRC */ |
3220 | SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT); |
||
3221 | /* Disable TXE interrupt */ |
||
3222 | __HAL_SPI_DISABLE_IT(hspi, SPI_IT_TXE); |
||
3223 | return; |
||
30 | mjames | 3224 | } |
50 | mjames | 3225 | #endif /* USE_SPI_CRC */ |
30 | mjames | 3226 | |
50 | mjames | 3227 | /* Disable TXE interrupt */ |
3228 | __HAL_SPI_DISABLE_IT(hspi, SPI_IT_TXE); |
||
30 | mjames | 3229 | |
50 | mjames | 3230 | if (hspi->RxXferCount == 0U) |
30 | mjames | 3231 | { |
50 | mjames | 3232 | SPI_CloseRxTx_ISR(hspi); |
3233 | } |
||
3234 | } |
||
3235 | } |
||
30 | mjames | 3236 | |
50 | mjames | 3237 | /** |
3238 | * @brief Rx 16-bit handler for Transmit and Receive in Interrupt mode. |
||
3239 | * @param hspi pointer to a SPI_HandleTypeDef structure that contains |
||
3240 | * the configuration information for SPI module. |
||
3241 | * @retval None |
||
3242 | */ |
||
3243 | static void SPI_2linesRxISR_16BIT(struct __SPI_HandleTypeDef *hspi) |
||
3244 | { |
||
3245 | /* Receive data in 16 Bit mode */ |
||
3246 | *((uint16_t *)hspi->pRxBuffPtr) = (uint16_t)(hspi->Instance->DR); |
||
3247 | hspi->pRxBuffPtr += sizeof(uint16_t); |
||
3248 | hspi->RxXferCount--; |
||
30 | mjames | 3249 | |
50 | mjames | 3250 | if (hspi->RxXferCount == 0U) |
3251 | { |
||
3252 | #if (USE_SPI_CRC != 0U) |
||
3253 | if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) |
||
3254 | { |
||
3255 | hspi->RxISR = SPI_2linesRxISR_16BITCRC; |
||
3256 | return; |
||
30 | mjames | 3257 | } |
50 | mjames | 3258 | #endif /* USE_SPI_CRC */ |
30 | mjames | 3259 | |
50 | mjames | 3260 | /* Disable RXNE interrupt */ |
3261 | __HAL_SPI_DISABLE_IT(hspi, SPI_IT_RXNE); |
||
30 | mjames | 3262 | |
50 | mjames | 3263 | if (hspi->TxXferCount == 0U) |
30 | mjames | 3264 | { |
50 | mjames | 3265 | SPI_CloseRxTx_ISR(hspi); |
30 | mjames | 3266 | } |
3267 | } |
||
3268 | } |
||
3269 | |||
50 | mjames | 3270 | #if (USE_SPI_CRC != 0U) |
30 | mjames | 3271 | /** |
50 | mjames | 3272 | * @brief Manage the CRC 16-bit receive for Transmit and Receive in Interrupt mode. |
3273 | * @param hspi pointer to a SPI_HandleTypeDef structure that contains |
||
3274 | * the configuration information for SPI module. |
||
30 | mjames | 3275 | * @retval None |
3276 | */ |
||
50 | mjames | 3277 | static void SPI_2linesRxISR_16BITCRC(struct __SPI_HandleTypeDef *hspi) |
30 | mjames | 3278 | { |
61 | mjames | 3279 | __IO uint32_t tmpreg = 0U; |
3280 | |||
50 | mjames | 3281 | /* Read 16bit CRC to flush Data Register */ |
61 | mjames | 3282 | tmpreg = READ_REG(hspi->Instance->DR); |
3283 | /* To avoid GCC warning */ |
||
3284 | UNUSED(tmpreg); |
||
30 | mjames | 3285 | |
50 | mjames | 3286 | /* Disable RXNE interrupt */ |
3287 | __HAL_SPI_DISABLE_IT(hspi, SPI_IT_RXNE); |
||
30 | mjames | 3288 | |
50 | mjames | 3289 | SPI_CloseRxTx_ISR(hspi); |
3290 | } |
||
3291 | #endif /* USE_SPI_CRC */ |
||
30 | mjames | 3292 | |
50 | mjames | 3293 | /** |
3294 | * @brief Tx 16-bit handler for Transmit and Receive in Interrupt mode. |
||
3295 | * @param hspi pointer to a SPI_HandleTypeDef structure that contains |
||
3296 | * the configuration information for SPI module. |
||
3297 | * @retval None |
||
3298 | */ |
||
3299 | static void SPI_2linesTxISR_16BIT(struct __SPI_HandleTypeDef *hspi) |
||
3300 | { |
||
3301 | /* Transmit data in 16 Bit mode */ |
||
3302 | hspi->Instance->DR = *((uint16_t *)hspi->pTxBuffPtr); |
||
3303 | hspi->pTxBuffPtr += sizeof(uint16_t); |
||
3304 | hspi->TxXferCount--; |
||
30 | mjames | 3305 | |
50 | mjames | 3306 | /* Enable CRC Transmission */ |
3307 | if (hspi->TxXferCount == 0U) |
||
3308 | { |
||
3309 | #if (USE_SPI_CRC != 0U) |
||
3310 | if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) |
||
30 | mjames | 3311 | { |
50 | mjames | 3312 | /* Set CRC Next Bit to send CRC */ |
3313 | SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT); |
||
3314 | /* Disable TXE interrupt */ |
||
3315 | __HAL_SPI_DISABLE_IT(hspi, SPI_IT_TXE); |
||
3316 | return; |
||
30 | mjames | 3317 | } |
50 | mjames | 3318 | #endif /* USE_SPI_CRC */ |
30 | mjames | 3319 | |
50 | mjames | 3320 | /* Disable TXE interrupt */ |
3321 | __HAL_SPI_DISABLE_IT(hspi, SPI_IT_TXE); |
||
3322 | |||
3323 | if (hspi->RxXferCount == 0U) |
||
30 | mjames | 3324 | { |
50 | mjames | 3325 | SPI_CloseRxTx_ISR(hspi); |
30 | mjames | 3326 | } |
50 | mjames | 3327 | } |
3328 | } |
||
30 | mjames | 3329 | |
50 | mjames | 3330 | #if (USE_SPI_CRC != 0U) |
3331 | /** |
||
3332 | * @brief Manage the CRC 8-bit receive in Interrupt context. |
||
3333 | * @param hspi pointer to a SPI_HandleTypeDef structure that contains |
||
3334 | * the configuration information for SPI module. |
||
3335 | * @retval None |
||
3336 | */ |
||
3337 | static void SPI_RxISR_8BITCRC(struct __SPI_HandleTypeDef *hspi) |
||
3338 | { |
||
61 | mjames | 3339 | __IO uint8_t * ptmpreg8; |
3340 | __IO uint8_t tmpreg8 = 0; |
||
3341 | |||
3342 | /* Initialize the 8bit temporary pointer */ |
||
3343 | ptmpreg8 = (__IO uint8_t *)&hspi->Instance->DR; |
||
50 | mjames | 3344 | /* Read 8bit CRC to flush Data Register */ |
61 | mjames | 3345 | tmpreg8 = *ptmpreg8; |
3346 | /* To avoid GCC warning */ |
||
3347 | UNUSED(tmpreg8); |
||
30 | mjames | 3348 | |
50 | mjames | 3349 | SPI_CloseRx_ISR(hspi); |
3350 | } |
||
3351 | #endif /* USE_SPI_CRC */ |
||
30 | mjames | 3352 | |
50 | mjames | 3353 | /** |
3354 | * @brief Manage the receive 8-bit in Interrupt context. |
||
3355 | * @param hspi pointer to a SPI_HandleTypeDef structure that contains |
||
3356 | * the configuration information for SPI module. |
||
3357 | * @retval None |
||
3358 | */ |
||
3359 | static void SPI_RxISR_8BIT(struct __SPI_HandleTypeDef *hspi) |
||
3360 | { |
||
3361 | *hspi->pRxBuffPtr = (*(__IO uint8_t *)&hspi->Instance->DR); |
||
3362 | hspi->pRxBuffPtr++; |
||
3363 | hspi->RxXferCount--; |
||
30 | mjames | 3364 | |
50 | mjames | 3365 | #if (USE_SPI_CRC != 0U) |
3366 | /* Enable CRC Transmission */ |
||
3367 | if ((hspi->RxXferCount == 1U) && (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)) |
||
3368 | { |
||
3369 | SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT); |
||
3370 | } |
||
3371 | #endif /* USE_SPI_CRC */ |
||
3372 | |||
3373 | if (hspi->RxXferCount == 0U) |
||
3374 | { |
||
3375 | #if (USE_SPI_CRC != 0U) |
||
3376 | if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) |
||
30 | mjames | 3377 | { |
50 | mjames | 3378 | hspi->RxISR = SPI_RxISR_8BITCRC; |
3379 | return; |
||
30 | mjames | 3380 | } |
50 | mjames | 3381 | #endif /* USE_SPI_CRC */ |
3382 | SPI_CloseRx_ISR(hspi); |
||
30 | mjames | 3383 | } |
3384 | } |
||
3385 | |||
50 | mjames | 3386 | #if (USE_SPI_CRC != 0U) |
30 | mjames | 3387 | /** |
50 | mjames | 3388 | * @brief Manage the CRC 16-bit receive in Interrupt context. |
3389 | * @param hspi pointer to a SPI_HandleTypeDef structure that contains |
||
3390 | * the configuration information for SPI module. |
||
30 | mjames | 3391 | * @retval None |
3392 | */ |
||
50 | mjames | 3393 | static void SPI_RxISR_16BITCRC(struct __SPI_HandleTypeDef *hspi) |
30 | mjames | 3394 | { |
61 | mjames | 3395 | __IO uint32_t tmpreg = 0U; |
3396 | |||
50 | mjames | 3397 | /* Read 16bit CRC to flush Data Register */ |
61 | mjames | 3398 | tmpreg = READ_REG(hspi->Instance->DR); |
3399 | /* To avoid GCC warning */ |
||
3400 | UNUSED(tmpreg); |
||
30 | mjames | 3401 | |
50 | mjames | 3402 | /* Disable RXNE and ERR interrupt */ |
3403 | __HAL_SPI_DISABLE_IT(hspi, (SPI_IT_RXNE | SPI_IT_ERR)); |
||
3404 | |||
3405 | SPI_CloseRx_ISR(hspi); |
||
30 | mjames | 3406 | } |
50 | mjames | 3407 | #endif /* USE_SPI_CRC */ |
30 | mjames | 3408 | |
3409 | /** |
||
50 | mjames | 3410 | * @brief Manage the 16-bit receive in Interrupt context. |
3411 | * @param hspi pointer to a SPI_HandleTypeDef structure that contains |
||
3412 | * the configuration information for SPI module. |
||
30 | mjames | 3413 | * @retval None |
3414 | */ |
||
50 | mjames | 3415 | static void SPI_RxISR_16BIT(struct __SPI_HandleTypeDef *hspi) |
30 | mjames | 3416 | { |
50 | mjames | 3417 | *((uint16_t *)hspi->pRxBuffPtr) = (uint16_t)(hspi->Instance->DR); |
3418 | hspi->pRxBuffPtr += sizeof(uint16_t); |
||
3419 | hspi->RxXferCount--; |
||
30 | mjames | 3420 | |
50 | mjames | 3421 | #if (USE_SPI_CRC != 0U) |
3422 | /* Enable CRC Transmission */ |
||
3423 | if ((hspi->RxXferCount == 1U) && (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)) |
||
3424 | { |
||
3425 | SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT); |
||
3426 | } |
||
3427 | #endif /* USE_SPI_CRC */ |
||
3428 | |||
3429 | if (hspi->RxXferCount == 0U) |
||
3430 | { |
||
3431 | #if (USE_SPI_CRC != 0U) |
||
3432 | if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) |
||
3433 | { |
||
3434 | hspi->RxISR = SPI_RxISR_16BITCRC; |
||
3435 | return; |
||
3436 | } |
||
3437 | #endif /* USE_SPI_CRC */ |
||
3438 | SPI_CloseRx_ISR(hspi); |
||
3439 | } |
||
30 | mjames | 3440 | } |
3441 | |||
3442 | /** |
||
50 | mjames | 3443 | * @brief Handle the data 8-bit transmit in Interrupt mode. |
3444 | * @param hspi pointer to a SPI_HandleTypeDef structure that contains |
||
3445 | * the configuration information for SPI module. |
||
30 | mjames | 3446 | * @retval None |
3447 | */ |
||
50 | mjames | 3448 | static void SPI_TxISR_8BIT(struct __SPI_HandleTypeDef *hspi) |
30 | mjames | 3449 | { |
50 | mjames | 3450 | *(__IO uint8_t *)&hspi->Instance->DR = (*hspi->pTxBuffPtr); |
3451 | hspi->pTxBuffPtr++; |
||
3452 | hspi->TxXferCount--; |
||
30 | mjames | 3453 | |
50 | mjames | 3454 | if (hspi->TxXferCount == 0U) |
3455 | { |
||
3456 | #if (USE_SPI_CRC != 0U) |
||
3457 | if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) |
||
3458 | { |
||
3459 | /* Enable CRC Transmission */ |
||
3460 | SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT); |
||
3461 | } |
||
3462 | #endif /* USE_SPI_CRC */ |
||
3463 | SPI_CloseTx_ISR(hspi); |
||
3464 | } |
||
30 | mjames | 3465 | } |
3466 | |||
3467 | /** |
||
50 | mjames | 3468 | * @brief Handle the data 16-bit transmit in Interrupt mode. |
3469 | * @param hspi pointer to a SPI_HandleTypeDef structure that contains |
||
3470 | * the configuration information for SPI module. |
||
30 | mjames | 3471 | * @retval None |
3472 | */ |
||
50 | mjames | 3473 | static void SPI_TxISR_16BIT(struct __SPI_HandleTypeDef *hspi) |
30 | mjames | 3474 | { |
50 | mjames | 3475 | /* Transmit data in 16 Bit mode */ |
3476 | hspi->Instance->DR = *((uint16_t *)hspi->pTxBuffPtr); |
||
3477 | hspi->pTxBuffPtr += sizeof(uint16_t); |
||
3478 | hspi->TxXferCount--; |
||
3479 | |||
3480 | if (hspi->TxXferCount == 0U) |
||
3481 | { |
||
3482 | #if (USE_SPI_CRC != 0U) |
||
3483 | if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) |
||
3484 | { |
||
3485 | /* Enable CRC Transmission */ |
||
3486 | SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT); |
||
3487 | } |
||
3488 | #endif /* USE_SPI_CRC */ |
||
3489 | SPI_CloseTx_ISR(hspi); |
||
3490 | } |
||
30 | mjames | 3491 | } |
3492 | |||
3493 | /** |
||
50 | mjames | 3494 | * @brief Handle SPI Communication Timeout. |
3495 | * @param hspi pointer to a SPI_HandleTypeDef structure that contains |
||
3496 | * the configuration information for SPI module. |
||
3497 | * @param Flag SPI flag to check |
||
3498 | * @param State flag state to check |
||
3499 | * @param Timeout Timeout duration |
||
3500 | * @param Tickstart tick start value |
||
30 | mjames | 3501 | * @retval HAL status |
3502 | */ |
||
50 | mjames | 3503 | static HAL_StatusTypeDef SPI_WaitFlagStateUntilTimeout(SPI_HandleTypeDef *hspi, uint32_t Flag, FlagStatus State, |
3504 | uint32_t Timeout, uint32_t Tickstart) |
||
30 | mjames | 3505 | { |
50 | mjames | 3506 | __IO uint32_t count; |
3507 | uint32_t tmp_timeout; |
||
3508 | uint32_t tmp_tickstart; |
||
30 | mjames | 3509 | |
50 | mjames | 3510 | /* Adjust Timeout value in case of end of transfer */ |
3511 | tmp_timeout = Timeout - (HAL_GetTick() - Tickstart); |
||
3512 | tmp_tickstart = HAL_GetTick(); |
||
30 | mjames | 3513 | |
50 | mjames | 3514 | /* Calculate Timeout based on a software loop to avoid blocking issue if Systick is disabled */ |
3515 | count = tmp_timeout * ((SystemCoreClock * 32U) >> 20U); |
||
3516 | |||
3517 | while ((__HAL_SPI_GET_FLAG(hspi, Flag) ? SET : RESET) != State) |
||
30 | mjames | 3518 | { |
50 | mjames | 3519 | if (Timeout != HAL_MAX_DELAY) |
30 | mjames | 3520 | { |
50 | mjames | 3521 | if (((HAL_GetTick() - tmp_tickstart) >= tmp_timeout) || (tmp_timeout == 0U)) |
30 | mjames | 3522 | { |
50 | mjames | 3523 | /* Disable the SPI and reset the CRC: the CRC value should be cleared |
3524 | on both master and slave sides in order to resynchronize the master |
||
3525 | and slave for their respective CRC calculation */ |
||
30 | mjames | 3526 | |
50 | mjames | 3527 | /* Disable TXE, RXNE and ERR interrupts for the interrupt process */ |
3528 | __HAL_SPI_DISABLE_IT(hspi, (SPI_IT_TXE | SPI_IT_RXNE | SPI_IT_ERR)); |
||
30 | mjames | 3529 | |
50 | mjames | 3530 | if ((hspi->Init.Mode == SPI_MODE_MASTER) && ((hspi->Init.Direction == SPI_DIRECTION_1LINE) |
3531 | || (hspi->Init.Direction == SPI_DIRECTION_2LINES_RXONLY))) |
||
3532 | { |
||
30 | mjames | 3533 | /* Disable SPI peripheral */ |
3534 | __HAL_SPI_DISABLE(hspi); |
||
50 | mjames | 3535 | } |
30 | mjames | 3536 | |
50 | mjames | 3537 | /* Reset CRC Calculation */ |
3538 | if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE) |
||
3539 | { |
||
3540 | SPI_RESET_CRC(hspi); |
||
3541 | } |
||
30 | mjames | 3542 | |
50 | mjames | 3543 | hspi->State = HAL_SPI_STATE_READY; |
30 | mjames | 3544 | |
50 | mjames | 3545 | /* Process Unlocked */ |
3546 | __HAL_UNLOCK(hspi); |
||
30 | mjames | 3547 | |
50 | mjames | 3548 | return HAL_TIMEOUT; |
30 | mjames | 3549 | } |
50 | mjames | 3550 | /* If Systick is disabled or not incremented, deactivate timeout to go in disable loop procedure */ |
3551 | if(count == 0U) |
||
3552 | { |
||
3553 | tmp_timeout = 0U; |
||
3554 | } |
||
3555 | count--; |
||
30 | mjames | 3556 | } |
3557 | } |
||
50 | mjames | 3558 | |
3559 | return HAL_OK; |
||
3560 | } |
||
3561 | |||
3562 | /** |
||
3563 | * @brief Handle the check of the RX transaction complete. |
||
3564 | * @param hspi pointer to a SPI_HandleTypeDef structure that contains |
||
3565 | * the configuration information for SPI module. |
||
3566 | * @param Timeout Timeout duration |
||
3567 | * @param Tickstart tick start value |
||
3568 | * @retval HAL status |
||
3569 | */ |
||
3570 | static HAL_StatusTypeDef SPI_EndRxTransaction(SPI_HandleTypeDef *hspi, uint32_t Timeout, uint32_t Tickstart) |
||
3571 | { |
||
3572 | if ((hspi->Init.Mode == SPI_MODE_MASTER) && ((hspi->Init.Direction == SPI_DIRECTION_1LINE) |
||
3573 | || (hspi->Init.Direction == SPI_DIRECTION_2LINES_RXONLY))) |
||
3574 | { |
||
3575 | /* Disable SPI peripheral */ |
||
3576 | __HAL_SPI_DISABLE(hspi); |
||
3577 | } |
||
3578 | |||
3579 | /* Erratasheet: BSY bit may stay high at the end of a data transfer in Slave mode */ |
||
3580 | if (hspi->Init.Mode == SPI_MODE_MASTER) |
||
3581 | { |
||
3582 | if (hspi->Init.Direction != SPI_DIRECTION_2LINES_RXONLY) |
||
3583 | { |
||
3584 | /* Control the BSY flag */ |
||
3585 | if (SPI_WaitFlagStateUntilTimeout(hspi, SPI_FLAG_BSY, RESET, Timeout, Tickstart) != HAL_OK) |
||
3586 | { |
||
3587 | SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG); |
||
3588 | return HAL_TIMEOUT; |
||
3589 | } |
||
3590 | } |
||
3591 | else |
||
3592 | { |
||
3593 | /* Wait the RXNE reset */ |
||
3594 | if (SPI_WaitFlagStateUntilTimeout(hspi, SPI_FLAG_RXNE, RESET, Timeout, Tickstart) != HAL_OK) |
||
3595 | { |
||
3596 | SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG); |
||
3597 | return HAL_TIMEOUT; |
||
3598 | } |
||
3599 | } |
||
3600 | } |
||
30 | mjames | 3601 | else |
3602 | { |
||
50 | mjames | 3603 | /* Wait the RXNE reset */ |
3604 | if (SPI_WaitFlagStateUntilTimeout(hspi, SPI_FLAG_RXNE, RESET, Timeout, Tickstart) != HAL_OK) |
||
30 | mjames | 3605 | { |
50 | mjames | 3606 | SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG); |
3607 | return HAL_TIMEOUT; |
||
3608 | } |
||
3609 | } |
||
3610 | return HAL_OK; |
||
3611 | } |
||
3612 | |||
3613 | /** |
||
3614 | * @brief Handle the check of the RXTX or TX transaction complete. |
||
3615 | * @param hspi SPI handle |
||
3616 | * @param Timeout Timeout duration |
||
3617 | * @param Tickstart tick start value |
||
3618 | * @retval HAL status |
||
3619 | */ |
||
3620 | static HAL_StatusTypeDef SPI_EndRxTxTransaction(SPI_HandleTypeDef *hspi, uint32_t Timeout, uint32_t Tickstart) |
||
3621 | { |
||
3622 | /* Timeout in µs */ |
||
3623 | __IO uint32_t count = SPI_BSY_FLAG_WORKAROUND_TIMEOUT * (SystemCoreClock / 24U / 1000000U); |
||
3624 | /* Erratasheet: BSY bit may stay high at the end of a data transfer in Slave mode */ |
||
3625 | if (hspi->Init.Mode == SPI_MODE_MASTER) |
||
3626 | { |
||
3627 | /* Control the BSY flag */ |
||
3628 | if (SPI_WaitFlagStateUntilTimeout(hspi, SPI_FLAG_BSY, RESET, Timeout, Tickstart) != HAL_OK) |
||
3629 | { |
||
3630 | SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG); |
||
3631 | return HAL_TIMEOUT; |
||
3632 | } |
||
3633 | } |
||
3634 | else |
||
3635 | { |
||
3636 | /* Wait BSY flag during 1 Byte time transfer in case of Full-Duplex and Tx transfer |
||
3637 | * If Timeout is reached, the transfer is considered as finish. |
||
3638 | * User have to calculate the timeout value to fit with the time of 1 byte transfer. |
||
3639 | * This time is directly link with the SPI clock from Master device. |
||
3640 | */ |
||
3641 | do |
||
3642 | { |
||
3643 | if (count == 0U) |
||
30 | mjames | 3644 | { |
50 | mjames | 3645 | break; |
3646 | } |
||
3647 | count--; |
||
3648 | } while (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_BSY) != RESET); |
||
3649 | } |
||
30 | mjames | 3650 | |
50 | mjames | 3651 | return HAL_OK; |
3652 | } |
||
30 | mjames | 3653 | |
50 | mjames | 3654 | /** |
3655 | * @brief Handle the end of the RXTX transaction. |
||
3656 | * @param hspi pointer to a SPI_HandleTypeDef structure that contains |
||
3657 | * the configuration information for SPI module. |
||
3658 | * @retval None |
||
3659 | */ |
||
3660 | static void SPI_CloseRxTx_ISR(SPI_HandleTypeDef *hspi) |
||
3661 | { |
||
3662 | uint32_t tickstart; |
||
3663 | __IO uint32_t count = SPI_DEFAULT_TIMEOUT * (SystemCoreClock / 24U / 1000U); |
||
30 | mjames | 3664 | |
50 | mjames | 3665 | /* Init tickstart for timeout management */ |
3666 | tickstart = HAL_GetTick(); |
||
30 | mjames | 3667 | |
50 | mjames | 3668 | /* Disable ERR interrupt */ |
3669 | __HAL_SPI_DISABLE_IT(hspi, SPI_IT_ERR); |
||
30 | mjames | 3670 | |
50 | mjames | 3671 | /* Wait until TXE flag is set */ |
3672 | do |
||
3673 | { |
||
3674 | if (count == 0U) |
||
3675 | { |
||
3676 | SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG); |
||
3677 | break; |
||
3678 | } |
||
3679 | count--; |
||
3680 | } while ((hspi->Instance->SR & SPI_FLAG_TXE) == RESET); |
||
30 | mjames | 3681 | |
50 | mjames | 3682 | /* Check the end of the transaction */ |
3683 | if (SPI_EndRxTxTransaction(hspi, SPI_DEFAULT_TIMEOUT, tickstart) != HAL_OK) |
||
3684 | { |
||
3685 | SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG); |
||
3686 | } |
||
3687 | |||
3688 | /* Clear overrun flag in 2 Lines communication mode because received is not read */ |
||
3689 | if (hspi->Init.Direction == SPI_DIRECTION_2LINES) |
||
3690 | { |
||
3691 | __HAL_SPI_CLEAR_OVRFLAG(hspi); |
||
3692 | } |
||
3693 | |||
3694 | #if (USE_SPI_CRC != 0U) |
||
3695 | /* Check if CRC error occurred */ |
||
3696 | if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_CRCERR) != RESET) |
||
3697 | { |
||
3698 | hspi->State = HAL_SPI_STATE_READY; |
||
3699 | SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC); |
||
3700 | __HAL_SPI_CLEAR_CRCERRFLAG(hspi); |
||
3701 | /* Call user error callback */ |
||
3702 | #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U) |
||
3703 | hspi->ErrorCallback(hspi); |
||
3704 | #else |
||
3705 | HAL_SPI_ErrorCallback(hspi); |
||
3706 | #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ |
||
3707 | } |
||
3708 | else |
||
3709 | { |
||
3710 | #endif /* USE_SPI_CRC */ |
||
3711 | if (hspi->ErrorCode == HAL_SPI_ERROR_NONE) |
||
3712 | { |
||
3713 | if (hspi->State == HAL_SPI_STATE_BUSY_RX) |
||
3714 | { |
||
3715 | hspi->State = HAL_SPI_STATE_READY; |
||
3716 | /* Call user Rx complete callback */ |
||
3717 | #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U) |
||
3718 | hspi->RxCpltCallback(hspi); |
||
3719 | #else |
||
3720 | HAL_SPI_RxCpltCallback(hspi); |
||
3721 | #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ |
||
30 | mjames | 3722 | } |
50 | mjames | 3723 | else |
3724 | { |
||
3725 | hspi->State = HAL_SPI_STATE_READY; |
||
3726 | /* Call user TxRx complete callback */ |
||
3727 | #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U) |
||
3728 | hspi->TxRxCpltCallback(hspi); |
||
3729 | #else |
||
3730 | HAL_SPI_TxRxCpltCallback(hspi); |
||
3731 | #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ |
||
3732 | } |
||
30 | mjames | 3733 | } |
50 | mjames | 3734 | else |
3735 | { |
||
3736 | hspi->State = HAL_SPI_STATE_READY; |
||
3737 | /* Call user error callback */ |
||
3738 | #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U) |
||
3739 | hspi->ErrorCallback(hspi); |
||
3740 | #else |
||
3741 | HAL_SPI_ErrorCallback(hspi); |
||
3742 | #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ |
||
3743 | } |
||
3744 | #if (USE_SPI_CRC != 0U) |
||
30 | mjames | 3745 | } |
50 | mjames | 3746 | #endif /* USE_SPI_CRC */ |
30 | mjames | 3747 | } |
50 | mjames | 3748 | |
30 | mjames | 3749 | /** |
50 | mjames | 3750 | * @brief Handle the end of the RX transaction. |
3751 | * @param hspi pointer to a SPI_HandleTypeDef structure that contains |
||
3752 | * the configuration information for SPI module. |
||
3753 | * @retval None |
||
3754 | */ |
||
3755 | static void SPI_CloseRx_ISR(SPI_HandleTypeDef *hspi) |
||
3756 | { |
||
3757 | /* Disable RXNE and ERR interrupt */ |
||
3758 | __HAL_SPI_DISABLE_IT(hspi, (SPI_IT_RXNE | SPI_IT_ERR)); |
||
3759 | |||
3760 | /* Check the end of the transaction */ |
||
3761 | if (SPI_EndRxTransaction(hspi, SPI_DEFAULT_TIMEOUT, HAL_GetTick()) != HAL_OK) |
||
3762 | { |
||
3763 | SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG); |
||
3764 | } |
||
3765 | |||
3766 | /* Clear overrun flag in 2 Lines communication mode because received is not read */ |
||
3767 | if (hspi->Init.Direction == SPI_DIRECTION_2LINES) |
||
3768 | { |
||
3769 | __HAL_SPI_CLEAR_OVRFLAG(hspi); |
||
3770 | } |
||
3771 | hspi->State = HAL_SPI_STATE_READY; |
||
3772 | |||
3773 | #if (USE_SPI_CRC != 0U) |
||
3774 | /* Check if CRC error occurred */ |
||
3775 | if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_CRCERR) != RESET) |
||
3776 | { |
||
3777 | SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC); |
||
3778 | __HAL_SPI_CLEAR_CRCERRFLAG(hspi); |
||
3779 | /* Call user error callback */ |
||
3780 | #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U) |
||
3781 | hspi->ErrorCallback(hspi); |
||
3782 | #else |
||
3783 | HAL_SPI_ErrorCallback(hspi); |
||
3784 | #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ |
||
3785 | } |
||
3786 | else |
||
3787 | { |
||
3788 | #endif /* USE_SPI_CRC */ |
||
3789 | if (hspi->ErrorCode == HAL_SPI_ERROR_NONE) |
||
3790 | { |
||
3791 | /* Call user Rx complete callback */ |
||
3792 | #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U) |
||
3793 | hspi->RxCpltCallback(hspi); |
||
3794 | #else |
||
3795 | HAL_SPI_RxCpltCallback(hspi); |
||
3796 | #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ |
||
3797 | } |
||
3798 | else |
||
3799 | { |
||
3800 | /* Call user error callback */ |
||
3801 | #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U) |
||
3802 | hspi->ErrorCallback(hspi); |
||
3803 | #else |
||
3804 | HAL_SPI_ErrorCallback(hspi); |
||
3805 | #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ |
||
3806 | } |
||
3807 | #if (USE_SPI_CRC != 0U) |
||
3808 | } |
||
3809 | #endif /* USE_SPI_CRC */ |
||
3810 | } |
||
3811 | |||
3812 | /** |
||
3813 | * @brief Handle the end of the TX transaction. |
||
3814 | * @param hspi pointer to a SPI_HandleTypeDef structure that contains |
||
3815 | * the configuration information for SPI module. |
||
3816 | * @retval None |
||
3817 | */ |
||
3818 | static void SPI_CloseTx_ISR(SPI_HandleTypeDef *hspi) |
||
3819 | { |
||
3820 | uint32_t tickstart; |
||
3821 | __IO uint32_t count = SPI_DEFAULT_TIMEOUT * (SystemCoreClock / 24U / 1000U); |
||
3822 | |||
3823 | /* Init tickstart for timeout management*/ |
||
3824 | tickstart = HAL_GetTick(); |
||
3825 | |||
3826 | /* Wait until TXE flag is set */ |
||
3827 | do |
||
3828 | { |
||
3829 | if (count == 0U) |
||
3830 | { |
||
3831 | SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG); |
||
3832 | break; |
||
3833 | } |
||
3834 | count--; |
||
3835 | } while ((hspi->Instance->SR & SPI_FLAG_TXE) == RESET); |
||
3836 | |||
3837 | /* Disable TXE and ERR interrupt */ |
||
3838 | __HAL_SPI_DISABLE_IT(hspi, (SPI_IT_TXE | SPI_IT_ERR)); |
||
3839 | |||
3840 | /* Check the end of the transaction */ |
||
3841 | if (SPI_EndRxTxTransaction(hspi, SPI_DEFAULT_TIMEOUT, tickstart) != HAL_OK) |
||
3842 | { |
||
3843 | SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG); |
||
3844 | } |
||
3845 | |||
3846 | /* Clear overrun flag in 2 Lines communication mode because received is not read */ |
||
3847 | if (hspi->Init.Direction == SPI_DIRECTION_2LINES) |
||
3848 | { |
||
3849 | __HAL_SPI_CLEAR_OVRFLAG(hspi); |
||
3850 | } |
||
3851 | |||
3852 | hspi->State = HAL_SPI_STATE_READY; |
||
3853 | if (hspi->ErrorCode != HAL_SPI_ERROR_NONE) |
||
3854 | { |
||
3855 | /* Call user error callback */ |
||
3856 | #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U) |
||
3857 | hspi->ErrorCallback(hspi); |
||
3858 | #else |
||
3859 | HAL_SPI_ErrorCallback(hspi); |
||
3860 | #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ |
||
3861 | } |
||
3862 | else |
||
3863 | { |
||
3864 | /* Call user Rx complete callback */ |
||
3865 | #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U) |
||
3866 | hspi->TxCpltCallback(hspi); |
||
3867 | #else |
||
3868 | HAL_SPI_TxCpltCallback(hspi); |
||
3869 | #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */ |
||
3870 | } |
||
3871 | } |
||
3872 | |||
3873 | /** |
||
3874 | * @brief Handle abort a Rx transaction. |
||
3875 | * @param hspi pointer to a SPI_HandleTypeDef structure that contains |
||
3876 | * the configuration information for SPI module. |
||
3877 | * @retval None |
||
3878 | */ |
||
3879 | static void SPI_AbortRx_ISR(SPI_HandleTypeDef *hspi) |
||
3880 | { |
||
61 | mjames | 3881 | __IO uint32_t tmpreg = 0U; |
50 | mjames | 3882 | __IO uint32_t count = SPI_DEFAULT_TIMEOUT * (SystemCoreClock / 24U / 1000U); |
3883 | |||
3884 | /* Wait until TXE flag is set */ |
||
3885 | do |
||
3886 | { |
||
3887 | if (count == 0U) |
||
3888 | { |
||
3889 | SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_ABORT); |
||
3890 | break; |
||
3891 | } |
||
3892 | count--; |
||
3893 | } while ((hspi->Instance->SR & SPI_FLAG_TXE) == RESET); |
||
3894 | |||
3895 | /* Disable SPI Peripheral */ |
||
3896 | __HAL_SPI_DISABLE(hspi); |
||
3897 | |||
3898 | /* Disable TXEIE, RXNEIE and ERRIE(mode fault event, overrun error, TI frame error) interrupts */ |
||
3899 | CLEAR_BIT(hspi->Instance->CR2, (SPI_CR2_TXEIE | SPI_CR2_RXNEIE | SPI_CR2_ERRIE)); |
||
3900 | |||
61 | mjames | 3901 | /* Flush Data Register by a blank read */ |
3902 | tmpreg = READ_REG(hspi->Instance->DR); |
||
3903 | /* To avoid GCC warning */ |
||
3904 | UNUSED(tmpreg); |
||
50 | mjames | 3905 | |
3906 | hspi->State = HAL_SPI_STATE_ABORT; |
||
3907 | } |
||
3908 | |||
3909 | /** |
||
3910 | * @brief Handle abort a Tx or Rx/Tx transaction. |
||
3911 | * @param hspi pointer to a SPI_HandleTypeDef structure that contains |
||
3912 | * the configuration information for SPI module. |
||
3913 | * @retval None |
||
3914 | */ |
||
3915 | static void SPI_AbortTx_ISR(SPI_HandleTypeDef *hspi) |
||
3916 | { |
||
3917 | /* Disable TXEIE interrupt */ |
||
3918 | CLEAR_BIT(hspi->Instance->CR2, (SPI_CR2_TXEIE)); |
||
3919 | |||
3920 | /* Disable SPI Peripheral */ |
||
3921 | __HAL_SPI_DISABLE(hspi); |
||
3922 | |||
3923 | hspi->State = HAL_SPI_STATE_ABORT; |
||
3924 | } |
||
3925 | |||
3926 | /** |
||
30 | mjames | 3927 | * @} |
3928 | */ |
||
3929 | |||
3930 | #endif /* HAL_SPI_MODULE_ENABLED */ |
||
50 | mjames | 3931 | |
30 | mjames | 3932 | /** |
3933 | * @} |
||
3934 | */ |
||
3935 | |||
3936 | /** |
||
3937 | * @} |
||
3938 | */ |
||
3939 | |||
3940 | /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ |