Subversion Repositories LedShow

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

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