stm32f4xx_hal_spi.c 87.8 KB
Newer Older
Dave Hylands's avatar
Dave Hylands committed
1
2
3
4
/**
  ******************************************************************************
  * @file    stm32f4xx_hal_spi.c
  * @author  MCD Application Team
5
6
  * @version V1.5.1
  * @date    01-July-2016
Dave Hylands's avatar
Dave Hylands committed
7
  * @brief   SPI HAL module driver.
8
  *          This file provides firmware functions to manage the following
Dave Hylands's avatar
Dave Hylands committed
9
10
11
  *          functionalities of the Serial Peripheral Interface (SPI) peripheral:
  *           + Initialization and de-initialization functions
  *           + IO operation functions
12
  *           + Peripheral Control functions
Dave Hylands's avatar
Dave Hylands committed
13
  *           + Peripheral State functions
14
  *
Dave Hylands's avatar
Dave Hylands committed
15
16
17
18
19
20
21
22
  @verbatim
  ==============================================================================
                        ##### How to use this driver #####
  ==============================================================================
    [..]
      The SPI HAL driver can be used as follows:

      (#) Declare a SPI_HandleTypeDef handle structure, for example:
23
          SPI_HandleTypeDef  hspi;
Dave Hylands's avatar
Dave Hylands committed
24

25
26
      (#)Initialize the SPI low level resources by implementing the HAL_SPI_MspInit() API:
          (##) Enable the SPIx interface clock
Dave Hylands's avatar
Dave Hylands committed
27
          (##) SPI pins configuration
28
              (+++) Enable the clock for the SPI GPIOs
Dave Hylands's avatar
Dave Hylands committed
29
30
31
32
33
34
              (+++) Configure these SPI pins as alternate function push-pull
          (##) NVIC configuration if you need to use interrupt process
              (+++) Configure the SPIx interrupt priority
              (+++) Enable the NVIC SPI IRQ handle
          (##) DMA Configuration if you need to use DMA process
              (+++) Declare a DMA_HandleTypeDef handle structure for the transmit or receive stream
35
36
37
38
39
              (+++) Enable the DMAx clock
              (+++) Configure the DMA handle parameters
              (+++) Configure the DMA Tx or Rx stream
              (+++) Associate the initialized hdma_tx handle to the hspi DMA Tx or Rx handle
              (+++) Configure the priority and enable the NVIC for the transfer complete interrupt on the DMA Tx or Rx stream
Dave Hylands's avatar
Dave Hylands committed
40

41
      (#) Program the Mode, BidirectionalMode , Data size, Baudrate Prescaler, NSS
Dave Hylands's avatar
Dave Hylands committed
42
43
44
45
          management, Clock polarity and phase, FirstBit and CRC configuration in the hspi Init structure.

      (#) Initialize the SPI registers by calling the HAL_SPI_Init() API:
          (++) This API configures also the low level Hardware GPIO, CLOCK, CORTEX...etc)
46
              by calling the customized HAL_SPI_MspInit() API.
47
48
49
50
51
52
     [..]
       Circular mode restriction:
      (#) The DMA circular mode cannot be used when the SPI is configured in these modes:
          (##) Master 2Lines RxOnly
          (##) Master 1Line Rx
      (#) The CRC feature is not managed when the DMA circular mode is enabled
53
      (#) When the SPI DMA Pause/Stop features are used, we must use the following APIs
54
          the HAL_SPI_DMAPause()/ HAL_SPI_DMAStop() only under the SPI callbacks
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
     [..]
       Master Receive mode restriction:
      (#) In Master unidirectional receive-only mode (MSTR =1, BIDIMODE=0, RXONLY=0) or
          bidirectional receive mode (MSTR=1, BIDIMODE=1, BIDIOE=0), to ensure that the SPI
          does not initiate a new transfer the following procedure has to be respected:
          (##) HAL_SPI_DeInit()
          (##) HAL_SPI_Init()
     [..]
       Using the HAL it is not possible to reach all supported SPI frequency with the differents SPI Modes,
       the following table resume the max SPI frequency reached with data size 8bits/16bits,
       according to frequency used on APBx Peripheral Clock (fPCLK) used by the SPI instance :

       DataSize = SPI_DATASIZE_8BIT:
       +----------------------------------------------------------------------------------------------+
       |         |                | 2Lines Fullduplex   |     2Lines RxOnly    |         1Line        |
       | Process | Tranfert mode  |---------------------|----------------------|----------------------|
       |         |                |  Master  |  Slave   |  Master   |  Slave   |  Master   |  Slave   |
       |==============================================================================================|
       |    T    |     Polling    | Fpclk/2  | Fpclk/2  |    NA     |    NA    |    NA     |   NA     |
       |    X    |----------------|----------|----------|-----------|----------|-----------|----------|
       |    /    |     Interrupt  | Fpclk/4  | Fpclk/8  |    NA     |    NA    |    NA     |   NA     |
       |    R    |----------------|----------|----------|-----------|----------|-----------|----------|
       |    X    |       DMA      | Fpclk/2  | Fpclk/2  |    NA     |    NA    |    NA     |   NA     |
       |=========|================|==========|==========|===========|==========|===========|==========|
       |         |     Polling    | Fpclk/2  | Fpclk/2  | Fpclk/64  | Fpclk/2  | Fpclk/64  | Fpclk/2  |
       |         |----------------|----------|----------|-----------|----------|-----------|----------|
       |    R    |     Interrupt  | Fpclk/8  | Fpclk/8  | Fpclk/64  | Fpclk/2  | Fpclk/64  | Fpclk/2  |
       |    X    |----------------|----------|----------|-----------|----------|-----------|----------|
       |         |       DMA      | Fpclk/2  | Fpclk/2  | Fpclk/64  | Fpclk/2  | Fpclk/128 | Fpclk/2  |
       |=========|================|==========|==========|===========|==========|===========|==========|
       |         |     Polling    | Fpclk/2  | Fpclk/4  |     NA    |    NA    | Fpclk/2   | Fpclk/64 |
       |         |----------------|----------|----------|-----------|----------|-----------|----------|
       |    T    |     Interrupt  | Fpclk/2  | Fpclk/4  |     NA    |    NA    | Fpclk/2   | Fpclk/64 |
       |    X    |----------------|----------|----------|-----------|----------|-----------|----------|
       |         |       DMA      | Fpclk/2  | Fpclk/2  |     NA    |    NA    | Fpclk/2   | Fpclk/128|
       +----------------------------------------------------------------------------------------------+

       DataSize = SPI_DATASIZE_16BIT:
       +----------------------------------------------------------------------------------------------+
       |         |                | 2Lines Fullduplex   |     2Lines RxOnly    |         1Line        |
       | Process | Tranfert mode  |---------------------|----------------------|----------------------|
       |         |                |  Master  |  Slave   |  Master   |  Slave   |  Master   |  Slave   |
       |==============================================================================================|
       |    T    |     Polling    | Fpclk/2  | Fpclk/2  |    NA     |    NA    |    NA     |   NA     |
       |    X    |----------------|----------|----------|-----------|----------|-----------|----------|
       |    /    |     Interrupt  | Fpclk/4  | Fpclk/4  |    NA     |    NA    |    NA     |   NA     |
       |    R    |----------------|----------|----------|-----------|----------|-----------|----------|
       |    X    |       DMA      | Fpclk/2  | Fpclk/2  |    NA     |    NA    |    NA     |   NA     |
       |=========|================|==========|==========|===========|==========|===========|==========|
       |         |     Polling    | Fpclk/2  | Fpclk/2  | Fpclk/64  | Fpclk/2  | Fpclk/32  | Fpclk/2  |
       |         |----------------|----------|----------|-----------|----------|-----------|----------|
       |    R    |     Interrupt  | Fpclk/4  | Fpclk/4  | Fpclk/64  | Fpclk/2  | Fpclk/64  | Fpclk/2  |
       |    X    |----------------|----------|----------|-----------|----------|-----------|----------|
       |         |       DMA      | Fpclk/2  | Fpclk/2  | Fpclk/64  | Fpclk/2  | Fpclk/128 | Fpclk/2  |
       |=========|================|==========|==========|===========|==========|===========|==========|
       |         |     Polling    | Fpclk/2  | Fpclk/2  |     NA    |    NA    | Fpclk/2   | Fpclk/32 |
       |         |----------------|----------|----------|-----------|----------|-----------|----------|
       |    T    |     Interrupt  | Fpclk/2  | Fpclk/2  |     NA    |    NA    | Fpclk/2   | Fpclk/64 |
       |    X    |----------------|----------|----------|-----------|----------|-----------|----------|
       |         |       DMA      | Fpclk/2  | Fpclk/2  |     NA    |    NA    | Fpclk/2   | Fpclk/128|
       +----------------------------------------------------------------------------------------------+
       @note The max SPI frequency depend on SPI data size (8bits, 16bits),
             SPI mode(2 Lines fullduplex, 2 lines RxOnly, 1 line TX/RX) and Process mode (Polling, IT, DMA).
       @note
            (#) TX/RX processes are HAL_SPI_TransmitReceive(), HAL_SPI_TransmitReceive_IT() and HAL_SPI_TransmitReceive_DMA()
            (#) RX processes are HAL_SPI_Receive(), HAL_SPI_Receive_IT() and HAL_SPI_Receive_DMA()
            (#) TX processes are HAL_SPI_Transmit(), HAL_SPI_Transmit_IT() and HAL_SPI_Transmit_DMA()
122

Dave Hylands's avatar
Dave Hylands committed
123
124
125
126
  @endverbatim
  ******************************************************************************
  * @attention
  *
127
  * <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
Dave Hylands's avatar
Dave Hylands committed
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
  *
  * Redistribution and use in source and binary forms, with or without modification,
  * are permitted provided that the following conditions are met:
  *   1. Redistributions of source code must retain the above copyright notice,
  *      this list of conditions and the following disclaimer.
  *   2. Redistributions in binary form must reproduce the above copyright notice,
  *      this list of conditions and the following disclaimer in the documentation
  *      and/or other materials provided with the distribution.
  *   3. Neither the name of STMicroelectronics nor the names of its contributors
  *      may be used to endorse or promote products derived from this software
  *      without specific prior written permission.
  *
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  ******************************************************************************
  */

