mirror of
				https://github.com/IcedRooibos/py32f0-template.git
				synced 2025-10-31 01:42:04 -07:00 
			
		
		
		
	
		
			
				
	
	
		
			3730 lines
		
	
	
		
			121 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			3730 lines
		
	
	
		
			121 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /**
 | |
|   ******************************************************************************
 | |
|   * @file    py32f0xx_hal_spi.c
 | |
|   * @author  MCU Application Team
 | |
|   * @brief   SPI HAL module driver.
 | |
|   *          This file provides firmware functions to manage the following
 | |
|   *          functionalities of the Serial Peripheral Interface (SPI) peripheral:
 | |
|   *           + Initialization and de-initialization functions
 | |
|   *           + IO operation functions
 | |
|   *           + Peripheral Control functions
 | |
|   *           + Peripheral State functions
 | |
|   *
 | |
|   @verbatim
 | |
|   ==============================================================================
 | |
|                         ##### How to use this driver #####
 | |
|   ==============================================================================
 | |
|     [..]
 | |
|       The SPI HAL driver can be used as follows:
 | |
| 
 | |
|       (#) Declare a SPI_HandleTypeDef handle structure, for example:
 | |
|           SPI_HandleTypeDef  hspi;
 | |
| 
 | |
|       (#)Initialize the SPI low level resources by implementing the HAL_SPI_MspInit() API:
 | |
|           (##) Enable the SPIx interface clock
 | |
|           (##) SPI pins configuration
 | |
|               (+++) Enable the clock for the SPI GPIOs
 | |
|               (+++) 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/Channel
 | |
|               (+++) Enable the DMAx clock
 | |
|               (+++) Configure the DMA handle parameters
 | |
|               (+++) Configure the DMA Tx or Rx Stream/Channel
 | |
|               (+++) Associate the initialized hdma_tx(or _rx)  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/Channel
 | |
| 
 | |
|       (#) Program the Mode, BidirectionalMode , Data size, Baudrate Prescaler, NSS
 | |
|           management, Clock polarity and phase, FirstBit 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)
 | |
|               by calling the customized HAL_SPI_MspInit() API.
 | |
|      [..]
 | |
|        Circular mode restriction:
 | |
|       (#) The DMA circular mode cannot be used when the SPI is configured in these modes:
 | |
|           (##) Master 2Lines RxOnly
 | |
|           (##) Master 1Line Rx
 | |
|       (#) When the SPI DMA Pause/Stop features are used, we must use the following APIs
 | |
|           the HAL_SPI_DMAPause()/ HAL_SPI_DMAStop() only under the SPI callbacks
 | |
|      [..]
 | |
|        Master Receive mode restriction:
 | |
|       (#) In Master unidirectional receive-only mode (MSTR =1, BIDIMODE=0, RXONLY=1) 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()
 | |
|      [..]
 | |
|        Data buffer address alignment restriction:
 | |
|       (#) In case more than 1 byte is requested to be transferred, the HAL SPI uses 16-bit access for data buffer.
 | |
|           But there is no support for unaligned accesses on the Cortex-M0 processor.
 | |
|           So, if the user wants to transfer more than 1 byte, it shall ensure that 16-bit aligned address is used for:
 | |
|           (##) pData parameter in HAL_SPI_Transmit(), HAL_SPI_Transmit_IT(), HAL_SPI_Receive() and HAL_SPI_Receive_IT()
 | |
|           (##) pTxData and pRxData parameters in HAL_SPI_TransmitReceive() and HAL_SPI_TransmitReceive_IT()
 | |
|       (#) There is no such restriction when going through DMA by using HAL_SPI_Transmit_DMA(), HAL_SPI_Receive_DMA()
 | |
|           and HAL_SPI_TransmitReceive_DMA().
 | |
|      [..]
 | |
|        Callback registration:
 | |
| 
 | |
|       (#) The compilation flag USE_HAL_SPI_REGISTER_CALLBACKS when set to 1U
 | |
|           allows the user to configure dynamically the driver callbacks.
 | |
|           Use Functions HAL_SPI_RegisterCallback() to register an interrupt callback.
 | |
| 
 | |
|           Function HAL_SPI_RegisterCallback() allows to register following callbacks:
 | |
|             (++) TxCpltCallback        : SPI Tx Completed callback
 | |
|             (++) RxCpltCallback        : SPI Rx Completed callback
 | |
|             (++) TxRxCpltCallback      : SPI TxRx Completed callback
 | |
|             (++) TxHalfCpltCallback    : SPI Tx Half Completed callback
 | |
|             (++) RxHalfCpltCallback    : SPI Rx Half Completed callback
 | |
|             (++) TxRxHalfCpltCallback  : SPI TxRx Half Completed callback
 | |
|             (++) ErrorCallback         : SPI Error callback
 | |
|             (++) AbortCpltCallback     : SPI Abort callback
 | |
|             (++) MspInitCallback       : SPI Msp Init callback
 | |
|             (++) MspDeInitCallback     : SPI Msp DeInit callback
 | |
|           This function takes as parameters the HAL peripheral handle, the Callback ID
 | |
|           and a pointer to the user callback function.
 | |
| 
 | |
| 
 | |
|       (#) Use function HAL_SPI_UnRegisterCallback to reset a callback to the default
 | |
|           weak function.
 | |
|           HAL_SPI_UnRegisterCallback takes as parameters the HAL peripheral handle,
 | |
|           and the Callback ID.
 | |
|           This function allows to reset following callbacks:
 | |
|             (++) TxCpltCallback        : SPI Tx Completed callback
 | |
|             (++) RxCpltCallback        : SPI Rx Completed callback
 | |
|             (++) TxRxCpltCallback      : SPI TxRx Completed callback
 | |
|             (++) TxHalfCpltCallback    : SPI Tx Half Completed callback
 | |
|             (++) RxHalfCpltCallback    : SPI Rx Half Completed callback
 | |
|             (++) TxRxHalfCpltCallback  : SPI TxRx Half Completed callback
 | |
|             (++) ErrorCallback         : SPI Error callback
 | |
|             (++) AbortCpltCallback     : SPI Abort callback
 | |
|             (++) MspInitCallback       : SPI Msp Init callback
 | |
|             (++) MspDeInitCallback     : SPI Msp DeInit callback
 | |
| 
 | |
|        [..]
 | |
|        By default, after the HAL_SPI_Init() and when the state is HAL_SPI_STATE_RESET
 | |
|        all callbacks are set to the corresponding weak functions:
 | |
|        examples HAL_SPI_MasterTxCpltCallback(), HAL_SPI_MasterRxCpltCallback().
 | |
|        Exception done for MspInit and MspDeInit functions that are
 | |
|        reset to the legacy weak functions in the HAL_SPI_Init()/ HAL_SPI_DeInit() only when
 | |
|        these callbacks are null (not registered beforehand).
 | |
|        If MspInit or MspDeInit are not null, the HAL_SPI_Init()/ HAL_SPI_DeInit()
 | |
|        keep and use the user MspInit/MspDeInit callbacks (registered beforehand) whatever the state.
 | |
| 
 | |
|        [..]
 | |
|        Callbacks can be registered/unregistered in HAL_SPI_STATE_READY state only.
 | |
|        Exception done MspInit/MspDeInit functions that can be registered/unregistered
 | |
|        in HAL_SPI_STATE_READY or HAL_SPI_STATE_RESET state,
 | |
|        thus registered (user) MspInit/DeInit callbacks can be used during the Init/DeInit.
 | |
|        Then, the user first registers the MspInit/MspDeInit user callbacks
 | |
|        using HAL_SPI_RegisterCallback() before calling HAL_SPI_DeInit()
 | |
|        or HAL_SPI_Init() function.
 | |
| 
 | |
|        [..]
 | |
|        When the compilation define USE_HAL_PPP_REGISTER_CALLBACKS is set to 0 or
 | |
|        not defined, the callback registering feature is not available
 | |
|        and weak (surcharged) callbacks are used.
 | |
| 
 | |
|      [..]
 | |
|        Using the HAL it is not possible to reach all supported SPI frequency with the different SPI Modes,
 | |
|        the following table resume the max SPI frequency reached with data size 8bits/16bits,
 | |
|          according to frequency of the APBx Peripheral Clock (fPCLK) used by the SPI instance.
 | |
| 
 | |
|   @endverbatim
 | |
| 
 | |
|   Additional table :
 | |
| 
 | |
|        DataSize = SPI_DATASIZE_8BIT:
 | |
|        +----------------------------------------------------------------------------------------------+
 | |
|        |         |                | 2Lines Fullduplex   |     2Lines RxOnly    |         1Line        |
 | |
|        | Process | Tranfert mode  |---------------------|----------------------|----------------------|
 | |
|        |         |                |  Master  |  Slave   |  Master   |  Slave   |  Master   |  Slave   |
 | |
|        |==============================================================================================|
 | |
|        |    T    |     Polling    | Fpclk/4  | Fpclk/8  |    NA     |    NA    |    NA     |   NA     |
 | |
|        |    X    |----------------|----------|----------|-----------|----------|-----------|----------|
 | |
|        |    /    |     Interrupt  | Fpclk/4  | Fpclk/16 |    NA     |    NA    |    NA     |   NA     |
 | |
|        |    R    |----------------|----------|----------|-----------|----------|-----------|----------|
 | |
|        |    X    |       DMA      | Fpclk/2  | Fpclk/2  |    NA     |    NA    |    NA     |   NA     |
 | |
|        |=========|================|==========|==========|===========|==========|===========|==========|
 | |
|        |         |     Polling    | Fpclk/4  | Fpclk/8  | Fpclk/16  | Fpclk/8  | Fpclk/8   | Fpclk/8  |
 | |
|        |         |----------------|----------|----------|-----------|----------|-----------|----------|
 | |
|        |    R    |     Interrupt  | Fpclk/8  | Fpclk/16 | Fpclk/8   | Fpclk/8  | Fpclk/8   | Fpclk/4  |
 | |
|        |    X    |----------------|----------|----------|-----------|----------|-----------|----------|
 | |
|        |         |       DMA      | Fpclk/4  | Fpclk/2  | Fpclk/2   | Fpclk/16 | Fpclk/2   | Fpclk/16 |
 | |
|        |=========|================|==========|==========|===========|==========|===========|==========|
 | |
|        |         |     Polling    | Fpclk/8  | Fpclk/2  |     NA    |    NA    | Fpclk/8   | Fpclk/8  |
 | |
|        |         |----------------|----------|----------|-----------|----------|-----------|----------|
 | |
|        |    T    |     Interrupt  | Fpclk/2  | Fpclk/4  |     NA    |    NA    | Fpclk/16  | Fpclk/8  |
 | |
|        |    X    |----------------|----------|----------|-----------|----------|-----------|----------|
 | |
|        |         |       DMA      | Fpclk/2  | Fpclk/2  |     NA    |    NA    | Fpclk/8   | Fpclk/16 |
 | |
|        +----------------------------------------------------------------------------------------------+
 | |
| 
 | |
|        DataSize = SPI_DATASIZE_16BIT:
 | |
|        +----------------------------------------------------------------------------------------------+
 | |
|        |         |                | 2Lines Fullduplex   |     2Lines RxOnly    |         1Line        |
 | |
|        | Process | Tranfert mode  |---------------------|----------------------|----------------------|
 | |
|        |         |                |  Master  |  Slave   |  Master   |  Slave   |  Master   |  Slave   |
 | |
|        |==============================================================================================|
 | |
|        |    T    |     Polling    | Fpclk/4  | Fpclk/8  |    NA     |    NA    |    NA     |   NA     |
 | |
|        |    X    |----------------|----------|----------|-----------|----------|-----------|----------|
 | |
|        |    /    |     Interrupt  | Fpclk/4  | Fpclk/16 |    NA     |    NA    |    NA     |   NA     |
 | |
|        |    R    |----------------|----------|----------|-----------|----------|-----------|----------|
 | |
|        |    X    |       DMA      | Fpclk/2  | Fpclk/2  |    NA     |    NA    |    NA     |   NA     |
 | |
|        |=========|================|==========|==========|===========|==========|===========|==========|
 | |
|        |         |     Polling    | Fpclk/4  | Fpclk/8  | Fpclk/16  | Fpclk/8  | Fpclk/8   | Fpclk/8  |
 | |
|        |         |----------------|----------|----------|-----------|----------|-----------|----------|
 | |
|        |    R    |     Interrupt  | Fpclk/8  | Fpclk/16 | Fpclk/8   | Fpclk/8  | Fpclk/8   | Fpclk/4  |
 | |
|        |    X    |----------------|----------|----------|-----------|----------|-----------|----------|
 | |
|        |         |       DMA      | Fpclk/4  | Fpclk/2  | Fpclk/2   | Fpclk/16 | Fpclk/2   | Fpclk/16 |
 | |
|        |=========|================|==========|==========|===========|==========|===========|==========|
 | |
|        |         |     Polling    | Fpclk/8  | Fpclk/2  |     NA    |    NA    | Fpclk/8   | Fpclk/8  |
 | |
|        |         |----------------|----------|----------|-----------|----------|-----------|----------|
 | |
|        |    T    |     Interrupt  | Fpclk/2  | Fpclk/4  |     NA    |    NA    | Fpclk/16  | Fpclk/8  |
 | |
|        |    X    |----------------|----------|----------|-----------|----------|-----------|----------|
 | |
|        |         |       DMA      | Fpclk/2  | Fpclk/2  |     NA    |    NA    | Fpclk/8   | Fpclk/16 |
 | |
|        +----------------------------------------------------------------------------------------------+
 | |
|        @note The max SPI frequency depend on SPI data size (4bits, 5bits,..., 8bits,...15bits, 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()
 | |
| 
 | |
|   ******************************************************************************
 | |
|   * @attention
 | |
|   *
 | |
|   * <h2><center>© Copyright (c) Puya Semiconductor Co.
 | |
|   * All rights reserved.</center></h2>
 | |
|   *
 | |
|   * <h2><center>© Copyright (c) 2016 STMicroelectronics.
 | |
|   * All rights reserved.</center></h2>
 | |
|   *
 | |
|   * This software component is licensed by ST under BSD 3-Clause license,
 | |
|   * the "License"; You may not use this file except in compliance with the
 | |
|   * License. You may obtain a copy of the License at:
 | |
|   *                        opensource.org/licenses/BSD-3-Clause
 | |
|   *
 | |
|   ******************************************************************************
 | |
|   */
 | |
| 
 | |
| /* Includes ------------------------------------------------------------------*/
 | |
| #include "py32f0xx_hal.h"
 | |
| 
 | |
| /** @addtogroup PY32F0xx_HAL_Driver
 | |
|   * @{
 | |
|   */
 | |
| 
 | |
| /** @defgroup SPI SPI
 | |
|   * @brief SPI HAL module driver
 | |
|   * @{
 | |
|   */
 | |
| #ifdef HAL_SPI_MODULE_ENABLED
 | |
| 
 | |
| /* Private typedef -----------------------------------------------------------*/
 | |
| /* Private defines -----------------------------------------------------------*/
 | |
| /** @defgroup SPI_Private_Constants SPI Private Constants
 | |
|   * @{
 | |
|   */
 | |
| #define SPI_DEFAULT_TIMEOUT 100U
 | |
| /**
 | |
|   * @}
 | |
|   */
 | |
| 
 | |
| /* Private macros ------------------------------------------------------------*/
 | |
| /* Private variables ---------------------------------------------------------*/
 | |
| /* Private function prototypes -----------------------------------------------*/
 | |
| /** @defgroup SPI_Private_Functions SPI Private Functions
 | |
|   * @{
 | |
|   */
 | |
| #if (defined(DMA1) || defined(DMA))
 | |
| static void SPI_DMATransmitCplt(DMA_HandleTypeDef *hdma);
 | |
| static void SPI_DMAReceiveCplt(DMA_HandleTypeDef *hdma);
 | |
| static void SPI_DMATransmitReceiveCplt(DMA_HandleTypeDef *hdma);
 | |
| static void SPI_DMAHalfTransmitCplt(DMA_HandleTypeDef *hdma);
 | |
| static void SPI_DMAHalfReceiveCplt(DMA_HandleTypeDef *hdma);
 | |
| static void SPI_DMAHalfTransmitReceiveCplt(DMA_HandleTypeDef *hdma);
 | |
| static void SPI_DMAError(DMA_HandleTypeDef *hdma);
 | |
| static void SPI_DMAAbortOnError(DMA_HandleTypeDef *hdma);
 | |
| static void SPI_DMATxAbortCallback(DMA_HandleTypeDef *hdma);
 | |
| static void SPI_DMARxAbortCallback(DMA_HandleTypeDef *hdma);
 | |
| #endif /* DMA1 or DMA */
 | |
| static HAL_StatusTypeDef SPI_WaitFlagStateUntilTimeout(SPI_HandleTypeDef *hspi, uint32_t Flag, FlagStatus State,
 | |
|     uint32_t Timeout, uint32_t Tickstart);
 | |
| static HAL_StatusTypeDef SPI_WaitFifoStateUntilTimeout(SPI_HandleTypeDef *hspi, uint32_t Fifo, 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);
 | |
| static void SPI_AbortRx_ISR(SPI_HandleTypeDef *hspi);
 | |
| static void SPI_AbortTx_ISR(SPI_HandleTypeDef *hspi);
 | |
| 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_EndRxTransaction(SPI_HandleTypeDef *hspi, uint32_t Timeout, uint32_t Tickstart);
 | |
| static HAL_StatusTypeDef SPI_EndRxTxTransaction(SPI_HandleTypeDef *hspi, uint32_t Timeout, uint32_t Tickstart);
 | |
| /**
 | |
|   * @}
 | |
|   */
 | |
| 
 | |
| /* Exported functions --------------------------------------------------------*/
 | |
| /** @defgroup SPI_Exported_Functions SPI Exported Functions
 | |
|   * @{
 | |
|   */
 | |
| 
 | |
| /** @defgroup SPI_Exported_Functions_Group1 Initialization and de-initialization functions
 | |
|   *  @brief    Initialization and Configuration functions
 | |
|   *
 | |
| @verbatim
 | |
|  ===============================================================================
 | |
|               ##### Initialization and de-initialization functions #####
 | |
|  ===============================================================================
 | |
|     [..]  This subsection provides a set of functions allowing to initialize and
 | |
|           de-initialize the SPIx peripheral:
 | |
| 
 | |
|       (+) User must implement HAL_SPI_MspInit() function in which he configures
 | |
|           all related peripherals resources (CLOCK, GPIO, DMA, IT and NVIC ).
 | |
| 
 | |
|       (+) Call the function HAL_SPI_Init() to configure the selected device with
 | |
|           the selected configuration:
 | |
|         (++) Mode
 | |
|         (++) Direction
 | |
|         (++) Data Size
 | |
|         (++) Clock Polarity and Phase
 | |
|         (++) NSS Management
 | |
|         (++) BaudRate Prescaler
 | |
|         (++) FirstBit
 | |
|         (++) FIFO reception threshold
 | |
| 
 | |
|       (+) Call the function HAL_SPI_DeInit() to restore the default configuration
 | |
|           of the selected SPIx peripheral.
 | |
| 
 | |
| @endverbatim
 | |
|   * @{
 | |
|   */
 | |
| 
 | |
| /**
 | |
|   * @brief  Initialize the SPI according to the specified parameters
 | |
|   *         in the SPI_InitTypeDef and initialize the associated handle.
 | |
|   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
 | |
|   *               the configuration information for SPI module.
 | |
|   * @retval HAL status
 | |
|   */
 | |
| HAL_StatusTypeDef HAL_SPI_Init(SPI_HandleTypeDef *hspi)
 | |
| {
 | |
|   uint32_t frxth;
 | |
| 
 | |
|   /* Check the SPI handle allocation */
 | |
|   if (hspi == NULL)
 | |
|   {
 | |
|     return HAL_ERROR;
 | |
|   }
 | |
| 
 | |
|   /* Check the parameters */
 | |
|   assert_param(IS_SPI_ALL_INSTANCE(hspi->Instance));
 | |
|   assert_param(IS_SPI_MODE(hspi->Init.Mode));
 | |
|   assert_param(IS_SPI_DIRECTION(hspi->Init.Direction));
 | |
|   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));
 | |
| 
 | |
|   if (hspi->State == HAL_SPI_STATE_RESET)
 | |