/* Includes ------------------------------------------------------------------*/
#include "stm32f4xx_hal.h"

/** @addtogroup STM32F4xx_HAL_Driver
  * @{
  */
160
/** @defgroup SPI SPI
Dave Hylands's avatar
Dave Hylands committed
161
162
163
164
165
166
  * @brief SPI HAL module driver
  * @{
  */
#ifdef HAL_SPI_MODULE_ENABLED

/* Private typedef -----------------------------------------------------------*/
167
168
169
170
171
172
173
174
175
176
/* Private defines -----------------------------------------------------------*/
/** @defgroup SPI_Private_Constants SPI Private Constants
  * @{
  */
#define SPI_DEFAULT_TIMEOUT 100U
/**
  * @}
  */

/* Private macros ------------------------------------------------------------*/
Dave Hylands's avatar
Dave Hylands committed
177
178
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
179
180
181
/** @addtogroup SPI_Private_Functions
  * @{
  */
Dave Hylands's avatar
Dave Hylands committed
182
183
184
static void SPI_DMATransmitCplt(DMA_HandleTypeDef *hdma);
static void SPI_DMAReceiveCplt(DMA_HandleTypeDef *hdma);
static void SPI_DMATransmitReceiveCplt(DMA_HandleTypeDef *hdma);
185
186
187
static void SPI_DMAHalfTransmitCplt(DMA_HandleTypeDef *hdma);
static void SPI_DMAHalfReceiveCplt(DMA_HandleTypeDef *hdma);
static void SPI_DMAHalfTransmitReceiveCplt(DMA_HandleTypeDef *hdma);
Dave Hylands's avatar
Dave Hylands committed
188
static void SPI_DMAError(DMA_HandleTypeDef *hdma);
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
static void SPI_DMAAbortOnError(DMA_HandleTypeDef *hdma);
static HAL_StatusTypeDef SPI_WaitFlagStateUntilTimeout(SPI_HandleTypeDef *hspi, uint32_t Flag, uint32_t State, uint32_t Timeout, uint32_t Tickstart);
static void SPI_TxISR_8BIT(struct __SPI_HandleTypeDef *hspi);
static void SPI_TxISR_16BIT(struct __SPI_HandleTypeDef *hspi);
static void SPI_RxISR_8BIT(struct __SPI_HandleTypeDef *hspi);
static void SPI_RxISR_16BIT(struct __SPI_HandleTypeDef *hspi);
static void SPI_2linesRxISR_8BIT(struct __SPI_HandleTypeDef *hspi);
static void SPI_2linesTxISR_8BIT(struct __SPI_HandleTypeDef *hspi);
static void SPI_2linesTxISR_16BIT(struct __SPI_HandleTypeDef *hspi);
static void SPI_2linesRxISR_16BIT(struct __SPI_HandleTypeDef *hspi);
#if (USE_SPI_CRC != 0U)
static void SPI_RxISR_8BITCRC(struct __SPI_HandleTypeDef *hspi);
static void SPI_RxISR_16BITCRC(struct __SPI_HandleTypeDef *hspi);
static void SPI_2linesRxISR_8BITCRC(struct __SPI_HandleTypeDef *hspi);
static void SPI_2linesRxISR_16BITCRC(struct __SPI_HandleTypeDef *hspi);
#endif /* USE_SPI_CRC */
static void SPI_CloseRxTx_ISR(SPI_HandleTypeDef *hspi);
static void SPI_CloseRx_ISR(SPI_HandleTypeDef *hspi);
static void SPI_CloseTx_ISR(SPI_HandleTypeDef *hspi);
static HAL_StatusTypeDef SPI_CheckFlag_BSY(SPI_HandleTypeDef *hspi, uint32_t Timeout, uint32_t Tickstart);
/**
  * @}
  */
Dave Hylands's avatar
Dave Hylands committed
212

213
214
/* Exported functions --------------------------------------------------------*/
/** @defgroup SPI_Exported_Functions SPI Exported Functions
Dave Hylands's avatar
Dave Hylands committed
215
216
217
  * @{
  */

218
219
/** @defgroup SPI_Exported_Functions_Group1 Initialization and de-initialization functions
 *  @brief    Initialization and Configuration functions
Dave Hylands's avatar
Dave Hylands committed
220
221
222
223
224
 *
@verbatim
 ===============================================================================
              ##### Initialization and de-initialization functions #####
 ===============================================================================
225
226
    [..]  This subsection provides a set of functions allowing to initialize and
          de-initialize the SPIx peripheral:
Dave Hylands's avatar
Dave Hylands committed
227

228
      (+) User must implement HAL_SPI_MspInit() function in which he configures
Dave Hylands's avatar
Dave Hylands committed
229
230
          all related peripherals resources (CLOCK, GPIO, DMA, IT and NVIC ).

231
      (+) Call the function HAL_SPI_Init() to configure the selected device with
Dave Hylands's avatar
Dave Hylands committed
232
233
          the selected configuration:
        (++) Mode
234
        (++) Direction
Dave Hylands's avatar
Dave Hylands committed
235
236
237
238
239
240
241
242
243
        (++) Data Size
        (++) Clock Polarity and Phase
        (++) NSS Management
        (++) BaudRate Prescaler
        (++) FirstBit
        (++) TIMode
        (++) CRC Calculation
        (++) CRC Polynomial if CRC enabled

244
245
      (+) Call the function HAL_SPI_DeInit() to restore the default configuration
          of the selected SPIx peripheral.
Dave Hylands's avatar
Dave Hylands committed
246
247
248
249
250
251

@endverbatim
  * @{
  */

/**
252
253
  * @brief  Initialize the SPI according to the specified parameters
  *         in the SPI_InitTypeDef and initialize the associated handle.
254
  * @param  hspi: pointer to a SPI_HandleTypeDef structure that contains
255
  *               the configuration information for SPI module.
Dave Hylands's avatar
Dave Hylands committed
256
257
258
259
260
261
262
263
264
265
266
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_SPI_Init(SPI_HandleTypeDef *hspi)
{
  /* Check the SPI handle allocation */
  if(hspi == NULL)
  {
    return HAL_ERROR;
  }

  /* Check the parameters */
267
  assert_param(IS_SPI_ALL_INSTANCE(hspi->Instance));
Dave Hylands's avatar
Dave Hylands committed
268
  assert_param(IS_SPI_MODE(hspi->Init.Mode));
269
  assert_param(IS_SPI_DIRECTION(hspi->Init.Direction));
Dave Hylands's avatar
Dave Hylands committed
270
271
272
273
274
  assert_param(IS_SPI_DATASIZE(hspi->Init.DataSize));
  assert_param(IS_SPI_NSS(hspi->Init.NSS));
  assert_param(IS_SPI_BAUDRATE_PRESCALER(hspi->Init.BaudRatePrescaler));
  assert_param(IS_SPI_FIRST_BIT(hspi->Init.FirstBit));
  assert_param(IS_SPI_TIMODE(hspi->Init.TIMode));
275
276
277
278
279
280
  if(hspi->Init.TIMode == SPI_TIMODE_DISABLE)
  {
    assert_param(IS_SPI_CPOL(hspi->Init.CLKPolarity));
    assert_param(IS_SPI_CPHA(hspi->Init.CLKPhase));
  }
#if (USE_SPI_CRC != 0U)
Dave Hylands's avatar
Dave Hylands committed
281
  assert_param(IS_SPI_CRC_CALCULATION(hspi->Init.CRCCalculation));
282
283
284
285
286
287
288
  if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
  {
    assert_param(IS_SPI_CRC_POLYNOMIAL(hspi->Init.CRCPolynomial));
  }
#else
  hspi->Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
#endif /* USE_SPI_CRC */
Dave Hylands's avatar
Dave Hylands committed
289
290
291

  if(hspi->State == HAL_SPI_STATE_RESET)
  {
292
293
294
    /* Allocate lock resource and initialize it */
    hspi->Lock = HAL_UNLOCKED;

Dave Hylands's avatar
Dave Hylands committed
295
296
297
    /* Init the low level hardware : GPIO, CLOCK, NVIC... */
    HAL_SPI_MspInit(hspi);
  }
298

Dave Hylands's avatar
Dave Hylands committed
299
300
  hspi->State = HAL_SPI_STATE_BUSY;

301
  /* Disable the selected SPI peripheral */
Dave Hylands's avatar
Dave Hylands committed
302
303
304
305
306
  __HAL_SPI_DISABLE(hspi);

  /*----------------------- SPIx CR1 & CR2 Configuration ---------------------*/
  /* Configure : SPI Mode, Communication Mode, Data size, Clock polarity and phase, NSS management,
  Communication speed, First bit and CRC calculation state */
307
308
309
  WRITE_REG(hspi->Instance->CR1, (hspi->Init.Mode | hspi->Init.Direction | hspi->Init.DataSize |
                                  hspi->Init.CLKPolarity | hspi->Init.CLKPhase | (hspi->Init.NSS & SPI_CR1_SSM) |
                                  hspi->Init.BaudRatePrescaler | hspi->Init.FirstBit  | hspi->Init.CRCCalculation) );
Dave Hylands's avatar
Dave Hylands committed
310
311

  /* Configure : NSS management */