|   {
 | |
|     /* Allocate lock resource and initialize it */
 | |
|     hspi->Lock = HAL_UNLOCKED;
 | |
| 
 | |
| #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U)
 | |
|     /* Init the SPI Callback settings */
 | |
|     hspi->TxCpltCallback       = HAL_SPI_TxCpltCallback;       /* Legacy weak TxCpltCallback       */
 | |
|     hspi->RxCpltCallback       = HAL_SPI_RxCpltCallback;       /* Legacy weak RxCpltCallback       */
 | |
|     hspi->TxRxCpltCallback     = HAL_SPI_TxRxCpltCallback;     /* Legacy weak TxRxCpltCallback     */
 | |
|     hspi->TxHalfCpltCallback   = HAL_SPI_TxHalfCpltCallback;   /* Legacy weak TxHalfCpltCallback   */
 | |
|     hspi->RxHalfCpltCallback   = HAL_SPI_RxHalfCpltCallback;   /* Legacy weak RxHalfCpltCallback   */
 | |
|     hspi->TxRxHalfCpltCallback = HAL_SPI_TxRxHalfCpltCallback; /* Legacy weak TxRxHalfCpltCallback */
 | |
|     hspi->ErrorCallback        = HAL_SPI_ErrorCallback;        /* Legacy weak ErrorCallback        */
 | |
|     hspi->AbortCpltCallback    = HAL_SPI_AbortCpltCallback;    /* Legacy weak AbortCpltCallback    */
 | |
| 
 | |
|     if (hspi->MspInitCallback == NULL)
 | |
|     {
 | |
|       hspi->MspInitCallback = HAL_SPI_MspInit; /* Legacy weak MspInit  */
 | |
|     }
 | |
| 
 | |
|     /* Init the low level hardware : GPIO, CLOCK, NVIC... */
 | |
|     hspi->MspInitCallback(hspi);
 | |
| #else
 | |
|     /* Init the low level hardware : GPIO, CLOCK, NVIC... */
 | |
|     HAL_SPI_MspInit(hspi);
 | |
| #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
 | |
|   }
 | |
| 
 | |
|   hspi->State = HAL_SPI_STATE_BUSY;
 | |
| 
 | |
|   /* Disable the selected SPI peripheral */
 | |
|   __HAL_SPI_DISABLE(hspi);
 | |
| 
 | |
|   /* Align by default the rs fifo threshold on the data size */
 | |
|   if (hspi->Init.DataSize > SPI_DATASIZE_8BIT)
 | |
|   {
 | |
|     frxth = SPI_RXFIFO_THRESHOLD_HF;
 | |
|   }
 | |
|   else
 | |
|   {
 | |
|     frxth = SPI_RXFIFO_THRESHOLD_QF;
 | |
|   }
 | |
| 
 | |
|   /*----------------------- SPIx CR1 & CR2 Configuration ---------------------*/
 | |
|   /* Configure : SPI Mode, Communication Mode, Clock polarity and phase, NSS management,
 | |
|   Communication speed, First bit */
 | |
|   WRITE_REG(hspi->Instance->CR1, (hspi->Init.Mode | hspi->Init.Direction |
 | |
|                                   hspi->Init.CLKPolarity | hspi->Init.CLKPhase | (hspi->Init.NSS & SPI_CR1_SSM) |
 | |
|                                   hspi->Init.BaudRatePrescaler | hspi->Init.FirstBit));
 | |
| 
 | |
|   /* Configure : NSS management, TI Mode, NSS Pulse, Data size and Rx Fifo threshold */
 | |
|   WRITE_REG(hspi->Instance->CR2, (((hspi->Init.NSS >> 16U) & SPI_CR2_SSOE) | hspi->Init.DataSize) | 
 | |
|                                     hspi->Init.SlaveFastMode | frxth);
 | |
| 
 | |
|   hspi->ErrorCode = HAL_SPI_ERROR_NONE;
 | |
|   hspi->State     = HAL_SPI_STATE_READY;
 | |
| 
 | |
|   return HAL_OK;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   * @brief  De-Initialize the SPI peripheral.
 | |
|   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
 | |
|   *               the configuration information for SPI module.
 | |
|   * @retval HAL status
 | |
|   */
 | |
| HAL_StatusTypeDef HAL_SPI_DeInit(SPI_HandleTypeDef *hspi)
 | |
| {
 | |
|   /* Check the SPI handle allocation */
 | |
|   if (hspi == NULL)
 | |
|   {
 | |
|     return HAL_ERROR;
 | |
|   }
 | |
| 
 | |
|   /* Check SPI Instance parameter */
 | |
|   assert_param(IS_SPI_ALL_INSTANCE(hspi->Instance));
 | |
| 
 | |
|   hspi->State = HAL_SPI_STATE_BUSY;
 | |
| 
 | |
|   /* Disable the SPI Peripheral Clock */
 | |
|   __HAL_SPI_DISABLE(hspi);
 | |
| 
 | |
| #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U)
 | |
|   if (hspi->MspDeInitCallback == NULL)
 | |
|   {
 | |
|     hspi->MspDeInitCallback = HAL_SPI_MspDeInit; /* Legacy weak MspDeInit  */
 | |
|   }
 | |
| 
 | |
|   /* DeInit the low level hardware: GPIO, CLOCK, NVIC... */
 | |
|   hspi->MspDeInitCallback(hspi);
 | |
| #else
 | |
|   /* DeInit the low level hardware: GPIO, CLOCK, NVIC... */
 | |
|   HAL_SPI_MspDeInit(hspi);
 | |
| #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
 | |
| 
 | |
|   hspi->ErrorCode = HAL_SPI_ERROR_NONE;
 | |
|   hspi->State = HAL_SPI_STATE_RESET;
 | |
| 
 | |
|   /* Release Lock */
 | |
|   __HAL_UNLOCK(hspi);
 | |
| 
 | |
|   return HAL_OK;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   * @brief  Initialize the SPI MSP.
 | |
|   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
 | |
|   *               the configuration information for SPI module.
 | |
|   * @retval None
 | |
|   */
 | |
| __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
 | |
|    */
 | |
| }
 | |
| 
 | |
| /**
 | |
|   * @brief  De-Initialize the SPI MSP.
 | |
|   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
 | |
|   *               the configuration information for SPI module.
 | |
|   * @retval None
 | |
|   */
 | |
| __weak void HAL_SPI_MspDeInit(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_MspDeInit should be implemented in the user file
 | |
|    */
 | |
| }
 | |
| 
 | |
| #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U)
 | |
| /**
 | |
|   * @brief  Register a User SPI Callback
 | |
|   *         To be used instead of the weak predefined callback
 | |
|   * @param  hspi Pointer to a SPI_HandleTypeDef structure that contains
 | |
|   *                the configuration information for the specified SPI.
 | |
|   * @param  CallbackID ID of the callback to be registered
 | |
|   * @param  pCallback pointer to the Callback function
 | |
|   * @retval HAL status
 | |
|   */
 | |
| HAL_StatusTypeDef HAL_SPI_RegisterCallback(SPI_HandleTypeDef *hspi, HAL_SPI_CallbackIDTypeDef CallbackID,
 | |
|     pSPI_CallbackTypeDef pCallback)
 | |
| {
 | |
|   HAL_StatusTypeDef status = HAL_OK;
 | |
| 
 | |
|   if (pCallback == NULL)
 | |
|   {
 | |
|     /* Update the error code */
 | |
|     hspi->ErrorCode |= HAL_SPI_ERROR_INVALID_CALLBACK;
 | |
| 
 | |
|     return HAL_ERROR;
 | |
|   }
 | |
|   /* Process locked */
 | |
|   __HAL_LOCK(hspi);
 | |
| 
 | |
|   if (HAL_SPI_STATE_READY == hspi->State)
 | |
|   {
 | |
|     switch (CallbackID)
 | |
|     {
 | |
|     case HAL_SPI_TX_COMPLETE_CB_ID :
 | |
|       hspi->TxCpltCallback = pCallback;
 | |
|       break;
 | |
| 
 | |
|     case HAL_SPI_RX_COMPLETE_CB_ID :
 | |
|       hspi->RxCpltCallback = pCallback;
 | |
|       break;
 | |
| 
 | |
|     case HAL_SPI_TX_RX_COMPLETE_CB_ID :
 | |
|       hspi->TxRxCpltCallback = pCallback;
 | |
|       break;
 | |
| 
 | |
|     case HAL_SPI_TX_HALF_COMPLETE_CB_ID :
 | |
|       hspi->TxHalfCpltCallback = pCallback;
 | |
|       break;
 | |
| 
 | |
|     case HAL_SPI_RX_HALF_COMPLETE_CB_ID :
 | |
|       hspi->RxHalfCpltCallback = pCallback;
 | |
|       break;
 | |
| 
 | |
|     case HAL_SPI_TX_RX_HALF_COMPLETE_CB_ID :
 | |
|       hspi->TxRxHalfCpltCallback = pCallback;
 | |
|       break;
 | |
| 
 | |
|     case HAL_SPI_ERROR_CB_ID :
 | |
|       hspi->ErrorCallback = pCallback;
 | |
|       break;
 | |
| 
 | |
|     case HAL_SPI_ABORT_CB_ID :
 | |
|       hspi->AbortCpltCallback = pCallback;
 | |
|       break;
 | |
| 
 | |
|     case HAL_SPI_MSPINIT_CB_ID :
 | |
|       hspi->MspInitCallback = pCallback;
 | |
|       break;
 | |
| 
 | |
|     case HAL_SPI_MSPDEINIT_CB_ID :
 | |
|       hspi->MspDeInitCallback = pCallback;
 | |
|       break;
 | |
| 
 | |
|     default :
 | |
|       /* Update the error code */
 | |
|       SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_INVALID_CALLBACK);
 | |
| 
 | |
|       /* Return error status */
 | |
|       status =  HAL_ERROR;
 | |
|       break;
 | |
|     }
 | |
|   }
 | |
|   else if (HAL_SPI_STATE_RESET == hspi->State)
 | |
|   {
 | |
|     switch (CallbackID)
 | |
|     {
 | |
|     case HAL_SPI_MSPINIT_CB_ID :
 | |
|       hspi->MspInitCallback = pCallback;
 | |
|       break;
 | |
| 
 | |
|     case HAL_SPI_MSPDEINIT_CB_ID :
 | |
|       hspi->MspDeInitCallback = pCallback;
 | |
|       break;
 | |
| 
 | |
|     default :
 | |
|       /* Update the error code */
 | |
|       SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_INVALID_CALLBACK);
 | |
| 
 | |
|       /* Return error status */
 | |
|       status =  HAL_ERROR;
 | |
|       break;
 | |
|     }
 | |
|   }
 | |
|   else
 | |
|   {
 | |
|     /* Update the error code */
 | |
|     SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_INVALID_CALLBACK);
 | |
| 
 | |
|     /* Return error status */
 | |
|     status =  HAL_ERROR;
 | |
|   }
 | |
| 
 | |
|   /* Release Lock */
 | |
|   __HAL_UNLOCK(hspi);
 | |
|   return status;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   * @brief  Unregister an SPI Callback
 | |
|   *         SPI callback is redirected to the weak predefined callback
 | |
|   * @param  hspi Pointer to a SPI_HandleTypeDef structure that contains
 | |
|   *                the configuration information for the specified SPI.
 | |
|   * @param  CallbackID ID of the callback to be unregistered
 | |
|   * @retval HAL status
 | |
|   */
 | |
| HAL_StatusTypeDef HAL_SPI_UnRegisterCallback(SPI_HandleTypeDef *hspi, HAL_SPI_CallbackIDTypeDef CallbackID)
 | |
| {
 | |
|   HAL_StatusTypeDef status = HAL_OK;
 | |
| 
 | |
|   /* Process locked */
 | |
|   __HAL_LOCK(hspi);
 | |
| 
 | |
|   if (HAL_SPI_STATE_READY == hspi->State)
 | |
|   {
 | |
|     switch (CallbackID)
 | |
|     {
 | |
|     case HAL_SPI_TX_COMPLETE_CB_ID :
 | |
|       hspi->TxCpltCallback = HAL_SPI_TxCpltCallback;             /* Legacy weak TxCpltCallback       */
 | |
|       break;
 | |
| 
 | |
|     case HAL_SPI_RX_COMPLETE_CB_ID :
 | |
|       hspi->RxCpltCallback = HAL_SPI_RxCpltCallback;             /* Legacy weak RxCpltCallback       */
 | |
|       break;
 | |
| 
 | |
|     case HAL_SPI_TX_RX_COMPLETE_CB_ID :
 | |
|       hspi->TxRxCpltCallback = HAL_SPI_TxRxCpltCallback;         /* Legacy weak TxRxCpltCallback     */
 | |
|       break;
 | |
| 
 | |
|     case HAL_SPI_TX_HALF_COMPLETE_CB_ID :
 | |
|       hspi->TxHalfCpltCallback = HAL_SPI_TxHalfCpltCallback;     /* Legacy weak TxHalfCpltCallback   */
 | |
|       break;
 | |
| 
 | |
|     case HAL_SPI_RX_HALF_COMPLETE_CB_ID :
 | |
|       hspi->RxHalfCpltCallback = HAL_SPI_RxHalfCpltCallback;     /* Legacy weak RxHalfCpltCallback   */
 | |
|       break;
 | |
| 
 | |
|     case HAL_SPI_TX_RX_HALF_COMPLETE_CB_ID :
 | |
|       hspi->TxRxHalfCpltCallback = HAL_SPI_TxRxHalfCpltCallback; /* Legacy weak TxRxHalfCpltCallback */
 | |
|       break;
 | |
| 
 | |
|     case HAL_SPI_ERROR_CB_ID :
 | |
|       hspi->ErrorCallback = HAL_SPI_ErrorCallback;               /* Legacy weak ErrorCallback        */
 | |
|       break;
 | |
| 
 | |
|     case HAL_SPI_ABORT_CB_ID :
 | |
|       hspi->AbortCpltCallback = HAL_SPI_AbortCpltCallback;       /* Legacy weak AbortCpltCallback    */
 | |
|       break;
 | |
| 
 | |
|     case HAL_SPI_MSPINIT_CB_ID :
 | |
|       hspi->MspInitCallback = HAL_SPI_MspInit;                   /* Legacy weak MspInit              */
 | |
|       break;
 | |
| 
 | |
|     case HAL_SPI_MSPDEINIT_CB_ID :
 | |
|       hspi->MspDeInitCallback = HAL_SPI_MspDeInit;               /* Legacy weak MspDeInit            */
 | |
|       break;
 | |
| 
 | |
|     default :
 | |
|       /* Update the error code */
 | |
|       SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_INVALID_CALLBACK);
 | |
| 
 | |
|       /* Return error status */
 | |
|       status =  HAL_ERROR;
 | |
|       break;
 | |
|     }
 | |
|   }
 | |
|   else if (HAL_SPI_STATE_RESET == hspi->State)
 | |
|   {
 | |
|     switch (CallbackID)
 | |
|     {
 | |
|     case HAL_SPI_MSPINIT_CB_ID :
 | |
|       hspi->MspInitCallback = HAL_SPI_MspInit;                   /* Legacy weak MspInit              */
 | |
|       break;
 | |
| 
 | |
|     case HAL_SPI_MSPDEINIT_CB_ID :
 | |
|       hspi->MspDeInitCallback = HAL_SPI_MspDeInit;               /* Legacy weak MspDeInit            */
 | |
|       break;
 | |
| 
 | |
|     default :
 | |
|       /* Update the error code */
 | |
|       SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_INVALID_CALLBACK);
 | |
| 
 | |
|       /* Return error status */
 | |
|       status =  HAL_ERROR;
 | |
|       break;
 | |
|     }
 | |
|   }
 | |
|   else
 | |
|   {
 | |
|     /* Update the error code */
 | |
|     SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_INVALID_CALLBACK);
 | |
| 
 | |
|     /* Return error status */
 | |
|     status =  HAL_ERROR;
 | |
|   }
 | |
| 
 | |
|   /* Release Lock */
 | |
|   __HAL_UNLOCK(hspi);
 | |
|   return status;
 | |
| }
 | |
| #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
 | |
| /**
 | |
|   * @}
 | |
|   */
 | |
| 
 | |
| /** @defgroup SPI_Exported_Functions_Group2 IO operation functions
 | |
|   *  @brief   Data transfers functions
 | |
|   *
 | |
| @verbatim
 | |
|   ==============================================================================
 | |
|                       ##### IO operation functions #####
 | |
|  ===============================================================================
 | |
|  [..]
 | |
|     This subsection provides a set of functions allowing to manage the SPI
 | |
|     data transfers.
 | |
| 
 | |
|     [..] The SPI supports master and slave mode :
 | |
| 
 | |
|     (#) There are two modes of transfer:
 | |
|        (++) 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
 | |
|             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.
 | |
| 
 | |
| @endverbatim
 | |
|   * @{
 | |
|   */
 | |
| 
 | |
| /**
 | |
|   * @brief  Transmit an amount of data in blocking mode.
 | |
|   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
 | |
|   *               the configuration information for SPI module.
 | |
|   * @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)
 | |
| {
 | |
|   uint32_t tickstart;
 | |
|   HAL_StatusTypeDef errorcode = HAL_OK;
 | |
|   uint16_t initial_TxXferCount;
 | |
| 
 | |
|   /* Check Direction parameter */
 | |
|   assert_param(IS_SPI_DIRECTION_2LINES_OR_1LINE(hspi->Init.Direction));
 | |
| 
 | |
|   /* Process Locked */
 | |
|   __HAL_LOCK(hspi);
 | |
| 
 | |
|   /* Init tickstart for timeout management*/
 | |
|   tickstart = HAL_GetTick();
 | |
|   initial_TxXferCount = Size;
 | |
| 
 | |
|   if (hspi->State != HAL_SPI_STATE_READY)
 | |
|   {
 | |
|     errorcode = HAL_BUSY;
 | |
|     goto error;
 | |
|   }
 | |
| 
 | |
|   if ((pData == NULL) || (Size == 0U))
 | |
|   {
 | |
|     errorcode = HAL_ERROR;
 | |
|     goto error;
 | |
|   }
 | |
| 
 | |
|   /* Disable SPI peripheral */
 | |
|   __HAL_SPI_DISABLE(hspi);
 | |
| 
 | |
|   /* 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);
 | |
|   }
 | |
| 
 | |
|   /* Check if the SPI is already enabled */
 | |
|   if ((hspi->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE)
 | |
|   {
 | |
|     /* Enable SPI peripheral */
 | |
|     __HAL_SPI_ENABLE(hspi);
 | |
|   }
 | |
| 
 | |
|   /* Transmit data in 16 Bit mode */
 | |
|   if (hspi->Init.DataSize > SPI_DATASIZE_8BIT)
 | |
|   {
 | |
|     if ((hspi->Init.Mode == SPI_MODE_SLAVE) || (initial_TxXferCount == 0x01U))
 | |
|     {
 | |
|       hspi->Instance->DR = *((uint16_t *)hspi->pTxBuffPtr);
 | |
|       hspi->pTxBuffPtr += sizeof(uint16_t);
 | |
|       hspi->TxXferCount--;
 | |
|     }
 | |
|     /* Transmit data in 16 Bit mode */
 | |
|     while (hspi->TxXferCount > 0U)
 | |
|     {
 | |
|       /* Wait until TXE flag is set to send data */
 | |
|       if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXE))
 | |
|       {
 | |
|         hspi->Instance->DR = *((uint16_t *)hspi->pTxBuffPtr);
 | |
|         hspi->pTxBuffPtr += sizeof(uint16_t);
 | |
|         hspi->TxXferCount--;
 | |
|       }
 | |
|       else
 | |
|       {
 | |
|         /* Timeout management */
 | |
|         if ((((HAL_GetTick() - tickstart) >=  Timeout) && (Timeout != HAL_MAX_DELAY)) || (Timeout == 0U))
 | |
|         {
 | |
|           errorcode = HAL_TIMEOUT;
 | |
|           goto error;
 | |
|         }
 | |
|       }
 | |
|     }
 | |
|   }
 | |
|   /* Transmit data in 8 Bit mode */
 | |
|   else
 | |
|   {
 | |
|     if ((hspi->Init.Mode == SPI_MODE_SLAVE) || (initial_TxXferCount == 0x01U))
 | |
|     {
 | |
|       *((__IO uint8_t *)&hspi->Instance->DR) = (*hspi->pTxBuffPtr);
 | |
|       hspi->pTxBuffPtr += sizeof(uint8_t);
 | |
|       hspi->TxXferCount--;
 | |
|     }
 | |
|     while (hspi->TxXferCount > 0U)
 | |
|     {
 | |
|       /* Wait until TXE flag is set to send data */
 | |
|       if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXE))
 | |
|       {
 | |
|         *((__IO uint8_t *)&hspi->Instance->DR) = (*hspi->pTxBuffPtr);
 | |
|         hspi->pTxBuffPtr += sizeof(uint8_t);
 | |
|         hspi->TxXferCount--;
 | |
|       }
 | |
|       else
 | |
|       {
 | |
|         /* Timeout management */
 | |
|         if ((((HAL_GetTick() - tickstart) >=  Timeout) && (Timeout != HAL_MAX_DELAY)) || (Timeout == 0U))
 | |
|         {
 | |
|           errorcode = HAL_TIMEOUT;
 | |
|           goto error;
 | |
|         }
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   /* Check the end of the transaction */
 | |
|   if (SPI_EndRxTxTransaction(hspi, Timeout, tickstart) != HAL_OK)
 | |
|   {
 | |
|     hspi->ErrorCode = HAL_SPI_ERROR_FLAG;
 | |
|   }
 | |
| 
 | |
|   /* 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);
 | |
|   }
 | |
| 
 | |
|   if (hspi->ErrorCode != HAL_SPI_ERROR_NONE)
 | |
|   {
 | |
|     errorcode = HAL_ERROR;
 | |
|   }
 | |
| 
 | |
| error:
 | |
|   hspi->State = HAL_SPI_STATE_READY;
 | |
|   /* Process Unlocked */
 | |
|   __HAL_UNLOCK(hspi);
 | |
|   return errorcode;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   * @brief  Receive an amount of data in blocking mode.
 | |
|   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
 | |
|   *               the configuration information for SPI module.
 | |
|   * @param  pData pointer to data buffer
 | |
|   * @param  Size amount of data to be received
 | |
|   * @param  Timeout Timeout duration
 | |
|   * @retval HAL status
 | |
|   */
 | |
| HAL_StatusTypeDef HAL_SPI_Receive(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout)
 | |
| {
 | |
|   uint32_t tickstart;
 | |
|   HAL_StatusTypeDef errorcode = HAL_OK;
 | |
| 
 | |
|   if ((hspi->Init.DataSize > SPI_DATASIZE_8BIT) || ((hspi->Init.DataSize <= SPI_DATASIZE_8BIT) && (Size > 1U)))
 | |
|   {
 | |
|     /* in this case, 16-bit access is performed on Data
 | |
|        So, check Data is 16-bit aligned address */
 | |
|     assert_param(IS_SPI_16BIT_ALIGNED_ADDRESS(pData));
 | |
|   }
 | |
| 
 | |
|   if ((hspi->Init.Mode == SPI_MODE_MASTER) && (hspi->Init.Direction == SPI_DIRECTION_2LINES))
 | |
|   {
 | |
|     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);
 | |
|   }
 | |
| 
 | |
|   /* Process Locked */
 | |
|   __HAL_LOCK(hspi);
 | |
| 
 | |
|   /* Init tickstart for timeout management*/
 | |
|   tickstart = HAL_GetTick();
 | |
| 
 | |
|   if (hspi->State != HAL_SPI_STATE_READY)
 | |
|   {
 | |
|     errorcode = HAL_BUSY;
 | |
|     goto error;
 | |
|   }
 | |
| 
 | |
|   if ((pData == NULL) || (Size == 0U))
 | |
|   {
 | |
|     errorcode = HAL_ERROR;
 | |
|     goto error;
 | |
|   }
 | |
| 
 | |
|   /* Disable SPI peripheral */
 | |
|   __HAL_SPI_DISABLE(hspi);
 | |
| 
 | |
|   /* 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;
 | |
| 
 | |
|   /* Set the Rx Fifo threshold */
 | |
|   if (hspi->Init.DataSize > SPI_DATASIZE_8BIT)
 | |
|   {
 | |
|     /* Set RX Fifo threshold according the reception data length: 16bit */
 | |
|     CLEAR_BIT(hspi->Instance->CR2, SPI_RXFIFO_THRESHOLD);
 | |
|   }
 | |
|   else
 | |
|   {
 | |
|     /* Set RX Fifo threshold according the reception data length: 8bit */
 | |
|     SET_BIT(hspi->Instance->CR2, SPI_RXFIFO_THRESHOLD);
 | |
|   }
 | |
| 
 | |
|   /* Configure communication direction: 1Line */
 | |
|   if (hspi->Init.Direction == SPI_DIRECTION_1LINE)
 | |
|   {
 | |
|     SPI_1LINE_RX(hspi);
 | |
|   }
 | |
| 
 | |
|   /* Check if the SPI is already enabled */
 | |
|   if ((hspi->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE)
 | |
|   {
 | |
|     /* Enable SPI peripheral */
 | |
|     __HAL_SPI_ENABLE(hspi);
 | |
|   }
 | |
| 
 | |
|   /* Receive data in 8 Bit mode */
 | |
|   if (hspi->Init.DataSize <= SPI_DATASIZE_8BIT)
 | |
|   {
 | |
|     /* Transfer loop */
 | |
|     while (hspi->RxXferCount > 0U)
 | |
|     {
 | |
|       /* Check the RXNE flag */
 | |
|       if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_RXNE))
 | |
|       {
 | |
|         /* read the received data */
 | |
|         (* (uint8_t *)hspi->pRxBuffPtr) = *(__IO uint8_t *)&hspi->Instance->DR;
 | |
|         hspi->pRxBuffPtr += sizeof(uint8_t);
 | |
|         hspi->RxXferCount--;
 | |
|       }
 | |
|       else
 | |
|       {
 | |
|         /* Timeout management */
 | |
|         if ((((HAL_GetTick() - tickstart) >=  Timeout) && (Timeout != HAL_MAX_DELAY)) || (Timeout == 0U))
 | |
|         {
 | |
|           errorcode = HAL_TIMEOUT;
 | |
|           goto error;
 | |
|         }
 | |
|       }
 | |
|     }
 | |
|   }
 | |
|   else
 | |