312
  WRITE_REG(hspi->Instance->CR2, (((hspi->Init.NSS >> 16U) & SPI_CR2_SSOE) | hspi->Init.TIMode));
Dave Hylands's avatar
Dave Hylands committed
313

314
#if (USE_SPI_CRC != 0U)
Dave Hylands's avatar
Dave Hylands committed
315
316
  /*---------------------------- SPIx CRCPOLY Configuration ------------------*/
  /* Configure : CRC Polynomial */
317
318
319
320
321
  if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
  {
    WRITE_REG(hspi->Instance->CRCPR, hspi->Init.CRCPolynomial);
  }
#endif /* USE_SPI_CRC */
Dave Hylands's avatar
Dave Hylands committed
322

323
#if defined(SPI_I2SCFGR_I2SMOD)
Dave Hylands's avatar
Dave Hylands committed
324
  /* Activate the SPI mode (Make sure that I2SMOD bit in I2SCFGR register is reset) */
325
326
  CLEAR_BIT(hspi->Instance->I2SCFGR, SPI_I2SCFGR_I2SMOD);
#endif /* USE_SPI_CRC */
Dave Hylands's avatar
Dave Hylands committed
327
328

  hspi->ErrorCode = HAL_SPI_ERROR_NONE;
329
330
  hspi->State     = HAL_SPI_STATE_READY;

Dave Hylands's avatar
Dave Hylands committed
331
332
333
334
  return HAL_OK;
}

/**
335
  * @brief  De Initialize the SPI peripheral.
336
  * @param  hspi: pointer to a SPI_HandleTypeDef structure that contains
337
  *               the configuration information for SPI module.
Dave Hylands's avatar
Dave Hylands committed
338
339
340
341
342
343
344
345
346
347
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_SPI_DeInit(SPI_HandleTypeDef *hspi)
{
  /* Check the SPI handle allocation */
  if(hspi == NULL)
  {
    return HAL_ERROR;
  }

348
349
350
351
352
  /* Check SPI Instance parameter */
  assert_param(IS_SPI_ALL_INSTANCE(hspi->Instance));

  hspi->State = HAL_SPI_STATE_BUSY;

Dave Hylands's avatar
Dave Hylands committed
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
  /* Disable the SPI Peripheral Clock */
  __HAL_SPI_DISABLE(hspi);

  /* DeInit the low level hardware: GPIO, CLOCK, NVIC... */
  HAL_SPI_MspDeInit(hspi);

  hspi->ErrorCode = HAL_SPI_ERROR_NONE;
  hspi->State = HAL_SPI_STATE_RESET;

  /* Release Lock */
  __HAL_UNLOCK(hspi);

  return HAL_OK;
}

/**
369
  * @brief  Initialize the SPI MSP.
370
  * @param  hspi: pointer to a SPI_HandleTypeDef structure that contains
371
  *               the configuration information for SPI module.
Dave Hylands's avatar
Dave Hylands committed
372
373
  * @retval None
  */
374
375
376
377
378
379
380
__weak void HAL_SPI_MspInit(SPI_HandleTypeDef *hspi)
{
  /* Prevent unused argument(s) compilation warning */
  UNUSED(hspi);
  /* NOTE : This function should not be modified, when the callback is needed,
            the HAL_SPI_MspInit should be implemented in the user file
  */
Dave Hylands's avatar
Dave Hylands committed
381
382
383
}

/**
384
  * @brief  De-Initialize the SPI MSP.
385
  * @param  hspi: pointer to a SPI_HandleTypeDef structure that contains
386
  *               the configuration information for SPI module.
Dave Hylands's avatar
Dave Hylands committed
387
388
  * @retval None
  */
389
__weak void HAL_SPI_MspDeInit(SPI_HandleTypeDef *hspi)
Dave Hylands's avatar
Dave Hylands committed
390
{
391
392
393
394
395
  /* Prevent unused argument(s) compilation warning */
  UNUSED(hspi);
  /* NOTE : This function should not be modified, when the callback is needed,
            the HAL_SPI_MspDeInit should be implemented in the user file
  */
Dave Hylands's avatar
Dave Hylands committed
396
397
398
399
400
401
}

/**
  * @}
  */

402
/** @defgroup SPI_Exported_Functions_Group2 IO operation functions
Dave Hylands's avatar
Dave Hylands committed
403
404
405
406
407
408
 *  @brief   Data transfers functions
 *
@verbatim
  ==============================================================================
                      ##### IO operation functions #####
 ===============================================================================
409
 [..]
Dave Hylands's avatar
Dave Hylands committed
410
411
412
413
414
    This subsection provides a set of functions allowing to manage the SPI
    data transfers.

    [..] The SPI supports master and slave mode :

415
    (#) There are two modes of transfer:
Dave Hylands's avatar
Dave Hylands committed
416
417
418
419
       (++) Blocking mode: The communication is performed in polling mode.
            The HAL status of all data processing is returned by the same function
            after finishing transfer.
       (++) No-Blocking mode: The communication is performed using Interrupts
420
421
422
423
424
425
426
427
428
429
            or DMA, These APIs return the HAL status.
            The end of the data processing will be indicated through the
            dedicated SPI IRQ when using Interrupt mode or the DMA IRQ when
            using DMA mode.
            The HAL_SPI_TxCpltCallback(), HAL_SPI_RxCpltCallback() and HAL_SPI_TxRxCpltCallback() user callbacks
            will be executed respectively at the end of the transmit or Receive process
            The HAL_SPI_ErrorCallback()user callback will be executed when a communication error is detected

    (#) APIs provided for these 2 transfer modes (Blocking mode or Non blocking mode using either Interrupt or DMA)
        exist for 1Line (simplex) and 2Lines (full duplex) modes.
Dave Hylands's avatar
Dave Hylands committed
430
431
432
433
434
435

@endverbatim
  * @{
  */

/**
436
  * @brief  Transmit an amount of data in blocking mode.
437
  * @param  hspi: pointer to a SPI_HandleTypeDef structure that contains
438
  *               the configuration information for SPI module.
Dave Hylands's avatar
Dave Hylands committed
439
440
441
442
443
444
445
  * @param  pData: pointer to data buffer
  * @param  Size: amount of data to be sent
  * @param  Timeout: Timeout duration
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_SPI_Transmit(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout)
{
446
447
  uint32_t tickstart = 0U;
  HAL_StatusTypeDef errorcode = HAL_OK;
Dave Hylands's avatar
Dave Hylands committed
448

449
450
  /* Check Direction parameter */
  assert_param(IS_SPI_DIRECTION_2LINES_OR_1LINE(hspi->Init.Direction));
Dave Hylands's avatar
Dave Hylands committed
451

452
453
  /* Process Locked */
  __HAL_LOCK(hspi);
Dave Hylands's avatar
Dave Hylands committed
454

455
456
  /* Init tickstart for timeout management*/
  tickstart = HAL_GetTick();
Dave Hylands's avatar
Dave Hylands committed
457

458
459
460
461
462
  if(hspi->State != HAL_SPI_STATE_READY)
  {
    errorcode = HAL_BUSY;
    goto error;
  }
Dave Hylands's avatar
Dave Hylands committed
463

464
465
466
467
468
  if((pData == NULL ) || (Size == 0U))
  {
    errorcode = HAL_ERROR;
    goto error;
  }
Dave Hylands's avatar
Dave Hylands committed
469

470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
  /* Set the transaction information */
  hspi->State       = HAL_SPI_STATE_BUSY_TX;
  hspi->ErrorCode   = HAL_SPI_ERROR_NONE;
  hspi->pTxBuffPtr  = (uint8_t *)pData;
  hspi->TxXferSize  = Size;
  hspi->TxXferCount = Size;

  /*Init field not used in handle to zero */
  hspi->pRxBuffPtr  = (uint8_t *)NULL;
  hspi->RxXferSize  = 0U;
  hspi->RxXferCount = 0U;
  hspi->TxISR       = NULL;
  hspi->RxISR       = NULL;

  /* Configure communication direction : 1Line */
  if(hspi->Init.Direction == SPI_DIRECTION_1LINE)
  {
    SPI_1LINE_TX(hspi);
  }
Dave Hylands's avatar
Dave Hylands committed
489

490
491
492
493
494
495
496
#if (USE_SPI_CRC != 0U)
  /* Reset CRC Calculation */
  if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
  {
    SPI_RESET_CRC(hspi);
  }
#endif /* USE_SPI_CRC */
Dave Hylands's avatar
Dave Hylands committed
497

498
499
500
501
502
503
  /* Check if the SPI is already enabled */
  if((hspi->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE)
  {
    /* Enable SPI peripheral */
    __HAL_SPI_ENABLE(hspi);
  }
Dave Hylands's avatar
Dave Hylands committed
504

505
506
507
508
  /* Transmit data in 16 Bit mode */
  if(hspi->Init.DataSize == SPI_DATASIZE_16BIT)
  {
    if((hspi->Init.Mode == SPI_MODE_SLAVE) || (hspi->TxXferCount == 0x01))
Dave Hylands's avatar
Dave Hylands committed
509
    {
510
511
512
      hspi->Instance->DR = *((uint16_t *)pData);
      pData += sizeof(uint16_t);
      hspi->TxXferCount--;
Dave Hylands's avatar
Dave Hylands committed
513
    }
514
515
    /* Transmit data in 16 Bit mode */
    while (hspi->TxXferCount > 0U)
Dave Hylands's avatar
Dave Hylands committed
516
    {
517
518
      /* Wait until TXE flag is set to send data */
      if(__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXE))
519
      {
520
521
522
          hspi->Instance->DR = *((uint16_t *)pData);
          pData += sizeof(uint16_t);
          hspi->TxXferCount--;
523
      }
524
      else
Dave Hylands's avatar
Dave Hylands committed
525
      {
526
527
528
529
530
        /* Timeout management */
        if((Timeout == 0U) || ((Timeout != HAL_MAX_DELAY) && ((HAL_GetTick()-tickstart) >=  Timeout)))
        {
          errorcode = HAL_TIMEOUT;
          goto error;
Dave Hylands's avatar
Dave Hylands committed
531
532
533
        }
      }
    }
534
535
536
537
538
539
540
541
542
543
544
  }
  /* Transmit data in 8 Bit mode */
  else
  {
    if((hspi->Init.Mode == SPI_MODE_SLAVE)|| (hspi->TxXferCount == 0x01))
    {
      *((__IO uint8_t*)&hspi->Instance->DR) = (*pData);
      pData += sizeof(uint8_t);
      hspi->TxXferCount--;
    }
    while (hspi->TxXferCount > 0U)
Dave Hylands's avatar
Dave Hylands committed
545
    {
546
547
      /* Wait until TXE flag is set to send data */
      if(__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXE))
548
      {
549
550
        *((__IO uint8_t*)&hspi->Instance->DR) = (*pData);
        pData += sizeof(uint8_t);
551
552
        hspi->TxXferCount--;
      }
553
      else
Dave Hylands's avatar
Dave Hylands committed
554
      {
555
556
557
558
559
        /* Timeout management */
        if((Timeout == 0U) || ((Timeout != HAL_MAX_DELAY) && ((HAL_GetTick()-tickstart) >=  Timeout)))
        {
          errorcode = HAL_TIMEOUT;
          goto error;
Dave Hylands's avatar
Dave Hylands committed
560
561
562
        }
      }
    }
563
  }
Dave Hylands's avatar
Dave Hylands committed
564

565
566
567
568
569
570
571
572
573
574
575
576
577
578
  /* Wait until TXE flag */
  if(SPI_WaitFlagStateUntilTimeout(hspi, SPI_FLAG_TXE, SET, Timeout, tickstart) != HAL_OK)
  {
    errorcode = HAL_TIMEOUT;
    goto error;
  }
  
  /* Check Busy flag */
  if(SPI_CheckFlag_BSY(hspi, Timeout, tickstart) != HAL_OK)
  {
    errorcode = HAL_ERROR;
    hspi->ErrorCode = HAL_SPI_ERROR_FLAG;
    goto error;
  }
Dave Hylands's avatar
Dave Hylands committed
579

580
581
582
583
  /* Clear overrun flag in 2 Lines communication mode because received is not read */
  if(hspi->Init.Direction == SPI_DIRECTION_2LINES)
  {
    __HAL_SPI_CLEAR_OVRFLAG(hspi);
Dave Hylands's avatar
Dave Hylands committed
584
  }
585
586
587
588
589
590
591
592
593
#if (USE_SPI_CRC != 0U)
  /* Enable CRC Transmission */
  if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
  {
     SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT);
  }
#endif /* USE_SPI_CRC */

  if(hspi->ErrorCode != HAL_SPI_ERROR_NONE)
Dave Hylands's avatar
Dave Hylands committed
594
  {
595
    errorcode = HAL_ERROR;
Dave Hylands's avatar
Dave Hylands committed
596
  }