|   {
 | |
|     /* Transfer loop */
 | |
|     while (hspi->RxXferCount > 0U)
 | |
|     {
 | |
|       /* Check the RXNE flag */
 | |
|       if (__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_RXNE))
 | |
|       {
 | |
|         *((uint16_t *)hspi->pRxBuffPtr) = (uint16_t)hspi->Instance->DR;
 | |
|         hspi->pRxBuffPtr += sizeof(uint16_t);
 | |
|         hspi->RxXferCount--;
 | |
|       }
 | |
|       else
 | |
|       {
 | |
|         /* Timeout management */
 | |
|         if ((((HAL_GetTick() - tickstart) >=  Timeout) && (Timeout != HAL_MAX_DELAY)) || (Timeout == 0U))
 | |
|         {
 | |
|           errorcode = HAL_TIMEOUT;
 | |
|           goto error;
 | |
|         }
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   /* Check the end of the transaction */
 | |
|   if (SPI_EndRxTransaction(hspi, Timeout, tickstart) != HAL_OK)
 | |
|   {
 | |
|     hspi->ErrorCode = HAL_SPI_ERROR_FLAG;
 | |
|   }
 | |
| 
 | |
|   if (hspi->ErrorCode != HAL_SPI_ERROR_NONE)
 | |
|   {
 | |
|     errorcode = HAL_ERROR;
 | |
|   }
 | |
| 
 | |
| error :
 | |
|   hspi->State = HAL_SPI_STATE_READY;
 | |
|   __HAL_UNLOCK(hspi);
 | |
|   return errorcode;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   * @brief  Transmit and Receive an amount of data in blocking mode.
 | |
|   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
 | |
|   *               the configuration information for SPI module.
 | |
|   * @param  pTxData pointer to transmission data buffer
 | |
|   * @param  pRxData pointer to reception data buffer
 | |
|   * @param  Size amount of data to be sent and received
 | |
|   * @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)
 | |
| {
 | |
|   uint16_t             initial_TxXferCount;
 | |
|   uint32_t             tmp_mode;
 | |
|   HAL_SPI_StateTypeDef tmp_state;
 | |
|   uint32_t             tickstart;
 | |
| 
 | |
|   /* 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));
 | |
| 
 | |
|   /* Process Locked */
 | |
|   __HAL_LOCK(hspi);
 | |
| 
 | |
|   /* Init tickstart for timeout management*/
 | |
|   tickstart = HAL_GetTick();
 | |
| 
 | |
|   /* Init temporary variables */
 | |
|   tmp_state           = hspi->State;
 | |
|   tmp_mode            = hspi->Init.Mode;
 | |
|   initial_TxXferCount = Size;
 | |
| 
 | |
|   if (!((tmp_state == HAL_SPI_STATE_READY) || \
 | |
|         ((tmp_mode == SPI_MODE_MASTER) && (hspi->Init.Direction == SPI_DIRECTION_2LINES) && (tmp_state == HAL_SPI_STATE_BUSY_RX))))
 | |
|   {
 | |
|     errorcode = HAL_BUSY;
 | |
|     goto error;
 | |
|   }
 | |
| 
 | |
|   if ((pTxData == NULL) || (pRxData == NULL) || (Size == 0U))
 | |
|   {
 | |
|     errorcode = HAL_ERROR;
 | |
|     goto error;
 | |
|   }
 | |
| 
 | |
|   /* Don't overwrite in case of HAL_SPI_STATE_BUSY_RX */
 | |
|   if (hspi->State != HAL_SPI_STATE_BUSY_RX)
 | |
|   {
 | |
|     hspi->State = HAL_SPI_STATE_BUSY_TX_RX;
 | |
|   }
 | |
| 
 | |
|   /* Disable SPI peripheral */
 | |
|   __HAL_SPI_DISABLE(hspi);
 | |
| 
 | |
|   /* 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;
 | |
| 
 | |
|   /* Set the Rx Fifo threshold */
 | |
|   if (hspi->Init.DataSize > SPI_DATASIZE_8BIT)
 | |
|   {
 | |
|     /* Set fiforxthreshold according the reception data length: 16bit */
 | |
|     CLEAR_BIT(hspi->Instance->CR2, SPI_RXFIFO_THRESHOLD);
 | |
|   }
 | |
|   else
 | |
|   {
 | |
|     /* Set fiforxthreshold according the reception data length: 8bit */
 | |
|     SET_BIT(hspi->Instance->CR2, SPI_RXFIFO_THRESHOLD);
 | |
|   }
 | |
| 
 | |
|   /* Check if the SPI is already enabled */
 | |
|   if ((hspi->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE)
 | |
|   {
 | |
|     /* Enable SPI peripheral */
 | |
|     __HAL_SPI_ENABLE(hspi);
 | |
|   }
 | |
| 
 | |
|   /* Transmit and Receive data in 16 Bit mode */
 | |
|   if (hspi->Init.DataSize > SPI_DATASIZE_8BIT)
 | |
|   {
 | |
|     if ((hspi->Init.Mode == SPI_MODE_SLAVE) || (initial_TxXferCount == 0x01U))
 | |
|     {
 | |
|       hspi->Instance->DR = *((uint16_t *)hspi->pTxBuffPtr);
 | |
|       hspi->pTxBuffPtr += sizeof(uint16_t);
 | |
|       hspi->TxXferCount--;
 | |
|     }
 | |
|     while ((hspi->TxXferCount > 0U) || (hspi->RxXferCount > 0U))
 | |
|     {
 | |
|       /* Check TXE flag */
 | |
|       if ((__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXE)) && (hspi->TxXferCount > 0U) && (txallowed == 1U))
 | |
|       {
 | |
|         hspi->Instance->DR = *((uint16_t *)hspi->pTxBuffPtr);
 | |
|         hspi->pTxBuffPtr += sizeof(uint16_t);
 | |
|         hspi->TxXferCount--;
 | |
|         /* Next Data is a reception (Rx). Tx not allowed */
 | |
|         txallowed = 0U;
 | |
|       }
 | |
| 
 | |
|       /* Check RXNE flag */
 | |
|       if ((__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_RXNE)) && (hspi->RxXferCount > 0U))
 | |
|       {
 | |
|         *((uint16_t *)hspi->pRxBuffPtr) = (uint16_t)hspi->Instance->DR;
 | |
|         hspi->pRxBuffPtr += sizeof(uint16_t);
 | |
|         hspi->RxXferCount--;
 | |
|         /* Next Data is a Transmission (Tx). Tx is allowed */
 | |
|         txallowed = 1U;
 | |
|       }
 | |
|       if (((HAL_GetTick() - tickstart) >=  Timeout) && (Timeout != HAL_MAX_DELAY))
 | |
|       {
 | |
|         errorcode = HAL_TIMEOUT;
 | |
|         goto error;
 | |
|       }
 | |
|     }
 | |
|   }
 | |
|   /* Transmit and Receive data in 8 Bit mode */
 | |
|   else
 | |
|   {
 | |
|     if ((hspi->Init.Mode == SPI_MODE_SLAVE) || (initial_TxXferCount == 0x01U))
 | |
|     {
 | |
|       *((__IO uint8_t *)&hspi->Instance->DR) = (*hspi->pTxBuffPtr);
 | |
|       hspi->pTxBuffPtr += sizeof(uint8_t);
 | |
|       hspi->TxXferCount--;
 | |
|     }
 | |
|     while ((hspi->TxXferCount > 0U) || (hspi->RxXferCount > 0U))
 | |
|     {
 | |
|       /* Check TXE flag */
 | |
|       if ((__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_TXE)) && (hspi->TxXferCount > 0U) && (txallowed == 1U))
 | |
|       {
 | |
|         *(__IO uint8_t *)&hspi->Instance->DR = (*hspi->pTxBuffPtr);
 | |
|         hspi->pTxBuffPtr++;
 | |
|         hspi->TxXferCount--;
 | |
|         /* Next Data is a reception (Rx). Tx not allowed */
 | |
|         txallowed = 0U;
 | |
|       }
 | |
| 
 | |
|       /* Wait until RXNE flag is reset */
 | |
|       if ((__HAL_SPI_GET_FLAG(hspi, SPI_FLAG_RXNE)) && (hspi->RxXferCount > 0U))
 | |
|       {
 | |
|         (*(uint8_t *)hspi->pRxBuffPtr) = *(__IO uint8_t *)&hspi->Instance->DR;
 | |
|         hspi->pRxBuffPtr++;
 | |
|         hspi->RxXferCount--;
 | |
|         /* Next Data is a Transmission (Tx). Tx is allowed */
 | |
|         txallowed = 1U;
 | |
|       }
 | |
|       if ((((HAL_GetTick() - tickstart) >=  Timeout) && ((Timeout != HAL_MAX_DELAY))) || (Timeout == 0U))
 | |
|       {
 | |
|         errorcode = HAL_TIMEOUT;
 | |
|         goto error;
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   /* Check the end of the transaction */
 | |
|   if (SPI_EndRxTxTransaction(hspi, Timeout, tickstart) != HAL_OK)
 | |
|   {
 | |
|     errorcode = HAL_ERROR;
 | |
|     hspi->ErrorCode = HAL_SPI_ERROR_FLAG;
 | |
|   }
 | |
| 
 | |
| error :
 | |
|   hspi->State = HAL_SPI_STATE_READY;
 | |
|   __HAL_UNLOCK(hspi);
 | |
|   return errorcode;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   * @brief  Transmit an amount of data in non-blocking mode with Interrupt.
 | |
|   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
 | |
|   *               the configuration information for SPI module.
 | |
|   * @param  pData pointer to data buffer
 | |
|   * @param  Size amount of data to be sent
 | |
|   * @retval HAL status
 | |
|   */
 | |
| HAL_StatusTypeDef HAL_SPI_Transmit_IT(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size)
 | |
| {
 | |
|   HAL_StatusTypeDef errorcode = HAL_OK;
 | |
| 
 | |
|   /* Check Direction parameter */
 | |
|   assert_param(IS_SPI_DIRECTION_2LINES_OR_1LINE(hspi->Init.Direction));
 | |
| 
 | |
|   /* Process Locked */
 | |
|   __HAL_LOCK(hspi);
 | |
| 
 | |
|   if ((pData == NULL) || (Size == 0U))
 | |
|   {
 | |
|     errorcode = HAL_ERROR;
 | |
|     goto error;
 | |
|   }
 | |
| 
 | |
|   if (hspi->State != HAL_SPI_STATE_READY)
 | |
|   {
 | |
|     errorcode = HAL_BUSY;
 | |
|     goto error;
 | |
|   }
 | |
| 
 | |
|   /* Disable SPI peripheral */
 | |
|   __HAL_SPI_DISABLE(hspi);
 | |
| 
 | |
|   /* 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->RxISR       = NULL;
 | |
| 
 | |
|   /* Set the function for IT treatment */
 | |
|   if (hspi->Init.DataSize > SPI_DATASIZE_8BIT)
 | |
|   {
 | |
|     hspi->TxISR = SPI_TxISR_16BIT;
 | |
|   }
 | |
|   else
 | |
|   {
 | |
|     hspi->TxISR = SPI_TxISR_8BIT;
 | |
|   }
 | |
| 
 | |
|   /* Configure communication direction : 1Line */
 | |
|   if (hspi->Init.Direction == SPI_DIRECTION_1LINE)
 | |
|   {
 | |
|     SPI_1LINE_TX(hspi);
 | |
|   }
 | |
| 
 | |
|   /* Enable TXE and ERR interrupt */
 | |
|   __HAL_SPI_ENABLE_IT(hspi, (SPI_IT_TXE | SPI_IT_ERR));
 | |
| 
 | |
| 
 | |
|   /* Check if the SPI is already enabled */
 | |
|   if ((hspi->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE)
 | |
|   {
 | |
|     /* Enable SPI peripheral */
 | |
|     __HAL_SPI_ENABLE(hspi);
 | |
|   }
 | |
| 
 | |
| error :
 | |
|   __HAL_UNLOCK(hspi);
 | |
|   return errorcode;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   * @brief  Receive an amount of data in non-blocking mode with Interrupt.
 | |
|   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
 | |
|   *               the configuration information for SPI module.
 | |
|   * @param  pData pointer to data buffer
 | |
|   * @param  Size amount of data to be sent
 | |
|   * @retval HAL status
 | |
|   */
 | |
| HAL_StatusTypeDef HAL_SPI_Receive_IT(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size)
 | |
| {
 | |
|   HAL_StatusTypeDef errorcode = HAL_OK;
 | |
| 
 | |
|   if ((hspi->Init.Direction == SPI_DIRECTION_2LINES) && (hspi->Init.Mode == SPI_MODE_MASTER))
 | |
|   {
 | |
|     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_IT(hspi, pData, pData, Size);
 | |
|   }
 | |
| 
 | |
|   /* Process Locked */
 | |
|   __HAL_LOCK(hspi);
 | |
| 
 | |
|   if (hspi->State != HAL_SPI_STATE_READY)
 | |
|   {
 | |
|     errorcode = HAL_BUSY;
 | |
|     goto error;
 | |
|   }
 | |
| 
 | |
|   if ((pData == NULL) || (Size == 0U))
 | |
|   {
 | |
|     errorcode = HAL_ERROR;
 | |
|     goto error;
 | |
|   }
 | |
| 
 | |
|   /* Disable SPI peripheral */
 | |
|   __HAL_SPI_DISABLE(hspi);
 | |
| 
 | |
|   /* 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->TxISR       = NULL;
 | |
| 
 | |
|   /* Check the data size to adapt Rx threshold and the set the function for IT treatment */
 | |
|   if (hspi->Init.DataSize > SPI_DATASIZE_8BIT)
 | |
|   {
 | |
|     /* Set RX Fifo threshold according the reception data length: 16 bit */
 | |
|     CLEAR_BIT(hspi->Instance->CR2, SPI_RXFIFO_THRESHOLD);
 | |
|     hspi->RxISR = SPI_RxISR_16BIT;
 | |
|   }
 | |
|   else
 | |
|   {
 | |
|     /* Set RX Fifo threshold according the reception data length: 8 bit */
 | |
|     SET_BIT(hspi->Instance->CR2, SPI_RXFIFO_THRESHOLD);
 | |
|     hspi->RxISR = SPI_RxISR_8BIT;
 | |
|   }
 | |
| 
 | |
|   /* Configure communication direction : 1Line */
 | |
|   if (hspi->Init.Direction == SPI_DIRECTION_1LINE)
 | |
|   {
 | |
|     SPI_1LINE_RX(hspi);
 | |
|   }
 | |
| 
 | |
|   /* Enable TXE and ERR interrupt */
 | |
|   __HAL_SPI_ENABLE_IT(hspi, (SPI_IT_RXNE | SPI_IT_ERR));
 | |
| 
 | |
|   /* Note : The SPI must be enabled after unlocking current process
 | |
|             to avoid the risk of SPI interrupt handle execution before current
 | |
|             process unlock */
 | |
| 
 | |
|   /* Check if the SPI is already enabled */
 | |
|   if ((hspi->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE)
 | |
|   {
 | |
|     /* Enable SPI peripheral */
 | |
|     __HAL_SPI_ENABLE(hspi);
 | |
|   }
 | |
| 
 | |
| error :
 | |
|   /* Process Unlocked */
 | |
|   __HAL_UNLOCK(hspi);
 | |
|   return errorcode;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   * @brief  Transmit and Receive an amount of data in non-blocking mode with Interrupt.
 | |
|   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
 | |
|   *               the configuration information for SPI module.
 | |
|   * @param  pTxData pointer to transmission data buffer
 | |
|   * @param  pRxData pointer to reception data buffer
 | |
|   * @param  Size amount of data to be sent and received
 | |
|   * @retval HAL status
 | |
|   */
 | |
| HAL_StatusTypeDef HAL_SPI_TransmitReceive_IT(SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size)
 | |
| {
 | |
|   uint32_t             tmp_mode;
 | |
|   HAL_SPI_StateTypeDef tmp_state;
 | |
|   HAL_StatusTypeDef    errorcode = HAL_OK;
 | |
| 
 | |
|   /* Check Direction parameter */
 | |
|   assert_param(IS_SPI_DIRECTION_2LINES(hspi->Init.Direction));
 | |
| 
 | |
|   /* Process locked */
 | |
|   __HAL_LOCK(hspi);
 | |
| 
 | |
|   /* Init temporary variables */
 | |
|   tmp_state           = hspi->State;
 | |
|   tmp_mode            = hspi->Init.Mode;
 | |
| 
 | |
|   if (!((tmp_state == HAL_SPI_STATE_READY) || \
 | |
|         ((tmp_mode == SPI_MODE_MASTER) && (hspi->Init.Direction == SPI_DIRECTION_2LINES) && (tmp_state == HAL_SPI_STATE_BUSY_RX))))
 | |
|   {
 | |
|     errorcode = HAL_BUSY;
 | |
|     goto error;
 | |
|   }
 | |
| 
 | |
|   if ((pTxData == NULL) || (pRxData == NULL) || (Size == 0U))
 | |
|   {
 | |
|     errorcode = HAL_ERROR;
 | |
|     goto error;
 | |
|   }
 | |
| 
 | |
|   /* Don't overwrite in case of HAL_SPI_STATE_BUSY_RX */
 | |
|   if (hspi->State != HAL_SPI_STATE_BUSY_RX)
 | |
|   {
 | |
|     hspi->State = HAL_SPI_STATE_BUSY_TX_RX;
 | |
|   }
 | |
| 
 | |
|   /* Disable SPI peripheral */
 | |
|   __HAL_SPI_DISABLE(hspi);
 | |
| 
 | |
|   /* Set the transaction information */
 | |
|   hspi->ErrorCode   = HAL_SPI_ERROR_NONE;
 | |
|   hspi->pTxBuffPtr  = (uint8_t *)pTxData;
 | |
|   hspi->TxXferSize  = Size;
 | |
|   hspi->TxXferCount = Size;
 | |
|   hspi->pRxBuffPtr  = (uint8_t *)pRxData;
 | |
|   hspi->RxXferSize  = Size;
 | |
|   hspi->RxXferCount = Size;
 | |
| 
 | |
|   /* Set the function for IT treatment */
 | |
|   if (hspi->Init.DataSize > SPI_DATASIZE_8BIT)
 | |
|   {
 | |
|     hspi->RxISR     = SPI_2linesRxISR_16BIT;
 | |
|     hspi->TxISR     = SPI_2linesTxISR_16BIT;
 | |
|   }
 | |
|   else
 | |
|   {
 | |
|     hspi->RxISR     = SPI_2linesRxISR_8BIT;
 | |
|     hspi->TxISR     = SPI_2linesTxISR_8BIT;
 | |
|   }
 | |
| 
 | |
|   /* Check if packing mode is enabled and if there is more than 2 data to receive */
 | |
|   if ((hspi->Init.DataSize > SPI_DATASIZE_8BIT) || (Size >= 2U))
 | |
|   {
 | |
|     /* Set RX Fifo threshold according the reception data length: 16 bit */
 | |
|     CLEAR_BIT(hspi->Instance->CR2, SPI_RXFIFO_THRESHOLD);
 | |
|   }
 | |
|   else
 | |
|   {
 | |
|     /* Set RX Fifo threshold according the reception data length: 8 bit */
 | |
|     SET_BIT(hspi->Instance->CR2, SPI_RXFIFO_THRESHOLD);
 | |
|   }
 | |
| 
 | |
|   /* Enable TXE, RXNE and ERR interrupt */
 | |
|   __HAL_SPI_ENABLE_IT(hspi, (SPI_IT_TXE | SPI_IT_RXNE | SPI_IT_ERR));
 | |
| 
 | |
|   /* Check if the SPI is already enabled */
 | |
|   if ((hspi->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE)
 | |
|   {
 | |
|     /* Enable SPI peripheral */
 | |
|     __HAL_SPI_ENABLE(hspi);
 | |
|   }
 | |
| 
 | |
| error :
 | |
|   /* Process Unlocked */
 | |
|   __HAL_UNLOCK(hspi);
 | |
|   return errorcode;
 | |
| }
 | |
| 
 | |
| #if (defined(DMA1) || defined(DMA))
 | |
| /**
 | |
|   * @brief  Transmit an amount of data in non-blocking mode with DMA.
 | |
|   * @note   Depending on devices and packages, DMA may not be available.
 | |
|   *         Refer to device datasheet for DMA availability.
 | |
|   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
 | |
|   *               the configuration information for SPI module.
 | |
|   * @param  pData pointer to data buffer
 | |
|   * @param  Size amount of data to be sent
 | |
|   * @retval HAL status
 | |
|   */
 | |
| HAL_StatusTypeDef HAL_SPI_Transmit_DMA(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size)
 | |
| {
 | |
|   HAL_StatusTypeDef errorcode = HAL_OK;
 | |
| 
 | |
|   /* Check tx dma handle */
 | |
|   assert_param(IS_SPI_DMA_HANDLE(hspi->hdmatx));
 | |
| 
 | |
|   /* Check Direction parameter */
 | |
|   assert_param(IS_SPI_DIRECTION_2LINES_OR_1LINE(hspi->Init.Direction));
 | |
| 
 | |
|   /* Process Locked */
 | |
|   __HAL_LOCK(hspi);
 | |
| 
 | |
|   if (hspi->State != HAL_SPI_STATE_READY)
 | |
|   {
 | |
|     errorcode = HAL_BUSY;
 | |
|     goto error;
 | |
|   }
 | |
| 
 | |
|   if ((pData == NULL) || (Size == 0U))
 | |
|   {
 | |
|     errorcode = HAL_ERROR;
 | |
|     goto error;
 | |
|   }
 | |
| 
 | |
|   /* Disable SPI peripheral */
 | |
|   __HAL_SPI_DISABLE(hspi);
 | |
| 
 | |
|   /* 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->TxISR       = NULL;
 | |
|   hspi->RxISR       = NULL;
 | |
|   hspi->RxXferSize  = 0U;
 | |
|   hspi->RxXferCount = 0U;
 | |
| 
 | |
|   /* Configure communication direction : 1Line */
 | |
|   if (hspi->Init.Direction == SPI_DIRECTION_1LINE)
 | |
|   {
 | |
|     SPI_1LINE_TX(hspi);
 | |
|   }
 | |
| 
 | |
|   /* Set the SPI TxDMA Half transfer complete callback */
 | |
|   hspi->hdmatx->XferHalfCpltCallback = SPI_DMAHalfTransmitCplt;
 | |
| 
 | |
|   /* Set the SPI TxDMA transfer complete callback */
 | |
|   hspi->hdmatx->XferCpltCallback = SPI_DMATransmitCplt;
 | |
| 
 | |
|   /* Set the DMA error callback */
 | |
|   hspi->hdmatx->XferErrorCallback = SPI_DMAError;
 | |
| 
 | |
|   /* Set the DMA AbortCpltCallback */
 | |
|   hspi->hdmatx->XferAbortCallback = NULL;
 | |
| 
 | |
|   CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_LDMA_TX);
 | |
|   /* Packing mode is enabled only if the DMA setting is HALWORD */
 | |
|   if ((hspi->Init.DataSize <= SPI_DATASIZE_8BIT) && (hspi->hdmatx->Init.MemDataAlignment == DMA_MDATAALIGN_HALFWORD))
 | |
|   {
 | |
|     /* Check the even/odd of the data size if enabled */
 | |
|     if ((hspi->TxXferCount & 0x1U) == 0U)
 | |
|     {
 | |
|       CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_LDMA_TX);
 | |
|       hspi->TxXferCount = (hspi->TxXferCount >> 1U);
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|       SET_BIT(hspi->Instance->CR2, SPI_CR2_LDMA_TX);
 | |
|       hspi->TxXferCount = (hspi->TxXferCount >> 1U) + 1U;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   /* Enable the Tx DMA Stream/Channel */
 | |
|   if (HAL_OK != HAL_DMA_Start_IT(hspi->hdmatx, (uint32_t)hspi->pTxBuffPtr, (uint32_t)&hspi->Instance->DR,
 | |
|                                  hspi->TxXferCount))
 | |
|   {
 | |
|     /* Update SPI error code */
 | |
|     SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_DMA);
 | |
|     errorcode = HAL_ERROR;
 | |
| 
 | |
|     hspi->State = HAL_SPI_STATE_READY;
 | |
|     goto error;
 | |
|   }
 | |
| 
 | |
|   /* Check if the SPI is already enabled */
 | |
|   if ((hspi->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE)
 | |
|   {
 | |
|     /* Enable SPI peripheral */
 | |
|     __HAL_SPI_ENABLE(hspi);
 | |
|   }
 | |
| 
 | |
|   /* Enable the SPI Error Interrupt Bit */
 | |
|   __HAL_SPI_ENABLE_IT(hspi, (SPI_IT_ERR));
 | |
| 
 | |
|   /* Enable Tx DMA Request */
 | |
|   SET_BIT(hspi->Instance->CR2, SPI_CR2_TXDMAEN);
 | |
| 
 | |
| error :
 | |
|   /* Process Unlocked */
 | |
|   __HAL_UNLOCK(hspi);
 | |
|   return errorcode;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   * @brief  Receive an amount of data in non-blocking mode with DMA.
 | |
|   * @note   In case of MASTER mode and SPI_DIRECTION_2LINES direction, hdmatx shall be defined.
 | |
|   * @note   Depending on devices and packages, DMA may not be available.
 | |
|   *         Refer to device datasheet for DMA availability.
 | |
|   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
 | |
|   *               the configuration information for SPI module.
 | |
|   * @param  pData pointer to data buffer
 | |
|   * @param  Size amount of data to be sent
 | |
|   * @retval HAL status
 | |
|   */
 | |
| HAL_StatusTypeDef HAL_SPI_Receive_DMA(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size)
 | |
| {
 | |
|   HAL_StatusTypeDef errorcode = HAL_OK;
 | |
| 
 | |
|   /* Check rx dma handle */
 | |
|   assert_param(IS_SPI_DMA_HANDLE(hspi->hdmarx));
 | |
| 
 | |
|   if ((hspi->Init.Direction == SPI_DIRECTION_2LINES) && (hspi->Init.Mode == SPI_MODE_MASTER))
 | |
|   {
 | |
|     hspi->State = HAL_SPI_STATE_BUSY_RX;
 | |
| 
 | |
|     /* Check tx dma handle */
 | |
|     assert_param(IS_SPI_DMA_HANDLE(hspi->hdmatx));
 | |
| 
 | |
|     /* Call transmit-receive function to send Dummy data on Tx line and generate clock on CLK line */
 | |
|     return HAL_SPI_TransmitReceive_DMA(hspi, pData, pData, Size);
 | |
|   }
 | |
| 
 | |
|   /* Process Locked */
 | |
|   __HAL_LOCK(hspi);
 | |
| 
 | |
|   if (hspi->State != HAL_SPI_STATE_READY)
 | |
|   {
 | |
|     errorcode = HAL_BUSY;
 | |
|     goto error;
 | |
|   }
 | |
| 
 | |
|   if ((pData == NULL) || (Size == 0U))
 | |
|   {
 | |
|     errorcode = HAL_ERROR;
 | |
|     goto error;
 | |
|   }
 | |
| 
 | |
|   /* Disable SPI peripheral */
 | |
|   __HAL_SPI_DISABLE(hspi);
 | |
| 
 | |
|   /* 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->RxISR       = NULL;
 | |
|   hspi->TxISR       = NULL;
 | |
|   hspi->TxXferSize  = 0U;
 | |
|   hspi->TxXferCount = 0U;
 | |
| 
 | |
|   /* Configure communication direction : 1Line */
 | |
|   if (hspi->Init.Direction == SPI_DIRECTION_1LINE)
 | |
|   {
 | |
|     SPI_1LINE_RX(hspi);
 | |
|   }
 | |
| 
 | |
|   CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_LDMA_RX);
 | |
|   if (hspi->Init.DataSize > SPI_DATASIZE_8BIT)
 | |
|   {
 | |
|     /* Set RX Fifo threshold according the reception data length: 16bit */
 | |
|     CLEAR_BIT(hspi->Instance->CR2, SPI_RXFIFO_THRESHOLD);
 | |
|   }
 | |
|   else
 | |
|   {
 | |
|     /* Set RX Fifo threshold according the reception data length: 8bit */
 | |
|     SET_BIT(hspi->Instance->CR2, SPI_RXFIFO_THRESHOLD);
 | |
| 
 | |
|     if (hspi->hdmarx->Init.MemDataAlignment == DMA_MDATAALIGN_HALFWORD)
 | |
|     {
 | |
|       /* Set RX Fifo threshold according the reception data length: 16bit */
 | |
|       CLEAR_BIT(hspi->Instance->CR2, SPI_RXFIFO_THRESHOLD);
 | |
| 
 | |
|       if ((hspi->RxXferCount & 0x1U) == 0x0U)
 | |
|       {
 | |
|         CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_LDMA_RX);
 | |
|         hspi->RxXferCount = hspi->RxXferCount >> 1U;
 | |
|       }
 | |
|       else
 | |
|       {
 | |
|         SET_BIT(hspi->Instance->CR2, SPI_CR2_LDMA_RX);
 | |
|         hspi->RxXferCount = (hspi->RxXferCount >> 1U) + 1U;
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   /* Set the SPI RxDMA Half transfer complete callback */
 | |
|   hspi->hdmarx->XferHalfCpltCallback = SPI_DMAHalfReceiveCplt;
 | |
| 
 | |
|   /* Set the SPI Rx DMA transfer complete callback */
 | |
|   hspi->hdmarx->XferCpltCallback = SPI_DMAReceiveCplt;
 | |
| 
 | |
|   /* Set the DMA error callback */
 | |
|   hspi->hdmarx->XferErrorCallback = SPI_DMAError;
 | |
| 
 | |
|   /* Set the DMA AbortCpltCallback */
 | |
|   hspi->hdmarx->XferAbortCallback = NULL;
 | |
| 
 | |
|   /* Enable the Rx DMA Stream/Channel  */
 | |
|   if (HAL_OK != HAL_DMA_Start_IT(hspi->hdmarx, (uint32_t)&hspi->Instance->DR, (uint32_t)hspi->pRxBuffPtr,
 | |
|                                  hspi->RxXferCount))
 | |
|   {
 | |
|     /* Update SPI error code */
 | |
|     SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_DMA);
 | |
|     errorcode = HAL_ERROR;
 | |
| 
 | |
|     hspi->State = HAL_SPI_STATE_READY;
 | |
|     goto error;
 | |
|   }
 | |
| 
 | |
|   /* Check if the SPI is already enabled */
 | |
|   if ((hspi->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE)
 | |
|   {
 | |
|     /* Enable SPI peripheral */
 | |
|     __HAL_SPI_ENABLE(hspi);
 | |
|   }
 | |
| 
 | |
|   /* Enable the SPI Error Interrupt Bit */
 | |
|   __HAL_SPI_ENABLE_IT(hspi, (SPI_IT_ERR));
 | |
| 
 | |
|   /* Enable Rx DMA Request */
 | |
|   SET_BIT(hspi->Instance->CR2, SPI_CR2_RXDMAEN);
 | |
| 
 | |
| error:
 | |
|   /* Process Unlocked */
 | |
|   __HAL_UNLOCK(hspi);
 | |
|   return errorcode;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   * @brief  Transmit and Receive an amount of data in non-blocking mode with DMA.
 | |
|   * @note   Depending on devices and packages, DMA may not be available.
 | |
|   *         Refer to device datasheet for DMA availability.
 | |
|   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
 | |
|   *               the configuration information for SPI module.
 | |
|   * @param  pTxData pointer to transmission data buffer
 | |
|   * @param  pRxData pointer to reception data buffer
 | |
|   * @param  Size amount of data to be sent
 | |
|   * @retval HAL status
 | |
|   */
 | |
| HAL_StatusTypeDef HAL_SPI_TransmitReceive_DMA(SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData,
 | |
|     uint16_t Size)
 | |
| {
 | |
|   uint32_t             tmp_mode;
 | |
|   HAL_SPI_StateTypeDef tmp_state;
 | |
|   HAL_StatusTypeDef errorcode = HAL_OK;
 | |
| 
 | |
|   /* Check rx & tx dma handles */
 | |
|   assert_param(IS_SPI_DMA_HANDLE(hspi->hdmarx));
 | |
|   assert_param(IS_SPI_DMA_HANDLE(hspi->hdmatx));
 | |
| 
 | |
|   /* Check Direction parameter */
 | |
|   assert_param(IS_SPI_DIRECTION_2LINES(hspi->Init.Direction));
 | |
| 
 | |
|   /* Process locked */
 | |
|   __HAL_LOCK(hspi);
 | |
| 
 | |
|   /* Init temporary variables */
 | |
|   tmp_state           = hspi->State;
 | |
|   tmp_mode            = hspi->Init.Mode;
 | |
| 
 | |
|   if (!((tmp_state == HAL_SPI_STATE_READY) ||
 | |
|         ((tmp_mode == SPI_MODE_MASTER) && (hspi->Init.Direction == SPI_DIRECTION_2LINES) && (tmp_state == HAL_SPI_STATE_BUSY_RX))))
 | |
|   {
 | |
|     errorcode = HAL_BUSY;
 | |
|     goto error;
 | |
|   }
 | |
| 
 | |
|   if ((pTxData == NULL) || (pRxData == NULL) || (Size == 0U))
 | |
|   {
 | |
|     errorcode = HAL_ERROR;
 | |
|     goto error;
 | |
|   }
 | |
| 
 | |
|   /* Don't overwrite in case of HAL_SPI_STATE_BUSY_RX */
 | |
|   if (hspi->State != HAL_SPI_STATE_BUSY_RX)
 | |
|   {
 | |
|     hspi->State = HAL_SPI_STATE_BUSY_TX_RX;
 | |
|   }
 | |
| 
 | |
|   /* Disable SPI peripheral */
 | |
|   __HAL_SPI_DISABLE(hspi);
 | |
| 
 | |
|   /* Set the transaction information */
 | |
|   hspi->ErrorCode   = HAL_SPI_ERROR_NONE;
 | |
|   hspi->pTxBuffPtr  = (uint8_t *)pTxData;
 | |
|   hspi->TxXferSize  = Size;
 | |
|   hspi->TxXferCount = Size;
 | |
|   hspi->pRxBuffPtr  = (uint8_t *)pRxData;
 | |
|   hspi->RxXferSize  = Size;
 | |
|   hspi->RxXferCount = Size;
 | |
| 
 | |
|   /* Init field not used in handle to zero */
 | |
|   hspi->RxISR       = NULL;
 | |
|   hspi->TxISR       = NULL;
 | |
| 
 | |
|   /* Reset the threshold bit */
 | |
|   CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_LDMA_TX | SPI_CR2_LDMA_RX);
 | |
| 
 | |
|   /* The packing mode management is enabled by the DMA settings according the spi data size */
 | |
|   if (hspi->Init.DataSize > SPI_DATASIZE_8BIT)
 | |
|   {
 | |
|     /* Set fiforxthreshold according the reception data length: 16bit */
 | |
|     CLEAR_BIT(hspi->Instance->CR2, SPI_RXFIFO_THRESHOLD);
 | |
|   }
 | |
|   else
 | |
|   {
 | |
|     /* Set RX Fifo threshold according the reception data length: 8bit */
 | |
|     SET_BIT(hspi->Instance->CR2, SPI_RXFIFO_THRESHOLD);
 | |
| 
 | |
|     if (hspi->hdmatx->Init.MemDataAlignment == DMA_MDATAALIGN_HALFWORD)
 | |
|     {
 | |
|       if ((hspi->TxXferSize & 0x1U) == 0x0U)
 | |
|       {
 | |
|         CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_LDMA_TX);
 | |
|         hspi->TxXferCount = hspi->TxXferCount >> 1U;
 | |
|       }
 | |
|       else
 | |
|       {
 | |
|         SET_BIT(hspi->Instance->CR2, SPI_CR2_LDMA_TX);
 | |
|         hspi->TxXferCount = (hspi->TxXferCount >> 1U) + 1U;
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     if (hspi->hdmarx->Init.MemDataAlignment == DMA_MDATAALIGN_HALFWORD)
 | |
|     {
 | |
|       /* Set RX Fifo threshold according the reception data length: 16bit */
 | |
|       CLEAR_BIT(hspi->Instance->CR2, SPI_RXFIFO_THRESHOLD);
 | |
| 
 | |
|       if ((hspi->RxXferCount & 0x1U) == 0x0U)
 | |
|       {
 | |
|         CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_LDMA_RX);
 | |
|         hspi->RxXferCount = hspi->RxXferCount >> 1U;
 | |
|       }
 | |
|       else
 | |
|       {
 | |
|         SET_BIT(hspi->Instance->CR2, SPI_CR2_LDMA_RX);
 | |
|         hspi->RxXferCount = (hspi->RxXferCount >> 1U) + 1U;
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   /* Check if we are in Rx only or in Rx/Tx Mode and configure the DMA transfer complete callback */
 | |
|   if (hspi->State == HAL_SPI_STATE_BUSY_RX)
 | |
|   {
 | |
|     /* Set the SPI Rx DMA Half transfer complete callback */
 | |
|     hspi->hdmarx->XferHalfCpltCallback = SPI_DMAHalfReceiveCplt;
 | |
|     hspi->hdmarx->XferCpltCallback     = SPI_DMAReceiveCplt;
 | |
|   }
 | |
|   else
 | |
|   {
 | |
|     /* Set the SPI Tx/Rx DMA Half transfer complete callback */
 | |
|     hspi->hdmarx->XferHalfCpltCallback = SPI_DMAHalfTransmitReceiveCplt;
 | |
|     hspi->hdmarx->XferCpltCallback     = SPI_DMATransmitReceiveCplt;
 | |
|   }
 | |
| 
 | |
|   /* Set the DMA error callback */
 | |
|   hspi->hdmarx->XferErrorCallback = SPI_DMAError;
 | |
| 
 | |
|   /* Set the DMA AbortCpltCallback */
 | |
|   hspi->hdmarx->XferAbortCallback = NULL;
 | |
| 
 | |
|   /* Enable the Rx DMA Stream/Channel  */
 | |
|   if (HAL_OK != HAL_DMA_Start_IT(hspi->hdmarx, (uint32_t)&hspi->Instance->DR, (uint32_t)hspi->pRxBuffPtr,
 | |
|                                  hspi->RxXferCount))
 | |
|   {
 | |
|     /* Update SPI error code */
 | |
|     SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_DMA);
 | |
|     errorcode = HAL_ERROR;
 | |
| 
 | |
|     hspi->State = HAL_SPI_STATE_READY;
 | |
|     goto error;
 | |
|   }
 | |
| 
 | |
|   /* Enable Rx DMA Request */
 | |
|   SET_BIT(hspi->Instance->CR2, SPI_CR2_RXDMAEN);
 | |
| 
 | |
|   /* Set the SPI Tx DMA transfer complete callback as NULL because the communication closing
 | |
|   is performed in DMA reception complete callback  */
 | |
|   hspi->hdmatx->XferHalfCpltCallback = NULL;
 | |
|   hspi->hdmatx->XferCpltCallback     = NULL;
 | |
|   hspi->hdmatx->XferErrorCallback    = NULL;
 | |
|   hspi->hdmatx->XferAbortCallback    = NULL;
 | |
| 
 | |
|   /* Enable the Tx DMA Stream/Channel  */
 | |
|   if (HAL_OK != HAL_DMA_Start_IT(hspi->hdmatx, (uint32_t)hspi->pTxBuffPtr, (uint32_t)&hspi->Instance->DR,
 | |
|                                  hspi->TxXferCount))
 | |
|   {
 | |
|     /* Update SPI error code */
 | |
|     SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_DMA);
 | |
|     errorcode = HAL_ERROR;
 | |
| 
 | |
|     hspi->State = HAL_SPI_STATE_READY;
 | |
|     goto error;
 | |
|   }
 | |
| 
 | |
|   /* Check if the SPI is already enabled */
 | |
|   if ((hspi->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE)
 | |
|   {
 | |
|     /* Enable SPI peripheral */
 | |
|     __HAL_SPI_ENABLE(hspi);
 | |
|   }
 | |
|   /* Enable the SPI Error Interrupt Bit */
 | |
|   __HAL_SPI_ENABLE_IT(hspi, (SPI_IT_ERR));
 | |
| 
 | |
|   /* Enable Tx DMA Request */
 | |
|   SET_BIT(hspi->Instance->CR2, SPI_CR2_TXDMAEN);
 | |
| 
 | |
| error :
 | |
|   /* Process Unlocked */
 | |
|   __HAL_UNLOCK(hspi);
 | |
|   return errorcode;
 | |
| }
 | |
| #endif /* DMA1 or DMA */
 | |
| 
 | |
| /**
 | |
|   * @brief  Abort ongoing transfer (blocking mode).
 | |
|   * @param  hspi SPI handle.
 | |
|   * @note   This procedure could be used for aborting any ongoing transfer (Tx and Rx),
 | |
|   *         started in Interrupt or DMA mode.
 | |
|   *         This procedure performs following operations :
 | |
|   *           - Disable SPI Interrupts (depending of transfer direction)
 | |
|   *           - Disable the DMA transfer in the peripheral register (if enabled)
 | |
|   *           - Abort DMA transfer by calling HAL_DMA_Abort (in case of transfer in DMA mode)
 | |
|   *           - Set handle State to READY
 | |
|   * @note   This procedure is executed in blocking mode : when exiting function, Abort is considered as completed.
 | |
|   * @note   Depending on devices and packages, DMA may not be available.
 | |
|   *         Refer to device datasheet for DMA availability.
 | |
|   * @retval HAL status
 | |
|   */
 | |
| HAL_StatusTypeDef HAL_SPI_Abort(SPI_HandleTypeDef *hspi)
 | |
| {
 | |
|   HAL_StatusTypeDef errorcode;
 | |
|   __IO uint32_t count;
 | |
|   __IO uint32_t resetcount;
 | |
| 
 | |
|   /* Initialized local variable  */
 | |
|   errorcode = HAL_OK;
 | |
|   resetcount = SPI_DEFAULT_TIMEOUT * (SystemCoreClock / 24U / 1000U);
 | |
|   count = resetcount;
 | |
| 
 | |
|   /* Clear ERRIE interrupt to avoid error interrupts generation during Abort procedure */
 | |
|   CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_ERRIE);
 | |
| 
 | |
|   /* Disable TXEIE, RXNEIE and ERRIE(mode fault event, overrun error) interrupts */
 | |
|   if (HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_TXEIE))
 | |
|   {
 | |
|     hspi->TxISR = SPI_AbortTx_ISR;
 | |
|     /* Wait HAL_SPI_STATE_ABORT state */
 | |
|     do
 | |
|     {
 | |
|       if (count == 0U)
 | |
|       {
 | |
|         SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_ABORT);
 | |
|         break;
 | |
|       }
 | |
|       count--;
 | |
|     } while (hspi->State != HAL_SPI_STATE_ABORT);
 | |
|     /* Reset Timeout Counter */
 | |
|     count = resetcount;
 | |
|   }
 | |
| 
 | |
|   if (HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_RXNEIE))
 | |
|   {
 | |
|     hspi->RxISR = SPI_AbortRx_ISR;
 | |
|     /* Wait HAL_SPI_STATE_ABORT state */
 | |
|     do
 | |
|     {
 | |
|       if (count == 0U)
 | |
|       {
 | |
|         SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_ABORT);
 | |
|         break;
 | |
|       }
 | |
|       count--;
 | |
|     } while (hspi->State != HAL_SPI_STATE_ABORT);
 | |
|     /* Reset Timeout Counter */
 | |
|     count = resetcount;
 | |
|   }
 | |
| 
 | |
| #if (defined(DMA1) || defined(DMA))
 | |
|   /* Disable the SPI DMA Tx request if enabled */
 | |
|   if (HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_TXDMAEN))
 | |
|   {
 | |
|     /* Abort the SPI DMA Tx Stream/Channel : use blocking DMA Abort API (no callback) */
 | |
|     if (hspi->hdmatx != NULL)
 | |
|     {
 | |
|       /* Set the SPI DMA Abort callback :
 | |
|       will lead to call HAL_SPI_AbortCpltCallback() at end of DMA abort procedure */
 | |
|       hspi->hdmatx->XferAbortCallback = NULL;
 | |
| 
 | |
|       /* Abort DMA Tx Handle linked to SPI Peripheral */
 | |
|       if (HAL_DMA_Abort(hspi->hdmatx) != HAL_OK)
 | |
|       {
 | |
|         hspi->ErrorCode = HAL_SPI_ERROR_ABORT;
 | |
|       }
 | |
| 
 | |
|       /* Disable Tx DMA Request */
 | |
|       CLEAR_BIT(hspi->Instance->CR2, (SPI_CR2_TXDMAEN));
 | |
| 
 | |
|       if (SPI_EndRxTxTransaction(hspi, SPI_DEFAULT_TIMEOUT, HAL_GetTick()) != HAL_OK)
 | |
|       {
 | |
|         hspi->ErrorCode = HAL_SPI_ERROR_ABORT;
 | |
|       }
 | |
| 
 | |
|       /* Disable SPI Peripheral */
 | |
|       __HAL_SPI_DISABLE(hspi);
 | |
| 
 | |
|       /* Empty the FRLVL fifo */
 | |
|       if (SPI_WaitFifoStateUntilTimeout(hspi, SPI_FLAG_FRLVL, SPI_FRLVL_EMPTY, SPI_DEFAULT_TIMEOUT, HAL_GetTick()) != HAL_OK)
 | |
|       {
 | |
|         hspi->ErrorCode = HAL_SPI_ERROR_ABORT;
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   /* Disable the SPI DMA Rx request if enabled */
 | |
|   if (HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_RXDMAEN))
 | |
|   {
 | |
|     /* Abort the SPI DMA Rx Stream/Channel : use blocking DMA Abort API (no callback) */
 | |
|     if (hspi->hdmarx != NULL)
 | |
|     {
 | |
|       /* Set the SPI DMA Abort callback :
 | |
|       will lead to call HAL_SPI_AbortCpltCallback() at end of DMA abort procedure */
 | |
|       hspi->hdmarx->XferAbortCallback = NULL;
 | |
| 
 | |
|       /* Abort DMA Rx Handle linked to SPI Peripheral */
 | |
|       if (HAL_DMA_Abort(hspi->hdmarx) != HAL_OK)
 | |
|       {
 | |
|         hspi->ErrorCode = HAL_SPI_ERROR_ABORT;
 | |
|       }
 | |
| 
 | |
|       /* Disable peripheral */
 | |
|       __HAL_SPI_DISABLE(hspi);
 | |
| 
 | |
|       /* Control the BSY flag */
 | |
|       if (SPI_WaitFlagStateUntilTimeout(hspi, SPI_FLAG_BSY, RESET, SPI_DEFAULT_TIMEOUT, HAL_GetTick()) != HAL_OK)
 | |
|       {
 | |
|         hspi->ErrorCode = HAL_SPI_ERROR_ABORT;
 | |
|       }
 | |
| 
 | |
|       /* Empty the FRLVL fifo */
 | |
|       if (SPI_WaitFifoStateUntilTimeout(hspi, SPI_FLAG_FRLVL, SPI_FRLVL_EMPTY, SPI_DEFAULT_TIMEOUT, HAL_GetTick()) != HAL_OK)
 | |
|       {
 | |
|         hspi->ErrorCode = HAL_SPI_ERROR_ABORT;
 | |
|       }
 | |
| 
 | |
|       /* Disable Rx DMA Request */
 | |
|       CLEAR_BIT(hspi->Instance->CR2, (SPI_CR2_RXDMAEN));
 | |
|     }
 | |
|   }
 | |
| #endif /* DMA1 or DMA */
 | |
|   
 | |
|   /* Reset Tx and Rx transfer counters */
 | |
|   hspi->RxXferCount = 0U;
 | |
|   hspi->TxXferCount = 0U;
 | |
| 
 | |
|   /* Check error during Abort procedure */
 | |
|   if (hspi->ErrorCode == HAL_SPI_ERROR_ABORT)
 | |
|   {
 | |
|     /* return HAL_Error in case of error during Abort procedure */
 | |
|     errorcode = HAL_ERROR;
 | |
|   }
 | |
|   else
 | |
|   {
 | |
|     /* Reset errorCode */
 | |
|     hspi->ErrorCode = HAL_SPI_ERROR_NONE;
 | |
|   }
 | |
| 
 | |
|   /* Clear the Error flags in the SR register */
 | |
|   __HAL_SPI_CLEAR_OVRFLAG(hspi);
 | |
|   __HAL_SPI_CLEAR_FREFLAG(hspi);
 | |
| 
 | |
|   /* Restore hspi->state to ready */
 | |
|   hspi->State = HAL_SPI_STATE_READY;
 | |
| 
 | |
|   return errorcode;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   * @brief  Abort ongoing transfer (Interrupt mode).
 | |
|   * @param  hspi SPI handle.
 | |
|   * @note   This procedure could be used for aborting any ongoing transfer (Tx and Rx),
 | |
|   *         started in Interrupt or DMA mode.
 | |
|   *         This procedure performs following operations :
 | |
|   *           - Disable SPI Interrupts (depending of transfer direction)
 | |
|   *           - Disable the DMA transfer in the peripheral register (if enabled)
 | |
|   *           - Abort DMA transfer by calling HAL_DMA_Abort_IT (in case of transfer in DMA mode)
 | |
|   *           - Set handle State to READY
 | |
|   *           - At abort completion, call user abort complete callback
 | |
|   * @note   This procedure is executed in Interrupt mode, meaning that abort procedure could be
 | |
|   *         considered as completed only when user abort complete callback is executed (not when exiting function).
 | |
|   * @note   Depending on devices and packages, DMA may not be available.
 | |
|   *         Refer to device datasheet for DMA availability.
 | |
|   * @retval HAL status
 | |
|   */
 | |
| HAL_StatusTypeDef HAL_SPI_Abort_IT(SPI_HandleTypeDef *hspi)
 | |
| {
 | |
|   HAL_StatusTypeDef errorcode;
 | |
|   uint32_t abortcplt ;
 | |
|   __IO uint32_t count;
 | |
|   __IO uint32_t resetcount;
 | |
| 
 | |
|   /* Initialized local variable  */
 | |
|   errorcode = HAL_OK;
 | |
|   abortcplt = 1U;
 | |
|   resetcount = SPI_DEFAULT_TIMEOUT * (SystemCoreClock / 24U / 1000U);
 | |
|   count = resetcount;
 | |
| 
 | |
|   /* Clear ERRIE interrupt to avoid error interrupts generation during Abort procedure */
 | |
|   CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_ERRIE);
 | |
| 
 | |
|   /* Change Rx and Tx Irq Handler to Disable TXEIE, RXNEIE and ERRIE interrupts */
 | |
|   if (HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_TXEIE))
 | |
|   {
 | |
|     hspi->TxISR = SPI_AbortTx_ISR;
 | |
|     /* Wait HAL_SPI_STATE_ABORT state */
 | |
|     do
 | |
|     {
 | |
|       if (count == 0U)
 | |
|       {
 | |
|         SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_ABORT);
 | |
|         break;
 | |
|       }
 | |
|       count--;
 | |
|     } while (hspi->State != HAL_SPI_STATE_ABORT);
 | |
|     /* Reset Timeout Counter */
 | |
|     count = resetcount;
 | |
|   }
 | |
| 
 | |
|   if (HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_RXNEIE))
 | |
|   {
 | |
|     hspi->RxISR = SPI_AbortRx_ISR;
 | |
|     /* Wait HAL_SPI_STATE_ABORT state */
 | |
|     do
 | |
|     {
 | |
|       if (count == 0U)
 | |
|       {
 | |
|         SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_ABORT);
 | |
|         break;
 | |
|       }
 | |
|       count--;
 | |
|     } while (hspi->State != HAL_SPI_STATE_ABORT);
 | |
|     /* Reset Timeout Counter */
 | |
|     count = resetcount;
 | |
|   }
 | |
| 
 | |
| #if (defined(DMA1) || defined(DMA))
 | |
|   /* If DMA Tx and/or DMA Rx Handles are associated to SPI Handle, DMA Abort complete callbacks should be initialised
 | |
|      before any call to DMA Abort functions */
 | |
|   /* DMA Tx Handle is valid */
 | |
|   if (hspi->hdmatx != NULL)
 | |
|   {
 | |
|     /* Set DMA Abort Complete callback if SPI DMA Tx request if enabled.
 | |
|        Otherwise, set it to NULL */
 | |
|     if (HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_TXDMAEN))
 | |
|     {
 | |
|       hspi->hdmatx->XferAbortCallback = SPI_DMATxAbortCallback;
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|       hspi->hdmatx->XferAbortCallback = NULL;
 | |
|     }
 | |
|   }
 | |
|   /* DMA Rx Handle is valid */
 | |
|   if (hspi->hdmarx != NULL)
 | |
|   {
 | |
|     /* Set DMA Abort Complete callback if SPI DMA Rx request if enabled.
 | |
|        Otherwise, set it to NULL */
 | |
|     if (HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_RXDMAEN))
 | |
|     {
 | |
|       hspi->hdmarx->XferAbortCallback = SPI_DMARxAbortCallback;
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|       hspi->hdmarx->XferAbortCallback = NULL;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   /* Disable the SPI DMA Tx request if enabled */
 | |
|   if (HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_TXDMAEN))
 | |
|   {
 | |
|     /* Abort the SPI DMA Tx Stream/Channel */
 | |
|     if (hspi->hdmatx != NULL)
 | |
|     {
 | |
|       /* Abort DMA Tx Handle linked to SPI Peripheral */
 | |
|       if (HAL_DMA_Abort_IT(hspi->hdmatx) != HAL_OK)
 | |
|       {
 | |
|         hspi->hdmatx->XferAbortCallback = NULL;
 | |
|         hspi->ErrorCode = HAL_SPI_ERROR_ABORT;
 | |
|       }
 | |
|       else
 | |
|       {
 | |
|         abortcplt = 0U;
 | |
|       }
 | |
|     }
 | |
|   }
 | |
|   /* Disable the SPI DMA Rx request if enabled */
 | |
|   if (HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_RXDMAEN))
 | |
|   {
 | |
|     /* Abort the SPI DMA Rx Stream/Channel */
 | |
|     if (hspi->hdmarx != NULL)
 | |
|     {
 | |
|       /* Abort DMA Rx Handle linked to SPI Peripheral */
 | |
|       if (HAL_DMA_Abort_IT(hspi->hdmarx) !=  HAL_OK)
 | |
|       {
 | |
|         hspi->hdmarx->XferAbortCallback = NULL;
 | |
|         hspi->ErrorCode = HAL_SPI_ERROR_ABORT;
 | |
|       }
 | |
|       else
 | |
|       {
 | |
|         abortcplt = 0U;
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| #endif /* DMA1 or DMA */
 | |
| 
 | |
|   if (abortcplt == 1U)
 | |
|   {
 | |
|     /* Reset Tx and Rx transfer counters */
 | |
|     hspi->RxXferCount = 0U;
 | |
|     hspi->TxXferCount = 0U;
 | |
| 
 | |
|     /* Check error during Abort procedure */
 | |
|     if (hspi->ErrorCode == HAL_SPI_ERROR_ABORT)
 | |
|     {
 | |
|       /* return HAL_Error in case of error during Abort procedure */
 | |
|       errorcode = HAL_ERROR;
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|       /* Reset errorCode */
 | |
|       hspi->ErrorCode = HAL_SPI_ERROR_NONE;
 | |
|     }
 | |
| 
 | |
|     /* Clear the Error flags in the SR register */
 | |
|     __HAL_SPI_CLEAR_OVRFLAG(hspi);
 | |
|     __HAL_SPI_CLEAR_FREFLAG(hspi);
 | |
| 
 | |
|     /* Restore hspi->State to Ready */
 | |
|     hspi->State = HAL_SPI_STATE_READY;
 | |
| 
 | |
|     /* As no DMA to be aborted, call directly user Abort complete callback */
 | |
| #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U)
 | |
|     hspi->AbortCpltCallback(hspi);
 | |
| #else
 | |
|     HAL_SPI_AbortCpltCallback(hspi);
 | |
| #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
 | |
|   }
 | |
| 
 | |
|   return errorcode;
 | |
| }
 | |
| 
 | |
| #if (defined(DMA1) || defined(DMA))
 | |
| /**
 | |
|   * @brief  Pause the DMA Transfer.
 | |
|   * @note   Depending on devices and packages, DMA may not be available.
 | |
|   *         Refer to device datasheet for DMA availability.
 | |
|   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
 | |
|   *               the configuration information for the specified SPI module.
 | |
|   * @retval HAL status
 | |
|   */
 | |
| HAL_StatusTypeDef HAL_SPI_DMAPause(SPI_HandleTypeDef *hspi)
 | |
| {
 | |
|   /* Process Locked */
 | |
|   __HAL_LOCK(hspi);
 | |
| 
 | |
|   /* Disable the SPI DMA Tx & Rx requests */
 | |
|   CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN);
 | |
| 
 | |
|   /* Process Unlocked */
 | |
|   __HAL_UNLOCK(hspi);
 | |
| 
 | |
|   return HAL_OK;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   * @brief  Resume the DMA Transfer.
 | |
|   * @note   Depending on devices and packages, DMA may not be available.
 | |
|   *         Refer to device datasheet for DMA availability.
 | |
|   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
 | |
|   *               the configuration information for the specified SPI module.
 | |
|   * @retval HAL status
 | |
|   */
 | |
| HAL_StatusTypeDef HAL_SPI_DMAResume(SPI_HandleTypeDef *hspi)
 | |
| {
 | |
|   /* Process Locked */
 | |
|   __HAL_LOCK(hspi);
 | |
| 
 | |
|   /* Enable the SPI DMA Tx & Rx requests */
 | |
|   SET_BIT(hspi->Instance->CR2, SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN);
 | |
| 
 | |
|   /* Process Unlocked */
 | |
|   __HAL_UNLOCK(hspi);
 | |
| 
 | |
|   return HAL_OK;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   * @brief  Stop the DMA Transfer.
 | |
|   * @note   Depending on devices and packages, DMA may not be available.
 | |
|   *         Refer to device datasheet for DMA availability.
 | |
|   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
 | |
|   *               the configuration information for the specified SPI module.
 | |
|   * @retval HAL status
 | |
|   */
 | |
| HAL_StatusTypeDef HAL_SPI_DMAStop(SPI_HandleTypeDef *hspi)
 | |
| {
 | |
|   HAL_StatusTypeDef errorcode = HAL_OK;
 | |
|   /* The Lock is not implemented on this API to allow the user application
 | |
|      to call the HAL SPI API under callbacks HAL_SPI_TxCpltCallback() or HAL_SPI_RxCpltCallback() or HAL_SPI_TxRxCpltCallback():
 | |
|      when calling HAL_DMA_Abort() API the DMA TX/RX Transfer complete interrupt is generated
 | |
|      and the correspond call back is executed HAL_SPI_TxCpltCallback() or HAL_SPI_RxCpltCallback() or HAL_SPI_TxRxCpltCallback()
 | |
|      */
 | |
| 
 | |
|   /* Abort the SPI DMA tx Stream/Channel  */
 | |
|   if (hspi->hdmatx != NULL)
 | |
|   {
 | |
|     if (HAL_OK != HAL_DMA_Abort(hspi->hdmatx))
 | |
|     {
 | |
|       SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_DMA);
 | |
|       errorcode = HAL_ERROR;
 | |
|     }
 | |
|   }
 | |
|   /* Abort the SPI DMA rx Stream/Channel  */
 | |
|   if (hspi->hdmarx != NULL)
 | |
|   {
 | |
|     if (HAL_OK != HAL_DMA_Abort(hspi->hdmarx))
 | |
|     {
 | |
|       SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_DMA);
 | |
|       errorcode = HAL_ERROR;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   /* Disable the SPI DMA Tx & Rx requests */
 | |
|   CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN);
 | |
|   hspi->State = HAL_SPI_STATE_READY;
 | |
|   return errorcode;
 | |
| }
 | |
| #endif /* DMA1 or DMA */
 | |
| 
 | |
| /**
 | |
|   * @brief  Handle SPI interrupt request.
 | |
|   * @note   Depending on devices and packages, DMA may not be available.
 | |
|   *         Refer to device datasheet for DMA availability.
 | |
|   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
 | |
|   *               the configuration information for the specified SPI module.
 | |
|   * @retval None
 | |
|   */
 | |
| void HAL_SPI_IRQHandler(SPI_HandleTypeDef *hspi)
 | |
| {
 | |
|   uint32_t itsource = hspi->Instance->CR2;
 | |
|   uint32_t itflag   = hspi->Instance->SR;
 | |
| 
 | |
|   /* SPI in mode Receiver ----------------------------------------------------*/
 | |
|   if ((SPI_CHECK_FLAG(itflag, SPI_FLAG_OVR) == RESET) &&
 | |
|       (SPI_CHECK_FLAG(itflag, SPI_FLAG_RXNE) != RESET) && (SPI_CHECK_IT_SOURCE(itsource, SPI_IT_RXNE) != RESET))
 | |
|   {
 | |
|     hspi->RxISR(hspi);
 | |
|     return;
 | |
|   }
 | |
| 
 | |
|   /* SPI in mode Transmitter -------------------------------------------------*/
 | |
|   if ((SPI_CHECK_FLAG(itflag, SPI_FLAG_TXE) != RESET) && (SPI_CHECK_IT_SOURCE(itsource, SPI_IT_TXE) != RESET))
 | |
|   {
 | |
|     hspi->TxISR(hspi);
 | |
|     return;
 | |
|   }
 | |
| 
 | |
|   /* SPI in Error Treatment --------------------------------------------------*/
 | |
|   if (((SPI_CHECK_FLAG(itflag, SPI_FLAG_MODF) != RESET) || (SPI_CHECK_FLAG(itflag, SPI_FLAG_OVR) != RESET))&& (SPI_CHECK_IT_SOURCE(itsource, SPI_IT_ERR) != RESET))
 | |
|   {
 | |
|     /* SPI Overrun error interrupt occurred ----------------------------------*/
 | |
|     if (SPI_CHECK_FLAG(itflag, SPI_FLAG_OVR) != RESET)
 | |
|     {
 | |
|       if (hspi->State != HAL_SPI_STATE_BUSY_TX)
 | |
|       {
 | |
|         SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_OVR);
 | |
|         __HAL_SPI_CLEAR_OVRFLAG(hspi);
 | |
|       }
 | |
|       else
 | |
|       {
 | |
|         __HAL_SPI_CLEAR_OVRFLAG(hspi);
 | |
|         return;
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     /* SPI Mode Fault error interrupt occurred -------------------------------*/
 | |
|     if (SPI_CHECK_FLAG(itflag, SPI_FLAG_MODF) != RESET)
 | |
|     {
 | |
|       SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_MODF);
 | |
|       __HAL_SPI_CLEAR_MODFFLAG(hspi);
 | |
|     }
 | |
| 
 | |
|     if (hspi->ErrorCode != HAL_SPI_ERROR_NONE)
 | |
|     {
 | |
|       /* Disable all interrupts */
 | |
|       __HAL_SPI_DISABLE_IT(hspi, SPI_IT_RXNE | SPI_IT_TXE | SPI_IT_ERR);
 | |
| 
 | |
|       hspi->State = HAL_SPI_STATE_READY;
 | |
| #if (defined(DMA1) || defined(DMA))
 | |
|       /* Disable the SPI DMA requests if enabled */
 | |
|       if ((HAL_IS_BIT_SET(itsource, SPI_CR2_TXDMAEN)) || (HAL_IS_BIT_SET(itsource, SPI_CR2_RXDMAEN)))
 | |
|       {
 | |
|         CLEAR_BIT(hspi->Instance->CR2, (SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN));
 | |
| 
 | |
|         /* Abort the SPI DMA Rx channel */
 | |
|         if (hspi->hdmarx != NULL)
 | |
|         {
 | |
|           /* Set the SPI DMA Abort callback :
 | |
|           will lead to call HAL_SPI_ErrorCallback() at end of DMA abort procedure */
 | |
|           hspi->hdmarx->XferAbortCallback = SPI_DMAAbortOnError;
 | |
|           if (HAL_OK != HAL_DMA_Abort_IT(hspi->hdmarx))
 | |
|           {
 | |
|             SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_ABORT);
 | |
|           }
 | |
|         }
 | |
|         /* Abort the SPI DMA Tx channel */
 | |
|         if (hspi->hdmatx != NULL)
 | |
|         {
 | |
|           /* Set the SPI DMA Abort callback :
 | |
|           will lead to call HAL_SPI_ErrorCallback() at end of DMA abort procedure */
 | |
|           hspi->hdmatx->XferAbortCallback = SPI_DMAAbortOnError;
 | |
|           if (HAL_OK != HAL_DMA_Abort_IT(hspi->hdmatx))
 | |
|           {
 | |
|             SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_ABORT);
 | |
|           }
 | |
|         }
 | |
|       }
 | |
|       else
 | |
|       {
 | |
| #endif /* DMA1 or DMA */
 | |
|         /* Call user error callback */
 | |
| #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U)
 | |
|         hspi->ErrorCallback(hspi);
 | |
| #else
 | |
|         HAL_SPI_ErrorCallback(hspi);
 | |
| #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
 | |
| #if (defined(DMA1) || defined(DMA))
 | |
|       }
 | |
| #endif /* DMA1 or DMA */
 | |
|     }
 | |
|     return;
 | |
|   }
 | |
| }
 | |
| 
 | |
| /**
 | |
|   * @brief  Tx Transfer completed callback.
 | |
|   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
 | |
|   *               the configuration information for SPI module.
 | |
|   * @retval None
 | |
|   */
 | |
| __weak void HAL_SPI_TxCpltCallback(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_TxCpltCallback should be implemented in the user file
 | |
|    */
 | |
| }
 | |
| 
 | |
| /**
 | |
|   * @brief  Rx Transfer completed callback.
 | |
|   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
 | |
|   *               the configuration information for SPI module.
 | |
|   * @retval None
 | |
|   */
 | |
| __weak void HAL_SPI_RxCpltCallback(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_RxCpltCallback should be implemented in the user file
 | |
|    */
 | |
| }
 | |
| 
 | |
| /**
 | |
|   * @brief  Tx and Rx Transfer completed callback.
 | |
|   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
 | |
|   *               the configuration information for SPI module.
 | |
|   * @retval None
 | |
|   */
 | |
| __weak void HAL_SPI_TxRxCpltCallback(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_TxRxCpltCallback should be implemented in the user file
 | |
|    */
 | |
| }
 | |
| 
 | |
| /**
 | |
|   * @brief  Tx Half Transfer completed callback.
 | |
|   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
 | |
|   *               the configuration information for SPI module.
 | |
|   * @retval None
 | |
|   */
 | |
| __weak void HAL_SPI_TxHalfCpltCallback(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_TxHalfCpltCallback should be implemented in the user file
 | |
|    */
 | |
| }
 | |
| 
 | |
| /**
 | |
|   * @brief  Rx Half Transfer completed callback.
 | |
|   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
 | |
|   *               the configuration information for SPI module.
 | |
|   * @retval None
 | |
|   */
 | |
| __weak void HAL_SPI_RxHalfCpltCallback(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_RxHalfCpltCallback() should be implemented in the user file
 | |
|    */
 | |
| }
 | |
| 
 | |
| /**
 | |
|   * @brief  Tx and Rx Half Transfer callback.
 | |
|   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
 | |
|   *               the configuration information for SPI module.
 | |
|   * @retval None
 | |
|   */
 | |
| __weak void HAL_SPI_TxRxHalfCpltCallback(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_TxRxHalfCpltCallback() should be implemented in the user file
 | |
|    */
 | |
| }
 | |
| 
 | |
| /**
 | |
|   * @brief  SPI error callback.
 | |
|   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
 | |
|   *               the configuration information for SPI module.
 | |
|   * @retval None
 | |
|   */
 | |
| __weak void HAL_SPI_ErrorCallback(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_ErrorCallback should be implemented in the user file
 | |
|    */
 | |
|   /* NOTE : The ErrorCode parameter in the hspi handle is updated by the SPI processes
 | |
|             and user can use HAL_SPI_GetError() API to check the latest error occurred
 | |
|    */
 | |
| }
 | |
| 
 | |
| /**
 | |
|   * @brief  SPI Abort Complete callback.
 | |
|   * @param  hspi SPI handle.
 | |
|   * @retval None
 | |
|   */
 | |
| __weak void HAL_SPI_AbortCpltCallback(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_AbortCpltCallback can be implemented in the user file.
 | |
|    */
 | |
| }
 | |
| 
 | |
| /**
 | |
|   * @}
 | |
|   */
 | |
| 
 | |
| /** @defgroup SPI_Exported_Functions_Group3 Peripheral State and Errors functions
 | |
|   * @brief   SPI control functions
 | |
|   *
 | |
| @verbatim
 | |
|  ===============================================================================
 | |
|                       ##### Peripheral State and Errors functions #####
 | |
|  ===============================================================================
 | |
|     [..]
 | |
|     This subsection provides a set of functions allowing to control the SPI.
 | |
|      (+) HAL_SPI_GetState() API can be helpful to check in run-time the state of the SPI peripheral
 | |
|      (+) HAL_SPI_GetError() check in run-time Errors occurring during communication
 | |
| @endverbatim
 | |
|   * @{
 | |
|   */
 | |
| 
 | |
| /**
 | |
|   * @brief  Return the SPI handle state.
 | |
|   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
 | |
|   *               the configuration information for SPI module.
 | |
|   * @retval SPI state
 | |
|   */
 | |
| HAL_SPI_StateTypeDef HAL_SPI_GetState(SPI_HandleTypeDef *hspi)
 | |
| {
 | |
|   /* Return SPI handle state */
 | |
|   return hspi->State;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   * @brief  Return the SPI error code.
 | |
|   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
 | |
|   *               the configuration information for SPI module.
 | |
|   * @retval SPI error code in bitmap format
 | |
|   */
 | |
| uint32_t HAL_SPI_GetError(SPI_HandleTypeDef *hspi)
 | |
| {
 | |
|   /* Return SPI ErrorCode */
 | |
|   return hspi->ErrorCode;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   * @}
 | |
|   */
 | |
| 
 | |
| /**
 | |
|   * @}
 | |
|   */
 | |
| 
 | |
| /** @addtogroup SPI_Private_Functions
 | |
|   * @brief   Private functions
 | |
|   * @{
 | |
|   */
 | |
| 
 | |
| #if (defined(DMA1) || defined(DMA))
 | |
| /**
 | |
|   * @brief  DMA SPI transmit process complete callback.
 | |
|   * @note   Depending on devices and packages, DMA may not be available.
 | |
|   *         Refer to device datasheet for DMA availability.
 | |
|   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
 | |
|   *               the configuration information for the specified DMA module.
 | |
|   * @retval None
 | |
|   */
 | |
| static void SPI_DMATransmitCplt(DMA_HandleTypeDef *hdma)
 | |
| {
 | |
|   SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent); /* Derogation MISRAC2012-Rule-11.5 */
 | |
|   uint32_t tickstart;
 | |
| 
 | |
|   /* Init tickstart for timeout management*/
 | |
|   tickstart = HAL_GetTick();
 | |
| 
 | |
|   /* DMA Normal Mode */
 | |
|   if ((hdma->Instance->CCR & DMA_CCR_CIRC) != DMA_CCR_CIRC)
 | |
|   {
 | |
|     /* Disable ERR interrupt */
 | |
|     __HAL_SPI_DISABLE_IT(hspi, SPI_IT_ERR);
 | |
| 
 | |
|     /* Disable Tx DMA Request */
 | |
|     CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_TXDMAEN);
 | |
| 
 | |
|     /* Check the end of the transaction */
 | |
|     if (SPI_EndRxTxTransaction(hspi, SPI_DEFAULT_TIMEOUT, tickstart) != HAL_OK)
 | |
|     {
 | |
|       SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG);
 | |
|     }
 | |
| 
 | |
|     /* Clear overrun flag in 2 Lines communication mode because received data is not read */
 | |
|     if (hspi->Init.Direction == SPI_DIRECTION_2LINES)
 | |
|     {
 | |
|       __HAL_SPI_CLEAR_OVRFLAG(hspi);
 | |
|     }
 | |
| 
 | |
|     hspi->TxXferCount = 0U;
 | |
|     hspi->State = HAL_SPI_STATE_READY;
 | |
| 
 | |
|     if (hspi->ErrorCode != HAL_SPI_ERROR_NONE)
 | |
|     {
 | |
|       /* Call user error callback */
 | |
| #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U)
 | |
|       hspi->ErrorCallback(hspi);
 | |
| #else
 | |
|       HAL_SPI_ErrorCallback(hspi);
 | |
| #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
 | |
|       return;
 | |
|     }
 | |
|   }
 | |
|   /* Call user Tx complete callback */
 | |
| #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U)
 | |
|   hspi->TxCpltCallback(hspi);
 | |
| #else
 | |
|   HAL_SPI_TxCpltCallback(hspi);
 | |
| #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
 | |
| }
 | |
| 
 | |
| /**
 | |
|   * @brief  DMA SPI receive process complete callback.
 | |
|   * @note   Depending on devices and packages, DMA may not be available.
 | |
|   *         Refer to device datasheet for DMA availability.
 | |
|   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
 | |
|   *               the configuration information for the specified DMA module.
 | |
|   * @retval None
 | |
|   */
 | |
| static void SPI_DMAReceiveCplt(DMA_HandleTypeDef *hdma)
 | |
| {
 | |
|   SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent); /* Derogation MISRAC2012-Rule-11.5 */
 | |
|   uint32_t tickstart;
 | |
| 
 | |
|   /* Init tickstart for timeout management*/
 | |
|   tickstart = HAL_GetTick();
 | |
| 
 | |
|   /* DMA Normal Mode */
 | |
|   if ((hdma->Instance->CCR & DMA_CCR_CIRC) != DMA_CCR_CIRC)
 | |
|   {
 | |
|     /* Disable ERR interrupt */
 | |
|     __HAL_SPI_DISABLE_IT(hspi, SPI_IT_ERR);
 | |
| 
 | |
|     /* Check if we are in Master RX 2 line mode */
 | |
|     if ((hspi->Init.Direction == SPI_DIRECTION_2LINES) && (hspi->Init.Mode == SPI_MODE_MASTER))
 | |
|     {
 | |
|       /* Disable Rx/Tx DMA Request (done by default to handle the case master rx direction 2 lines) */
 | |
|       CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN);
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|       /* Normal case */
 | |
|       CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_RXDMAEN);
 | |
|     }
 | |
| 
 | |
|     /* Check the end of the transaction */
 | |
|     if (SPI_EndRxTransaction(hspi, SPI_DEFAULT_TIMEOUT, tickstart) != HAL_OK)
 | |
|     {
 | |
|       hspi->ErrorCode = HAL_SPI_ERROR_FLAG;
 | |
|     }
 | |
| 
 | |
|     hspi->RxXferCount = 0U;
 | |
|     hspi->State = HAL_SPI_STATE_READY;
 | |
| 
 | |
|     if (hspi->ErrorCode != HAL_SPI_ERROR_NONE)
 | |
|     {
 | |
|       /* Call user error callback */
 | |
| #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U)
 | |
|       hspi->ErrorCallback(hspi);
 | |
| #else
 | |
|       HAL_SPI_ErrorCallback(hspi);
 | |
| #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
 | |
|       return;
 | |
|     }
 | |
|   }
 | |
|   /* Call user Rx complete callback */
 | |
| #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U)
 | |
|   hspi->RxCpltCallback(hspi);
 | |
| #else
 | |
|   HAL_SPI_RxCpltCallback(hspi);
 | |
| #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
 | |
| }
 | |
| 
 | |
| /**
 | |
|   * @brief  DMA SPI transmit receive process complete callback.
 | |
|   * @note   Depending on devices and packages, DMA may not be available.
 | |
|   *         Refer to device datasheet for DMA availability.
 | |
|   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
 | |
|   *               the configuration information for the specified DMA module.
 | |
|   * @retval None
 | |
|   */
 | |