597
598
599
600
601
602

error:
  hspi->State = HAL_SPI_STATE_READY;
  /* Process Unlocked */
  __HAL_UNLOCK(hspi);
  return errorcode;
Dave Hylands's avatar
Dave Hylands committed
603
604
605
}

/**
606
  * @brief  Receive an amount of data in blocking mode.
607
  * @param  hspi: pointer to a SPI_HandleTypeDef structure that contains
608
  *               the configuration information for SPI module.
Dave Hylands's avatar
Dave Hylands committed
609
  * @param  pData: pointer to data buffer
610
  * @param  Size: amount of data to be received
Dave Hylands's avatar
Dave Hylands committed
611
612
613
614
615
  * @param  Timeout: Timeout duration
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_SPI_Receive(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout)
{
616
617
618
619
620
#if (USE_SPI_CRC != 0U)
  __IO uint16_t tmpreg = 0U;
#endif /* USE_SPI_CRC */
  uint32_t tickstart = 0U;
  HAL_StatusTypeDef errorcode = HAL_OK;
Dave Hylands's avatar
Dave Hylands committed
621

622
  if((hspi->Init.Mode == SPI_MODE_MASTER) && (hspi->Init.Direction == SPI_DIRECTION_2LINES))
Dave Hylands's avatar
Dave Hylands committed
623
  {
624
625
626
627
     hspi->State = HAL_SPI_STATE_BUSY_RX;
     /* Call transmit-receive function to send Dummy data on Tx line and generate clock on CLK line */
    return HAL_SPI_TransmitReceive(hspi,pData,pData,Size,Timeout);
  }
Dave Hylands's avatar
Dave Hylands committed
628

629
630
  /* Process Locked */
  __HAL_LOCK(hspi);
Dave Hylands's avatar
Dave Hylands committed
631

632
633
  /* Init tickstart for timeout management*/
  tickstart = HAL_GetTick();
Dave Hylands's avatar
Dave Hylands committed
634

635
636
637
638
639
  if(hspi->State != HAL_SPI_STATE_READY)
  {
    errorcode = HAL_BUSY;
    goto error;
  }
Dave Hylands's avatar
Dave Hylands committed
640

641
642
643
644
645
  if((pData == NULL ) || (Size == 0U))
  {
    errorcode = HAL_ERROR;
    goto error;
  }
Dave Hylands's avatar
Dave Hylands committed
646

647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
  /* Set the transaction information */
  hspi->State       = HAL_SPI_STATE_BUSY_RX;
  hspi->ErrorCode   = HAL_SPI_ERROR_NONE;
  hspi->pRxBuffPtr  = (uint8_t *)pData;
  hspi->RxXferSize  = Size;
  hspi->RxXferCount = Size;

  /*Init field not used in handle to zero */
  hspi->pTxBuffPtr  = (uint8_t *)NULL;
  hspi->TxXferSize  = 0U;
  hspi->TxXferCount = 0U;
  hspi->RxISR       = NULL;
  hspi->TxISR       = NULL;

#if (USE_SPI_CRC != 0U)
  /* Reset CRC Calculation */
  if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
  {
    SPI_RESET_CRC(hspi);
    /* this is done to handle the CRCNEXT before the latest data */
    hspi->RxXferCount--;
  }
#endif /* USE_SPI_CRC */
Dave Hylands's avatar
Dave Hylands committed
670

671
672
673
674
675
  /* Configure communication direction: 1Line */
  if(hspi->Init.Direction == SPI_DIRECTION_1LINE)
  {
    SPI_1LINE_RX(hspi);
  }
Dave Hylands's avatar
Dave Hylands committed
676

677
678
679
680
681
682
  /* Check if the SPI is already enabled */
  if((hspi->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE)
  {
    /* Enable SPI peripheral */
    __HAL_SPI_ENABLE(hspi);
  }
Dave Hylands's avatar
Dave Hylands committed
683
684

    /* Receive data in 8 Bit mode */
685
686
687
688
  if(hspi->Init.DataSize == SPI_DATASIZE_8BIT)
  {
    /* Transfer loop */
    while(hspi->RxXferCount > 0U)
Dave Hylands's avatar
Dave Hylands committed
689
    {
690
691
      /* Check the RXNE flag */
      if(__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_RXNE))
Dave Hylands's avatar
Dave Hylands committed
692
      {
693
694
695
        /* read the received data */
        (* (uint8_t *)pData)= *(__IO uint8_t *)&hspi->Instance->DR;
        pData += sizeof(uint8_t);
Dave Hylands's avatar
Dave Hylands committed
696
697
        hspi->RxXferCount--;
      }
698
      else
Dave Hylands's avatar
Dave Hylands committed
699
      {
700
701
702
703
704
705
        /* Timeout management */
        if((Timeout == 0U) || ((Timeout != HAL_MAX_DELAY) && ((HAL_GetTick()-tickstart) >=  Timeout)))
        {
          errorcode = HAL_TIMEOUT;
          goto error;
        }
Dave Hylands's avatar
Dave Hylands committed
706
707
      }
    }
708
709
710
711
712
  }
  else
  {
    /* Transfer loop */
    while(hspi->RxXferCount > 0U)
Dave Hylands's avatar
Dave Hylands committed
713
    {
714
715
      /* Check the RXNE flag */
      if(__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_RXNE))
Dave Hylands's avatar
Dave Hylands committed
716
      {
717
718
        *((uint16_t*)pData) = hspi->Instance->DR;
        pData += sizeof(uint16_t);
Dave Hylands's avatar
Dave Hylands committed
719
720
        hspi->RxXferCount--;
      }
721
      else
Dave Hylands's avatar
Dave Hylands committed
722
      {
723
724
725
726
727
728
        /* Timeout management */
        if((Timeout == 0U) || ((Timeout != HAL_MAX_DELAY) && ((HAL_GetTick()-tickstart) >=  Timeout)))
        {
          errorcode = HAL_TIMEOUT;
          goto error;
        }
Dave Hylands's avatar
Dave Hylands committed
729
730
      }
    }
731
  }
Dave Hylands's avatar
Dave Hylands committed
732

733
734
735
736
737
738
#if (USE_SPI_CRC != 0U)
  /* Handle the CRC Transmission */
  if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
  {
    /* freeze the CRC before the latest data */
    SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT);
Dave Hylands's avatar
Dave Hylands committed
739

740
741
    /* Read the latest data */
    if(SPI_WaitFlagStateUntilTimeout(hspi, SPI_FLAG_RXNE, SET, Timeout, tickstart) != HAL_OK)