| static void SPI_DMATransmitReceiveCplt(DMA_HandleTypeDef *hdma)
 | |
| {
 | |
|   SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent); /* Derogation MISRAC2012-Rule-11.5 */
 | |
|   uint32_t tickstart;
 | |
| 
 | |
|   /* Init tickstart for timeout management*/
 | |
|   tickstart = HAL_GetTick();
 | |
| 
 | |
|   /* DMA Normal Mode */
 | |
|   if ((hdma->Instance->CCR & DMA_CCR_CIRC) != DMA_CCR_CIRC)
 | |
|   {
 | |
|     /* Disable ERR interrupt */
 | |
|     __HAL_SPI_DISABLE_IT(hspi, SPI_IT_ERR);
 | |
| 
 | |
|     /* Check the end of the transaction */
 | |
|     if (SPI_EndRxTxTransaction(hspi, SPI_DEFAULT_TIMEOUT, tickstart) != HAL_OK)
 | |
|     {
 | |
|       SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG);
 | |
|     }
 | |
| 
 | |
|     /* Disable Rx/Tx DMA Request */
 | |
|     CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN);
 | |
| 
 | |
|     hspi->TxXferCount = 0U;
 | |
|     hspi->RxXferCount = 0U;
 | |
|     hspi->State = HAL_SPI_STATE_READY;
 | |
| 
 | |
|     if (hspi->ErrorCode != HAL_SPI_ERROR_NONE)
 | |
|     {
 | |
|       /* Call user error callback */
 | |
| #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U)
 | |
|       hspi->ErrorCallback(hspi);
 | |
| #else
 | |
|       HAL_SPI_ErrorCallback(hspi);
 | |
| #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
 | |
|       return;
 | |
|     }
 | |
|   }
 | |
|   /* Call user TxRx complete callback */
 | |
| #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U)
 | |
|   hspi->TxRxCpltCallback(hspi);
 | |
| #else
 | |
|   HAL_SPI_TxRxCpltCallback(hspi);
 | |
| #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
 | |
| }
 | |
| 
 | |
| /**
 | |
|   * @brief  DMA SPI half transmit process complete callback.
 | |
|   * @note   Depending on devices and packages, DMA may not be available.
 | |
|   *         Refer to device datasheet for DMA availability.
 | |
|   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
 | |
|   *               the configuration information for the specified DMA module.
 | |
|   * @retval None
 | |
|   */
 | |
| static void SPI_DMAHalfTransmitCplt(DMA_HandleTypeDef *hdma)
 | |
| {
 | |
|   SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent); /* Derogation MISRAC2012-Rule-11.5 */
 | |
| 
 | |
|   /* Call user Tx half complete callback */
 | |
| #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U)
 | |
|   hspi->TxHalfCpltCallback(hspi);
 | |
| #else
 | |
|   HAL_SPI_TxHalfCpltCallback(hspi);
 | |
| #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
 | |
| }
 | |
| 
 | |
| /**
 | |
|   * @brief  DMA SPI half receive process complete callback
 | |
|   * @note   Depending on devices and packages, DMA may not be available.
 | |
|   *         Refer to device datasheet for DMA availability.
 | |
|   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
 | |
|   *               the configuration information for the specified DMA module.
 | |
|   * @retval None
 | |
|   */
 | |
| static void SPI_DMAHalfReceiveCplt(DMA_HandleTypeDef *hdma)
 | |
| {
 | |
|   SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent); /* Derogation MISRAC2012-Rule-11.5 */
 | |
| 
 | |
|   /* Call user Rx half complete callback */
 | |
| #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U)
 | |
|   hspi->RxHalfCpltCallback(hspi);
 | |
| #else
 | |
|   HAL_SPI_RxHalfCpltCallback(hspi);
 | |
| #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
 | |
| }
 | |
| 
 | |
| /**
 | |
|   * @brief  DMA SPI half transmit receive process complete callback.
 | |
|   * @note   Depending on devices and packages, DMA may not be available.
 | |
|   *         Refer to device datasheet for DMA availability.
 | |
|   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
 | |
|   *               the configuration information for the specified DMA module.
 | |
|   * @retval None
 | |
|   */
 | |
| static void SPI_DMAHalfTransmitReceiveCplt(DMA_HandleTypeDef *hdma)
 | |
| {
 | |
|   SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent); /* Derogation MISRAC2012-Rule-11.5 */
 | |
| 
 | |
|   /* Call user TxRx half complete callback */
 | |
| #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U)
 | |
|   hspi->TxRxHalfCpltCallback(hspi);
 | |
| #else
 | |
|   HAL_SPI_TxRxHalfCpltCallback(hspi);
 | |
| #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
 | |
| }
 | |
| 
 | |
| /**
 | |
|   * @brief  DMA SPI communication error callback.
 | |
|   * @note   Depending on devices and packages, DMA may not be available.
 | |
|   *         Refer to device datasheet for DMA availability.
 | |
|   * @param  hdma pointer to a DMA_HandleTypeDef structure that contains
 | |
|   *               the configuration information for the specified DMA module.
 | |
|   * @retval None
 | |
|   */
 | |
| static void SPI_DMAError(DMA_HandleTypeDef *hdma)
 | |
| {
 | |
|   SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent); /* Derogation MISRAC2012-Rule-11.5 */
 | |
| 
 | |
|   /* Stop the disable DMA transfer on SPI side */
 | |
|   CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_TXDMAEN | SPI_CR2_RXDMAEN);
 | |
| 
 | |
|   SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_DMA);
 | |
|   hspi->State = HAL_SPI_STATE_READY;
 | |
|   /* Call user error callback */
 | |
| #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U)
 | |
|   hspi->ErrorCallback(hspi);
 | |
| #else
 | |
|   HAL_SPI_ErrorCallback(hspi);
 | |
| #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
 | |
| }
 | |
| 
 | |
| /**
 | |
|   * @brief  DMA SPI communication abort callback, when initiated by HAL services on Error
 | |
|   *         (To be called at end of DMA Abort procedure following error occurrence).
 | |
|   * @note   Depending on devices and packages, DMA may not be available.
 | |
|   *         Refer to device datasheet for DMA availability.
 | |
|   * @param  hdma DMA handle.
 | |
|   * @retval None
 | |
|   */
 | |
| static void SPI_DMAAbortOnError(DMA_HandleTypeDef *hdma)
 | |
| {
 | |
|   SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent); /* Derogation MISRAC2012-Rule-11.5 */
 | |
|   hspi->RxXferCount = 0U;
 | |
|   hspi->TxXferCount = 0U;
 | |
| 
 | |
|   /* Call user error callback */
 | |
| #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U)
 | |
|   hspi->ErrorCallback(hspi);
 | |
| #else
 | |
|   HAL_SPI_ErrorCallback(hspi);
 | |
| #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
 | |
| }
 | |
| 
 | |
| /**
 | |
|   * @brief  DMA SPI Tx communication abort callback, when initiated by user
 | |
|   *         (To be called at end of DMA Tx Abort procedure following user abort request).
 | |
|   * @note   When this callback is executed, User Abort complete call back is called only if no
 | |
|   *         Abort still ongoing for Rx DMA Handle.
 | |
|   * @note   Depending on devices and packages, DMA may not be available.
 | |
|   *         Refer to device datasheet for DMA availability.
 | |
|   * @param  hdma DMA handle.
 | |
|   * @retval None
 | |
|   */
 | |
| static void SPI_DMATxAbortCallback(DMA_HandleTypeDef *hdma)
 | |
| {
 | |
|   SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent); /* Derogation MISRAC2012-Rule-11.5 */
 | |
| 
 | |
|   hspi->hdmatx->XferAbortCallback = NULL;
 | |
| 
 | |
|   /* Disable Tx DMA Request */
 | |
|   CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_TXDMAEN);
 | |
| 
 | |
|   if (SPI_EndRxTxTransaction(hspi, SPI_DEFAULT_TIMEOUT, HAL_GetTick()) != HAL_OK)
 | |
|   {
 | |
|     hspi->ErrorCode = HAL_SPI_ERROR_ABORT;
 | |
|   }
 | |
| 
 | |
|   /* Disable SPI Peripheral */
 | |
|   __HAL_SPI_DISABLE(hspi);
 | |
| 
 | |
|   /* Empty the FRLVL fifo */
 | |
|   if (SPI_WaitFifoStateUntilTimeout(hspi, SPI_FLAG_FRLVL, SPI_FRLVL_EMPTY, SPI_DEFAULT_TIMEOUT, HAL_GetTick()) != HAL_OK)
 | |
|   {
 | |
|     hspi->ErrorCode = HAL_SPI_ERROR_ABORT;
 | |
|   }
 | |
| 
 | |
|   /* Check if an Abort process is still ongoing */
 | |
|   if (hspi->hdmarx != NULL)
 | |
|   {
 | |
|     if (hspi->hdmarx->XferAbortCallback != NULL)
 | |
|     {
 | |
|       return;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   /* No Abort process still ongoing : All DMA Stream/Channel are aborted, call user Abort Complete callback */
 | |
|   hspi->RxXferCount = 0U;
 | |
|   hspi->TxXferCount = 0U;
 | |
| 
 | |
|   /* Check no error during Abort procedure */
 | |
|   if (hspi->ErrorCode != HAL_SPI_ERROR_ABORT)
 | |
|   {
 | |
|     /* Reset errorCode */
 | |
|     hspi->ErrorCode = HAL_SPI_ERROR_NONE;
 | |
|   }
 | |
| 
 | |
|   /* Clear the Error flags in the SR register */
 | |
|   __HAL_SPI_CLEAR_OVRFLAG(hspi);
 | |
|   __HAL_SPI_CLEAR_FREFLAG(hspi);
 | |
| 
 | |
|   /* Restore hspi->State to Ready */
 | |
|   hspi->State  = HAL_SPI_STATE_READY;
 | |
| 
 | |
|   /* Call user Abort complete callback */
 | |
| #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U)
 | |
|   hspi->AbortCpltCallback(hspi);
 | |
| #else
 | |
|   HAL_SPI_AbortCpltCallback(hspi);
 | |
| #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
 | |
| }
 | |
| 
 | |
| /**
 | |
|   * @brief  DMA SPI Rx communication abort callback, when initiated by user
 | |
|   *         (To be called at end of DMA Rx Abort procedure following user abort request).
 | |
|   * @note   When this callback is executed, User Abort complete call back is called only if no
 | |
|   *         Abort still ongoing for Tx DMA Handle.
 | |
|   * @note   Depending on devices and packages, DMA may not be available.
 | |
|   *         Refer to device datasheet for DMA availability.
 | |
|   * @param  hdma DMA handle.
 | |
|   * @retval None
 | |
|   */
 | |
| static void SPI_DMARxAbortCallback(DMA_HandleTypeDef *hdma)
 | |
| {
 | |
|   SPI_HandleTypeDef *hspi = (SPI_HandleTypeDef *)(((DMA_HandleTypeDef *)hdma)->Parent); /* Derogation MISRAC2012-Rule-11.5 */
 | |
| 
 | |
|   /* Disable SPI Peripheral */
 | |
|   __HAL_SPI_DISABLE(hspi);
 | |
| 
 | |
|   hspi->hdmarx->XferAbortCallback = NULL;
 | |
| 
 | |
|   /* Disable Rx DMA Request */
 | |
|   CLEAR_BIT(hspi->Instance->CR2, SPI_CR2_RXDMAEN);
 | |
| 
 | |
|   /* Control the BSY flag */
 | |
|   if (SPI_WaitFlagStateUntilTimeout(hspi, SPI_FLAG_BSY, RESET, SPI_DEFAULT_TIMEOUT, HAL_GetTick()) != HAL_OK)
 | |
|   {
 | |
|     hspi->ErrorCode = HAL_SPI_ERROR_ABORT;
 | |
|   }
 | |
| 
 | |
|   /* Empty the FRLVL fifo */
 | |
|   if (SPI_WaitFifoStateUntilTimeout(hspi, SPI_FLAG_FRLVL, SPI_FRLVL_EMPTY, SPI_DEFAULT_TIMEOUT, HAL_GetTick()) != HAL_OK)
 | |
|   {
 | |
|     hspi->ErrorCode = HAL_SPI_ERROR_ABORT;
 | |
|   }
 | |
| 
 | |
|   /* Check if an Abort process is still ongoing */
 | |
|   if (hspi->hdmatx != NULL)
 | |
|   {
 | |
|     if (hspi->hdmatx->XferAbortCallback != NULL)
 | |
|     {
 | |
|       return;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   /* No Abort process still ongoing : All DMA Stream/Channel are aborted, call user Abort Complete callback */
 | |
|   hspi->RxXferCount = 0U;
 | |
|   hspi->TxXferCount = 0U;
 | |
| 
 | |
|   /* Check no error during Abort procedure */
 | |
|   if (hspi->ErrorCode != HAL_SPI_ERROR_ABORT)
 | |
|   {
 | |
|     /* Reset errorCode */
 | |
|     hspi->ErrorCode = HAL_SPI_ERROR_NONE;
 | |
|   }
 | |
| 
 | |
|   /* Clear the Error flags in the SR register */
 | |
|   __HAL_SPI_CLEAR_OVRFLAG(hspi);
 | |
|   __HAL_SPI_CLEAR_FREFLAG(hspi);
 | |
| 
 | |
|   /* Restore hspi->State to Ready */
 | |
|   hspi->State  = HAL_SPI_STATE_READY;
 | |
| 
 | |
|   /* Call user Abort complete callback */
 | |
| #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U)
 | |
|   hspi->AbortCpltCallback(hspi);
 | |
| #else
 | |
|   HAL_SPI_AbortCpltCallback(hspi);
 | |
| #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
 | |
| }
 | |
| #endif /* DMA1 or DMA */
 | |
| 
 | |
| /**
 | |
|   * @brief  Rx 8-bit handler for Transmit and Receive in Interrupt mode.
 | |
|   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
 | |
|   *               the configuration information for SPI module.
 | |
|   * @retval None
 | |
|   */
 | |
| static void SPI_2linesRxISR_8BIT(struct __SPI_HandleTypeDef *hspi)
 | |
| {
 | |
|   /* Receive data in packing mode */
 | |
|   if (hspi->RxXferCount > 1U)
 | |
|   {
 | |
|     *((uint16_t *)hspi->pRxBuffPtr) = (uint16_t)(hspi->Instance->DR);
 | |
|     hspi->pRxBuffPtr += sizeof(uint16_t);
 | |
|     hspi->RxXferCount -= 2U;
 | |
|     if (hspi->RxXferCount == 1U)
 | |
|     {
 | |
|       /* Set RX Fifo threshold according the reception data length: 8bit */
 | |
|       SET_BIT(hspi->Instance->CR2, SPI_RXFIFO_THRESHOLD);
 | |
|     }
 | |
|   }
 | |
|   /* Receive data in 8 Bit mode */
 | |
|   else
 | |
|   {
 | |
|     *hspi->pRxBuffPtr = *((__IO uint8_t *)&hspi->Instance->DR);
 | |
|     hspi->pRxBuffPtr++;
 | |
|     hspi->RxXferCount--;
 | |
|   }
 | |
| 
 | |
|   /* Check end of the reception */
 | |
|   if (hspi->RxXferCount == 0U)
 | |
|   {
 | |
|     /* Disable RXNE  and ERR interrupt */
 | |
|     __HAL_SPI_DISABLE_IT(hspi, (SPI_IT_RXNE | SPI_IT_ERR));
 | |
| 
 | |
|     if (hspi->TxXferCount == 0U)
 | |
|     {
 | |
|       SPI_CloseRxTx_ISR(hspi);
 | |
|     }
 | |
|   }
 | |
| }
 | |
| 
 | |
| /**
 | |
|   * @brief  Tx 8-bit handler for Transmit and Receive in Interrupt mode.
 | |
|   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
 | |
|   *               the configuration information for SPI module.
 | |
|   * @retval None
 | |
|   */
 | |
| static void SPI_2linesTxISR_8BIT(struct __SPI_HandleTypeDef *hspi)
 | |
| {
 | |
|   /* Transmit data in packing Bit mode */
 | |
|   if (hspi->TxXferCount >= 2U)
 | |
|   {
 | |
|     hspi->Instance->DR = *((uint16_t *)hspi->pTxBuffPtr);
 | |
|     hspi->pTxBuffPtr += sizeof(uint16_t);
 | |
|     hspi->TxXferCount -= 2U;
 | |
|   }
 | |
|   /* Transmit data in 8 Bit mode */
 | |
|   else
 | |
|   {
 | |
|     *(__IO uint8_t *)&hspi->Instance->DR = (*hspi->pTxBuffPtr);
 | |
|     hspi->pTxBuffPtr++;
 | |
|     hspi->TxXferCount--;
 | |
|   }
 | |
| 
 | |
|   /* Check the end of the transmission */
 | |
|   if (hspi->TxXferCount == 0U)
 | |
|   {
 | |
|     /* Disable TXE interrupt */
 | |
|     __HAL_SPI_DISABLE_IT(hspi, SPI_IT_TXE);
 | |
| 
 | |
|     if (hspi->RxXferCount == 0U)
 | |
|     {
 | |
|       SPI_CloseRxTx_ISR(hspi);
 | |
|     }
 | |
|   }
 | |
| }
 | |
| 
 | |
| /**
 | |
|   * @brief  Rx 16-bit handler for Transmit and Receive in Interrupt mode.
 | |
|   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
 | |
|   *               the configuration information for SPI module.
 | |
|   * @retval None
 | |
|   */
 | |
| static void SPI_2linesRxISR_16BIT(struct __SPI_HandleTypeDef *hspi)
 | |
| {
 | |
|   /* Receive data in 16 Bit mode */
 | |
|   *((uint16_t *)hspi->pRxBuffPtr) = (uint16_t)(hspi->Instance->DR);
 | |
|   hspi->pRxBuffPtr += sizeof(uint16_t);
 | |
|   hspi->RxXferCount--;
 | |
| 
 | |
|   if (hspi->RxXferCount == 0U)
 | |
|   {
 | |
|     /* Disable RXNE interrupt */
 | |
|     __HAL_SPI_DISABLE_IT(hspi, SPI_IT_RXNE);
 | |
| 
 | |
|     if (hspi->TxXferCount == 0U)
 | |
|     {
 | |
|       SPI_CloseRxTx_ISR(hspi);
 | |
|     }
 | |
|   }
 | |
| }
 | |
| 
 | |
| /**
 | |
|   * @brief  Tx 16-bit handler for Transmit and Receive in Interrupt mode.
 | |
|   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
 | |
|   *               the configuration information for SPI module.
 | |
|   * @retval None
 | |
|   */
 | |
| static void SPI_2linesTxISR_16BIT(struct __SPI_HandleTypeDef *hspi)
 | |
| {
 | |
|   /* Transmit data in 16 Bit mode */
 | |
|   hspi->Instance->DR = *((uint16_t *)hspi->pTxBuffPtr);
 | |
|   hspi->pTxBuffPtr += sizeof(uint16_t);
 | |
|   hspi->TxXferCount--;
 | |
| 
 | |
|   if (hspi->TxXferCount == 0U)
 | |
|   {
 | |
|     /* Disable TXE interrupt */
 | |
|     __HAL_SPI_DISABLE_IT(hspi, SPI_IT_TXE);
 | |
| 
 | |
|     if (hspi->RxXferCount == 0U)
 | |
|     {
 | |
|       SPI_CloseRxTx_ISR(hspi);
 | |
|     }
 | |
|   }
 | |
| }
 | |
| 
 | |
| /**
 | |
|   * @brief  Manage the receive 8-bit in Interrupt context.
 | |
|   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
 | |
|   *               the configuration information for SPI module.
 | |
|   * @retval None
 | |
|   */
 | |
| static void SPI_RxISR_8BIT(struct __SPI_HandleTypeDef *hspi)
 | |
| {
 | |
|   *hspi->pRxBuffPtr = (*(__IO uint8_t *)&hspi->Instance->DR);
 | |
|   hspi->pRxBuffPtr++;
 | |
|   hspi->RxXferCount--;
 | |
| 
 | |
|   if (hspi->RxXferCount == 0U)
 | |
|   {
 | |
|     SPI_CloseRx_ISR(hspi);
 | |
|   }
 | |
| }
 | |
| 
 | |
| /**
 | |
|   * @brief  Manage the 16-bit receive in Interrupt context.
 | |
|   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
 | |
|   *               the configuration information for SPI module.
 | |
|   * @retval None
 | |
|   */
 | |
| static void SPI_RxISR_16BIT(struct __SPI_HandleTypeDef *hspi)
 | |
| {
 | |
|   *((uint16_t *)hspi->pRxBuffPtr) = (uint16_t)(hspi->Instance->DR);
 | |
|   hspi->pRxBuffPtr += sizeof(uint16_t);
 | |
|   hspi->RxXferCount--;
 | |
| 
 | |
|   if (hspi->RxXferCount == 0U)
 | |
|   {
 | |
|     SPI_CloseRx_ISR(hspi);
 | |
|   }
 | |
| }
 | |
| 
 | |
| /**
 | |
|   * @brief  Handle the data 8-bit transmit in Interrupt mode.
 | |
|   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
 | |
|   *               the configuration information for SPI module.
 | |
|   * @retval None
 | |
|   */
 | |
| static void SPI_TxISR_8BIT(struct __SPI_HandleTypeDef *hspi)
 | |
| {
 | |
|   *(__IO uint8_t *)&hspi->Instance->DR = (*hspi->pTxBuffPtr);
 | |
|   hspi->pTxBuffPtr++;
 | |
|   hspi->TxXferCount--;
 | |
| 
 | |
|   if (hspi->TxXferCount == 0U)
 | |
|   {
 | |
|     SPI_CloseTx_ISR(hspi);
 | |
|   }
 | |
| }
 | |
| 
 | |
| /**
 | |
|   * @brief  Handle the data 16-bit transmit in Interrupt mode.
 | |
|   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
 | |
|   *               the configuration information for SPI module.
 | |
|   * @retval None
 | |
|   */
 | |
| static void SPI_TxISR_16BIT(struct __SPI_HandleTypeDef *hspi)
 | |
| {
 | |
|   /* Transmit data in 16 Bit mode */
 | |
|   hspi->Instance->DR = *((uint16_t *)hspi->pTxBuffPtr);
 | |
|   hspi->pTxBuffPtr += sizeof(uint16_t);
 | |
|   hspi->TxXferCount--;
 | |
| 
 | |
|   if (hspi->TxXferCount == 0U)
 | |
|   {
 | |
|     SPI_CloseTx_ISR(hspi);
 | |
|   }
 | |
| }
 | |
| 
 | |
| /**
 | |
|   * @brief  Handle SPI Communication Timeout.
 | |
|   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
 | |
|   *              the configuration information for SPI module.
 | |
|   * @param  Flag SPI flag to check
 | |
|   * @param  State flag state to check
 | |
|   * @param  Timeout Timeout duration
 | |
|   * @param  Tickstart tick start value
 | |
|   * @retval HAL status
 | |
|   */
 | |
| static HAL_StatusTypeDef SPI_WaitFlagStateUntilTimeout(SPI_HandleTypeDef *hspi, uint32_t Flag, FlagStatus State,
 | |
|     uint32_t Timeout, uint32_t Tickstart)
 | |
| {
 | |
|   __IO uint32_t count;
 | |
|   uint32_t tmp_timeout;
 | |
|   uint32_t tmp_tickstart;
 | |
| 
 | |
|   /* Adjust Timeout value  in case of end of transfer */
 | |
|   tmp_timeout   = Timeout - (HAL_GetTick() - Tickstart);
 | |
|   tmp_tickstart = HAL_GetTick();
 | |
| 
 | |
|   /* Calculate Timeout based on a software loop to avoid blocking issue if Systick is disabled */
 | |
|   count = tmp_timeout * ((SystemCoreClock * 32U) >> 20U);
 | |
| 
 | |
|   while ((__HAL_SPI_GET_FLAG(hspi, Flag) ? SET : RESET) != State)
 | |
|   {
 | |
|     if (Timeout != HAL_MAX_DELAY)
 | |
|     {
 | |
|       if (((HAL_GetTick() - tmp_tickstart) >= tmp_timeout) || (tmp_timeout == 0U))
 | |
|       {
 | |
|         /* Disable TXE, RXNE and ERR interrupts for the interrupt process */
 | |
|         __HAL_SPI_DISABLE_IT(hspi, (SPI_IT_TXE | SPI_IT_RXNE | SPI_IT_ERR));
 | |
| 
 | |
|         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);
 | |
|         }
 | |
| 
 | |
|         hspi->State = HAL_SPI_STATE_READY;
 | |
| 
 | |
|         /* Process Unlocked */
 | |
|         __HAL_UNLOCK(hspi);
 | |
| 
 | |
|         return HAL_TIMEOUT;
 | |
|       }
 | |
|       /* If Systick is disabled or not incremented, deactivate timeout to go in disable loop procedure */
 | |
|       if(count == 0U)
 | |
|       {
 | |
|         tmp_timeout = 0U;
 | |
|       }
 | |
|       count--;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   return HAL_OK;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   * @brief  Handle SPI FIFO Communication Timeout.
 | |
|   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
 | |
|   *              the configuration information for SPI module.
 | |
|   * @param  Fifo Fifo to check
 | |
|   * @param  State Fifo state to check
 | |
|   * @param  Timeout Timeout duration
 | |
|   * @param  Tickstart tick start value
 | |
|   * @retval HAL status
 | |
|   */
 | |
| static HAL_StatusTypeDef SPI_WaitFifoStateUntilTimeout(SPI_HandleTypeDef *hspi, uint32_t Fifo, uint32_t State,
 | |
|     uint32_t Timeout, uint32_t Tickstart)
 | |
| {
 | |
|   __IO uint32_t count;
 | |
|   uint32_t tmp_timeout;
 | |
|   uint32_t tmp_tickstart;
 | |
|   __IO uint8_t  * ptmpreg8;
 | |
|   __IO uint8_t  tmpreg8 = 0;
 | |
| 
 | |
|   /* Adjust Timeout value  in case of end of transfer */
 | |
|   tmp_timeout = Timeout - (HAL_GetTick() - Tickstart);
 | |
|   tmp_tickstart = HAL_GetTick();
 | |
| 
 | |
|   /* Initialize the 8bit temporary pointer */
 | |
|   ptmpreg8 = (__IO uint8_t *)&hspi->Instance->DR;
 | |
| 
 | |
|   /* Calculate Timeout based on a software loop to avoid blocking issue if Systick is disabled */
 | |
|   count = tmp_timeout * ((SystemCoreClock * 35U) >> 20U);
 | |
| 
 | |
|   while ((hspi->Instance->SR & Fifo) != State)
 | |
|   {
 | |
|     if ((Fifo == SPI_SR_FRLVL) && (State == SPI_FRLVL_EMPTY))
 | |
|     {
 | |
|       /* Flush Data Register by a blank read */
 | |
|       tmpreg8 = *ptmpreg8;
 | |
|       /* To avoid GCC warning */
 | |
|       UNUSED(tmpreg8);
 | |
|     }
 | |
| 
 | |
|     if (Timeout != HAL_MAX_DELAY)
 | |
|     {
 | |
|       if (((HAL_GetTick() - tmp_tickstart) >= tmp_timeout) || (tmp_timeout == 0U))
 | |
|       {
 | |
|         /* Disable TXE, RXNE and ERR interrupts for the interrupt process */
 | |
|         __HAL_SPI_DISABLE_IT(hspi, (SPI_IT_TXE | SPI_IT_RXNE | SPI_IT_ERR));
 | |
| 
 | |
|         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);
 | |
|         }
 | |
| 
 | |
|         hspi->State = HAL_SPI_STATE_READY;
 | |
| 
 | |
|         /* Process Unlocked */
 | |
|         __HAL_UNLOCK(hspi);
 | |
| 
 | |
|         return HAL_TIMEOUT;
 | |
|       }
 | |
|       /* If Systick is disabled or not incremented, deactivate timeout to go in disable loop procedure */
 | |
|       if(count == 0U)
 | |
|       {
 | |
|         tmp_timeout = 0U;
 | |
|       }      
 | |
|       count--;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   return HAL_OK;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   * @brief  Handle the check of the RX transaction complete.
 | |
|   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
 | |
|   *               the configuration information for SPI module.
 | |
|   * @param  Timeout Timeout duration
 | |
|   * @param  Tickstart tick start value
 | |
|   * @retval HAL status
 | |
|   */
 | |
| static HAL_StatusTypeDef SPI_EndRxTransaction(SPI_HandleTypeDef *hspi,  uint32_t Timeout, uint32_t Tickstart)
 | |
| {
 | |
|   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);
 | |
|   }
 | |
| 
 | |
|   /* Control the BSY flag */
 | |
|   if (SPI_WaitFlagStateUntilTimeout(hspi, SPI_FLAG_BSY, RESET, Timeout, Tickstart) != HAL_OK)
 | |
|   {
 | |
|     SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG);
 | |
|     return HAL_TIMEOUT;
 | |
|   }
 | |
| 
 | |
|   if ((hspi->Init.Mode == SPI_MODE_MASTER) && ((hspi->Init.Direction == SPI_DIRECTION_1LINE)
 | |
|       || (hspi->Init.Direction == SPI_DIRECTION_2LINES_RXONLY)))
 | |
|   {
 | |
|     /* Empty the FRLVL fifo */
 | |
|     if (SPI_WaitFifoStateUntilTimeout(hspi, SPI_FLAG_FRLVL, SPI_FRLVL_EMPTY, Timeout, Tickstart) != HAL_OK)
 | |
|     {
 | |
|       SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG);
 | |
|       return HAL_TIMEOUT;
 | |
|     }
 | |
|   }
 | |
|   return HAL_OK;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   * @brief  Handle the check of the RXTX or TX transaction complete.
 | |
|   * @param  hspi SPI handle
 | |
|   * @param  Timeout Timeout duration
 | |
|   * @param  Tickstart tick start value
 | |
|   * @retval HAL status
 | |
|   */
 | |
| static HAL_StatusTypeDef SPI_EndRxTxTransaction(SPI_HandleTypeDef *hspi, uint32_t Timeout, uint32_t Tickstart)
 | |
| {
 | |
|   /* Control if the TX fifo is empty */
 | |
|   if (SPI_WaitFifoStateUntilTimeout(hspi, SPI_FLAG_FTLVL, SPI_FTLVL_EMPTY, Timeout, Tickstart) != HAL_OK)
 | |
|   {
 | |
|     SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG);
 | |
|     return HAL_TIMEOUT;
 | |
|   }
 | |
| 
 | |
|   /* Control the BSY flag */
 | |
|   if (SPI_WaitFlagStateUntilTimeout(hspi, SPI_FLAG_BSY, RESET, Timeout, Tickstart) != HAL_OK)
 | |
|   {
 | |
|     SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG);
 | |
|     return HAL_TIMEOUT;
 | |
|   }
 | |
| 
 | |
|   /* Control if the RX fifo is empty */
 | |
|   if (SPI_WaitFifoStateUntilTimeout(hspi, SPI_FLAG_FRLVL, SPI_FRLVL_EMPTY, Timeout, Tickstart) != HAL_OK)
 | |
|   {
 | |
|     SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG);
 | |
|     return HAL_TIMEOUT;
 | |
|   }
 | |