Dave Hylands's avatar
Dave Hylands committed
742
    {
743
744
745
      /* the latest data has not been received */
      errorcode = HAL_TIMEOUT;
      goto error;
Dave Hylands's avatar
Dave Hylands committed
746
    }
747

Dave Hylands's avatar
Dave Hylands committed
748
    /* Receive last data in 16 Bit mode */
749
    if(hspi->Init.DataSize == SPI_DATASIZE_16BIT)
Dave Hylands's avatar
Dave Hylands committed
750
    {
751
      *((uint16_t*)pData) = hspi->Instance->DR;
Dave Hylands's avatar
Dave Hylands committed
752
    }
753
754
    /* Receive last data in 8 Bit mode */
    else
Dave Hylands's avatar
Dave Hylands committed
755
    {
756
      (*(uint8_t *)pData) = *(__IO uint8_t *)&hspi->Instance->DR;
Dave Hylands's avatar
Dave Hylands committed
757
    }
758
759
760

    /* Wait the CRC data */
    if(SPI_WaitFlagStateUntilTimeout(hspi, SPI_FLAG_RXNE, SET, Timeout, tickstart) != HAL_OK)
Dave Hylands's avatar
Dave Hylands committed
761
    {
762
763
764
      SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC);
      errorcode = HAL_TIMEOUT;
      goto error;
Dave Hylands's avatar
Dave Hylands committed
765
766
    }

767
768
769
770
771
772
    /* Read CRC to Flush DR and RXNE flag */
    tmpreg = hspi->Instance->DR;
    /* To avoid GCC warning */
    UNUSED(tmpreg);
  }
#endif /* USE_SPI_CRC */
Dave Hylands's avatar
Dave Hylands committed
773

774
775
776
777
778
  if((hspi->Init.Mode == SPI_MODE_MASTER)&&((hspi->Init.Direction == SPI_DIRECTION_1LINE)||(hspi->Init.Direction == SPI_DIRECTION_2LINES_RXONLY)))
  {
    /* Disable SPI peripheral */
    __HAL_SPI_DISABLE(hspi);
  }
Dave Hylands's avatar
Dave Hylands committed
779

780
781
782
783
784
785
#if (USE_SPI_CRC != 0U)
  /* Check if CRC error occurred */
  if(__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_CRCERR))
  {
    SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC);
    __HAL_SPI_CLEAR_CRCERRFLAG(hspi);
Dave Hylands's avatar
Dave Hylands committed
786
  }
787
788
789
#endif /* USE_SPI_CRC */

  if(hspi->ErrorCode != HAL_SPI_ERROR_NONE)
Dave Hylands's avatar
Dave Hylands committed
790
  {
791
    errorcode = HAL_ERROR;
Dave Hylands's avatar
Dave Hylands committed
792
  }
793
794
795
796
797

error :
  hspi->State = HAL_SPI_STATE_READY;
  __HAL_UNLOCK(hspi);
  return errorcode;
Dave Hylands's avatar
Dave Hylands committed
798
799
800
}

/**
801
  * @brief  Transmit and Receive an amount of data in blocking mode.
802
  * @param  hspi: pointer to a SPI_HandleTypeDef structure that contains
803
  *               the configuration information for SPI module.
Dave Hylands's avatar
Dave Hylands committed
804
  * @param  pTxData: pointer to transmission data buffer
805
806
  * @param  pRxData: pointer to reception data buffer
  * @param  Size: amount of data to be sent and received
Dave Hylands's avatar
Dave Hylands committed
807
808
809
810
811
  * @param  Timeout: Timeout duration
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_SPI_TransmitReceive(SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size, uint32_t Timeout)
{
812
813
814
815
816
817
818
819
820
821
822
  uint32_t tmp = 0U, tmp1 = 0U;
#if (USE_SPI_CRC != 0U)
  __IO uint16_t tmpreg1 = 0U;
#endif /* USE_SPI_CRC */
  uint32_t tickstart = 0U;
  /* Variable used to alternate Rx and Tx during transfer */
  uint32_t txallowed = 1U;
  HAL_StatusTypeDef errorcode = HAL_OK;

  /* Check Direction parameter */
  assert_param(IS_SPI_DIRECTION_2LINES(hspi->Init.Direction));
Dave Hylands's avatar
Dave Hylands committed
823

824
825
  /* Process Locked */
  __HAL_LOCK(hspi);
Dave Hylands's avatar
Dave Hylands committed
826

827
828
829
830
831
832
833
834
835
836
837
838
  /* Init tickstart for timeout management*/
  tickstart = HAL_GetTick();
  
  tmp  = hspi->State;
  tmp1 = hspi->Init.Mode;
  
  if(!((tmp == HAL_SPI_STATE_READY) || \
    ((tmp1 == SPI_MODE_MASTER) && (hspi->Init.Direction == SPI_DIRECTION_2LINES) && (tmp == HAL_SPI_STATE_BUSY_RX))))
  {
    errorcode = HAL_BUSY;
    goto error;
  }
Dave Hylands's avatar
Dave Hylands committed
839

840
841
842
843
844
  if((pTxData == NULL) || (pRxData == NULL) || (Size == 0U))
  {
    errorcode = HAL_ERROR;
    goto error;
  }
Dave Hylands's avatar
Dave Hylands committed
845

846
847
848
849
850
  /* Don't overwrite in case of HAL_SPI_STATE_BUSY_RX */
  if(hspi->State == HAL_SPI_STATE_READY)
  {
    hspi->State = HAL_SPI_STATE_BUSY_TX_RX;
  }
Dave Hylands's avatar
Dave Hylands committed
851

852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
  /* Set the transaction information */
  hspi->ErrorCode   = HAL_SPI_ERROR_NONE;
  hspi->pRxBuffPtr  = (uint8_t *)pRxData;
  hspi->RxXferCount = Size;
  hspi->RxXferSize  = Size;
  hspi->pTxBuffPtr  = (uint8_t *)pTxData;
  hspi->TxXferCount = Size;
  hspi->TxXferSize  = Size;

  /*Init field not used in handle to zero */
  hspi->RxISR       = NULL;
  hspi->TxISR       = NULL;

#if (USE_SPI_CRC != 0U)
  /* Reset CRC Calculation */
  if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
  {
    SPI_RESET_CRC(hspi);
  }
#endif /* USE_SPI_CRC */
Dave Hylands's avatar
Dave Hylands committed
872

873
874
875
876
877
878
  /* Check if the SPI is already enabled */
  if((hspi->Instance->CR1 &SPI_CR1_SPE) != SPI_CR1_SPE)
  {
    /* Enable SPI peripheral */
    __HAL_SPI_ENABLE(hspi);
  }
Dave Hylands's avatar
Dave Hylands committed
879

880
881
882
883
  /* Transmit and Receive data in 16 Bit mode */
  if(hspi->Init.DataSize == SPI_DATASIZE_16BIT)
  {
    if((hspi->Init.Mode == SPI_MODE_SLAVE) || (hspi->TxXferCount == 0x01))
Dave Hylands's avatar
Dave Hylands committed
884
    {
885
886
887
      hspi->Instance->DR = *((uint16_t *)pTxData);
      pTxData += sizeof(uint16_t);
      hspi->TxXferCount--;
Dave Hylands's avatar
Dave Hylands committed
888
    }
889
    while ((hspi->TxXferCount > 0U) || (hspi->RxXferCount > 0U))
Dave Hylands's avatar
Dave Hylands committed
890
    {
891
892
      /* Check TXE flag */
      if(txallowed && (hspi->TxXferCount > 0U) && (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXE)))
893
      {
894
895
        hspi->Instance->DR = *((uint16_t *)pTxData);
        pTxData += sizeof(uint16_t);
896
        hspi->TxXferCount--;
897
898
899
900
        /* Next Data is a reception (Rx). Tx not allowed */ 
        txallowed = 0U;

#if (USE_SPI_CRC != 0U)
Dave Hylands's avatar
Dave Hylands committed
901
        /* Enable CRC Transmission */
902
        if((hspi->TxXferCount == 0U) && (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE))
Dave Hylands's avatar
Dave Hylands committed
903
        {
904
          SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT);
Dave Hylands's avatar
Dave Hylands committed
905
        }
906
907
#endif /* USE_SPI_CRC */
      }
Dave Hylands's avatar
Dave Hylands committed
908

909
910
911
912
913
      /* Check RXNE flag */
      if((hspi->RxXferCount > 0U) && (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_RXNE)))
      {
        *((uint16_t *)pRxData) = hspi->Instance->DR;
        pRxData += sizeof(uint16_t);
Dave Hylands's avatar
Dave Hylands committed
914
        hspi->RxXferCount--;
915
916
        /* Next Data is a Transmission (Tx). Tx is allowed */ 
        txallowed = 1U;
Dave Hylands's avatar
Dave Hylands committed
917
      }
918
      if((Timeout != HAL_MAX_DELAY) && ((HAL_GetTick()-tickstart) >=  Timeout))
Dave Hylands's avatar
Dave Hylands committed
919
      {
920
921
        errorcode = HAL_TIMEOUT;
        goto error;
Dave Hylands's avatar
Dave Hylands committed
922
923
      }
    }
924
925
926
927
928
929
930
931
932
933
934
  }
  /* Transmit and Receive data in 8 Bit mode */
  else
  {
    if((hspi->Init.Mode == SPI_MODE_SLAVE) || (hspi->TxXferCount == 0x01))
    {
      *((__IO uint8_t*)&hspi->Instance->DR) = (*pTxData);
      pTxData += sizeof(uint8_t);
      hspi->TxXferCount--;
    }
    while((hspi->TxXferCount > 0U) || (hspi->RxXferCount > 0U))
Dave Hylands's avatar
Dave Hylands committed
935
    {
936
937
      /* check TXE flag */
      if(txallowed && (hspi->TxXferCount > 0U) && (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXE)))
938
      {
939
        *(__IO uint8_t *)&hspi->Instance->DR = (*pTxData++);
940
        hspi->TxXferCount--;
941
942
        /* Next Data is a reception (Rx). Tx not allowed */ 
        txallowed = 0U;
Dave Hylands's avatar
Dave Hylands committed
943

944
945
946
#if (USE_SPI_CRC != 0U)
        /* Enable CRC Transmission */
        if((hspi->TxXferCount == 0U) && (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE))
Dave Hylands's avatar
Dave Hylands committed
947
        {
948
          SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT);
Dave Hylands's avatar
Dave Hylands committed
949
        }
950
951
#endif /* USE_SPI_CRC */
      }
Dave Hylands's avatar
Dave Hylands committed
952

953
954
955
956
      /* Wait until RXNE flag is reset */
      if((hspi->RxXferCount > 0U) && (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_RXNE)))
      {
        (*(uint8_t *)pRxData++) = hspi->Instance->DR;
Dave Hylands's avatar
Dave Hylands committed
957
        hspi->RxXferCount--;
958
959
        /* Next Data is a Transmission (Tx). Tx is allowed */ 
        txallowed = 1U;
Dave Hylands's avatar
Dave Hylands committed
960
      }
961
      if((Timeout != HAL_MAX_DELAY) && ((HAL_GetTick()-tickstart) >=  Timeout))
Dave Hylands's avatar
Dave Hylands committed
962
      {
963
964
        errorcode = HAL_TIMEOUT;
        goto error;
Dave Hylands's avatar
Dave Hylands committed
965
966
      }
    }
967
  }
Dave Hylands's avatar
Dave Hylands committed
968

969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
#if (USE_SPI_CRC != 0U)
  /* Read CRC from DR to close CRC calculation process */
  if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)
  {
    /* Wait until TXE flag */
    if(SPI_WaitFlagStateUntilTimeout(hspi, SPI_FLAG_RXNE, SET, Timeout, tickstart) != HAL_OK)
    {
      /* Error on the CRC reception */
      SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC);
      errorcode = HAL_TIMEOUT;
      goto error;
    }
    /* Read CRC */
    tmpreg1 = hspi->Instance->DR;
    /* To avoid GCC warning */
    UNUSED(tmpreg1);
  }
Dave Hylands's avatar
Dave Hylands committed
986

987
988
989
990
991
992
  /* Check if CRC error occurred */
  if(__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_CRCERR))
  {
    SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_CRC);
    /* Clear CRC Flag */
    __HAL_SPI_CLEAR_CRCERRFLAG(hspi);
Dave Hylands's avatar
Dave Hylands committed
993

994
995
996
    errorcode = HAL_ERROR;
  }
#endif /* USE_SPI_CRC */
Dave Hylands's avatar
Dave Hylands committed
997

998
999
1000
  /* Wait until TXE flag */
  if(SPI_WaitFlagStateUntilTimeout(hspi, SPI_FLAG_TXE, SET, Timeout, tickstart) != HAL_OK)
  {
For faster browsing, not all history is shown. View entire blame