| 
 | |
|   return HAL_OK;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   * @brief  Handle the end of the RXTX transaction.
 | |
|   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
 | |
|   *               the configuration information for SPI module.
 | |
|   * @retval None
 | |
|   */
 | |
| static void SPI_CloseRxTx_ISR(SPI_HandleTypeDef *hspi)
 | |
| {
 | |
|   uint32_t tickstart;
 | |
| 
 | |
|   /* Init tickstart for timeout managment*/
 | |
|   tickstart = HAL_GetTick();
 | |
| 
 | |
|   /* Disable ERR interrupt */
 | |
|   __HAL_SPI_DISABLE_IT(hspi, SPI_IT_ERR);
 | |
| 
 | |
|   /* Check the end of the transaction */
 | |
|   if (SPI_EndRxTxTransaction(hspi, SPI_DEFAULT_TIMEOUT, tickstart) != HAL_OK)
 | |
|   {
 | |
|     SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG);
 | |
|   }
 | |
|   if (hspi->ErrorCode == HAL_SPI_ERROR_NONE)
 | |
|   {
 | |
|     if (hspi->State == HAL_SPI_STATE_BUSY_RX)
 | |
|     {
 | |
|       hspi->State = HAL_SPI_STATE_READY;
 | |
|       /* Call user Rx complete callback */
 | |
| #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U)
 | |
|       hspi->RxCpltCallback(hspi);
 | |
| #else
 | |
|       HAL_SPI_RxCpltCallback(hspi);
 | |
| #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|       hspi->State = HAL_SPI_STATE_READY;
 | |
|       /* Call user TxRx complete callback */
 | |
| #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U)
 | |
|       hspi->TxRxCpltCallback(hspi);
 | |
| #else
 | |
|       HAL_SPI_TxRxCpltCallback(hspi);
 | |
| #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
 | |
|     }
 | |
|   }
 | |
|   else
 | |
|   {
 | |
|     hspi->State = HAL_SPI_STATE_READY;
 | |
|     /* Call user error callback */
 | |
| #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U)
 | |
|     hspi->ErrorCallback(hspi);
 | |
| #else
 | |
|     HAL_SPI_ErrorCallback(hspi);
 | |
| #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
 | |
|   }
 | |
| }
 | |
| 
 | |
| /**
 | |
|   * @brief  Handle the end of the RX transaction.
 | |
|   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
 | |
|   *               the configuration information for SPI module.
 | |
|   * @retval None
 | |
|   */
 | |
| static void SPI_CloseRx_ISR(SPI_HandleTypeDef *hspi)
 | |
| {
 | |
|   /* Disable RXNE and ERR interrupt */
 | |
|   __HAL_SPI_DISABLE_IT(hspi, (SPI_IT_RXNE | SPI_IT_ERR));
 | |
| 
 | |
|   /* Check the end of the transaction */
 | |
|   if (SPI_EndRxTransaction(hspi, SPI_DEFAULT_TIMEOUT, HAL_GetTick()) != HAL_OK)
 | |
|   {
 | |
|     SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG);
 | |
|   }
 | |
|   hspi->State = HAL_SPI_STATE_READY;
 | |
| 
 | |
|   if (hspi->ErrorCode == HAL_SPI_ERROR_NONE)
 | |
|   {
 | |
|     /* Call user Rx complete callback */
 | |
| #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U)
 | |
|     hspi->RxCpltCallback(hspi);
 | |
| #else
 | |
|     HAL_SPI_RxCpltCallback(hspi);
 | |
| #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
 | |
|   }
 | |
|   else
 | |
|   {
 | |
|     /* Call user error callback */
 | |
| #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U)
 | |
|     hspi->ErrorCallback(hspi);
 | |
| #else
 | |
|     HAL_SPI_ErrorCallback(hspi);
 | |
| #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
 | |
|   }
 | |
| }
 | |
| 
 | |
| /**
 | |
|   * @brief  Handle the end of the TX transaction.
 | |
|   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
 | |
|   *               the configuration information for SPI module.
 | |
|   * @retval None
 | |
|   */
 | |
| static void SPI_CloseTx_ISR(SPI_HandleTypeDef *hspi)
 | |
| {
 | |
|   uint32_t tickstart;
 | |
| 
 | |
|   /* Init tickstart for timeout management*/
 | |
|   tickstart = HAL_GetTick();
 | |
| 
 | |
|   /* Disable TXE and ERR interrupt */
 | |
|   __HAL_SPI_DISABLE_IT(hspi, (SPI_IT_TXE | SPI_IT_ERR));
 | |
| 
 | |
|   /* Check the end of the transaction */
 | |
|   if (SPI_EndRxTxTransaction(hspi, SPI_DEFAULT_TIMEOUT, tickstart) != HAL_OK)
 | |
|   {
 | |
|     SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_FLAG);
 | |
|   }
 | |
| 
 | |
|   /* 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);
 | |
|   }
 | |
| 
 | |
|   hspi->State = HAL_SPI_STATE_READY;
 | |
|   if (hspi->ErrorCode != HAL_SPI_ERROR_NONE)
 | |
|   {
 | |
|     /* Call user error callback */
 | |
| #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U)
 | |
|     hspi->ErrorCallback(hspi);
 | |
| #else
 | |
|     HAL_SPI_ErrorCallback(hspi);
 | |
| #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
 | |
|   }
 | |
|   else
 | |
|   {
 | |
|     /* Call user Rx complete callback */
 | |
| #if (USE_HAL_SPI_REGISTER_CALLBACKS == 1U)
 | |
|     hspi->TxCpltCallback(hspi);
 | |
| #else
 | |
|     HAL_SPI_TxCpltCallback(hspi);
 | |
| #endif /* USE_HAL_SPI_REGISTER_CALLBACKS */
 | |
|   }
 | |
| }
 | |
| 
 | |
| /**
 | |
|   * @brief  Handle abort a Rx transaction.
 | |
|   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
 | |
|   *               the configuration information for SPI module.
 | |
|   * @retval None
 | |
|   */
 | |
| static void SPI_AbortRx_ISR(SPI_HandleTypeDef *hspi)
 | |
| {
 | |
|   __IO uint32_t count;
 | |
| 
 | |
|   /* Disable SPI Peripheral */
 | |
|   __HAL_SPI_DISABLE(hspi);
 | |
| 
 | |
|   count = SPI_DEFAULT_TIMEOUT * (SystemCoreClock / 24U / 1000U);
 | |
| 
 | |
|   /* Disable RXNEIE interrupt */
 | |
|   CLEAR_BIT(hspi->Instance->CR2, (SPI_CR2_RXNEIE));
 | |
| 
 | |
|   /* Check RXNEIE is disabled */
 | |
|   do
 | |
|   {
 | |
|     if (count == 0U)
 | |
|     {
 | |
|       SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_ABORT);
 | |
|       break;
 | |
|     }
 | |
|     count--;
 | |
|   } while (HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_RXNEIE));
 | |
| 
 | |
|   /* Control the BSY flag */
 | |
|   if (SPI_WaitFlagStateUntilTimeout(hspi, SPI_FLAG_BSY, RESET, SPI_DEFAULT_TIMEOUT, HAL_GetTick()) != HAL_OK)
 | |
|   {
 | |
|     hspi->ErrorCode = HAL_SPI_ERROR_ABORT;
 | |
|   }
 | |
| 
 | |
|   /* Empty the FRLVL fifo */
 | |
|   if (SPI_WaitFifoStateUntilTimeout(hspi, SPI_FLAG_FRLVL, SPI_FRLVL_EMPTY, SPI_DEFAULT_TIMEOUT, HAL_GetTick()) != HAL_OK)
 | |
|   {
 | |
|     hspi->ErrorCode = HAL_SPI_ERROR_ABORT;
 | |
|   }
 | |
| 
 | |
|   hspi->State = HAL_SPI_STATE_ABORT;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   * @brief  Handle abort a Tx or Rx/Tx transaction.
 | |
|   * @param  hspi pointer to a SPI_HandleTypeDef structure that contains
 | |
|   *               the configuration information for SPI module.
 | |
|   * @retval None
 | |
|   */
 | |
| static void SPI_AbortTx_ISR(SPI_HandleTypeDef *hspi)
 | |
| {
 | |
|   __IO uint32_t count;
 | |
| 
 | |
|   count = SPI_DEFAULT_TIMEOUT * (SystemCoreClock / 24U / 1000U);
 | |
| 
 | |
|   /* Disable TXEIE interrupt */
 | |
|   CLEAR_BIT(hspi->Instance->CR2, (SPI_CR2_TXEIE));
 | |
| 
 | |
|   /* Check TXEIE is disabled */
 | |
|   do
 | |
|   {
 | |
|     if (count == 0U)
 | |
|     {
 | |
|       SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_ABORT);
 | |
|       break;
 | |
|     }
 | |
|     count--;
 | |
|   } while (HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_TXEIE));
 | |
| 
 | |
|   if (SPI_EndRxTxTransaction(hspi, SPI_DEFAULT_TIMEOUT, HAL_GetTick()) != HAL_OK)
 | |
|   {
 | |
|     hspi->ErrorCode = HAL_SPI_ERROR_ABORT;
 | |
|   }
 | |
| 
 | |
|   /* Disable SPI Peripheral */
 | |
|   __HAL_SPI_DISABLE(hspi);
 | |
| 
 | |
|   /* Empty the FRLVL fifo */
 | |
|   if (SPI_WaitFifoStateUntilTimeout(hspi, SPI_FLAG_FRLVL, SPI_FRLVL_EMPTY, SPI_DEFAULT_TIMEOUT, HAL_GetTick()) != HAL_OK)
 | |
|   {
 | |
|     hspi->ErrorCode = HAL_SPI_ERROR_ABORT;
 | |
|   }
 | |
| 
 | |
|   /* Check case of Full-Duplex Mode and disable directly RXNEIE interrupt */
 | |
|   if (HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_RXNEIE))
 | |
|   {
 | |
|     /* Disable RXNEIE interrupt */
 | |
|     CLEAR_BIT(hspi->Instance->CR2, (SPI_CR2_RXNEIE));
 | |
| 
 | |
|     /* Check RXNEIE is disabled */
 | |
|     do
 | |
|     {
 | |
|       if (count == 0U)
 | |
|       {
 | |
|         SET_BIT(hspi->ErrorCode, HAL_SPI_ERROR_ABORT);
 | |
|         break;
 | |
|       }
 | |
|       count--;
 | |
|     } while (HAL_IS_BIT_SET(hspi->Instance->CR2, SPI_CR2_RXNEIE));
 | |
| 
 | |
|     /* Control the BSY flag */
 | |
|     if (SPI_WaitFlagStateUntilTimeout(hspi, SPI_FLAG_BSY, RESET, SPI_DEFAULT_TIMEOUT, HAL_GetTick()) != HAL_OK)
 | |
|     {
 | |
|       hspi->ErrorCode = HAL_SPI_ERROR_ABORT;
 | |
|     }
 | |
| 
 | |
|     /* Empty the FRLVL fifo */
 | |
|     if (SPI_WaitFifoStateUntilTimeout(hspi, SPI_FLAG_FRLVL, SPI_FRLVL_EMPTY, SPI_DEFAULT_TIMEOUT, HAL_GetTick()) != HAL_OK)
 | |
|     {
 | |
|       hspi->ErrorCode = HAL_SPI_ERROR_ABORT;
 | |
|     }
 | |
|   }
 | |
|   hspi->State = HAL_SPI_STATE_ABORT;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   * @}
 | |
|   */
 | |
| 
 | |
| #endif /* HAL_SPI_MODULE_ENABLED */
 | |
| 
 | |
| /**
 | |
|   * @}
 | |
|   */
 | |
| 
 | |
| /**
 | |
|   * @}
 | |
|   */
 | |
| 
 | |
| /************************ (C) COPYRIGHT Puya *****END OF FILE****/
 | 
